Esempio n. 1
0
File: vpn.py Progetto: pierky/exabgp
def ip_vpn(tokeniser, afi, safi):
    action = OUT.ANNOUNCE if tokeniser.announce else OUT.WITHDRAW
    ipmask = prefix(tokeniser)

    nlri = IPVPN(afi, safi, action)
    nlri.cidr = CIDR(ipmask.pack(), ipmask.mask)

    change = Change(nlri, Attributes())

    while True:
        command = tokeniser()

        if not command:
            break

        action = AnnounceVPN.action.get(command, '')

        if action == 'attribute-add':
            change.attributes.add(AnnounceVPN.known[command](tokeniser))
        elif action == 'nlri-set':
            change.nlri.assign(AnnounceVPN.assign[command],
                               AnnounceVPN.known[command](tokeniser))
        elif action == 'nexthop-and-attribute':
            nexthop, attribute = AnnounceVPN.known[command](tokeniser)
            change.nlri.nexthop = nexthop
            change.attributes.add(attribute)
        else:
            raise ValueError('unknown command "%s"' % command)

    if not AnnounceVPN.check(change, afi):
        raise ValueError(
            'invalid announcement (missing next-hop, label or rd ?)')

    return [change]
Esempio n. 2
0
def ip_vpn(tokeniser, afi, safi):
    ipmask = prefix(tokeniser)

    nlri = IPVPN(afi, safi, OUT.ANNOUNCE)
    nlri.cidr = CIDR(ipmask.pack(), ipmask.mask)

    change = Change(nlri, Attributes())

    while True:
        command = tokeniser()

        if not command:
            break

        action = ParseVPN.action.get(command, '')

        if action == 'attribute-add':
            change.attributes.add(ParseVPN.known[command](tokeniser))
        elif action == 'nlri-set':
            change.nlri.assign(ParseVPN.assign[command],
                               ParseVPN.known[command](tokeniser))
        elif action == 'nexthop-and-attribute':
            nexthop, attribute = ParseVPN.known[command](tokeniser)
            change.nlri.nexthop = nexthop
            change.attributes.add(attribute)
        else:
            raise ValueError('route: unknown command "%s"' % command)

    return [change]
Esempio n. 3
0
def ip_multicast(tokeniser, afi, safi):
    action = OUT.ANNOUNCE if tokeniser.announce else OUT.WITHDRAW
    ipmask = prefix(tokeniser)

    nlri = INET(afi, safi, action)
    nlri.cidr = CIDR(ipmask.pack(), ipmask.mask)

    change = Change(nlri, Attributes())

    while True:
        command = tokeniser()

        if not command:
            break

        action = AnnounceIP.action.get(command, '')

        if action == 'attribute-add':
            change.attributes.add(AnnounceIP.known[command](tokeniser))
        elif action == 'nlri-set':
            change.nlri.assign(AnnounceIP.assign[command],
                               AnnounceIP.known[command](tokeniser))
        elif action == 'nexthop-and-attribute':
            nexthop, attribute = AnnounceIP.known[command](tokeniser)
            change.nlri.nexthop = nexthop
            change.attributes.add(attribute)
        else:
            raise ValueError('unknown command "%s"' % command)

    return [change]
Esempio n. 4
0
    def unpack_nlri(cls, afi, safi, bgp, action, addpath):
        nlri = cls(afi, safi, action)

        if addpath:
            nlri.path_info = PathInfo(bgp[:4])
            bgp = bgp[4:]

        mask = bgp[0]
        bgp = bgp[1:]

        _, rd_size = Family.size.get((afi, safi), (0, 0))
        rd_mask = rd_size * 8

        if safi.has_label():
            labels = []
            while mask - rd_mask >= 24:
                label = int(unpack('!L', bytes([0]) + bgp[:3])[0])
                bgp = bgp[3:]
                mask -= 24  # 3 bytes
                # The last 4 bits are the bottom of Stack
                # The last bit is set for the last label
                labels.append(label >> 4)
                # This is a route withdrawal
                if label == 0x800000 and action == IN.WITHDRAWN:
                    break
                # This is a next-hop
                if label == 0x000000:
                    break
                if label & 1:
                    break
            nlri.labels = Labels(labels)

        if rd_size:
            mask -= rd_mask  # the route distinguisher
            rd = bgp[:rd_size]
            bgp = bgp[rd_size:]
            nlri.rd = RouteDistinguisher(rd)

        if mask < 0:
            raise Notify(3, 10, 'invalid length in NLRI prefix')

        if not bgp and mask:
            raise Notify(
                3, 10,
                'not enough data for the mask provided to decode the NLRI')

        size = CIDR.size(mask)

        if len(bgp) < size:
            raise Notify(
                3, 10,
                'could not decode route with family %s (AFI %d) %s (SAFI %d)' %
                (AFI(afi), int(afi), SAFI(safi), int(safi)))

        network, bgp = bgp[:size], bgp[size:]

        nlri.cidr = CIDR(network + bytes(IP.length(afi) - size), mask)

        return nlri, bgp
Esempio n. 5
0
 def new(cls, afi, safi, packed, mask, labels, rd, nexthop, action):
     instance = cls(afi, safi, OUT.ANNOUNCE)
     instance.cidr = CIDR(packed, mask)
     instance.labels = labels
     instance.rd = rd
     instance.nexthop = NextHop(IP.ntop(nexthop), nexthop)
     instance.action = action
     return instance
Esempio n. 6
0
	def new (cls, afi, safi, packed, mask, labels, rd, nexthop=None, action=OUT.UNSET):
		instance = cls(afi,safi,action)
		instance.cidr = CIDR(packed, mask)
		instance.labels = labels
		instance.rd = rd
		instance.nexthop = IP.create(nexthop) if nexthop else NoNextHop
		instance.action = action
		return instance
Esempio n. 7
0
File: inet.py Progetto: doddt/exabgp
    def unpack_nlri(cls, afi, safi, bgp, action, addpath):
        nlri = cls(afi, safi, action)

        if addpath:
            nlri.path_info = PathInfo(bgp[:4])
            bgp = bgp[4:]

        mask = ord(bgp[0])
        bgp = bgp[1:]

        if cls.has_label():
            labels = []
            while bgp and mask >= 8:
                label = int(unpack('!L', chr(0) + bgp[:3])[0])
                bgp = bgp[3:]
                mask -= 24  # 3 bytes
                # The last 4 bits are the bottom of Stack
                # The last bit is set for the last label
                labels.append(label >> 4)
                # This is a route withdrawal
                if label == 0x800000 and action == IN.WITHDRAWN:
                    break
                # This is a next-hop
                if label == 0x000000:
                    break
                if label & 1:
                    break
            nlri.labels = Labels(labels)

        if cls.has_rd():
            mask -= 8 * 8  # the 8 bytes of the route distinguisher
            rd = bgp[:8]
            bgp = bgp[8:]
            nlri.rd = RouteDistinguisher(rd)

        if mask < 0:
            raise Notify(3, 10, 'invalid length in NLRI prefix')

        if not bgp and mask:
            raise Notify(
                3, 10,
                'not enough data for the mask provided to decode the NLRI')

        size = CIDR.size(mask)

        if len(bgp) < size:
            raise Notify(
                3, 10, 'could not decode route with AFI %d sand SAFI %d' %
                (afi, safi))

        network, bgp = bgp[:size], bgp[size:]
        padding = '\0' * (IP.length(afi) - size)

        nlri.cidr = CIDR(network + padding, mask)

        return nlri, bgp
Esempio n. 8
0
    def split(last):
        if Attribute.CODE.INTERNAL_SPLIT not in last.attributes:
            yield last
            return

        # ignore if the request is for an aggregate, or the same size
        mask = last.nlri.cidr.mask
        cut = last.attributes[Attribute.CODE.INTERNAL_SPLIT]
        if mask >= cut:
            yield last
            return

        # calculate the number of IP in the /<size> of the new route
        increment = pow(2, last.nlri.afi.mask() - cut)
        # how many new routes are we going to create from the initial one
        number = pow(2, cut - last.nlri.cidr.mask)

        # convert the IP into a integer/long
        ip = 0
        for c in last.nlri.cidr.ton():
            ip <<= 8
            ip += c

        afi = last.nlri.afi
        safi = last.nlri.safi

        # Really ugly
        klass = last.nlri.__class__
        nexthop = last.nlri.nexthop
        if safi.has_path():
            path_info = last.nlri.path_info
        if safi.has_label():
            labels = last.nlri.labels
        if safi.has_rd():
            rd = last.nlri.rd

        # XXX: Looks weird to set and then set to None, check
        last.nlri.cidr.mask = cut
        last.nlri = None

        # generate the new routes
        for _ in range(number):
            # update ip to the next route, this recalculate the "ip" field of the Inet class
            nlri = klass(afi, safi, OUT.ANNOUNCE)
            nlri.cidr = CIDR(pack_int(afi, ip), cut)
            nlri.nexthop = nexthop  # nexthop can be NextHopSelf
            if safi.has_path():
                nlri.path_info = path_info
            if safi.has_label():
                nlri.labels = labels
            if safi.has_rd():
                nlri.rd = rd
            # next ip
            ip += increment
            yield Change(nlri, last.attributes)
Esempio n. 9
0
 def __init__(self, raw, netmask, offset):
     self.cidr = CIDR(raw, netmask)
     self.offset = offset
Esempio n. 10
0
 def __init__(self, raw, netmask):
     self.cidr = CIDR(raw, netmask)
Esempio n. 11
0
 def __init__(self, raw, netmask):
     self.nlri = CIDR(raw, netmask)