class EmulatedRIB(object): """Emulated RIB using a Radix object.""" def __init__(self): self.radix = Radix() self.peers = dict() def update(self, prefix, peer, value): """Update the information stored concerning a specific prefix.""" peer_sym = self.peers.get(peer, None) if peer_sym is None: peer_sym = self.peers[peer] = peer node = self.radix.add(prefix) node.data[peer_sym] = value return node def lookup(self, prefix, peer): peer_sym = self.peers.get(peer, None) if peer_sym is not None: node = self.radix.search_exact(prefix) if node is not None: return node.data.get(peer_sym, None) def pop(self, prefix, peer): node = self.radix.search_exact(prefix) if node is not None: val = node.data.pop(peer, None) if len(node.data) == 0: self.radix.delete(prefix) return val def delete(self, prefix): return self.radix.delete(prefix) def search_all_containing(self, prefix): tmp_node = self.radix.search_covering(prefix) if tmp_node is None: return [] return tmp_node def search_all_contained(self, prefix): tmp_node = self.radix.search_covered(prefix) if tmp_node is None: return [] return tmp_node def search_exact(self, prefix): return self.radix.search_exact(prefix) def nodes(self): return self.radix.nodes() def prefixes(self): return self.radix.prefixes()
class RIB(object): def __init__(self): self.radixRib = Radix() def serialize(self): '''To encode the py-radix object, we'll convert into a dictionary''' # The py-radix object contains all the prefixes and associated metadata for # each prefix in a single py-radix object. Convert this into a nested dict. rib = [] # walk through the current list of nodes in the tree nodes = self.radixRib.nodes() for node in nodes: entry = {} entry["family"] = node.family entry["network"] = node.network entry["prefix"] = node.prefix entry["prefix_len"] = node.prefixlen entry["paths"] = node.data rib.append(entry) return rib def process_msg(self, route): # Start processing the individual routes Received addr = inet_aton(str(route['prefix'])) logger.debug("Received route with prefix = " + str(route['prefix']) + "/" + str(route['prefix_len']) + " and action=" + str(route['action'])) ribnode = self.radixRib.search_exact(packed=addr, masklen=int(route['prefix_len'])) if ribnode is None: # Particular prefix/prefix-len does not exist in tree, create the node ribnode = self.radixRib.add(packed=addr, masklen=int(route['prefix_len'])) # Create a dictionary with only the path information and path hash as the key for key in ['prefix', 'prefix_len']: del route[key] path_hash = route['hash'] del route['hash'] route_paths = {str(path_hash): route} # add the path to the route path dictionary ribnode.data.update(route_paths) logger.debug("Added the path to the route entry, path hash=" + path_hash) else: #Particular prefix/prefix-len already exists in tree, update the path based on action # Create a dictionary with only the path information and path hash as the key for key in ['prefix', 'prefix_len']: del route[key] path_hash = route['hash'] del route['hash'] # if action == add, update the existing path # if action == del, delete the existing path # if route["action"] == "del": # if path_hash in ribnode.data: # del ribnode.data[path_hash] # logger.debug("path deleted from tree, hash="+path_hash) # else: # logger.debug("Delete for a path that did not exist already") # elif route["action"] == "add": route_paths = {str(path_hash): route} ribnode.data.update(route_paths) logger.debug("Path updated in the tree, hash=" + path_hash)