コード例 #1
0
    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    
コード例 #2
0
    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