Пример #1
0
    def pack(self, negotiated, with_default=True, add_mp={}):
        local_asn = negotiated.local_as
        peer_asn = negotiated.peer_as

        message = ''

        default = {
            Attribute.CODE.ORIGIN:
            lambda l, r: Origin(Origin.IGP),
            #Attribute.CODE.AS_PATH: lambda l,r: ASPath([],[]) if l == r else ASPath([local_asn,],[]),
            Attribute.CODE.LOCAL_PREF:
            lambda l, r: LocalPreference(100) if l == r else NOTHING,
        }

        if hasattr(negotiated.neighbor, 'bgpsec'):
            if negotiated.neighbor.bgpsec:
                default[Attribute.CODE.BGPSEC] = lambda l, r: BGPSEC(
                    negotiated, add_mp)
            else:
                default[Attribute.CODE.AS_PATH] = lambda l, r: ASPath([], [
                ]) if l == r else ASPath([
                    local_asn,
                ], [])

        check = {
            Attribute.CODE.NEXT_HOP: lambda l, r, nh: nh.ipv4() is True,
            Attribute.CODE.LOCAL_PREF: lambda l, r, nh: l == r,
        }

        keys = self.keys()
        alls = set(keys + default.keys() if with_default else [])

        for code in sorted(alls):
            if code in (Attribute.CODE.INTERNAL_SPLIT,
                        Attribute.CODE.INTERNAL_WATCHDOG,
                        Attribute.CODE.INTERNAL_WITHDRAW,
                        Attribute.CODE.INTERNAL_NAME):
                continue

            if code not in keys and code in default:
                message += default[code](local_asn, peer_asn).pack(negotiated)
                continue

            attribute = self[code]

            if code in check and not check[code](local_asn, peer_asn,
                                                 attribute):
                continue

            if code in Attributes.MULTIPLE:
                for attr in attribute:
                    message += attr.pack(negotiated)
            else:
                message += attribute.pack(negotiated)

        return message
Пример #2
0
    def pack(self, negotiated, with_default=True):
        asn4 = negotiated.asn4
        local_asn = negotiated.local_as
        peer_asn = negotiated.peer_as

        if negotiated.neighbor.aigp is None:
            aigp = True if local_asn == peer_asn else False
        else:
            aigp = negotiated.neighbor.aigp

        message = ''

        default = {
            AID.ORIGIN:
            lambda l, r: Origin(Origin.IGP),
            AID.AS_PATH:
            lambda l, r: ASPath([], []) if l == r else ASPath([
                local_asn,
            ], []),
            AID.LOCAL_PREF:
            lambda l, r: LocalPreference('\x00\x00\x00d')
            if l == r else NOTHING,
        }

        check = {
            AID.NEXT_HOP: lambda l, r, nh: nh.afi == AFI.ipv4,
            AID.LOCAL_PREF: lambda l, r, nh: l == r,
        }

        if with_default:
            keys = set(self.keys() + default.keys())
        else:
            keys = set(self.keys())

        # AGGREGATOR generate both AGGREGATOR and AS4_AGGREGATOR
        for code in sorted(keys):
            if code in (AID.INTERNAL_SPLIT, AID.INTERNAL_WATCHDOG,
                        AID.INTERNAL_WITHDRAW):
                continue
            if code in self:
                if code == AID.AIGP and not aigp:
                    continue
                if code in check:
                    if check[code](local_asn, peer_asn, self[code]):
                        message += self[code].pack(asn4)
                        continue
                else:
                    message += self[code].pack(asn4)
                    continue
            else:
                if code in default:
                    message += default[code](local_asn, peer_asn).pack(asn4)

        return message
Пример #3
0
    def pack(self, negotiated, with_default=True, add_mp={}):
        local_asn = negotiated.local_as
        peer_asn = negotiated.peer_as

        message = b''

        default = {
            Attribute.CODE.ORIGIN:
            lambda left, right: Origin(Origin.IGP),
            #Attribute.CODE.AS_PATH: lambda left,right: ASPath([],[]) if left == right else ASPath([local_asn,],[]),
            Attribute.CODE.LOCAL_PREF:
            lambda left, right: LocalPreference(100)
            if left == right else NOTHING,
        }

        if hasattr(negotiated.neighbor, 'bgpsec'):
            if negotiated.neighbor.bgpsec:
                default[Attribute.CODE.BGPSEC] = lambda l, r: BGPSEC(
                    negotiated, add_mp)
            else:
                default[Attribute.CODE.AS_PATH] = lambda l, r: ASPath([], [
                ]) if l == r else ASPath([
                    local_asn,
                ], [])

        skip = {
            Attribute.CODE.NEXT_HOP:
            lambda left, right, nh: nh.ipv4() is not True,
            Attribute.CODE.LOCAL_PREF: lambda left, right, nh: left != right,
        }

        keys = list(self)
        alls = set(keys + list(default) if with_default else [])

        for code in sorted(alls):
            if code in Attributes.INTERNAL:
                continue

            if code not in keys and code in default:
                message += default[code](local_asn, peer_asn).pack(negotiated)
                continue

            attribute = self[code]

            if code in skip and skip[code](local_asn, peer_asn, attribute):
                continue

            message += attribute.pack(negotiated)

        return message
Пример #4
0
    def pack(self, negotiated, with_default=True):
        local_asn = negotiated.local_as
        peer_asn = negotiated.peer_as

        message = ''

        default = {
            Attribute.CODE.ORIGIN:
            lambda l, r: Origin(Origin.IGP),
            Attribute.CODE.AS_PATH:
            lambda l, r: ASPath([], []) if l == r else ASPath([
                local_asn,
            ], []),
            Attribute.CODE.LOCAL_PREF:
            lambda l, r: LocalPreference(100) if l == r else NOTHING,
        }

        skip = {
            Attribute.CODE.NEXT_HOP: lambda l, r, nh: nh.ipv4() is not True,
            Attribute.CODE.LOCAL_PREF: lambda l, r, nh: l != r,
        }

        keys = self.keys()
        alls = set(keys + default.keys() if with_default else [])

        for code in sorted(alls):
            if code in (Attribute.CODE.INTERNAL_SPLIT,
                        Attribute.CODE.INTERNAL_WATCHDOG,
                        Attribute.CODE.INTERNAL_WITHDRAW,
                        Attribute.CODE.INTERNAL_NAME):
                continue

            if code not in keys and code in default:
                message += default[code](local_asn, peer_asn).pack(negotiated)
                continue

            attribute = self[code]

            if code in skip and skip[code](local_asn, peer_asn, attribute):
                continue

            if code in Attributes.MULTIPLE:
                for attr in attribute:
                    message += attr.pack(negotiated)
            else:
                message += attribute.pack(negotiated)

        return message
Пример #5
0
    def pack(self, negotiated, with_default=True):
        local_asn = negotiated.local_as
        peer_asn = negotiated.peer_as

        message = ''

        default = {
            Attribute.CODE.ORIGIN:
            lambda l, r: Origin(Origin.IGP),  # noqa
            Attribute.CODE.AS_PATH:
            lambda l, r: ASPath([], []) if l == r else ASPath([
                local_asn,
            ], []),  # noqa
            Attribute.CODE.LOCAL_PREF:
            lambda l, r: LocalPreference(100) if l == r else NOTHING,  # noqa
        }

        check = {
            Attribute.CODE.NEXT_HOP:
            lambda l, r, nh: nh.ipv4() == True,  # noqa
            Attribute.CODE.LOCAL_PREF: lambda l, r, nh: l == r,
        }

        if with_default:
            keys = set(self.keys() + default.keys())
        else:
            keys = set(self.keys())

        for code in sorted(keys):
            if code in (Attribute.CODE.INTERNAL_SPLIT,
                        Attribute.CODE.INTERNAL_WATCHDOG,
                        Attribute.CODE.INTERNAL_WITHDRAW,
                        Attribute.CODE.INTERNAL_NAME):
                continue
            if code in self:
                if code in check:
                    if check[code](local_asn, peer_asn, self[code]):
                        message += self[code].pack(negotiated)
                        continue
                else:
                    message += self[code].pack(negotiated)
                    continue
            else:
                if code in default:
                    message += default[code](local_asn,
                                             peer_asn).pack(negotiated)

        return message
Пример #6
0
def aspath(tokeniser):
    as_seq = []
    as_set = []
    value = tokeniser()
    inset = False
    try:
        if value == '[':
            while True:
                value = tokeniser()
                if value == ',':
                    continue
                if value in ('(', '['):
                    inset = True
                    while True:
                        value = tokeniser()
                        if value == ')':
                            break
                        as_set.append(asn(tokeniser, value))
                if value == ')':
                    inset = False
                    continue
                if value == ']':
                    if inset:
                        inset = False
                        continue
                    break
                as_seq.append(ASN(tokeniser, value))
        else:
            as_seq.append(asn(tokeniser, value))
    except ValueError:
        raise ValueError('could not parse as-path')
    return ASPath(as_seq, as_set)
Пример #7
0
    def merge_attributes(self):
        as2path = self[Attribute.CODE.AS_PATH]
        as4path = self[Attribute.CODE.AS4_PATH]
        self.remove(Attribute.CODE.AS_PATH)
        self.remove(Attribute.CODE.AS4_PATH)

        # this key is unique as index length is a two header, plus a number of ASN of size 2 or 4
        # so adding the: make the length odd and unique
        key = "%s:%s" % (as2path.index, as4path.index)

        # found a cache copy
        cached = Attribute.cache.get(Attribute.CODE.AS_PATH, {}).get(key, None)
        if cached:
            self.add(cached, key)
            return

        # as_seq = []
        # as_set = []

        len2 = len(as2path.as_seq)
        len4 = len(as4path.as_seq)

        # RFC 4893 section 4.2.3
        if len2 < len4:
            as_seq = as2path.as_seq
        else:
            as_seq = as2path.as_seq[:-len4]
            as_seq.extend(as4path.as_seq)

        len2 = len(as2path.as_set)
        len4 = len(as4path.as_set)

        if len2 < len4:
            as_set = as4path.as_set
        else:
            as_set = as2path.as_set[:-len4]
            as_set.extend(as4path.as_set)

        aspath = ASPath(as_seq, as_set)
        self.add(aspath, key)
Пример #8
0
    def merge_attributes(self):
        as2path = self[AID.AS_PATH]
        as4path = self[AID.AS4_PATH]
        self.remove(AID.AS_PATH)
        self.remove(AID.AS4_PATH)

        # this key is unique as index length is a two header, plus a number of ASN of size 2 or 4
        # so adding the : make the length odd and unique
        key = "%s:%s" % (as2path.index, as4path.index)

        # found a cache copy
        if self.add_from_cache(AID.AS_PATH, key):
            return

        as_seq = []
        as_set = []

        len2 = len(as2path.as_seq)
        len4 = len(as4path.as_seq)

        # RFC 4893 section 4.2.3
        if len2 < len4:
            as_seq = as2path.as_seq
        else:
            as_seq = as2path.as_seq[:-len4]
            as_seq.extend(as4path.as_seq)

        len2 = len(as2path.as_set)
        len4 = len(as4path.as_set)

        if len2 < len4:
            as_set = as4path.as_set
        else:
            as_set = as2path.as_set[:-len4]
            as_set.extend(as4path.as_set)

        aspath = ASPath(as_seq, as_set)
        self.add(aspath, key)