diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/afi_string.go | 17 | ||||
-rw-r--r-- | zebra/api_type_string.go | 16 | ||||
-rw-r--r-- | zebra/link_type_string.go | 16 | ||||
-rw-r--r-- | zebra/nexthop_flag_string.go | 17 | ||||
-rw-r--r-- | zebra/ptm_enable_string.go | 16 | ||||
-rw-r--r-- | zebra/ptm_status_string.go | 16 | ||||
-rw-r--r-- | zebra/route_type_string.go | 16 | ||||
-rw-r--r-- | zebra/safi_string.go | 17 | ||||
-rw-r--r-- | zebra/zapi.go | 1917 | ||||
-rw-r--r-- | zebra/zapi_bsd.go | 58 | ||||
-rw-r--r-- | zebra/zapi_darwin.go | 59 | ||||
-rw-r--r-- | zebra/zapi_linux.go | 83 | ||||
-rw-r--r-- | zebra/zapi_test.go | 531 | ||||
-rw-r--r-- | zebra/zapi_windows.go | 38 |
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, " | ") -} |