Example #1
0
    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)
Example #2
0
    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
Example #3
0
    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)
Example #4
0
    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