def get_domains_for_mc_addr(mc_addr): """ Get domains which have subscriptions on a given multicast address :param mc_addr: multicast address :return: list of domains """ bfrs = GroupManager.get_bfr_by_mc_addr(mc_addr) domains = [0] for bfr in bfrs: domains.extend(TopologyManager.get_domain_for_device(bfr)) domains = list(set(domains)) return domains
def compute_bier_header(mc_addr=None, domain=None): """ Compute the bier header for a given mc_addr in a given domain :param mc_addr: multicast address :param domain: domain identifier :return: """ # only use bfrs in given domain all_bfrs = filter( lambda x: domain in TopologyManager.get_domain_for_device(x), GroupManager.get_bfr_by_mc_addr(mc_addr)) # get (domain specific) bfr ids bfrs = map(lambda x: TopologyManager.get_device(x).get_bfr_id(domain), all_bfrs) bier_header = reduce( ior, map(lambda x: BierComputation.id_to_bitstring(x), bfrs), 0) return bier_header
def update_bier_decap_rule(self, switch=None): """ Updates the bier decap rules based on the current topology :param switch: switch where decap rules should be installed :return: """ valid_entries = [] # bier decap rules for domain in TopologyManager.get_domain_for_device(switch): domain = int(domain) bfr_id = BierComputation.id_to_bitstring( TopologyManager.get_device(switch).get_bfr_id(domain)) entry = TableEntry(switch=switch, match_fields={ "hdr.bier[0].BitString": (bfr_id, bfr_id), "hdr.bier[0].Domain": domain }, action_name="ingress.tunnel_c.bier_decap", action_params={"decapBit": bfr_id}, priority=1) if TableEntryManager.handle_table_entry( manager=self.table_manager, table_name="ingress.tunnel_c.decap_bier", table_entry=entry): Log.async_debug("BIER decap rule updated on", switch, "for domain", domain) valid_entries.append(entry.match_fields) self.table_manager.remove_invalid_entries( switch=switch, table_name="ingress.tunnel_c.decap_bier", valid_entries=valid_entries)
def update_bier_forwarding_entries(self, switch=None): """ Adds bier forwarding entry for given switch in specifc domain :param switch: :param domain: domain identifier :return: """ table_name = "ingress.bier_c.bift" valid_entries = [] for domain in TopologyManager.get_domain_for_device(switch): domain = int(domain) bift = BierComputation.build_bift(switch=switch, domain=domain) for entry in bift: bit_string = BierComputation.id_to_bitstring(id=entry) out_port = TopologyManager.get_device( switch).get_device_to_port(bift.get(entry)[1]) # generate default bier entry e = TableEntry( switch=switch, match_fields={ "meta.bier_md.remainingBits": (bit_string, bit_string), "meta.ports.status": (BierComputation.id_to_bitstring(id=out_port), BierComputation.id_to_bitstring(id=out_port)) }, action_name="ingress.bier_c.forward", action_params={ "fbm": bift.get(entry)[0], "port": out_port }, priority=1) if TableEntryManager.handle_table_entry( manager=self.table_manager, table_name=table_name, table_entry=e): Log.async_debug("Installed BIER rule for", switch, "to bfr-id", entry) valid_entries.append(e.match_fields) # generate bier-frr link protection entry for this switch and bfr if Configuration.get('protection') == 'Link': frr_entry = self.update_frr_link_protection( switch=switch, domain=domain, port=out_port, to_id=entry, fbm=bift.get(entry)[0], next_hop=bift.get(entry)[1]) if TableEntryManager.handle_table_entry( manager=self.table_manager, table_name=table_name, table_entry=frr_entry): Log.async_debug( "Installed BIER-FRR link protection rule for", switch) valid_entries.append(frr_entry.match_fields) # generate bier-frr node protection entry for this switch and bfr if Configuration.get('protection') == 'Node': frr_entry = self.update_frr_node_protection( switch=switch, domain=domain, port=out_port, to_id=entry, fbm=bift.get(entry)[0], next_hop=bift.get(entry)[1]) if frr_entry: if TableEntryManager.handle_table_entry( manager=self.table_manager, table_name=table_name, table_entry=frr_entry): Log.async_debug( "Installed BIER-FRR node protection rule for", switch, "to", entry) valid_entries.append(frr_entry.match_fields) bfr_id = BierComputation.id_to_bitstring( TopologyManager.get_device(switch).get_bfr_id(0)) # Add decap entry entry = TableEntry( switch=switch, match_fields={"meta.bier_md.remainingBits": (bfr_id, bfr_id)}, action_name="ingress.bier_c.decap", action_params={"decapBit": bfr_id}, priority=1) if TableEntryManager.handle_table_entry(manager=self.table_manager, table_name=table_name, table_entry=entry): Log.async_debug("Installed BIER decap rule for", switch) valid_entries.append(entry.match_fields) self.table_manager.remove_invalid_entries(switch=switch, table_name=table_name, valid_entries=valid_entries)