Ejemplo n.º 1
0
 def test_parse(self):
     self.maxDiff = None
     data_bin = b"\x00\x02\x00" \
                b"\x55\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x02\x00" \
                b"\x00\x04\x00\x00\xff\xfe\x02\x01\x00\x04\x00\x00\x00\x00\x02\x03" \
                b"\x00\x06\x00\x00\x00\x00\x00\x03\x01\x01\x00\x1a\x02\x00\x00\x04" \
                b"\x00\x00\xff\xfe\x02\x01\x00\x04\x00\x00\x00\x00\x02\x03\x00\x06" \
                b"\x00\x00\x00\x00\x00\x01\x01\x03\x00\x04\x01\x03\x00\x02\x01\x04" \
                b"\x00\x04\x01\x03\x00\x01"
     data_dict = [{
         'type':
         'link',
         'value': [
             {
                 'type': 'local-node',
                 'value': {
                     'as': 65534,
                     'bgpls-id': '0.0.0.0',
                     'igp-id': '0.0.0.3'
                 }
             },
             {
                 'type': 'remote-node',
                 'value': {
                     'as': 65534,
                     'bgpls-id': '0.0.0.0',
                     'igp-id': '0.0.0.1'
                 }
             },
             {
                 'type': 'link-local-ipv4',
                 'value': '1.3.0.2'
             },
             {
                 'type': 'link-remote-ipv4',
                 'value': '1.3.0.1'
             },
         ]
     }]
     self.assertEqual(data_dict, BGPLS.parse(data_bin))
Ejemplo n.º 2
0
 def test_parse(self):
     self.maxDiff = None
     data_bin = b"\x00\x02\x00" \
                b"\x55\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x02\x00" \
                b"\x00\x04\x00\x00\xff\xfe\x02\x01\x00\x04\x00\x00\x00\x00\x02\x03" \
                b"\x00\x06\x00\x00\x00\x00\x00\x03\x01\x01\x00\x1a\x02\x00\x00\x04" \
                b"\x00\x00\xff\xfe\x02\x01\x00\x04\x00\x00\x00\x00\x02\x03\x00\x06" \
                b"\x00\x00\x00\x00\x00\x01\x01\x03\x00\x04\x01\x03\x00\x02\x01\x04" \
                b"\x00\x04\x01\x03\x00\x01"
     data_dict = [
         {
             'type': 'link',
             'protocol_id': 2,
             'instances_id': 0,
             'descriptors': [
                 {
                     'type': 'local_node',
                     'value': {
                         'as_num': 65534,
                         'bgpls_id': '0.0.0.0',
                         'igp_router_id': {'pseudonode': False, 'iso_node_id': '0000.0000.0003'}}},
                 {
                     'type': 'remote_node',
                     'value': {
                         'as_num': 65534,
                         'bgpls_id': '0.0.0.0',
                         'igp_router_id': {
                             'pseudonode': False,
                             'iso_node_id': '0000.0000.0001'
                         }}},
                 {
                     'type': 'link_local_ipv4',
                     'value': '1.3.0.2'},
                 {
                     'type': 'link_remote_ipv4',
                     'value': '1.3.0.1'},
             ]
         }
     ]
     self.assertEqual(data_dict, BGPLS.parse(data_bin))
Ejemplo n.º 3
0
 def test_parse(self):
     self.maxDiff = None
     data_bin = b"\x00\x02\x00\x51\x07\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" \
                b"\x18\x02\x00\x00\x04\x00\x00\x00\xc8\x02\x01\x00\x04\x00\x00\x00" \
                b"\x00\x02\x05\x00\x04\x00\x00\x00" \
                b"\xc8\x01\x01\x00\x18\x02\x00\x00\x04\x00\x00\x01\x2c\x02\x01\x00" \
                b"\x04\x00\x00\x00\x00\x02\x05\x00" \
                b"\x04\x00\x00\x01\x2c\x01\x03\x00\x04\xc0\xa8\x04\x03\x01\x04\x00" \
                b"\x04\xc0\xa8\x04\x04"
     data_dict = [
         {
             'type': 'link',
             'protocol_id': 7,
             'instances_id': 0,
             'descriptors': [
                 {
                     'type': 'local_node',
                     'value': {
                         'as_num': 200,
                         'bgpls_id': '0.0.0.0',
                         # 'bgp_router_id': '3.3.3.3',
                         'member_as_num': 200}},
                 {
                     'type': 'remote_node',
                     'value': {
                         'as_num': 300,
                         'bgpls_id': '0.0.0.0',
                         # 'bgp_router_id': '4.4.4.4',
                         'member_as_num': 300}},
                 {
                     'type': 'link_local_ipv4',
                     'value': '192.168.4.3'},
                 {
                     'type': 'link_remote_ipv4',
                     'value': '192.168.4.4'},
             ]
         }
     ]
     self.assertEqual(data_dict, BGPLS.parse(data_bin))
Ejemplo n.º 4
0
    def parse(cls, value):
        try:
            afi, safi = struct.unpack('!HB', value[0:3])
        except Exception:
            raise excep.UpdateMessageError(sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,
                                           data='')

        nlri_bin = value[3:]

        # for IPv4
        if afi == afn.AFNUM_INET:

            # VPNv4
            if safi == safn.SAFNUM_LAB_VPNUNICAST:
                nlri = IPv4MPLSVPN.parse(nlri_bin, iswithdraw=True)
                return dict(afi_safi=(afi, safi), withdraw=nlri)
            # BGP flow spec
            elif safi == safn.SAFNUM_FSPEC_RULE:
                # if nlri length is greater than 240 bytes, it is encoded over 2 bytes
                withdraw_list = []
                while nlri_bin:
                    length = ord(nlri_bin[0])
                    if length >> 4 == 0xf and len(nlri_bin) > 2:
                        length = struct.unpack('!H', nlri_bin[:2])[0]
                        nlri_tmp = nlri_bin[2: length + 2]
                        nlri_bin = nlri_bin[length + 2:]
                    else:
                        nlri_tmp = nlri_bin[1: length + 1]
                        nlri_bin = nlri_bin[length + 1:]
                    nlri = IPv4FlowSpec.parse(nlri_tmp)
                    if nlri:
                        withdraw_list.append(nlri)

                return dict(afi_safi=(afi, safi), withdraw=withdraw_list)
            else:
                return dict(afi_safi=(afn.AFNUM_INET, safi), withdraw=repr(nlri_bin))
        # for ipv6
        elif afi == afn.AFNUM_INET6:
            # for ipv6 unicast
            if safi == safn.SAFNUM_UNICAST:
                return dict(afi_safi=(afi, safi), withdraw=IPv6Unicast.parse(nlri_data=nlri_bin))
            elif safi == safn.SAFNUM_LAB_VPNUNICAST:
                return dict(afi_safi=(afi, safi), withdraw=IPv6MPLSVPN.parse(value=nlri_bin, iswithdraw=True))
            else:
                return dict(afi_safi=(afi, safi), withdraw=repr(nlri_bin))
        # for l2vpn
        elif afi == afn.AFNUM_L2VPN:
            # for evpn
            if safi == safn.SAFNUM_EVPN:
                return dict(afi_safi=(afi, safi), withdraw=EVPN.parse(nlri_data=nlri_bin))
            else:
                return dict(afi_safi=(afi, safi), withdraw=repr(nlri_bin))
        # BGP LS
        elif afi == afn.AFNUM_BGPLS:
            if safi == safn.SAFNUM_BGPLS:
                withdraw = BGPLS.parse(nlri_bin)
                return dict(afi_safi=(afi, safi), withdraw=withdraw)
            else:
                pass
        else:
            return dict(afi_safi=(afi, safi), withdraw=repr(nlri_bin))
Ejemplo n.º 5
0
    def parse(cls, value):
        """parse
        """
        try:
            afi, safi, nexthop_length = struct.unpack('!HBB', value[0:4])
            nexthop_bin = value[4:4 + nexthop_length]
            nlri_bin = value[5 + nexthop_length:]
        except Exception:
            # error when lenght is wrong
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=str(value))

        #  Address Family IPv4
        if afi == afn.AFNUM_INET:
            if safi == safn.SAFNUM_LAB_VPNUNICAST:
                # MPLS VPN
                # parse nexthop
                rd_bin = nexthop_bin[0:8]
                rd_type = struct.unpack('!H', rd_bin[0:2])[0]
                rd_value_bin = rd_bin[2:]
                if rd_type == 0:
                    asn, an = struct.unpack('!HI', rd_value_bin)
                    ipv4 = str(
                        netaddr.IPAddress(
                            int(binascii.b2a_hex(nexthop_bin[8:]), 16)))
                    nexthop = {'rd': '%s:%s' % (asn, an), 'str': ipv4}
                else:
                    nexthop = binascii.b2a_hex((nexthop_bin[8:]))
                # parse nlri
                nlri = IPv4MPLSVPN.parse(nlri_bin)
                return dict(afi_safi=(afi, safi), nexthop=nexthop, nlri=nlri)
            elif safi == safn.SAFNUM_MPLS_LABEL:
                if nexthop_bin:
                    nexthop = str(
                        netaddr.IPAddress(
                            int(binascii.b2a_hex(nexthop_bin), 16)))
                else:
                    nexthop = ''
                nlri = IPv4LabeledUnicast.parse(nlri_bin)
                return dict(afi_safi=(afi, safi), nexthop=nexthop, nlri=nlri)
            elif safi == safn.SAFNUM_FSPEC_RULE:
                # if nlri length is greater than 240 bytes, it is encoded over 2 bytes
                nlri_list = []
                while nlri_bin:
                    length = ord(nlri_bin[0])
                    if length >> 4 == 0xf and len(nlri_bin) > 2:
                        length = struct.unpack('!H', nlri_bin[:2])[0]
                        nlri_tmp = nlri_bin[2:length + 2]
                        nlri_bin = nlri_bin[length + 2:]
                    else:
                        nlri_tmp = nlri_bin[1:length + 1]
                        nlri_bin = nlri_bin[length + 1:]
                    nlri = IPv4FlowSpec.parse(nlri_tmp)
                    if nlri:
                        nlri_list.append(nlri)
                if nexthop_bin:
                    nexthop = str(
                        netaddr.IPAddress(
                            int(binascii.b2a_hex(nexthop_bin), 16)))
                else:
                    nexthop = ''
                return dict(afi_safi=(afi, safi),
                            nexthop=nexthop,
                            nlri=nlri_list)
            else:
                nlri = binascii.b2a_hex(nlri_bin)

        # #  Address Family IPv6
        elif afi == afn.AFNUM_INET6:
            # IPv6 unicast
            if safi == safn.SAFNUM_UNICAST:
                # decode nexthop
                # RFC 2545
                # The value of the Length of Next Hop Network Address field on a
                # MP_REACH_NLRI attribute shall be set to 16, when only a global
                # address is present, or 32 if a link-local address is also included in
                # the Next Hop field.
                #
                # The link-local address shall be included in the Next Hop field if and
                # only if the BGP speaker shares a common subnet with the entity
                # identified by the global IPv6 address carried in the Network Address
                # of Next Hop field and the peer the route is being advertised to.
                nexthop_addrlen = 16
                has_link_local = False
                nexthop = str(
                    netaddr.IPAddress(
                        int(binascii.b2a_hex(nexthop_bin[:nexthop_addrlen]),
                            16)))
                if len(nexthop_bin) == 2 * nexthop_addrlen:
                    # has link local address
                    has_link_local = True
                    linklocal_nexthop = str(
                        netaddr.IPAddress(
                            int(
                                binascii.b2a_hex(
                                    nexthop_bin[nexthop_addrlen:]), 16)))
                nlri = IPv6Unicast.parse(nlri_bin)
                if has_link_local:
                    return dict(afi_safi=(afi, safi),
                                nexthop=nexthop,
                                linklocal_nexthop=linklocal_nexthop,
                                nlri=nlri)
                else:
                    return dict(afi_safi=(afi, safi),
                                nexthop=nexthop,
                                nlri=nlri)
            elif safi == safn.SAFNUM_LAB_VPNUNICAST:
                # IPv6 MPLS VPN
                # parse nexthop
                rd_bin = nexthop_bin[0:8]
                rd_type = struct.unpack('!H', rd_bin[0:2])[0]
                rd_value_bin = rd_bin[2:]
                if rd_type == 0:
                    asn, an = struct.unpack('!HI', rd_value_bin)
                    ipv6 = str(
                        netaddr.IPAddress(
                            int(binascii.b2a_hex(nexthop_bin[8:]), 16)))
                    nexthop = {'rd': '%s:%s' % (asn, an), 'str': ipv6}
                # TODO(xiaoquwl) for other RD type decoding
                else:
                    nexthop = binascii.b2a_hex(nexthop_bin[8:])
                # parse nlri
                nlri = IPv6MPLSVPN.parse(nlri_bin)
                return dict(afi_safi=(afi, safi), nexthop=nexthop, nlri=nlri)
            elif safi == safn.SAFNUM_MPLS_LABEL:
                if nexthop_bin:
                    nexthop = str(
                        netaddr.IPAddress(
                            int(binascii.b2a_hex(nexthop_bin), 16)))
                else:
                    nexthop = ''
                nlri = IPv6LabeledUnicast.parse(nlri_bin)
                return dict(afi_safi=(afi, safi), nexthop=nexthop, nlri=nlri)
            else:
                return dict(afi_safi=(afi, safi),
                            nexthop=nexthop_bin,
                            nlri=nlri_bin)

        # for l2vpn
        elif afi == afn.AFNUM_L2VPN:
            if safi == safn.SAFNUM_EVPN:
                nexthop = str(
                    netaddr.IPAddress(int(binascii.b2a_hex(nexthop_bin), 16)))
                nlri = EVPN.parse(nlri_bin)
                return dict(afi_safi=(afi, safi), nexthop=nexthop, nlri=nlri)
            else:
                nlri = binascii.b2a_hex(nlri_bin)

        # BGP LS
        elif afi == afn.AFNUM_BGPLS:
            if safi == safn.SAFNUM_BGPLS:
                nexthop = str(
                    netaddr.IPAddress(int(binascii.b2a_hex(nexthop_bin), 16)))
                nlri = BGPLS.parse(nlri_bin)
                return dict(afi_safi=(afi, safi), nexthop=nexthop, nlri=nlri)
            else:
                pass
        else:
            nlri = binascii.b2a_hex(nlri_bin)

        return dict(afi_safi=(afi, safi),
                    nexthop=binascii.b2a_hex(nexthop_bin),
                    nlri=binascii.b2a_hex(nlri_bin))