diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/server/server.go | 4 | ||||
-rw-r--r-- | pkg/server/zclient.go | 19 | ||||
-rw-r--r-- | pkg/server/zclient_test.go | 204 |
3 files changed, 138 insertions, 89 deletions
diff --git a/pkg/server/server.go b/pkg/server/server.go index f31235aa..75921ec1 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -1706,7 +1706,7 @@ func (s *BgpServer) EnableZebra(ctx context.Context, r *api.EnableZebraRequest) } for _, p := range r.RouteTypes { - if _, err := zebra.RouteTypeFromString(p, uint8(r.Version)); err != nil { + if _, err := zebra.RouteTypeFromString(p, uint8(r.Version), r.SoftwareName); err != nil { return err } } @@ -1716,7 +1716,7 @@ func (s *BgpServer) EnableZebra(ctx context.Context, r *api.EnableZebraRequest) protos = append(protos, string(p)) } var err error - s.zclient, err = newZebraClient(s, r.Url, protos, uint8(r.Version), r.NexthopTriggerEnable, uint8(r.NexthopTriggerDelay), r.MplsLabelRangeSize) + s.zclient, err = newZebraClient(s, r.Url, protos, uint8(r.Version), r.NexthopTriggerEnable, uint8(r.NexthopTriggerDelay), r.MplsLabelRangeSize, r.SoftwareName) return err }, false) } diff --git a/pkg/server/zclient.go b/pkg/server/zclient.go index e16edd93..a4b8e378 100644 --- a/pkg/server/zclient.go +++ b/pkg/server/zclient.go @@ -185,9 +185,12 @@ func newIPRouteBody(dst []*table.Path, vrfId uint32, z *zebraClient) (body *zebr } var flags zebra.FLAG if path.IsIBGP() { - flags = zebra.FLAG_IBGP | zebra.FLAG_INTERNAL + flags = zebra.FLAG_IBGP | zebra.FLAG_ALLOW_RECURSION // 0x08|0x01 + if z.client.Version == 6 && z.client.SoftwareName != "frr6" { + flags = zebra.FRR_ZAPI6_FLAG_IBGP | zebra.FRR_ZAPI6_FLAG_ALLOW_RECURSION //0x04|0x01 + } } else if path.GetSource().MultihopTtl > 0 { - flags = zebra.FLAG_INTERNAL + flags = zebra.FLAG_ALLOW_RECURSION // 0x01, FRR_ZAPI6_FLAG_ALLOW_RECURSION is same. } return &zebra.IPRouteBody{ Type: zebra.ROUTE_BGP, @@ -252,7 +255,7 @@ func newNexthopUnregisterBody(family uint16, prefix net.IP) *zebra.NexthopRegist } } -func newPathFromIPRouteMessage(m *zebra.Message, version uint8) *table.Path { +func newPathFromIPRouteMessage(m *zebra.Message, version uint8, software string) *table.Path { header := m.Header body := m.Body.(*zebra.IPRouteBody) family := body.RouteFamily(version) @@ -266,7 +269,7 @@ func newPathFromIPRouteMessage(m *zebra.Message, version uint8) *table.Path { log.WithFields(log.Fields{ "Topic": "Zebra", "RouteType": body.Type.String(), - "Flag": body.Flags.String(), + "Flag": body.Flags.String(version, software), "Message": body.Message, "Family": body.Prefix.Family, "Prefix": body.Prefix.Prefix, @@ -379,7 +382,7 @@ func (z *zebraClient) loop() { } switch body := msg.Body.(type) { case *zebra.IPRouteBody: - if path := newPathFromIPRouteMessage(msg, z.client.Version); path != nil { + if path := newPathFromIPRouteMessage(msg, z.client.Version, z.client.SoftwareName); path != nil { if err := z.server.addPathList("", []*table.Path{path}); err != nil { log.WithFields(log.Fields{ "Topic": "Zebra", @@ -462,7 +465,7 @@ func (z *zebraClient) loop() { } } -func newZebraClient(s *BgpServer, url string, protos []string, version uint8, nhtEnable bool, nhtDelay uint8, mplsLabelRangeSize uint32) (*zebraClient, error) { +func newZebraClient(s *BgpServer, url string, protos []string, version uint8, nhtEnable bool, nhtDelay uint8, mplsLabelRangeSize uint32, softwareName string) (*zebraClient, error) { l := strings.SplitN(url, ":", 2) if len(l) != 2 { return nil, fmt.Errorf("unsupported url: %s", url) @@ -480,7 +483,7 @@ func newZebraClient(s *BgpServer, url string, protos []string, version uint8, nh ver++ } for elem, ver := range zapivers { - cli, err = zebra.NewClient(l[0], l[1], zebra.ROUTE_BGP, ver) + cli, err = zebra.NewClient(l[0], l[1], zebra.ROUTE_BGP, ver, softwareName) if cli != nil && err == nil { usingVersion = ver break @@ -508,7 +511,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, version) + t, err := zebra.RouteTypeFromString(typ, version, softwareName) if err != nil { return nil, err } diff --git a/pkg/server/zclient_test.go b/pkg/server/zclient_test.go index 732b6d8b..b9681e93 100644 --- a/pkg/server/zclient_test.go +++ b/pkg/server/zclient_test.go @@ -29,93 +29,139 @@ import ( func Test_newPathFromIPRouteMessage(t *testing.T) { assert := assert.New(t) - // IPv4 Route Add - m := &zebra.Message{} - h := &zebra.Header{ - Len: zebra.HeaderSize(2), - Marker: zebra.HEADER_MARKER, - Version: 2, - Command: zebra.IPV4_ROUTE_ADD, + ipv4RouteAddCommand := map[uint8]zebra.API_TYPE{ + 2: zebra.IPV4_ROUTE_ADD, + 3: zebra.IPV4_ROUTE_ADD, + 4: zebra.FRR_IPV4_ROUTE_ADD, + 5: zebra.FRR_ZAPI5_IPV4_ROUTE_ADD, + 6: zebra.FRR_ZAPI6_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: zebra.Prefix{ - Prefix: net.ParseIP("192.168.100.0"), - PrefixLen: uint8(24), - }, - Nexthops: []zebra.Nexthop{ - { - Gate: net.ParseIP("0.0.0.0"), + ipv4RouteDeleteCommand := map[uint8]zebra.API_TYPE{ + 2: zebra.IPV4_ROUTE_DELETE, + 3: zebra.IPV4_ROUTE_DELETE, + 4: zebra.FRR_IPV4_ROUTE_DELETE, + 5: zebra.FRR_ZAPI5_IPV4_ROUTE_DELETE, + 6: zebra.FRR_ZAPI6_ROUTE_DELETE, + } + ipv6RouteAddCommand := map[uint8]zebra.API_TYPE{ + 2: zebra.IPV6_ROUTE_ADD, + 3: zebra.IPV6_ROUTE_ADD, + 4: zebra.FRR_IPV6_ROUTE_ADD, + 5: zebra.FRR_ZAPI5_IPV6_ROUTE_ADD, + 6: zebra.FRR_ZAPI6_ROUTE_ADD, + } + ipv6RouteDeleteCommand := map[uint8]zebra.API_TYPE{ + 2: zebra.IPV6_ROUTE_DELETE, + 3: zebra.IPV6_ROUTE_DELETE, + 4: zebra.FRR_IPV6_ROUTE_DELETE, + 5: zebra.FRR_ZAPI5_IPV6_ROUTE_DELETE, + 6: zebra.FRR_ZAPI6_ROUTE_DELETE, + } + message := map[uint8]zebra.MESSAGE_FLAG{ + 2: zebra.MESSAGE_NEXTHOP | zebra.MESSAGE_DISTANCE | zebra.MESSAGE_METRIC | zebra.MESSAGE_MTU, + 3: zebra.MESSAGE_NEXTHOP | zebra.MESSAGE_DISTANCE | zebra.MESSAGE_METRIC | zebra.MESSAGE_MTU, + 4: zebra.FRR_MESSAGE_NEXTHOP | zebra.FRR_MESSAGE_DISTANCE | zebra.FRR_MESSAGE_METRIC | zebra.FRR_MESSAGE_MTU, + 5: zebra.FRR_ZAPI5_MESSAGE_NEXTHOP | zebra.FRR_ZAPI5_MESSAGE_DISTANCE | zebra.FRR_ZAPI5_MESSAGE_METRIC | zebra.FRR_ZAPI5_MESSAGE_MTU, + 6: zebra.FRR_ZAPI5_MESSAGE_NEXTHOP | zebra.FRR_ZAPI5_MESSAGE_DISTANCE | zebra.FRR_ZAPI5_MESSAGE_METRIC | zebra.FRR_ZAPI5_MESSAGE_MTU, + } + + for v := zebra.MinZapiVer; v <= zebra.MaxZapiVer; v++ { + // IPv4 Route Add + m := &zebra.Message{} + marker := zebra.HEADER_MARKER + if v > 3 { + marker = zebra.FRR_HEADER_MARKER + } + flag := zebra.FLAG_SELECTED + if v > 5 { + flag = zebra.FRR_ZAPI6_FLAG_SELECTED + } + h := &zebra.Header{ + Len: zebra.HeaderSize(v), + Marker: marker, + Version: v, + Command: ipv4RouteAddCommand[v], + } + b := &zebra.IPRouteBody{ + Type: zebra.ROUTE_TYPE(zebra.ROUTE_STATIC), + Flags: flag, + Message: message[v], + SAFI: zebra.SAFI(zebra.SAFI_UNICAST), // 1, FRR_ZAPI5_SAFI_UNICAST is same + Prefix: zebra.Prefix{ + Prefix: net.ParseIP("192.168.100.0"), + PrefixLen: uint8(24), }, - { - Ifindex: uint32(1), + 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 + Distance: uint8(0), + Metric: uint32(100), + Mtu: uint32(0), + Api: zebra.API_TYPE(ipv4RouteAddCommand[v]), + } + m.Header = *h + m.Body = b - 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()) - assert.Equal("192.168.100.0/24", pp.GetNlri().String()) - assert.True(pp.IsFromExternal()) - assert.False(pp.IsWithdraw) + path := newPathFromIPRouteMessage(m, v, "") + 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()) + assert.Equal("192.168.100.0/24", pp.GetNlri().String()) + assert.True(pp.IsFromExternal()) + assert.False(pp.IsWithdraw) - // IPv4 Route Delete - h.Command = zebra.IPV4_ROUTE_DELETE - b.Api = zebra.IPV4_ROUTE_DELETE - m.Header = *h - m.Body = b + // IPv4 Route Delete + h.Command = ipv4RouteDeleteCommand[v] + b.Api = ipv4RouteDeleteCommand[v] + m.Header = *h + m.Body = b - 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()) - assert.Equal("192.168.100.0/24", pp.GetNlri().String()) - med, _ := pp.GetMed() - assert.Equal(uint32(100), med) - assert.True(pp.IsFromExternal()) - assert.True(pp.IsWithdraw) + path = newPathFromIPRouteMessage(m, v, "") + 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()) + assert.Equal("192.168.100.0/24", pp.GetNlri().String()) + med, _ := pp.GetMed() + assert.Equal(uint32(100), med) + assert.True(pp.IsFromExternal()) + assert.True(pp.IsWithdraw) - // IPv6 Route Add - h.Command = zebra.IPV6_ROUTE_ADD - b.Api = zebra.IPV6_ROUTE_ADD - 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 + // IPv6 Route Add + h.Command = ipv6RouteAddCommand[v] + b.Api = ipv6RouteAddCommand[v] + 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, 2) - pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) - pp.SetIsFromExternal(path.IsFromExternal()) - assert.Equal("::", pp.GetNexthop().String()) - assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String()) - med, _ = pp.GetMed() - assert.Equal(uint32(100), med) - assert.True(pp.IsFromExternal()) - assert.False(pp.IsWithdraw) + path = newPathFromIPRouteMessage(m, v, "") + pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) + pp.SetIsFromExternal(path.IsFromExternal()) + assert.Equal("::", pp.GetNexthop().String()) + assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String()) + med, _ = pp.GetMed() + assert.Equal(uint32(100), med) + assert.True(pp.IsFromExternal()) + assert.False(pp.IsWithdraw) - // IPv6 Route Delete - h.Command = zebra.IPV6_ROUTE_DELETE - b.Api = zebra.IPV6_ROUTE_DELETE - m.Header = *h - m.Body = b + // IPv6 Route Delete + h.Command = ipv6RouteDeleteCommand[v] + b.Api = ipv6RouteDeleteCommand[v] + m.Header = *h + m.Body = b - 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()) - assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String()) - assert.True(pp.IsFromExternal()) - assert.True(pp.IsWithdraw) + path = newPathFromIPRouteMessage(m, v, "") + pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) + pp.SetIsFromExternal(path.IsFromExternal()) + assert.Equal("::", pp.GetNexthop().String()) + assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String()) + assert.True(pp.IsFromExternal()) + assert.True(pp.IsWithdraw) + } } |