diff options
-rw-r--r-- | api/gobgp.pb.go | 784 | ||||
-rw-r--r-- | api/gobgp.proto | 216 | ||||
-rw-r--r-- | gobgp/common.go | 79 | ||||
-rw-r--r-- | gobgp/monitor.go | 10 | ||||
-rw-r--r-- | gobgp/neighbor.go | 328 | ||||
-rw-r--r-- | packet/bgp.go | 734 | ||||
-rw-r--r-- | server/grpc_server.go | 66 | ||||
-rw-r--r-- | server/server.go | 38 | ||||
-rw-r--r-- | table/destination.go | 25 | ||||
-rw-r--r-- | table/path.go | 27 | ||||
-rw-r--r-- | test/scenario_test/bgp_router_test.py | 6 | ||||
-rw-r--r-- | test/scenario_test/constant.py | 4 | ||||
-rw-r--r-- | test/scenario_test/evpn_test.py | 6 | ||||
-rw-r--r-- | test/scenario_test/gobgp_test.py | 5 | ||||
-rw-r--r-- | test/scenario_test/ibgp_router_test.py | 8 | ||||
-rw-r--r-- | test/scenario_test/lib/base.py | 1 | ||||
-rw-r--r-- | test/scenario_test/lib/gobgp.py | 29 | ||||
-rw-r--r-- | test/scenario_test/route_server_policy_test.py | 64 |
18 files changed, 694 insertions, 1736 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index 99973473..5c332c6f 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -16,23 +16,9 @@ It has these top-level messages: MrtArguments ModVrfArguments AddressFamily - RouteDistinguisher GracefulRestartTuple GracefulRestart Capability - Aggregator - ExtendedCommunity - EVPNNlri - EvpnMacIpAdvertisement - EvpnInclusiveMulticastEthernetTag - RTNlri - VPNNlri - Nlri - TunnelEncapSubTLV - TunnelEncapTLV - PmsiTunnel - PathAttr - AsPath Path Destination PeerConf @@ -213,29 +199,6 @@ func (x SAFI) String() string { return proto.EnumName(SAFI_name, int32(x)) } -type ROUTE_DISTINGUISHER_TYPE int32 - -const ( - ROUTE_DISTINGUISHER_TYPE_TWO_OCTET_AS ROUTE_DISTINGUISHER_TYPE = 0 - ROUTE_DISTINGUISHER_TYPE_IP4 ROUTE_DISTINGUISHER_TYPE = 1 - ROUTE_DISTINGUISHER_TYPE_FOUR_OCTET_AS ROUTE_DISTINGUISHER_TYPE = 2 -) - -var ROUTE_DISTINGUISHER_TYPE_name = map[int32]string{ - 0: "TWO_OCTET_AS", - 1: "IP4", - 2: "FOUR_OCTET_AS", -} -var ROUTE_DISTINGUISHER_TYPE_value = map[string]int32{ - "TWO_OCTET_AS": 0, - "IP4": 1, - "FOUR_OCTET_AS": 2, -} - -func (x ROUTE_DISTINGUISHER_TYPE) String() string { - return proto.EnumName(ROUTE_DISTINGUISHER_TYPE_name, int32(x)) -} - type BGP_CAPABILITY int32 const ( @@ -274,231 +237,6 @@ func (x BGP_CAPABILITY) String() string { return proto.EnumName(BGP_CAPABILITY_name, int32(x)) } -type Origin int32 - -const ( - Origin_IGP Origin = 0 - Origin_EGP Origin = 1 - Origin_INCOMPLETE Origin = 2 -) - -var Origin_name = map[int32]string{ - 0: "IGP", - 1: "EGP", - 2: "INCOMPLETE", -} -var Origin_value = map[string]int32{ - "IGP": 0, - "EGP": 1, - "INCOMPLETE": 2, -} - -func (x Origin) String() string { - return proto.EnumName(Origin_name, int32(x)) -} - -type TUNNEL_TYPE int32 - -const ( - TUNNEL_TYPE_UNKNOWN_TUNNEL_TYPE TUNNEL_TYPE = 0 - TUNNEL_TYPE_L2TPV3_OVER_IP TUNNEL_TYPE = 1 - TUNNEL_TYPE_GRE TUNNEL_TYPE = 2 - TUNNEL_TYPE_IP_IN_IP TUNNEL_TYPE = 7 - TUNNEL_TYPE_VXLAN TUNNEL_TYPE = 8 - TUNNEL_TYPE_NVGRE TUNNEL_TYPE = 9 - TUNNEL_TYPE_MPLS TUNNEL_TYPE = 10 - TUNNEL_TYPE_MPLS_IN_GRE TUNNEL_TYPE = 11 - TUNNEL_TYPE_VXLAN_GRE TUNNEL_TYPE = 12 -) - -var TUNNEL_TYPE_name = map[int32]string{ - 0: "UNKNOWN_TUNNEL_TYPE", - 1: "L2TPV3_OVER_IP", - 2: "GRE", - 7: "IP_IN_IP", - 8: "VXLAN", - 9: "NVGRE", - 10: "MPLS", - 11: "MPLS_IN_GRE", - 12: "VXLAN_GRE", -} -var TUNNEL_TYPE_value = map[string]int32{ - "UNKNOWN_TUNNEL_TYPE": 0, - "L2TPV3_OVER_IP": 1, - "GRE": 2, - "IP_IN_IP": 7, - "VXLAN": 8, - "NVGRE": 9, - "MPLS": 10, - "MPLS_IN_GRE": 11, - "VXLAN_GRE": 12, -} - -func (x TUNNEL_TYPE) String() string { - return proto.EnumName(TUNNEL_TYPE_name, int32(x)) -} - -type PMSI_TUNNEL_TYPE int32 - -const ( - PMSI_TUNNEL_TYPE_NO_TUNNEL PMSI_TUNNEL_TYPE = 0 - PMSI_TUNNEL_TYPE_RSVP_TE_P2MP PMSI_TUNNEL_TYPE = 1 - PMSI_TUNNEL_TYPE_MLDP_P2MP PMSI_TUNNEL_TYPE = 2 - PMSI_TUNNEL_TYPE_PIM_SSM_TREE PMSI_TUNNEL_TYPE = 3 - PMSI_TUNNEL_TYPE_PIM_SM_TREE PMSI_TUNNEL_TYPE = 4 - PMSI_TUNNEL_TYPE_BIDIR_PIM_TREE PMSI_TUNNEL_TYPE = 5 - PMSI_TUNNEL_TYPE_INGRESS_REPL PMSI_TUNNEL_TYPE = 6 - PMSI_TUNNEL_TYPE_MLDP_MP2MP PMSI_TUNNEL_TYPE = 7 -) - -var PMSI_TUNNEL_TYPE_name = map[int32]string{ - 0: "NO_TUNNEL", - 1: "RSVP_TE_P2MP", - 2: "MLDP_P2MP", - 3: "PIM_SSM_TREE", - 4: "PIM_SM_TREE", - 5: "BIDIR_PIM_TREE", - 6: "INGRESS_REPL", - 7: "MLDP_MP2MP", -} -var PMSI_TUNNEL_TYPE_value = map[string]int32{ - "NO_TUNNEL": 0, - "RSVP_TE_P2MP": 1, - "MLDP_P2MP": 2, - "PIM_SSM_TREE": 3, - "PIM_SM_TREE": 4, - "BIDIR_PIM_TREE": 5, - "INGRESS_REPL": 6, - "MLDP_MP2MP": 7, -} - -func (x PMSI_TUNNEL_TYPE) String() string { - return proto.EnumName(PMSI_TUNNEL_TYPE_name, int32(x)) -} - -type EVPN_TYPE int32 - -const ( - EVPN_TYPE_UNKNOWN_EVPN_TYPE EVPN_TYPE = 0 - EVPN_TYPE_ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY EVPN_TYPE = 1 - EVPN_TYPE_ROUTE_TYPE_MAC_IP_ADVERTISEMENT EVPN_TYPE = 2 - EVPN_TYPE_INCLUSIVE_MULTICAST_ETHERNET_TAG EVPN_TYPE = 3 - EVPN_TYPE_ETHERNET_SEGMENT_ROUTE EVPN_TYPE = 4 -) - -var EVPN_TYPE_name = map[int32]string{ - 0: "UNKNOWN_EVPN_TYPE", - 1: "ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY", - 2: "ROUTE_TYPE_MAC_IP_ADVERTISEMENT", - 3: "INCLUSIVE_MULTICAST_ETHERNET_TAG", - 4: "ETHERNET_SEGMENT_ROUTE", -} -var EVPN_TYPE_value = map[string]int32{ - "UNKNOWN_EVPN_TYPE": 0, - "ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY": 1, - "ROUTE_TYPE_MAC_IP_ADVERTISEMENT": 2, - "INCLUSIVE_MULTICAST_ETHERNET_TAG": 3, - "ETHERNET_SEGMENT_ROUTE": 4, -} - -func (x EVPN_TYPE) String() string { - return proto.EnumName(EVPN_TYPE_name, int32(x)) -} - -type ENCAP_SUBTLV_TYPE int32 - -const ( - ENCAP_SUBTLV_TYPE_UNKNOWN_SUBTLV_TYPE ENCAP_SUBTLV_TYPE = 0 - ENCAP_SUBTLV_TYPE_ENCAPSULATION ENCAP_SUBTLV_TYPE = 1 - ENCAP_SUBTLV_TYPE_PROTOCOL ENCAP_SUBTLV_TYPE = 2 - ENCAP_SUBTLV_TYPE_COLOR ENCAP_SUBTLV_TYPE = 4 -) - -var ENCAP_SUBTLV_TYPE_name = map[int32]string{ - 0: "UNKNOWN_SUBTLV_TYPE", - 1: "ENCAPSULATION", - 2: "PROTOCOL", - 4: "COLOR", -} -var ENCAP_SUBTLV_TYPE_value = map[string]int32{ - "UNKNOWN_SUBTLV_TYPE": 0, - "ENCAPSULATION": 1, - "PROTOCOL": 2, - "COLOR": 4, -} - -func (x ENCAP_SUBTLV_TYPE) String() string { - return proto.EnumName(ENCAP_SUBTLV_TYPE_name, int32(x)) -} - -type BGP_ATTR_TYPE int32 - -const ( - BGP_ATTR_TYPE_UNKNOWN_ATTR BGP_ATTR_TYPE = 0 - BGP_ATTR_TYPE_ORIGIN BGP_ATTR_TYPE = 1 - BGP_ATTR_TYPE_AS_PATH BGP_ATTR_TYPE = 2 - BGP_ATTR_TYPE_NEXT_HOP BGP_ATTR_TYPE = 3 - BGP_ATTR_TYPE_MULTI_EXIT_DISC BGP_ATTR_TYPE = 4 - BGP_ATTR_TYPE_LOCAL_PREF BGP_ATTR_TYPE = 5 - BGP_ATTR_TYPE_ATOMIC_AGGREGATE BGP_ATTR_TYPE = 6 - BGP_ATTR_TYPE_AGGREGATOR BGP_ATTR_TYPE = 7 - BGP_ATTR_TYPE_COMMUNITIES BGP_ATTR_TYPE = 8 - BGP_ATTR_TYPE_ORIGINATOR_ID BGP_ATTR_TYPE = 9 - BGP_ATTR_TYPE_CLUSTER_LIST BGP_ATTR_TYPE = 10 - BGP_ATTR_TYPE_MP_REACH_NLRI BGP_ATTR_TYPE = 14 - BGP_ATTR_TYPE_MP_UNREACH_NLRI BGP_ATTR_TYPE = 15 - BGP_ATTR_TYPE_EXTENDED_COMMUNITIES BGP_ATTR_TYPE = 16 - BGP_ATTR_TYPE_AS4_PATH BGP_ATTR_TYPE = 17 - BGP_ATTR_TYPE_AS4_AGGREGATOR BGP_ATTR_TYPE = 18 - BGP_ATTR_TYPE_PMSI_TUNNEL BGP_ATTR_TYPE = 22 - BGP_ATTR_TYPE_TUNNEL_ENCAP BGP_ATTR_TYPE = 23 -) - -var BGP_ATTR_TYPE_name = map[int32]string{ - 0: "UNKNOWN_ATTR", - 1: "ORIGIN", - 2: "AS_PATH", - 3: "NEXT_HOP", - 4: "MULTI_EXIT_DISC", - 5: "LOCAL_PREF", - 6: "ATOMIC_AGGREGATE", - 7: "AGGREGATOR", - 8: "COMMUNITIES", - 9: "ORIGINATOR_ID", - 10: "CLUSTER_LIST", - 14: "MP_REACH_NLRI", - 15: "MP_UNREACH_NLRI", - 16: "EXTENDED_COMMUNITIES", - 17: "AS4_PATH", - 18: "AS4_AGGREGATOR", - 22: "PMSI_TUNNEL", - 23: "TUNNEL_ENCAP", -} -var BGP_ATTR_TYPE_value = map[string]int32{ - "UNKNOWN_ATTR": 0, - "ORIGIN": 1, - "AS_PATH": 2, - "NEXT_HOP": 3, - "MULTI_EXIT_DISC": 4, - "LOCAL_PREF": 5, - "ATOMIC_AGGREGATE": 6, - "AGGREGATOR": 7, - "COMMUNITIES": 8, - "ORIGINATOR_ID": 9, - "CLUSTER_LIST": 10, - "MP_REACH_NLRI": 14, - "MP_UNREACH_NLRI": 15, - "EXTENDED_COMMUNITIES": 16, - "AS4_PATH": 17, - "AS4_AGGREGATOR": 18, - "PMSI_TUNNEL": 22, - "TUNNEL_ENCAP": 23, -} - -func (x BGP_ATTR_TYPE) String() string { - return proto.EnumName(BGP_ATTR_TYPE_name, int32(x)) -} - type Error_ErrorCode int32 const ( @@ -519,64 +257,6 @@ func (x Error_ErrorCode) String() string { return proto.EnumName(Error_ErrorCode_name, int32(x)) } -type ExtendedCommunity_Type int32 - -const ( - ExtendedCommunity_TWO_OCTET_AS_SPECIFIC ExtendedCommunity_Type = 0 - ExtendedCommunity_IP4_SPECIFIC ExtendedCommunity_Type = 1 - ExtendedCommunity_FOUR_OCTET_AS_SPECIFIC ExtendedCommunity_Type = 2 - ExtendedCommunity_OPAQUE ExtendedCommunity_Type = 3 - ExtendedCommunity_EVPN ExtendedCommunity_Type = 4 -) - -var ExtendedCommunity_Type_name = map[int32]string{ - 0: "TWO_OCTET_AS_SPECIFIC", - 1: "IP4_SPECIFIC", - 2: "FOUR_OCTET_AS_SPECIFIC", - 3: "OPAQUE", - 4: "EVPN", -} -var ExtendedCommunity_Type_value = map[string]int32{ - "TWO_OCTET_AS_SPECIFIC": 0, - "IP4_SPECIFIC": 1, - "FOUR_OCTET_AS_SPECIFIC": 2, - "OPAQUE": 3, - "EVPN": 4, -} - -func (x ExtendedCommunity_Type) String() string { - return proto.EnumName(ExtendedCommunity_Type_name, int32(x)) -} - -type ExtendedCommunity_Subtype int32 - -const ( - ExtendedCommunity_ORIGIN_VALIDATION ExtendedCommunity_Subtype = 0 - ExtendedCommunity_ROUTE_TARGET ExtendedCommunity_Subtype = 2 - ExtendedCommunity_ROUTE_ORIGIN ExtendedCommunity_Subtype = 3 - ExtendedCommunity_ESI_LABEL ExtendedCommunity_Subtype = 4 - ExtendedCommunity_MAC_MOBILITY ExtendedCommunity_Subtype = 5 -) - -var ExtendedCommunity_Subtype_name = map[int32]string{ - 0: "ORIGIN_VALIDATION", - 2: "ROUTE_TARGET", - 3: "ROUTE_ORIGIN", - 4: "ESI_LABEL", - 5: "MAC_MOBILITY", -} -var ExtendedCommunity_Subtype_value = map[string]int32{ - "ORIGIN_VALIDATION": 0, - "ROUTE_TARGET": 2, - "ROUTE_ORIGIN": 3, - "ESI_LABEL": 4, - "MAC_MOBILITY": 5, -} - -func (x ExtendedCommunity_Subtype) String() string { - return proto.EnumName(ExtendedCommunity_Subtype_name, int32(x)) -} - type Error struct { Code Error_ErrorCode `protobuf:"varint,1,opt,name=code,enum=api.Error_ErrorCode" json:"code,omitempty"` Msg string `protobuf:"bytes,2,opt,name=msg" json:"msg,omitempty"` @@ -686,16 +366,6 @@ func (m *AddressFamily) Reset() { *m = AddressFamily{} } func (m *AddressFamily) String() string { return proto.CompactTextString(m) } func (*AddressFamily) ProtoMessage() {} -type RouteDistinguisher struct { - Type ROUTE_DISTINGUISHER_TYPE `protobuf:"varint,1,opt,name=type,enum=api.ROUTE_DISTINGUISHER_TYPE" json:"type,omitempty"` - Admin string `protobuf:"bytes,2,opt,name=admin" json:"admin,omitempty"` - Assigned uint32 `protobuf:"varint,3,opt,name=assigned" json:"assigned,omitempty"` -} - -func (m *RouteDistinguisher) Reset() { *m = RouteDistinguisher{} } -func (m *RouteDistinguisher) String() string { return proto.CompactTextString(m) } -func (*RouteDistinguisher) ProtoMessage() {} - type GracefulRestartTuple struct { Af *AddressFamily `protobuf:"bytes,1,opt,name=af" json:"af,omitempty"` Flags uint32 `protobuf:"varint,2,opt,name=flags" json:"flags,omitempty"` @@ -754,304 +424,21 @@ func (m *Capability) GetGracefulRestart() *GracefulRestart { return nil } -type Aggregator struct { - As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"` - Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` -} - -func (m *Aggregator) Reset() { *m = Aggregator{} } -func (m *Aggregator) String() string { return proto.CompactTextString(m) } -func (*Aggregator) ProtoMessage() {} - -type ExtendedCommunity struct { - Type ExtendedCommunity_Type `protobuf:"varint,1,opt,name=type,enum=api.ExtendedCommunity_Type" json:"type,omitempty"` - Subtype ExtendedCommunity_Subtype `protobuf:"varint,2,opt,name=subtype,enum=api.ExtendedCommunity_Subtype" json:"subtype,omitempty"` - IsTransitive bool `protobuf:"varint,3,opt,name=is_transitive" json:"is_transitive,omitempty"` - Asn uint32 `protobuf:"varint,4,opt,name=asn" json:"asn,omitempty"` - Ipv4 string `protobuf:"bytes,5,opt,name=ipv4" json:"ipv4,omitempty"` - LocalAdmin uint32 `protobuf:"varint,6,opt,name=local_admin" json:"local_admin,omitempty"` - IsSingleActive bool `protobuf:"varint,7,opt,name=is_single_active" json:"is_single_active,omitempty"` - Label uint32 `protobuf:"varint,8,opt,name=label" json:"label,omitempty"` - EsImport string `protobuf:"bytes,9,opt,name=es_import" json:"es_import,omitempty"` - Sequence uint32 `protobuf:"varint,10,opt,name=sequence" json:"sequence,omitempty"` - IsSticky bool `protobuf:"varint,11,opt,name=is_sticky" json:"is_sticky,omitempty"` -} - -func (m *ExtendedCommunity) Reset() { *m = ExtendedCommunity{} } -func (m *ExtendedCommunity) String() string { return proto.CompactTextString(m) } -func (*ExtendedCommunity) ProtoMessage() {} - -type EVPNNlri struct { - Type EVPN_TYPE `protobuf:"varint,1,opt,name=type,enum=api.EVPN_TYPE" json:"type,omitempty"` - // EvpnAutoDiscoveryRoute = 2; - MacIpAdv *EvpnMacIpAdvertisement `protobuf:"bytes,3,opt,name=mac_ip_adv" json:"mac_ip_adv,omitempty"` - MulticastEtag *EvpnInclusiveMulticastEthernetTag `protobuf:"bytes,4,opt,name=multicast_etag" json:"multicast_etag,omitempty"` -} - -func (m *EVPNNlri) Reset() { *m = EVPNNlri{} } -func (m *EVPNNlri) String() string { return proto.CompactTextString(m) } -func (*EVPNNlri) ProtoMessage() {} - -func (m *EVPNNlri) GetMacIpAdv() *EvpnMacIpAdvertisement { - if m != nil { - return m.MacIpAdv - } - return nil -} - -func (m *EVPNNlri) GetMulticastEtag() *EvpnInclusiveMulticastEthernetTag { - if m != nil { - return m.MulticastEtag - } - return nil -} - -type EvpnMacIpAdvertisement struct { - MacAddr string `protobuf:"bytes,1,opt,name=mac_addr" json:"mac_addr,omitempty"` - MacAddrLen uint32 `protobuf:"varint,2,opt,name=mac_addr_len" json:"mac_addr_len,omitempty"` - IpAddr string `protobuf:"bytes,3,opt,name=ip_addr" json:"ip_addr,omitempty"` - IpAddrLen uint32 `protobuf:"varint,4,opt,name=ip_addr_len" json:"ip_addr_len,omitempty"` - Rd string `protobuf:"bytes,5,opt,name=rd" json:"rd,omitempty"` - Esi string `protobuf:"bytes,6,opt,name=esi" json:"esi,omitempty"` - Etag uint32 `protobuf:"varint,7,opt,name=etag" json:"etag,omitempty"` - Labels []uint32 `protobuf:"varint,8,rep,name=labels" json:"labels,omitempty"` -} - -func (m *EvpnMacIpAdvertisement) Reset() { *m = EvpnMacIpAdvertisement{} } -func (m *EvpnMacIpAdvertisement) String() string { return proto.CompactTextString(m) } -func (*EvpnMacIpAdvertisement) ProtoMessage() {} - -type EvpnInclusiveMulticastEthernetTag struct { - Rd string `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` - Etag uint32 `protobuf:"varint,2,opt,name=etag" json:"etag,omitempty"` - IpAddr string `protobuf:"bytes,3,opt,name=ip_addr" json:"ip_addr,omitempty"` - IpAddrLen uint32 `protobuf:"varint,4,opt,name=ip_addr_len" json:"ip_addr_len,omitempty"` -} - -func (m *EvpnInclusiveMulticastEthernetTag) Reset() { *m = EvpnInclusiveMulticastEthernetTag{} } -func (m *EvpnInclusiveMulticastEthernetTag) String() string { return proto.CompactTextString(m) } -func (*EvpnInclusiveMulticastEthernetTag) ProtoMessage() {} - -type RTNlri struct { - Asn uint32 `protobuf:"varint,1,opt,name=asn" json:"asn,omitempty"` - Target *ExtendedCommunity `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"` - Length uint32 `protobuf:"varint,3,opt,name=length" json:"length,omitempty"` -} - -func (m *RTNlri) Reset() { *m = RTNlri{} } -func (m *RTNlri) String() string { return proto.CompactTextString(m) } -func (*RTNlri) ProtoMessage() {} - -func (m *RTNlri) GetTarget() *ExtendedCommunity { - if m != nil { - return m.Target - } - return nil -} - -type VPNNlri struct { - Rd *RouteDistinguisher `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` - Labels []uint32 `protobuf:"varint,2,rep,name=labels" json:"labels,omitempty"` - IpAddr string `protobuf:"bytes,3,opt,name=ip_addr" json:"ip_addr,omitempty"` - IpAddrLen uint32 `protobuf:"varint,4,opt,name=ip_addr_len" json:"ip_addr_len,omitempty"` -} - -func (m *VPNNlri) Reset() { *m = VPNNlri{} } -func (m *VPNNlri) String() string { return proto.CompactTextString(m) } -func (*VPNNlri) ProtoMessage() {} - -func (m *VPNNlri) GetRd() *RouteDistinguisher { - if m != nil { - return m.Rd - } - return nil -} - -type Nlri struct { - Af *AddressFamily `protobuf:"bytes,1,opt,name=af" json:"af,omitempty"` - Prefix string `protobuf:"bytes,2,opt,name=prefix" json:"prefix,omitempty"` - Nexthop string `protobuf:"bytes,3,opt,name=nexthop" json:"nexthop,omitempty"` - EvpnNlri *EVPNNlri `protobuf:"bytes,4,opt,name=evpn_nlri" json:"evpn_nlri,omitempty"` - RtNlri *RTNlri `protobuf:"bytes,5,opt,name=rt_nlri" json:"rt_nlri,omitempty"` - VpnNlri *VPNNlri `protobuf:"bytes,6,opt,name=vpn_nlri" json:"vpn_nlri,omitempty"` -} - -func (m *Nlri) Reset() { *m = Nlri{} } -func (m *Nlri) String() string { return proto.CompactTextString(m) } -func (*Nlri) ProtoMessage() {} - -func (m *Nlri) GetAf() *AddressFamily { - if m != nil { - return m.Af - } - return nil -} - -func (m *Nlri) GetEvpnNlri() *EVPNNlri { - if m != nil { - return m.EvpnNlri - } - return nil -} - -func (m *Nlri) GetRtNlri() *RTNlri { - if m != nil { - return m.RtNlri - } - return nil -} - -func (m *Nlri) GetVpnNlri() *VPNNlri { - if m != nil { - return m.VpnNlri - } - return nil -} - -type TunnelEncapSubTLV struct { - Type ENCAP_SUBTLV_TYPE `protobuf:"varint,1,opt,name=type,enum=api.ENCAP_SUBTLV_TYPE" json:"type,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` - Key uint32 `protobuf:"varint,3,opt,name=key" json:"key,omitempty"` - Cookie string `protobuf:"bytes,4,opt,name=cookie" json:"cookie,omitempty"` - Protocol uint32 `protobuf:"varint,5,opt,name=protocol" json:"protocol,omitempty"` - Color uint32 `protobuf:"varint,6,opt,name=color" json:"color,omitempty"` -} - -func (m *TunnelEncapSubTLV) Reset() { *m = TunnelEncapSubTLV{} } -func (m *TunnelEncapSubTLV) String() string { return proto.CompactTextString(m) } -func (*TunnelEncapSubTLV) ProtoMessage() {} - -type TunnelEncapTLV struct { - Type TUNNEL_TYPE `protobuf:"varint,1,opt,name=type,enum=api.TUNNEL_TYPE" json:"type,omitempty"` - SubTlv []*TunnelEncapSubTLV `protobuf:"bytes,2,rep,name=sub_tlv" json:"sub_tlv,omitempty"` -} - -func (m *TunnelEncapTLV) Reset() { *m = TunnelEncapTLV{} } -func (m *TunnelEncapTLV) String() string { return proto.CompactTextString(m) } -func (*TunnelEncapTLV) ProtoMessage() {} - -func (m *TunnelEncapTLV) GetSubTlv() []*TunnelEncapSubTLV { - if m != nil { - return m.SubTlv - } - return nil -} - -type PmsiTunnel struct { - IsLeafInfoRequired bool `protobuf:"varint,1,opt,name=is_leaf_info_required" json:"is_leaf_info_required,omitempty"` - Type PMSI_TUNNEL_TYPE `protobuf:"varint,2,opt,name=type,enum=api.PMSI_TUNNEL_TYPE" json:"type,omitempty"` - Label uint32 `protobuf:"varint,3,opt,name=label" json:"label,omitempty"` - TunnelId string `protobuf:"bytes,4,opt,name=tunnel_id" json:"tunnel_id,omitempty"` -} - -func (m *PmsiTunnel) Reset() { *m = PmsiTunnel{} } -func (m *PmsiTunnel) String() string { return proto.CompactTextString(m) } -func (*PmsiTunnel) ProtoMessage() {} - -type PathAttr struct { - Type BGP_ATTR_TYPE `protobuf:"varint,1,opt,name=type,enum=api.BGP_ATTR_TYPE" json:"type,omitempty"` - Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` - Origin Origin `protobuf:"varint,3,opt,name=origin,enum=api.Origin" json:"origin,omitempty"` - AsPaths []*AsPath `protobuf:"bytes,4,rep,name=as_paths" json:"as_paths,omitempty"` - Nexthop string `protobuf:"bytes,5,opt,name=nexthop" json:"nexthop,omitempty"` - Metric uint32 `protobuf:"varint,6,opt,name=metric" json:"metric,omitempty"` - Pref uint32 `protobuf:"varint,7,opt,name=pref" json:"pref,omitempty"` - Aggregator *Aggregator `protobuf:"bytes,8,opt,name=aggregator" json:"aggregator,omitempty"` - Communites []uint32 `protobuf:"varint,9,rep,name=communites" json:"communites,omitempty"` - Originator string `protobuf:"bytes,10,opt,name=originator" json:"originator,omitempty"` - Cluster []string `protobuf:"bytes,11,rep,name=cluster" json:"cluster,omitempty"` - Nlri []*Nlri `protobuf:"bytes,12,rep,name=nlri" json:"nlri,omitempty"` - TunnelEncap []*TunnelEncapTLV `protobuf:"bytes,13,rep,name=tunnel_encap" json:"tunnel_encap,omitempty"` - ExtendedCommunities []*ExtendedCommunity `protobuf:"bytes,16,rep,name=extended_communities" json:"extended_communities,omitempty"` - PmsiTunnel *PmsiTunnel `protobuf:"bytes,14,opt,name=pmsi_tunnel" json:"pmsi_tunnel,omitempty"` -} - -func (m *PathAttr) Reset() { *m = PathAttr{} } -func (m *PathAttr) String() string { return proto.CompactTextString(m) } -func (*PathAttr) ProtoMessage() {} - -func (m *PathAttr) GetAsPaths() []*AsPath { - if m != nil { - return m.AsPaths - } - return nil -} - -func (m *PathAttr) GetAggregator() *Aggregator { - if m != nil { - return m.Aggregator - } - return nil -} - -func (m *PathAttr) GetNlri() []*Nlri { - if m != nil { - return m.Nlri - } - return nil -} - -func (m *PathAttr) GetTunnelEncap() []*TunnelEncapTLV { - if m != nil { - return m.TunnelEncap - } - return nil -} - -func (m *PathAttr) GetExtendedCommunities() []*ExtendedCommunity { - if m != nil { - return m.ExtendedCommunities - } - return nil -} - -func (m *PathAttr) GetPmsiTunnel() *PmsiTunnel { - if m != nil { - return m.PmsiTunnel - } - return nil -} - -type AsPath struct { - SegmentType uint32 `protobuf:"varint,1,opt,name=segment_type" json:"segment_type,omitempty"` - Asns []uint32 `protobuf:"varint,2,rep,name=asns" json:"asns,omitempty"` -} - -func (m *AsPath) Reset() { *m = AsPath{} } -func (m *AsPath) String() string { return proto.CompactTextString(m) } -func (*AsPath) ProtoMessage() {} - type Path struct { - Nlri *Nlri `protobuf:"bytes,1,opt,name=nlri" json:"nlri,omitempty"` - Nexthop string `protobuf:"bytes,2,opt,name=nexthop" json:"nexthop,omitempty"` - Age int64 `protobuf:"varint,3,opt,name=age" json:"age,omitempty"` - Attrs []*PathAttr `protobuf:"bytes,4,rep,name=attrs" json:"attrs,omitempty"` - Best bool `protobuf:"varint,5,opt,name=best" json:"best,omitempty"` - IsWithdraw bool `protobuf:"varint,6,opt,name=is_withdraw" json:"is_withdraw,omitempty"` + Nlri []byte `protobuf:"bytes,1,opt,name=nlri,proto3" json:"nlri,omitempty"` + Pattrs [][]byte `protobuf:"bytes,2,rep,name=pattrs,proto3" json:"pattrs,omitempty"` + Age int64 `protobuf:"varint,3,opt,name=age" json:"age,omitempty"` + Best bool `protobuf:"varint,4,opt,name=best" json:"best,omitempty"` + IsWithdraw bool `protobuf:"varint,5,opt,name=is_withdraw" json:"is_withdraw,omitempty"` } func (m *Path) Reset() { *m = Path{} } func (m *Path) String() string { return proto.CompactTextString(m) } func (*Path) ProtoMessage() {} -func (m *Path) GetNlri() *Nlri { - if m != nil { - return m.Nlri - } - return nil -} - -func (m *Path) GetAttrs() []*PathAttr { - if m != nil { - return m.Attrs - } - return nil -} - type Destination struct { - Prefix string `protobuf:"bytes,1,opt,name=prefix" json:"prefix,omitempty"` - Paths []*Path `protobuf:"bytes,2,rep,name=paths" json:"paths,omitempty"` - BestPathIdx uint32 `protobuf:"varint,3,opt,name=best_path_idx" json:"best_path_idx,omitempty"` + Prefix string `protobuf:"bytes,1,opt,name=prefix" json:"prefix,omitempty"` + Paths []*Path `protobuf:"bytes,2,rep,name=paths" json:"paths,omitempty"` } func (m *Destination) Reset() { *m = Destination{} } @@ -1449,17 +836,8 @@ func init() { proto.RegisterEnum("api.Operation", Operation_name, Operation_value) proto.RegisterEnum("api.AFI", AFI_name, AFI_value) proto.RegisterEnum("api.SAFI", SAFI_name, SAFI_value) - proto.RegisterEnum("api.ROUTE_DISTINGUISHER_TYPE", ROUTE_DISTINGUISHER_TYPE_name, ROUTE_DISTINGUISHER_TYPE_value) proto.RegisterEnum("api.BGP_CAPABILITY", BGP_CAPABILITY_name, BGP_CAPABILITY_value) - proto.RegisterEnum("api.Origin", Origin_name, Origin_value) - proto.RegisterEnum("api.TUNNEL_TYPE", TUNNEL_TYPE_name, TUNNEL_TYPE_value) - proto.RegisterEnum("api.PMSI_TUNNEL_TYPE", PMSI_TUNNEL_TYPE_name, PMSI_TUNNEL_TYPE_value) - proto.RegisterEnum("api.EVPN_TYPE", EVPN_TYPE_name, EVPN_TYPE_value) - proto.RegisterEnum("api.ENCAP_SUBTLV_TYPE", ENCAP_SUBTLV_TYPE_name, ENCAP_SUBTLV_TYPE_value) - proto.RegisterEnum("api.BGP_ATTR_TYPE", BGP_ATTR_TYPE_name, BGP_ATTR_TYPE_value) proto.RegisterEnum("api.Error_ErrorCode", Error_ErrorCode_name, Error_ErrorCode_value) - proto.RegisterEnum("api.ExtendedCommunity_Type", ExtendedCommunity_Type_name, ExtendedCommunity_Type_value) - proto.RegisterEnum("api.ExtendedCommunity_Subtype", ExtendedCommunity_Subtype_name, ExtendedCommunity_Subtype_value) } // Client API for Grpc service @@ -1468,7 +846,6 @@ type GrpcClient interface { GetNeighbors(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetNeighborsClient, error) GetNeighbor(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Peer, error) GetRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetRibClient, error) - GetAdjRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetAdjRibClient, error) Reset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) SoftReset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) SoftResetIn(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) @@ -1487,7 +864,6 @@ type GrpcClient interface { GetMrt(ctx context.Context, in *MrtArguments, opts ...grpc.CallOption) (Grpc_GetMrtClient, error) GetRPKI(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetRPKIClient, error) GetVrfs(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetVrfsClient, error) - GetVrf(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetVrfClient, error) ModVrf(ctx context.Context, in *ModVrfArguments, opts ...grpc.CallOption) (*Error, error) } @@ -1572,38 +948,6 @@ func (x *grpcGetRibClient) Recv() (*Destination, error) { return m, nil } -func (c *grpcClient) GetAdjRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetAdjRibClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[2], c.cc, "/api.Grpc/GetAdjRib", opts...) - if err != nil { - return nil, err - } - x := &grpcGetAdjRibClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type Grpc_GetAdjRibClient interface { - Recv() (*Path, error) - grpc.ClientStream -} - -type grpcGetAdjRibClient struct { - grpc.ClientStream -} - -func (x *grpcGetAdjRibClient) Recv() (*Path, error) { - m := new(Path) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - func (c *grpcClient) Reset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) { out := new(Error) err := grpc.Invoke(ctx, "/api.Grpc/Reset", in, out, c.cc, opts...) @@ -1668,7 +1012,7 @@ func (c *grpcClient) Disable(ctx context.Context, in *Arguments, opts ...grpc.Ca } func (c *grpcClient) ModPath(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPathClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[3], c.cc, "/api.Grpc/ModPath", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[2], c.cc, "/api.Grpc/ModPath", opts...) if err != nil { return nil, err } @@ -1711,7 +1055,7 @@ func (c *grpcClient) GetNeighborPolicy(ctx context.Context, in *Arguments, opts } func (c *grpcClient) ModNeighborPolicy(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModNeighborPolicyClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[4], c.cc, "/api.Grpc/ModNeighborPolicy", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[3], c.cc, "/api.Grpc/ModNeighborPolicy", opts...) if err != nil { return nil, err } @@ -1742,7 +1086,7 @@ func (x *grpcModNeighborPolicyClient) Recv() (*Error, error) { } func (c *grpcClient) GetPolicyRoutePolicies(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyRoutePoliciesClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[5], c.cc, "/api.Grpc/GetPolicyRoutePolicies", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[4], c.cc, "/api.Grpc/GetPolicyRoutePolicies", opts...) if err != nil { return nil, err } @@ -1783,7 +1127,7 @@ func (c *grpcClient) GetPolicyRoutePolicy(ctx context.Context, in *PolicyArgumen } func (c *grpcClient) ModPolicyRoutePolicy(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPolicyRoutePolicyClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[6], c.cc, "/api.Grpc/ModPolicyRoutePolicy", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[5], c.cc, "/api.Grpc/ModPolicyRoutePolicy", opts...) if err != nil { return nil, err } @@ -1814,7 +1158,7 @@ func (x *grpcModPolicyRoutePolicyClient) Recv() (*Error, error) { } func (c *grpcClient) MonitorBestChanged(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_MonitorBestChangedClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[7], c.cc, "/api.Grpc/MonitorBestChanged", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[6], c.cc, "/api.Grpc/MonitorBestChanged", opts...) if err != nil { return nil, err } @@ -1829,7 +1173,7 @@ func (c *grpcClient) MonitorBestChanged(ctx context.Context, in *Arguments, opts } type Grpc_MonitorBestChangedClient interface { - Recv() (*Path, error) + Recv() (*Destination, error) grpc.ClientStream } @@ -1837,8 +1181,8 @@ type grpcMonitorBestChangedClient struct { grpc.ClientStream } -func (x *grpcMonitorBestChangedClient) Recv() (*Path, error) { - m := new(Path) +func (x *grpcMonitorBestChangedClient) Recv() (*Destination, error) { + m := new(Destination) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err } @@ -1846,7 +1190,7 @@ func (x *grpcMonitorBestChangedClient) Recv() (*Path, error) { } func (c *grpcClient) MonitorPeerState(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_MonitorPeerStateClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[8], c.cc, "/api.Grpc/MonitorPeerState", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[7], c.cc, "/api.Grpc/MonitorPeerState", opts...) if err != nil { return nil, err } @@ -1878,7 +1222,7 @@ func (x *grpcMonitorPeerStateClient) Recv() (*Peer, error) { } func (c *grpcClient) GetMrt(ctx context.Context, in *MrtArguments, opts ...grpc.CallOption) (Grpc_GetMrtClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[9], c.cc, "/api.Grpc/GetMrt", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[8], c.cc, "/api.Grpc/GetMrt", opts...) if err != nil { return nil, err } @@ -1910,7 +1254,7 @@ func (x *grpcGetMrtClient) Recv() (*MrtMessage, error) { } func (c *grpcClient) GetRPKI(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetRPKIClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[10], c.cc, "/api.Grpc/GetRPKI", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[9], c.cc, "/api.Grpc/GetRPKI", opts...) if err != nil { return nil, err } @@ -1942,7 +1286,7 @@ func (x *grpcGetRPKIClient) Recv() (*ROA, error) { } func (c *grpcClient) GetVrfs(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetVrfsClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[11], c.cc, "/api.Grpc/GetVrfs", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[10], c.cc, "/api.Grpc/GetVrfs", opts...) if err != nil { return nil, err } @@ -1973,38 +1317,6 @@ func (x *grpcGetVrfsClient) Recv() (*Vrf, error) { return m, nil } -func (c *grpcClient) GetVrf(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetVrfClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[12], c.cc, "/api.Grpc/GetVrf", opts...) - if err != nil { - return nil, err - } - x := &grpcGetVrfClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type Grpc_GetVrfClient interface { - Recv() (*Path, error) - grpc.ClientStream -} - -type grpcGetVrfClient struct { - grpc.ClientStream -} - -func (x *grpcGetVrfClient) Recv() (*Path, error) { - m := new(Path) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - func (c *grpcClient) ModVrf(ctx context.Context, in *ModVrfArguments, opts ...grpc.CallOption) (*Error, error) { out := new(Error) err := grpc.Invoke(ctx, "/api.Grpc/ModVrf", in, out, c.cc, opts...) @@ -2020,7 +1332,6 @@ type GrpcServer interface { GetNeighbors(*Arguments, Grpc_GetNeighborsServer) error GetNeighbor(context.Context, *Arguments) (*Peer, error) GetRib(*Arguments, Grpc_GetRibServer) error - GetAdjRib(*Arguments, Grpc_GetAdjRibServer) error Reset(context.Context, *Arguments) (*Error, error) SoftReset(context.Context, *Arguments) (*Error, error) SoftResetIn(context.Context, *Arguments) (*Error, error) @@ -2039,7 +1350,6 @@ type GrpcServer interface { GetMrt(*MrtArguments, Grpc_GetMrtServer) error GetRPKI(*Arguments, Grpc_GetRPKIServer) error GetVrfs(*Arguments, Grpc_GetVrfsServer) error - GetVrf(*Arguments, Grpc_GetVrfServer) error ModVrf(context.Context, *ModVrfArguments) (*Error, error) } @@ -2101,27 +1411,6 @@ func (x *grpcGetRibServer) Send(m *Destination) error { return x.ServerStream.SendMsg(m) } -func _Grpc_GetAdjRib_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(Arguments) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(GrpcServer).GetAdjRib(m, &grpcGetAdjRibServer{stream}) -} - -type Grpc_GetAdjRibServer interface { - Send(*Path) error - grpc.ServerStream -} - -type grpcGetAdjRibServer struct { - grpc.ServerStream -} - -func (x *grpcGetAdjRibServer) Send(m *Path) error { - return x.ServerStream.SendMsg(m) -} - func _Grpc_Reset_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { in := new(Arguments) if err := codec.Unmarshal(buf, in); err != nil { @@ -2338,7 +1627,7 @@ func _Grpc_MonitorBestChanged_Handler(srv interface{}, stream grpc.ServerStream) } type Grpc_MonitorBestChangedServer interface { - Send(*Path) error + Send(*Destination) error grpc.ServerStream } @@ -2346,7 +1635,7 @@ type grpcMonitorBestChangedServer struct { grpc.ServerStream } -func (x *grpcMonitorBestChangedServer) Send(m *Path) error { +func (x *grpcMonitorBestChangedServer) Send(m *Destination) error { return x.ServerStream.SendMsg(m) } @@ -2434,27 +1723,6 @@ func (x *grpcGetVrfsServer) Send(m *Vrf) error { return x.ServerStream.SendMsg(m) } -func _Grpc_GetVrf_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(Arguments) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(GrpcServer).GetVrf(m, &grpcGetVrfServer{stream}) -} - -type Grpc_GetVrfServer interface { - Send(*Path) error - grpc.ServerStream -} - -type grpcGetVrfServer struct { - grpc.ServerStream -} - -func (x *grpcGetVrfServer) Send(m *Path) error { - return x.ServerStream.SendMsg(m) -} - func _Grpc_ModVrf_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { in := new(ModVrfArguments) if err := codec.Unmarshal(buf, in); err != nil { @@ -2528,11 +1796,6 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{ ServerStreams: true, }, { - StreamName: "GetAdjRib", - Handler: _Grpc_GetAdjRib_Handler, - ServerStreams: true, - }, - { StreamName: "ModPath", Handler: _Grpc_ModPath_Handler, ClientStreams: true, @@ -2579,10 +1842,5 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{ Handler: _Grpc_GetVrfs_Handler, ServerStreams: true, }, - { - StreamName: "GetVrf", - Handler: _Grpc_GetVrf_Handler, - ServerStreams: true, - }, }, } diff --git a/api/gobgp.proto b/api/gobgp.proto index 5e6fc867..cfc8fffd 100644 --- a/api/gobgp.proto +++ b/api/gobgp.proto @@ -23,7 +23,6 @@ service Grpc { rpc GetNeighbors(Arguments) returns (stream Peer) {} rpc GetNeighbor(Arguments) returns (Peer) {} rpc GetRib(Arguments) returns (stream Destination) {} - rpc GetAdjRib(Arguments) returns (stream Path) {} rpc Reset(Arguments) returns (Error) {} rpc SoftReset(Arguments) returns (Error) {} rpc SoftResetIn(Arguments) returns (Error) {} @@ -37,12 +36,11 @@ service Grpc { rpc GetPolicyRoutePolicies(PolicyArguments) returns (stream PolicyDefinition) {} rpc GetPolicyRoutePolicy(PolicyArguments) returns (PolicyDefinition) {} rpc ModPolicyRoutePolicy(stream PolicyArguments) returns (stream Error) {} - rpc MonitorBestChanged(Arguments) returns (stream Path) {} + rpc MonitorBestChanged(Arguments) returns (stream Destination) {} rpc MonitorPeerState(Arguments) returns (stream Peer) {} rpc GetMrt(MrtArguments) returns (stream MrtMessage) {} rpc GetRPKI(Arguments) returns (stream ROA) {} rpc GetVrfs(Arguments) returns (stream Vrf) {} - rpc GetVrf(Arguments) returns (stream Path) {} rpc ModVrf(ModVrfArguments) returns (Error) {} } @@ -136,18 +134,6 @@ message AddressFamily { SAFI Safi = 2; } -enum ROUTE_DISTINGUISHER_TYPE { - TWO_OCTET_AS = 0; - IP4 = 1; - FOUR_OCTET_AS = 2; -} - -message RouteDistinguisher { - ROUTE_DISTINGUISHER_TYPE type = 1; - string admin = 2; - uint32 assigned = 3; -} - enum BGP_CAPABILITY { UNKNOWN_CAP = 0; MULTIPROTOCOL = 1; @@ -177,209 +163,17 @@ message Capability { uint32 asn = 4; } -enum Origin { - IGP = 0; - EGP = 1; - INCOMPLETE = 2; -} - -message Aggregator { - uint32 as = 1; - string address = 2; -} - -message ExtendedCommunity { - enum Type { - TWO_OCTET_AS_SPECIFIC = 0; - IP4_SPECIFIC = 1; - FOUR_OCTET_AS_SPECIFIC = 2; - OPAQUE = 3; - EVPN = 4; - } - Type type = 1; - enum Subtype { - ORIGIN_VALIDATION = 0; - ROUTE_TARGET = 2; - ROUTE_ORIGIN = 3; - ESI_LABEL = 4; - MAC_MOBILITY = 5; - } - Subtype subtype = 2; - bool is_transitive = 3; - uint32 asn = 4; - string ipv4 = 5; - uint32 local_admin = 6; - bool is_single_active = 7; - uint32 label = 8; - string es_import = 9; - uint32 sequence = 10; - bool is_sticky = 11; -} - -enum TUNNEL_TYPE { - UNKNOWN_TUNNEL_TYPE = 0; - L2TPV3_OVER_IP = 1; - GRE = 2; - IP_IN_IP = 7; - VXLAN = 8; - NVGRE = 9; - MPLS = 10; - MPLS_IN_GRE = 11; - VXLAN_GRE = 12; -} - -enum PMSI_TUNNEL_TYPE { - NO_TUNNEL = 0; - RSVP_TE_P2MP = 1; - MLDP_P2MP = 2; - PIM_SSM_TREE = 3; - PIM_SM_TREE = 4; - BIDIR_PIM_TREE = 5; - INGRESS_REPL = 6; - MLDP_MP2MP = 7; -} - -enum EVPN_TYPE { - UNKNOWN_EVPN_TYPE = 0; - ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY = 1; - ROUTE_TYPE_MAC_IP_ADVERTISEMENT = 2; - INCLUSIVE_MULTICAST_ETHERNET_TAG = 3; - ETHERNET_SEGMENT_ROUTE = 4; -} - -message EVPNNlri { - EVPN_TYPE type = 1; -// EvpnAutoDiscoveryRoute = 2; - EvpnMacIpAdvertisement mac_ip_adv = 3; - EvpnInclusiveMulticastEthernetTag multicast_etag = 4; -// EvpnEthernetSegmentRoute = 5; -} - -message EvpnMacIpAdvertisement { - string mac_addr = 1; - uint32 mac_addr_len = 2; - string ip_addr = 3; - uint32 ip_addr_len = 4; - string rd = 5; - string esi = 6; - uint32 etag = 7; - repeated uint32 labels = 8; -} - -message EvpnInclusiveMulticastEthernetTag { - string rd = 1; - uint32 etag = 2; - string ip_addr = 3; - uint32 ip_addr_len = 4; -} - -message RTNlri { - uint32 asn = 1; - ExtendedCommunity target = 2; - uint32 length = 3; -} - -message VPNNlri { - RouteDistinguisher rd = 1; - repeated uint32 labels = 2; - string ip_addr = 3; - uint32 ip_addr_len = 4; -} - -message Nlri { - AddressFamily af = 1; - string prefix = 2; - string nexthop = 3; - EVPNNlri evpn_nlri = 4; - RTNlri rt_nlri = 5; - VPNNlri vpn_nlri = 6; -} - -enum ENCAP_SUBTLV_TYPE { - UNKNOWN_SUBTLV_TYPE = 0; - ENCAPSULATION = 1; - PROTOCOL = 2; - COLOR = 4; -} - -message TunnelEncapSubTLV { - ENCAP_SUBTLV_TYPE type = 1; - string value = 2; - uint32 key = 3; - string cookie = 4; - uint32 protocol = 5; - uint32 color = 6; -} - -message TunnelEncapTLV { - TUNNEL_TYPE type = 1; - repeated TunnelEncapSubTLV sub_tlv = 2; -} - -message PmsiTunnel { - bool is_leaf_info_required = 1; - PMSI_TUNNEL_TYPE type = 2; - uint32 label = 3; - string tunnel_id = 4; -} - -enum BGP_ATTR_TYPE { - UNKNOWN_ATTR = 0; - ORIGIN = 1; - AS_PATH = 2; - NEXT_HOP = 3; - MULTI_EXIT_DISC = 4; - LOCAL_PREF = 5; - ATOMIC_AGGREGATE = 6; - AGGREGATOR = 7; - COMMUNITIES = 8; - ORIGINATOR_ID = 9; - CLUSTER_LIST = 10; - MP_REACH_NLRI = 14; - MP_UNREACH_NLRI = 15; - EXTENDED_COMMUNITIES = 16; - AS4_PATH = 17; - AS4_AGGREGATOR = 18; - PMSI_TUNNEL = 22; - TUNNEL_ENCAP = 23; -} - -message PathAttr { - BGP_ATTR_TYPE type = 1; - repeated string value = 2; - Origin origin = 3; - repeated AsPath as_paths = 4; - string nexthop = 5; - uint32 metric = 6; - uint32 pref = 7; - Aggregator aggregator = 8; - repeated uint32 communites = 9; - string originator = 10; - repeated string cluster = 11; - repeated Nlri nlri = 12; - repeated TunnelEncapTLV tunnel_encap = 13; - repeated ExtendedCommunity extended_communities = 16; - PmsiTunnel pmsi_tunnel = 14; -} - -message AsPath { - uint32 segment_type = 1; - repeated uint32 asns = 2; -} - message Path { - Nlri nlri = 1; - string nexthop = 2; + bytes nlri = 1; + repeated bytes pattrs = 2; int64 age = 3; - repeated PathAttr attrs = 4; - bool best = 5; - bool is_withdraw = 6; + bool best = 4; + bool is_withdraw = 5; } message Destination { string prefix = 1; repeated Path paths = 2; - uint32 best_path_idx = 3; } message PeerConf { diff --git a/gobgp/common.go b/gobgp/common.go index 7e4f2b20..b37f748c 100644 --- a/gobgp/common.go +++ b/gobgp/common.go @@ -19,6 +19,7 @@ import ( "bytes" "fmt" "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/packet" "google.golang.org/grpc" "net" "os" @@ -124,7 +125,77 @@ func cidr2prefix(cidr string) string { return buffer.String()[:ones] } -type paths []*api.Path +type Destination struct { + Prefix string `json:"prefix"` + Paths []*Path `json:"paths"` +} + +func ApiStruct2Destination(dst *api.Destination) (*Destination, error) { + paths := make([]*Path, 0, len(dst.Paths)) + for _, p := range dst.Paths { + path, err := ApiStruct2Path(p) + if err != nil { + return nil, err + } + paths = append(paths, path) + } + return &Destination{ + Prefix: dst.Prefix, + Paths: paths, + }, nil + +} + +type Path struct { + Nlri bgp.AddrPrefixInterface `json:"nlri"` + PathAttrs []bgp.PathAttributeInterface `json:"attrs"` + Age int64 `json:"age"` + Best bool `json:"best"` + IsWithdraw bool `json:"isWithdraw"` +} + +func ApiStruct2Path(p *api.Path) (*Path, error) { + var nlri bgp.AddrPrefixInterface + if len(p.Nlri) > 0 { + nlri = &bgp.NLRInfo{} + err := nlri.DecodeFromBytes(p.Nlri) + if err != nil { + return nil, err + } + } + + pattr := make([]bgp.PathAttributeInterface, 0, len(p.Pattrs)) + for _, attr := range p.Pattrs { + p, err := bgp.GetPathAttribute(attr) + if err != nil { + return nil, err + } + + err = p.DecodeFromBytes(attr) + if err != nil { + return nil, err + } + + switch p.GetType() { + case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI: + mpreach := p.(*bgp.PathAttributeMpReachNLRI) + if len(mpreach.Value) != 1 { + return nil, fmt.Errorf("include only one route in mp_reach_nlri") + } + nlri = mpreach.Value[0] + } + pattr = append(pattr, p) + } + return &Path{ + Nlri: nlri, + PathAttrs: pattr, + Age: p.Age, + Best: p.Best, + IsWithdraw: p.IsWithdraw, + }, nil +} + +type paths []*Path func (p paths) Len() int { return len(p) @@ -135,13 +206,13 @@ func (p paths) Swap(i, j int) { } func (p paths) Less(i, j int) bool { - if p[i].Nlri.Prefix == p[j].Nlri.Prefix { + if p[i].Nlri.String() == p[j].Nlri.String() { if p[i].Best { return true } } - strings := sort.StringSlice{cidr2prefix(p[i].Nlri.Prefix), - cidr2prefix(p[j].Nlri.Prefix)} + strings := sort.StringSlice{cidr2prefix(p[i].Nlri.String()), + cidr2prefix(p[j].Nlri.String())} return strings.Less(0, 1) } diff --git a/gobgp/monitor.go b/gobgp/monitor.go index ebd68716..0bb32bc8 100644 --- a/gobgp/monitor.go +++ b/gobgp/monitor.go @@ -46,18 +46,24 @@ func NewMonitorCmd() *cobra.Command { os.Exit(1) } for { - p, err := stream.Recv() + d, err := stream.Recv() if err == io.EOF { break } else if err != nil { fmt.Println(err) os.Exit(1) } + p, err := ApiStruct2Path(d.Paths[0]) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + if globalOpts.Json { j, _ := json.Marshal(p) fmt.Println(string(j)) } else { - showRoute([]*api.Path{p}, false, false, true) + showRoute([]*Path{p}, false, false, true) } } diff --git a/gobgp/neighbor.go b/gobgp/neighbor.go index 51d82dd3..bbd2954a 100644 --- a/gobgp/neighbor.go +++ b/gobgp/neighbor.go @@ -223,129 +223,80 @@ type AsPathFormat struct { separator string } -func showRoute(pathList []*api.Path, showAge bool, showBest bool, isMonitor bool) { +func showRoute(pathList []*Path, showAge bool, showBest bool, isMonitor bool) { var pathStrs [][]interface{} - maxPrefixLen := len("Network") - maxNexthopLen := len("Next Hop") - maxAsPathLen := len("AS_PATH") - - for _, p := range pathList { - aspath := func(attrs []*api.PathAttr) string { - - delimiter := make(map[int]*AsPathFormat) - delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SET] = &AsPathFormat{"{", "}", ","} - delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SEQ] = &AsPathFormat{"", "", " "} - delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ] = &AsPathFormat{"(", ")", " "} - delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET] = &AsPathFormat{"[", "]", ","} - - var segments []string = make([]string, 0) - for _, a := range attrs { - if a.Type == api.BGP_ATTR_TYPE_AS_PATH { - aspaths := a.AsPaths - for _, aspath := range aspaths { - s := bytes.NewBuffer(make([]byte, 0, 64)) - t := int(aspath.SegmentType) - start := delimiter[t].start - end := delimiter[t].end - separator := delimiter[t].separator - s.WriteString(start) - var asnsStr []string - for _, asn := range aspath.Asns { - asnsStr = append(asnsStr, fmt.Sprintf("%d", asn)) - } - s.WriteString(strings.Join(asnsStr, separator)) - s.WriteString(end) - segments = append(segments, s.String()) - } + maxPrefixLen := 20 + maxNexthopLen := 20 + maxAsPathLen := 20 + aspath := func(a bgp.PathAttributeInterface) string { + + delimiter := make(map[uint8]*AsPathFormat) + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SET] = &AsPathFormat{"{", "}", ","} + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SEQ] = &AsPathFormat{"", "", " "} + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ] = &AsPathFormat{"(", ")", " "} + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET] = &AsPathFormat{"[", "]", ","} + + var segments []string = make([]string, 0) + aspaths := a.(*bgp.PathAttributeAsPath).Value + for _, aspath := range aspaths { + var t uint8 + var asnsStr []string + switch aspath.(type) { + case *bgp.AsPathParam: + a := aspath.(*bgp.AsPathParam) + t = a.Type + for _, asn := range a.AS { + asnsStr = append(asnsStr, fmt.Sprintf("%d", asn)) } - } - return strings.Join(segments, " ") - } - formatAttrs := func(attrs []*api.PathAttr) string { - s := []string{} - for _, a := range attrs { - switch a.Type { - case api.BGP_ATTR_TYPE_ORIGIN: - s = append(s, fmt.Sprintf("{Origin: %s}", a.Origin)) - case api.BGP_ATTR_TYPE_MULTI_EXIT_DISC: - s = append(s, fmt.Sprintf("{Med: %d}", a.Metric)) - case api.BGP_ATTR_TYPE_LOCAL_PREF: - s = append(s, fmt.Sprintf("{LocalPref: %v}", a.Pref)) - case api.BGP_ATTR_TYPE_ATOMIC_AGGREGATE: - s = append(s, "AtomicAggregate") - case api.BGP_ATTR_TYPE_AGGREGATOR: - s = append(s, fmt.Sprintf("{Aggregate: {AS: %d, Address: %s}", a.GetAggregator().As, a.GetAggregator().Address)) - case api.BGP_ATTR_TYPE_COMMUNITIES: - l := []string{} - known := map[uint32]string{ - 0xffff0000: "planned-shut", - 0xffff0001: "accept-own", - 0xffff0002: "ROUTE_FILTER_TRANSLATED_v4", - 0xffff0003: "ROUTE_FILTER_v4", - 0xffff0004: "ROUTE_FILTER_TRANSLATED_v6", - 0xffff0005: "ROUTE_FILTER_v6", - 0xffff0006: "LLGR_STALE", - 0xffff0007: "NO_LLGR", - 0xFFFFFF01: "NO_EXPORT", - 0xFFFFFF02: "NO_ADVERTISE", - 0xFFFFFF03: "NO_EXPORT_SUBCONFED", - 0xFFFFFF04: "NOPEER"} - - for _, v := range a.Communites { - k, found := known[v] - if found { - l = append(l, fmt.Sprint(k)) - } else { - l = append(l, fmt.Sprintf("%d:%d", (0xffff0000&v)>>16, 0xffff&v)) - } - } - s = append(s, fmt.Sprintf("{Community: %v}", l)) - case api.BGP_ATTR_TYPE_ORIGINATOR_ID: - s = append(s, fmt.Sprintf("{Originator: %v}", a.Originator)) - case api.BGP_ATTR_TYPE_CLUSTER_LIST: - s = append(s, fmt.Sprintf("{Cluster: %v}", a.Cluster)) - case api.BGP_ATTR_TYPE_PMSI_TUNNEL: - info := a.PmsiTunnel - s1 := bytes.NewBuffer(make([]byte, 0, 64)) - s1.WriteString(fmt.Sprintf("{PMSI Tunnel: {Type: %s, ID: %s", info.Type, info.TunnelId)) - if info.Label > 0 { - s1.WriteString(fmt.Sprintf(", Label: %d", info.Label)) - } - if info.IsLeafInfoRequired { - s1.WriteString(fmt.Sprintf(", Leaf Info Required")) - } - s1.WriteString("}}") - s = append(s, s1.String()) - case api.BGP_ATTR_TYPE_TUNNEL_ENCAP: - s1 := bytes.NewBuffer(make([]byte, 0, 64)) - s1.WriteString("{Encap: ") - var s2 []string - for _, tlv := range a.TunnelEncap { - s3 := bytes.NewBuffer(make([]byte, 0, 64)) - s3.WriteString(fmt.Sprintf("< %s | ", tlv.Type)) - var s4 []string - for _, subTlv := range tlv.SubTlv { - if subTlv.Type == api.ENCAP_SUBTLV_TYPE_COLOR { - s4 = append(s4, fmt.Sprintf("color: %d", subTlv.Color)) - } - } - s3.WriteString(strings.Join(s4, ",")) - s3.WriteString(" >") - s2 = append(s2, s3.String()) - } - s1.WriteString(strings.Join(s2, "|")) - s1.WriteString("}") - s = append(s, s1.String()) - case api.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES: - s = append(s, fmt.Sprintf("{Ext Comms: %v}", a.ExtendedCommunities)) - case api.BGP_ATTR_TYPE_AS4_PATH, api.BGP_ATTR_TYPE_MP_REACH_NLRI, api.BGP_ATTR_TYPE_MP_UNREACH_NLRI, api.BGP_ATTR_TYPE_NEXT_HOP, api.BGP_ATTR_TYPE_AS_PATH: - default: - s = append(s, fmt.Sprintf("{%v: %v}", a.Type, a.Value)) + case *bgp.As4PathParam: + a := aspath.(*bgp.As4PathParam) + t = a.Type + for _, asn := range a.AS { + asnsStr = append(asnsStr, fmt.Sprintf("%d", asn)) } } - return fmt.Sprint(s) + s := bytes.NewBuffer(make([]byte, 0, 64)) + start := delimiter[t].start + end := delimiter[t].end + separator := delimiter[t].separator + s.WriteString(start) + s.WriteString(strings.Join(asnsStr, separator)) + s.WriteString(end) + segments = append(segments, s.String()) + } + return strings.Join(segments, " ") + } + + for _, p := range pathList { + var nexthop string + var aspathstr string + + s := []string{} + for _, a := range p.PathAttrs { + switch a.GetType() { + case bgp.BGP_ATTR_TYPE_NEXT_HOP: + nexthop = a.(*bgp.PathAttributeNextHop).Value.String() + case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI: + nexthop = a.(*bgp.PathAttributeMpReachNLRI).Nexthop.String() + case bgp.BGP_ATTR_TYPE_AS_PATH: + aspathstr = aspath(a) + case bgp.BGP_ATTR_TYPE_AS4_PATH: + continue + default: + s = append(s, a.String()) + } + } + pattrstr := fmt.Sprint(s) + + if maxNexthopLen < len(nexthop) { + maxNexthopLen = len(nexthop) + } + + if maxAsPathLen < len(aspathstr) { + maxAsPathLen = len(aspathstr) } + best := "" if showBest { if p.Best { @@ -355,27 +306,20 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool, isMonitor bool } } - if maxPrefixLen < len(p.Nlri.Prefix) { - maxPrefixLen = len(p.Nlri.Prefix) - } - - if maxNexthopLen < len(p.Nexthop) { - maxNexthopLen = len(p.Nexthop) + if maxPrefixLen < len(p.Nlri.String()) { + maxPrefixLen = len(p.Nlri.String()) } - if maxAsPathLen < len(aspath(p.Attrs)) { - maxAsPathLen = len(aspath(p.Attrs)) - } if isMonitor { title := "ROUTE" if p.IsWithdraw { title = "DELROUTE" } - pathStrs = append(pathStrs, []interface{}{title, p.Nlri.Prefix, p.Nexthop, aspath(p.Attrs), formatAttrs(p.Attrs)}) + pathStrs = append(pathStrs, []interface{}{title, p.Nlri.String(), nexthop, aspathstr, pattrstr}) } else if showAge { - pathStrs = append(pathStrs, []interface{}{best, p.Nlri.Prefix, p.Nexthop, aspath(p.Attrs), formatTimedelta(p.Age), formatAttrs(p.Attrs)}) + pathStrs = append(pathStrs, []interface{}{best, p.Nlri.String(), nexthop, aspathstr, formatTimedelta(p.Age), pattrstr}) } else { - pathStrs = append(pathStrs, []interface{}{best, p.Nlri.Prefix, p.Nexthop, aspath(p.Attrs), formatAttrs(p.Attrs)}) + pathStrs = append(pathStrs, []interface{}{best, p.Nlri.String(), nexthop, aspathstr, pattrstr}) } } @@ -397,14 +341,19 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool, isMonitor bool func showNeighborRib(r string, name string, args []string) error { var resource api.Resource + showBest := false + showAge := true switch r { case CMD_GLOBAL: + showBest = true resource = api.Resource_GLOBAL case CMD_LOCAL: + showBest = true resource = api.Resource_LOCAL case CMD_ADJ_IN: resource = api.Resource_ADJ_IN case CMD_ADJ_OUT: + showAge = false resource = api.Resource_ADJ_OUT case CMD_VRF: resource = api.Resource_VRF @@ -437,107 +386,54 @@ func showNeighborRib(r string, name string, args []string) error { Name: name, } - ps := paths{} - showBest := false - showAge := true - - var stream interface { - Recv() (*api.Path, error) + stream, err := client.GetRib(context.Background(), arg) + if err != nil { + return err } - switch resource { - case api.Resource_LOCAL, api.Resource_GLOBAL: - showBest = true - stream, e := client.GetRib(context.Background(), arg) - if e != nil { + dsts := []*Destination{} + maxOnes := 0 + for { + d, e := stream.Recv() + if e == io.EOF { + break + } else if e != nil { return e } - - ds := []*api.Destination{} - maxOnes := 0 - for { - d, e := stream.Recv() - if e == io.EOF { - break - } else if e != nil { - return e - } - if prefix != "" && prefix != d.Prefix { - continue - } - if host != nil { - _, prefix, _ := net.ParseCIDR(d.Prefix) - ones, _ := prefix.Mask.Size() - if maxOnes < ones && prefix.Contains(host) { - ds = []*api.Destination{} + if prefix != "" && prefix != d.Prefix { + continue + } + if host != nil { + _, prefix, _ := net.ParseCIDR(d.Prefix) + ones, _ := prefix.Mask.Size() + if prefix.Contains(host) { + if maxOnes < ones { + dsts = []*Destination{} maxOnes = ones - } else { + } else if maxOnes > ones { continue } + } else { + continue } - ds = append(ds, d) } - if globalOpts.Json { - j, _ := json.Marshal(ds) - fmt.Println(string(j)) - return nil - } - - for _, d := range ds { - for idx, p := range d.Paths { - if idx == int(d.BestPathIdx) { - p.Best = true - } - ps = append(ps, p) - } - } - case api.Resource_ADJ_OUT: - showAge = false - fallthrough - case api.Resource_ADJ_IN: - stream, err = client.GetAdjRib(context.Background(), arg) - fallthrough - case api.Resource_VRF: - if stream == nil { - stream, err = client.GetVrf(context.Background(), arg) - } + dst, err := ApiStruct2Destination(d) if err != nil { return err } - maxOnes := 0 - for { - p, e := stream.Recv() - if e == io.EOF { - break - } else if e != nil { - return e - } - if prefix != "" && prefix != p.Nlri.Prefix { - continue - } - if host != nil { - _, prefix, _ := net.ParseCIDR(p.Nlri.Prefix) - ones, _ := prefix.Mask.Size() - if prefix.Contains(host) { - if maxOnes < ones { - ps = paths{} - maxOnes = ones - } else if maxOnes > ones { - continue - } - } else { - continue - } - } + dsts = append(dsts, dst) + } - ps = append(ps, p) - } - if globalOpts.Json { - j, _ := json.Marshal(ps) - fmt.Println(string(j)) - return nil - } + if globalOpts.Json { + j, _ := json.Marshal(dsts) + fmt.Println(string(j)) + return nil + } + + ps := paths{} + for _, dst := range dsts { + ps = append(ps, dst.Paths...) } if len(ps) == 0 { diff --git a/packet/bgp.go b/packet/bgp.go index 62be473a..a8b73864 100644 --- a/packet/bgp.go +++ b/packet/bgp.go @@ -601,7 +601,7 @@ type AddrPrefixInterface interface { SAFI() uint8 Len() int String() string - ToApiStruct() *api.Nlri + MarshalJSON() ([]byte, error) } type IPAddrPrefixDefault struct { @@ -647,6 +647,14 @@ func (r *IPAddrPrefixDefault) String() string { return fmt.Sprintf("%s/%d", r.Prefix.String(), r.Length) } +func (r *IPAddrPrefixDefault) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Prefix string `json:"prefix"` + }{ + Prefix: r.String(), + }) +} + type IPAddrPrefix struct { IPAddrPrefixDefault addrlen uint8 @@ -683,13 +691,6 @@ func (r *IPAddrPrefix) SAFI() uint8 { return SAFI_UNICAST } -func (r *IPAddrPrefix) ToApiStruct() *api.Nlri { - return &api.Nlri{ - Af: &api.AddressFamily{api.AFI(r.AFI()), api.SAFI(r.SAFI())}, - Prefix: r.String(), - } -} - func NewIPAddrPrefix(length uint8, prefix string) *IPAddrPrefix { return &IPAddrPrefix{ IPAddrPrefixDefault{length, net.ParseIP(prefix).To4()}, @@ -1053,13 +1054,6 @@ func (l *LabeledVPNIPAddrPrefix) SAFI() uint8 { return SAFI_MPLS_VPN } -func (l *LabeledVPNIPAddrPrefix) ToApiStruct() *api.Nlri { - return &api.Nlri{ - Af: &api.AddressFamily{api.AFI(l.AFI()), api.SAFI(l.SAFI())}, - Prefix: l.String(), - } -} - func (l *LabeledVPNIPAddrPrefix) String() string { masklen := l.IPAddrPrefixDefault.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) return fmt.Sprintf("%s:%s/%d", l.RD, l.IPAddrPrefixDefault.Prefix, masklen) @@ -1115,13 +1109,6 @@ func (r *LabeledIPAddrPrefix) SAFI() uint8 { return SAFI_MPLS_LABEL } -func (r *LabeledIPAddrPrefix) ToApiStruct() *api.Nlri { - return &api.Nlri{ - Af: &api.AddressFamily{api.AFI(r.AFI()), api.SAFI(r.SAFI())}, - Prefix: r.String(), - } -} - func (r *IPAddrPrefix) decodeNextHop(data []byte) net.IP { if r.addrlen == 0 { r.addrlen = 4 @@ -1254,20 +1241,12 @@ func (n *RouteTargetMembershipNLRI) String() string { return fmt.Sprintf("%d:%s", n.AS, target) } -func (n *RouteTargetMembershipNLRI) ToApiStruct() *api.Nlri { - var target *api.ExtendedCommunity - if n.RouteTarget != nil { - target = n.RouteTarget.ToApiStruct() - } - return &api.Nlri{ - Af: &api.AddressFamily{api.AFI(n.AFI()), api.SAFI(n.SAFI())}, +func (n *RouteTargetMembershipNLRI) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Prefix string `json:"prefix"` + }{ Prefix: n.String(), - RtNlri: &api.RTNlri{ - Asn: n.AS, - Target: target, - Length: uint32(n.Length), - }, - } + }) } func NewRouteTargetMembershipNLRI(as uint32, target ExtendedCommunityInterface) *RouteTargetMembershipNLRI { @@ -1522,19 +1501,6 @@ func (er *EVPNMacIPAdvertisementRoute) Serialize() ([]byte, error) { return buf, nil } -func (er *EVPNMacIPAdvertisementRoute) ToApiStruct() *api.EvpnMacIpAdvertisement { - return &api.EvpnMacIpAdvertisement{ - MacAddr: er.MacAddress.String(), - MacAddrLen: uint32(er.MacAddressLength), - IpAddr: er.IPAddress.String(), - IpAddrLen: uint32(er.IPAddressLength), - Rd: er.RD.String(), - Esi: er.ESI.String(), - Etag: er.ETag, - Labels: er.Labels, - } -} - func (er *EVPNMacIPAdvertisementRoute) String() string { return fmt.Sprintf("[type:macadv][rd:%s][esi:%s][etag:%d][mac:%s][ip:%s][labels:%v]", er.RD, er.ESI.String(), er.ETag, er.MacAddress, er.IPAddress, er.Labels) } @@ -1589,15 +1555,6 @@ func (er *EVPNMulticastEthernetTagRoute) Serialize() ([]byte, error) { return buf, nil } -func (er *EVPNMulticastEthernetTagRoute) ToApiStruct() *api.EvpnInclusiveMulticastEthernetTag { - return &api.EvpnInclusiveMulticastEthernetTag{ - Rd: er.RD.String(), - Etag: er.ETag, - IpAddr: er.IPAddress.String(), - IpAddrLen: uint32(er.IPAddressLength), - } -} - func (er *EVPNMulticastEthernetTagRoute) String() string { return fmt.Sprintf("[type:multicast][rd:%s][etag:%d][ip:%s]", er.RD, er.ETag, er.IPAddress) } @@ -1739,23 +1696,12 @@ func (n *EVPNNLRI) String() string { return fmt.Sprintf("%d:%d", n.RouteType, n.Length) } -func (n *EVPNNLRI) ToApiStruct() *api.Nlri { - evpn := &api.EVPNNlri{} - switch n.RouteType { - case EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT: - evpn.Type = api.EVPN_TYPE_ROUTE_TYPE_MAC_IP_ADVERTISEMENT - macIpAdv := n.RouteTypeData.(*EVPNMacIPAdvertisementRoute).ToApiStruct() - evpn.MacIpAdv = macIpAdv - case EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG: - evpn.Type = api.EVPN_TYPE_INCLUSIVE_MULTICAST_ETHERNET_TAG - eTag := n.RouteTypeData.(*EVPNMulticastEthernetTagRoute).ToApiStruct() - evpn.MulticastEtag = eTag - } - return &api.Nlri{ - Af: &api.AddressFamily{api.AFI(n.AFI()), api.SAFI(n.SAFI())}, - Prefix: n.String(), - EvpnNlri: evpn, - } +func (n *EVPNNLRI) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Prefix string `json:"prefix"` + }{ + Prefix: n.String(), + }) } func NewEVPNNLRI(routetype uint8, length uint8, routetypedata EVPNRouteTypeInterface) *EVPNNLRI { @@ -1810,13 +1756,6 @@ func (n *EncapNLRI) SAFI() uint8 { return SAFI_ENCAPSULATION } -func (n *EncapNLRI) ToApiStruct() *api.Nlri { - return &api.Nlri{ - Af: &api.AddressFamily{api.AFI(n.AFI()), api.SAFI(n.SAFI())}, - Prefix: n.String(), - } -} - func NewEncapNLRI(endpoint string) *EncapNLRI { return &EncapNLRI{ IPAddrPrefixDefault{0, net.ParseIP(endpoint)}, @@ -2062,7 +2001,8 @@ type PathAttributeInterface interface { Len() int getFlags() BGPAttrFlag GetType() BGPAttrType - ToApiStruct() *api.PathAttr + String() string + MarshalJSON() ([]byte, error) } type PathAttribute struct { @@ -2147,19 +2087,45 @@ func (p *PathAttribute) Serialize() ([]byte, error) { return buf, nil } +func (p *PathAttribute) String() string { + return fmt.Sprintf("%s %s %s", p.Type, p.Flags, []byte(p.Value)) +} + +func (p *PathAttribute) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value []byte `json:"value"` + }{ + Type: p.GetType(), + Value: p.Value, + }) +} + type PathAttributeOrigin struct { PathAttribute } -func (p *PathAttributeOrigin) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_ORIGIN, - Origin: api.Origin(uint8(p.Value[0])), +func (p *PathAttributeOrigin) String() string { + typ := "-" + switch p.Value[0] { + case BGP_ORIGIN_ATTR_TYPE_IGP: + typ = "i" + case BGP_ORIGIN_ATTR_TYPE_EGP: + typ = "e" + case BGP_ORIGIN_ATTR_TYPE_INCOMPLETE: + typ = "?" } + return fmt.Sprintf("{Origin: %s}", typ) } func (p *PathAttributeOrigin) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value uint8 `json:"value"` + }{ + Type: p.GetType(), + Value: p.Value[0], + }) } func NewPathAttributeOrigin(value uint8) *PathAttributeOrigin { @@ -2174,6 +2140,14 @@ func NewPathAttributeOrigin(value uint8) *PathAttributeOrigin { } } +type AsPathParamInterface interface { + Serialize() ([]byte, error) + DecodeFromBytes([]byte) error + Len() int + ASLen() int + MarshalJSON() ([]byte, error) +} + type AsPathParam struct { Type uint8 Num uint8 @@ -2225,6 +2199,18 @@ func (a *AsPathParam) ASLen() int { return 0 } +func (a *AsPathParam) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type uint8 `json:"segment_type"` + Num uint8 `json:"num"` + AS []uint16 `json:"asns"` + }{ + Type: a.Type, + Num: a.Num, + AS: a.AS, + }) +} + func NewAsPathParam(segType uint8, as []uint16) *AsPathParam { return &AsPathParam{ Type: segType, @@ -2284,6 +2270,18 @@ func (a *As4PathParam) ASLen() int { return 0 } +func (a *As4PathParam) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type uint8 `json:"segment_type"` + Num uint8 `json:"num"` + AS []uint32 `json:"asns"` + }{ + Type: a.Type, + Num: a.Num, + AS: a.AS, + }) +} + func NewAs4PathParam(segType uint8, as []uint32) *As4PathParam { return &As4PathParam{ Type: segType, @@ -2341,13 +2339,6 @@ func (p *DefaultAsPath) isValidAspath(data []byte) (bool, error) { return false, NewMessageError(eCode, eSubCode, nil, "can't parse AS_PATH") } -type AsPathParamInterface interface { - Serialize() ([]byte, error) - DecodeFromBytes([]byte) error - Len() int - ASLen() int -} - type PathAttributeAsPath struct { DefaultAsPath PathAttribute @@ -2402,33 +2393,14 @@ func (p *PathAttributeAsPath) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeAsPath) ToApiStruct() *api.PathAttr { - aspaths := make([]*api.AsPath, 0) - for _, a := range p.Value { - path, y := a.(*As4PathParam) - aspath := &api.AsPath{} - if y { - aspath.Asns = path.AS - aspath.SegmentType = uint32(path.Type) - } else { - path := a.(*AsPathParam) - asns := make([]uint32, 0) - for _, v := range path.AS { - asns = append(asns, uint32(v)) - } - aspath.Asns = asns - aspath.SegmentType = uint32(path.Type) - } - aspaths = append(aspaths, aspath) - } - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_AS_PATH, - AsPaths: aspaths, - } -} - func (p *PathAttributeAsPath) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value []AsPathParamInterface `json:"as_paths"` + }{ + Type: p.GetType(), + Value: p.Value, + }) } func NewPathAttributeAsPath(value []AsPathParamInterface) *PathAttributeAsPath { @@ -2466,15 +2438,18 @@ func (p *PathAttributeNextHop) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeNextHop) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_NEXT_HOP, - Nexthop: p.Value.String(), - } +func (p *PathAttributeNextHop) String() string { + return fmt.Sprintf("{Nexthop: %s}", p.Value) } func (p *PathAttributeNextHop) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value string `json:"nexthop"` + }{ + Type: p.GetType(), + Value: p.Value.String(), + }) } func NewPathAttributeNextHop(value string) *PathAttributeNextHop { @@ -2514,15 +2489,18 @@ func (p *PathAttributeMultiExitDisc) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeMultiExitDisc) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_MULTI_EXIT_DISC, - Metric: p.Value, - } +func (p *PathAttributeMultiExitDisc) String() string { + return fmt.Sprintf("{Med: %d}", p.Value) } func (p *PathAttributeMultiExitDisc) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value uint32 `json:"metric"` + }{ + Type: p.GetType(), + Value: p.Value, + }) } func NewPathAttributeMultiExitDisc(value uint32) *PathAttributeMultiExitDisc { @@ -2562,15 +2540,18 @@ func (p *PathAttributeLocalPref) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeLocalPref) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_LOCAL_PREF, - Pref: p.Value, - } +func (p *PathAttributeLocalPref) String() string { + return fmt.Sprintf("{LocalPref: %d}", p.Value) } func (p *PathAttributeLocalPref) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value uint32 `json:"value"` + }{ + Type: p.GetType(), + Value: p.Value, + }) } func NewPathAttributeLocalPref(value uint32) *PathAttributeLocalPref { @@ -2588,14 +2569,16 @@ type PathAttributeAtomicAggregate struct { PathAttribute } -func (p *PathAttributeAtomicAggregate) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_ATOMIC_AGGREGATE, - } +func (p *PathAttributeAtomicAggregate) String() string { + return "{AtomicAggregate}" } func (p *PathAttributeAtomicAggregate) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + }{ + Type: p.GetType(), + }) } func NewPathAttributeAtomicAggregate() *PathAttributeAtomicAggregate { @@ -2658,18 +2641,20 @@ func (p *PathAttributeAggregator) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeAggregator) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_AGGREGATOR, - Aggregator: &api.Aggregator{ - As: p.Value.AS, - Address: p.Value.Address.String(), - }, - } +func (p *PathAttributeAggregator) String() string { + return fmt.Sprintf("{Aggregate: {AS: %d, Address: %s}}", p.Value.AS, p.Value.Address) } func (p *PathAttributeAggregator) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + AS uint32 `json:"as"` + Address string `json:"address"` + }{ + Type: p.GetType(), + AS: p.Value.AS, + Address: p.Value.Address.String(), + }) } func NewPathAttributeAggregator(as interface{}, address string) *PathAttributeAggregator { @@ -2720,15 +2705,49 @@ func (p *PathAttributeCommunities) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeCommunities) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_COMMUNITIES, - Communites: p.Value, +func (p *PathAttributeCommunities) String() string { + l := []string{} + for _, v := range p.Value { + switch v { + case 0xffff0000: + l = append(l, "planned-shut") + case 0xffff0001: + l = append(l, "accept-own") + case 0xffff0002: + l = append(l, "ROUTE_FILTER_TRANSLATED_v4") + case 0xffff0003: + l = append(l, "ROUTE_FILTER_v4") + case 0xffff0004: + l = append(l, "ROUTE_FILTER_TRANSLATED_v6") + case 0xffff0005: + l = append(l, "ROUTE_FILTER_v6") + case 0xffff0006: + l = append(l, "LLGR_STALE") + case 0xffff0007: + l = append(l, "NO_LLGR") + case 0xffffff01: + l = append(l, "NO_EXPORT") + case 0xffffff02: + l = append(l, "NO_ADVERTISE") + case 0xffffff03: + l = append(l, "NO_EXPORT_SUBCONFED") + case 0xffffff04: + l = append(l, "NO_PEER") + default: + l = append(l, fmt.Sprintf("%d:%d", (0xffff0000&v)>>16, 0xffff&v)) + } } + return fmt.Sprintf("{Communities: %s}", strings.Join(l, ", ")) } func (p *PathAttributeCommunities) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value []uint32 `json:"communities"` + }{ + Type: p.GetType(), + Value: p.Value, + }) } func NewPathAttributeCommunities(value []uint32) *PathAttributeCommunities { @@ -2762,6 +2781,20 @@ func (p *PathAttributeOriginatorId) DecodeFromBytes(data []byte) error { return nil } +func (p *PathAttributeOriginatorId) String() string { + return fmt.Sprintf("{Originator: %s}", p.Value) +} + +func (p *PathAttributeOriginatorId) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value string `json:"value"` + }{ + Type: p.GetType(), + Value: p.Value.String(), + }) +} + func (p *PathAttributeOriginatorId) Serialize() ([]byte, error) { buf := make([]byte, 4) copy(buf, p.Value) @@ -2769,17 +2802,6 @@ func (p *PathAttributeOriginatorId) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeOriginatorId) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_ORIGINATOR_ID, - Originator: p.Value.String(), - } -} - -func (p *PathAttributeOriginatorId) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) -} - func NewPathAttributeOriginatorId(value string) *PathAttributeOriginatorId { t := BGP_ATTR_TYPE_ORIGINATOR_ID return &PathAttributeOriginatorId{ @@ -2824,19 +2846,22 @@ func (p *PathAttributeClusterList) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeClusterList) ToApiStruct() *api.PathAttr { - l := make([]string, 0) - for _, addr := range p.Value { - l = append(l, addr.String()) - } - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_CLUSTER_LIST, - Cluster: l, - } +func (p *PathAttributeClusterList) String() string { + return fmt.Sprintf("{ClusterList: %v}", p.Value) } func (p *PathAttributeClusterList) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + value := make([]string, 0, len(p.Value)) + for _, v := range p.Value { + value = append(value, v.String()) + } + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value []string `json:"value"` + }{ + Type: p.GetType(), + Value: value, + }) } func NewPathAttributeClusterList(value []string) *PathAttributeClusterList { @@ -2965,20 +2990,20 @@ func (p *PathAttributeMpReachNLRI) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeMpReachNLRI) ToApiStruct() *api.PathAttr { - nlri := make([]*api.Nlri, 0, len(p.Value)) - for _, v := range p.Value { - nlri = append(nlri, v.ToApiStruct()) - } - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_MP_REACH_NLRI, - Nexthop: p.Nexthop.String(), - Nlri: nlri, - } -} - func (p *PathAttributeMpReachNLRI) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Nexthop string `json:"nexthop"` + AFI uint16 `json:"afi"` + SAFI uint8 `json:"safi"` + Value []AddrPrefixInterface `json:"value"` + }{ + Type: p.GetType(), + Nexthop: p.Nexthop.String(), + AFI: p.AFI, + SAFI: p.SAFI, + Value: p.Value, + }) } func NewPathAttributeMpReachNLRI(nexthop string, nlri []AddrPrefixInterface) *PathAttributeMpReachNLRI { @@ -3063,16 +3088,6 @@ func (p *PathAttributeMpUnreachNLRI) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeMpUnreachNLRI) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_MP_UNREACH_NLRI, - } -} - -func (p *PathAttributeMpUnreachNLRI) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) -} - func NewPathAttributeMpUnreachNLRI(nlri []AddrPrefixInterface) *PathAttributeMpUnreachNLRI { t := BGP_ATTR_TYPE_MP_UNREACH_NLRI p := &PathAttributeMpUnreachNLRI{ @@ -3094,7 +3109,7 @@ type ExtendedCommunityInterface interface { Serialize() ([]byte, error) String() string GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) - ToApiStruct() *api.ExtendedCommunity + MarshalJSON() ([]byte, error) } type TwoOctetAsSpecificExtended struct { @@ -3121,6 +3136,19 @@ func (e *TwoOctetAsSpecificExtended) String() string { return fmt.Sprintf("%d:%d", e.AS, e.LocalAdmin) } +func (e *TwoOctetAsSpecificExtended) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Value string `json:"value"` + }{ + Type: t, + Subtype: s, + Value: e.String(), + }) +} + func (e *TwoOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { t := EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC if !e.IsTransitive { @@ -3129,16 +3157,6 @@ func (e *TwoOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, Exte return t, e.SubType } -func (e *TwoOctetAsSpecificExtended) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{ - Type: api.ExtendedCommunity_TWO_OCTET_AS_SPECIFIC, - Subtype: api.ExtendedCommunity_Subtype(e.SubType), - IsTransitive: e.IsTransitive, - Asn: uint32(e.AS), - LocalAdmin: e.LocalAdmin, - } -} - func NewTwoOctetAsSpecificExtended(as uint16, localAdmin uint32, isTransitive bool) *TwoOctetAsSpecificExtended { return &TwoOctetAsSpecificExtended{ SubType: ExtendedCommunityAttrSubType(EC_SUBTYPE_ROUTE_TARGET), @@ -3172,6 +3190,19 @@ func (e *IPv4AddressSpecificExtended) String() string { return fmt.Sprintf("%s:%d", e.IPv4.String(), e.LocalAdmin) } +func (e *IPv4AddressSpecificExtended) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Value string `json:"value"` + }{ + Type: t, + Subtype: s, + Value: e.String(), + }) +} + func (e *IPv4AddressSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { t := EC_TYPE_TRANSITIVE_IP4_SPECIFIC if !e.IsTransitive { @@ -3180,16 +3211,6 @@ func (e *IPv4AddressSpecificExtended) GetTypes() (ExtendedCommunityAttrType, Ext return t, e.SubType } -func (e *IPv4AddressSpecificExtended) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{ - Type: api.ExtendedCommunity_IP4_SPECIFIC, - Subtype: api.ExtendedCommunity_Subtype(e.SubType), - IsTransitive: e.IsTransitive, - Ipv4: e.IPv4.String(), - LocalAdmin: uint32(e.LocalAdmin), - } -} - func NewIPv4AddressSpecificExtended(ip string, localAdmin uint16, isTransitive bool) *IPv4AddressSpecificExtended { ipv4 := net.ParseIP(ip) if ipv4.To4() == nil { @@ -3231,6 +3252,19 @@ func (e *FourOctetAsSpecificExtended) String() string { return fmt.Sprintf("%d.%d:%d", asUpper, asLower, e.LocalAdmin) } +func (e *FourOctetAsSpecificExtended) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Value string `json:"value"` + }{ + Type: t, + Subtype: s, + Value: e.String(), + }) +} + func (e *FourOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { t := EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC if !e.IsTransitive { @@ -3239,16 +3273,6 @@ func (e *FourOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, Ext return t, e.SubType } -func (e *FourOctetAsSpecificExtended) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{ - Type: api.ExtendedCommunity_FOUR_OCTET_AS_SPECIFIC, - Subtype: api.ExtendedCommunity_Subtype(e.SubType), - IsTransitive: e.IsTransitive, - Asn: e.AS, - LocalAdmin: uint32(e.LocalAdmin), - } -} - func NewFourOctetAsSpecificExtended(as uint32, localAdmin uint16, isTransitive bool) *FourOctetAsSpecificExtended { return &FourOctetAsSpecificExtended{ SubType: ExtendedCommunityAttrSubType(EC_SUBTYPE_ROUTE_TARGET), @@ -3399,6 +3423,19 @@ func (e *OpaqueExtended) String() string { return e.Value.String() } +func (e *OpaqueExtended) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Value OpaqueExtendedValueInterface `json:"value"` + }{ + Type: t, + Subtype: s, + Value: e.Value, + }) +} + func (e *OpaqueExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { t := EC_TYPE_TRANSITIVE_OPAQUE if !e.IsTransitive { @@ -3407,12 +3444,6 @@ func (e *OpaqueExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunit return t, ExtendedCommunityAttrSubType(0xFF) } -func (e *OpaqueExtended) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{ - Type: api.ExtendedCommunity_OPAQUE, - } -} - func NewOpaqueExtended(isTransitive bool) *OpaqueExtended { return &OpaqueExtended{ IsTransitive: isTransitive, @@ -3443,17 +3474,23 @@ func (e *ESILabelExtended) String() string { return fmt.Sprintf("ESI LABEL: Label [%d] IsSingleActive [%t]", e.Label, e.IsSingleActive) } -func (e *ESILabelExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { - return EC_TYPE_EVPN, EC_SUBTYPE_ESI_LABEL +func (e *ESILabelExtended) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Label uint32 `json:"label"` + IsSingleActive bool `json:"is_single_active"` + }{ + Type: t, + Subtype: s, + Label: e.Label, + IsSingleActive: e.IsSingleActive, + }) } -func (e *ESILabelExtended) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{ - Type: api.ExtendedCommunity_EVPN, - Subtype: api.ExtendedCommunity_ESI_LABEL, - IsSingleActive: e.IsSingleActive, - Label: e.Label, - } +func (e *ESILabelExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { + return EC_TYPE_EVPN, EC_SUBTYPE_ESI_LABEL } func NewESILabelExtended(label uint32, isSingleActive bool) *ESILabelExtended { @@ -3479,16 +3516,21 @@ func (e *ESImportRouteTarget) String() string { return fmt.Sprintf("ES-IMPORT ROUTE TARGET: ES-Import [%s]", e.ESImport.String()) } -func (e *ESImportRouteTarget) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { - return EC_TYPE_EVPN, EC_SUBTYPE_ES_IMPORT +func (e *ESImportRouteTarget) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Value string `json:"value"` + }{ + Type: t, + Subtype: s, + Value: e.ESImport.String(), + }) } -func (e *ESImportRouteTarget) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{ - Type: api.ExtendedCommunity_EVPN, - Subtype: api.ExtendedCommunity_ROUTE_TARGET, - EsImport: e.ESImport.String(), - } +func (e *ESImportRouteTarget) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { + return EC_TYPE_EVPN, EC_SUBTYPE_ES_IMPORT } func NewESImportRouteTarget(mac string) *ESImportRouteTarget { @@ -3521,17 +3563,23 @@ func (e *MacMobilityExtended) String() string { return fmt.Sprintf("MAC MOBILITY: Seq [%d] IsSticky [%t]", e.Sequence, e.IsSticky) } -func (e *MacMobilityExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { - return EC_TYPE_EVPN, EC_SUBTYPE_MAC_MOBILITY -} - -func (e *MacMobilityExtended) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{ - Type: api.ExtendedCommunity_EVPN, - Subtype: api.ExtendedCommunity_MAC_MOBILITY, +func (e *MacMobilityExtended) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Sequence uint32 `json:"sequence"` + IsSticky bool `json:"is_sticky"` + }{ + Type: t, + Subtype: s, Sequence: e.Sequence, IsSticky: e.IsSticky, - } + }) +} + +func (e *MacMobilityExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { + return EC_TYPE_EVPN, EC_SUBTYPE_MAC_MOBILITY } func NewMacMobilityExtended(seq uint32, isSticky bool) *MacMobilityExtended { @@ -3595,12 +3643,21 @@ func (e *UnknownExtended) String() string { return fmt.Sprintf("%d", v) } -func (e *UnknownExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { - return ExtendedCommunityAttrType(0xFF), ExtendedCommunityAttrSubType(0xFF) +func (e *UnknownExtended) MarshalJSON() ([]byte, error) { + t, s := e.GetTypes() + return json.Marshal(struct { + Type ExtendedCommunityAttrType `json:"type"` + Subtype ExtendedCommunityAttrSubType `json:"subtype"` + Value []byte `json:"string"` + }{ + Type: t, + Subtype: s, + Value: e.Value, + }) } -func (e *UnknownExtended) ToApiStruct() *api.ExtendedCommunity { - return &api.ExtendedCommunity{} +func (e *UnknownExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { + return ExtendedCommunityAttrType(0xFF), ExtendedCommunityAttrSubType(0xFF) } type PathAttributeExtendedCommunities struct { @@ -3694,22 +3751,22 @@ func (p *PathAttributeExtendedCommunities) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeExtendedCommunities) ToApiStruct() *api.PathAttr { - ecs := func(arg []ExtendedCommunityInterface) []*api.ExtendedCommunity { - ret := make([]*api.ExtendedCommunity, 0, len(arg)) - for _, v := range p.Value { - ret = append(ret, v.ToApiStruct()) - } - return ret - }(p.Value) - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES, - ExtendedCommunities: ecs, +func (p *PathAttributeExtendedCommunities) String() string { + l := []string{} + for _, v := range p.Value { + l = append(l, v.String()) } + return fmt.Sprintf("{Extcomms: %s}", strings.Join(l, ", ")) } func (p *PathAttributeExtendedCommunities) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) + return json.Marshal(struct { + Type BGPAttrType `json:"type"` + Value []ExtendedCommunityInterface `json:"value"` + }{ + Type: p.GetType(), + Value: p.Value, + }) } func NewPathAttributeExtendedCommunities(value []ExtendedCommunityInterface) *PathAttributeExtendedCommunities { @@ -3769,26 +3826,6 @@ func (p *PathAttributeAs4Path) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeAs4Path) ToApiStruct() *api.PathAttr { - aspaths := make([]*api.AsPath, 0) - aspath := &api.AsPath{ - SegmentType: uint32(p.Type), - Asns: make([]uint32, 0), - } - for _, a := range p.Value { - aspath.Asns = append(aspath.Asns, a.AS...) - } - aspaths = append(aspaths, aspath) - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_AS_PATH, - AsPaths: aspaths, - } -} - -func (p *PathAttributeAs4Path) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) -} - func NewPathAttributeAs4Path(value []*As4PathParam) *PathAttributeAs4Path { t := BGP_ATTR_TYPE_AS4_PATH return &PathAttributeAs4Path{ @@ -3828,20 +3865,6 @@ func (p *PathAttributeAs4Aggregator) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeAs4Aggregator) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_AS4_AGGREGATOR, - Aggregator: &api.Aggregator{ - As: p.Value.AS, - Address: p.Value.Address.String(), - }, - } -} - -func (p *PathAttributeAs4Aggregator) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) -} - func NewPathAttributeAs4Aggregator(as uint32, address string) *PathAttributeAs4Aggregator { t := BGP_ATTR_TYPE_AS4_AGGREGATOR return &PathAttributeAs4Aggregator{ @@ -3858,7 +3881,6 @@ func NewPathAttributeAs4Aggregator(as uint32, address string) *PathAttributeAs4A type TunnelEncapSubTLVValue interface { Serialize() ([]byte, error) - ToApiStruct() *api.TunnelEncapSubTLV } type TunnelEncapSubTLVDefault struct { @@ -3869,13 +3891,6 @@ func (t *TunnelEncapSubTLVDefault) Serialize() ([]byte, error) { return t.Value, nil } -func (t *TunnelEncapSubTLVDefault) ToApiStruct() *api.TunnelEncapSubTLV { - return &api.TunnelEncapSubTLV{ - Type: api.ENCAP_SUBTLV_TYPE_UNKNOWN_SUBTLV_TYPE, - Value: string(t.Value), - } -} - type TunnelEncapSubTLVEncapuslation struct { Key uint32 // this represent both SessionID for L2TPv3 case and GRE-key for GRE case (RFC5512 4.) Cookie []byte @@ -3887,14 +3902,6 @@ func (t *TunnelEncapSubTLVEncapuslation) Serialize() ([]byte, error) { return append(buf, t.Cookie...), nil } -func (t *TunnelEncapSubTLVEncapuslation) ToApiStruct() *api.TunnelEncapSubTLV { - return &api.TunnelEncapSubTLV{ - Type: api.ENCAP_SUBTLV_TYPE_ENCAPSULATION, - Key: t.Key, - Cookie: string(t.Cookie), - } -} - type TunnelEncapSubTLVProtocol struct { Protocol uint16 } @@ -3905,13 +3912,6 @@ func (t *TunnelEncapSubTLVProtocol) Serialize() ([]byte, error) { return buf, nil } -func (t *TunnelEncapSubTLVProtocol) ToApiStruct() *api.TunnelEncapSubTLV { - return &api.TunnelEncapSubTLV{ - Type: api.ENCAP_SUBTLV_TYPE_PROTOCOL, - Protocol: uint32(t.Protocol), - } -} - type TunnelEncapSubTLVColor struct { Color uint32 } @@ -3924,13 +3924,6 @@ func (t *TunnelEncapSubTLVColor) Serialize() ([]byte, error) { return buf, nil } -func (t *TunnelEncapSubTLVColor) ToApiStruct() *api.TunnelEncapSubTLV { - return &api.TunnelEncapSubTLV{ - Type: api.ENCAP_SUBTLV_TYPE_COLOR, - Color: t.Color, - } -} - type TunnelEncapSubTLV struct { Type EncapSubTLVType Len int @@ -3979,10 +3972,6 @@ func (p *TunnelEncapSubTLV) DecodeFromBytes(data []byte) error { return nil } -func (p *TunnelEncapSubTLV) ToApiStruct() *api.TunnelEncapSubTLV { - return p.Value.ToApiStruct() -} - type TunnelEncapTLV struct { Type TunnelType Len int @@ -4029,17 +4018,6 @@ func (p *TunnelEncapTLV) Serialize() ([]byte, error) { return buf, nil } -func (p *TunnelEncapTLV) ToApiStruct() *api.TunnelEncapTLV { - subTlvs := make([]*api.TunnelEncapSubTLV, 0, len(p.Value)) - for _, v := range p.Value { - subTlvs = append(subTlvs, v.ToApiStruct()) - } - return &api.TunnelEncapTLV{ - Type: api.TUNNEL_TYPE(p.Type), - SubTlv: subTlvs, - } -} - type PathAttributeTunnelEncap struct { PathAttribute Value []*TunnelEncapTLV @@ -4089,21 +4067,6 @@ func (p *PathAttributeTunnelEncap) Serialize() ([]byte, error) { return p.PathAttribute.Serialize() } -func (p *PathAttributeTunnelEncap) ToApiStruct() *api.PathAttr { - tlvs := make([]*api.TunnelEncapTLV, 0, len(p.Value)) - for _, v := range p.Value { - tlvs = append(tlvs, v.ToApiStruct()) - } - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_TUNNEL_ENCAP, - TunnelEncap: tlvs, - } -} - -func (p *PathAttributeTunnelEncap) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) -} - func NewPathAttributeTunnelEncap(value []*TunnelEncapTLV) *PathAttributeTunnelEncap { t := BGP_ATTR_TYPE_TUNNEL_ENCAP return &PathAttributeTunnelEncap{ @@ -4198,33 +4161,10 @@ func (p *PathAttributePmsiTunnel) Serialize() ([]byte, error) { return buf, nil } -func (p *PathAttributePmsiTunnel) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_PMSI_TUNNEL, - PmsiTunnel: &api.PmsiTunnel{ - IsLeafInfoRequired: p.IsLeafInfoRequired, - Type: api.PMSI_TUNNEL_TYPE(p.TunnelType), - Label: p.Label, - TunnelId: p.TunnelID.String(), - }, - } -} - type PathAttributeUnknown struct { PathAttribute } -func (p *PathAttributeUnknown) ToApiStruct() *api.PathAttr { - return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_UNKNOWN_ATTR, - Value: []string{string(p.Value)}, - } -} - -func (p *PathAttributeUnknown) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ToApiStruct()) -} - func GetPathAttribute(data []byte) (PathAttributeInterface, error) { if len(data) < 1 { eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) diff --git a/server/grpc_server.go b/server/grpc_server.go index 041f0659..d767c1ee 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -160,38 +160,6 @@ func (s *Server) GetNeighbors(_ *api.Arguments, stream api.Grpc_GetNeighborsServ return nil } -func (s *Server) GetAdjRib(arg *api.Arguments, stream api.Grpc_GetAdjRibServer) error { - var reqType int - switch arg.Resource { - case api.Resource_ADJ_IN: - reqType = REQ_ADJ_RIB_IN - case api.Resource_ADJ_OUT: - reqType = REQ_ADJ_RIB_OUT - default: - return fmt.Errorf("unsupported resource type: %v", arg.Resource) - } - - rf, err := convertAf2Rf(arg.Af) - if err != nil { - return err - } - - req := NewGrpcRequest(reqType, arg.Name, rf, nil) - s.bgpServerCh <- req - - for res := range req.ResponseCh { - if err := res.Err(); err != nil { - log.Debug(err.Error()) - return err - } - if err := stream.Send(res.Data.(*api.Path)); err != nil { - return err - } - } - - return nil -} - func (s *Server) GetRib(arg *api.Arguments, stream api.Grpc_GetRibServer) error { var reqType int switch arg.Resource { @@ -199,6 +167,12 @@ func (s *Server) GetRib(arg *api.Arguments, stream api.Grpc_GetRibServer) error reqType = REQ_LOCAL_RIB case api.Resource_GLOBAL: reqType = REQ_GLOBAL_RIB + case api.Resource_ADJ_IN: + reqType = REQ_ADJ_RIB_IN + case api.Resource_ADJ_OUT: + reqType = REQ_ADJ_RIB_OUT + case api.Resource_VRF: + reqType = REQ_VRF default: return fmt.Errorf("unsupported resource type: %v", arg.Resource) } @@ -245,7 +219,7 @@ func (s *Server) MonitorBestChanged(arg *api.Arguments, stream api.Grpc_MonitorB log.Debug(err.Error()) goto END } - if err = stream.Send(res.Data.(*api.Path)); err != nil { + if err = stream.Send(res.Data.(*api.Destination)); err != nil { goto END } } @@ -638,26 +612,6 @@ func (s *Server) GetRPKI(arg *api.Arguments, stream api.Grpc_GetRPKIServer) erro return nil } -func (s *Server) GetVrf(arg *api.Arguments, stream api.Grpc_GetVrfServer) error { - rf, err := convertAf2Rf(arg.Af) - if err != nil { - return err - } - req := NewGrpcRequest(REQ_VRF, "", rf, arg) - s.bgpServerCh <- req - - for res := range req.ResponseCh { - if err := res.Err(); err != nil { - log.Debug(err.Error()) - return err - } - if err := stream.Send(res.Data.(*api.Path)); err != nil { - return err - } - } - return nil -} - func (s *Server) GetVrfs(arg *api.Arguments, stream api.Grpc_GetVrfsServer) error { req := NewGrpcRequest(REQ_VRFS, "", bgp.RouteFamily(0), nil) s.bgpServerCh <- req @@ -688,7 +642,7 @@ func (s *Server) ModVrf(ctx context.Context, arg *api.ModVrfArguments) (*api.Err type GrpcRequest struct { RequestType int - RemoteAddr string + Name string RouteFamily bgp.RouteFamily ResponseCh chan *GrpcResponse EndCh chan struct{} @@ -696,11 +650,11 @@ type GrpcRequest struct { Data interface{} } -func NewGrpcRequest(reqType int, remoteAddr string, rf bgp.RouteFamily, d interface{}) *GrpcRequest { +func NewGrpcRequest(reqType int, name string, rf bgp.RouteFamily, d interface{}) *GrpcRequest { r := &GrpcRequest{ RequestType: reqType, RouteFamily: rf, - RemoteAddr: remoteAddr, + Name: name, ResponseCh: make(chan *GrpcResponse, 8), EndCh: make(chan struct{}, 1), Data: d, diff --git a/server/server.go b/server/server.go index 56ef8c68..cb301fef 100644 --- a/server/server.go +++ b/server/server.go @@ -507,7 +507,10 @@ func (server *BgpServer) broadcastBests(bests []*table.Path) { } result := &GrpcResponse{ - Data: path.ToApiStruct(), + Data: &api.Destination{ + Prefix: path.GetNlri().String(), + Paths: []*api.Path{path.ToApiStruct()}, + }, } remainReqs := make([]*GrpcRequest, 0, len(server.broadcastReqs)) for _, req := range server.broadcastReqs { @@ -543,7 +546,7 @@ func (server *BgpServer) broadcastPeerState(peer *Peer) { default: } ignore := req.RequestType != REQ_MONITOR_NEIGHBOR_PEER_STATE - ignore = ignore || (req.RemoteAddr != "" && req.RemoteAddr != peer.conf.NeighborConfig.NeighborAddress.String()) + ignore = ignore || (req.Name != "" && req.Name != peer.conf.NeighborConfig.NeighborAddress.String()) if ignore { remainReqs = append(remainReqs, req) continue @@ -748,7 +751,7 @@ func (server *BgpServer) handlePolicy(pl config.RoutingPolicy) { } func (server *BgpServer) checkNeighborRequest(grpcReq *GrpcRequest) (*Peer, error) { - remoteAddr := grpcReq.RemoteAddr + remoteAddr := grpcReq.Name peer, found := server.neighborMap[remoteAddr] if !found { result := &GrpcResponse{} @@ -1022,11 +1025,11 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path { switch req.RequestType { case REQ_VRF: - arg := req.Data.(*api.Arguments) + name := req.Name rib := server.localRibMap[GLOBAL_RIB_NAME].rib vrfs := rib.Vrfs - if _, ok := vrfs[arg.Name]; !ok { - result.ResponseErr = fmt.Errorf("vrf %s not found", arg.Name) + if _, ok := vrfs[name]; !ok { + result.ResponseErr = fmt.Errorf("vrf %s not found", name) break } var rf bgp.RouteFamily @@ -1042,12 +1045,15 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path { break } for _, path := range rib.GetPathList(rf) { - ok := policy.CanImportToVrf(vrfs[arg.Name], path) + ok := policy.CanImportToVrf(vrfs[name], path) if !ok { continue } req.ResponseCh <- &GrpcResponse{ - Data: path.ToApiStruct(), + Data: &api.Destination{ + Prefix: path.GetNlri().String(), + Paths: []*api.Path{path.ToApiStruct()}, + }, } } goto END @@ -1124,7 +1130,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { break } if peer.fsm.adminState != ADMIN_STATE_DOWN { - remoteAddr := grpcReq.RemoteAddr + remoteAddr := grpcReq.Name if t, ok := server.localRibMap[remoteAddr].rib.Tables[grpcReq.RouteFamily]; ok { for _, dst := range t.GetDestinations() { result := &GrpcResponse{} @@ -1152,8 +1158,12 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { } for _, p := range paths { - result := &GrpcResponse{} - result.Data = p.ToApiStruct() + result := &GrpcResponse{ + Data: &api.Destination{ + Prefix: p.GetNlri().String(), + Paths: []*api.Path{p.ToApiStruct()}, + }, + } grpcReq.ResponseCh <- result } close(grpcReq.ResponseCh) @@ -2028,15 +2038,15 @@ func (server *BgpServer) handleMrt(grpcReq *GrpcRequest) { if err != nil { return } - loc, ok := server.localRibMap[grpcReq.RemoteAddr] + loc, ok := server.localRibMap[grpcReq.Name] if !ok { - result.ResponseErr = fmt.Errorf("no local rib for %s", grpcReq.RemoteAddr) + result.ResponseErr = fmt.Errorf("no local rib for %s", grpcReq.Name) grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) return } manager = loc.rib - view = grpcReq.RemoteAddr + view = grpcReq.Name } msg, err := server.mkMrtPeerIndexTableMsg(now, view) diff --git a/table/destination.go b/table/destination.go index 5b704e6b..51d6b5d0 100644 --- a/table/destination.go +++ b/table/destination.go @@ -88,32 +88,21 @@ func (dd *Destination) MarshalJSON() ([]byte, error) { func (dd *Destination) ToApiStruct() *api.Destination { prefix := dd.GetNlri().String() - - idx := func() int { - for i, p := range dd.knownPathList { - if dd.GetBestPath().Equal(p) { - return i - } - } - log.WithFields(log.Fields{ - "Topic": "Table", - "Key": prefix, - }).Panic("no best path") - return 0 - }() - paths := func(arg []*Path) []*api.Path { ret := make([]*api.Path, 0, len(arg)) for _, p := range arg { - ret = append(ret, p.ToApiStruct()) + pp := p.ToApiStruct() + if dd.GetBestPath().Equal(p) { + pp.Best = true + } + ret = append(ret, pp) } return ret }(dd.knownPathList) return &api.Destination{ - Prefix: prefix, - Paths: paths, - BestPathIdx: uint32(idx), + Prefix: prefix, + Paths: paths, } } diff --git a/table/path.go b/table/path.go index 4f1ff637..224cda9d 100644 --- a/table/path.go +++ b/table/path.go @@ -142,22 +142,37 @@ func (path *Path) IsLocal() bool { } func (path *Path) ToApiStruct() *api.Path { - pathAttrs := func(arg []bgp.PathAttributeInterface) []*api.PathAttr { - ret := make([]*api.PathAttr, 0, len(arg)) + nlri, _ := path.GetNlri().Serialize() + pattrs := func(arg []bgp.PathAttributeInterface) [][]byte { + ret := make([][]byte, 0, len(arg)) for _, a := range arg { - ret = append(ret, a.ToApiStruct()) + aa, _ := a.Serialize() + ret = append(ret, aa) } return ret }(path.GetPathAttrs()) return &api.Path{ - Nlri: path.GetNlri().ToApiStruct(), - Nexthop: path.GetNexthop().String(), - Attrs: pathAttrs, + Nlri: nlri, + Pattrs: pattrs, Age: int64(time.Now().Sub(path.timestamp).Seconds()), IsWithdraw: path.IsWithdraw, } } +func (path *Path) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Source *PeerInfo `json:"source"` + IsWithdraw bool `json:"is_withdraw"` + Nlri bgp.AddrPrefixInterface `json:"nlri"` + Pathattrs []bgp.PathAttributeInterface `json:"pattrs"` + }{ + Source: path.source, + IsWithdraw: path.IsWithdraw, + Nlri: path.nlri, + Pathattrs: path.pathAttrs, + }) +} + // create new PathAttributes func (path *Path) Clone(isWithdraw bool) *Path { nlri := path.nlri diff --git a/test/scenario_test/bgp_router_test.py b/test/scenario_test/bgp_router_test.py index a5ce3d7e..804003aa 100644 --- a/test/scenario_test/bgp_router_test.py +++ b/test/scenario_test/bgp_router_test.py @@ -95,7 +95,7 @@ class GoBGPTestBase(unittest.TestCase): def test_03_check_gobgp_adj_out_rib(self): for q in self.quaggas.itervalues(): for path in self.gobgp.get_adj_rib_out(q): - asns = self.gobgp._get_as_path(path) + asns = path['as_path'] self.assertTrue(self.gobgp.asn in asns) # check routes are properly advertised to all BGP speaker @@ -219,7 +219,7 @@ class GoBGPTestBase(unittest.TestCase): self.assertTrue(len(dst[0]['paths']) == 1) path = dst[0]['paths'][0] self.assertTrue(path['nexthop'] == '0.0.0.0') - self.assertTrue(len(self.gobgp._get_as_path(path)) == 0) + self.assertTrue(len(path['as_path']) == 0) def test_11_check_adj_rib_out(self): for q in self.quaggas.itervalues(): @@ -229,7 +229,7 @@ class GoBGPTestBase(unittest.TestCase): peer_info = self.gobgp.peers[q] local_addr = peer_info['local_addr'].split('/')[0] self.assertTrue(path['nexthop'] == local_addr) - self.assertTrue(self.gobgp._get_as_path(path) == [self.gobgp.asn]) + self.assertTrue(path['as_path'] == [self.gobgp.asn]) def test_12_disable_peer(self): q1 = self.quaggas['q1'] diff --git a/test/scenario_test/constant.py b/test/scenario_test/constant.py index 65908a4f..33572c8d 100644 --- a/test/scenario_test/constant.py +++ b/test/scenario_test/constant.py @@ -67,3 +67,7 @@ LOCAL_RIB = "local" GLOBAL_RIB = "global rib" NEIGHBOR = "neighbor" POLICY = "policy" + +BGP_ATTR_TYPE_AS_PATH= 2 +BGP_ATTR_TYPE_MED = 4 +BGP_ATTR_TYPE_COMMUNITIES = 8 diff --git a/test/scenario_test/evpn_test.py b/test/scenario_test/evpn_test.py index 270773bb..b3e893c5 100644 --- a/test/scenario_test/evpn_test.py +++ b/test/scenario_test/evpn_test.py @@ -26,11 +26,11 @@ from noseplugin import OptionParser, parser_option from itertools import combinations def get_mac_mobility_sequence(pattr): - for ecs in [p['extended_communities'] for p in pattr + for ecs in [p['value'] for p in pattr if 'type' in p and \ p['type'] == BGP_ATTR_TYPE_EXTENDED_COMMUNITIES]: - for ec in [e for e in ecs if 'type' in e and e['type'] == 4]: - if ec['subtype'] == 5: + for ec in [e for e in ecs if 'type' in e and e['type'] == 6]: + if ec['subtype'] == 0: if 'sequence' not in ec: return 0 else: diff --git a/test/scenario_test/gobgp_test.py b/test/scenario_test/gobgp_test.py index 03443777..45f36f1e 100644 --- a/test/scenario_test/gobgp_test.py +++ b/test/scenario_test/gobgp_test.py @@ -260,11 +260,12 @@ class GoBGPTestBase(unittest.TestCase): retry_count = 0 while True: rib = self.ask_gobgp(type, neighbor_address, af) - paths = [p for p in rib if p['nlri']['prefix'] == target_prefix] + paths = [p for p in rib if p['prefix'] == target_prefix] if len(paths) > 0: assert len(paths) == 1 - return paths[0] + assert len(paths[0]['paths']) == 1 + return paths[0]['paths'][0] else: retry_count += 1 if retry_count > retry: diff --git a/test/scenario_test/ibgp_router_test.py b/test/scenario_test/ibgp_router_test.py index 2fad2da3..65d6cb99 100644 --- a/test/scenario_test/ibgp_router_test.py +++ b/test/scenario_test/ibgp_router_test.py @@ -104,7 +104,7 @@ class GoBGPTestBase(unittest.TestCase): self.assertTrue(len(dst[0]['paths']) == 1) path = dst[0]['paths'][0] self.assertTrue(path['nexthop'] == '0.0.0.0') - self.assertTrue(len(self.gobgp._get_as_path(path)) == 0) + self.assertTrue(len(path['as_path']) == 0) def test_05_check_gobgp_adj_rib_out(self): for q in self.quaggas.itervalues(): @@ -115,7 +115,7 @@ class GoBGPTestBase(unittest.TestCase): peer_info = self.gobgp.peers[q] local_addr = peer_info['local_addr'].split('/')[0] self.assertTrue(path['nexthop'] == local_addr) - self.assertTrue(len(self.gobgp._get_as_path(path)) == 0) + self.assertTrue(len(path['as_path']) == 0) # check routes are properly advertised to all BGP speaker def test_06_check_quagga_global_rib(self): @@ -181,7 +181,7 @@ class GoBGPTestBase(unittest.TestCase): peer_info = self.gobgp.peers[q3] local_addr = peer_info['local_addr'].split('/')[0] self.assertTrue(path['nexthop'] == local_addr) - self.assertTrue(self.gobgp._get_as_path(path) == [self.gobgp.asn]) + self.assertTrue(path['as_path'] == [self.gobgp.asn]) def test_10_check_gobgp_ibgp_adj_rib_out(self): q1 = self.quaggas['q1'] @@ -198,7 +198,7 @@ class GoBGPTestBase(unittest.TestCase): self.assertTrue(path['nexthop'] == neigh_addr) # bgp router mustn't change aspath of routes from eBGP peers # which are sent to iBGP peers - self.assertTrue(self.gobgp._get_as_path(path) == [q3.asn]) + self.assertTrue(path['as_path'] == [q3.asn]) # disable ebgp peer, check ebgp routes are removed def test_11_disable_ebgp_peer(self): diff --git a/test/scenario_test/lib/base.py b/test/scenario_test/lib/base.py index 274a68cf..7bb7b79f 100644 --- a/test/scenario_test/lib/base.py +++ b/test/scenario_test/lib/base.py @@ -36,6 +36,7 @@ BGP_ATTR_TYPE_AS_PATH = 2 BGP_ATTR_TYPE_NEXT_HOP = 3 BGP_ATTR_TYPE_MULTI_EXIT_DISC = 4 BGP_ATTR_TYPE_LOCAL_PREF = 5 +BGP_ATTR_TYPE_MP_REACH_NLRI = 14 BGP_ATTR_TYPE_EXTENDED_COMMUNITIES = 16 diff --git a/test/scenario_test/lib/gobgp.py b/test/scenario_test/lib/gobgp.py index c7a9631e..e1da72c8 100644 --- a/test/scenario_test/lib/gobgp.py +++ b/test/scenario_test/lib/gobgp.py @@ -51,11 +51,17 @@ class GoBGPContainer(BGPContainer): def _get_as_path(self, path): asps = (p['as_paths'] for p in path['attrs'] if - p['type'] == BGP_ATTR_TYPE_AS_PATH and 'as_paths' in p) + p['type'] == BGP_ATTR_TYPE_AS_PATH and 'as_paths' in p + and p['as_paths'] != None) asps = chain.from_iterable(asps) asns = (asp['asns'] for asp in asps) return list(chain.from_iterable(asns)) + def _get_nexthop(self, path): + for p in path['attrs']: + if p['type'] == BGP_ATTR_TYPE_NEXT_HOP or p['type'] == BGP_ATTR_TYPE_MP_REACH_NLRI: + return p['nexthop'] + def _trigger_peer_cmd(self, cmd, peer): if peer not in self.peers: raise Exception('not found peer {0}'.format(peer.router_id)) @@ -75,13 +81,22 @@ class GoBGPContainer(BGPContainer): peer_addr = self.peers[peer]['neigh_addr'].split('/')[0] cmd = 'gobgp -j neighbor {0} local -a {1}'.format(peer_addr, rf) output = self.local(cmd, capture=True) - n = json.loads(output) - return n + ret = json.loads(output) + for d in ret: + for p in d["paths"]: + p["nexthop"] = self._get_nexthop(p) + p["as_path"] = self._get_as_path(p) + return ret def get_global_rib(self, prefix='', rf='ipv4'): cmd = 'gobgp -j global rib {0} -a {1}'.format(prefix, rf) output = self.local(cmd, capture=True) - return json.loads(output) + ret = json.loads(output) + for d in ret: + for p in d["paths"]: + p["nexthop"] = self._get_nexthop(p) + p["as_path"] = self._get_as_path(p) + return ret def _get_adj_rib(self, adj_type, peer, prefix='', rf='ipv4'): if peer not in self.peers: @@ -91,7 +106,11 @@ class GoBGPContainer(BGPContainer): adj_type, prefix, rf) output = self.local(cmd, capture=True) - return json.loads(output) + ret = [p["paths"][0] for p in json.loads(output)] + for p in ret: + p["nexthop"] = self._get_nexthop(p) + p["as_path"] = self._get_as_path(p) + return ret def get_adj_rib_in(self, peer, prefix='', rf='ipv4'): return self._get_adj_rib('in', peer, prefix, rf) diff --git a/test/scenario_test/route_server_policy_test.py b/test/scenario_test/route_server_policy_test.py index 1107eadb..3ff08a1e 100644 --- a/test/scenario_test/route_server_policy_test.py +++ b/test/scenario_test/route_server_policy_test.py @@ -1229,8 +1229,8 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1,retry=0) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertTrue((65100 << 16 | 20) in attrs[0]['communites']) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertTrue((65100 << 16 | 20) in attrs[0]['communities']) # check show ip bgp on peer2(quagga2) qpath = self.get_route(peer2, prefix1, retry=self.retry_count_common) @@ -1283,9 +1283,9 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1,retry=0) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertTrue((65100 << 16 | 20) in attrs[0]['communites']) - self.assertTrue((65100 << 16 | 30) in attrs[0]['communites']) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertTrue((65100 << 16 | 20) in attrs[0]['communities']) + self.assertTrue((65100 << 16 | 30) in attrs[0]['communities']) # check show ip bgp on peer2(quagga2) qpath = self.get_route(peer2,prefix1, retry=self.retry_count_common) @@ -1339,9 +1339,9 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1,retry=0) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertTrue((65100 << 16 | 20) not in attrs[0]['communites']) - self.assertTrue((65100 << 16 | 30) not in attrs[0]['communites']) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertTrue((65100 << 16 | 20) not in attrs[0]['communities']) + self.assertTrue((65100 << 16 | 30) not in attrs[0]['communities']) # check show ip bgp on peer2(quagga2) qpath = self.get_route(peer2,prefix1, retry=self.retry_count_common) @@ -1397,8 +1397,8 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1,retry=0) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertFalse('communites' in attrs) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertFalse('communities' in attrs) # check show ip bgp on peer2(quagga2) qpath = self.get_route(peer2,prefix1, retry=self.retry_count_common) @@ -1452,12 +1452,12 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1,retry=0) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertFalse((65100 << 16 | 20) in attrs[0]['communites']) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertFalse((65100 << 16 | 20) in attrs[0]['communities']) # check out-rib path = self.get_adj_rib_out(peer2, prefix1, retry=0) - attrs = [x for x in path['attrs'] if 'communites' in x ] - self.assertTrue((65100 << 16 | 20) in attrs[0]['communites']) + attrs = [x for x in path['attrs'] if 'communities' in x ] + self.assertTrue((65100 << 16 | 20) in attrs[0]['communities']) # check show ip bgp on peer2(quagga2) qpath = self.get_route(peer2,prefix1, retry=self.retry_count_common) @@ -1511,14 +1511,14 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1, retry=0) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertFalse((65100 << 16 | 20) in attrs[0]['communites']) - self.assertFalse((65100 << 16 | 30) in attrs[0]['communites']) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertFalse((65100 << 16 | 20) in attrs[0]['communities']) + self.assertFalse((65100 << 16 | 30) in attrs[0]['communities']) # check out-rib path = self.get_adj_rib_out(peer2, prefix1, retry=1) - attrs = [x for x in path['attrs'] if 'communites' in x ] - self.assertTrue((65100 << 16 | 20) in attrs[0]['communites']) - self.assertTrue((65100 << 16 | 30) in attrs[0]['communites']) + attrs = [x for x in path['attrs'] if 'communities' in x ] + self.assertTrue((65100 << 16 | 20) in attrs[0]['communities']) + self.assertTrue((65100 << 16 | 30) in attrs[0]['communities']) # check show ip bgp on peer2(quagga2) @@ -1574,14 +1574,14 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1, retry=1) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertTrue((65100 << 16 | 20) in attrs[0]['communites']) - self.assertTrue((65100 << 16 | 30) in attrs[0]['communites']) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertTrue((65100 << 16 | 20) in attrs[0]['communities']) + self.assertTrue((65100 << 16 | 30) in attrs[0]['communities']) # check out-rib path = self.get_adj_rib_out(peer2, prefix1, retry=1) - attrs = [x for x in path['attrs'] if 'communites' in x ] - self.assertFalse((65100 << 16 | 20) in attrs[0]['communites']) - self.assertFalse((65100 << 16 | 30) in attrs[0]['communites']) + attrs = [x for x in path['attrs'] if 'communities' in x ] + self.assertFalse((65100 << 16 | 20) in attrs[0]['communities']) + self.assertFalse((65100 << 16 | 30) in attrs[0]['communities']) # check show ip bgp on peer2(quagga2) @@ -1638,14 +1638,14 @@ class GoBGPTest(GoBGPTestBase): # check adj-rib-out in peer2 path = self.get_paths_in_localrib(peer2, prefix1, retry=0) self.assertIsNotNone(path) - attrs = [x for x in path[0]['attrs'] if 'communites' in x ] - self.assertTrue((65100 << 16 | 10) in attrs[0]['communites']) - self.assertTrue((65100 << 16 | 20) in attrs[0]['communites']) - self.assertTrue((65100 << 16 | 30) in attrs[0]['communites']) + attrs = [x for x in path[0]['attrs'] if 'communities' in x ] + self.assertTrue((65100 << 16 | 10) in attrs[0]['communities']) + self.assertTrue((65100 << 16 | 20) in attrs[0]['communities']) + self.assertTrue((65100 << 16 | 30) in attrs[0]['communities']) # check out-rib path = self.get_adj_rib_out(peer2, prefix1, retry=1) - attrs = [x for x in path['attrs'] if 'communites' in x ] - self.assertFalse('communites' in attrs) + attrs = [x for x in path['attrs'] if 'communities' in x ] + self.assertFalse('communities' in attrs) # check show ip bgp on peer2(quagga2) qpath = self.get_route(peer2,prefix1, retry=self.retry_count_common) |