Esempio n. 1
0
    def updates(self, grouped):
        attr_af_nlri = self._new_attr_af_nlri
        new_attr = self._new_attribute

        # Get ready to accept more data
        self._new_nlri = {}
        self._new_attr_af_nlri = {}
        self._new_attribute = {}

        # if we need to perform a route-refresh, sending the message
        # to indicate the start of the announcements

        rr_announced = []

        for afi, safi in self._enhanced_refresh_start:
            rr_announced.append((afi, safi))
            yield Update(RouteRefresh(afi, safi, RouteRefresh.start),
                         Attributes())

        # generating Updates from what is in the RIB

        for attr_index, per_family in attr_af_nlri.items():
            for family, changes in per_family.items():
                if not changes:
                    continue

                # only yield once we have a consistent state, otherwise it will go wrong
                # as we will try to modify things we are iterating over and using

                attributes = new_attr[attr_index]

                if family == (AFI.ipv4, SAFI.unicast) and grouped:
                    yield Update([change.nlri for change in changes.values()],
                                 attributes)
                else:
                    for change in changes.values():
                        yield Update(
                            [
                                change.nlri,
                            ],
                            attributes,
                        )

        # If we are performing a route-refresh, indicating that the
        # update were all sent

        if rr_announced:
            for afi, safi in rr_announced:
                self._enhanced_refresh_start.remove((afi, safi))
                yield Update(RouteRefresh(afi, safi, RouteRefresh.end),
                             Attributes())

            for change in self._enhanced_refresh_delay:
                self.add_to_rib(change, True)
            self._enhanced_refresh_delay = []

            for update in self.updates(grouped):
                yield update
Esempio n. 2
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)
Esempio n. 3
0
    def updates(self, grouped):
        if self._changes:
            dict_nlri = self._modify_nlri

            for family in self._seen:
                for change in self._seen[family].itervalues():
                    if change.index() not in self._modify_nlri:
                        change.nlri.action = OUT.WITHDRAW
                        self.insert_announced(change, True)

            for new in self._changes:
                self.insert_announced(new, True)
            self._changes = None
        # end of changes

        rr_announced = []

        for afi, safi in self._enhanced_refresh_start:
            rr_announced.append((afi, safi))
            yield Update(RouteRefresh(afi, safi, RouteRefresh.start),
                         Attributes())

        dict_sorted = self._modify_sorted
        dict_nlri = self._modify_nlri
        dict_attr = self._cache_attribute

        for attr_index, full_dict_change in dict_sorted.items():
            if self.cache:
                dict_change = {}
                for nlri_index, change in full_dict_change.iteritems():
                    family = change.nlri.family()
                    announced = self._seen.get(family, {})
                    if change.nlri.action == OUT.ANNOUNCE:
                        if nlri_index in announced:
                            old_change = announced[nlri_index]
                            # it is a duplicate route
                            if old_change.attributes.index(
                            ) == change.attributes.index(
                            ) and old_change.nlri.nexthop.index(
                            ) == change.nlri.nexthop.index():
                                continue
                    elif change.nlri.action == OUT.WITHDRAW:
                        if nlri_index not in announced:
                            if dict_nlri[
                                    nlri_index].nlri.action == OUT.ANNOUNCE:
                                continue
                    dict_change[nlri_index] = change
            else:
                dict_change = full_dict_change

            if not dict_change:
                continue

            attributes = dict_attr[attr_index].attributes

            # we NEED the copy provided by list() here as insert_announced can be called while we iterate
            changed = list(dict_change.itervalues())

            if grouped:
                updates = []
                nlris = []
                for change in dict_change.values():
                    if change.nlri.afi == AFI.ipv4:
                        nlris.append(change.nlri)
                        continue
                    updates.append(Update([change.nlri], attributes))
                if nlris:
                    updates.append(Update(nlris, attributes))
                    nlris = []

                for change in changed:
                    nlri_index = change.index()
                    del dict_sorted[attr_index][nlri_index]
                    del dict_nlri[nlri_index]
                # only yield once we have a consistent state, otherwise it will go wrong
                # as we will try to modify things we are using
                for update in updates:
                    yield update
            else:
                updates = []
                for change in changed:
                    updates.append(Update([
                        change.nlri,
                    ], attributes))
                    nlri_index = change.index()
                    del dict_sorted[attr_index][nlri_index]
                    del dict_nlri[nlri_index]
                # only yield once we have a consistent state, otherwise it will go wrong
                # as we will try to modify things we are using
                for update in updates:
                    yield update

            if self.cache:
                announced = self._seen
                for change in changed:
                    if change.nlri.action == OUT.ANNOUNCE:
                        announced.setdefault(change.nlri.family(),
                                             {})[change.index()] = change
                    else:
                        family = change.nlri.family()
                        if family in announced:
                            announced[family].pop(change.index(), None)

        if rr_announced:
            for afi, safi in rr_announced:
                self._enhanced_refresh_start.remove((afi, safi))
                yield Update(RouteRefresh(afi, safi, RouteRefresh.end),
                             Attributes())

            for change in self._enhanced_refresh_delay:
                self.insert_announced(change, True)
            self.enhanced_refresh_delay = []

            for update in self.updates(grouped):
                yield update
Esempio n. 4
0
	def updates (self, grouped):
		if self._changes:
			dict_nlri = self._modify_nlri

			for family in self._seen:
				for change in six.itervalues(self._seen[family]):
					if change.index() not in self._modify_nlri:
						change.nlri.action = OUT.WITHDRAW
						self.insert_announced(change,True)

			for new in self._changes:
				self.insert_announced(new,True)
			self._changes = None
		# end of changes

		rr_announced = []

		for afi,safi in self._enhanced_refresh_start:
			rr_announced.append((afi,safi))
			yield Update(RouteRefresh(afi,safi,RouteRefresh.start),Attributes())

		dict_sorted = self._modify_sorted
		dict_nlri = self._modify_nlri
		dict_attr = self._cache_attribute

		for attr_index,dict_change in dict_sorted.items():
			if not dict_change:
				continue

			updates = {}
			changed = dict_change.values()
			attributes = dict_attr[attr_index].attributes

			for change in dict_change.values():
				updates.setdefault(change.nlri.family(),[]).append(change.nlri)
				nlri_index = change.index()

			# only yield once we have a consistent state, otherwise it will go wrong
			# as we will try to modify things we are iterating over and using

			if grouped:
				for nlris in six.itervalues(updates):
					yield Update(nlris, attributes)
			else:
				for nlris in six.itervalues(updates):
					for nlri in nlris:
						yield Update([nlri,], attributes)

			if self.cache:
				announced = self._seen
				for change in changed:
					if change.nlri.action == OUT.ANNOUNCE:
						announced.setdefault(change.nlri.family(),{})[change.index()] = change
					else:
						family = change.nlri.family()
						if family in announced:
							announced[family].pop(change.index(),None)

		self._modify_sorted = {}
		self._modify_nlri = {}

		if rr_announced:
			for afi,safi in rr_announced:
				self._enhanced_refresh_start.remove((afi,safi))
				yield Update(RouteRefresh(afi,safi,RouteRefresh.end),Attributes())

			for change in self._enhanced_refresh_delay:
				self.insert_announced(change,True)
			self.enhanced_refresh_delay = []

			for update in self.updates(grouped):
				yield update