def test_parse_construct_flowspec_redirect_nh(self): community_list = [[bgp_cons.BGP_EXT_REDIRECT_NH, '0.0.0.0', 0]] self.assertEqual(b'\xc0\x10\x08\x08\x00\x00\x00\x00\x00\x00\x00', ExtCommunity.construct(value=community_list)) self.assertEqual( [[bgp_cons.BGP_EXT_REDIRECT_NH, '0.0.0.0', 0]], ExtCommunity.parse(value=b'\x08\x00\x00\x00\x00\x00\x00\x00'))
def test_parse_construct_flowspec_redirect_vrf(self): community_list = [[bgp_cons.BGP_EXT_REDIRECT_VRF, '4837:100']] self.assertEqual(b'\xc0\x10\x08\x80\x08\x12\xe5\x00\x00\x00d', ExtCommunity.construct(value=community_list)) community_hex = b'\x80\x08\x12\xe5\x00\x00\x00d' self.assertEqual(community_list, ExtCommunity.parse(value=community_hex))
def test_parse_construct_es_import(self): community_list = [[ bgp_cons.BGP_EXT_COM_EVPN_ES_IMPORT, '00-11-22-33-44-55' ]] community_hex = b'\x06\x02\x00\x11\x22\x33\x44\x55' self.assertEqual(community_list, ExtCommunity.parse(community_hex)) self.assertEqual(community_hex, ExtCommunity.construct(community_list)[3:])
def test_parse_invalid_length(self): # invalid length self.assertRaises(excep.UpdateMessageError, ExtCommunity.parse, b'\x00\x00\x02\x00\x64\x00\x00\x00\x0c') try: ExtCommunity.parse(value=b'\x00\x00\x02\x00\x64\x00\x00\x00\x0c') except excep.UpdateMessageError as e: self.assertEqual(bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, e.sub_error)
def test_parse_construct_evpn_route_mac(self): comunity_list = [[1539, '74-A0-2F-DE-FE-FB']] community_hex = b'\x06\x03\x74\xa0\x2f\xde\xfe\xfb' self.assertEqual(comunity_list, ExtCommunity.parse(community_hex)) self.assertEqual(community_hex, ExtCommunity.construct(comunity_list)[3:])
def parse_attributes(data, asn4=False): """ Parses an RFC4271 encoded blob of BGP attributes into a list :param data: :param asn4: support 4 bytes asn or not :return: """ attributes = {} postfix = data while len(postfix) > 0: try: flags, type_code = struct.unpack('!BB', postfix[:2]) if flags & AttributeFlag.EXTENDED_LENGTH: attr_len = struct.unpack('!H', postfix[2:4])[0] attr_value = postfix[4:4 + attr_len] postfix = postfix[4 + attr_len:] # Next attribute else: # standard 1-octet length if isinstance(postfix[2], int): attr_len = postfix[2] else: attr_len = ord(postfix[2]) attr_value = postfix[3:3 + attr_len] postfix = postfix[3 + attr_len:] # Next attribute except Exception as e: LOG.error(e) error_str = traceback.format_exc() LOG.debug(error_str) raise excep.UpdateMessageError( sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ATTR_LIST, data='') if type_code == bgp_cons.BGPTYPE_ORIGIN: decode_value = Origin.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_AS_PATH: decode_value = ASPath.parse(value=attr_value, asn4=asn4) elif type_code == bgp_cons.BGPTYPE_NEXT_HOP: decode_value = NextHop.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_MULTI_EXIT_DISC: decode_value = MED.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_LOCAL_PREF: decode_value = LocalPreference.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_ATOMIC_AGGREGATE: decode_value = AtomicAggregate.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_AGGREGATOR: decode_value = Aggregator.parse(value=attr_value, asn4=asn4) elif type_code == bgp_cons.BGPTYPE_COMMUNITIES: decode_value = Community.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_ORIGINATOR_ID: decode_value = OriginatorID.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_CLUSTER_LIST: decode_value = ClusterList.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_NEW_AS_PATH: decode_value = ASPath.parse(value=attr_value, asn4=True) elif type_code == bgp_cons.BGPTYPE_NEW_AGGREGATOR: decode_value = Aggregator.parse(value=attr_value, asn4=True) elif type_code == bgp_cons.BGPTYPE_MP_REACH_NLRI: decode_value = MpReachNLRI.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_MP_UNREACH_NLRI: decode_value = MpUnReachNLRI.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_EXTENDED_COMMUNITY: decode_value = ExtCommunity.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_PMSI_TUNNEL: decode_value = PMSITunnel.parse(value=attr_value) else: decode_value = repr(attr_value) attributes[type_code] = decode_value return attributes
def test_construct_ro2(self): ext_community = ExtCommunity.construct(value=[(bgp_cons.BGP_EXT_COM_RO_2, '65537:12')]) self.assertEqual(b'\xc0\x10\x08\x02\x03\x00\x01\x00\x01\x00\x0c', ext_community)
def test_construct_transitive_opaque_color(self): community_list = [[bgp_cons.BGP_EXT_COM_COLOR, 10]] community_hex = b'\x03\x0b\x00\x00\x00\x00\x00\x0a' self.assertEqual(community_hex, ExtCommunity.construct(community_list)[3:])
def test_parse_ro0(self): # Route Origin,Format AS(2bytes):AN(4bytes) ext_community = ExtCommunity.parse(value=b'\x00\x03\x00\x64\x00\x00\x00\x0c') self.assertEqual([[bgp_cons.BGP_EXT_COM_RO_0, '100:12']], ext_community)
def test_construct_ro1(self): ext_community = ExtCommunity.construct(value=[(bgp_cons.BGP_EXT_COM_RO_1, '10.10.10.10:12')]) self.assertEqual(b'\xc0\x10\x08\x01\x03\x0a\x0a\x0a\x0a\x00\x0c', ext_community)
def test_parse_rt1(self): # Route Target,Format IPv4 address(4bytes):AN(2bytes) ext_community = ExtCommunity.parse(value=b'\x01\x02\x0a\x0a\x0a\x0a\x00\x0c') self.assertEqual([(bgp_cons.BGP_EXT_COM_RT_1, '10.10.10.10:12')], ext_community)
def test_parse_construct_tarffic_rate(self): community_list = [[bgp_cons.BGP_EXT_TRA_RATE, "100:6250000"]] self.assertEqual(b'\xc0\x10\x08\x80\x06\x00dJ\xbe\xbc ', ExtCommunity.construct(value=community_list)) self.assertEqual([[bgp_cons.BGP_EXT_TRA_RATE, "100:6250000"]], ExtCommunity.parse(value=b'\x80\x06\x00dJ\xbe\xbc '))
def test_parse_rt1(self): # Route Target,Format IPv4 address(4bytes):AN(2bytes) ext_community = ExtCommunity.parse(value=b'\x01\x02\x0a\x0a\x0a\x0a\x00\x0c') self.assertEqual([[bgp_cons.BGP_EXT_COM_RT_1, '10.10.10.10:12']], ext_community)
def test_parse_rt2(self): # Route Target,Format AS(4bytes):AN(2bytes) ext_community = ExtCommunity.parse(value=b'\x02\x02\x00\x01\x00\x01\x00\x0c') self.assertEqual([[bgp_cons.BGP_EXT_COM_RT_2, '65537:12']], ext_community)
def test_parse_construct_mac_mobil(self): community_list = [[bgp_cons.BGP_EXT_COM_EVPN_MAC_MOBIL, 1, 500]] community_hex = b'\x06\x00\x01\x00\x00\x00\x01\xf4' self.assertEqual(community_hex, ExtCommunity.construct(community_list)[3:]) self.assertEqual(community_list, ExtCommunity.parse(community_hex))
def test_parse_construct_els_label(self): community_list = [[bgp_cons.BGP_EXT_COM_EVPN_ESI_MPLS_LABEL, 1, 20]] community_hex = b'\x06\x01\x01\x00\x00\x00\x01\x41' self.assertEqual(community_hex, ExtCommunity.construct(community_list)[3:]) self.assertEqual(community_list, ExtCommunity.parse(community_hex))
def construct_attributes(attr_dict, asn4=False): """ construts BGP Update attirubte. :param attr_dict: bgp attribute dictionary :param asn4: support 4 bytes asn or not """ attr_raw_hex = b'' for type_code, value in attr_dict.items(): if type_code == bgp_cons.BGPTYPE_ORIGIN: origin_hex = Origin.construct(value=value) attr_raw_hex += origin_hex elif type_code == bgp_cons.BGPTYPE_AS_PATH: aspath_hex = ASPath.construct(value=value, asn4=asn4) attr_raw_hex += aspath_hex elif type_code == bgp_cons.BGPTYPE_NEXT_HOP: nexthop_hex = NextHop.construct(value=value) attr_raw_hex += nexthop_hex elif type_code == bgp_cons.BGPTYPE_MULTI_EXIT_DISC: med_hex = MED.construct(value=value) attr_raw_hex += med_hex elif type_code == bgp_cons.BGPTYPE_LOCAL_PREF: localpre_hex = LocalPreference.construct(value=value) attr_raw_hex += localpre_hex elif type_code == bgp_cons.BGPTYPE_ATOMIC_AGGREGATE: atomicaggregate_hex = AtomicAggregate.construct(value=value) attr_raw_hex += atomicaggregate_hex elif type_code == bgp_cons.BGPTYPE_AGGREGATOR: aggregator_hex = Aggregator.construct(value=value, asn4=asn4) attr_raw_hex += aggregator_hex elif type_code == bgp_cons.BGPTYPE_COMMUNITIES: community_hex = Community.construct(value=value) attr_raw_hex += community_hex elif type_code == bgp_cons.BGPTYPE_ORIGINATOR_ID: originatorid_hex = OriginatorID.construct(value=value) attr_raw_hex += originatorid_hex elif type_code == bgp_cons.BGPTYPE_CLUSTER_LIST: clusterlist_hex = ClusterList.construct(value=value) attr_raw_hex += clusterlist_hex elif type_code == bgp_cons.BGPTYPE_MP_REACH_NLRI: mpreach_hex = MpReachNLRI().construct(value=value) attr_raw_hex += mpreach_hex elif type_code == bgp_cons.BGPTYPE_MP_UNREACH_NLRI: mpunreach_hex = MpUnReachNLRI.construct(value=value) attr_raw_hex += mpunreach_hex elif type_code == bgp_cons.BGPTYPE_EXTENDED_COMMUNITY: community_ext_hex = ExtCommunity.construct(value=value) attr_raw_hex += community_ext_hex return attr_raw_hex
def test_parse_rt2(self): # Route Target,Format AS(4bytes):AN(2bytes) ext_community = ExtCommunity.parse(value=b'\x02\x02\x00\x01\x00\x01\x00\x0c') self.assertEqual([(bgp_cons.BGP_EXT_COM_RT_2, '65537:12')], ext_community)
def test_parse_construct_flowspec_redirect_nh(self): community_list = [[bgp_cons.BGP_EXT_REDIRECT_NH, '0.0.0.0', 0]] self.assertEqual(b'\xc0\x10\x08\x08\x00\x00\x00\x00\x00\x00\x00', ExtCommunity.construct(value=community_list)) self.assertEqual([[bgp_cons.BGP_EXT_REDIRECT_NH, '0.0.0.0', 0]], ExtCommunity.parse(value=b'\x08\x00\x00\x00\x00\x00\x00\x00'))
def test_parse_construct_transitive_opaque_encap(self): community_list = [[bgp_cons.BGP_EXT_COM_ENCAP, 8]] community_hex = b'\x03\x0c\x00\x00\x00\x00\x00\x08' self.assertEqual(community_list, ExtCommunity.parse(community_hex)) self.assertEqual(community_hex, ExtCommunity.construct(community_list)[3:])
def test_construct_rt0(self): ext_community = ExtCommunity.construct(value=[(bgp_cons.BGP_EXT_COM_RT_0, '100:12')]) self.assertEqual(b'\xc0\x10\x08\x00\x02\x00\x64\x00\x00\x00\x0c', ext_community)
def test_parse_unknow(self): # unknow hex_tmp = b'\x09\x03\x00\x01\x00\x01\x00\x0c' ext_community = ExtCommunity.parse(value=hex_tmp) self.assertEqual(bgp_cons.BGP_EXT_COM_UNKNOW, ext_community[0][0])
def test_parse_ro1(self): # Route Origin,Format IPv4 address(4bytes):AN(2bytes) ext_community = ExtCommunity.parse(value=b'\x01\x03\x0a\x0a\x0a\x0a\x00\x0c') self.assertEqual([[bgp_cons.BGP_EXT_COM_RO_1, '10.10.10.10:12']], ext_community)
def test_parse_ro2(self): # Route Origin,Format AS(4bytes):AN(2bytes) ext_community = ExtCommunity.parse(value=b'\x02\x03\x00\x01\x00\x01\x00\x0c') self.assertEqual([[bgp_cons.BGP_EXT_COM_RO_2, '65537:12']], ext_community)
def test_parse_construct_es_import(self): community_list = [[bgp_cons.BGP_EXT_COM_EVPN_ES_IMPORT, '00-11-22-33-44-55']] community_hex = b'\x06\x02\x00\x11\x22\x33\x44\x55' self.assertEqual(community_list, ExtCommunity.parse(community_hex)) self.assertEqual(community_hex, ExtCommunity.construct(community_list)[3:])