def detect_conflicts(collector, files, opener=default_opener, format=mabo_format, is_watched=None, rib=None): """ Get a list of conflicts (hijacks without annotation) from the BGP files (bviews and updates). :param collector: Name of the collector the files come from :param files: List of files to process :param opener: Function to use in order to open the files :param format: Format of the BGP data in the files :param is_watched: Function returning True if the BGP update must be followed :return: Generator of conflicts """ if rib is None: rib = EmulatedRIB() queue = deque(files) # insert initial bview in the RIB bviews = [] while len(queue): try: bview_file = queue.popleft() with opener(bview_file) as f: for data in f: for msg in format(collector, data): if msg.type != "F": raise ValueError if len(list(default_route(msg))) > 0: logger.warning("got a default route %s", msg) continue if is_watched is None or is_watched(msg): route(rib, msg, data) except ValueError: # this file is not a bview, stop right now queue.appendleft(bview_file) break else: bviews.append(bview_file) if len(bviews) == 0 and len(rib.nodes()) == 0: # In case of pre-populated RIB, supplying rib records again # is not a requirement. Can also be invoked with only the update records. raise ValueError("no bviews were loaded") # play all BGP updates to detect BGP conflicts for file in chain(bviews, queue): with opener(file) as f: for data in f: for msg in format(collector, data): default, _, conflicts = process_message( rib, collector, msg, is_watched) if len(default) > 0: logger.warning("got a default route %s", msg) for conflict in conflicts: yield conflict
def process_message(rib, collector, message, is_watched=None, data=None): """ Modify the RIB according to the BGP `message'. """ default = list(default_route(message)) if len(default) > 0: # XXX replace with a filter function # we ignore default routes return default, [], [] conflicts = list(hijack(rib, message)) if message.as_path is None or message.origin is None: routes = withdraw(rib, message) elif len(conflicts) > 0 \ or is_watched is None or is_watched(message) is True: routes = route(rib, message, data) else: routes = [] return default, routes, conflicts