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
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()
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
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)