def compute_path_intents_defualt_queue(network_graph, fs): intent_list = [] # Get the port where the host connects at the first switch in the path link_ports_dict = network_graph.get_link_ports_dict( fs.ng_src_host.node_id, fs.ng_src_host.sw.node_id) in_port = link_ports_dict[fs.ng_src_host.sw.node_id] # This loop always starts at a switch for i in range(1, len(fs.path) - 1): link_ports_dict = network_graph.get_link_ports_dict( fs.path[i], fs.path[i + 1]) fwd_flow_match = deepcopy(fs.flow_match) mac_int = int(fs.ng_dst_host.mac_addr.replace(":", ""), 16) fwd_flow_match["ethernet_destination"] = int(mac_int) intent = Intent("primary", fwd_flow_match, in_port, link_ports_dict[fs.path[i]], True, min_rate=None, max_rate=None) # Store the switch id in the intent intent.switch_id = fs.path[i] intent_list.append(intent) in_port = link_ports_dict[fs.path[i + 1]] return intent_list
def compute_push_vlan_tag_intents(self, h_obj, flow_match, required_tag): push_vlan_match = deepcopy(flow_match) push_vlan_match["in_port"] = int(h_obj.switch_port.port_number) push_vlan_tag_intent = Intent("push_vlan", push_vlan_match, h_obj.switch_port.port_number, "all", self.apply_tag_intents_immediately) push_vlan_tag_intent.required_vlan_id = required_tag # Avoiding adding a new intent for every departing flow for this switch, # by adding the tag as the key self.add_intent(h_obj.sw.node_id, required_tag, push_vlan_tag_intent)
def push_src_sw_vlan_push_intents(self, src_sw, dst_sw, flow_match): for h_obj in dst_sw.attached_hosts: host_flow_match = deepcopy(flow_match) mac_int = int(h_obj.mac_addr.replace(":", ""), 16) host_flow_match["ethernet_destination"] = int(mac_int) host_flow_match["vlan_id"] = sys.maxsize host_flow_match["in_port"] = sys.maxsize push_vlan_tag_intent = Intent("push_vlan", host_flow_match, "all", "all") push_vlan_tag_intent.required_vlan_id = int(dst_sw.synthesis_tag) | (1 << self.num_bits_for_switches) self.synthesis_lib.push_vlan_push_intents(src_sw.node_id, [push_vlan_tag_intent], self.tree_vlan_tag_push_rules)
def compute_sw_intent_lists(self, dst_sw, flow_match, tree, tree_id): for src_n in tree: src_sw = self.network_graph.get_node_object(src_n) for pred in tree.predecessors(src_n): link_port_dict = self.network_graph.get_link_ports_dict(src_n, pred) out_port = link_port_dict[src_n] intent = Intent("primary", flow_match, "all", out_port) intent.tree_id = tree_id intent.tree = tree if src_sw in self.sw_intent_lists: if dst_sw in self.sw_intent_lists[src_sw]: self.sw_intent_lists[src_sw][dst_sw].append(intent) else: self.sw_intent_lists[src_sw][dst_sw] = [intent] else: self.sw_intent_lists[src_sw][dst_sw] = [intent]
def compute_path_intents(self, fs): intent_list = [] src_host_dict = self.network_configuration.get_host_dict(fs.src_host_id) dst_host_dict = self.network_configuration.get_host_dict(fs.dst_host_id) fs.path = nx.shortest_path(self.network_configuration.graph, source=fs.src_host_id, target=fs.dst_host_id, weight='weight') # Get the port where the host connects at the first switch in the path link_ports_dict = self.network_configuration.get_link_dict(fs.src_host_id, src_host_dict["bridge_id"]) in_port = link_ports_dict["node2_port"] # This loop always starts at a switch for i in range(1, len(fs.path) - 1): # Out port is the port on which the next switch is connected at this switch link_ports_dict = self.network_configuration.get_link_dict(fs.path[i], fs.path[i+1]) out_port = link_ports_dict["node1_port"] intent = Intent("primary", None, in_port, out_port, True, min_rate=fs.configured_rate_bps, max_rate=fs.configured_rate_bps) intent.src_ip = src_host_dict["host_IP"] intent.dst_ip = dst_host_dict["host_IP"] intent.src_mac = src_host_dict["host_MAC"] intent.dst_mac = dst_host_dict["host_MAC"] # Store the switch id in the intent intent.min_rate = fs.configured_rate_bps intent.max_rate = fs.configured_rate_bps intent.bridge_dict = self.network_configuration.get_bridge_dict(link_ports_dict["node1"]) intent_list.append(intent) in_port = link_ports_dict["node2_port"] return intent_list
def push_local_mac_forwarding_rules_rules(self, sw, flow_match): for h_obj in sw.attached_hosts: host_flow_match = deepcopy(flow_match) mac_int = int(h_obj.mac_addr.replace(":", ""), 16) host_flow_match["ethernet_destination"] = int(mac_int) edge_ports_dict = self.network_graph.get_link_ports_dict(h_obj.sw.node_id, h_obj.node_id) out_port = edge_ports_dict[h_obj.sw.node_id] host_mac_intent = Intent("mac", host_flow_match, "all", out_port) self.synthesis_lib.push_destination_host_mac_intents(sw.node_id, [host_mac_intent], self.local_mac_forwarding_rules)
def compute_and_push_vlan_tag_intents(self, src_h_obj, dst_h_obj, flow_match, required_tag, primary_first_intent, failover_first_intent): group_id = None sw = src_h_obj.sw.node_id if primary_first_intent and failover_first_intent: group_id = self.synthesis_lib.push_fast_failover_group( sw, primary_first_intent, failover_first_intent) elif primary_first_intent: group_id = self.synthesis_lib.push_select_all_group( sw, [primary_first_intent]) push_vlan_match = deepcopy(flow_match) mac_int = int(dst_h_obj.mac_addr.replace(":", ""), 16) push_vlan_match["ethernet_destination"] = int(mac_int) push_vlan_match["in_port"] = int(src_h_obj.switch_port.port_number) push_vlan_tag_intent = Intent("push_vlan", push_vlan_match, src_h_obj.switch_port.port_number, "all", apply_immediately=True) push_vlan_tag_intent.required_vlan_id = required_tag flow = self.synthesis_lib.push_match_per_in_port_destination_instruct_group_flow( sw, self.vlan_tag_push_rules_table_id, group_id, 1, push_vlan_match, True) # Take care of vlan tag push intents for this destination self.synthesis_lib.push_vlan_push_intents_2( src_h_obj.sw.node_id, push_vlan_tag_intent, self.vlan_tag_push_rules_table_id, group_id, True)
def compute_br_intent_lists(self, dst_bridge_dict, tree, tree_id): dst_node_id = dst_bridge_dict["bridge_name"] for src_node_id in tree: for pred in tree.predecessors(src_node_id): link_port_dict = self.network_configuration.get_link_dict( src_node_id, pred) out_port = link_port_dict["node1_port"] intent = Intent("primary", None, "all", out_port) intent.tree_id = tree_id if src_node_id in self.br_intent_lists: if dst_node_id in self.br_intent_lists[src_node_id]: self.br_intent_lists[src_node_id][dst_node_id].append( intent) else: self.br_intent_lists[src_node_id][dst_node_id] = [ intent ] else: self.br_intent_lists[src_node_id][dst_node_id] = [intent]
def compute_path_intents(self, src_host, dst_host, p, intent_type, flow_match, first_in_port, dst_switch_tag, rate): edge_ports_dict = self.network_graph.get_link_ports_dict(p[0], p[1]) in_port = first_in_port out_port = edge_ports_dict[p[0]] # This loop always starts at a switch for i in range(len(p) - 1): fwd_flow_match = deepcopy(flow_match) if not self.params["same_output_queue"]: mac_int = int(dst_host.mac_addr.replace(":", ""), 16) fwd_flow_match["ethernet_destination"] = int(mac_int) intent = Intent(intent_type, fwd_flow_match, in_port, out_port, self.apply_other_intents_immediately, min_rate=rate, max_rate=rate) # Using dst_switch_tag as key here to # avoid adding multiple intents for the same destination if self.params["same_output_queue"]: self.add_intent(p[i], dst_switch_tag, intent) else: self.add_intent(p[i], (dst_switch_tag, dst_host.mac_addr), intent) # Prep for next switch if i < len(p) - 2: edge_ports_dict = self.network_graph.get_link_ports_dict( p[i], p[i + 1]) in_port = edge_ports_dict[p[i + 1]] edge_ports_dict = self.network_graph.get_link_ports_dict( p[i + 1], p[i + 2]) out_port = edge_ports_dict[p[i + 1]]
def _compute_destination_host_mac_intents(self, h_obj, flow_match, matching_tag): edge_ports_dict = self.network_graph.get_link_ports_dict( h_obj.sw.node_id, h_obj.node_id) out_port = edge_ports_dict[h_obj.sw.node_id] host_mac_match = deepcopy(flow_match) mac_int = int(h_obj.mac_addr.replace(":", ""), 16) host_mac_match["ethernet_destination"] = int(mac_int) host_mac_match["vlan_id"] = int(matching_tag) host_mac_intent = Intent("mac", host_mac_match, "all", out_port, apply_immediately=True) # Avoiding addition of multiple mac forwarding intents for the same host # by using its mac address as the key self._add_intent(h_obj.sw.node_id, h_obj.mac_addr, host_mac_intent)
def _compute_path_ip_intents(self, src_host, dst_host, p, intent_type, flow_match, first_in_port, dst_switch_tag, edge_broken=None, switch_port_tuple_prefix_list=None): edge_ports_dict = self.network_graph.get_link_ports_dict(p[0], p[1]) switch_port_tuple_list = [] in_port = first_in_port out_port = edge_ports_dict[p[0]] # Save it for returning first_path_intent = None # This loop always starts at a switch for i in xrange(len(p) - 1): fwd_flow_match = deepcopy(flow_match) # All intents except the first one in the primary path must specify the vlan tag if not (i == 0 and intent_type == "primary"): fwd_flow_match["vlan_id"] = int(dst_switch_tag) intent = Intent(intent_type, fwd_flow_match, in_port, out_port) intent.src_host = src_host intent.dst_host = dst_host switch_port_tuple_list.append((p[i], in_port, out_port)) if i == 0: first_path_intent = intent # Using dst_switch_tag as key here to # avoid adding multiple intents for the same destination self._add_intent(p[i], dst_switch_tag, intent) # Prep for next switch if i < len(p) - 2: edge_ports_dict = self.network_graph.get_link_ports_dict( p[i], p[i + 1]) in_port = edge_ports_dict[p[i + 1]] edge_ports_dict = self.network_graph.get_link_ports_dict( p[i + 1], p[i + 2]) out_port = edge_ports_dict[p[i + 1]] last_switch = p[len(p) - 1] last_edge_ports_dict = self.network_graph.get_link_ports_dict( p[len(p) - 2], p[len(p) - 1]) last_switch_in_port = edge_ports_dict[last_switch] switch_port_tuple_list.append((last_switch, last_switch_in_port, dst_host.switch_port.port_number)) if intent_type == "primary": self.synthesis_lib.record_primary_path(src_host, dst_host, switch_port_tuple_list) elif intent_type == "failover": self.synthesis_lib.record_failover_path( src_host, dst_host, edge_broken, switch_port_tuple_prefix_list + switch_port_tuple_list) return first_path_intent