summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHitoshi Irino <irino@sfc.wide.ad.jp>2019-07-21 15:08:23 +0900
committerHitoshi Irino <irino@sfc.wide.ad.jp>2019-07-21 15:25:50 +0900
commit7284d4cf8b3f9ecd03068dfa3ab3d433860b5089 (patch)
treea3e65926529501e19a33a8181fa4e14cd17d792b
parent426709893303ecd0ff189cfe0b24eda89edef95e (diff)
Avoid panic by receiving vpnv6 prefixes with zebra reported in issue #2113
- Additionally bug fix which avoid panic caused by displaying vpnv6 prefixes using gobgp vrf rib - Supporting FRRouting 7.1.x
-rw-r--r--cmd/gobgp/neighbor.go3
-rw-r--r--docs/sources/zebra.md22
-rw-r--r--internal/pkg/config/default.go2
-rw-r--r--internal/pkg/zebra/zapi.go101
-rw-r--r--internal/pkg/zebra/zapi_test.go60
-rw-r--r--pkg/server/zclient.go14
6 files changed, 111 insertions, 91 deletions
diff --git a/cmd/gobgp/neighbor.go b/cmd/gobgp/neighbor.go
index 2a1075da..ef8e904b 100644
--- a/cmd/gobgp/neighbor.go
+++ b/cmd/gobgp/neighbor.go
@@ -925,7 +925,8 @@ func showNeighborRib(r string, name string, args []string) error {
for _, dst := range rib {
prefix := dst.Prefix
if t == api.TableType_VRF {
- s := strings.Split(prefix, ":")
+ // extract prefix from original which is RD(AS:VRF):IPv4 or IPv6 address
+ s := strings.SplitN(prefix, ":", 3)
prefix = s[len(s)-1]
}
_, p, _ := net.ParseCIDR(prefix)
diff --git a/docs/sources/zebra.md b/docs/sources/zebra.md
index e79a8c97..d8b5f595 100644
--- a/docs/sources/zebra.md
+++ b/docs/sources/zebra.md
@@ -15,11 +15,11 @@ version 4), 5.0.x (Zebra API version 5), and 7.0.x (Zebra API version
6) are supported as default. FRRouting version 5.0.x changes zebra
message and it doesn't keep backward compatibility for FRRouting
version 4.0.x although FRRouting version 4.0.x and 5.0.x use Zebra API
-version 5. Also, FRRouting version 7.0.x changes zebra message and it
-doesn't keep backward compatibility for FRRouting version 6.0.x
-although FRRouting version 6.0.x and 7.0.x use Zebra API version 6. If
-you need to integrate with FRRouting version 4.0.x or 6.0x, please use
-`software-name` configuration.
+version 5. Also, FRRouting version 7.0.x and 7.1.x changes zebra
+message and it doesn't keep backward compatibility for FRRouting
+version 6.0.x although FRRouting version 6.0.x, 7.0.x and 7.1.x use
+Zebra API version 6. If you need to integrate with FRRouting version
+4.0.x or 6.0x, please use `software-name` configuration.
## Contents
@@ -59,15 +59,17 @@ You need to enable the zebra feature in the Global configuration as follows.
For connecting to FRRouting 7.0.x, please specify `6`.
- `mpls-label-range-size` specifies mpls label range size for
- requesting to Zebra. It works with FRRouting 5.0.x, FRRouting
- 6.0.x and FRRouting 7.0.x.
+ requesting to Zebra. It works with FRRouting 5.0.x, FRRouting 6.0.x,
+ FRRouting 7.0.x and FRRouting 7.1.x.
- `sotware-name` specifies software name for zebra when only `version`
configuration cannot specify software uniquely. This configuration
is used with 'version' configuration. For connecting to FRRouting
- 6.0.x, please specify `6` as `version` and `frr6` as
- `software-name`. For connecting to FRRouting 4.0.x, please specify
- `5` as `version` and `frr4` as `software-name`.
+ 7.1.x, please specify `6` as `version` and `frr7.1` as
+ `software-name`. For connecting to FRRouting 6.0.x, please specify
+ `6` as `version` and `frr6` as `software-name`. For connecting to
+ FRRouting 4.0.x, please specify `5` as `version` and `frr4` as
+ `software-name`.
## Check Routes from zebra
diff --git a/internal/pkg/config/default.go b/internal/pkg/config/default.go
index 7fd5b5c1..3ac8db34 100644
--- a/internal/pkg/config/default.go
+++ b/internal/pkg/config/default.go
@@ -422,7 +422,7 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
}
//SoftwareName for Zebra
- allowableZebraSoftwareName := []string{"", "quagga", "frr3", "frr4", "frr5", "frr6", "frr7"}
+ allowableZebraSoftwareName := []string{"", "quagga", "frr3", "frr4", "frr5", "frr6", "frr7", "frr7.1"}
isAllowable := false
for _, allowable := range allowableZebraSoftwareName {
if b.Zebra.Config.SoftwareName == allowable {
diff --git a/internal/pkg/zebra/zapi.go b/internal/pkg/zebra/zapi.go
index 7bd1ea39..fd308a6d 100644
--- a/internal/pkg/zebra/zapi.go
+++ b/internal/pkg/zebra/zapi.go
@@ -1060,10 +1060,11 @@ func NewClient(network, address string, typ ROUTE_TYPE, version uint8, software
version = MaxZapiVer
}
isAllowableSoftware := true
+
if ((version == 2 || version == 3) && software != "" && software != "quagga") ||
(version == 4 && software != "" && software != "frr3") ||
(version == 5 && software != "" && software != "frr4" && software != "frr5") ||
- (version == 6 && software != "" && software != "frr6" && software != "frr7") {
+ (version == 6 && software != "" && software != "frr6" && software != "frr7" && software != "frr7.1") {
isAllowableSoftware = false
}
if !isAllowableSoftware {
@@ -1086,7 +1087,7 @@ func NewClient(network, address string, typ ROUTE_TYPE, version uint8, software
for {
m, more := <-outgoing
if more {
- b, err := m.Serialize()
+ b, err := m.Serialize(software)
if err != nil {
log.WithFields(log.Fields{
"Topic": "Zebra",
@@ -1575,8 +1576,8 @@ func (h *Header) DecodeFromBytes(data []byte) error {
}
type Body interface {
- DecodeFromBytes([]byte, uint8) error
- Serialize(uint8) ([]byte, error)
+ DecodeFromBytes([]byte, uint8, string) error
+ Serialize(uint8, string) ([]byte, error)
String(uint8, string) string
}
@@ -1584,12 +1585,12 @@ type UnknownBody struct {
Data []byte
}
-func (b *UnknownBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *UnknownBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
b.Data = data
return nil
}
-func (b *UnknownBody) Serialize(version uint8) ([]byte, error) {
+func (b *UnknownBody) Serialize(version uint8, softwareName string) ([]byte, error) {
return b.Data, nil
}
@@ -1606,7 +1607,7 @@ type HelloBody struct {
// Reference: zread_hello function in zebra/zserv.c of Quagga1.2.x (ZAPI3)
// Reference: zread_hello function in zebra/zserv.c of FRR3.x (ZAPI4)
// Reference: zread_hello function in zebra/zapi_msg.c of FRR5.x (ZAPI5)
-func (b *HelloBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *HelloBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
b.RedistDefault = ROUTE_TYPE(data[0])
if version >= 4 {
b.Instance = binary.BigEndian.Uint16(data[1:3])
@@ -1620,7 +1621,7 @@ func (b *HelloBody) DecodeFromBytes(data []byte, version uint8) error {
// Reference: zebra_hello_send function in lib/zclient.c of Quagga1.2.x (ZAPI3)
// Reference: zebra_hello_send function in lib/zclient.c of FRR3.x (ZAPI4)
// Reference: zebra_hello_send function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *HelloBody) Serialize(version uint8) ([]byte, error) {
+func (b *HelloBody) Serialize(version uint8, softwareName string) ([]byte, error) {
if version <= 3 {
return []byte{uint8(b.RedistDefault)}, nil
} else { // version >= 4
@@ -1654,7 +1655,7 @@ type RedistributeBody struct {
// Reference: zebra_redistribute_add function in zebra/redistribute.c of Quagga1.2.x (ZAPI3)
// Reference: zebra_redistribute_add function in zebra/redistribute.c of FRR3.x (ZAPI4)
// Reference: zebra_redistribute_add function in zebra/redistribute.c of FRR5.x (ZAPI5)
-func (b *RedistributeBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *RedistributeBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
if version <= 3 {
b.Redist = ROUTE_TYPE(data[0])
} else { // version >= 4
@@ -1668,7 +1669,7 @@ func (b *RedistributeBody) DecodeFromBytes(data []byte, version uint8) error {
// Reference: zebra_redistribute_send function in lib/zclient.c of Quagga1.2.x (ZAPI3)
// Reference: zebra_redistribute_send function in lib/zclient.c of FRR3.x (ZAPI4)
// Reference: zebra_redistribute_send function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *RedistributeBody) Serialize(version uint8) ([]byte, error) {
+func (b *RedistributeBody) Serialize(version uint8, softwareName string) ([]byte, error) {
if version <= 3 {
return []byte{uint8(b.Redist)}, nil
} else { // version >= 4
@@ -1726,7 +1727,7 @@ type InterfaceUpdateBody struct {
// Reference: zebra_interface_if_set_value function in lib/zclient.c of Quagga1.2.x (ZAPI4)
// Reference: zebra_interface_if_set_value function in lib/zclient.c of FRR3.x (ZAPI4)
// Reference: zebra_interface_if_set_value function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *InterfaceUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *InterfaceUpdateBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
if len(data) < INTERFACE_NAMSIZ+33 {
return fmt.Errorf("lack of bytes. need %d but %d", INTERFACE_NAMSIZ+29, len(data))
}
@@ -1791,7 +1792,7 @@ func (b *InterfaceUpdateBody) DecodeFromBytes(data []byte, version uint8) error
return nil
}
-func (b *InterfaceUpdateBody) Serialize(version uint8) ([]byte, error) {
+func (b *InterfaceUpdateBody) Serialize(version uint8, softwareName string) ([]byte, error) {
return []byte{}, nil
}
@@ -1816,7 +1817,7 @@ type InterfaceAddressUpdateBody struct {
// Reference: zebra_interface_address_read function in lib/zclient.c of Quagga1.2.x (ZAPI4)
// Reference: zebra_interface_address_read function in lib/zclient.c of FRR3.x (ZAPI4)
// Reference: zebra_interface_address_read function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *InterfaceAddressUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *InterfaceAddressUpdateBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
b.Index = binary.BigEndian.Uint32(data[:4])
b.Flags = INTERFACE_ADDRESS_FLAG(data[4])
family := data[5]
@@ -1830,7 +1831,7 @@ func (b *InterfaceAddressUpdateBody) DecodeFromBytes(data []byte, version uint8)
return nil
}
-func (b *InterfaceAddressUpdateBody) Serialize(version uint8) ([]byte, error) {
+func (b *InterfaceAddressUpdateBody) Serialize(version uint8, softwareName string) ([]byte, error) {
return []byte{}, nil
}
@@ -1848,7 +1849,7 @@ type RouterIDUpdateBody struct {
// Reference: zebra_router_id_update_read function in lib/zclient.c of Quagga1.2.x (ZAPI4)
// Reference: zebra_router_id_update_read function in lib/zclient.c of FRR3.x (ZAPI4)
// Reference: zebra_router_id_update_read function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *RouterIDUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *RouterIDUpdateBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
family := data[0]
addrlen, err := addressByteLength(family)
@@ -1860,7 +1861,7 @@ func (b *RouterIDUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
return nil
}
-func (b *RouterIDUpdateBody) Serialize(version uint8) ([]byte, error) {
+func (b *RouterIDUpdateBody) Serialize(version uint8, softwareName string) ([]byte, error) {
return []byte{}, nil
}
@@ -1879,6 +1880,7 @@ type Nexthop struct {
BlackholeType uint8
LabelNum uint8
MplsLabels []uint32
+ Onlink uint8
}
func (n *Nexthop) String() string {
@@ -2038,7 +2040,7 @@ func (b *IPRouteBody) IsWithdraw(version uint8) bool {
// Reference: zapi_ipv4_route function in lib/zclient.c of Quagga1.2.x (ZAPI3)
// Reference: zapi_ipv4_route function in lib/zclient.c of FRR3.x (ZAPI4)
// Reference: zapi_route_encode function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *IPRouteBody) Serialize(version uint8) ([]byte, error) {
+func (b *IPRouteBody) Serialize(version uint8, softwareName string) ([]byte, error) {
var buf []byte
if version <= 3 {
buf = make([]byte, 5)
@@ -2137,6 +2139,9 @@ func (b *IPRouteBody) Serialize(version uint8) ([]byte, error) {
buf = append(buf, uint8(nexthop.Type))
+ if version == 6 && softwareName == "frr7.1" {
+ buf = append(buf, nexthop.Onlink)
+ }
if (version <= 3 && nexthop.Type == NEXTHOP_TYPE_IPV4) ||
(version >= 4 && nexthop.Type == FRR_NEXTHOP_TYPE_IPV4) {
buf = append(buf, nexthop.Gate.To4()...)
@@ -2207,7 +2212,7 @@ func (b *IPRouteBody) Serialize(version uint8) ([]byte, error) {
// Reference: zebra_read_ipv4 function in bgpd/bgp_zebra.c of Quagga1.2.x (ZAPI3)
// Reference: zebra_read_ipv4 function in bgpd/bgp_zebra.c of FRR4.x (ZAPI4)
// Reference: zapi_route_decode function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *IPRouteBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *IPRouteBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
if b == nil {
return fmt.Errorf("IPRouteBody is nil")
}
@@ -2321,6 +2326,10 @@ func (b *IPRouteBody) DecodeFromBytes(data []byte, version uint8) error {
nexthop.VrfId = binary.BigEndian.Uint32(data[pos : pos+4])
nexthop.Type = NEXTHOP_TYPE(data[pos+4])
pos += 5
+ if softwareName == "frr7.1" {
+ nexthop.Onlink = uint8(data[pos])
+ pos += 1
+ }
}
if (version <= 3 && nexthop.Type == NEXTHOP_TYPE_IPV4) ||
@@ -2531,7 +2540,7 @@ type NexthopLookupBody struct {
}
// Quagga only. Reference: zread_ipv[4|6]_nexthop_lookup in zebra/zserv.c of Quagga1.2.x (ZAPI3)
-func (b *NexthopLookupBody) Serialize(version uint8) ([]byte, error) {
+func (b *NexthopLookupBody) Serialize(version uint8, softwareName string) ([]byte, error) {
family := addressFamilyFromApi(b.Api, version)
buf := make([]byte, 0)
@@ -2544,7 +2553,7 @@ func (b *NexthopLookupBody) Serialize(version uint8) ([]byte, error) {
}
// Quagga only. Reference: zsend_ipv[4|6]_nexthop_lookup in zebra/zserv.c of Quagga1.2.x (ZAPI3)
-func (b *NexthopLookupBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *NexthopLookupBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
family := addressFamilyFromApi(b.Api, version)
addrByteLen, err := addressByteLength(family)
if err != nil {
@@ -2601,7 +2610,7 @@ type ImportLookupBody struct {
}
// Quagga only. Reference: zread_ipv4_import_lookup in zebra/zserv.c of Quagga1.2.x (ZAPI3)
-func (b *ImportLookupBody) Serialize(version uint8) ([]byte, error) {
+func (b *ImportLookupBody) Serialize(version uint8, softwareName string) ([]byte, error) {
buf := make([]byte, 1)
buf[0] = b.PrefixLength
buf = append(buf, b.Addr.To4()...)
@@ -2609,7 +2618,7 @@ func (b *ImportLookupBody) Serialize(version uint8) ([]byte, error) {
}
// Quagga only. Reference: zsend_ipv4_import_lookup in zebra/zserv.c of Quagga1.2.x (ZAPI3)
-func (b *ImportLookupBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *ImportLookupBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
family := addressFamilyFromApi(b.Api, version)
addrByteLen, err := addressByteLength(family)
if err != nil {
@@ -2704,7 +2713,7 @@ func (n *RegisteredNexthop) Serialize() ([]byte, error) {
// Reference: zserv_nexthop_register in zebra/zserv.c of Quagga1.2.x (ZAPI3)
// Reference: zserv_rnh_register in zebra/zserv.c of FRR3.x (ZAPI4)
// Reference: zread_rnh_register in zebra/zapi_msg.c of FRR5.x (ZAPI5)
-func (n *RegisteredNexthop) DecodeFromBytes(data []byte) error {
+func (n *RegisteredNexthop) DecodeFromBytes(data []byte, softwareName string) error {
// Connected (1 byte)
n.Connected = uint8(data[0])
// Address Family (2 bytes)
@@ -2731,7 +2740,7 @@ type NexthopRegisterBody struct {
// Reference: sendmsg_nexthop in bgpd/bgp_nht.c of Quagga1.2.x (ZAPI3)
// Reference: sendmsg_zebra_rnh in bgpd/bgp_nht.c of FRR3.x (ZAPI4)
// Reference: zclient_send_rnh function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *NexthopRegisterBody) Serialize(version uint8) ([]byte, error) {
+func (b *NexthopRegisterBody) Serialize(version uint8, softwareName string) ([]byte, error) {
buf := make([]byte, 0)
// List of Registered Nexthops
@@ -2749,14 +2758,14 @@ func (b *NexthopRegisterBody) Serialize(version uint8) ([]byte, error) {
// Reference: zserv_nexthop_register in zebra/zserv.c of Quagga1.2.x (ZAPI3)
// Reference: zserv_rnh_register in zebra/zserv.c of FRR3.x (ZAPI4)
// Reference: zread_rnh_register in zebra/zapi_msg.c of FRR5.x (ZAPI5)
-func (b *NexthopRegisterBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *NexthopRegisterBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
offset := 0
// List of Registered Nexthops
b.Nexthops = []*RegisteredNexthop{}
for len(data[offset:]) > 0 {
nh := new(RegisteredNexthop)
- err := nh.DecodeFromBytes(data[offset:])
+ err := nh.DecodeFromBytes(data[offset:], softwareName)
if err != nil {
return err
}
@@ -2786,7 +2795,7 @@ type NexthopUpdateBody IPRouteBody
// Reference: send_client function in zebra/zebra_rnh.c of Quagga1.2.x (ZAPI3)
// Reference: send_client function in zebra/zebra_rnh.c of FRR3.x (ZAPI4)
// Reference: send_client function in zebra/zebra_rnh.c of FRR5.x (ZAPI5)
-func (b *NexthopUpdateBody) Serialize(version uint8) ([]byte, error) {
+func (b *NexthopUpdateBody) Serialize(version uint8, softwareName string) ([]byte, error) {
// Address Family (2 bytes)
buf := make([]byte, 3)
binary.BigEndian.PutUint16(buf, uint16(b.Prefix.Family))
@@ -2831,7 +2840,7 @@ func (b *NexthopUpdateBody) Serialize(version uint8) ([]byte, error) {
// Reference: bgp_parse_nexthop_update function in bgpd/bgp_nht.c of Quagga1.2.x (ZAPI3)
// Reference: bgp_parse_nexthop_update function in bgpd/bgp_nht.c of FRR3.x (ZAPI4)
// Reference: zapi_nexthop_update_decode function in lib/zclient.c of FRR5.x (ZAPI5)
-func (b *NexthopUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *NexthopUpdateBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
// Address Family (2 bytes)
prefixFamily := binary.BigEndian.Uint16(data[0:2])
b.Prefix.Family = uint8(prefixFamily)
@@ -2892,14 +2901,14 @@ type LabelManagerConnectBody struct {
}
// Reference: lm_label_manager_connect in lib/zclient.c of FRR
-func (b *LabelManagerConnectBody) Serialize(version uint8) ([]byte, error) {
+func (b *LabelManagerConnectBody) Serialize(version uint8, softwareName string) ([]byte, error) {
buf := make([]byte, 3)
buf[0] = uint8(b.RedistDefault)
binary.BigEndian.PutUint16(buf[1:3], b.Instance)
return buf, nil
}
-func (b *LabelManagerConnectBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *LabelManagerConnectBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
size := 1
// FRR v4 may work incorrectly. It returns result only although it uses ZAPI v5.
if version >= 4 {
@@ -2938,7 +2947,7 @@ type GetLabelChunkBody struct {
// Reference: zread_get_label_chunk in zebra/zserv.c of FRR3.x
// Reference: zread_get_label_chunk in zebra/zapi_msg.c of FRR5.x and 6.x
-func (b *GetLabelChunkBody) Serialize(version uint8) ([]byte, error) {
+func (b *GetLabelChunkBody) Serialize(version uint8, softwareName string) ([]byte, error) {
buf := make([]byte, 8)
pos := 0
if version > 4 {
@@ -2954,7 +2963,7 @@ func (b *GetLabelChunkBody) Serialize(version uint8) ([]byte, error) {
// Reference: zsend_assign_label_chunk_response in zebra/zserv.c of FRR3.x
// Reference: zsend_assign_label_chunk_response in zebra/zapi_msg.c of FRR5.x and 6.x
-func (b *GetLabelChunkBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *GetLabelChunkBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
size := 9
if version > 4 {
size = 12
@@ -2987,7 +2996,7 @@ type ReleaseLabelChunkBody struct {
End uint32
}
-func (b *ReleaseLabelChunkBody) Serialize(version uint8) ([]byte, error) {
+func (b *ReleaseLabelChunkBody) Serialize(version uint8, softwareName string) ([]byte, error) {
buf := make([]byte, 11)
pos := 0
if version > 4 {
@@ -3001,7 +3010,7 @@ func (b *ReleaseLabelChunkBody) Serialize(version uint8) ([]byte, error) {
return buf[0:pos], nil
}
-func (b *ReleaseLabelChunkBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *ReleaseLabelChunkBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
// No response from Zebra
return nil
}
@@ -3031,7 +3040,7 @@ type VrfLabelBody struct {
}
// Reference: zclient_send_vrf_label in lib/zclient.c of FRR 5.x and 6.x
-func (b *VrfLabelBody) Serialize(version uint8) ([]byte, error) {
+func (b *VrfLabelBody) Serialize(version uint8, softwareName string) ([]byte, error) {
buf := make([]byte, 6)
binary.BigEndian.PutUint32(buf[0:4], b.Label)
buf[4] = uint8(b.Afi)
@@ -3039,7 +3048,7 @@ func (b *VrfLabelBody) Serialize(version uint8) ([]byte, error) {
return buf, nil
}
-func (b *VrfLabelBody) DecodeFromBytes(data []byte, version uint8) error {
+func (b *VrfLabelBody) DecodeFromBytes(data []byte, version uint8, softwareName string) error {
if len(data) < 6 {
return fmt.Errorf("invalid message length for VRF_LABEL message: %d<6", len(data))
}
@@ -3060,11 +3069,11 @@ type Message struct {
Body Body
}
-func (m *Message) Serialize() ([]byte, error) {
+func (m *Message) Serialize(software string) ([]byte, error) {
var body []byte
if m.Body != nil {
var err error
- body, err = m.Body.Serialize(m.Header.Version)
+ body, err = m.Body.Serialize(m.Header.Version, software)
if err != nil {
return nil, err
}
@@ -3077,7 +3086,7 @@ func (m *Message) Serialize() ([]byte, error) {
return append(hdr, body...), nil
}
-func (m *Message) parseMessage(data []byte) error {
+func (m *Message) parseMessage(data []byte, software string) error {
switch m.Header.Command {
case INTERFACE_ADD, INTERFACE_DELETE, INTERFACE_UP, INTERFACE_DOWN:
m.Body = &InterfaceUpdateBody{}
@@ -3096,10 +3105,10 @@ func (m *Message) parseMessage(data []byte) error {
default:
m.Body = &UnknownBody{}
}
- return m.Body.DecodeFromBytes(data, m.Header.Version)
+ return m.Body.DecodeFromBytes(data, m.Header.Version, software)
}
-func (m *Message) parseFrrMessage(data []byte) error {
+func (m *Message) parseFrrMessage(data []byte, software string) error {
switch m.Header.Command {
case FRR_INTERFACE_ADD, FRR_INTERFACE_DELETE, FRR_INTERFACE_UP, FRR_INTERFACE_DOWN:
m.Body = &InterfaceUpdateBody{}
@@ -3144,7 +3153,7 @@ func (m *Message) parseFrrMessage(data []byte) error {
default:
m.Body = &UnknownBody{}
}
- return m.Body.DecodeFromBytes(data, m.Header.Version)
+ return m.Body.DecodeFromBytes(data, m.Header.Version, software)
}
func (m *Message) parseFrrZapi5Message(data []byte, software string) error {
@@ -3202,7 +3211,7 @@ func (m *Message) parseFrrZapi5Message(data []byte, software string) error {
default:
m.Body = &UnknownBody{}
}
- return m.Body.DecodeFromBytes(data, m.Header.Version)
+ return m.Body.DecodeFromBytes(data, m.Header.Version, software)
}
func (m *Message) parseFrrZapi6Message(data []byte, software string) error {
@@ -3259,19 +3268,19 @@ func (m *Message) parseFrrZapi6Message(data []byte, software string) error {
default:
m.Body = &UnknownBody{}
}
- return m.Body.DecodeFromBytes(data, m.Header.Version)
+ return m.Body.DecodeFromBytes(data, m.Header.Version, software)
}
func ParseMessage(hdr *Header, data []byte, software string) (m *Message, err error) {
m = &Message{Header: *hdr}
if m.Header.Version == 4 {
- err = m.parseFrrMessage(data)
+ err = m.parseFrrMessage(data, software)
} else if m.Header.Version == 5 {
err = m.parseFrrZapi5Message(data, software)
} else if m.Header.Version == 6 {
err = m.parseFrrZapi6Message(data, software)
} else {
- err = m.parseMessage(data)
+ err = m.parseMessage(data, software)
}
if err != nil {
return nil, err
diff --git a/internal/pkg/zebra/zapi_test.go b/internal/pkg/zebra/zapi_test.go
index 9454a8a0..b75421c2 100644
--- a/internal/pkg/zebra/zapi_test.go
+++ b/internal/pkg/zebra/zapi_test.go
@@ -127,12 +127,12 @@ func Test_InterfaceUpdateBody(t *testing.T) {
pos += 1
}
b := &InterfaceUpdateBody{}
- err := b.DecodeFromBytes(buf, v)
+ err := b.DecodeFromBytes(buf, v, "")
assert.Equal(nil, err)
assert.Equal("01:23:45:67:89:ab", b.HardwareAddr.String())
buf = make([]byte, INTERFACE_NAMSIZ+32) //size mismatch
b = &InterfaceUpdateBody{}
- err = b.DecodeFromBytes(buf, v)
+ err = b.DecodeFromBytes(buf, v, "")
assert.NotEqual(nil, err)
}
}
@@ -159,7 +159,7 @@ func Test_InterfaceAddressUpdateBody(t *testing.T) {
copy(buf[pos:pos+4], []byte(dst))
b := &InterfaceAddressUpdateBody{}
- err := b.DecodeFromBytes(buf, v)
+ err := b.DecodeFromBytes(buf, v, "")
require.NoError(t, err)
assert.Equal(uint32(0), b.Index)
@@ -172,7 +172,7 @@ func Test_InterfaceAddressUpdateBody(t *testing.T) {
buf[5] = 0x4
pos += 1
b = &InterfaceAddressUpdateBody{}
- err = b.DecodeFromBytes(buf, v)
+ err = b.DecodeFromBytes(buf, v, "")
assert.NotEqual(nil, err)
}
}
@@ -192,7 +192,7 @@ func Test_RouterIDUpdateBody(t *testing.T) {
buf[pos] = byte(32)
b := &RouterIDUpdateBody{}
- err := b.DecodeFromBytes(buf, v)
+ err := b.DecodeFromBytes(buf, v, "")
assert.Equal(nil, err)
assert.Equal("192.168.100.1", b.Prefix.String())
assert.Equal(uint8(32), b.Length)
@@ -201,7 +201,7 @@ func Test_RouterIDUpdateBody(t *testing.T) {
buf[0] = 0x4
pos += 1
b = &RouterIDUpdateBody{}
- err = b.DecodeFromBytes(buf, v)
+ err = b.DecodeFromBytes(buf, v, "")
assert.NotEqual(nil, err)
}
}
@@ -294,7 +294,7 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], 1) // mtu
pos += 4
r := &IPRouteBody{Api: command[v]}
- err := r.DecodeFromBytes(buf, v)
+ err := r.DecodeFromBytes(buf, v, "")
assert.Equal(nil, err)
assert.Equal("192.168.100.0", r.Prefix.Prefix.String())
assert.Equal(uint8(0x18), r.Prefix.PrefixLen)
@@ -311,7 +311,7 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
assert.Equal(uint32(1), r.Mtu)
//Serialize
- buf, err = r.Serialize(v)
+ buf, err = r.Serialize(v, "")
assert.Equal(nil, err)
switch v {
case 2, 3:
@@ -416,7 +416,7 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
pos += 4
r = &IPRouteBody{Api: command[v]}
- err = r.DecodeFromBytes(buf, v)
+ err = r.DecodeFromBytes(buf, v, "")
switch v {
case 2, 3, 4:
assert.Equal("MESSAGE_METRIC message length invalid pos:14 rest:14", err.Error())
@@ -461,7 +461,7 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], 0) //metric
pos += 4
r = &IPRouteBody{Api: command[v]}
- err = r.DecodeFromBytes(buf, v)
+ err = r.DecodeFromBytes(buf, v, "")
assert.Equal(nil, err)
}
}
@@ -560,7 +560,7 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], 1) // mtu
pos += 4
r := &IPRouteBody{Api: command[v]}
- err := r.DecodeFromBytes(buf, v)
+ err := r.DecodeFromBytes(buf, v, "")
assert.Equal(nil, err)
assert.Equal("2001:db8:0:f101::", r.Prefix.Prefix.String())
assert.Equal(uint8(64), r.Prefix.PrefixLen)
@@ -577,7 +577,7 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
assert.Equal(uint32(1), r.Mtu)
//Serialize
- buf, err = r.Serialize(v)
+ buf, err = r.Serialize(v, "")
assert.Equal(nil, err)
switch v {
case 2, 3:
@@ -683,7 +683,7 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
pos += 4
r = &IPRouteBody{Api: command[v]}
- err = r.DecodeFromBytes(buf, v)
+ err = r.DecodeFromBytes(buf, v, "")
switch v {
case 2, 3, 4:
assert.Equal("message length invalid pos:39 rest:46", err.Error())
@@ -726,7 +726,7 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
buf[pos] = 1 //distance
binary.BigEndian.PutUint32(buf[pos:], 0) //metic
r = &IPRouteBody{Api: command[v]}
- err = r.DecodeFromBytes(buf, v)
+ err = r.DecodeFromBytes(buf, v, "")
assert.Equal(nil, err)
}
}
@@ -754,7 +754,7 @@ func Test_NexthopLookupBody(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], 3)
b := &NexthopLookupBody{Api: IPV4_NEXTHOP_LOOKUP}
- err := b.DecodeFromBytes(buf, 2)
+ err := b.DecodeFromBytes(buf, 2, "")
assert.Equal(nil, err)
assert.Equal("192.168.50.0", b.Addr.String())
assert.Equal(uint32(10), b.Metric)
@@ -763,7 +763,7 @@ func Test_NexthopLookupBody(t *testing.T) {
assert.Equal("172.16.1.101", b.Nexthops[0].Gate.String())
//Serialize
- buf, err = b.Serialize(2)
+ buf, err = b.Serialize(2, "")
ip = net.ParseIP("192.168.50.0").To4()
assert.Equal(nil, err)
assert.Equal([]byte(ip)[0:4], buf[0:4])
@@ -771,7 +771,7 @@ func Test_NexthopLookupBody(t *testing.T) {
// length invalid
buf = make([]byte, 3)
b = &NexthopLookupBody{Api: IPV4_NEXTHOP_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
+ err = b.DecodeFromBytes(buf, 2, "")
assert.NotEqual(nil, err)
//ipv6
@@ -793,7 +793,7 @@ func Test_NexthopLookupBody(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], 3)
b = &NexthopLookupBody{Api: IPV6_NEXTHOP_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
+ err = b.DecodeFromBytes(buf, 2, "")
assert.Equal(nil, err)
assert.Equal("2001:db8:0:f101::", b.Addr.String())
assert.Equal(uint32(10), b.Metric)
@@ -802,7 +802,7 @@ func Test_NexthopLookupBody(t *testing.T) {
assert.Equal("2001:db8:0:1111::1", b.Nexthops[0].Gate.String())
//Serialize
- buf, err = b.Serialize(2)
+ buf, err = b.Serialize(2, "")
ip = net.ParseIP("2001:db8:0:f101::").To16()
assert.Equal(nil, err)
assert.Equal([]byte(ip)[0:16], buf[0:16])
@@ -810,7 +810,7 @@ func Test_NexthopLookupBody(t *testing.T) {
// length invalid
buf = make([]byte, 15)
b = &NexthopLookupBody{Api: IPV6_NEXTHOP_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
+ err = b.DecodeFromBytes(buf, 2, "")
assert.NotEqual(nil, err)
}
@@ -836,7 +836,7 @@ func Test_ImportLookupBody(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], 3)
b := &ImportLookupBody{Api: IPV4_IMPORT_LOOKUP}
- err := b.DecodeFromBytes(buf, 2)
+ err := b.DecodeFromBytes(buf, 2, "")
assert.Equal(nil, err)
assert.Equal("192.168.50.0", b.Addr.String())
assert.Equal(uint32(10), b.Metric)
@@ -846,7 +846,7 @@ func Test_ImportLookupBody(t *testing.T) {
//Serialize
b.PrefixLength = uint8(24)
- buf, err = b.Serialize(2)
+ buf, err = b.Serialize(2, "")
ip = net.ParseIP("192.168.50.0").To4()
assert.Equal(nil, err)
assert.Equal(uint8(24), buf[0])
@@ -855,7 +855,7 @@ func Test_ImportLookupBody(t *testing.T) {
// length invalid
buf = make([]byte, 3)
b = &ImportLookupBody{Api: IPV4_IMPORT_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
+ err = b.DecodeFromBytes(buf, 2, "")
assert.NotEqual(nil, err)
}
@@ -882,7 +882,7 @@ func Test_NexthopRegisterBody(t *testing.T) {
for v := MinZapiVer; v <= MaxZapiVer; v++ {
// Test DecodeFromBytes()
b := &NexthopRegisterBody{Api: command[v]}
- err := b.DecodeFromBytes(bufIn, v)
+ err := b.DecodeFromBytes(bufIn, v, "")
assert.Nil(err)
// Test decoded values
@@ -894,7 +894,7 @@ func Test_NexthopRegisterBody(t *testing.T) {
assert.Equal(net.ParseIP("2001:db8:1:1::1").To16(), b.Nexthops[1].Prefix)
// Test Serialize()
- bufOut, err := b.Serialize(v)
+ bufOut, err := b.Serialize(v, "")
assert.Nil(err)
// Test serialised value
@@ -950,7 +950,7 @@ func Test_NexthopUpdateBody(t *testing.T) {
// Test DecodeFromBytes()
b := &NexthopUpdateBody{Api: command[v]}
- err := b.DecodeFromBytes(bufIn, v)
+ err := b.DecodeFromBytes(bufIn, v, "")
assert.Nil(err)
// Test decoded values
@@ -982,12 +982,12 @@ func Test_GetLabelChunkBody(t *testing.T) {
binary.BigEndian.PutUint32(buf[8:], 89) //End
b := &GetLabelChunkBody{}
- err := b.DecodeFromBytes(buf, v)
+ err := b.DecodeFromBytes(buf, v, "")
assert.Equal(nil, err)
//Serialize
b.ChunkSize = 10
- buf, err = b.Serialize(v)
+ buf, err = b.Serialize(v, "")
assert.Equal(nil, err)
assert.Equal(byte(routeType[v]), buf[0])
bi := make([]byte, 4)
@@ -1006,11 +1006,11 @@ func Test_VrfLabelBody(t *testing.T) {
bufIn[4] = byte(AFI_IP)
bufIn[5] = byte(LSP_BGP)
b := &VrfLabelBody{}
- err := b.DecodeFromBytes(bufIn, v)
+ err := b.DecodeFromBytes(bufIn, v, "")
assert.Equal(nil, err)
//Serialize
var bufOut []byte
- bufOut, err = b.Serialize(v)
+ bufOut, err = b.Serialize(v, "")
assert.Equal(nil, err)
assert.Equal(bufIn, bufOut)
}
diff --git a/pkg/server/zclient.go b/pkg/server/zclient.go
index 6bfdc895..1c315a6c 100644
--- a/pkg/server/zclient.go
+++ b/pkg/server/zclient.go
@@ -121,9 +121,17 @@ func addMessageLabelToIPRouteBody(path *table.Path, vrfId uint32, z *zebraClient
rf := path.GetRouteFamily()
if v > 4 && (rf == bgp.RF_IPv4_VPN || rf == bgp.RF_IPv6_VPN) {
*msgFlags |= zebra.FRR_ZAPI5_MESSAGE_LABEL
- for _, label := range path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).Labels.Labels {
- nexthop.LabelNum++
- nexthop.MplsLabels = append(nexthop.MplsLabels, label)
+ switch rf {
+ case bgp.RF_IPv4_VPN:
+ for _, label := range path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).Labels.Labels {
+ nexthop.LabelNum++
+ nexthop.MplsLabels = append(nexthop.MplsLabels, label)
+ }
+ case bgp.RF_IPv6_VPN:
+ for _, label := range path.GetNlri().(*bgp.LabeledVPNIPv6AddrPrefix).Labels.Labels {
+ nexthop.LabelNum++
+ nexthop.MplsLabels = append(nexthop.MplsLabels, label)
+ }
}
}
}