Example #1
0
    def setUp(self):
        self.negotiated = {}

        for asn4 in (True, False):
            neighbor = FakeNeighbor()
            neighbor.asn4 = asn4

            capa = Capabilities().new(neighbor, False)
            capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()

            # path = {}
            # for f in NLRI.known_families():
            # 	if neighbor.add_path:
            # 		path[f] = neighbor.add_path
            # capa[Capability.CODE.ADD_PATH] = path

            routerid_1 = str(neighbor.router_id)
            routerid_2 = '.'.join(
                str((int(_) + 1) % 250)
                for _ in str(neighbor.router_id).split('.', -1))

            o1 = Open(Version(4), ASN(neighbor.local_as), HoldTime(180),
                      RouterID(routerid_1), capa)
            o2 = Open(Version(4), ASN(neighbor.peer_as), HoldTime(180),
                      RouterID(routerid_2), capa)

            negotiated = Negotiated(neighbor)
            negotiated.sent(o1)
            negotiated.received(o2)

            self.negotiated[asn4] = negotiated
Example #2
0
class FakeNeighbor(object):
    description = 'a test neighbor'
    router_id = RouterID('127.0.0.1')
    local_address = IPv4('127.0.0.1')
    peer_address = IPv4('127.0.0.1')
    host_name = 'localhost'
    domain_name = 'localdomain'
    peer_as = ASN('65500')
    local_as = ASN('65500')
    hold_time = HoldTime(180)
    asn4 = False
    add_path = 0
    extended_message = False
    nexthop = None

    # capability
    route_refresh = False
    graceful_restart = False
    multisession = None
    add_path = None
    aigp = None
    operational = None

    @staticmethod
    def families():
        return NLRI.known_families()
Example #3
0
    def unpack_nlri(cls, afi, safi, bgp, action, addpath):

        length = bgp[0]

        if length == 0:
            return cls(afi, safi, action, ASN(0), None), bgp[1:]

        if length < 8 * 4:
            raise Exception("incorrect RT length: %d (should be >=32,<=96)" %
                            length)

        # We are reseting the flags on the RouteTarget extended
        # community, because they do not make sense for an RTC route

        return (
            cls(
                afi,
                safi,
                action,
                ASN(unpack('!L', bgp[1:5])[0]),
                RouteTarget.unpack(
                    bytes([RTC.resetFlags(bgp[5])]) + bgp[6:13]),
            ),
            bgp[13:],
        )
Example #4
0
    def setUp(self):
        self.negotiated = {}

        for asn4 in (True, False):
            neighbor = FakeNeighbor()
            neighbor.asn4 = asn4

            capa = Capabilities().new(neighbor, False)
            capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()

            # path = {}
            # for f in NLRI.known_families():
            # 	if neighbor.add_path:
            # 		path[f] = neighbor.add_path
            # capa[Capability.CODE.ADD_PATH] = path

            o1 = Open(Version(4), ASN(neighbor.local_as), HoldTime(180),
                      RouterID(neighbor.local_address.top()), capa)
            o2 = Open(Version(4), ASN(neighbor.peer_as), HoldTime(180),
                      RouterID(neighbor.peer_address.top()), capa)

            negotiated = Negotiated(neighbor)
            negotiated.sent(o1)
            negotiated.received(o2)

            self.negotiated[asn4] = negotiated
Example #5
0
 def __init__(self):
     self.update({
         'description': 'a test neighbor',
         'router-id': RouterID('127.0.0.1'),
         'local-address': IPv4('127.0.0.1'),
         'peer-address': IPv4('127.0.0.1'),
         'host-name': 'localhost',
         'domain-name': 'localdomain',
         'peer-as': ASN('65500'),
         'local-as': ASN('65500'),
         'hold-time': HoldTime(180),
         'capability': {
             'asn4': False,
             'add-path': 0,
             'extended_message': False,
             'nexthop': None,
             'route-refresh': False,
             'graceful-restart': False,
             'multi-session': None,
             'add-path': None,
             'aigp': None,
             'operational': None,
             'extended-message': True,
         },
     })
Example #6
0
 def __init__(self, local, remote, asn, peer):
     self['local-address'] = IPv4(local)
     self['peer_address'] = IPv4(remote)
     self['peer-as'] = ASN(asn)
     self['local-as'] = ASN(peer)
     self['capability'] = {
         'asn4': True,
     }
Example #7
0
File: rtc.py Project: xw2060/exabgp
    def unpack(afi, safi, data):
        length = ord(data[0])

        if length == 0:
            return RouteTargetConstraint(afi, safi, ASN(0), None)

        return RouteTargetConstraint(afi, safi,
                                     ASN(unpack('!L', data[1:5])[0]),
                                     RouteTarget.unpack(data[5:]))
Example #8
0
    def unpack(cls, afi, safi, data, addpath, nexthop, action):
        length = ord(data[0])

        if length == 0:
            return 1, cls(afi, safi, action, NoNextHop, ASN(0), None)

        # We are reseting the flags on the RouteTarget extended
        # community, because they do not make sense for an RTC route

        return 13, cls(
            afi, safi, action, nexthop, ASN(unpack('!L', data[1:5])[0]),
            RouteTarget.unpack(RTC.resetFlags(data[5]) + data[6:13]))
Example #9
0
    def unpack(cls, afi, safi, data, addpath, nexthop, action):
        length = ord(data[0])

        if length == 0:
            return 1, RouteTargetConstraint(afi, safi, action, ASN(0), None)

        # safeguard: let's ignore any ext com flag that might be set here
        packedRT = RouteTargetConstraint.resetFlags(data[5]) + data[6:13]

        return 13, RouteTargetConstraint(afi, safi, action, nexthop,
                                         ASN(unpack('!L', data[1:5])[0]),
                                         RouteTarget.unpack(packedRT))
Example #10
0
    def unpack_nlri(cls, afi, safi, bgp, action, addpath):

        length = ord(bgp[0])

        if length == 0:
            return 1, cls(afi, safi, action, ASN(0), None)

        # We are reseting the flags on the RouteTarget extended
        # community, because they do not make sense for an RTC route

        return cls(afi, safi, action, ASN(unpack('!L', bgp[1:5])[0]),
                   RouteTarget.unpack(RTC.resetFlags(bgp[5]) +
                                      bgp[6:13])), bgp[13:]
Example #11
0
    def __init__(self):
        self.sent_open = None
        self.received_open = None

        self.holdtime = HoldTime(0)
        self.local_as = ASN(0)
        self.peer_as = ASN(0)
        self.families = []
        self.asn4 = False
        self.addpath = RequirePath()
        self.multisession = False
        self.msg_size = 4096 - 19
        self.operational = False
Example #12
0
 def newASN(value):
     if value.count('.'):
         high, low = value.split('.', 1)
         as_number = (int(high) << 16) + int(low)
     else:
         as_number = int(value)
     return ASN(as_number)
Example #13
0
	def __init__ (self,aggregator):
		asn = 0
		for value in (ord(_) for _ in aggregator[:-4]):
			asn = (asn << 8) + value
		self.asn=ASN(asn)
		self.speaker=Inet(AFI.ipv4,SAFI.unicast,aggregator[-4:])
		self._str = '%s:%s' % (self.asn,self.speaker)
Example #14
0
    def aggregator(self, scope, name, command, tokens):
        try:
            if tokens:
                if tokens.pop(0) != '(':
                    raise ValueError('invalid aggregator syntax')
                asn, address = tokens.pop(0).split(':')
                if tokens.pop(0) != ')':
                    raise ValueError('invalid aggregator syntax')
                local_as = ASN(asn)
                local_address = RouterID(address)
            else:
                local_as = scope[-1]['local-as']
                local_address = scope[-1]['local-address']
        except (ValueError, IndexError):
            return self.error.set(self.syntax)
        except KeyError:
            return self.error(
                'local-as and/or local-address missing from neighbor/group to make aggregator'
            )
        except ValueError:
            return self.error.set(self.syntax)

        scope[-1]['announce'][-1].attributes.add(
            Aggregator(local_as, local_address))
        return True
Example #15
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)
Example #16
0
    def __init__(self, neighbor):
        self.neighbor = neighbor

        self.sent_open = None
        self.received_open = None

        self.holdtime = HoldTime(0)
        self.local_as = ASN(0)
        self.peer_as = ASN(0)
        self.families = []
        self.asn4 = False
        self.addpath = RequirePath()
        self.multisession = False
        self.msg_size = self.MAX_SIZE
        self.operational = False
        self.refresh = REFRESH.ABSENT  # pylint: disable=E1101
        self.aigp = None
Example #17
0
 def discard(self, scope, name, command, tokens):
     # README: We are setting the ASN as zero as that what Juniper (and Arbor) did when we created a local flow route
     try:
         scope[-1]['announce'][-1].attributes[
             Attribute.CODE.EXTENDED_COMMUNITY].add(TrafficRate(ASN(0), 0))
         return True
     except ValueError:
         return self.error.set(self.syntax)
Example #18
0
    def __init__(self, neighbor):
        self.neighbor = neighbor

        self.sent_open = None
        self.received_open = None

        self.holdtime = HoldTime(0)
        self.local_as = ASN(0)
        self.peer_as = ASN(0)
        self.families = []
        self.asn4 = False
        self.addpath = RequirePath()
        self.multisession = False
        self.msg_size = 4096
        self.operational = False
        self.refresh = REFRESH.absent
        self.aigp = None
Example #19
0
    def _new_aspaths(cls, data, asn4, klass=None):
        as_set = []
        as_seq = []
        as_cset = []
        as_cseq = []

        backup = data

        unpacker = {
            False: '!H',
            True: '!L',
        }
        size = {
            False: 2,
            True: 4,
        }
        as_choice = {
            ASPath.AS_SEQUENCE: as_seq,
            ASPath.AS_SET: as_set,
            ASPath.AS_CONFED_SEQUENCE: as_cseq,
            ASPath.AS_CONFED_SET: as_cset,
        }

        upr = unpacker[asn4]
        length = size[asn4]

        try:

            while data:
                stype = data[0]
                slen = data[1]

                if stype not in (ASPath.AS_SET, ASPath.AS_SEQUENCE,
                                 ASPath.AS_CONFED_SEQUENCE,
                                 ASPath.AS_CONFED_SET):
                    raise Notify(3, 11, 'invalid AS Path type sent %d' % stype)

                end = 2 + (slen * length)
                sdata = data[2:end]
                data = data[end:]
                # Eat the data and ignore it if the ASPath attribute is know known
                asns = as_choice.get(stype, [])

                for _ in range(slen):
                    asn = unpack(upr, sdata[:length])[0]
                    asns.append(ASN(asn))
                    sdata = sdata[length:]

        except IndexError:
            raise Notify(3, 11,
                         'not enough data to decode AS_PATH or AS4_PATH')
        except error:  # struct
            raise Notify(3, 11,
                         'not enough data to decode AS_PATH or AS4_PATH')

        if klass:
            return klass(as_seq, as_set, as_cseq, as_cset, backup)
        return cls(as_seq, as_set, as_cseq, as_cset, backup)
Example #20
0
def rate_limit(tokeniser):
    # README: We are setting the ASN as zero as that what Juniper (and Arbor) did when we created a local flow route
    speed = int(tokeniser())
    if speed < 9600 and speed != 0:
        log.warning("rate-limiting flow under 9600 bytes per seconds may not work", 'configuration')
    if speed > 1000000000000:
        speed = 1000000000000
        log.warning("rate-limiting changed for 1 000 000 000 000 bytes from %s" % speed, 'configuration')
    return ExtendedCommunities().add(TrafficRate(ASN(0), speed))
Example #21
0
 def unpack_message(cls, data, _=None):
     version = data[0]
     if version != 4:
         # Only version 4 is supported nowdays..
         raise Notify(2, 1, bytes(data[0], 'ascii'))
     asn = unpack('!H', data[1:3])[0]
     hold_time = unpack('!H', data[3:5])[0]
     numeric = unpack('!L', data[5:9])[0]
     router_id = "%d.%d.%d.%d" % (numeric >> 24, (numeric >> 16) & 0xFF, (numeric >> 8) & 0xFF, numeric & 0xFF)
     return cls(Version(version), ASN(asn), HoldTime(hold_time), RouterID(router_id), Capabilities.unpack(data[9:]))
Example #22
0
    def __init__(self, neighbor):
        self.neighbor = neighbor

        self.sent_open = None
        self.received_open = None

        self.holdtime = HoldTime(0)
        self.local_as = ASN(0)
        self.peer_as = ASN(0)
        self.families = []
        self.nexthop = []
        self.asn4 = False
        self.addpath = RequirePath()
        self.multisession = False
        self.msg_size = ExtendedMessage.INITIAL_SIZE
        self.operational = False
        self.refresh = REFRESH.ABSENT  # pylint: disable=E1101
        self.aigp = neighbor['capability']['aigp']
        self.mismatch = []
Example #23
0
def asn(tokeniser, value=None):
    value = tokeniser() if value is None else value
    try:
        if value.count('.'):
            high, low = value.split('.', 1)
            as_number = (int(high) << 16) + int(low)
        else:
            as_number = int(value)
        return ASN(as_number)
    except ValueError:
        raise ValueError('"%s" is an invalid ASN' % value)
Example #24
0
class Neighbor:
    description = 'a test neighbor'
    router_id = RouterID('127.0.0.1')
    local_address = IPv4('127.0.0.1')
    peer_address = IPv4('127.0.0.1')
    peer_as = ASN('65500')
    local_as = ASN('65500')
    hold_time = HoldTime(180)
    asn4 = False
    add_path = 0

    # capability
    route_refresh = False
    graceful_restart = False
    multisession = None
    add_path = None
    aigp = None

    @staticmethod
    def families():
        return known_families()
Example #25
0
    def __new_aspaths(cls, data, asn4, klass=None):
        as_set = []
        as_seq = []
        backup = data

        unpacker = {
            False: '!H',
            True: '!L',
        }
        size = {
            False: 2,
            True: 4,
        }
        as_choice = {
            ASPath.AS_SEQUENCE: as_seq,
            ASPath.AS_SET: as_set,
        }

        upr = unpacker[asn4]
        length = size[asn4]

        try:

            while data:
                stype = ord(data[0])
                slen = ord(data[1])

                if stype not in (ASPath.AS_SET, ASPath.AS_SEQUENCE):
                    raise Notify(3, 11, 'invalid AS Path type sent %d' % stype)

                end = 2 + (slen * length)
                sdata = data[2:end]
                data = data[end:]
                asns = as_choice[stype]

                for i in range(slen):
                    asn = unpack(upr, sdata[:length])[0]
                    asns.append(ASN(asn))
                    sdata = sdata[length:]

        except IndexError:
            raise Notify(3, 11,
                         'not enough data to decode AS_PATH or AS4_PATH')
        except error:  # struct
            raise Notify(3, 11,
                         'not enough data to decode AS_PATH or AS4_PATH')

        if klass:
            return klass(as_seq, as_set, backup)
        return cls(as_seq, as_set, backup)
Example #26
0
def asn(tokeniser, value=None):
    if value is None:
        if not tokeniser.tokens:
            raise ValueError('an asn is required')

    value = tokeniser()
    try:
        if value.count('.'):
            high, low = value.split('.', 1)
            as_number = (int(high) << 16) + int(low)
        else:
            as_number = int(value)
        return ASN(as_number)
    except ValueError:
        raise ValueError('"%s" is an invalid ASN' % value)
Example #27
0
    def _new_aspaths(cls, data, asn4, klass=None):
        backup = data

        unpacker = {
            False: '!H',
            True: '!L',
        }
        size = {
            False: 2,
            True: 4,
        }

        upr = unpacker[asn4]
        length = size[asn4]

        aspath = []

        try:
            while data:
                stype = data[0]
                slen = data[1]

                if stype not in cls._DISPATCH:
                    raise Notify(3, 11, 'invalid AS Path type sent %d' % stype)

                end = 2 + (slen * length)
                sdata = data[2:end]
                data = data[end:]
                # Eat the data and ignore it if the ASPath attribute is know known
                asns = cls._DISPATCH[stype]()

                for _ in range(slen):
                    asn = unpack(upr, sdata[:length])[0]
                    asns.append(ASN(asn))
                    sdata = sdata[length:]

                aspath.append(asns)

        except IndexError:
            raise Notify(3, 11, 'not enough data to decode AS_PATH or AS4_PATH')
        except error:  # struct
            raise Notify(3, 11, 'not enough data to decode AS_PATH or AS4_PATH')

        if klass:
            return klass(aspath, backup)
        return cls(aspath, backup)
Example #28
0
 def rate_limit(self, scope, name, command, tokens):
     # README: We are setting the ASN as zero as that what Juniper (and Arbor) did when we created a local flow route
     try:
         speed = int(tokens[0])
         if speed < 9600 and speed != 0:
             self.logger.configuration(
                 "rate-limiting flow under 9600 bytes per seconds may not work",
                 'warning')
         if speed > 1000000000000:
             speed = 1000000000000
             self.logger.configuration(
                 "rate-limiting changed for 1 000 000 000 000 bytes from %s"
                 % tokens[0], 'warning')
         scope[-1]['announce'][-1].attributes[
             Attribute.CODE.EXTENDED_COMMUNITY].add(
                 TrafficRate(ASN(0), speed))
         return True
     except ValueError:
         return self.error.set(self.syntax)
Example #29
0
def aggregator(tokeniser):
    value = tokeniser()
    if value != '(':
        tokeniser.rewind(value)
        return None

    try:
        as_number, address = tokeniser().split(':')
    except (ValueError, IndexError):
        raise ValueError('invalid aggregator')

    value = tokeniser()
    if value != ')':
        raise ValueError('invalid aggregator')

    local_as = ASN(as_number)
    local_address = RouterID(address)

    # XXX: This is buggy it can be an Aggregator4
    return Aggregator(local_as, local_address)
Example #30
0
 def unpack(data):
     asn, rate = unpack('!Hf', data[2:8])
     return TrafficRate(ASN(asn), rate, data[:8])