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
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)
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
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