def test_unpack(self): data_bin = b'\x04\x04\x00\x04\x02\x02\x02\x02\x04\x06\x00\x04\x01\x01\x01\x01' \ b'\x04\x40\x00\x04\x00\x00\x00\x00\x04\x41\x00\x04\x4c\xee\x6b\x28' \ b'\x04\x42\x00\x04\x00\x00\x00\x00\x04\x43\x00\x20\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x44\x00\x04' \ b'\x00\x00\x00\x0a\x04\x47\x00\x03\x00\x00\x0a\x04\x4b\x00\x07\x70' \ b'\x00\x00\x00\x00\x61\xa8\x04\x4b\x00\x07\x30\x00\x00\x00\x00\x61' \ b'\xa9' self.assertEqual(None, LinkState.unpack(data_bin).dict())
def test_max_link_bw_parse(self): hex_value = b'\x04\x43\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ls = { 29: [{ 'unreserved-bandwidth': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] }] } self.assertEqual(ls, LinkState.parse(hex_value).dict())
def test_prefix_sid_flags_ospf(self): self.maxDiff = None data_bin = b'\x04\x86\x00\x07\xb4\x00\x00\x00\x00\x61\xa9' data_dict = { 29: [{ 'type': 'prefix_sid', 'value': { 'sid': 25001, 'flags': { 'NP': 0, 'M': 1, 'E': 1, 'V': 0, 'L': 1 }, 'algorithm': 0 } }] } self.assertEqual(data_dict, LinkState.unpack(data_bin, 3).dict())
def test_parse(self): ls = { 29: [{ 'local-router-id': '2.2.2.2' }, { 'te-default-metric': 10 }, { 'igp-link-metric': 10 }, { 'UNKNOWN': { 'type': 1099, 'value': '700000000061a8' } }, { 'UNKNOWN': { 'type': 1099, 'value': '300000000061a9' } }] } hex_value = b'\x04\x06\x00\x04\x02\x02\x02\x02\x04\x44\x00\x04\x00\x00\x00\x0a' \ b'\x04\x47\x00\x03\x00\x00\x0a\x04\x4b\x00\x07\x70\x00\x00\x00\x00' \ b'\x61\xa8\x04\x4b\x00\x07\x30\x00\x00\x00\x00\x61\xa9' self.assertEqual(ls, LinkState.parse(hex_value).dict())
def test_parse(self): hex_value = b'\x04\x44\x00\x04\x00\x00\x00\x0a' ls = {29: [{'te-default-metric': 10}]} self.assertEqual(ls, LinkState.parse(hex_value).dict())
def test_parse(self): hex_value = b'\x04\x04\x00\x04\x02\x02\x02\x02' ls = {29: [{'local-router-id': '2.2.2.2'}]} self.assertEqual(ls, LinkState.parse(hex_value).dict())
def test_parse(self): hex_value = b'\x04\x40\x00\x04\x00\x00\x00\x00' ls = {29: [{'administrative-group': 0}]} self.assertEqual(ls, LinkState.parse(hex_value).dict())
def test_parse(self): hex_value = b'\x04\x03\x00\x03\x50\x00\x00' ls = {29: [{'isis-area-id': '0x500000'}]} self.assertEqual(ls, LinkState.parse(hex_value).dict())
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_LINK_STATE: decode_value = LinkState.parse(value=attr_value).dict()[29] 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 = binascii.b2a_hex(attr_value) attributes[type_code] = decode_value return attributes
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 bgpls_pro_id = None bgpls_attr = None 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_LARGE_COMMUNITY: decode_value = LargeCommunity.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_MP_REACH_NLRI: decode_value = MpReachNLRI.parse(value=attr_value) if decode_value['nlri'][0] and type( decode_value['nlri'][0]) is dict: if decode_value['nlri'][0].get("protocol_id"): bgpls_pro_id = decode_value['nlri'][0]["protocol_id"] 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) pmsi_hex = attr_value elif type_code == bgp_cons.BGPTYPE_LINK_STATE: if bgpls_pro_id: attributes.update( LinkState.unpack(bgpls_pro_id=bgpls_pro_id, data=attr_value).dict()) else: bgpls_attr = attr_value continue else: decode_value = binascii.b2a_hex(attr_value) attributes[type_code] = decode_value if bgpls_attr: attributes.update( LinkState.unpack(bgpls_pro_id=bgpls_pro_id, data=attr_value).dict()) evpn_overlay = EVPN.signal_evpn_overlay(attributes) if evpn_overlay['evpn'] and evpn_overlay['encap_ec']: if bgp_cons.BGPTYPE_PMSI_TUNNEL in attributes: attributes[bgp_cons.BGPTYPE_PMSI_TUNNEL] = PMSITunnel.parse( value=pmsi_hex, evpn_overlay=evpn_overlay) return attributes
def test_unpack(self): self.maxDiff = None data_bin = b"\x04\x04\x00\x04\x03\x03\x03\x03\x04\x40\x00\x04\x00\x00\x00\x00" \ b"\x04\x41\x00\x04\x4c\xee\x6b\x28\x04\x42\x00\x04\x00\x00\x00\x00" \ b"\x04\x43\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x04\x44\x00\x04\x00\x00\x00\x01\x04\x47\x00\x03" \ b"\x00\x00\x01\x04\x4b\x00\x07\x60\x00\x00\x00\x00\x5d\xc1\x01\x0b" \ b"\x00\x02\x01\x0a\x04\x5a\x00\x04\x00\x0f\x42\x40\x04\x5b\x00\x08" \ b"\x00\x0f\x42\x40\x00\x0f\x42\x40\x04\x5c\x00\x04\x00\x00\x00\x00" \ b"\x04\x5d\x00\x04\x11\x11\x11\x11\x04\x5e\x00\x04\x11\x11\x11\x11" \ b"\x04\x5f\x00\x04\x11\x11\x11\x11\x04\x60\x00\x04\x11\x11\x11\x11" data_dict = { 29: [{ "type": "local_router_id", "value": "3.3.3.3" }, { "type": "admin_group", "value": 0 }, { "type": "max_bandwidth", "value": 125000000.0 }, { "type": "max_rsv_bandwidth", "value": 0.0 }, { "type": "unrsv_bandwidth", "value": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] }, { "type": "te_metric", "value": 1 }, { "type": "igp_metric", "value": 1 }, { "type": "adj_sid", "value": { "flags": { "P": 0, "B": 0, "L": 1, "G": 0, "V": 1 }, "value": 24001, "weight": 0 } }, { "type": "link_msd", "value": { "type": 1, "value": 10 } }, { "type": "unidirect_link_delay", "value": 1000000 }, { "type": "min_max_unidirect_link_delay", "value": { "max_link_delay": 1000000, "min_link_delay": 1000000 } }, { "type": "unidirect_delay_var", "value": 0 }, { "type": "unidirect_packet_loss", "value": 286331153 }, { "type": "unidirect_residual_bw", "value": 286331153 }, { "type": "unidirect_avail_bw", "value": 286331153 }, { "type": "unidirect_bw_util", "value": 286331153 }] } self.assertEqual(data_dict, LinkState.unpack(data_bin).dict())
def test_parse(self): hex_value = b'\x04\x47\x00\x03\x00\x00\x0a' ls = {29: [{'igp-link-metric': 10}]} self.assertEqual(ls, LinkState.parse(hex_value).dict())