summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorHitoshi Irino <irino@sfc.wide.ad.jp>2019-05-05 20:35:52 +0900
committerFUJITA Tomonori <fujita.tomonori@gmail.com>2019-05-08 08:48:26 +0900
commit7d2823d4c037caf39c7222632669210a4b6d1ed4 (patch)
treedb6523171ffe4f086629ec95108cfa2cc6766d43 /pkg
parentcc267fad9e6410705420af220d73d25d288e8a58 (diff)
zebra: supporting FRRouting version 7
- the "version" parameter (which means ZAPI) 6 in zebra config changes supporting FRRouting version 7 instead of FRRouting version 6. - the "software-name" parameter which supports backward compatibility is added in zebra config. (GoBGP support FRRouting version 6 when "version = 6" and "software-name = frr6" is configured.)
Diffstat (limited to 'pkg')
-rw-r--r--pkg/server/server.go4
-rw-r--r--pkg/server/zclient.go19
-rw-r--r--pkg/server/zclient_test.go204
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)
+ }
}