예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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)
예제 #4
0
    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)