예제 #1
0
    def compute_edge_admitted_traffic(self, traffic_to_propagate, edge):

        pred_admitted_traffic = Traffic()

        for ed in edge.edge_data_list:

            # At succ edges, set the in_port of the admitted match for destination to wildcard
            if edge.edge_type == "outside":
                traffic_to_propagate.set_field("in_port", is_wildcard=True)
                traffic_to_propagate.clear_switch_modifications()

            # If there were modifications along the way...
            if ed.applied_modifications:
                ttp = traffic_to_propagate.get_orig_traffic(
                    ed.applied_modifications)
            else:
                ttp = traffic_to_propagate

            i = ed.edge_filter_traffic.intersect(ttp)
            i.set_enabling_edge_data(ed)

            if not i.is_empty():
                pred_admitted_traffic.union(i)

        return pred_admitted_traffic
예제 #2
0
    def get_admitted_traffic(self, node, dst):

        dst_admitted_traffic = Traffic()

        if dst in node.admitted_traffic:
            for succ in node.admitted_traffic[dst]:
                dst_admitted_traffic.union(node.admitted_traffic[dst][succ])

        return dst_admitted_traffic
    def init_switch_port_graph(self):

        print "Initializing Port Graph for switch:", self.sw.node_id

        # Initialize switch ports' port graph state
        for port_num in self.sw.ports:

            if port_num == 1 and self.sw.node_id == "s1":
                pass

            self.sw.ports[port_num].init_port_graph_state()

        # Initialize port graph state per table and add its node to switch port graph
        for flow_table in self.sw.flow_tables:
            flow_table.init_port_graph_state()
            self.add_node(flow_table.port_graph_node)

        # Add two nodes per physical port in port graph one for incoming and outgoing direction
        # Connect incoming direction port to table 0's port
        for port_num in self.sw.ports:

            port = self.sw.ports[port_num]

            self.add_node(port.switch_port_graph_ingress_node)
            self.add_node(port.switch_port_graph_egress_node)

            self.boundary_ingress_nodes.append(
                port.switch_port_graph_ingress_node)
            self.boundary_egress_nodes.append(
                port.switch_port_graph_egress_node)

            edge = PortGraphEdge(port.switch_port_graph_ingress_node,
                                 self.sw.flow_tables[0].port_graph_node)
            edge_traffic_filter = Traffic()
            edge_traffic_filter.union(port.ingress_node_traffic)
            edge_data = SwitchPortGraphEdgeData(edge_traffic_filter, None,
                                                None, None)
            edge.add_edge_data(edge_data)
            self.add_edge(port.switch_port_graph_ingress_node,
                          self.sw.flow_tables[0].port_graph_node, edge)

        # Try passing a wildcard through the flow table
        for flow_table in self.sw.flow_tables:
            flow_table.compute_flow_table_port_graph_edges()
            self.add_flow_table_edges(flow_table)

        # Initialize all groups' active buckets
        for group_id in self.sw.group_table.groups:
            self.sw.group_table.groups[group_id].set_active_bucket()
예제 #4
0
    def init_network_admitted_traffic_for_sw(self, sw):
        for non_host_port in sw.non_host_port_iter():

            # Accumulate traffic that is admitted for each host
            admitted_host_traffic = Traffic()
            for host_port in sw.host_port_iter():
                at = sw.port_graph.get_admitted_traffic(
                    non_host_port.switch_port_graph_ingress_node,
                    host_port.switch_port_graph_egress_node)
                admitted_host_traffic.union(at)

            end_to_end_modified_edges = []
            self.propagate_admitted_traffic(
                non_host_port.network_port_graph_ingress_node,
                admitted_host_traffic, None,
                non_host_port.network_port_graph_ingress_node,
                end_to_end_modified_edges)

            admitted_host_traffic.set_field("in_port",
                                            int(non_host_port.port_number))
    def compute_edge_admitted_traffic(self, traffic_to_propagate, edge):

        pred_admitted_traffic = Traffic()

        for ed in edge.edge_data_list:

            if edge.edge_type == "egress":

                # if the output_action type is applied, no written modifications take effect.
                if ed.edge_action.instruction_type == "applied":
                    traffic_to_propagate.set_written_modifications_apply(False)
                else:
                    traffic_to_propagate.set_written_modifications_apply(True)

            # Always roll-back applied modifications if the edge has any...
            if ed.applied_modifications:
                ttp = traffic_to_propagate.get_orig_traffic(
                    ed.applied_modifications)
            else:
                ttp = traffic_to_propagate

            # At ingress edges, first roll-back any accumulated written modifications
            if edge.edge_type == "ingress":
                ttp = ttp.get_orig_traffic(
                    use_embedded_written_modifications=True)

            i = ed.edge_filter_traffic.intersect(ttp)
            i.set_enabling_edge_data(ed)

            if not i.is_empty():
                # At all the non-ingress edges accumulate written modifications
                if edge.edge_type != "ingress" and ed.written_modifications:
                    i.set_written_modifications(ed.written_modifications)

                pred_admitted_traffic.union(i)

        return pred_admitted_traffic
예제 #6
0
    def update_admitted_traffic(self, modified_edges,
                                end_to_end_modified_edges):

        # This object holds for each pred/dst combinations
        # that have changed as keys and list of succ ports as values
        admitted_traffic_changes = defaultdict(defaultdict)

        for modified_edge in modified_edges:

            pred = self.get_node(modified_edge[0])
            succ = self.get_node(modified_edge[1])

            # TODO Limit the destinations by using markers in modified_flow_table_edges
            # Right now, just take all the destinations at succ and marking them as having been modified...

            for dst in self.get_admitted_traffic_dsts(succ):
                if dst not in admitted_traffic_changes[pred]:
                    admitted_traffic_changes[pred][dst] = [succ]
                else:
                    if succ not in admitted_traffic_changes[pred][dst]:
                        admitted_traffic_changes[pred][dst].append(succ)

        # Do this for each pred port that has changed
        for pred in admitted_traffic_changes:

            # For each destination that may have been affected at the pred port
            for dst in admitted_traffic_changes[pred]:

                now_pred_traffic = Traffic()

                # Check the fate of traffic from changed successors in this loop
                for succ in admitted_traffic_changes[pred][dst]:

                    edge = self.get_edge(pred, succ)

                    succ_traffic = self.get_admitted_traffic(succ, dst)

                    # Update admitted traffic at successor node to reflect changes
                    pred_traffic_via_succ = self.compute_edge_admitted_traffic(
                        succ_traffic, edge)
                    self.set_admitted_traffic_via_succ(pred, dst, succ,
                                                       pred_traffic_via_succ)

                    # Accumulate total traffic admitted at this pred
                    now_pred_traffic.union(pred_traffic_via_succ)

                # Collect traffic from any succs that was not changed
                for succ in self.get_admitted_traffic_succs(pred, dst):
                    if succ not in admitted_traffic_changes[pred][dst]:
                        now_pred_traffic.union(
                            self.get_admitted_traffic_via_succ(
                                pred, dst, succ))

                # Propagate the net unioned traffic to all of predecessors of the predecessor itself.
                for pred_pred in self.predecessors_iter(pred):

                    edge = self.get_edge(pred_pred, pred)
                    pred_pred_traffic = self.compute_edge_admitted_traffic(
                        now_pred_traffic, edge)

                    self.propagate_admitted_traffic(pred_pred,
                                                    pred_pred_traffic, pred,
                                                    dst,
                                                    end_to_end_modified_edges)