summaryrefslogtreecommitdiffhomepage
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/afi_string.go17
-rw-r--r--zebra/api_type_string.go16
-rw-r--r--zebra/link_type_string.go16
-rw-r--r--zebra/nexthop_flag_string.go17
-rw-r--r--zebra/ptm_enable_string.go16
-rw-r--r--zebra/ptm_status_string.go16
-rw-r--r--zebra/route_type_string.go16
-rw-r--r--zebra/safi_string.go17
-rw-r--r--zebra/zapi.go1917
-rw-r--r--zebra/zapi_bsd.go58
-rw-r--r--zebra/zapi_darwin.go59
-rw-r--r--zebra/zapi_linux.go83
-rw-r--r--zebra/zapi_test.go531
-rw-r--r--zebra/zapi_windows.go38
14 files changed, 0 insertions, 2817 deletions
diff --git a/zebra/afi_string.go b/zebra/afi_string.go
deleted file mode 100644
index 6c07a09d..00000000
--- a/zebra/afi_string.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Code generated by "stringer -type=AFI"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _AFI_name = "AFI_IPAFI_IP6AFI_ETHERAFI_MAX"
-
-var _AFI_index = [...]uint8{0, 6, 13, 22, 29}
-
-func (i AFI) String() string {
- i -= 1
- if i >= AFI(len(_AFI_index)-1) {
- return fmt.Sprintf("AFI(%d)", i+1)
- }
- return _AFI_name[_AFI_index[i]:_AFI_index[i+1]]
-}
diff --git a/zebra/api_type_string.go b/zebra/api_type_string.go
deleted file mode 100644
index e97059b1..00000000
--- a/zebra/api_type_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type=API_TYPE"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _API_TYPE_name = "FRR_INTERFACE_ADDINTERFACE_ADDINTERFACE_DELETEINTERFACE_ADDRESS_ADDINTERFACE_ADDRESS_DELETEINTERFACE_UPINTERFACE_DOWNIPV4_ROUTE_ADDIPV4_ROUTE_DELETEIPV6_ROUTE_ADDIPV6_ROUTE_DELETEREDISTRIBUTE_ADDREDISTRIBUTE_DELETEREDISTRIBUTE_DEFAULT_ADDREDISTRIBUTE_DEFAULT_DELETEIPV4_NEXTHOP_LOOKUPIPV6_NEXTHOP_LOOKUPIPV4_IMPORT_LOOKUPIPV6_IMPORT_LOOKUPINTERFACE_RENAMEROUTER_ID_ADDROUTER_ID_DELETEROUTER_ID_UPDATEHELLOIPV4_NEXTHOP_LOOKUP_MRIBVRF_UNREGISTERINTERFACE_LINK_PARAMSNEXTHOP_REGISTERNEXTHOP_UNREGISTERNEXTHOP_UPDATEMESSAGE_MAXFRR_BFD_DEST_REPLAYFRR_REDISTRIBUTE_IPV4_ADDFRR_REDISTRIBUTE_IPV4_DELFRR_REDISTRIBUTE_IPV6_ADDFRR_REDISTRIBUTE_IPV6_DELFRR_VRF_UNREGISTERFRR_VRF_ADDFRR_VRF_DELETEFRR_INTERFACE_VRF_UPDATEFRR_BFD_CLIENT_REGISTERFRR_INTERFACE_ENABLE_RADVFRR_INTERFACE_DISABLE_RADVFRR_IPV4_NEXTHOP_LOOKUP_MRIBFRR_INTERFACE_LINK_PARAMSFRR_MPLS_LABELS_ADDFRR_MPLS_LABELS_DELETEFRR_IPV4_NEXTHOP_ADDFRR_IPV4_NEXTHOP_DELETEFRR_IPV6_NEXTHOP_ADDFRR_IPV6_NEXTHOP_DELETEFRR_IPMR_ROUTE_STATSFRR_LABEL_MANAGER_CONNECTFRR_GET_LABEL_CHUNKFRR_RELEASE_LABEL_CHUNKFRR_PW_ADDFRR_PW_DELETEFRR_PW_SETFRR_PW_UNSETFRR_PW_STATUS_UPDATE"
-
-var _API_TYPE_index = [...]uint16{0, 17, 30, 46, 67, 91, 103, 117, 131, 148, 162, 179, 195, 214, 238, 265, 284, 303, 321, 339, 355, 368, 384, 400, 405, 429, 443, 464, 480, 498, 512, 523, 542, 567, 592, 617, 642, 660, 671, 685, 709, 732, 757, 783, 811, 836, 855, 877, 897, 920, 940, 963, 983, 1008, 1027, 1050, 1060, 1073, 1083, 1095, 1115}
-
-func (i API_TYPE) String() string {
- if i >= API_TYPE(len(_API_TYPE_index)-1) {
- return fmt.Sprintf("API_TYPE(%d)", i)
- }
- return _API_TYPE_name[_API_TYPE_index[i]:_API_TYPE_index[i+1]]
-}
diff --git a/zebra/link_type_string.go b/zebra/link_type_string.go
deleted file mode 100644
index 9db8544b..00000000
--- a/zebra/link_type_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type=LINK_TYPE"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _LINK_TYPE_name = "LINK_TYPE_UNKNOWNLINK_TYPE_ETHERLINK_TYPE_EETHERLINK_TYPE_AX25LINK_TYPE_PRONETLINK_TYPE_IEEE802LINK_TYPE_ARCNETLINK_TYPE_APPLETLKLINK_TYPE_DLCILINK_TYPE_ATMLINK_TYPE_METRICOMLINK_TYPE_IEEE1394LINK_TYPE_EUI64LINK_TYPE_INFINIBANDLINK_TYPE_SLIPLINK_TYPE_CSLIPLINK_TYPE_SLIP6LINK_TYPE_CSLIP6LINK_TYPE_RSRVDLINK_TYPE_ADAPTLINK_TYPE_ROSELINK_TYPE_X25LINK_TYPE_PPPLINK_TYPE_CHDLCLINK_TYPE_LAPBLINK_TYPE_RAWHDLCLINK_TYPE_IPIPLINK_TYPE_IPIP6LINK_TYPE_FRADLINK_TYPE_SKIPLINK_TYPE_LOOPBACKLINK_TYPE_LOCALTLKLINK_TYPE_FDDILINK_TYPE_SITLINK_TYPE_IPDDPLINK_TYPE_IPGRELINK_TYPE_IP6GRELINK_TYPE_PIMREGLINK_TYPE_HIPPILINK_TYPE_ECONETLINK_TYPE_IRDALINK_TYPE_FCPPLINK_TYPE_FCALLINK_TYPE_FCPLLINK_TYPE_FCFABRICLINK_TYPE_IEEE802_TRLINK_TYPE_IEEE80211LINK_TYPE_IEEE80211_RADIOTAPLINK_TYPE_IEEE802154LINK_TYPE_IEEE802154_PHY"
-
-var _LINK_TYPE_index = [...]uint16{0, 17, 32, 48, 62, 78, 95, 111, 129, 143, 156, 174, 192, 207, 227, 241, 256, 271, 287, 302, 317, 331, 344, 357, 372, 386, 403, 417, 432, 446, 460, 478, 496, 510, 523, 538, 553, 569, 585, 600, 616, 630, 644, 658, 672, 690, 710, 729, 757, 777, 801}
-
-func (i LINK_TYPE) String() string {
- if i >= LINK_TYPE(len(_LINK_TYPE_index)-1) {
- return fmt.Sprintf("LINK_TYPE(%d)", i)
- }
- return _LINK_TYPE_name[_LINK_TYPE_index[i]:_LINK_TYPE_index[i+1]]
-}
diff --git a/zebra/nexthop_flag_string.go b/zebra/nexthop_flag_string.go
deleted file mode 100644
index 38f08b8a..00000000
--- a/zebra/nexthop_flag_string.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Code generated by "stringer -type=NEXTHOP_FLAG"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _NEXTHOP_FLAG_name = "NEXTHOP_IFINDEXNEXTHOP_IFNAMENEXTHOP_IPV4NEXTHOP_IPV4_IFINDEXNEXTHOP_IPV4_IFNAMENEXTHOP_IPV6NEXTHOP_IPV6_IFINDEXNEXTHOP_IPV6_IFNAMENEXTHOP_BLACKHOLE"
-
-var _NEXTHOP_FLAG_index = [...]uint8{0, 15, 29, 41, 61, 80, 92, 112, 131, 148}
-
-func (i NEXTHOP_FLAG) String() string {
- i -= 1
- if i >= NEXTHOP_FLAG(len(_NEXTHOP_FLAG_index)-1) {
- return fmt.Sprintf("NEXTHOP_FLAG(%d)", i+1)
- }
- return _NEXTHOP_FLAG_name[_NEXTHOP_FLAG_index[i]:_NEXTHOP_FLAG_index[i+1]]
-}
diff --git a/zebra/ptm_enable_string.go b/zebra/ptm_enable_string.go
deleted file mode 100644
index d750542e..00000000
--- a/zebra/ptm_enable_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type=PTM_ENABLE"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _PTM_ENABLE_name = "PTM_ENABLE_OFFPTM_ENABLE_ONPTM_ENABLE_UNSPEC"
-
-var _PTM_ENABLE_index = [...]uint8{0, 14, 27, 44}
-
-func (i PTM_ENABLE) String() string {
- if i >= PTM_ENABLE(len(_PTM_ENABLE_index)-1) {
- return fmt.Sprintf("PTM_ENABLE(%d)", i)
- }
- return _PTM_ENABLE_name[_PTM_ENABLE_index[i]:_PTM_ENABLE_index[i+1]]
-}
diff --git a/zebra/ptm_status_string.go b/zebra/ptm_status_string.go
deleted file mode 100644
index 464233b7..00000000
--- a/zebra/ptm_status_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type=PTM_STATUS"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _PTM_STATUS_name = "PTM_STATUS_DOWNPTM_STATUS_UPPTM_STATUS_UNKNOWN"
-
-var _PTM_STATUS_index = [...]uint8{0, 15, 28, 46}
-
-func (i PTM_STATUS) String() string {
- if i >= PTM_STATUS(len(_PTM_STATUS_index)-1) {
- return fmt.Sprintf("PTM_STATUS(%d)", i)
- }
- return _PTM_STATUS_name[_PTM_STATUS_index[i]:_PTM_STATUS_index[i+1]]
-}
diff --git a/zebra/route_type_string.go b/zebra/route_type_string.go
deleted file mode 100644
index e2ad6c97..00000000
--- a/zebra/route_type_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type=ROUTE_TYPE"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _ROUTE_TYPE_name = "ROUTE_SYSTEMROUTE_KERNELROUTE_CONNECTROUTE_STATICROUTE_RIPROUTE_RIPNGROUTE_OSPFROUTE_OSPF6ROUTE_ISISROUTE_BGPROUTE_PIMROUTE_HSLSROUTE_OLSRROUTE_BABELROUTE_MAXFRR_ROUTE_VNCFRR_ROUTE_VNC_DIRECTFRR_ROUTE_VNC_DIRECT_RHFRR_ROUTE_BGP_DIRECTFRR_ROUTE_BGP_DIRECT_EXTFRR_ROUTE_ALLFRR_ROUTE_MAX"
-
-var _ROUTE_TYPE_index = [...]uint16{0, 12, 24, 37, 49, 58, 69, 79, 90, 100, 109, 118, 128, 138, 149, 158, 171, 191, 214, 234, 258, 271, 284}
-
-func (i ROUTE_TYPE) String() string {
- if i >= ROUTE_TYPE(len(_ROUTE_TYPE_index)-1) {
- return fmt.Sprintf("ROUTE_TYPE(%d)", i)
- }
- return _ROUTE_TYPE_name[_ROUTE_TYPE_index[i]:_ROUTE_TYPE_index[i+1]]
-}
diff --git a/zebra/safi_string.go b/zebra/safi_string.go
deleted file mode 100644
index ab491cb6..00000000
--- a/zebra/safi_string.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Code generated by "stringer -type=SAFI"; DO NOT EDIT.
-
-package zebra
-
-import "fmt"
-
-const _SAFI_name = "SAFI_UNICASTSAFI_MULTICASTSAFI_RESERVED_3SAFI_MPLS_VPNSAFI_MAX"
-
-var _SAFI_index = [...]uint8{0, 12, 26, 41, 54, 62}
-
-func (i SAFI) String() string {
- i -= 1
- if i >= SAFI(len(_SAFI_index)-1) {
- return fmt.Sprintf("SAFI(%d)", i+1)
- }
- return _SAFI_name[_SAFI_index[i]:_SAFI_index[i+1]]
-}
diff --git a/zebra/zapi.go b/zebra/zapi.go
deleted file mode 100644
index 667cfcd9..00000000
--- a/zebra/zapi.go
+++ /dev/null
@@ -1,1917 +0,0 @@
-// Copyright (C) 2014, 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package zebra
-
-import (
- "encoding/binary"
- "fmt"
- "io"
- "net"
- "strings"
- "syscall"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/osrg/gobgp/packet/bgp"
-)
-
-const (
- HEADER_MARKER = 255
- FRR_HEADER_MARKER = 254
- INTERFACE_NAMSIZ = 20
-)
-
-// Internal Interface Status.
-type INTERFACE_STATUS uint8
-
-const (
- INTERFACE_ACTIVE INTERFACE_STATUS = 0x01
- INTERFACE_SUB INTERFACE_STATUS = 0x02
- INTERFACE_LINKDETECTION INTERFACE_STATUS = 0x04
- INTERFACE_VRF_LOOPBACK INTERFACE_STATUS = 0x08
-)
-
-// Interface Link Layer Types.
-//go:generate stringer -type=LINK_TYPE
-type LINK_TYPE uint32
-
-const (
- LINK_TYPE_UNKNOWN LINK_TYPE = iota
- LINK_TYPE_ETHER
- LINK_TYPE_EETHER
- LINK_TYPE_AX25
- LINK_TYPE_PRONET
- LINK_TYPE_IEEE802
- LINK_TYPE_ARCNET
- LINK_TYPE_APPLETLK
- LINK_TYPE_DLCI
- LINK_TYPE_ATM
- LINK_TYPE_METRICOM
- LINK_TYPE_IEEE1394
- LINK_TYPE_EUI64
- LINK_TYPE_INFINIBAND
- LINK_TYPE_SLIP
- LINK_TYPE_CSLIP
- LINK_TYPE_SLIP6
- LINK_TYPE_CSLIP6
- LINK_TYPE_RSRVD
- LINK_TYPE_ADAPT
- LINK_TYPE_ROSE
- LINK_TYPE_X25
- LINK_TYPE_PPP
- LINK_TYPE_CHDLC
- LINK_TYPE_LAPB
- LINK_TYPE_RAWHDLC
- LINK_TYPE_IPIP
- LINK_TYPE_IPIP6
- LINK_TYPE_FRAD
- LINK_TYPE_SKIP
- LINK_TYPE_LOOPBACK
- LINK_TYPE_LOCALTLK
- LINK_TYPE_FDDI
- LINK_TYPE_SIT
- LINK_TYPE_IPDDP
- LINK_TYPE_IPGRE
- LINK_TYPE_IP6GRE
- LINK_TYPE_PIMREG
- LINK_TYPE_HIPPI
- LINK_TYPE_ECONET
- LINK_TYPE_IRDA
- LINK_TYPE_FCPP
- LINK_TYPE_FCAL
- LINK_TYPE_FCPL
- LINK_TYPE_FCFABRIC
- LINK_TYPE_IEEE802_TR
- LINK_TYPE_IEEE80211
- LINK_TYPE_IEEE80211_RADIOTAP
- LINK_TYPE_IEEE802154
- LINK_TYPE_IEEE802154_PHY
-)
-
-const VRF_DEFAULT = 0
-
-func HeaderSize(version uint8) uint16 {
- switch version {
- case 3, 4:
- return 8
- default:
- return 6
- }
-}
-
-func (t INTERFACE_STATUS) String() string {
- ss := make([]string, 0, 3)
- if t&INTERFACE_ACTIVE > 0 {
- ss = append(ss, "ACTIVE")
- }
- if t&INTERFACE_SUB > 0 {
- ss = append(ss, "SUB")
- }
- if t&INTERFACE_LINKDETECTION > 0 {
- ss = append(ss, "LINKDETECTION")
- }
- if t&INTERFACE_VRF_LOOPBACK > 0 {
- ss = append(ss, "VRF_LOOPBACK")
- }
- return strings.Join(ss, "|")
-}
-
-// Interface Connected Address Flags
-type INTERFACE_ADDRESS_FLAG uint8
-
-const (
- INTERFACE_ADDRESS_SECONDARY INTERFACE_ADDRESS_FLAG = 0x01
- INTERFACE_ADDRESS_PEER INTERFACE_ADDRESS_FLAG = 0x02
- INTERFACE_ADDRESS_UNNUMBERED INTERFACE_ADDRESS_FLAG = 0x04
-)
-
-func (t INTERFACE_ADDRESS_FLAG) String() string {
- ss := make([]string, 0, 3)
- if t&INTERFACE_ADDRESS_SECONDARY > 0 {
- ss = append(ss, "SECONDARY")
- }
- if t&INTERFACE_ADDRESS_PEER > 0 {
- ss = append(ss, "PEER")
- }
- if t&INTERFACE_ADDRESS_UNNUMBERED > 0 {
- ss = append(ss, "UNNUMBERED")
- }
- return strings.Join(ss, "|")
-}
-
-// Address Family Identifier.
-//go:generate stringer -type=AFI
-type AFI uint8
-
-const (
- AFI_IP AFI = 1
- AFI_IP6 AFI = 2
- AFI_ETHER AFI = 3
- AFI_MAX AFI = 4
-)
-
-// Subsequent Address Family Identifier.
-//go:generate stringer -type=SAFI
-type SAFI uint8
-
-const (
- _ SAFI = iota
- SAFI_UNICAST
- SAFI_MULTICAST
- SAFI_RESERVED_3
- SAFI_MPLS_VPN
- SAFI_MAX
-)
-
-// API Types.
-//go:generate stringer -type=API_TYPE
-type API_TYPE uint16
-
-// For Quagga.
-const (
- _ API_TYPE = iota
- INTERFACE_ADD
- INTERFACE_DELETE
- INTERFACE_ADDRESS_ADD
- INTERFACE_ADDRESS_DELETE
- INTERFACE_UP
- INTERFACE_DOWN
- IPV4_ROUTE_ADD
- IPV4_ROUTE_DELETE
- IPV6_ROUTE_ADD
- IPV6_ROUTE_DELETE
- REDISTRIBUTE_ADD
- REDISTRIBUTE_DELETE
- REDISTRIBUTE_DEFAULT_ADD
- REDISTRIBUTE_DEFAULT_DELETE
- IPV4_NEXTHOP_LOOKUP
- IPV6_NEXTHOP_LOOKUP
- IPV4_IMPORT_LOOKUP
- IPV6_IMPORT_LOOKUP
- INTERFACE_RENAME
- ROUTER_ID_ADD
- ROUTER_ID_DELETE
- ROUTER_ID_UPDATE
- HELLO
- IPV4_NEXTHOP_LOOKUP_MRIB
- VRF_UNREGISTER
- INTERFACE_LINK_PARAMS
- NEXTHOP_REGISTER
- NEXTHOP_UNREGISTER
- NEXTHOP_UPDATE
- MESSAGE_MAX
-)
-
-// For FRRouting.
-const (
- FRR_INTERFACE_ADD API_TYPE = iota
- FRR_INTERFACE_DELETE
- FRR_INTERFACE_ADDRESS_ADD
- FRR_INTERFACE_ADDRESS_DELETE
- FRR_INTERFACE_UP
- FRR_INTERFACE_DOWN
- FRR_IPV4_ROUTE_ADD
- FRR_IPV4_ROUTE_DELETE
- FRR_IPV6_ROUTE_ADD
- FRR_IPV6_ROUTE_DELETE
- FRR_REDISTRIBUTE_ADD
- FRR_REDISTRIBUTE_DELETE
- FRR_REDISTRIBUTE_DEFAULT_ADD
- FRR_REDISTRIBUTE_DEFAULT_DELETE
- FRR_ROUTER_ID_ADD
- FRR_ROUTER_ID_DELETE
- FRR_ROUTER_ID_UPDATE
- FRR_HELLO
- FRR_NEXTHOP_REGISTER
- FRR_NEXTHOP_UNREGISTER
- FRR_NEXTHOP_UPDATE
- FRR_INTERFACE_NBR_ADDRESS_ADD
- FRR_INTERFACE_NBR_ADDRESS_DELETE
- FRR_INTERFACE_BFD_DEST_UPDATE
- FRR_IMPORT_ROUTE_REGISTER
- FRR_IMPORT_ROUTE_UNREGISTER
- FRR_IMPORT_CHECK_UPDATE
- FRR_IPV4_ROUTE_IPV6_NEXTHOP_ADD
- FRR_BFD_DEST_REGISTER
- FRR_BFD_DEST_DEREGISTER
- FRR_BFD_DEST_UPDATE
- FRR_BFD_DEST_REPLAY
- FRR_REDISTRIBUTE_IPV4_ADD
- FRR_REDISTRIBUTE_IPV4_DEL
- FRR_REDISTRIBUTE_IPV6_ADD
- FRR_REDISTRIBUTE_IPV6_DEL
- FRR_VRF_UNREGISTER
- FRR_VRF_ADD
- FRR_VRF_DELETE
- FRR_INTERFACE_VRF_UPDATE
- FRR_BFD_CLIENT_REGISTER
- FRR_INTERFACE_ENABLE_RADV
- FRR_INTERFACE_DISABLE_RADV
- FRR_IPV4_NEXTHOP_LOOKUP_MRIB
- FRR_INTERFACE_LINK_PARAMS
- FRR_MPLS_LABELS_ADD
- FRR_MPLS_LABELS_DELETE
- FRR_IPV4_NEXTHOP_ADD
- FRR_IPV4_NEXTHOP_DELETE
- FRR_IPV6_NEXTHOP_ADD
- FRR_IPV6_NEXTHOP_DELETE
- FRR_IPMR_ROUTE_STATS
- FRR_LABEL_MANAGER_CONNECT
- FRR_GET_LABEL_CHUNK
- FRR_RELEASE_LABEL_CHUNK
- FRR_PW_ADD
- FRR_PW_DELETE
- FRR_PW_SET
- FRR_PW_UNSET
- FRR_PW_STATUS_UPDATE
-)
-
-// Route Types.
-//go:generate stringer -type=ROUTE_TYPE
-type ROUTE_TYPE uint8
-
-// For Quagga.
-const (
- ROUTE_SYSTEM ROUTE_TYPE = iota
- ROUTE_KERNEL
- ROUTE_CONNECT
- ROUTE_STATIC
- ROUTE_RIP
- ROUTE_RIPNG
- ROUTE_OSPF
- ROUTE_OSPF6
- ROUTE_ISIS
- ROUTE_BGP
- ROUTE_PIM
- ROUTE_HSLS
- ROUTE_OLSR
- ROUTE_BABEL
- ROUTE_MAX
-)
-
-// For FRRouting.
-const (
- FRR_ROUTE_SYSTEM ROUTE_TYPE = iota
- FRR_ROUTE_KERNEL
- FRR_ROUTE_CONNECT
- FRR_ROUTE_STATIC
- FRR_ROUTE_RIP
- FRR_ROUTE_RIPNG
- FRR_ROUTE_OSPF
- FRR_ROUTE_OSPF6
- FRR_ROUTE_ISIS
- FRR_ROUTE_BGP
- FRR_ROUTE_PIM
- FRR_ROUTE_HSLS
- FRR_ROUTE_OLSR
- FRR_ROUTE_TABLE
- FRR_ROUTE_LDP
- FRR_ROUTE_VNC
- FRR_ROUTE_VNC_DIRECT
- FRR_ROUTE_VNC_DIRECT_RH
- FRR_ROUTE_BGP_DIRECT
- FRR_ROUTE_BGP_DIRECT_EXT
- FRR_ROUTE_ALL
- FRR_ROUTE_MAX
-)
-
-var routeTypeValueMap = map[string]ROUTE_TYPE{
- "system": ROUTE_SYSTEM,
- "kernel": ROUTE_KERNEL,
- "connect": ROUTE_CONNECT, // hack for backyard compatibility
- "directly-connected": ROUTE_CONNECT,
- "static": ROUTE_STATIC,
- "rip": ROUTE_RIP,
- "ripng": ROUTE_RIPNG,
- "ospf": ROUTE_OSPF,
- "ospf3": ROUTE_OSPF6,
- "isis": ROUTE_ISIS,
- "bgp": ROUTE_BGP,
- "pim": ROUTE_PIM,
- "hsls": ROUTE_HSLS,
- "olsr": ROUTE_OLSR,
- "babel": ROUTE_BABEL,
- "table": FRR_ROUTE_TABLE,
- "ldp": FRR_ROUTE_LDP,
- "vnc": FRR_ROUTE_VNC,
- "vnc-direct": FRR_ROUTE_VNC_DIRECT,
- "vnc-direct-rh": FRR_ROUTE_VNC_DIRECT_RH,
- "bgp-direct": FRR_ROUTE_BGP_DIRECT,
- "bgp-direct-ext": FRR_ROUTE_BGP_DIRECT_EXT,
- "all": FRR_ROUTE_ALL,
-}
-
-func RouteTypeFromString(typ string) (ROUTE_TYPE, error) {
- t, ok := routeTypeValueMap[typ]
- if ok {
- return t, nil
- }
- return t, fmt.Errorf("unknown route type: %s", typ)
-}
-
-// API Message Flags.
-type MESSAGE_FLAG uint8
-
-// For Quagga.
-const (
- MESSAGE_NEXTHOP MESSAGE_FLAG = 0x01
- MESSAGE_IFINDEX MESSAGE_FLAG = 0x02
- MESSAGE_DISTANCE MESSAGE_FLAG = 0x04
- MESSAGE_METRIC MESSAGE_FLAG = 0x08
- MESSAGE_MTU MESSAGE_FLAG = 0x10
- MESSAGE_TAG MESSAGE_FLAG = 0x20
-)
-
-func (t MESSAGE_FLAG) String() string {
- var ss []string
- if t&MESSAGE_NEXTHOP > 0 {
- ss = append(ss, "NEXTHOP")
- }
- if t&MESSAGE_IFINDEX > 0 {
- ss = append(ss, "IFINDEX")
- }
- if t&MESSAGE_DISTANCE > 0 {
- ss = append(ss, "DISTANCE")
- }
- if t&MESSAGE_METRIC > 0 {
- ss = append(ss, "METRIC")
- }
- if t&MESSAGE_MTU > 0 {
- ss = append(ss, "MTU")
- }
- if t&MESSAGE_TAG > 0 {
- ss = append(ss, "TAG")
- }
- return strings.Join(ss, "|")
-}
-
-// For FRRouting.
-const (
- FRR_MESSAGE_NEXTHOP MESSAGE_FLAG = 0x01
- FRR_MESSAGE_IFINDEX MESSAGE_FLAG = 0x02
- FRR_MESSAGE_DISTANCE MESSAGE_FLAG = 0x04
- FRR_MESSAGE_METRIC MESSAGE_FLAG = 0x08
- FRR_MESSAGE_TAG MESSAGE_FLAG = 0x10
- FRR_MESSAGE_MTU MESSAGE_FLAG = 0x20
- FRR_MESSAGE_SRCPFX MESSAGE_FLAG = 0x40
-)
-
-// Message Flags
-type FLAG uint64
-
-const (
- FLAG_INTERNAL FLAG = 0x01
- FLAG_SELFROUTE FLAG = 0x02
- FLAG_BLACKHOLE FLAG = 0x04
- FLAG_IBGP FLAG = 0x08
- FLAG_SELECTED FLAG = 0x10
- FLAG_CHANGED FLAG = 0x20
- FLAG_STATIC FLAG = 0x40
- FLAG_REJECT FLAG = 0x80
- FLAG_SCOPE_LINK FLAG = 0x100
- FLAG_FIB_OVERRIDE FLAG = 0x200
-)
-
-func (t FLAG) String() string {
- var ss []string
- if t&FLAG_INTERNAL > 0 {
- ss = append(ss, "FLAG_INTERNAL")
- }
- if t&FLAG_SELFROUTE > 0 {
- ss = append(ss, "FLAG_SELFROUTE")
- }
- if t&FLAG_BLACKHOLE > 0 {
- ss = append(ss, "FLAG_BLACKHOLE")
- }
- if t&FLAG_IBGP > 0 {
- ss = append(ss, "FLAG_IBGP")
- }
- if t&FLAG_SELECTED > 0 {
- ss = append(ss, "FLAG_SELECTED")
- }
- if t&FLAG_CHANGED > 0 {
- ss = append(ss, "FLAG_CHANGED")
- }
- if t&FLAG_STATIC > 0 {
- ss = append(ss, "FLAG_STATIC")
- }
- if t&FLAG_REJECT > 0 {
- ss = append(ss, "FLAG_REJECT")
- }
- if t&FLAG_SCOPE_LINK > 0 {
- ss = append(ss, "FLAG_SCOPE_LINK")
- }
- if t&FLAG_FIB_OVERRIDE > 0 {
- ss = append(ss, "FLAG_FIB_OVERRIDE")
- }
- return strings.Join(ss, "|")
-}
-
-// Nexthop Flags.
-//go:generate stringer -type=NEXTHOP_FLAG
-type NEXTHOP_FLAG uint8
-
-// For Quagga.
-const (
- _ NEXTHOP_FLAG = iota
- NEXTHOP_IFINDEX
- NEXTHOP_IFNAME
- NEXTHOP_IPV4
- NEXTHOP_IPV4_IFINDEX
- NEXTHOP_IPV4_IFNAME
- NEXTHOP_IPV6
- NEXTHOP_IPV6_IFINDEX
- NEXTHOP_IPV6_IFNAME
- NEXTHOP_BLACKHOLE
-)
-
-// For FRRouting.
-const (
- _ NEXTHOP_FLAG = iota
- FRR_NEXTHOP_IFINDEX
- FRR_NEXTHOP_IPV4
- FRR_NEXTHOP_IPV4_IFINDEX
- FRR_NEXTHOP_IPV6
- FRR_NEXTHOP_IPV6_IFINDEX
- FRR_NEXTHOP_BLACKHOLE
-)
-
-// Interface PTM Enable Configuration.
-//go:generate stringer -type=PTM_ENABLE
-type PTM_ENABLE uint8
-
-const (
- PTM_ENABLE_OFF PTM_ENABLE = 0
- PTM_ENABLE_ON PTM_ENABLE = 1
- PTM_ENABLE_UNSPEC PTM_ENABLE = 2
-)
-
-// PTM Status.
-//go:generate stringer -type=PTM_STATUS
-type PTM_STATUS uint8
-
-const (
- PTM_STATUS_DOWN PTM_STATUS = 0
- PTM_STATUS_UP PTM_STATUS = 1
- PTM_STATUS_UNKNOWN PTM_STATUS = 2
-)
-
-type Client struct {
- outgoing chan *Message
- incoming chan *Message
- redistDefault ROUTE_TYPE
- conn net.Conn
- Version uint8
-}
-
-func NewClient(network, address string, typ ROUTE_TYPE, version uint8) (*Client, error) {
- conn, err := net.Dial(network, address)
- if err != nil {
- return nil, err
- }
- outgoing := make(chan *Message)
- incoming := make(chan *Message, 64)
- if version < 2 {
- version = 2
- } else if version > 4 {
- version = 4
- }
-
- c := &Client{
- outgoing: outgoing,
- incoming: incoming,
- redistDefault: typ,
- conn: conn,
- Version: version,
- }
-
- go func() {
- for {
- m, more := <-outgoing
- if more {
- b, err := m.Serialize()
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- }).Warnf("failed to serialize: %v", m)
- continue
- }
-
- _, err = conn.Write(b)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- }).Errorf("failed to write: %s", err)
- close(outgoing)
- }
- } else {
- log.Debug("finish outgoing loop")
- return
- }
- }
- }()
-
- // Send HELLO/ROUTER_ID_ADD messages to negotiate the Zebra message version.
- c.SendHello()
- c.SendRouterIDAdd()
-
- receiveSingleMsg := func() (*Message, error) {
- headerBuf, err := readAll(conn, int(HeaderSize(version)))
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- "Error": err,
- }).Error("failed to read header")
- return nil, err
- }
-
- hd := &Header{}
- err = hd.DecodeFromBytes(headerBuf)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- "Data": headerBuf,
- "Error": err,
- }).Error("failed to decode header")
- return nil, err
- }
-
- bodyBuf, err := readAll(conn, int(hd.Len-HeaderSize(version)))
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- "Header": hd,
- "Error": err,
- }).Error("failed to read body")
- return nil, err
- }
-
- m, err := ParseMessage(hd, bodyBuf)
- if err != nil {
- // Just outputting warnings (not error message) and ignore this
- // error considering the case that body parser is not implemented
- // yet.
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- "Header": hd,
- "Data": bodyBuf,
- "Error": err,
- }).Warn("failed to decode body")
- return nil, nil
- }
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- "Message": m,
- }).Debug("read message from zebra")
-
- return m, nil
- }
-
- // Try to receive the first message from Zebra.
- if m, err := receiveSingleMsg(); err != nil {
- c.Close()
- // Return error explicitly in order to retry connection.
- return nil, err
- } else if m != nil {
- incoming <- m
- }
-
- // Start receive loop only when the first message successfully received.
- go func() {
- defer close(incoming)
- for {
- if m, err := receiveSingleMsg(); err != nil {
- return
- } else if m != nil {
- incoming <- m
- }
- }
- }()
-
- return c, nil
-}
-
-func readAll(conn net.Conn, length int) ([]byte, error) {
- buf := make([]byte, length)
- _, err := io.ReadFull(conn, buf)
- return buf, err
-}
-
-func (c *Client) Receive() chan *Message {
- return c.incoming
-}
-
-func (c *Client) Send(m *Message) {
- defer func() {
- if err := recover(); err != nil {
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- }).Debugf("recovered: %s", err)
- }
- }()
- log.WithFields(log.Fields{
- "Topic": "Zebra",
- "Header": m.Header,
- "Body": m.Body,
- }).Debug("send command to zebra")
- c.outgoing <- m
-}
-
-func (c *Client) SendCommand(command API_TYPE, vrfId uint16, body Body) error {
- var marker uint8 = HEADER_MARKER
- if c.Version >= 4 {
- marker = FRR_HEADER_MARKER
- }
- m := &Message{
- Header: Header{
- Len: HeaderSize(c.Version),
- Marker: marker,
- Version: c.Version,
- VrfId: vrfId,
- Command: command,
- },
- Body: body,
- }
- c.Send(m)
- return nil
-}
-
-func (c *Client) SendHello() error {
- if c.redistDefault > 0 {
- command := HELLO
- body := &HelloBody{
- RedistDefault: c.redistDefault,
- Instance: 0,
- }
- if c.Version >= 4 {
- command = FRR_HELLO
- }
- return c.SendCommand(command, VRF_DEFAULT, body)
- }
- return nil
-}
-
-func (c *Client) SendRouterIDAdd() error {
- command := ROUTER_ID_ADD
- if c.Version >= 4 {
- command = FRR_ROUTER_ID_ADD
- }
- return c.SendCommand(command, VRF_DEFAULT, nil)
-}
-
-func (c *Client) SendInterfaceAdd() error {
- command := INTERFACE_ADD
- if c.Version >= 4 {
- command = FRR_INTERFACE_ADD
- }
- return c.SendCommand(command, VRF_DEFAULT, nil)
-}
-
-func (c *Client) SendRedistribute(t ROUTE_TYPE, vrfId uint16) error {
- command := REDISTRIBUTE_ADD
- if c.redistDefault != t {
- bodies := make([]*RedistributeBody, 0)
- if c.Version <= 3 {
- bodies = append(bodies, &RedistributeBody{
- Redist: t,
- })
- } else { // version >= 4
- command = FRR_REDISTRIBUTE_ADD
- for _, afi := range []AFI{AFI_IP, AFI_IP6} {
- bodies = append(bodies, &RedistributeBody{
- Afi: afi,
- Redist: t,
- Instance: 0,
- })
- }
- }
-
- for _, body := range bodies {
- return c.SendCommand(command, vrfId, body)
- }
- }
-
- return nil
-}
-
-func (c *Client) SendRedistributeDelete(t ROUTE_TYPE) error {
- if t < ROUTE_MAX {
- command := REDISTRIBUTE_DELETE
- if c.Version >= 4 {
- command = FRR_REDISTRIBUTE_DELETE
- }
- body := &RedistributeBody{
- Redist: t,
- }
- return c.SendCommand(command, VRF_DEFAULT, body)
- } else {
- return fmt.Errorf("unknown route type: %d", t)
- }
-}
-
-func (c *Client) SendIPRoute(vrfId uint16, body *IPRouteBody, isWithdraw bool) error {
- command := IPV4_ROUTE_ADD
- if c.Version <= 3 {
- if body.Prefix.To4() != nil {
- if isWithdraw {
- command = IPV4_ROUTE_DELETE
- }
- } else {
- if isWithdraw {
- command = IPV6_ROUTE_DELETE
- } else {
- command = IPV6_ROUTE_ADD
- }
- }
- } else { // version >= 4
- if body.Prefix.To4() != nil {
- if isWithdraw {
- command = FRR_IPV4_ROUTE_DELETE
- } else {
- command = FRR_IPV4_ROUTE_ADD
- }
- } else {
- if isWithdraw {
- command = FRR_IPV6_ROUTE_DELETE
- } else {
- command = FRR_IPV6_ROUTE_ADD
- }
- }
- }
- return c.SendCommand(command, vrfId, body)
-}
-
-func (c *Client) SendNexthopRegister(vrfId uint16, body *NexthopRegisterBody, isWithdraw bool) error {
- // Note: NEXTHOP_REGISTER and NEXTHOP_UNREGISTER messages are not
- // supported in Zebra protocol version<3.
- if c.Version < 3 {
- return fmt.Errorf("NEXTHOP_REGISTER/NEXTHOP_UNREGISTER are not supported in version: %d", c.Version)
- }
- command := NEXTHOP_REGISTER
- if c.Version == 3 {
- if isWithdraw {
- command = NEXTHOP_UNREGISTER
- }
- } else { // version >= 4
- if isWithdraw {
- command = FRR_NEXTHOP_UNREGISTER
- } else {
- command = FRR_NEXTHOP_REGISTER
- }
- }
- return c.SendCommand(command, vrfId, body)
-}
-
-func (c *Client) Close() error {
- close(c.outgoing)
- return c.conn.Close()
-}
-
-type Header struct {
- Len uint16
- Marker uint8
- Version uint8
- VrfId uint16
- Command API_TYPE
-}
-
-func (h *Header) Serialize() ([]byte, error) {
- buf := make([]byte, HeaderSize(h.Version))
- binary.BigEndian.PutUint16(buf[0:2], h.Len)
- buf[2] = h.Marker
- buf[3] = h.Version
- switch h.Version {
- case 2:
- binary.BigEndian.PutUint16(buf[4:6], uint16(h.Command))
- case 3, 4:
- binary.BigEndian.PutUint16(buf[4:6], uint16(h.VrfId))
- binary.BigEndian.PutUint16(buf[6:8], uint16(h.Command))
- default:
- return nil, fmt.Errorf("Unsupported ZAPI version: %d", h.Version)
- }
- return buf, nil
-}
-
-func (h *Header) DecodeFromBytes(data []byte) error {
- if uint16(len(data)) < 4 {
- return fmt.Errorf("Not all ZAPI message header")
- }
- h.Len = binary.BigEndian.Uint16(data[0:2])
- h.Marker = data[2]
- h.Version = data[3]
- if uint16(len(data)) < HeaderSize(h.Version) {
- return fmt.Errorf("Not all ZAPI message header")
- }
- switch h.Version {
- case 2:
- h.Command = API_TYPE(binary.BigEndian.Uint16(data[4:6]))
- case 3, 4:
- h.VrfId = binary.BigEndian.Uint16(data[4:6])
- h.Command = API_TYPE(binary.BigEndian.Uint16(data[6:8]))
- default:
- return fmt.Errorf("Unsupported ZAPI version: %d", h.Version)
- }
- return nil
-}
-
-type Body interface {
- DecodeFromBytes([]byte, uint8) error
- Serialize(uint8) ([]byte, error)
- String() string
-}
-
-type UnknownBody struct {
- Data []byte
-}
-
-func (b *UnknownBody) DecodeFromBytes(data []byte, version uint8) error {
- b.Data = data
- return nil
-}
-
-func (b *UnknownBody) Serialize(version uint8) ([]byte, error) {
- return b.Data, nil
-}
-
-func (b *UnknownBody) String() string {
- return fmt.Sprintf("data: %v", b.Data)
-}
-
-type HelloBody struct {
- RedistDefault ROUTE_TYPE
- Instance uint16
-}
-
-func (b *HelloBody) DecodeFromBytes(data []byte, version uint8) error {
- b.RedistDefault = ROUTE_TYPE(data[0])
- if version >= 4 {
- b.Instance = binary.BigEndian.Uint16(data[1:3])
- }
- return nil
-}
-
-func (b *HelloBody) Serialize(version uint8) ([]byte, error) {
- if version <= 3 {
- return []byte{uint8(b.RedistDefault)}, nil
- } else { // version >= 4
- buf := make([]byte, 3)
- buf[0] = uint8(b.RedistDefault)
- binary.BigEndian.PutUint16(buf[1:3], b.Instance)
- return buf, nil
-
- }
-}
-
-func (b *HelloBody) String() string {
- return fmt.Sprintf(
- "route_type: %s, instance :%d",
- b.RedistDefault.String(), b.Instance)
-}
-
-type RedistributeBody struct {
- Afi AFI
- Redist ROUTE_TYPE
- Instance uint16
-}
-
-func (b *RedistributeBody) DecodeFromBytes(data []byte, version uint8) error {
- if version <= 3 {
- b.Redist = ROUTE_TYPE(data[0])
- } else { // version >= 4
- b.Afi = AFI(data[0])
- b.Redist = ROUTE_TYPE(data[1])
- b.Instance = binary.BigEndian.Uint16(data[2:4])
- }
- return nil
-}
-
-func (b *RedistributeBody) Serialize(version uint8) ([]byte, error) {
- if version <= 3 {
- return []byte{uint8(b.Redist)}, nil
- } else { // version >= 4
- buf := make([]byte, 4)
- buf[0] = uint8(b.Afi)
- buf[1] = uint8(b.Redist)
- binary.BigEndian.PutUint16(buf[2:4], b.Instance)
- return buf, nil
- }
-}
-
-func (b *RedistributeBody) String() string {
- return fmt.Sprintf(
- "afi: %s, route_type: %s, instance :%d",
- b.Afi.String(), b.Redist.String(), b.Instance)
-}
-
-type InterfaceUpdateBody struct {
- Name string
- Index uint32
- Status INTERFACE_STATUS
- Flags uint64
- PTMEnable PTM_ENABLE
- PTMStatus PTM_STATUS
- Metric uint32
- Speed uint32
- MTU uint32
- MTU6 uint32
- Bandwidth uint32
- Linktype LINK_TYPE
- HardwareAddr net.HardwareAddr
-}
-
-func (b *InterfaceUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
- if len(data) < INTERFACE_NAMSIZ+29 {
- return fmt.Errorf("lack of bytes. need %d but %d", INTERFACE_NAMSIZ+29, len(data))
- }
-
- b.Name = strings.Trim(string(data[:INTERFACE_NAMSIZ]), "\u0000")
- data = data[INTERFACE_NAMSIZ:]
- b.Index = binary.BigEndian.Uint32(data[0:4])
- b.Status = INTERFACE_STATUS(data[4])
- b.Flags = binary.BigEndian.Uint64(data[5:13])
- if version >= 4 {
- b.PTMEnable = PTM_ENABLE(data[13])
- b.PTMStatus = PTM_STATUS(data[14])
- b.Metric = binary.BigEndian.Uint32(data[15:19])
- b.Speed = binary.BigEndian.Uint32(data[19:23])
- data = data[23:]
- } else {
- b.Metric = binary.BigEndian.Uint32(data[13:17])
- data = data[17:]
- }
- b.MTU = binary.BigEndian.Uint32(data[0:4])
- b.MTU6 = binary.BigEndian.Uint32(data[4:8])
- b.Bandwidth = binary.BigEndian.Uint32(data[8:12])
- if version >= 3 {
- b.Linktype = LINK_TYPE(binary.BigEndian.Uint32(data[12:16]))
- data = data[16:]
- } else {
- data = data[12:]
- }
- l := binary.BigEndian.Uint32(data[:4])
- if l > 0 {
- if len(data) < 4+int(l) {
- return fmt.Errorf("lack of bytes. need %d but %d", 4+l, len(data))
- }
- b.HardwareAddr = data[4 : 4+l]
- }
- return nil
-}
-
-func (b *InterfaceUpdateBody) Serialize(version uint8) ([]byte, error) {
- return []byte{}, nil
-}
-
-func (b *InterfaceUpdateBody) String() string {
- s := fmt.Sprintf(
- "name: %s, idx: %d, status: %s, flags: %s, ptm_enable: %s, ptm_status: %s, metric: %d, speed: %d, mtu: %d, mtu6: %d, bandwidth: %d, linktype: %s",
- b.Name, b.Index, b.Status.String(), intfflag2string(b.Flags), b.PTMEnable.String(), b.PTMStatus.String(), b.Metric, b.Speed, b.MTU, b.MTU6, b.Bandwidth, b.Linktype.String())
- if len(b.HardwareAddr) > 0 {
- return s + fmt.Sprintf(", mac: %s", b.HardwareAddr.String())
- }
- return s
-}
-
-type InterfaceAddressUpdateBody struct {
- Index uint32
- Flags INTERFACE_ADDRESS_FLAG
- Prefix net.IP
- Length uint8
- Destination net.IP
-}
-
-func (b *InterfaceAddressUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
- b.Index = binary.BigEndian.Uint32(data[:4])
- b.Flags = INTERFACE_ADDRESS_FLAG(data[4])
- family := data[5]
- var addrlen int8
- switch family {
- case syscall.AF_INET:
- addrlen = net.IPv4len
- case syscall.AF_INET6:
- addrlen = net.IPv6len
- default:
- return fmt.Errorf("unknown address family: %d", family)
- }
- b.Prefix = data[6 : 6+addrlen]
- b.Length = data[6+addrlen]
- b.Destination = data[7+addrlen : 7+addrlen*2]
- return nil
-}
-
-func (b *InterfaceAddressUpdateBody) Serialize(version uint8) ([]byte, error) {
- return []byte{}, nil
-}
-
-func (b *InterfaceAddressUpdateBody) String() string {
- return fmt.Sprintf(
- "idx: %d, flags: %s, addr: %s/%d",
- b.Index, b.Flags.String(), b.Prefix.String(), b.Length)
-}
-
-type RouterIDUpdateBody struct {
- Length uint8
- Prefix net.IP
-}
-
-func (b *RouterIDUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
- family := data[0]
- var addrlen int8
- switch family {
- case syscall.AF_INET:
- addrlen = net.IPv4len
- case syscall.AF_INET6:
- addrlen = net.IPv6len
- default:
- return fmt.Errorf("unknown address family: %d", family)
- }
- b.Prefix = data[1 : 1+addrlen]
- b.Length = data[1+addrlen]
- return nil
-}
-
-func (b *RouterIDUpdateBody) Serialize(version uint8) ([]byte, error) {
- return []byte{}, nil
-}
-
-func (b *RouterIDUpdateBody) String() string {
- return fmt.Sprintf("id: %s/%d", b.Prefix.String(), b.Length)
-}
-
-type IPRouteBody struct {
- Type ROUTE_TYPE
- Instance uint16
- Flags FLAG
- Message MESSAGE_FLAG
- SAFI SAFI
- Prefix net.IP
- PrefixLength uint8
- SrcPrefix net.IP
- SrcPrefixLength uint8
- Nexthops []net.IP
- Ifindexs []uint32
- Distance uint8
- Metric uint32
- Mtu uint32
- Tag uint32
- Api API_TYPE
-}
-
-func (b *IPRouteBody) RouteFamily() bgp.RouteFamily {
- switch b.Api {
- case IPV4_ROUTE_ADD, IPV4_ROUTE_DELETE, FRR_REDISTRIBUTE_IPV4_ADD, FRR_REDISTRIBUTE_IPV4_DEL:
- return bgp.RF_IPv4_UC
- case IPV6_ROUTE_ADD, IPV6_ROUTE_DELETE, FRR_REDISTRIBUTE_IPV6_ADD, FRR_REDISTRIBUTE_IPV6_DEL:
- return bgp.RF_IPv6_UC
- default:
- return bgp.RF_OPAQUE
- }
-}
-
-func (b *IPRouteBody) IsWithdraw() bool {
- switch b.Api {
- case IPV4_ROUTE_DELETE, FRR_REDISTRIBUTE_IPV4_DEL, IPV6_ROUTE_DELETE, FRR_REDISTRIBUTE_IPV6_DEL:
- return true
- default:
- return false
- }
-}
-
-func (b *IPRouteBody) Serialize(version uint8) ([]byte, error) {
-
- var buf []byte
- nhfIPv4 := uint8(NEXTHOP_IPV4)
- nhfIPv6 := uint8(NEXTHOP_IPV6)
- nhfIndx := uint8(NEXTHOP_IFINDEX)
- nhfBlkH := uint8(NEXTHOP_BLACKHOLE)
- if version <= 3 {
- buf = make([]byte, 5)
- buf[0] = uint8(b.Type)
- buf[1] = uint8(b.Flags)
- buf[2] = uint8(b.Message)
- binary.BigEndian.PutUint16(buf[3:5], uint16(b.SAFI))
- } else { // version >= 4
- buf = make([]byte, 10)
- buf[0] = uint8(b.Type)
- binary.BigEndian.PutUint16(buf[1:3], uint16(b.Instance))
- binary.BigEndian.PutUint32(buf[3:7], uint32(b.Flags))
- buf[7] = uint8(b.Message)
- binary.BigEndian.PutUint16(buf[8:10], uint16(b.SAFI))
- nhfIPv4 = uint8(FRR_NEXTHOP_IPV4)
- nhfIPv6 = uint8(FRR_NEXTHOP_IPV6)
- nhfIndx = uint8(FRR_NEXTHOP_IFINDEX)
- nhfBlkH = uint8(FRR_NEXTHOP_BLACKHOLE)
- }
- byteLen := (int(b.PrefixLength) + 7) / 8
- buf = append(buf, b.PrefixLength)
- buf = append(buf, b.Prefix[:byteLen]...)
- if b.Message&FRR_MESSAGE_SRCPFX > 0 {
- byteLen = (int(b.SrcPrefixLength) + 7) / 8
- buf = append(buf, b.SrcPrefixLength)
- buf = append(buf, b.SrcPrefix[:byteLen]...)
- }
-
- if b.Message&MESSAGE_NEXTHOP > 0 {
- if b.Flags&FLAG_BLACKHOLE > 0 {
- buf = append(buf, []byte{1, nhfBlkH}...)
- } else {
- buf = append(buf, uint8(len(b.Nexthops)+len(b.Ifindexs)))
- }
-
- for _, v := range b.Nexthops {
- if v.To4() != nil {
- buf = append(buf, nhfIPv4)
- buf = append(buf, v.To4()...)
- } else {
- buf = append(buf, nhfIPv6)
- buf = append(buf, v.To16()...)
- }
- }
-
- for _, v := range b.Ifindexs {
- buf = append(buf, nhfIndx)
- bbuf := make([]byte, 4)
- binary.BigEndian.PutUint32(bbuf, v)
- buf = append(buf, bbuf...)
- }
- }
-
- if b.Message&MESSAGE_DISTANCE > 0 {
- buf = append(buf, b.Distance)
- }
- if b.Message&MESSAGE_METRIC > 0 {
- bbuf := make([]byte, 4)
- binary.BigEndian.PutUint32(bbuf, b.Metric)
- buf = append(buf, bbuf...)
- }
- if version <= 3 {
- if b.Message&MESSAGE_MTU > 0 {
- bbuf := make([]byte, 4)
- binary.BigEndian.PutUint32(bbuf, b.Mtu)
- buf = append(buf, bbuf...)
- }
- if b.Message&MESSAGE_TAG > 0 {
- bbuf := make([]byte, 4)
- binary.BigEndian.PutUint32(bbuf, b.Tag)
- buf = append(buf, bbuf...)
- }
- } else { // version >= 4
- if b.Message&FRR_MESSAGE_TAG > 0 {
- bbuf := make([]byte, 4)
- binary.BigEndian.PutUint32(bbuf, b.Tag)
- buf = append(buf, bbuf...)
- }
- if b.Message&FRR_MESSAGE_MTU > 0 {
- bbuf := make([]byte, 4)
- binary.BigEndian.PutUint32(bbuf, b.Mtu)
- buf = append(buf, bbuf...)
- }
- }
- return buf, nil
-}
-
-func (b *IPRouteBody) DecodeFromBytes(data []byte, version uint8) error {
- isV4 := true
- if version <= 3 {
- isV4 = b.Api == IPV4_ROUTE_ADD || b.Api == IPV4_ROUTE_DELETE
- } else {
- isV4 = b.Api == FRR_REDISTRIBUTE_IPV4_ADD || b.Api == FRR_REDISTRIBUTE_IPV4_DEL
- }
- var addrLen uint8 = net.IPv4len
- if !isV4 {
- addrLen = net.IPv6len
- }
-
- b.Type = ROUTE_TYPE(data[0])
- if version <= 3 {
- b.Flags = FLAG(data[1])
- data = data[2:]
- } else { // version >= 4
- b.Instance = binary.BigEndian.Uint16(data[1:3])
- b.Flags = FLAG(binary.BigEndian.Uint32(data[3:7]))
- data = data[7:]
- }
-
- b.Message = MESSAGE_FLAG(data[0])
- b.SAFI = SAFI(SAFI_UNICAST)
-
- b.PrefixLength = data[1]
- if b.PrefixLength > addrLen*8 {
- return fmt.Errorf("prefix length is greater than %d", addrLen*8)
- }
- pos := 2
- buf := make([]byte, addrLen)
- byteLen := int((b.PrefixLength + 7) / 8)
- copy(buf, data[pos:pos+byteLen])
- if isV4 {
- b.Prefix = net.IP(buf).To4()
- } else {
- b.Prefix = net.IP(buf).To16()
- }
- pos += byteLen
-
- if b.Message&FRR_MESSAGE_SRCPFX > 0 {
- b.SrcPrefixLength = data[pos]
- pos += 1
- buf = make([]byte, addrLen)
- byteLen = int((b.SrcPrefixLength + 7) / 8)
- copy(buf, data[pos:pos+byteLen])
- if isV4 {
- b.SrcPrefix = net.IP(buf).To4()
- } else {
- b.SrcPrefix = net.IP(buf).To16()
- }
- pos += byteLen
- }
-
- rest := 0
- var numNexthop int
- if b.Message&MESSAGE_NEXTHOP > 0 {
- numNexthop = int(data[pos])
- // rest = numNexthop(1) + (nexthop(4 or 16) + placeholder(1) + ifindex(4)) * numNexthop
- rest += 1 + numNexthop*(int(addrLen)+5)
- }
- if b.Message&MESSAGE_DISTANCE > 0 {
- // distance(1)
- rest += 1
- }
- if b.Message&MESSAGE_METRIC > 0 {
- // metric(4)
- rest += 4
- }
- if version <= 3 {
- if b.Message&MESSAGE_MTU > 0 {
- // mtu(4)
- rest += 4
- }
- if b.Message&MESSAGE_TAG > 0 {
- // tag(4)
- rest += 4
- }
- } else { // version >= 4
- if b.Message&FRR_MESSAGE_TAG > 0 {
- // tag(4)
- rest += 4
- }
- if b.Message&FRR_MESSAGE_MTU > 0 {
- // mtu(4)
- rest += 4
- }
- }
-
- if len(data[pos:]) != rest {
- return fmt.Errorf("message length invalid")
- }
-
- b.Nexthops = []net.IP{}
- b.Ifindexs = []uint32{}
-
- if b.Message&MESSAGE_NEXTHOP > 0 {
- pos += 1
- for i := 0; i < numNexthop; i++ {
- addr := data[pos : pos+int(addrLen)]
- var nexthop net.IP
- if isV4 {
- nexthop = net.IP(addr).To4()
- } else {
- nexthop = net.IP(addr).To16()
- }
- b.Nexthops = append(b.Nexthops, nexthop)
-
- // skip nexthop and 1byte place holder
- pos += int(addrLen + 1)
- ifidx := binary.BigEndian.Uint32(data[pos : pos+4])
- b.Ifindexs = append(b.Ifindexs, ifidx)
- pos += 4
- }
- }
-
- if b.Message&MESSAGE_DISTANCE > 0 {
- b.Distance = data[pos]
- pos += 1
- }
- if b.Message&MESSAGE_METRIC > 0 {
- b.Metric = binary.BigEndian.Uint32(data[pos : pos+4])
- pos += 4
- }
- if version <= 3 {
- if b.Message&MESSAGE_MTU > 0 {
- b.Mtu = binary.BigEndian.Uint32(data[pos : pos+4])
- pos += 4
- }
- if b.Message&MESSAGE_TAG > 0 {
- b.Tag = binary.BigEndian.Uint32(data[pos : pos+4])
- pos += 4
- }
- } else {
- if b.Message&FRR_MESSAGE_TAG > 0 {
- b.Tag = binary.BigEndian.Uint32(data[pos : pos+4])
- pos += 4
- }
- if b.Message&FRR_MESSAGE_MTU > 0 {
- b.Mtu = binary.BigEndian.Uint32(data[pos : pos+4])
- pos += 4
- }
- }
-
- return nil
-}
-
-func (b *IPRouteBody) String() string {
- s := fmt.Sprintf(
- "type: %s, instance: %d, flags: %s, message: %d, safi: %s, prefix: %s/%d, src_prefix: %s/%d",
- b.Type.String(), b.Instance, b.Flags.String(), b.Message, b.SAFI.String(), b.Prefix.String(), b.PrefixLength, b.SrcPrefix.String(), b.SrcPrefixLength)
- for i, nh := range b.Nexthops {
- s += fmt.Sprintf(", nexthops[%d]: %s", i, nh.String())
- }
- for i, idx := range b.Ifindexs {
- s += fmt.Sprintf(", ifindex[%d]: %d", i, idx)
- }
- return s + fmt.Sprintf(
- ", distance: %d, metric: %d, mtu: %d, tag: %d",
- b.Distance, b.Metric, b.Mtu, b.Tag)
-}
-
-type NexthopLookupBody struct {
- Api API_TYPE
- Addr net.IP
- Distance uint8
- Metric uint32
- Nexthops []*Nexthop
-}
-
-type Nexthop struct {
- Ifname string
- Ifindex uint32
- Type NEXTHOP_FLAG
- Addr net.IP
-}
-
-func (n *Nexthop) String() string {
- s := fmt.Sprintf(
- "type: %s, addr: %s, ifindex: %d, ifname: %s",
- n.Type.String(), n.Addr.String(), n.Ifindex, n.Ifname)
- return s
-}
-
-func decodeNexthopsFromBytes(nexthops *[]*Nexthop, data []byte, isV4 bool, version uint8) (int, error) {
- addrLen := net.IPv4len
- if !isV4 {
- addrLen = net.IPv6len
- }
- nhIfindex := NEXTHOP_IFINDEX
- nhIfname := NEXTHOP_IFNAME
- nhIPv4 := NEXTHOP_IPV4
- nhIPv4Ifindex := NEXTHOP_IPV4_IFINDEX
- nhIPv4Ifname := NEXTHOP_IPV4_IFNAME
- nhIPv6 := NEXTHOP_IPV6
- nhIPv6Ifindex := NEXTHOP_IPV6_IFINDEX
- nhIPv6Ifname := NEXTHOP_IPV6_IFNAME
- if version >= 4 {
- nhIfindex = FRR_NEXTHOP_IFINDEX
- nhIfname = NEXTHOP_FLAG(0)
- nhIPv4 = FRR_NEXTHOP_IPV4
- nhIPv4Ifindex = FRR_NEXTHOP_IPV4_IFINDEX
- nhIPv4Ifname = NEXTHOP_FLAG(0)
- nhIPv6 = FRR_NEXTHOP_IPV6
- nhIPv6Ifindex = FRR_NEXTHOP_IPV6_IFINDEX
- nhIPv6Ifname = NEXTHOP_FLAG(0)
- }
-
- numNexthop := int(data[0])
- offset := 1
-
- for i := 0; i < numNexthop; i++ {
- nh := &Nexthop{}
- nh.Type = NEXTHOP_FLAG(data[offset])
- offset += 1
-
- switch nh.Type {
- case nhIfindex, nhIfname:
- nh.Ifindex = binary.BigEndian.Uint32(data[offset : offset+4])
- offset += 4
-
- case nhIPv4, nhIPv6:
- if isV4 {
- nh.Addr = net.IP(data[offset : offset+addrLen]).To4()
- } else {
- nh.Addr = net.IP(data[offset : offset+addrLen]).To16()
- }
- offset += addrLen
- if version >= 4 {
- // On FRRouting version 3.0 or later, NEXTHOP_IPV4 and
- // NEXTHOP_IPV6 have the same structure with
- // NEXTHOP_TYPE_IPV4_IFINDEX and NEXTHOP_TYPE_IPV6_IFINDEX.
- nh.Ifindex = binary.BigEndian.Uint32(data[offset : offset+4])
- offset += 4
- }
-
- case nhIPv4Ifindex, nhIPv4Ifname, nhIPv6Ifindex, nhIPv6Ifname:
- if isV4 {
- nh.Addr = net.IP(data[offset : offset+addrLen]).To4()
- } else {
- nh.Addr = net.IP(data[offset : offset+addrLen]).To16()
- }
- offset += addrLen
- nh.Ifindex = binary.BigEndian.Uint32(data[offset : offset+4])
- offset += 4
- }
- *nexthops = append(*nexthops, nh)
- }
-
- return offset, nil
-}
-
-func (b *NexthopLookupBody) Serialize(version uint8) ([]byte, error) {
- isV4 := false
- if version <= 3 {
- isV4 = b.Api == IPV4_NEXTHOP_LOOKUP
- } else { // version >= 4
- isV4 = b.Api == FRR_IPV4_NEXTHOP_LOOKUP_MRIB
- }
-
- buf := make([]byte, 0)
-
- if isV4 {
- buf = append(buf, b.Addr.To4()...)
- } else {
- buf = append(buf, b.Addr.To16()...)
- }
- return buf, nil
-}
-
-func (b *NexthopLookupBody) DecodeFromBytes(data []byte, version uint8) error {
- isV4 := false
- if version <= 3 {
- isV4 = b.Api == IPV4_NEXTHOP_LOOKUP
- } else { // version >= 4
- isV4 = b.Api == FRR_IPV4_NEXTHOP_LOOKUP_MRIB
- }
- addrLen := net.IPv4len
- if !isV4 {
- addrLen = net.IPv6len
- }
-
- if len(data) < addrLen {
- return fmt.Errorf("message length invalid")
- }
-
- buf := make([]byte, addrLen)
- copy(buf, data[0:addrLen])
- pos := addrLen
-
- if isV4 {
- b.Addr = net.IP(buf).To4()
- } else {
- b.Addr = net.IP(buf).To16()
- }
-
- if version >= 4 {
- b.Distance = data[pos]
- pos++
- }
-
- if len(data[pos:]) > int(1+addrLen) {
- b.Metric = binary.BigEndian.Uint32(data[pos : pos+4])
- pos += 4
- b.Nexthops = []*Nexthop{}
- if nexthopsByteLen, err := decodeNexthopsFromBytes(&b.Nexthops, data[pos:], isV4, version); err != nil {
- return err
- } else {
- pos += nexthopsByteLen
- }
- }
-
- return nil
-}
-
-func (b *NexthopLookupBody) String() string {
- s := fmt.Sprintf(
- "addr: %s, distance:%d, metric: %d",
- b.Addr.String(), b.Distance, b.Metric)
- if len(b.Nexthops) > 0 {
- for _, nh := range b.Nexthops {
- s = s + fmt.Sprintf(", nexthop:{%s}", nh.String())
- }
- }
- return s
-}
-
-type ImportLookupBody struct {
- Api API_TYPE
- PrefixLength uint8
- Prefix net.IP
- Addr net.IP
- Metric uint32
- Nexthops []*Nexthop
-}
-
-func (b *ImportLookupBody) Serialize(version uint8) ([]byte, error) {
- buf := make([]byte, 1)
- buf[0] = b.PrefixLength
- buf = append(buf, b.Addr.To4()...)
- return buf, nil
-}
-
-func (b *ImportLookupBody) DecodeFromBytes(data []byte, version uint8) error {
- isV4 := b.Api == IPV4_IMPORT_LOOKUP
- addrLen := net.IPv4len
- if !isV4 {
- addrLen = net.IPv6len
- }
-
- if len(data) < addrLen {
- return fmt.Errorf("message length invalid")
- }
-
- buf := make([]byte, addrLen)
- copy(buf, data[0:addrLen])
- pos := addrLen
-
- b.Addr = net.IP(buf).To4()
-
- if len(data[pos:]) > int(1+addrLen) {
- b.Metric = binary.BigEndian.Uint32(data[pos : pos+4])
- pos += 4
- b.Nexthops = []*Nexthop{}
- if nexthopsByteLen, err := decodeNexthopsFromBytes(&b.Nexthops, data[pos:], isV4, version); err != nil {
- return err
- } else {
- pos += nexthopsByteLen
- }
- }
-
- return nil
-}
-
-func (b *ImportLookupBody) String() string {
- s := fmt.Sprintf(
- "prefix: %s/%d, addr: %s, metric: %d",
- b.Prefix.String(), b.PrefixLength, b.Addr.String(), b.Metric)
- if len(b.Nexthops) > 0 {
- for _, nh := range b.Nexthops {
- s = s + fmt.Sprintf(", nexthop:{%s}", nh.String())
- }
- }
- return s
-}
-
-type RegisteredNexthop struct {
- Connected uint8
- Family uint16
- // Note: Ignores PrefixLength (uint8),
- // because this field should be always:
- // - 32 if Address Family is AF_INET
- // - 128 if Address Family is AF_INET6
- Prefix net.IP
-}
-
-func (n *RegisteredNexthop) Len() int {
- // Connected (1 byte) + Address Family (2 bytes) + Prefix Length (1 byte) + Prefix (variable)
- if n.Family == uint16(syscall.AF_INET) {
- return 4 + net.IPv4len
- } else {
- return 4 + net.IPv6len
- }
-}
-
-func (n *RegisteredNexthop) Serialize() ([]byte, error) {
- // Connected (1 byte)
- buf := make([]byte, 4)
- buf[0] = byte(n.Connected)
-
- // Address Family (2 bytes)
- binary.BigEndian.PutUint16(buf[1:3], n.Family)
-
- // Prefix Length (1 byte) + Prefix (variable)
- switch n.Family {
- case uint16(syscall.AF_INET):
- buf[3] = byte(net.IPv4len * 8)
- buf = append(buf, n.Prefix.To4()...)
- case uint16(syscall.AF_INET6):
- buf[3] = byte(net.IPv6len * 8)
- buf = append(buf, n.Prefix.To16()...)
- default:
- return nil, fmt.Errorf("invalid address family: %d", n.Family)
- }
-
- return buf, nil
-}
-
-func (n *RegisteredNexthop) DecodeFromBytes(data []byte) error {
- // Connected (1 byte)
- n.Connected = uint8(data[0])
- offset := 1
-
- // Address Family (2 bytes)
- n.Family = binary.BigEndian.Uint16(data[offset : offset+2])
- isV4 := n.Family == uint16(syscall.AF_INET)
- addrLen := int(net.IPv4len)
- if !isV4 {
- addrLen = net.IPv6len
- }
- // Note: Ignores Prefix Length (1 byte)
- offset += 3
-
- // Prefix (variable)
- if isV4 {
- n.Prefix = net.IP(data[offset : offset+addrLen]).To4()
- } else {
- n.Prefix = net.IP(data[offset : offset+addrLen]).To16()
- }
-
- return nil
-}
-
-func (n *RegisteredNexthop) String() string {
- return fmt.Sprintf(
- "connected: %d, family: %d, prefix: %s",
- n.Connected, n.Family, n.Prefix.String())
-}
-
-type NexthopRegisterBody struct {
- Api API_TYPE
- Nexthops []*RegisteredNexthop
-}
-
-func (b *NexthopRegisterBody) Serialize(version uint8) ([]byte, error) {
- buf := make([]byte, 0)
-
- // List of Registered Nexthops
- for _, nh := range b.Nexthops {
- nhBuf, err := nh.Serialize()
- if err != nil {
- return nil, err
- }
- buf = append(buf, nhBuf...)
- }
-
- return buf, nil
-}
-
-func (b *NexthopRegisterBody) DecodeFromBytes(data []byte, version uint8) error {
- offset := 0
-
- // List of Registered Nexthops
- b.Nexthops = []*RegisteredNexthop{}
- for len(data[offset:]) > 0 {
- nh := new(RegisteredNexthop)
- err := nh.DecodeFromBytes(data[offset:])
- if err != nil {
- return err
- }
- b.Nexthops = append(b.Nexthops, nh)
-
- offset += nh.Len()
- if len(data) < offset {
- break
- }
- }
-
- return nil
-}
-
-func (b *NexthopRegisterBody) String() string {
- s := make([]string, 0)
- for _, nh := range b.Nexthops {
- s = append(s, fmt.Sprintf("nexthop:{%s}", nh.String()))
- }
- return strings.Join(s, ", ")
-}
-
-type NexthopUpdateBody struct {
- Api API_TYPE
- Family uint16
- // Note: Ignores PrefixLength (uint8),
- // because this field should be always:
- // - 32 if Address Family is AF_INET
- // - 128 if Address Family is AF_INET6
- Prefix net.IP
- Distance uint8
- Metric uint32
- Nexthops []*Nexthop
-}
-
-func (b *NexthopUpdateBody) Serialize(version uint8) ([]byte, error) {
- // Address Family (2 bytes)
- buf := make([]byte, 3)
- binary.BigEndian.PutUint16(buf, b.Family)
-
- // Prefix Length (1 byte) + Prefix (variable)
- switch b.Family {
- case uint16(syscall.AF_INET):
- buf[2] = byte(net.IPv4len * 8)
- buf = append(buf, b.Prefix.To4()...)
- case uint16(syscall.AF_INET6):
- buf[2] = byte(net.IPv6len * 8)
- buf = append(buf, b.Prefix.To16()...)
- default:
- return nil, fmt.Errorf("invalid address family: %d", b.Family)
- }
-
- return buf, nil
-}
-
-func (b *NexthopUpdateBody) DecodeFromBytes(data []byte, version uint8) error {
- // Address Family (2 bytes)
- b.Family = binary.BigEndian.Uint16(data[0:2])
- isV4 := b.Family == uint16(syscall.AF_INET)
- addrLen := int(net.IPv4len)
- if !isV4 {
- addrLen = net.IPv6len
- }
- // Note: Ignores Prefix Length (1 byte)
- offset := 3
-
- // Prefix (variable)
- if isV4 {
- b.Prefix = net.IP(data[offset : offset+addrLen]).To4()
- } else {
- b.Prefix = net.IP(data[offset : offset+addrLen]).To16()
- }
- offset += addrLen
-
- // Distance (1 byte) (if version>=4)
- // Metric (4 bytes)
- // Number of Nexthops (1 byte)
- if version >= 4 {
- if len(data[offset:]) < 6 {
- return fmt.Errorf("invalid message length: missing distance(1 byte), metric(4 bytes) or nexthops(1 byte): %d<6", len(data[offset:]))
- }
- b.Distance = data[offset]
- offset += 1
- } else if len(data[offset:]) < 5 {
- return fmt.Errorf("invalid message length: missing metric(4 bytes) or nexthops(1 byte): %d<5", len(data[offset:]))
- }
- b.Metric = binary.BigEndian.Uint32(data[offset : offset+4])
- offset += 4
-
- // List of Nexthops
- b.Nexthops = []*Nexthop{}
- if nexthopsByteLen, err := decodeNexthopsFromBytes(&b.Nexthops, data[offset:], isV4, version); err != nil {
- return err
- } else {
- offset += nexthopsByteLen
- }
-
- return nil
-}
-
-func (b *NexthopUpdateBody) String() string {
- s := fmt.Sprintf(
- "family: %d, prefix: %s, distance: %d, metric: %d",
- b.Family, b.Prefix.String(), b.Distance, b.Metric)
- for _, nh := range b.Nexthops {
- s = s + fmt.Sprintf(", nexthop:{%s}", nh.String())
- }
- return s
-}
-
-type Message struct {
- Header Header
- Body Body
-}
-
-func (m *Message) Serialize() ([]byte, error) {
- var body []byte
- if m.Body != nil {
- var err error
- body, err = m.Body.Serialize(m.Header.Version)
- if err != nil {
- return nil, err
- }
- }
- m.Header.Len = uint16(len(body)) + HeaderSize(m.Header.Version)
- hdr, err := m.Header.Serialize()
- if err != nil {
- return nil, err
- }
- return append(hdr, body...), nil
-}
-
-func (m *Message) parseMessage(data []byte) error {
- switch m.Header.Command {
- case INTERFACE_ADD, INTERFACE_DELETE, INTERFACE_UP, INTERFACE_DOWN:
- m.Body = &InterfaceUpdateBody{}
- case INTERFACE_ADDRESS_ADD, INTERFACE_ADDRESS_DELETE:
- m.Body = &InterfaceAddressUpdateBody{}
- case ROUTER_ID_UPDATE:
- m.Body = &RouterIDUpdateBody{}
- case IPV4_ROUTE_ADD, IPV6_ROUTE_ADD, IPV4_ROUTE_DELETE, IPV6_ROUTE_DELETE:
- m.Body = &IPRouteBody{Api: m.Header.Command}
- case IPV4_NEXTHOP_LOOKUP, IPV6_NEXTHOP_LOOKUP:
- m.Body = &NexthopLookupBody{Api: m.Header.Command}
- case IPV4_IMPORT_LOOKUP:
- m.Body = &ImportLookupBody{Api: m.Header.Command}
- case NEXTHOP_UPDATE:
- m.Body = &NexthopUpdateBody{Api: m.Header.Command}
- default:
- m.Body = &UnknownBody{}
- }
- return m.Body.DecodeFromBytes(data, m.Header.Version)
-}
-
-func (m *Message) parseFrrMessage(data []byte) error {
- switch m.Header.Command {
- case FRR_INTERFACE_ADD, FRR_INTERFACE_DELETE, FRR_INTERFACE_UP, FRR_INTERFACE_DOWN:
- m.Body = &InterfaceUpdateBody{}
- case FRR_INTERFACE_ADDRESS_ADD, FRR_INTERFACE_ADDRESS_DELETE:
- m.Body = &InterfaceAddressUpdateBody{}
- case FRR_ROUTER_ID_UPDATE:
- m.Body = &RouterIDUpdateBody{}
- case FRR_NEXTHOP_UPDATE:
- m.Body = &NexthopUpdateBody{}
- case FRR_INTERFACE_NBR_ADDRESS_ADD, FRR_INTERFACE_NBR_ADDRESS_DELETE:
- // TODO
- m.Body = &UnknownBody{}
- case FRR_INTERFACE_BFD_DEST_UPDATE:
- // TODO
- m.Body = &UnknownBody{}
- case FRR_IMPORT_CHECK_UPDATE:
- // TODO
- m.Body = &UnknownBody{}
- case FRR_BFD_DEST_REPLAY:
- // TODO
- m.Body = &UnknownBody{}
- case FRR_REDISTRIBUTE_IPV4_ADD, FRR_REDISTRIBUTE_IPV4_DEL, FRR_REDISTRIBUTE_IPV6_ADD, FRR_REDISTRIBUTE_IPV6_DEL:
- m.Body = &IPRouteBody{Api: m.Header.Command}
- case FRR_INTERFACE_VRF_UPDATE:
- // TODO
- m.Body = &UnknownBody{}
- case FRR_INTERFACE_LINK_PARAMS:
- // TODO
- m.Body = &UnknownBody{}
- case FRR_PW_STATUS_UPDATE:
- // TODO
- m.Body = &UnknownBody{}
- default:
- m.Body = &UnknownBody{}
- }
- return m.Body.DecodeFromBytes(data, m.Header.Version)
-}
-
-func ParseMessage(hdr *Header, data []byte) (m *Message, err error) {
- m = &Message{Header: *hdr}
- if m.Header.Version == 4 {
- err = m.parseFrrMessage(data)
- } else {
- err = m.parseMessage(data)
- }
- if err != nil {
- return nil, err
- }
- return m, nil
-}
diff --git a/zebra/zapi_bsd.go b/zebra/zapi_bsd.go
deleted file mode 100644
index 8960e796..00000000
--- a/zebra/zapi_bsd.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (C) 2014, 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build freebsd netbsd openbsd
-
-package zebra
-
-import (
- "strings"
- "syscall"
-)
-
-func intfflag2string(flag uint64) string {
- ss := make([]string, 0, 10)
- if flag&syscall.IFF_UP > 0 {
- ss = append(ss, "UP")
- }
- if flag&syscall.IFF_BROADCAST > 0 {
- ss = append(ss, "BROADCAST")
- }
- if flag&syscall.IFF_DEBUG > 0 {
- ss = append(ss, "DEBUG")
- }
- if flag&syscall.IFF_LOOPBACK > 0 {
- ss = append(ss, "LOOPBACK")
- }
- if flag&syscall.IFF_POINTOPOINT > 0 {
- ss = append(ss, "POINTOPOINT")
- }
- if flag&syscall.IFF_RUNNING > 0 {
- ss = append(ss, "RUNNING")
- }
- if flag&syscall.IFF_NOARP > 0 {
- ss = append(ss, "NOARP")
- }
- if flag&syscall.IFF_PROMISC > 0 {
- ss = append(ss, "PROMISC")
- }
- if flag&syscall.IFF_ALLMULTI > 0 {
- ss = append(ss, "ALLMULTI")
- }
- if flag&syscall.IFF_MULTICAST > 0 {
- ss = append(ss, "MULTICAST")
- }
- return strings.Join(ss, " | ")
-}
diff --git a/zebra/zapi_darwin.go b/zebra/zapi_darwin.go
deleted file mode 100644
index a2536913..00000000
--- a/zebra/zapi_darwin.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (C) 2014, 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package zebra
-
-import (
- "strings"
- "syscall"
-)
-
-func intfflag2string(flag uint64) string {
- ss := make([]string, 0, 10)
- if flag&syscall.IFF_UP > 0 {
- ss = append(ss, "UP")
- }
- if flag&syscall.IFF_BROADCAST > 0 {
- ss = append(ss, "BROADCAST")
- }
- if flag&syscall.IFF_DEBUG > 0 {
- ss = append(ss, "DEBUG")
- }
- if flag&syscall.IFF_LOOPBACK > 0 {
- ss = append(ss, "LOOPBACK")
- }
- if flag&syscall.IFF_POINTOPOINT > 0 {
- ss = append(ss, "POINTOPOINT")
- }
- if flag&syscall.IFF_NOTRAILERS > 0 {
- ss = append(ss, "NOTRAILERS")
- }
- if flag&syscall.IFF_RUNNING > 0 {
- ss = append(ss, "RUNNING")
- }
- if flag&syscall.IFF_NOARP > 0 {
- ss = append(ss, "NOARP")
- }
- if flag&syscall.IFF_PROMISC > 0 {
- ss = append(ss, "PROMISC")
- }
- if flag&syscall.IFF_ALLMULTI > 0 {
- ss = append(ss, "ALLMULTI")
- }
- if flag&syscall.IFF_MULTICAST > 0 {
- ss = append(ss, "MULTICAST")
- }
- return strings.Join(ss, " | ")
-}
diff --git a/zebra/zapi_linux.go b/zebra/zapi_linux.go
deleted file mode 100644
index 66fccb74..00000000
--- a/zebra/zapi_linux.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2014, 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package zebra
-
-import (
- "strings"
- "syscall"
-)
-
-func intfflag2string(flag uint64) string {
- ss := make([]string, 0, 10)
- if flag&syscall.IFF_UP > 0 {
- ss = append(ss, "UP")
- }
- if flag&syscall.IFF_BROADCAST > 0 {
- ss = append(ss, "BROADCAST")
- }
- if flag&syscall.IFF_DEBUG > 0 {
- ss = append(ss, "DEBUG")
- }
- if flag&syscall.IFF_LOOPBACK > 0 {
- ss = append(ss, "LOOPBACK")
- }
- if flag&syscall.IFF_POINTOPOINT > 0 {
- ss = append(ss, "POINTOPOINT")
- }
- if flag&syscall.IFF_NOTRAILERS > 0 {
- ss = append(ss, "NOTRAILERS")
- }
- if flag&syscall.IFF_RUNNING > 0 {
- ss = append(ss, "RUNNING")
- }
- if flag&syscall.IFF_NOARP > 0 {
- ss = append(ss, "NOARP")
- }
- if flag&syscall.IFF_PROMISC > 0 {
- ss = append(ss, "PROMISC")
- }
- if flag&syscall.IFF_ALLMULTI > 0 {
- ss = append(ss, "ALLMULTI")
- }
- if flag&syscall.IFF_MASTER > 0 {
- ss = append(ss, "MASTER")
- }
- if flag&syscall.IFF_SLAVE > 0 {
- ss = append(ss, "SLAVE")
- }
- if flag&syscall.IFF_MULTICAST > 0 {
- ss = append(ss, "MULTICAST")
- }
- if flag&syscall.IFF_PORTSEL > 0 {
- ss = append(ss, "PORTSEL")
- }
- if flag&syscall.IFF_AUTOMEDIA > 0 {
- ss = append(ss, "AUTOMEDIA")
- }
- if flag&syscall.IFF_DYNAMIC > 0 {
- ss = append(ss, "DYNAMIC")
- }
- // if flag&syscall.IFF_LOWER_UP > 0 {
- // ss = append(ss, "LOWER_UP")
- // }
- // if flag&syscall.IFF_DORMANT > 0 {
- // ss = append(ss, "DORMANT")
- // }
- // if flag&syscall.IFF_ECHO > 0 {
- // ss = append(ss, "ECHO")
- // }
- return strings.Join(ss, " | ")
-}
diff --git a/zebra/zapi_test.go b/zebra/zapi_test.go
deleted file mode 100644
index 9fda5416..00000000
--- a/zebra/zapi_test.go
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright (C) 2014, 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package zebra
-
-import (
- "encoding/binary"
- "net"
- "syscall"
- "testing"
-
- "github.com/stretchr/testify/require"
-
- "github.com/stretchr/testify/assert"
-)
-
-func Test_Header(t *testing.T) {
- assert := assert.New(t)
-
- //DecodeFromBytes
- buf := make([]byte, 6)
- binary.BigEndian.PutUint16(buf[0:], 10)
- buf[2] = HEADER_MARKER
- buf[3] = 2
- binary.BigEndian.PutUint16(buf[4:], uint16(IPV4_ROUTE_ADD))
- h := &Header{}
- err := h.DecodeFromBytes(buf)
- assert.Equal(nil, err)
-
- //Serialize
- buf, err = h.Serialize()
- assert.Equal(nil, err)
- h2 := &Header{}
- err = h2.DecodeFromBytes(buf)
- assert.Equal(nil, err)
- assert.Equal(h, h2)
-
- // header_size mismatch
- buf = make([]byte, HeaderSize(2)-1)
- binary.BigEndian.PutUint16(buf[0:], 10)
- buf[2] = 0xff
- buf[3] = 0x02
- h3 := &Header{}
- err = h3.DecodeFromBytes(buf)
- assert.NotEqual(nil, err)
-}
-
-func Test_InterfaceUpdateBody(t *testing.T) {
- assert := assert.New(t)
-
- //DecodeFromBytes
- buf := make([]byte, INTERFACE_NAMSIZ+49)
- pos := INTERFACE_NAMSIZ
- binary.BigEndian.PutUint32(buf[pos:], 1)
- pos += 4
- buf[pos] = byte(INTERFACE_ACTIVE)
- pos += 1
- binary.BigEndian.PutUint64(buf[pos:], 1)
- pos += 8 // flags
- binary.BigEndian.PutUint32(buf[pos:], 1)
- pos += 4 // metric
- binary.BigEndian.PutUint32(buf[pos:], 1500)
- pos += 4 // MTU
- binary.BigEndian.PutUint32(buf[pos:], 1500)
- pos += 4 // MTU6
- binary.BigEndian.PutUint32(buf[pos:], 200)
- pos += 4 // bandwidth
- binary.BigEndian.PutUint32(buf[pos:], 6)
- pos += 4 // hwaddr_len
- mac, _ := net.ParseMAC("01:23:45:67:89:ab")
- copy(buf[pos:pos+6], []byte(mac))
- pos += 4
- b := &InterfaceUpdateBody{}
- err := b.DecodeFromBytes(buf, 2)
- assert.Equal(nil, err)
- assert.Equal("01:23:45:67:89:ab", b.HardwareAddr.String())
-
- buf = make([]byte, INTERFACE_NAMSIZ+28)
- b = &InterfaceUpdateBody{}
- err = b.DecodeFromBytes(buf, 2)
- assert.NotEqual(nil, err)
-}
-
-func Test_InterfaceAddressUpdateBody(t *testing.T) {
- assert := assert.New(t)
-
- //DecodeFromBytes
- buf := make([]byte, 15)
- pos := 0
- binary.BigEndian.PutUint32(buf[pos:], 0) // index
- pos += 4
- buf[pos] = 0x01 // flags
- pos += 1
- buf[pos] = 0x2 // family
- pos += 1
- ip := net.ParseIP("192.168.100.1").To4() // prefix
- copy(buf[pos:pos+4], []byte(ip))
- pos += 4
- buf[pos] = byte(24) // prefix len
- pos += 1
- dst := net.ParseIP("192.168.100.255").To4() // destination
- copy(buf[pos:pos+4], []byte(dst))
-
- b := &InterfaceAddressUpdateBody{}
- err := b.DecodeFromBytes(buf, 2)
- require.NoError(t, err)
-
- assert.Equal(uint32(0), b.Index)
- assert.Equal(INTERFACE_ADDRESS_FLAG(1), b.Flags)
- assert.Equal("192.168.100.1", b.Prefix.String())
- assert.Equal(uint8(24), b.Length)
- assert.Equal("192.168.100.255", b.Destination.String())
-
- // af invalid
- buf[5] = 0x4
- pos += 1
- b = &InterfaceAddressUpdateBody{}
- err = b.DecodeFromBytes(buf, 2)
- assert.NotEqual(nil, err)
-}
-
-func Test_RouterIDUpdateBody(t *testing.T) {
- assert := assert.New(t)
-
- //DecodeFromBytes
- buf := make([]byte, 6)
- pos := 0
- buf[pos] = 0x2
- pos += 1
- ip := net.ParseIP("192.168.100.1").To4()
- copy(buf[pos:pos+4], []byte(ip))
- pos += 4
- buf[pos] = byte(32)
-
- b := &RouterIDUpdateBody{}
- err := b.DecodeFromBytes(buf, 2)
- assert.Equal(nil, err)
- assert.Equal("192.168.100.1", b.Prefix.String())
- assert.Equal(uint8(32), b.Length)
-
- // af invalid
- buf[0] = 0x4
- pos += 1
- b = &RouterIDUpdateBody{}
- err = b.DecodeFromBytes(buf, 2)
- assert.NotEqual(nil, err)
-}
-
-func Test_IPRouteBody_IPv4(t *testing.T) {
- assert := assert.New(t)
-
- //DecodeFromBytes IPV4_ROUTE
- buf := make([]byte, 26)
- buf[0] = byte(ROUTE_CONNECT)
- buf[1] = byte(FLAG_SELECTED)
- buf[2] = byte(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))
-
- buf[7] = 1
- nexthop := net.ParseIP("0.0.0.0").To4()
- copy(buf[8:12], []byte(nexthop))
-
- buf[12] = 1
- 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(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(2)
- assert.Equal(nil, err)
- 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()
- assert.Equal([]byte(ip)[0:3], buf[6:9])
- assert.Equal(byte(NEXTHOP_IPV4), buf[10])
- assert.Equal(byte(NEXTHOP_IFINDEX), buf[15])
- assert.Equal(byte(0x0), buf[20])
-
- bi := make([]byte, 4)
- binary.BigEndian.PutUint32(bi, 1)
- assert.Equal(bi, buf[21:25])
- assert.Equal(bi, buf[25:])
-
- // length invalid
- buf = make([]byte, 18)
- buf[0] = byte(ROUTE_CONNECT)
- buf[1] = byte(FLAG_SELECTED)
- buf[2] = byte(MESSAGE_NEXTHOP | MESSAGE_DISTANCE | MESSAGE_METRIC)
- buf[3] = 24
- ip = net.ParseIP("192.168.100.0").To4()
- copy(buf[4:7], []byte(ip))
- buf[7] = 1
- nexthop = net.ParseIP("0.0.0.0").To4()
- copy(buf[8:12], []byte(nexthop))
- buf[12] = 1
- binary.BigEndian.PutUint32(buf[13:], 1)
-
- r = &IPRouteBody{Api: IPV4_ROUTE_ADD}
- err = r.DecodeFromBytes(buf, 2)
- assert.Equal("message length invalid", err.Error())
-
- // no nexthop
- buf = make([]byte, 12)
- buf[0] = byte(ROUTE_CONNECT)
- buf[1] = byte(FLAG_SELECTED)
- buf[2] = byte(MESSAGE_DISTANCE | MESSAGE_METRIC)
- buf[3] = 24
- ip = net.ParseIP("192.168.100.0").To4()
- copy(buf[4:7], []byte(ip))
- buf[7] = 1
- binary.BigEndian.PutUint32(buf[8:], 0)
- r = &IPRouteBody{Api: IPV4_ROUTE_ADD}
- err = r.DecodeFromBytes(buf, 2)
- assert.Equal(nil, err)
-
-}
-
-func Test_IPRouteBody_IPv6(t *testing.T) {
- assert := assert.New(t)
-
- //DecodeFromBytes IPV6_ROUTE
- buf := make([]byte, 43)
- buf[0] = byte(ROUTE_CONNECT)
- buf[1] = byte(FLAG_SELECTED)
- buf[2] = byte(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))
-
- buf[12] = 1
- nexthop := net.ParseIP("::").To16()
- copy(buf[13:29], []byte(nexthop))
- // ifindex
- buf[29] = 1
- binary.BigEndian.PutUint32(buf[30:], 1)
-
- 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(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(2)
- assert.Equal(nil, err)
- 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()
- assert.Equal([]byte(ip)[0:8], buf[6:14])
- assert.Equal(byte(2), buf[14])
- assert.Equal(byte(NEXTHOP_IPV6), buf[15])
- ip = net.ParseIP("::").To16()
- assert.Equal([]byte(ip), buf[16:32])
- assert.Equal(byte(NEXTHOP_IFINDEX), buf[32])
- bi := make([]byte, 4)
- binary.BigEndian.PutUint32(bi, 1)
- assert.Equal(bi, buf[33:37])
-
- //distance
- assert.Equal(byte(0), buf[37])
- bi = make([]byte, 4)
- binary.BigEndian.PutUint32(bi, 1)
- assert.Equal(bi, buf[38:42])
- assert.Equal(bi, buf[42:])
-
- // length invalid
- buf = make([]byte, 50)
- buf[0] = byte(ROUTE_CONNECT)
- buf[1] = byte(FLAG_SELECTED)
- buf[2] = byte(MESSAGE_NEXTHOP | MESSAGE_DISTANCE | MESSAGE_METRIC)
- buf[3] = 24
- ip = net.ParseIP("2001:db8:0:f101::").To4()
- copy(buf[4:12], []byte(ip))
- buf[13] = 1
- nexthop = net.ParseIP("::").To16()
- copy(buf[14:30], []byte(nexthop))
- buf[31] = 1
- binary.BigEndian.PutUint32(buf[32:], 1)
-
- r = &IPRouteBody{Api: IPV6_ROUTE_ADD}
- err = r.DecodeFromBytes(buf, 2)
- assert.Equal("message length invalid", err.Error())
-
- // no nexthop
- buf = make([]byte, 11)
- buf[0] = byte(ROUTE_CONNECT)
- buf[1] = byte(FLAG_SELECTED)
- buf[2] = byte(MESSAGE_DISTANCE | MESSAGE_METRIC)
- buf[3] = 16
- ip = net.ParseIP("2501::").To16()
- copy(buf[4:6], []byte(ip))
- buf[6] = 1
- binary.BigEndian.PutUint32(buf[7:], 0)
- r = &IPRouteBody{Api: IPV6_ROUTE_ADD}
- err = r.DecodeFromBytes(buf, 2)
- assert.Equal(nil, err)
-}
-
-func Test_NexthopLookupBody(t *testing.T) {
- assert := assert.New(t)
-
- //ipv4
- //DecodeFromBytes
- pos := 0
- buf := make([]byte, 18)
- ip := net.ParseIP("192.168.50.0").To4()
- copy(buf[0:4], []byte(ip))
- pos += 4
- binary.BigEndian.PutUint32(buf[pos:], 10)
- pos += 4
- buf[pos] = byte(1)
- pos += 1
- buf[pos] = byte(4)
- pos += 1
- ip = net.ParseIP("172.16.1.101").To4()
- copy(buf[pos:pos+4], []byte(ip))
- pos += 4
- binary.BigEndian.PutUint32(buf[pos:], 3)
-
- b := &NexthopLookupBody{Api: IPV4_NEXTHOP_LOOKUP}
- err := b.DecodeFromBytes(buf, 2)
- assert.Equal(nil, err)
- assert.Equal("192.168.50.0", b.Addr.String())
- assert.Equal(uint32(10), b.Metric)
- assert.Equal(uint32(3), b.Nexthops[0].Ifindex)
- assert.Equal(NEXTHOP_FLAG(4), b.Nexthops[0].Type)
- assert.Equal("172.16.1.101", b.Nexthops[0].Addr.String())
-
- //Serialize
- 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])
-
- // length invalid
- buf = make([]byte, 3)
- b = &NexthopLookupBody{Api: IPV4_NEXTHOP_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
- assert.NotEqual(nil, err)
-
- //ipv6
- //DecodeFromBytes
- pos = 0
- buf = make([]byte, 46)
- ip = net.ParseIP("2001:db8:0:f101::").To16()
- copy(buf[0:16], []byte(ip))
- pos += 16
- binary.BigEndian.PutUint32(buf[pos:], 10)
- pos += 4
- buf[pos] = byte(1)
- pos += 1
- buf[pos] = byte(4)
- pos += 1
- ip = net.ParseIP("2001:db8:0:1111::1").To16()
- copy(buf[pos:pos+16], []byte(ip))
- pos += 16
- binary.BigEndian.PutUint32(buf[pos:], 3)
-
- b = &NexthopLookupBody{Api: IPV6_NEXTHOP_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
- assert.Equal(nil, err)
- assert.Equal("2001:db8:0:f101::", b.Addr.String())
- assert.Equal(uint32(10), b.Metric)
- assert.Equal(uint32(3), b.Nexthops[0].Ifindex)
- assert.Equal(NEXTHOP_FLAG(4), b.Nexthops[0].Type)
- assert.Equal("2001:db8:0:1111::1", b.Nexthops[0].Addr.String())
-
- //Serialize
- 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])
-
- // length invalid
- buf = make([]byte, 15)
- b = &NexthopLookupBody{Api: IPV6_NEXTHOP_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
- assert.NotEqual(nil, err)
-}
-
-func Test_ImportLookupBody(t *testing.T) {
- assert := assert.New(t)
-
- //DecodeFromBytes
- pos := 0
- buf := make([]byte, 18)
- ip := net.ParseIP("192.168.50.0").To4()
- copy(buf[0:4], []byte(ip))
- pos += 4
- binary.BigEndian.PutUint32(buf[pos:], 10)
- pos += 4
- buf[pos] = byte(1)
- pos += 1
- buf[pos] = byte(4)
- pos += 1
- ip = net.ParseIP("172.16.1.101").To4()
- copy(buf[pos:pos+4], []byte(ip))
- pos += 4
- binary.BigEndian.PutUint32(buf[pos:], 3)
-
- b := &ImportLookupBody{Api: IPV4_IMPORT_LOOKUP}
- err := b.DecodeFromBytes(buf, 2)
- assert.Equal(nil, err)
- assert.Equal("192.168.50.0", b.Addr.String())
- assert.Equal(uint32(10), b.Metric)
- assert.Equal(uint32(3), b.Nexthops[0].Ifindex)
- assert.Equal(NEXTHOP_FLAG(4), b.Nexthops[0].Type)
- assert.Equal("172.16.1.101", b.Nexthops[0].Addr.String())
-
- //Serialize
- b.PrefixLength = uint8(24)
- buf, err = b.Serialize(2)
- ip = net.ParseIP("192.168.50.0").To4()
- assert.Equal(nil, err)
- assert.Equal(uint8(24), buf[0])
- assert.Equal([]byte(ip)[0:4], buf[1:5])
-
- // length invalid
- buf = make([]byte, 3)
- b = &ImportLookupBody{Api: IPV4_IMPORT_LOOKUP}
- err = b.DecodeFromBytes(buf, 2)
- assert.NotEqual(nil, err)
-}
-
-func Test_NexthopRegisterBody(t *testing.T) {
- assert := assert.New(t)
-
- // Input binary
- bufIn := []byte{
- 0x01, 0x00, 0x02, 0x20, // connected(1 byte)=1, afi(2 bytes)=AF_INET, prefix_len(1 byte)=32
- 0xc0, 0xa8, 0x01, 0x01, // prefix(4 bytes)="192.168.1.1"
- 0x00, 0x00, 0x0a, 0x80, // connected(1 byte)=0, afi(2 bytes)=AF_INET6, prefix_len(1 byte)=128
- 0x20, 0x01, 0x0d, 0xb8, // prefix(16 bytes)="2001:db8:1:1::1"
- 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01,
- }
- binary.BigEndian.PutUint16(bufIn[1:], syscall.AF_INET)
- binary.BigEndian.PutUint16(bufIn[9:], syscall.AF_INET6)
-
- // Test DecodeFromBytes()
- b := &NexthopRegisterBody{Api: NEXTHOP_REGISTER}
- err := b.DecodeFromBytes(bufIn, 3)
- assert.Nil(err)
-
- // Test decoded values
- assert.Equal(uint8(1), b.Nexthops[0].Connected)
- assert.Equal(uint16(syscall.AF_INET), b.Nexthops[0].Family)
- assert.Equal(net.ParseIP("192.168.1.1").To4(), b.Nexthops[0].Prefix)
- assert.Equal(uint8(0), b.Nexthops[1].Connected)
- assert.Equal(uint16(syscall.AF_INET6), b.Nexthops[1].Family)
- assert.Equal(net.ParseIP("2001:db8:1:1::1").To16(), b.Nexthops[1].Prefix)
-
- // Test Serialize()
- bufOut, err := b.Serialize(3)
- assert.Nil(err)
-
- // Test serialised value
- assert.Equal(bufIn, bufOut)
-}
-
-func Test_NexthopUpdateBody(t *testing.T) {
- assert := assert.New(t)
-
- // Input binary
- bufIn := []byte{
- 0x00, 0x02, 0x20, // afi(2 bytes)=AF_INET, prefix_len(1 byte)=32
- 0xc0, 0xa8, 0x01, 0x01, // prefix(4 bytes)="192.168.1.1"
- 0x00, 0x00, 0x00, 0x01, // metric(4 bytes)=1
- 0x01, // nexthops(1 byte)=1
- 0x04, // nexthop_type(1 byte)=NEXTHOP_IPV4_IFINDEX
- 0xc0, 0xa8, 0x01, 0x01, // nexthop_ip(4 bytes)="192.168.0.1"
- 0x00, 0x00, 0x00, 0x02, // nexthop_ifindex(4 byte)=2
- }
-
- // Test DecodeFromBytes()
- b := &NexthopUpdateBody{Api: NEXTHOP_UPDATE}
- err := b.DecodeFromBytes(bufIn, 2)
- assert.Nil(err)
-
- // Test decoded values
- assert.Equal(uint16(syscall.AF_INET), b.Family)
- assert.Equal(net.ParseIP("192.168.1.1").To4(), b.Prefix)
- assert.Equal(uint32(1), b.Metric)
- nexthop := &Nexthop{
- Type: NEXTHOP_FLAG(NEXTHOP_IPV4_IFINDEX),
- Addr: net.ParseIP("192.168.1.1").To4(),
- Ifindex: uint32(2),
- }
- assert.Equal(1, len(b.Nexthops))
- assert.Equal(nexthop, b.Nexthops[0])
-}
diff --git a/zebra/zapi_windows.go b/zebra/zapi_windows.go
deleted file mode 100644
index d55525db..00000000
--- a/zebra/zapi_windows.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2014, 2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package zebra
-
-import (
- "strings"
- "syscall"
-)
-
-func intfflag2string(flag uint64) string {
- ss := make([]string, 0, 10)
- if flag&syscall.IFF_UP > 0 {
- ss = append(ss, "UP")
- }
- if flag&syscall.IFF_BROADCAST > 0 {
- ss = append(ss, "BROADCAST")
- }
- if flag&syscall.IFF_LOOPBACK > 0 {
- ss = append(ss, "LOOPBACK")
- }
- if flag&syscall.IFF_MULTICAST > 0 {
- ss = append(ss, "MULTICAST")
- }
- return strings.Join(ss, " | ")
-}