Exemple #1
0
	def __init__ (self,what,afi,safi,data=''):
		self.afi = AFI(afi)
		self.safi = SAFI(afi)
		Operational.__init__(
			self,what,
			'%s%s%s' % (self.afi.pack(),self.safi.pack(),data)
		)
Exemple #2
0
	def unpack_nlri (cls, afi, safi, data, action, addpath):
		if not cls.logger:
			cls.logger = Logger()
		cls.logger.parser(LazyNLRI(afi,safi,data))

		key = '%s/%s' % (AFI(afi),SAFI(safi))
		if key in cls.registered_nlri:
			return cls.registered_nlri[key].unpack_nlri(afi,safi,data,action,addpath)
		raise Notify(3,0,'trying to decode unknown family %s/%s' % (AFI(afi),SAFI(safi)))
Exemple #3
0
 def unpack_capability(instance, data, capability=None):  # pylint: disable=W0613
     # XXX: FIXME: we should complain if we have twice the same AFI/SAFI
     # XXX: FIXME: should check that we have not yet seen the capability
     while data:
         afi = AFI.unpack(data[:2])
         safi = SAFI.unpack(data[3])
         nexthop = AFI.unpack(data[4:6])
         instance.add_nexthop(afi, safi, nexthop)
         data = data[6:]
     return instance
Exemple #4
0
	def unpack_capability (instance, data, capability=None):  # pylint: disable=W0613
		# XXX: FIXME: we should complain if we have twice the same AFI/SAFI
		# XXX: FIXME: should check that we have not yet seen the capability
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[3])
			nexthop = AFI.unpack(data[4:6])
			instance.add_nexthop(afi, safi, nexthop)
			data = data[6:]
		return instance
Exemple #5
0
	def _add (self, tokeniser, afi_name, safi_names):
		self._check_duplicate(tokeniser,RaisedFamily)
		known = self.content.setdefault(AFI(AFI.value(afi_name)),[])

		for (idx_line,idx_column,line,safi_name) in safi_names:
			if safi_name not in AFI.implemented_safi(afi_name):
				raise RaisedFamily(Location(idx_line,idx_column,line),'the family pair afi/safi %s/%s is unimplemented' % (afi_name,safi_name))

			safi = SAFI(SAFI.value(safi_name))
			if safi in known:
				raise RaisedFamily(Location(idx_line,idx_column,line),'afi/safi pair already defined in this family')
			known.append(safi)
Exemple #6
0
    def _family(self, tokeniser, afi, safis, nhafis):
        safi = tokeniser().lower()
        if safi not in safis:
            raise ValueError('invalid afi/safi pair %s/%s' % (afi, safi))

        nhafi = tokeniser().lower()
        if nhafi not in nhafis:
            raise ValueError('invalid nexthop afi %s' % nhafi)

        seen = (AFI.fromString(afi), SAFI.fromString(safi), AFI.fromString(nhafi))
        self._seen.append(seen)
        return seen
Exemple #7
0
	def _add (self,tokeniser,afi_name,safi_names):
		self._check_duplicate(tokeniser,RaisedFamily)
		known = self.content.setdefault(AFI(AFI.value(afi_name)),[])

		for (idx_line,idx_column,line,safi_name) in safi_names:
			if safi_name not in AFI.implemented_safi(afi_name):
				raise RaisedFamily(Location(idx_line,idx_column,line),'the family pair afi/safi %s/%s is unimplemented' % (afi_name,safi_name))

			safi = SAFI(SAFI.value(safi_name))
			if safi in known:
				raise RaisedFamily(Location(idx_line,idx_column,line),'afi/safi pair already defined in this family')
			known.append(safi)
Exemple #8
0
	def _family (self, tokeniser, afi, safis, nhafis):
		safi = tokeniser().lower()
		if safi not in safis:
			raise ValueError('invalid afi/safi pair %s/%s' % (afi, safi))

		nhafi = tokeniser().lower()
		if nhafi not in nhafis:
			raise ValueError('invalid nexthop afi %s' % nhafi)

		seen = (AFI.fromString(afi), SAFI.fromString(safi), AFI.fromString(nhafi))
		self._seen.append(seen)
		return seen
Exemple #9
0
class RouteRefresh(Message):
    TYPE = chr(Message.Type.ROUTE_REFRESH)

    request = 0
    start = 1
    end = 2

    def __init__(self, afi, safi, reserved=0):
        self.afi = AFI(afi)
        self.safi = SAFI(safi)
        self.reserved = Reserved(reserved)

    def messages(self, negotitated):
        return [
            self._message(
                '%s%s%s' %
                (self.afi.pack(), chr(self.reserved), self.safi.pack())),
        ]

    def __str__(self):
        return "REFRESH"

    def extensive(self):
        return 'route refresh %s/%d/%s' % (self.afi, self.reserved, self.safi)

    def families(self):
        return self._families[:]
Exemple #10
0
    def ipv6(self, tokeniser):
        self._check_conflict()
        safi = tokeniser()

        if safi == 'unicast':
            self.content.append((AFI(AFI.ipv6), SAFI(SAFI.unicast)))
        elif safi == 'mpls-vpn':
            self.content.append((AFI(AFI.ipv6), SAFI(SAFI.mpls_vpn)))
        elif safi in ('flow'):
            self.content.append((AFI(AFI.ipv6), SAFI(SAFI.flow_ip)))
        elif safi == 'flow-vpn':
            self.content.append((AFI(AFI.ipv6), SAFI(SAFI.flow_vpn)))
        else:
            raise Raised('unknow family safi %s' % safi)

        self._drop_colon(tokeniser)
Exemple #11
0
class EVPN(object):
    registered_evpn = dict()
    # CODE : NEED to be defined in the subclasses
    NAME = 'unknown'
    SHORT_NAME = 'unknown'

    # lower case to match the class Address API
    afi = AFI(AFI.l2vpn)
    safi = SAFI(SAFI.evpn)

    def __init__(self, packed):
        self.packed = packed

    def _prefix(self):
        return "evpn:%s:" % (self._name.get(self.CODE, 'unknown').lower())

    def __str__(self):
        return "evpn:%s:%s" % (self._name.get(self.CODE, 'unknown').lower(),
                               '0x' + ''.join('%02x' % ord(_)
                                              for _ in self.packed))

    def __repr__(self):
        return str(self)

    def pack(self):
        return pack('!BB', self.CODE, len(self.packed)) + self.packed

    def __len__(self):
        return len(self.packed) + 2

    # For subtype 2 (MAC/IP advertisement route),
    # we will have to ignore a part of the route, so this method will be overridden

    def __cmp__(self, other):
        if not isinstance(other, EVPN):
            return -1
        if self.CODE != other.CODE:
            return -1
        if self.packed != other.packed:
            return -1
        return 0

    def __hash__(self):
        return hash("%s:%s:%s:%s" %
                    (self.afi, self.safi, self.CODE, self.packed))

    @classmethod
    def register_evpn(cls):
        cls.registered_evpn[cls.CODE] = cls

    @classmethod
    def unpack(cls, data):
        code = ord(data[0])
        length = ord(data[1])

        if code in cls.registered_evpn:
            return cls.registered_evpn[code].unpack(data[length + 1:])
        klass = cls(data[length + 1:])
        klass.CODE = code
        return klass
Exemple #12
0
class RouteRefresh (Message):
	ID = Message.ID.ROUTE_REFRESH
	TYPE = chr(Message.ID.ROUTE_REFRESH)

	request = 0
	start = 1
	end = 2

	def __init__ (self,afi,safi,reserved=0):
		self.afi = AFI(afi)
		self.safi = SAFI(safi)
		self.reserved = Reserved(reserved)

	def messages (self,negotitated):
		return [self._message('%s%s%s' % (self.afi.pack(),chr(self.reserved),self.safi.pack())),]

	def __str__ (self):
		return "REFRESH"

	def extensive (self):
		return 'route refresh %s/%d/%s' % (self.afi,self.reserved,self.safi)

	def families (self):
		return self._families[:]

	@classmethod
	def unpack_message (cls,data,negotitated):
		try:
			afi,reserved,safi = unpack('!HBB',data)
		except error:
			raise Notify(7,1,'invalid route-refresh message')
		if reserved not in (0,1,2):
			raise Notify(7,2,'invalid route-refresh message subtype')
		return RouteRefresh(afi,safi,reserved)
Exemple #13
0
    def unpack(cls, data, direction, negotiated):
        nlris = []

        # -- Reading AFI/SAFI
        afi, safi = unpack('!HB', data[:3])
        offset = 3
        data = data[offset:]

        if negotiated and (afi, safi) not in negotiated.families:
            raise Notify(
                3, 0, 'presented a non-negotiated family %s %s' %
                (AFI.create(afi), SAFI.create(safi)))

        # Do we need to handle Path Information with the route (AddPath)
        if direction == Direction.IN:
            addpath = negotiated.addpath.receive(afi, safi)
        else:
            addpath = negotiated.addpath.send(afi, safi)

        while data:
            nlri, data = NLRI.unpack_nlri(afi, safi, data, IN.WITHDRAWN,
                                          addpath)
            # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri
            if nlri:
                nlris.append(nlri)

        return cls(afi, safi, nlris)
Exemple #14
0
 def register_nlri(klass):
     cls.registered_nlri['%d/%d' % (afi, safi)] = klass
     new = (AFI(afi), SAFI(safi))
     if new in cls.registered_nlri:
         raise RuntimeError('Tried to register %s/%s twice' % new)
     cls.registered_families.append(new)
     return klass
Exemple #15
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
Exemple #16
0
    def unpack_nlri(cls, afi, safi, data, action, addpath):
        a, s = AFI.create(afi), SAFI.create(safi)
        log.debug(LazyNLRI(a, s, addpath, data), 'parser')

        key = '%s/%s' % (a, s)
        if key in cls.registered_nlri:
            return cls.registered_nlri[key].unpack_nlri(a, s, data, action, addpath)
        raise Notify(3, 0, 'trying to decode unknown family %s/%s' % (a, s))
Exemple #17
0
	def unpack (cls,afi,safi,data,addpath,nexthop,action):
		if not cls.logger:
			cls.logger = Logger()
		cls.logger.parser(LazyFormat("parsing %s/%s nlri payload " % (afi,safi),data))

		key = '%d/%d' % (afi,safi)
		if key in cls.registered_nlri:
			return cls.registered_nlri[key].unpack(afi,safi,data,addpath,nexthop,action)
		raise Notify(3,0,'trying to decode unknown family %s/%s' % (AFI(afi),SAFI(safi)))
Exemple #18
0
	def unpack_capability (instance, data, capability=None):  # pylint: disable=W0613
		# XXX: FIXME: should check that we have not yet seen the capability
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[2])
			sr = ord(data[3])
			instance.add_path(afi,safi,sr)
			data = data[4:]
		return instance
Exemple #19
0
 def api_refresh(self, command):
     tokens = formated(command).split(' ')[2:]
     if len(tokens) != 2:
         return False
     afi = AFI.value(tokens.pop(0))
     safi = SAFI.value(tokens.pop(0))
     if afi is None or safi is None:
         return False
     return RouteRefresh(afi, safi)
Exemple #20
0
	def parse_api_refresh (self,command):
		tokens = formated(command).split(' ')[2:]
		if len(tokens) != 2:
			return False
		afi = AFI.value(tokens.pop(0))
		safi = SAFI.value(tokens.pop(0))
		if afi is None or safi is None:
			return False
		return RouteRefresh(afi,safi)
Exemple #21
0
 def unpack(capability, instance, data):
     # XXX: FIXME: should check that we have not yet seen the capability
     while data:
         afi = AFI.unpack(data[:2])
         safi = SAFI.unpack(data[2])
         sr = ord(data[3])
         instance.add_path(afi, safi, sr)
         data = data[4:]
     return instance
Exemple #22
0
	def unpack_capability (instance, data, capability=None):  # pylint: disable=W0613
		# XXX: FIXME: should check that we have not yet seen the capability
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[2])
			sr = ord_(data[3])
			instance.add_path(afi,safi,sr)
			data = data[4:]
		return instance
Exemple #23
0
	def unpack (capability,instance,data):
		# XXX: FIXME: should check that we have not yet seen the capability
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[2])
			sr = ord(data[3])
			instance.add_path(afi,safi,sr)
			data = data[4:]
		return instance
Exemple #24
0
    def new(self, neighbor, restarted):
        graceful = neighbor.graceful_restart
        families = neighbor.families()

        mp = MultiProtocol()
        mp.extend(families)
        self[Capability.ID.MULTIPROTOCOL_EXTENSIONS] = mp

        if neighbor.asn4:
            self[Capability.ID.FOUR_BYTES_ASN] = ASN4(neighbor.local_as)

        if neighbor.add_path:
            ap_families = []
            if (AFI(AFI.ipv4), SAFI(SAFI.unicast)) in families:
                ap_families.append((AFI(AFI.ipv4), SAFI(SAFI.unicast)))
            if (AFI(AFI.ipv6), SAFI(SAFI.unicast)) in families:
                ap_families.append((AFI(AFI.ipv6), SAFI(SAFI.unicast)))
            # if (AFI(AFI.ipv4),SAFI(SAFI.nlri_mpls)) in families:
            # 	ap_families.append((AFI(AFI.ipv4),SAFI(SAFI.nlri_mpls)))
            #if (AFI(AFI.ipv6),SAFI(SAFI.unicast)) in families:
            #	ap_families.append((AFI(AFI.ipv6),SAFI(SAFI.unicast)))
            self[Capability.ID.ADD_PATH] = AddPath(ap_families,
                                                   neighbor.add_path)

        if graceful:
            if restarted:
                self[Capability.ID.GRACEFUL_RESTART] = Graceful().set(
                    Graceful.RESTART_STATE, graceful,
                    [(afi, safi, Graceful.FORWARDING_STATE)
                     for (afi, safi) in families])
            else:
                self[Capability.ID.GRACEFUL_RESTART] = Graceful().set(
                    0x0, graceful, [(afi, safi, Graceful.FORWARDING_STATE)
                                    for (afi, safi) in families])

        if neighbor.route_refresh:
            self[Capability.ID.ROUTE_REFRESH] = RouteRefresh()
            self[Capability.ID.ENHANCED_ROUTE_REFRESH] = EnhancedRouteRefresh()

        # MUST be the last key added
        if neighbor.multisession:
            self[Capability.ID.MULTISESSION_BGP] = MultiSession().set(
                [Capability.ID.MULTIPROTOCOL_EXTENSIONS])
        return self
Exemple #25
0
    def l2vpn(self, tokeniser):
        self._check_conflict()
        safi = tokeniser()

        if safi == 'vpls':
            self.content.append((AFI(AFI.l2vpn), SAFI(SAFI.vpls)))
        else:
            raise Raised('unknow family safi %s' % safi)

        self._drop_colon(tokeniser)
Exemple #26
0
	def unpack_nlri (cls, afi, safi, data, action, addpath):
		if not cls.logger:
			cls.logger = Logger()

		a,s = AFI.create(afi),SAFI.create(safi)
		cls.logger.debug(LazyNLRI(a,s,addpath,data),'parser')

		key = '%s/%s' % (a, s)
		if key in cls.registered_nlri:
			return cls.registered_nlri[key].unpack_nlri(a,s,data,action,addpath)
		raise Notify(3,0,'trying to decode unknown family %s/%s' % (a,s))
Exemple #27
0
class OperationalFamily (Operational):
	def __init__ (self,what,afi,safi,data=''):
		self.afi = AFI(afi)
		self.safi = SAFI(afi)
		Operational.__init__(
			self,what,
			'%s%s%s' % (self.afi.pack(),self.safi.pack(),data)
		)

	def family (self):
		return (self.afi,self.safi)
Exemple #28
0
 def register_nlri(klass):
     new = (AFI(afi), SAFI(safi))
     if new in cls.registered_nlri:
         if force:
             cls.registered_nlri['%d/%d' % new] = klass
         else:
             raise RuntimeError('Tried to register %s/%s twice' % new)
     else:
         cls.registered_nlri['%d/%d' % new] = klass
         cls.registered_families.append(new)
     return klass
Exemple #29
0
		def register_nlri (klass):
			new = (AFI(afi),SAFI(safi))
			if new in cls.registered_nlri:
				if force:
					# python has a bug and does not allow %ld/%ld (pypy does)
					cls.registered_nlri['%s/%s' % new] = klass
				else:
					raise RuntimeError('Tried to register %s/%s twice' % new)
			else:
				# python has a bug and does not allow %ld/%ld (pypy does)
				cls.registered_nlri['%s/%s' % new] = klass
				cls.registered_families.append(new)
			return klass
Exemple #30
0
		def register_nlri (klass):
			new = (AFI.create(afi),SAFI.create(safi))
			if new in cls.registered_nlri:
				if force:
					# python has a bug and does not allow %ld/%ld (pypy does)
					cls.registered_nlri['%s/%s' % new] = klass
				else:
					raise RuntimeError('Tried to register %s/%s twice' % new)
			else:
				# python has a bug and does not allow %ld/%ld (pypy does)
				cls.registered_nlri['%s/%s' % new] = klass
				cls.registered_families.append(new)
			return klass
Exemple #31
0
class RouteRefresh(Message):
    ID = Message.CODE.ROUTE_REFRESH
    TYPE = character(Message.CODE.ROUTE_REFRESH)

    request = 0
    start = 1
    end = 2

    def __init__(self, afi, safi, reserved=0):
        self.afi = AFI(afi)
        self.safi = SAFI(safi)
        self.reserved = Reserved(reserved)

    def message(self, negotiated=None):
        return self._message(
            concat_bytes(self.afi.pack(), character(self.reserved),
                         self.safi.pack()))

    def __str__(self):
        return "REFRESH"

    def extensive(self):
        return 'route refresh %s/%d/%s' % (self.afi, self.reserved, self.safi)

    # XXX: Check how we get this data into the RR
    def families(self):
        return self._families[:]

    @classmethod
    def unpack_message(cls, data, _):
        try:
            afi, reserved, safi = unpack('!HBB', data)
        except error:
            raise Notify(7, 1, 'invalid route-refresh message')
        if reserved not in (0, 1, 2):
            raise Notify(7, 2, 'invalid route-refresh message subtype')
        return RouteRefresh(afi, safi, reserved)

    def __eq__(self, other):
        if not isinstance(other, RouteRefresh):
            return False
        if self.afi != other.afi:
            return False
        if self.safi != other.safi:
            return False
        if self.reserved != other.reserved:
            return False
        return True

    def __ne__(self, other):
        return not self.__eq__(other)
Exemple #32
0
	def _addpath (self, neighbor):
		if not neighbor.add_path:
			return

		families = neighbor.families()
		ap_families = []
		if (AFI(AFI.ipv4),SAFI(SAFI.unicast)) in families:
			ap_families.append((AFI(AFI.ipv4),SAFI(SAFI.unicast)))
		if (AFI(AFI.ipv6),SAFI(SAFI.unicast)) in families:
			ap_families.append((AFI(AFI.ipv6),SAFI(SAFI.unicast)))
		if (AFI(AFI.ipv4),SAFI(SAFI.nlri_mpls)) in families:
			ap_families.append((AFI(AFI.ipv4),SAFI(SAFI.nlri_mpls)))
		if (AFI(AFI.ipv6),SAFI(SAFI.unicast)) in families:
			ap_families.append((AFI(AFI.ipv6),SAFI(SAFI.unicast)))
		self[Capability.CODE.ADD_PATH] = AddPath(ap_families,neighbor.add_path)
Exemple #33
0
	def unpack (what,instance,data):
		# XXX: FIXME: should raise if instance was already setup
		restart = unpack('!H',data[:2])[0]
		restart_flag = restart >> 12
		restart_time = restart & Graceful.TIME_MASK
		data = data[2:]
		families = []
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[2])
			flag_family = ord(data[0])
			families.append((afi,safi,flag_family))
			data = data[4:]
		return instance.set(restart_flag,restart_time,families)
Exemple #34
0
	def unpack_capability (instance, data, capability=None):  # pylint: disable=W0613
		# XXX: FIXME: should raise if instance was already setup
		restart = unpack('!H',data[:2])[0]
		restart_flag = restart >> 12
		restart_time = restart & Graceful.TIME_MASK
		data = data[2:]
		families = []
		while data:
			afi = AFI.unpack(data[:2])
			safi = SAFI.unpack(data[2])
			flag_family = ord(data[3])
			families.append((afi,safi,flag_family))
			data = data[4:]
		return instance.set(restart_flag,restart_time,families)
Exemple #35
0
 def unpack_capability(instance, data, _=None):
     # XXX: FIXME: should raise if instance was already setup
     restart = unpack('!H', data[:2])[0]
     restart_flag = restart >> 12
     restart_time = restart & Graceful.TIME_MASK
     data = data[2:]
     families = []
     while data:
         afi = AFI.unpack(data[:2])
         safi = SAFI.unpack(data[2])
         flag_family = ord(data[0])
         families.append((afi, safi, flag_family))
         data = data[4:]
     return instance.set(restart_flag, restart_time, families)
Exemple #36
0
class RouteRefresh(Message):
    ID = Message.CODE.ROUTE_REFRESH
    TYPE = chr(Message.CODE.ROUTE_REFRESH)

    request = 0
    start = 1
    end = 2

    def __init__(self, afi, safi, reserved=0):
        self.afi = AFI(afi)
        self.safi = SAFI(safi)
        self.reserved = Reserved(reserved)

    def messages(self, negotitated):  # pylint: disable=W0613
        return [
            self._message(
                '%s%s%s' %
                (self.afi.pack(), chr(self.reserved), self.safi.pack())),
        ]

    def __str__(self):
        return "REFRESH"

    def extensive(self):
        return 'route refresh %s/%d/%s' % (self.afi, self.reserved, self.safi)

    def families(self):
        return self._families[:]

    @classmethod
    def unpack_message(cls, data, _):
        try:
            afi, reserved, safi = unpack('!HBB', data)
        except error:
            raise Notify(7, 1, 'invalid route-refresh message')
        if reserved not in (0, 1, 2):
            raise Notify(7, 2, 'invalid route-refresh message subtype')
        return RouteRefresh(afi, safi, reserved)

    def __eq__(self, other):
        if not isinstance(other, RouteRefresh):
            return False
        if self.afi != other.afi:
            return False
        if self.safi != other.safi:
            return False
        if self.reserved != other.reserved:
            return False
        return True
Exemple #37
0
class RouteRefresh (Message):
	ID = Message.CODE.ROUTE_REFRESH
	TYPE = chr(Message.CODE.ROUTE_REFRESH)

	request = 0
	start = 1
	end = 2

	def __init__ (self, afi, safi, reserved=0):
		self.afi = AFI(afi)
		self.safi = SAFI(safi)
		self.reserved = Reserved(reserved)

	def message (self,negotiated=None):
		return self._message('%s%s%s' % (self.afi.pack(),chr(self.reserved),self.safi.pack()))

	def __str__ (self):
		return "REFRESH"

	def extensive (self):
		return 'route refresh %s/%d/%s' % (self.afi,self.reserved,self.safi)

	def families (self):
		return self._families[:]

	@classmethod
	def unpack_message (cls, data, _):
		try:
			afi,reserved,safi = unpack('!HBB',data)
		except error:
			raise Notify(7,1,'invalid route-refresh message')
		if reserved not in (0,1,2):
			raise Notify(7,2,'invalid route-refresh message subtype')
		return RouteRefresh(afi,safi,reserved)

	def __eq__ (self, other):
		if not isinstance(other, RouteRefresh):
			return False
		if self.afi != other.afi:
			return False
		if self.safi != other.safi:
			return False
		if self.reserved != other.reserved:
			return False
		return True

	def __ne__ (self, other):
		return not self.__eq__(other)
Exemple #38
0
 def add(self, rule):
     ID = rule.ID
     if ID in (FlowDestination.ID, FlowSource.ID):
         if ID in self.rules:
             return False
         if ID == FlowDestination.ID:
             pair = self.rules.get(FlowSource.ID, [])
         else:
             pair = self.rules.get(FlowDestination.ID, [])
         if pair:
             if rule.afi != pair[0].afi:
                 return False
         if rule.NAME.endswith('ipv6'):  # better way to check this ?
             self.afi = AFI(AFI.ipv6)
     self.rules.setdefault(ID, []).append(rule)
     return True
Exemple #39
0
class OperationalFamily(Operational):
    has_family = True

    def __init__(self, what, afi, safi, data=b''):
        Operational.__init__(self, what)
        self.afi = AFI(afi)
        self.safi = SAFI(safi)
        self.data = data

    def family(self):
        return (self.afi, self.safi)

    def _message(self, data):
        return Operational._message(
            self, concat_bytes(self.afi.pack(), self.safi.pack(), data))

    def message(self, negotiated):
        return self._message(self.data)
Exemple #40
0
	def unpack (cls, data, negotiated):
		nlris = []

		# -- Reading AFI/SAFI
		afi,safi = unpack('!HB',data[:3])
		offset = 3
		data = data[offset:]

		if negotiated and (afi,safi) not in negotiated.families:
			raise Notify(3,0,'presented a non-negotiated family %s %s' % (AFI.create(afi),SAFI.create(safi)))

		# Is the peer going to send us some Path Information with the route (AddPath)
		addpath = negotiated.addpath.receive(afi,safi)

		while data:
			nlri,data = NLRI.unpack_nlri(afi,safi,data,IN.WITHDRAWN,addpath)
			nlris.append(nlri)

		return cls(afi,safi,nlris)
Exemple #41
0
	def api_eor (self, command):
		tokens = formated(command).split(' ')[2:]
		number = len(tokens)

		if not number:
			return Family(1,1)

		if number != 2:
			return False

		afi = AFI.fromString(tokens[0])
		if afi == AFI.undefined:
			return False

		safi = SAFI.fromString(tokens[1])
		if safi == SAFI.undefined:
			return False

		return Family(afi,safi)
Exemple #42
0
    def api_eor(self, command):
        tokens = formated(command).split(' ')[2:]
        number = len(tokens)

        if not number:
            return Family(1, 1)

        if number != 2:
            return False

        afi = AFI.fromString(tokens[0])
        if afi == AFI.undefined:
            return False

        safi = SAFI.fromString(tokens[1])
        if safi == SAFI.undefined:
            return False

        return Family(afi, safi)
Exemple #43
0
	def parse_api_eor (self,command):
		tokens = formated(command).split(' ')[2:]
		lt = len(tokens)

		if not lt:
			return Family(1,1)

		if lt !=2:
			return False

		afi = AFI.fromString(tokens[0])
		if afi == AFI.undefined:
			return False

		safi = SAFI.fromString(tokens[1])
		if safi == SAFI.undefined:
			return False

		return Family(afi,safi)
Exemple #44
0
	def parse_api_eor (self,command):
		tokens = formated(command).split(' ')[2:]
		lt = len(tokens)

		if not lt:
			return Family(1,1)

		if lt !=2:
			return False

		afi = AFI.fromString(tokens[0])
		if afi == AFI.undefined:
			return False

		safi = SAFI.fromString(tokens[1])
		if safi == SAFI.undefined:
			return False

		return Family(afi,safi)
Exemple #45
0
	def unpack (cls, data, negotiated):
		nlris = []

		# -- Reading AFI/SAFI
		afi,safi = unpack('!HB',data[:3])
		offset = 3
		data = data[offset:]

		if negotiated and (afi,safi) not in negotiated.families:
			raise Notify(3,0,'presented a non-negotiated family %s %s' % (AFI.create(afi),SAFI.create(safi)))

		# Is the peer going to send us some Path Information with the route (AddPath)
		addpath = negotiated.addpath.receive(afi,safi)

		while data:
			nlri,data = NLRI.unpack_nlri(afi,safi,data,IN.WITHDRAWN,addpath)
			nlris.append(nlri)

		return cls(afi,safi,nlris)
Exemple #46
0
class OperationalFamily (Operational):
	has_family = True

	def __init__ (self,what,afi,safi,data=''):
		Operational.__init__(self,what)
		self.afi = AFI(afi)
		self.safi = SAFI(afi)
		self.data = data

	def family (self):
		return (self.afi,self.safi)

	def _message (self,data):
		return Operational._message(self,"%s%s%s" % (
			self.afi.pack(),
			self.safi.pack(),
			data
		))

	def message (self,negotiated):
		return self._message(self.data)
Exemple #47
0
class RouteRefresh (Message):
	TYPE = chr(Message.Type.ROUTE_REFRESH)

	request = 0
	start = 1
	end = 2

	def __init__ (self,afi,safi,reserved=0):
		self.afi = AFI(afi)
		self.safi = SAFI(safi)
		self.reserved = Reserved(reserved)

	def messages (self,negotitated):
		return [self._message('%s%s%s' % (self.afi.pack(),chr(self.reserved),self.safi.pack())),]

	def __str__ (self):
		return "REFRESH"

	def extensive (self):
		return 'route refresh %s/%d/%s' % (self.afi,self.reserved,self.safi)

	def families (self):
		return self._families[:]
Exemple #48
0
	def __init__ (self, what, afi, safi, data=b''):
		Operational.__init__(self,what)
		self.afi = AFI.create(afi)
		self.safi = SAFI.create(safi)
		self.data = data
Exemple #49
0
	def unpack_message (cls, data, negotiated):
		header_length = len(EOR.NLRI.PREFIX)
		return cls(AFI.unpack(data[header_length:header_length+2]),SAFI.unpack(data[header_length+2]))
Exemple #50
0
	def unpack_capability (instance, data, capability=None):  # pylint: disable=W0613
		# XXX: FIXME: we should raise if we have twice the same AFI/SAFI
		afi = AFI.unpack(data[:2])
		safi = SAFI.unpack(data[3])
		instance.append((afi,safi))
		return instance
Exemple #51
0
	def all (self,tokeniser):
		for afi_name in ('ipv4','ipv6','l2vpn'):
			for safi_name in AFI.implemented_safi(afi_name):
				self._add(tokeniser,afi_name,safi_name)
Exemple #52
0
	def unpack (cls, data, negotiated):
		nlris = []

		# -- Reading AFI/SAFI
		_afi,_safi = unpack('!HB',data[:3])
		afi,safi = AFI.create(_afi),SAFI.create(_safi)
		offset = 3

		# we do not want to accept unknown families
		if negotiated and (afi,safi) not in negotiated.families:
			raise Notify(3,0,'presented a non-negotiated family %s/%s' % (afi,safi))

		# -- Reading length of next-hop
		len_nh = ordinal(data[offset])
		offset += 1

		if (afi,safi) not in Family.size:
			raise Notify(3,0,'unsupported %s %s' % (afi,safi))

		length,rd = Family.size[(afi,safi)]

		if len_nh not in length:
			raise Notify(3,0,'invalid %s %s next-hop length %d expected %s' % (afi,safi,len_nh,' or '.join(str(_) for _ in length)))

		size = len_nh - rd

		# XXX: FIXME: GET IT FROM CACHE HERE ?
		nhs = data[offset+rd:offset+rd+size]
		nexthops = [nhs[pos:pos+16] for pos in range(0,len(nhs),16)]

		# chech the RD is well zero
		if rd and sum([int(ordinal(_)) for _ in data[offset:8]]) != 0:
			raise Notify(3,0,"MP_REACH_NLRI next-hop's route-distinguisher must be zero")

		offset += len_nh

		# Skip a reserved bit as somone had to bug us !
		reserved = ordinal(data[offset])
		offset += 1

		if reserved != 0:
			raise Notify(3,0,'the reserved bit of MP_REACH_NLRI is not zero')

		# Is the peer going to send us some Path Information with the route (AddPath)
		addpath = negotiated.addpath.receive(afi,safi)

		# Reading the NLRIs
		data = data[offset:]

		if not data:
			raise Notify(3,0,'No data to decode in an MPREACHNLRI but it is not an EOR %d/%d' % (afi,safi))

		while data:
			if nexthops:
				for nexthop in nexthops:
					nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath)
					nlri.nexthop = NextHop.unpack(nexthop)
					nlris.append(nlri)
			else:
				nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath)
				nlris.append(nlri)

			if left == data:
				raise RuntimeError("sub-calls should consume data")

			data = left
		return cls(afi,safi,nlris)
Exemple #53
0
	def __init__ (self, afi, safi, reserved=0):
		self.afi = AFI(afi)
		self.safi = SAFI(safi)
		self.reserved = Reserved(reserved)
Exemple #54
0
	def unpack (what,instance,data):
		# XXX: FIXME: we should raise if we have twice the same AFI/SAFI
		afi = AFI.unpack(data[:2])
		safi = SAFI.unpack(data[3])
		instance.append((afi,safi))
		return instance
Exemple #55
0
	def __init__ (self,what,afi,safi,data=''):
		Operational.__init__(self,what)
		self.afi = AFI(afi)
		self.safi = SAFI(afi)
		self.data = data