diff options
author | Hitoshi Irino <irino@sfc.wide.ad.jp> | 2018-08-17 19:41:32 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2018-08-18 10:41:20 +0900 |
commit | edbedebf7b048034eeed4bc7f442432d15d549d8 (patch) | |
tree | 9ace882d6b57e1b458fe208cd7e7ef200853adce /pkg | |
parent | 75254037d47ca8a6cf86604d8371d5db5db8464d (diff) |
ZAPI5 (FRRouting version 5) support
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/server/server.go | 8 | ||||
-rw-r--r-- | pkg/server/zclient.go | 78 | ||||
-rw-r--r-- | pkg/server/zclient_test.go | 46 |
3 files changed, 73 insertions, 59 deletions
diff --git a/pkg/server/server.go b/pkg/server/server.go index 472da9ad..1ac5845b 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -621,13 +621,13 @@ func (server *BgpServer) notifyBestWatcher(best []*table.Path, multipath [][]*ta clonedM[i] = clonePathList(pathList) } clonedB := clonePathList(best) - m := make(map[string]uint16) + m := make(map[string]uint32) for _, p := range clonedB { switch p.GetRouteFamily() { case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN: for _, vrf := range server.globalRib.Vrfs { if vrf.Id != 0 && table.CanImportToVrf(vrf, p) { - m[p.GetNlri().String()] = uint16(vrf.Id) + m[p.GetNlri().String()] = uint32(vrf.Id) } } } @@ -1547,7 +1547,7 @@ func (s *BgpServer) EnableZebra(ctx context.Context, r *api.EnableZebraRequest) } for _, p := range r.RouteTypes { - if _, err := zebra.RouteTypeFromString(p); err != nil { + if _, err := zebra.RouteTypeFromString(p, uint8(r.Version)); err != nil { return err } } @@ -3387,7 +3387,7 @@ type WatchEventTable struct { type WatchEventBestPath struct { PathList []*table.Path MultiPathList [][]*table.Path - Vrf map[string]uint16 + Vrf map[string]uint32 } type WatchEventMessage struct { diff --git a/pkg/server/zclient.go b/pkg/server/zclient.go index 1ee1eee7..57aacf83 100644 --- a/pkg/server/zclient.go +++ b/pkg/server/zclient.go @@ -68,14 +68,14 @@ func (m nexthopStateCache) updateByNexthopUpdate(body *zebra.NexthopUpdateBody) if len(body.Nexthops) == 0 { // If NEXTHOP_UPDATE message does not contain any nexthop, the given // nexthop is unreachable. - if _, ok := m[body.Prefix.String()]; !ok { + if _, ok := m[body.Prefix.Prefix.String()]; !ok { // Zebra will send an empty NEXTHOP_UPDATE message as the fist // response for the NEXTHOP_REGISTER message. Here ignores it. return false } - m[body.Prefix.String()] = math.MaxUint32 // means unreachable + m[body.Prefix.Prefix.String()] = math.MaxUint32 // means unreachable } else { - m[body.Prefix.String()] = body.Metric + m[body.Prefix.Prefix.String()] = body.Metric } return true } @@ -125,7 +125,9 @@ func newIPRouteBody(dst []*table.Path) (body *zebra.IPRouteBody, isWithdraw bool l := strings.SplitN(path.GetNlri().String(), "/", 2) var prefix net.IP - nexthops := make([]net.IP, 0, len(paths)) + //nexthops := make([]net.IP, 0, len(paths)) + var nexthop zebra.Nexthop + nexthops := make([]zebra.Nexthop, 0, len(paths)) switch path.GetRouteFamily() { case bgp.RF_IPv4_UC, bgp.RF_IPv4_VPN: if path.GetRouteFamily() == bgp.RF_IPv4_UC { @@ -134,7 +136,8 @@ func newIPRouteBody(dst []*table.Path) (body *zebra.IPRouteBody, isWithdraw bool prefix = path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).IPAddrPrefixDefault.Prefix.To4() } for _, p := range paths { - nexthops = append(nexthops, p.GetNexthop().To4()) + nexthop.Gate = p.GetNexthop().To4() + nexthops = append(nexthops, nexthop) } case bgp.RF_IPv6_UC, bgp.RF_IPv6_VPN: if path.GetRouteFamily() == bgp.RF_IPv6_UC { @@ -143,7 +146,8 @@ func newIPRouteBody(dst []*table.Path) (body *zebra.IPRouteBody, isWithdraw bool prefix = path.GetNlri().(*bgp.LabeledVPNIPv6AddrPrefix).IPAddrPrefixDefault.Prefix.To16() } for _, p := range paths { - nexthops = append(nexthops, p.GetNexthop().To16()) + nexthop.Gate = p.GetNexthop().To16() + nexthops = append(nexthops, nexthop) } default: return nil, false @@ -162,14 +166,16 @@ func newIPRouteBody(dst []*table.Path) (body *zebra.IPRouteBody, isWithdraw bool flags = zebra.FLAG_INTERNAL } return &zebra.IPRouteBody{ - Type: zebra.ROUTE_BGP, - Flags: flags, - SAFI: zebra.SAFI_UNICAST, - Message: msgFlags, - Prefix: prefix, - PrefixLength: uint8(plen), - Nexthops: nexthops, - Metric: med, + Type: zebra.ROUTE_BGP, + Flags: flags, + SAFI: zebra.SAFI_UNICAST, + Message: msgFlags, + Prefix: zebra.Prefix{ + Prefix: prefix, + PrefixLen: uint8(plen), + }, + Nexthops: nexthops, + Metric: med, }, path.IsWithdraw } @@ -222,11 +228,11 @@ func newNexthopUnregisterBody(family uint16, prefix net.IP) *zebra.NexthopRegist } } -func newPathFromIPRouteMessage(m *zebra.Message) *table.Path { +func newPathFromIPRouteMessage(m *zebra.Message, version uint8) *table.Path { header := m.Header body := m.Body.(*zebra.IPRouteBody) - family := body.RouteFamily() - isWithdraw := body.IsWithdraw() + family := body.RouteFamily(version) + isWithdraw := body.IsWithdraw(version) var nlri bgp.AddrPrefixInterface pattr := make([]bgp.PathAttributeInterface, 0) @@ -238,10 +244,10 @@ func newPathFromIPRouteMessage(m *zebra.Message) *table.Path { "RouteType": body.Type.String(), "Flag": body.Flags.String(), "Message": body.Message, - "Prefix": body.Prefix, - "PrefixLength": body.PrefixLength, + "Family": body.Prefix.Family, + "Prefix": body.Prefix.Prefix, + "PrefixLength": body.Prefix.PrefixLen, "Nexthop": body.Nexthops, - "IfIndex": body.Ifindexs, "Metric": body.Metric, "Distance": body.Distance, "Mtu": body.Mtu, @@ -250,15 +256,15 @@ func newPathFromIPRouteMessage(m *zebra.Message) *table.Path { switch family { case bgp.RF_IPv4_UC: - nlri = bgp.NewIPAddrPrefix(body.PrefixLength, body.Prefix.String()) + nlri = bgp.NewIPAddrPrefix(body.Prefix.PrefixLen, body.Prefix.Prefix.String()) if len(body.Nexthops) > 0 { - pattr = append(pattr, bgp.NewPathAttributeNextHop(body.Nexthops[0].String())) + pattr = append(pattr, bgp.NewPathAttributeNextHop(body.Nexthops[0].Gate.String())) } case bgp.RF_IPv6_UC: - nlri = bgp.NewIPv6AddrPrefix(body.PrefixLength, body.Prefix.String()) + nlri = bgp.NewIPv6AddrPrefix(body.Prefix.PrefixLen, body.Prefix.Prefix.String()) nexthop := "" if len(body.Nexthops) > 0 { - nexthop = body.Nexthops[0].String() + nexthop = body.Nexthops[0].Gate.String() } pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri})) default: @@ -289,10 +295,10 @@ func (z *zebraClient) getPathListWithNexthopUpdate(body *zebra.NexthopUpdateBody } var rfList []bgp.RouteFamily - switch body.Family { - case uint16(syscall.AF_INET): + switch body.Prefix.Family { + case syscall.AF_INET: rfList = []bgp.RouteFamily{bgp.RF_IPv4_UC, bgp.RF_IPv4_VPN} - case uint16(syscall.AF_INET6): + case syscall.AF_INET6: rfList = []bgp.RouteFamily{bgp.RF_IPv6_UC, bgp.RF_IPv6_VPN} } @@ -309,7 +315,7 @@ func (z *zebraClient) getPathListWithNexthopUpdate(body *zebra.NexthopUpdateBody rib.Tables[rf] = tbl } - return rib.GetPathListWithNexthop(table.GLOBAL_RIB_NAME, rfList, body.Prefix) + return rib.GetPathListWithNexthop(table.GLOBAL_RIB_NAME, rfList, body.Prefix.Prefix) } func (z *zebraClient) updatePathByNexthopCache(paths []*table.Path) { @@ -338,7 +344,7 @@ func (z *zebraClient) loop() { case msg := <-z.client.Receive(): switch body := msg.Body.(type) { case *zebra.IPRouteBody: - if path := newPathFromIPRouteMessage(msg); path != nil { + if path := newPathFromIPRouteMessage(msg, z.client.Version); path != nil { if err := z.server.addPathList("", []*table.Path{path}); err != nil { log.WithFields(log.Fields{ "Topic": "Zebra", @@ -355,8 +361,8 @@ func (z *zebraClient) loop() { if len(paths) == 0 { // If there is no path bound for the given nexthop, send // NEXTHOP_UNREGISTER message. - z.client.SendNexthopRegister(msg.Header.VrfId, newNexthopUnregisterBody(body.Family, body.Prefix), true) - delete(z.nexthopCache, body.Prefix.String()) + z.client.SendNexthopRegister(msg.Header.VrfId, newNexthopUnregisterBody(uint16(body.Prefix.Family), body.Prefix.Prefix), true) + delete(z.nexthopCache, body.Prefix.Prefix.String()) } z.updatePathByNexthopCache(paths) } @@ -376,7 +382,7 @@ func (z *zebraClient) loop() { } else { z.updatePathByNexthopCache(msg.PathList) for _, path := range msg.PathList { - vrfs := []uint16{0} + vrfs := []uint32{0} if msg.Vrf != nil { if v, ok := msg.Vrf[path.GetNlri().String()]; ok { vrfs = append(vrfs, v) @@ -394,10 +400,10 @@ func (z *zebraClient) loop() { } case *WatchEventUpdate: if body := newNexthopRegisterBody(msg.PathList, z.nexthopCache); body != nil { - vrfID := uint16(0) + vrfID := uint32(0) for _, vrf := range z.server.listVrf() { if vrf.Name == msg.Neighbor.Config.Vrf { - vrfID = uint16(vrf.Id) + vrfID = uint32(vrf.Id) } } z.client.SendNexthopRegister(vrfID, body, false) @@ -414,7 +420,7 @@ func newZebraClient(s *BgpServer, url string, protos []string, version uint8, nh } var cli *zebra.Client var err error - for _, ver := range []uint8{version, 2, 3, 4} { + for _, ver := range []uint8{version, 2, 3, 4, 5} { cli, err = zebra.NewClient(l[0], l[1], zebra.ROUTE_BGP, ver) if err == nil { break @@ -433,7 +439,7 @@ func newZebraClient(s *BgpServer, url string, protos []string, version uint8, nh // cli.SendRouterIDAdd() cli.SendInterfaceAdd() for _, typ := range protos { - t, err := zebra.RouteTypeFromString(typ) + t, err := zebra.RouteTypeFromString(typ, version) if err != nil { return nil, err } diff --git a/pkg/server/zclient_test.go b/pkg/server/zclient_test.go index c7868c0b..732b6d8b 100644 --- a/pkg/server/zclient_test.go +++ b/pkg/server/zclient_test.go @@ -38,23 +38,31 @@ func Test_newPathFromIPRouteMessage(t *testing.T) { Command: zebra.IPV4_ROUTE_ADD, } b := &zebra.IPRouteBody{ - Type: zebra.ROUTE_TYPE(zebra.ROUTE_STATIC), - Flags: zebra.FLAG(zebra.FLAG_SELECTED), - Message: zebra.MESSAGE_NEXTHOP | zebra.MESSAGE_DISTANCE | zebra.MESSAGE_METRIC | zebra.MESSAGE_MTU, - SAFI: zebra.SAFI(zebra.SAFI_UNICAST), - Prefix: net.ParseIP("192.168.100.0"), - PrefixLength: uint8(24), - Nexthops: []net.IP{net.ParseIP("0.0.0.0")}, - Ifindexs: []uint32{1}, - Distance: uint8(0), - Metric: uint32(100), - Mtu: uint32(0), - Api: zebra.API_TYPE(zebra.IPV4_ROUTE_ADD), + Type: zebra.ROUTE_TYPE(zebra.ROUTE_STATIC), + Flags: zebra.FLAG(zebra.FLAG_SELECTED), + Message: zebra.MESSAGE_NEXTHOP | zebra.MESSAGE_DISTANCE | zebra.MESSAGE_METRIC | zebra.MESSAGE_MTU, + SAFI: zebra.SAFI(zebra.SAFI_UNICAST), + Prefix: zebra.Prefix{ + Prefix: net.ParseIP("192.168.100.0"), + PrefixLen: uint8(24), + }, + Nexthops: []zebra.Nexthop{ + { + Gate: net.ParseIP("0.0.0.0"), + }, + { + Ifindex: uint32(1), + }, + }, + Distance: uint8(0), + Metric: uint32(100), + Mtu: uint32(0), + Api: zebra.API_TYPE(zebra.IPV4_ROUTE_ADD), } m.Header = *h m.Body = b - path := newPathFromIPRouteMessage(m) + path := newPathFromIPRouteMessage(m, 2) pp := table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("0.0.0.0", pp.GetNexthop().String()) @@ -68,7 +76,7 @@ func Test_newPathFromIPRouteMessage(t *testing.T) { m.Header = *h m.Body = b - path = newPathFromIPRouteMessage(m) + path = newPathFromIPRouteMessage(m, 2) pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("0.0.0.0", pp.GetNexthop().String()) @@ -81,13 +89,13 @@ func Test_newPathFromIPRouteMessage(t *testing.T) { // IPv6 Route Add h.Command = zebra.IPV6_ROUTE_ADD b.Api = zebra.IPV6_ROUTE_ADD - b.Prefix = net.ParseIP("2001:db8:0:f101::") - b.PrefixLength = uint8(64) - b.Nexthops = []net.IP{net.ParseIP("::")} + b.Prefix.Prefix = net.ParseIP("2001:db8:0:f101::") + b.Prefix.PrefixLen = uint8(64) + b.Nexthops = []zebra.Nexthop{{Gate: net.ParseIP("::")}} m.Header = *h m.Body = b - path = newPathFromIPRouteMessage(m) + path = newPathFromIPRouteMessage(m, 2) pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("::", pp.GetNexthop().String()) @@ -103,7 +111,7 @@ func Test_newPathFromIPRouteMessage(t *testing.T) { m.Header = *h m.Body = b - path = newPathFromIPRouteMessage(m) + path = newPathFromIPRouteMessage(m, 2) pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("::", pp.GetNexthop().String()) |