def construct(cls, value): """Construct a attribute :param value: python dictionary {'afi_safi': (1,128), 'nexthop': {}, 'nlri': [] """ afi, safi = value['afi_safi'] if afi == afn.AFNUM_INET: if safi == safn.SAFNUM_LAB_VPNUNICAST: # MPLS VPN nexthop_hex = cls.construct_mpls_vpn_nexthop(value['nexthop']) nlri_hex = IPv4MPLSVPN.construct(value['nlri']) attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) +\ struct.pack('!B', len(nexthop_hex)) + nexthop_hex + b'\x00' + nlri_hex return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value elif safi == safn.SAFNUM_FSPEC_RULE: # BGP Flow spec try: try: nexthop = netaddr.IPAddress(value['nexthop']).packed except netaddr.core.AddrFormatError: nexthop = '' nlri = IPv4FlowSpec.construct(value=value['nlri']) if nlri: attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + \ struct.pack('!B', len(nexthop)) + nexthop + b'\x00' + nlri return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value except Exception as e: raise excep.ConstructAttributeFailed( reason='failed to construct attributes: %s' % e, data=value) else: raise excep.ConstructAttributeFailed( reason='unsupport this sub address family', data=value) # ipv6 unicast elif afi == afn.AFNUM_INET6: if safi == safn.SAFNUM_LAB_VPNUNICAST: # MPLS VPN nexthop_hex = cls.construct_mpls_vpn_nexthop(value['nexthop']) nlri_hex = IPv6MPLSVPN.construct(value['nlri']) attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) +\ struct.pack('!B', len(nexthop_hex)) + nexthop_hex + b'\x00' + nlri_hex return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value elif safi == safn.SAFNUM_UNICAST: nexthop_len = 16 nexthop_bin = netaddr.IPAddress(value['nexthop']).packed if value.get('linklocal_nexthop'): nexthop_len *= 2 nexthop_bin += netaddr.IPAddress( value['linklocal_nexthop']).packed nlri_bin = IPv6Unicast.construct(nlri_list=value['nlri']) attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + struct.pack('!B', nexthop_len) + \ nexthop_bin + b'\x00' + nlri_bin return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID)\ + struct.pack('!B', len(attr_value)) + attr_value # for l2vpn elif afi == afn.AFNUM_L2VPN: if safi == safn.SAFNUM_EVPN: nexthop_bin = netaddr.IPAddress(value['nexthop']).packed nlri_bin = EVPN.construct(nlri_list=value['nlri']) attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + struct.pack('!B', len(nexthop_bin)) + \ nexthop_bin + b'\x00' + nlri_bin return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID)\ + struct.pack('!B', len(attr_value)) + attr_value else: raise excep.ConstructAttributeFailed( reason='unsupport this sub address family', data=value)
def construct(cls, value): """Construct a attribute :param value: python dictionary { "0": "old", "6": 100, "7": 25102, "128": [ { "9": 10, "1": [ { "1": { "label": 2000 } }, { "3": { "node": "10.1.1.1", "SID": { "label": 3000, "TC": 0, "S": 0, "TTL": 255 } } } ] } ] } """ policy_hex = b'' policy = value data = dict([(int(l), r) for (l, r) in policy.items()]) policy_value_hex = b'' items = data.keys() if bgp_cons.BGP_BSID_PREFERENCE_OLD_OR_NEW not in items: raise excep.ConstructAttributeFailed( reason='failed to construct attributes: %s' % 'please provide the value of TLV encoding', data={}) for type_tmp in items: if type_tmp == bgp_cons.BGP_BSID_PREFERENCE_OLD_OR_NEW: # format of binding sid is same with the mpls label # the high order 20 bit was truly used as the bsid # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Label | ... | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # old ios if data[type_tmp] == 'old': # Preference Sub-TLV if bgp_cons.BGPSUB_TLV_PREFERENCE not in items: if bgp_cons.BGPSUB_TLV_PREFERENCE_NEW in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE) + struct.pack('!B', 6) + \ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE_NEW]) else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE) + struct.pack('!B', 6) + \ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE]) # Binding SID Sub-TLV if bgp_cons.BGPSUB_TLV_BINDGINGSID not in items: if bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW not in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID) + struct.pack('!B', 2) +\ b'\x00\x00' else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW] << 12) else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID] << 12) # new ios elif data[type_tmp] == 'new': # Preference Sub-TLV if bgp_cons.BGPSUB_TLV_PREFERENCE not in items: if bgp_cons.BGPSUB_TLV_PREFERENCE_NEW in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE_NEW) + struct.pack('!B', 6) + \ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE_NEW]) else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE_NEW) + struct.pack('!B', 6) + \ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE]) # Binding SID Sub-TLV if bgp_cons.BGPSUB_TLV_BINDGINGSID not in items: if bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW not in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW) + struct.pack('!B', 2) +\ b'\x00\x00' else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW] << 12) else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID] << 12) else: raise excep.ConstructAttributeFailed( reason='failed to construct attributes: %s' % 'TLV encoding must be one value of new or old', data={}) if type_tmp == bgp_cons.BGPSUB_TLV_SIDLIST: # Sub_TLV segment list seg_list_hex = b'' for seg_list in data[type_tmp]: segment_list = dict([(int(l), r) for (l, r) in seg_list.items()]) weight_hex, seg_hex = cls.construct_weight_and_seg( segment_list) seg_list_hex += struct.pack('!B', type_tmp) + struct.pack('!H', len(weight_hex) + len(seg_hex) + 1) +\ b'\x00' + weight_hex + seg_hex policy_value_hex += seg_list_hex policy_hex += struct.pack('!H', bgp_cons.BGP_TUNNEL_ENCAPS_SR_TE_POLICY_TYPE) +\ struct.pack('!H', len(policy_value_hex)) + policy_value_hex return struct.pack('!B', cls.FLAG) + struct.pack( '!B', cls.ID) + struct.pack('!H', len(policy_hex)) + policy_hex
def construct(cls, value): """Construct a attribute :param value: python dictionary {'afi_safi': (1,128), 'withdraw': [] """ afi, safi = value['afi_safi'] if afi == afn.AFNUM_INET: if safi == safn.SAFNUM_LAB_VPNUNICAST: # MPLS VPN nlri = IPv4MPLSVPN.construct(value['withdraw'], iswithdraw=True) if nlri: attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + nlri return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value else: return None elif safi == safn.SAFNUM_FSPEC_RULE: try: nlri_list = value.get('withdraw') or [] if not nlri_list: return None nlri_hex = b'' for nlri in nlri_list: nlri_hex += IPv4FlowSpec.construct(value=nlri) attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + nlri_hex return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value except Exception: raise excep.ConstructAttributeFailed( reason='failed to construct attributes', data=value ) else: raise excep.ConstructAttributeFailed( reason='unsupport this sub address family', data=value) elif afi == afn.AFNUM_INET6: if safi == safn.SAFNUM_UNICAST: nlri = IPv6Unicast.construct(nlri_list=value['withdraw']) if nlri: attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + nlri return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value elif safi == safn.SAFNUM_LAB_VPNUNICAST: nlri = IPv6MPLSVPN.construct(value=value['withdraw'], iswithdraw=True) if nlri: attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + nlri return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value else: return None # for l2vpn elif afi == afn.AFNUM_L2VPN: # for evpn if safi == safn.SAFNUM_EVPN: nlri = EVPN.construct(nlri_list=value['withdraw']) if nlri: attr_value = struct.pack('!H', afi) + struct.pack('!B', safi) + nlri return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ + struct.pack('!B', len(attr_value)) + attr_value else: return None else: raise excep.ConstructAttributeFailed( reason='unsupport this sub address family', data=value)
def construct(cls, value): """Construct a attribute :param value: python dictionary { "0": "old", "6": 100, "7": 25102, "128": [ { "9": 10, "1": [ { "1": { "label": 2000 } }, { "3": { "node": "10.1.1.1", "SID": { "label": 3000, "TC": 0, "S": 0, "TTL": 255 } } } ] } ] } """ policy_hex = b'' policy = value data = dict([(int(l), r) for (l, r) in policy.items()]) policy_value_hex = b'' items = data.keys() if bgp_cons.BGP_BSID_PREFERENCE_OLD_OR_NEW not in items: raise excep.ConstructAttributeFailed( reason='failed to construct attributes: %s' % 'please provide the value of TLV encoding', data={} ) for type_tmp in items: if type_tmp == bgp_cons.BGP_BSID_PREFERENCE_OLD_OR_NEW: # format of binding sid is same with the mpls label # the high order 20 bit was truly used as the bsid # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Label | ... | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # old ios if data[type_tmp] == 'old': # Preference Sub-TLV if bgp_cons.BGPSUB_TLV_PREFERENCE not in items: if bgp_cons.BGPSUB_TLV_PREFERENCE_NEW in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE) + struct.pack('!B', 6) + \ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE_NEW]) else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE) + struct.pack('!B', 6) + \ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE]) # Binding SID Sub-TLV if bgp_cons.BGPSUB_TLV_BINDGINGSID not in items: if bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW not in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID) + struct.pack('!B', 2) +\ b'\x00\x00' else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW] << 12) else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID] << 12) # new ios elif data[type_tmp] == 'new': # Preference Sub-TLV if bgp_cons.BGPSUB_TLV_PREFERENCE not in items: if bgp_cons.BGPSUB_TLV_PREFERENCE_NEW in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE_NEW) + struct.pack('!B', 6) + \ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE_NEW]) # else: # policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE_NEW) + \ # struct.pack('!B', 6) + b'\x00\x00' \ # + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE]) # Binding SID Sub-TLV if bgp_cons.BGPSUB_TLV_BINDGINGSID not in items: if bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW not in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW) + struct.pack('!B', 2) +\ b'\x00\x00' else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW] << 12) else: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW) + struct.pack('!B', 6) +\ b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID] << 12) # Explicit NULL Label Policy Sub-TLV if bgp_cons.BGPSUB_TLV_ENLP_NEW in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_ENLP_NEW) + struct.pack('!B', 3) + \ b'\x00\x00' + struct.pack('!B', data[bgp_cons.BGPSUB_TLV_ENLP_NEW]) # Policy Priority Sub-TLV if bgp_cons.BGPSUB_TLV_PRIORITY_NEW in items: policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PRIORITY_NEW) + struct.pack('!B', 2) + \ struct.pack('!B', data[bgp_cons.BGPSUB_TLV_PRIORITY_NEW]) + b'\x00' # Policy Name Sub-TLV if bgp_cons.BGPSUB_TLV_POLICYNAME_NEW in items: length = len(data[bgp_cons.BGPSUB_TLV_POLICYNAME_NEW]) + 1 policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_POLICYNAME_NEW) + struct.pack('!H', length) + \ b'\x00' + str(data[bgp_cons.BGPSUB_TLV_POLICYNAME_NEW]).encode('ascii') # 3.1. The Remote Endpoint Sub-TLV: if bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW in items: asn = data[bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW].get('asn') af = data[bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW].get('afi') address = data[bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW].get('address') if af == 'ipv4': length = 10 af_value = 1 elif af == 'ipv6': length = 22 af_value = 2 else: raise excep.ConstructAttributeFailed( reason='failed to construct attributes: %s' % 'remote endpoint address family' ' is ipv4 or ipv6', data={} ) policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW) + struct.pack('!B', length) \ + struct.pack('!I', asn) + struct.pack('!H', af_value) + netaddr.IPAddress(address).packed else: raise excep.ConstructAttributeFailed( reason='failed to construct attributes: %s' % 'TLV encoding must be one value of new or old', data={} ) if type_tmp == bgp_cons.BGPSUB_TLV_SIDLIST: # Sub_TLV segment list seg_list_hex = b'' for seg_list in data[type_tmp]: segment_list = dict([(int(l), r) for (l, r) in seg_list.items()]) weight_hex, seg_hex = cls.construct_weight_and_seg(segment_list) seg_list_hex += struct.pack('!B', type_tmp) + struct.pack('!H', len(weight_hex) + len(seg_hex) + 1) +\ b'\x00' + weight_hex + seg_hex policy_value_hex += seg_list_hex policy_hex += struct.pack('!H', bgp_cons.BGP_TUNNEL_ENCAPS_SR_TE_POLICY_TYPE) +\ struct.pack('!H', len(policy_value_hex)) + policy_value_hex return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) + struct.pack('!H', len(policy_hex)) + policy_hex