def getNFFG(self, session_id): session = get_session() session_ref = session.query(GraphSessionModel).filter_by(session_id=session_id).one() # [ NF-FG ] nffg = NF_FG() nffg.id = session_ref.graph_id nffg.name = session_ref.graph_name nffg.description = session_ref.description # [ ENDPOINTs ] end_points_ref = session.query(EndpointModel).filter_by(session_id=session_id).all() for end_point_ref in end_points_ref: # Add endpoint to NFFG end_point = EndPoint(_id=end_point_ref.graph_endpoint_id, name=end_point_ref.name, _type=end_point_ref.type, db_id=end_point_ref.id) nffg.addEndPoint(end_point) # End_point resource end_point_resorces_ref = session.query(EndpointResourceModel).filter_by(endpoint_id=end_point_ref.id).all() for end_point_resorce_ref in end_point_resorces_ref: if end_point_resorce_ref.resource_type == 'port': try: port_ref = session.query(PortModel).filter_by(id=end_point_resorce_ref.resource_id).one() except NoResultFound: port_ref = None logging.debug("Port not found for endpoint "+end_point_ref.graph_endpoint_id) if port_ref is not None: end_point.switch_id = port_ref.switch_id end_point.interface = port_ref.graph_port_id end_point.vlan_id = port_ref.vlan_id # [ FLOW RULEs ] flow_rules_ref = session.query(FlowRuleModel).filter_by(session_id=session_id).all() for flow_rule_ref in flow_rules_ref: if flow_rule_ref.type is not None: # None or 'external' continue # Add flow rule to NFFG flow_rule = FlowRule(_id=flow_rule_ref.graph_flow_rule_id, internal_id=flow_rule_ref.internal_id, priority=int(flow_rule_ref.priority), description=flow_rule_ref.description, db_id=flow_rule_ref.id) nffg.addFlowRule(flow_rule) # [ MATCH ] try: match_ref = session.query(MatchModel).filter_by(flow_rule_id=flow_rule_ref.id).one() except NoResultFound: match_ref = None logging.debug("Found flowrule without a match") if match_ref is not None: # Retrieve endpoint data port_in = None if match_ref.port_in_type == 'endpoint': end_point_ref = session.query(EndpointModel).filter_by(id=match_ref.port_in).first() port_in = 'endpoint:'+end_point_ref.graph_endpoint_id # Add match to this flow rule match = Match(port_in=port_in, ether_type=match_ref.ether_type, vlan_id=match_ref.vlan_id, vlan_priority=match_ref.vlan_priority, source_mac=match_ref.source_mac, dest_mac=match_ref.dest_mac, source_ip=match_ref.source_ip, dest_ip=match_ref.dest_ip, tos_bits=match_ref.tos_bits, source_port=match_ref.source_port, dest_port=match_ref.dest_port, protocol=match_ref.protocol, db_id=match_ref.id) flow_rule.match = match # [ ACTIONs ] actions_ref = session.query(ActionModel).filter_by(flow_rule_id=flow_rule_ref.id).all() if len(actions_ref)==0: logging.debug("Found flowrule without actions") for action_ref in actions_ref: output_to_port = None # Retrieve endpoint data if action_ref.output_type == 'endpoint': end_point_ref = session.query(EndpointModel).filter_by(id = action_ref.output_to_port).first() output_to_port = action_ref.output_type+':'+end_point_ref.graph_endpoint_id # Add action to this flow rule action = Action(output=output_to_port, controller=action_ref.output_to_controller, drop=action_ref._drop, set_vlan_id=action_ref.set_vlan_id, set_vlan_priority=action_ref.set_vlan_priority, push_vlan=action_ref.push_vlan, pop_vlan=action_ref.pop_vlan, set_ethernet_src_address=action_ref.set_ethernet_src_address, set_ethernet_dst_address=action_ref.set_ethernet_dst_address, set_ip_src_address=action_ref.set_ip_src_address, set_ip_dst_address=action_ref.set_ip_dst_address, set_ip_tos=action_ref.set_ip_tos, set_l4_src_port=action_ref.set_l4_src_port, set_l4_dst_port=action_ref.set_l4_dst_port, output_to_queue=action_ref.output_to_queue, db_id=action_ref.id) flow_rule.actions.append(action) return nffg
def searchMatchesBetweenDomains(self, domains_info, domain_id_1, domain_id_2, number_of_links): matches_found = 0 characterization = [] middle_nffg = None domain_1 = domains_info[domain_id_1] # Directly linked domains # Vlan for interface in domain_1.interfaces: for neighbor in interface.neighbors: if neighbor.domain_name != "internet" and neighbor.interface is not None: # Search for direct connections try: remote_domain = Domain().getDomainFromName(neighbor.domain_name) except DomainNotFound: # Remote_domain not found, continue continue remote_node = neighbor.node remote_interface_name = neighbor.interface if remote_domain.id == domain_id_2 and remote_domain.id in domains_info: remote_interface = domains_info[remote_domain.id].getInterface( remote_node, remote_interface_name ) if ( remote_interface is not None and self.isNeighbor(remote_interface, Domain().getDomain(domain_id_1).name, interface) is True ): if interface.vlan is True and remote_interface.vlan is True: while matches_found < number_of_links: vlan_id = self.findFreeVlanId(interface.vlans_free, remote_interface.vlans_free) if vlan_id is not None: print("vlan match found") matches_found = matches_found + 1 characterization.append( Vlan( interface.node, interface.name, domain_1.type, remote_node, remote_interface_name, remote_domain.type, vlan_id, ) ) else: logging.debug("vlan id free not found") break if matches_found == number_of_links: break if matches_found == number_of_links: break # Direct links if matches_found < number_of_links: for interface in domain_1.interfaces: for neighbor in interface.neighbors: if neighbor.domain_name != "internet" and neighbor.interface is not None: # Search for direct connections try: remote_domain = Domain().getDomainFromName(neighbor.domain_name) except DomainNotFound: # Remote_domain not found, continue continue remote_node = neighbor.node remote_interface_name = neighbor.interface if remote_domain.id == domain_id_2 and remote_domain.id in domains_info: remote_interface = domains_info[remote_domain.id].getInterface( remote_node, remote_interface_name ) if ( remote_interface is not None and self.isNeighbor(remote_interface, Domain().getDomain(domain_id_1).name, interface) is True ): print("direct link match found") matches_found = matches_found + 1 characterization.append( DirectLink( interface.node, interface.name, domain_1.type, remote_node, remote_interface_name, remote_domain.type, ) ) if matches_found == number_of_links: break if matches_found == number_of_links: break # Domains not directly linked if matches_found < number_of_links: for interface in domain_1.interfaces: result = self.searchConnectionThroughADomain(domains_info, interface, domain_id_1, domain_id_2) if result is not None: middle_domain = result[0] middle_interface_1 = result[1] middle_interface_2 = result[2] remote_interface = result[3] # TODO: Direct links support? if ( interface.vlan is True and middle_interface_1.vlan is True and middle_interface_2.vlan is True and remote_interface.vlan is True ): middle_nffg = NF_FG() middle_nffg.name = "Passthrough" middle_nffg.domain = middle_domain.name nffg_manager = NFFG_Manager(middle_nffg) while matches_found < number_of_links: vlan_id_1 = self.findFreeVlanId(interface.vlans_free, middle_interface_1.vlans_free) vlan_id_2 = self.findFreeVlanId(middle_interface_2.vlans_free, remote_interface.vlans_free) if vlan_id_1 is not None and vlan_id_2 is not None: print("vlan match through an external domain found") nffg_manager.addEndpointsCoupleAndFlowrules(matches_found) matches_found = matches_found + 1 characterization.append( Vlan( interface.node, interface.name, domain_1.type, middle_interface_1.node, middle_interface_1.name, middle_domain.type, vlan_id_1, partial=1, ) ) characterization.append( Vlan( middle_interface_2.node, middle_interface_2.name, middle_domain.type, remote_interface.node, remote_interface.name, Domain().getDomain(domain_id_2).type, vlan_id_2, partial=2, ) ) else: logging.debug("vlan id free not found") break if matches_found == number_of_links: break # Domains connected through an IP domain # GRE if matches_found < number_of_links: # Search for internet connections for interface in domain_1.interfaces: if self.isConnectedToIPDomain(interface) is True and interface.gre is True: # if self.checkActiveTunnels(interface, node_id_2) is True: domain_2 = domains_info[domain_id_2] for remote_interface in domain_2.interfaces: if self.isConnectedToIPDomain(remote_interface) is True and remote_interface.gre is True: # Gre_tunnel endpoints found # If local and/or remote interfaces are Openstack compute nodes we need to set the local/remote GRE IP addresses accordingly if interface.node is not None: local_ip = interface.node else: local_ip = Domain().getDomainIP(domain_id_1) if remote_interface.node is not None: remote_ip = remote_interface.node else: remote_ip = Domain().getDomainIP(domain_id_2) while matches_found < number_of_links: print("gre match found") matches_found = matches_found + 1 characterization.append(Gre(local_ip, remote_ip)) break if matches_found == number_of_links: break if matches_found == number_of_links: print("Characterization found") return characterization, middle_nffg else: return None