summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTatsushi Demachi <tdemachi@gmail.com>2017-02-10 20:38:17 +0900
committerTatsushi Demachi <tdemachi@gmail.com>2017-02-10 20:57:11 +0900
commite84bf755a9740d5bca3405da494d3c4a85d30679 (patch)
tree295c691d7537bacbb00a232a91f2724b763bb20f
parent3703916e558624e383794b015b8f8e69422654c1 (diff)
zebra: Process per-route MTU zebra message
Since Quagga 1.0.20160309, it implements per-route MTU handling which adds MTU attribute to every ZEBRA_IPV4_ROUTE_ADD and ZEBRA_IPV6_ROUTE_ADD messages. It causes "message length invalid" error when GoBGP receives messages from Zebra and as the result, routes from Zebra are no longer added to GoBGP. This fixes the issue by decoding/encoding MTU attribute properly. Now parsed MTU attribute is not used anywhere, just kept in an internal structure.
-rw-r--r--server/zclient.go1
-rw-r--r--server/zclient_test.go3
-rw-r--r--zebra/zapi.go20
-rw-r--r--zebra/zapi_test.go28
4 files changed, 38 insertions, 14 deletions
diff --git a/server/zclient.go b/server/zclient.go
index 3f8627c3..df92f038 100644
--- a/server/zclient.go
+++ b/server/zclient.go
@@ -138,6 +138,7 @@ func createPathFromIPRouteMessage(m *zebra.Message) *table.Path {
"IfIndex": body.Ifindexs,
"Metric": body.Metric,
"Distance": body.Distance,
+ "Mtu": body.Mtu,
"api": header.Command.String(),
}).Debugf("create path from ip route message.")
diff --git a/server/zclient_test.go b/server/zclient_test.go
index 7338adcb..d15155c9 100644
--- a/server/zclient_test.go
+++ b/server/zclient_test.go
@@ -38,7 +38,7 @@ func Test_createRequestFromIPRouteMessage(t *testing.T) {
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,
+ 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),
@@ -46,6 +46,7 @@ func Test_createRequestFromIPRouteMessage(t *testing.T) {
Ifindexs: []uint32{1},
Distance: uint8(0),
Metric: uint32(100),
+ Mtu: uint32(0),
Api: zebra.API_TYPE(zebra.IPV4_ROUTE_ADD),
}
diff --git a/zebra/zapi.go b/zebra/zapi.go
index 25647257..dcee2d7a 100644
--- a/zebra/zapi.go
+++ b/zebra/zapi.go
@@ -211,6 +211,7 @@ const (
MESSAGE_IFINDEX = 0x02
MESSAGE_DISTANCE = 0x04
MESSAGE_METRIC = 0x08
+ MESSAGE_MTU = 0x10
)
// Message Flags
@@ -662,6 +663,7 @@ type IPRouteBody struct {
Ifindexs []uint32
Distance uint8
Metric uint32
+ Mtu uint32
Api API_TYPE
}
@@ -716,6 +718,11 @@ func (b *IPRouteBody) Serialize() ([]byte, error) {
binary.BigEndian.PutUint32(bbuf, b.Metric)
buf = append(buf, bbuf...)
}
+ if b.Message&MESSAGE_MTU > 0 {
+ bbuf := make([]byte, 4)
+ binary.BigEndian.PutUint32(bbuf, b.Mtu)
+ buf = append(buf, bbuf...)
+ }
return buf, nil
}
@@ -769,6 +776,11 @@ func (b *IPRouteBody) DecodeFromBytes(data []byte, version uint8) error {
rest += 4
}
+ if b.Message&MESSAGE_MTU > 0 {
+ // mtu(4)
+ rest += 4
+ }
+
if len(data[pos:]) != rest {
return fmt.Errorf("message length invalid")
}
@@ -803,13 +815,17 @@ func (b *IPRouteBody) DecodeFromBytes(data []byte, version uint8) error {
pos += 1
b.Metric = binary.BigEndian.Uint32(data[pos : pos+4])
}
+ if b.Message&MESSAGE_MTU > 0 {
+ pos += 4
+ b.Mtu = binary.BigEndian.Uint32(data[pos : pos+4])
+ }
return nil
}
func (b *IPRouteBody) String() string {
- s := fmt.Sprintf("type: %s, flags: %s, message: %d, prefix: %s, length: %d, nexthop: %s, distance: %d, metric: %d",
- b.Type.String(), b.Flags.String(), b.Message, b.Prefix.String(), b.PrefixLength, b.Nexthops[0].String(), b.Distance, b.Metric)
+ s := fmt.Sprintf("type: %s, flags: %s, message: %d, prefix: %s, length: %d, nexthop: %s, distance: %d, metric: %d, mtu: %d",
+ b.Type.String(), b.Flags.String(), b.Message, b.Prefix.String(), b.PrefixLength, b.Nexthops[0].String(), b.Distance, b.Metric, b.Mtu)
return s
}
diff --git a/zebra/zapi_test.go b/zebra/zapi_test.go
index 696374b4..ac4862f0 100644
--- a/zebra/zapi_test.go
+++ b/zebra/zapi_test.go
@@ -152,10 +152,10 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
assert := assert.New(t)
//DecodeFromBytes IPV4_ROUTE
- buf := make([]byte, 22)
+ buf := make([]byte, 26)
buf[0] = byte(ROUTE_CONNECT)
buf[1] = byte(FLAG_SELECTED)
- buf[2] = MESSAGE_NEXTHOP | MESSAGE_DISTANCE | MESSAGE_METRIC
+ buf[2] = MESSAGE_NEXTHOP | MESSAGE_DISTANCE | MESSAGE_METRIC | MESSAGE_MTU
buf[3] = 24
ip := net.ParseIP("192.168.100.0").To4()
copy(buf[4:7], []byte(ip))
@@ -168,22 +168,24 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
binary.BigEndian.PutUint32(buf[13:], 1)
buf[17] = 0 // distance
binary.BigEndian.PutUint32(buf[18:], 1)
+ binary.BigEndian.PutUint32(buf[22:], 1)
r := &IPRouteBody{Api: IPV4_ROUTE_ADD}
err := r.DecodeFromBytes(buf, 2)
assert.Equal(nil, err)
assert.Equal("192.168.100.0", r.Prefix.String())
assert.Equal(uint8(0x18), r.PrefixLength)
- assert.Equal(uint8(MESSAGE_NEXTHOP|MESSAGE_DISTANCE|MESSAGE_METRIC), r.Message)
+ assert.Equal(uint8(MESSAGE_NEXTHOP|MESSAGE_DISTANCE|MESSAGE_METRIC|MESSAGE_MTU), r.Message)
assert.Equal("0.0.0.0", r.Nexthops[0].String())
assert.Equal(uint32(1), r.Ifindexs[0])
assert.Equal(uint8(0), r.Distance)
assert.Equal(uint32(1), r.Metric)
+ assert.Equal(uint32(1), r.Mtu)
//Serialize
buf, err = r.Serialize()
assert.Equal(nil, err)
- assert.Equal([]byte{0x2, 0x10, 0xd}, buf[0:3])
+ assert.Equal([]byte{0x2, 0x10, 0x1d}, buf[0:3])
assert.Equal([]byte{0x0, 0x1}, buf[3:5])
assert.Equal(byte(24), buf[5])
ip = net.ParseIP("192.168.100.0").To4()
@@ -194,7 +196,8 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
bi := make([]byte, 4)
binary.BigEndian.PutUint32(bi, 1)
- assert.Equal(bi, buf[21:])
+ assert.Equal(bi, buf[21:25])
+ assert.Equal(bi, buf[25:])
// length invalid
buf = make([]byte, 18)
@@ -224,7 +227,7 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
copy(buf[4:7], []byte(ip))
buf[7] = 1
binary.BigEndian.PutUint32(buf[8:], 0)
- r = &IPRouteBody{Api: IPV6_ROUTE_ADD}
+ r = &IPRouteBody{Api: IPV4_ROUTE_ADD}
err = r.DecodeFromBytes(buf, 2)
assert.Equal(nil, err)
@@ -234,10 +237,10 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
assert := assert.New(t)
//DecodeFromBytes IPV6_ROUTE
- buf := make([]byte, 39)
+ buf := make([]byte, 43)
buf[0] = byte(ROUTE_CONNECT)
buf[1] = byte(FLAG_SELECTED)
- buf[2] = MESSAGE_NEXTHOP | MESSAGE_DISTANCE | MESSAGE_METRIC
+ buf[2] = MESSAGE_NEXTHOP | MESSAGE_DISTANCE | MESSAGE_METRIC | MESSAGE_MTU
buf[3] = 64
ip := net.ParseIP("2001:db8:0:f101::").To16()
copy(buf[4:12], []byte(ip))
@@ -251,22 +254,24 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
buf[34] = 0 // distance
binary.BigEndian.PutUint32(buf[35:], 1)
+ binary.BigEndian.PutUint32(buf[39:], 1)
r := &IPRouteBody{Api: IPV6_ROUTE_ADD}
err := r.DecodeFromBytes(buf, 2)
assert.Equal(nil, err)
assert.Equal("2001:db8:0:f101::", r.Prefix.String())
assert.Equal(uint8(64), r.PrefixLength)
- assert.Equal(uint8(MESSAGE_NEXTHOP|MESSAGE_DISTANCE|MESSAGE_METRIC), r.Message)
+ assert.Equal(uint8(MESSAGE_NEXTHOP|MESSAGE_DISTANCE|MESSAGE_METRIC|MESSAGE_MTU), r.Message)
assert.Equal("::", r.Nexthops[0].String())
assert.Equal(uint32(1), r.Ifindexs[0])
assert.Equal(uint8(0), r.Distance)
assert.Equal(uint32(1), r.Metric)
+ assert.Equal(uint32(1), r.Mtu)
//Serialize
buf, err = r.Serialize()
assert.Equal(nil, err)
- assert.Equal([]byte{0x2, 0x10, 0xd}, buf[0:3])
+ assert.Equal([]byte{0x2, 0x10, 0x1d}, buf[0:3])
assert.Equal([]byte{0x0, 0x1}, buf[3:5])
assert.Equal(byte(64), buf[5])
ip = net.ParseIP("2001:db8:0:f101::").To16()
@@ -284,7 +289,8 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
assert.Equal(byte(0), buf[37])
bi = make([]byte, 4)
binary.BigEndian.PutUint32(bi, 1)
- assert.Equal(bi, buf[38:])
+ assert.Equal(bi, buf[38:42])
+ assert.Equal(bi, buf[42:])
// length invalid
buf = make([]byte, 50)