Ejemplo n.º 1
0
class LinuxbridgeMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
    """Attach to networks using linuxbridge L2 agent.

    The LinuxbridgeMechanismDriver integrates the ml2 plugin with the
    linuxbridge L2 agent. Port binding with this driver requires the
    linuxbridge agent to be running on the port's host, and that agent
    to have connectivity to at least one segment of the port's
    network.
    """

    def __init__(self):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        sg_enabled = securitygroups_rpc.is_firewall_enabled()
        vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
                       portbindings.VIF_DETAILS_CONNECTIVITY:
                           portbindings.CONNECTIVITY_L2}
        super(LinuxbridgeMechanismDriver, self).__init__(
            constants.AGENT_TYPE_LINUXBRIDGE,
            portbindings.VIF_TYPE_BRIDGE,
            vif_details)
        lb_qos_driver.register()

    def get_allowed_network_types(self, agent):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        return (agent['configurations'].get('tunnel_types', []) +
                [constants.TYPE_LOCAL, constants.TYPE_FLAT,
                 constants.TYPE_VLAN])

    def get_mappings(self, agent):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        mappings = dict(agent['configurations'].get('interface_mappings', {}),
                        **agent['configurations'].get('bridge_mappings', {}))
        return mappings

    def check_vlan_transparency(self, context):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        """Linuxbridge driver vlan transparency support."""
        return True
Ejemplo n.º 2
0
 def update_port_status_to_active(self, port, rpc_context, port_id, host):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
              log_utils.get_fname(2))
     plugin = directory.get_plugin()
     if port and port['device_owner'] == n_const.DEVICE_OWNER_DVR_INTERFACE:
         # NOTE(kevinbenton): we have to special case DVR ports because of
         # the special multi-binding status update logic they have that
         # depends on the host
         plugin.update_port_status(rpc_context, port_id,
                                   n_const.PORT_STATUS_ACTIVE, host)
     else:
         # _device_to_port_id may have returned a truncated UUID if the
         # agent did not provide a full one (e.g. Linux Bridge case). We
         # need to look up the full one before calling provisioning_complete
         if not port:
             port = ml2_db.get_port(rpc_context, port_id)
         if not port:
             # port doesn't exist, no need to add a provisioning block
             return
         provisioning_blocks.provisioning_complete(
             rpc_context, port['id'], resources.PORT,
             provisioning_blocks.L2_AGENT_ENTITY)
Ejemplo n.º 3
0
class QosRuleTypeDriver(base.NeutronObject):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
             log_utils.get_fname(2))
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'name': obj_fields.StringField(),
        'supported_parameters': common_types.ListOfDictOfMiscValuesField()
    }

    def to_dict(self):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        return {
            'name': self.name,
            'supported_parameters': self.supported_parameters
        }

    @classmethod
    def get_objects(cls, context, **kwargs):
        raise NotImplementedError()
Ejemplo n.º 4
0
    def get_standard_device_mappings(self, agent):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        """Return the agent's bridge mappings in a standard way.

        The common format for OVS and SRIOv mechanism drivers:
        {'physnet_name': ['device_or_bridge_1', 'device_or_bridge_2']}

        :param agent: The agent
        :returns A dict in the format: {'physnet_name': ['bridge_or_device']}
        :raises ValueError: if there is no bridge_mappings key in
                            agent['configurations']
        """
        if 'bridge_mappings' in agent['configurations']:
            return {
                k: [v]
                for k, v in agent['configurations']['bridge_mappings'].items()
            }
        else:
            raise ValueError(
                _('Cannot standardize bridge mappings of agent '
                  'type: %s'), agent['agent_type'])
Ejemplo n.º 5
0
    def handle_port(self, context, port):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        """Handle agent QoS extension for port.

        This method applies a new policy to a port using the QoS driver.
        Update events are handled in _handle_notification.
        """
        port_id = port['port_id']
        port_qos_policy_id = port.get('qos_policy_id')
        network_qos_policy_id = port.get('network_qos_policy_id')
        qos_policy_id = port_qos_policy_id or network_qos_policy_id
        if qos_policy_id is None:
            self._process_reset_port(port)
            return

        if not self.policy_map.has_policy_changed(port, qos_policy_id):
            return

        qos_policy = self.policy_map.get_policy(
            qos_policy_id) or self.resource_rpc.pull(
                context, resources.QOS_POLICY, qos_policy_id)
        if qos_policy is None:
            LOG.info(
                "QoS policy %(qos_policy_id)s applied to port "
                "%(port_id)s is not available on server, "
                "it has been deleted. Skipping.", {
                    'qos_policy_id': qos_policy_id,
                    'port_id': port_id
                })
            self._process_reset_port(port)
        else:
            old_qos_policy = self.policy_map.set_port_policy(port, qos_policy)
            # Before applying the new rules, the old rules should be cleared,
            # even if the old_qos_policy is None,
            # to avoid the data being out of sync before the l2-agent starts.
            self.qos_driver.delete(port, old_qos_policy)
            if qos_policy.rules:
                self.qos_driver.create(port, qos_policy)
Ejemplo n.º 6
0
    def process_gateway_rate_limit(self, context, router_info):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        is_distributed_router = router_info.router.get('distributed')
        agent_mode = router_info.agent_conf.agent_mode
        LOG.debug(
            "Start processing gateway IP QoS for "
            "router %(router_id)s, router "
            "distributed: %(distributed)s, "
            "agent mode: %(agent_mode)s", {
                "router_id": router_info.router_id,
                "distributed": is_distributed_router,
                "agent_mode": agent_mode
            })
        if is_distributed_router and agent_mode in (
                constants.L3_AGENT_MODE_DVR,
                constants.L3_AGENT_MODE_DVR_NO_EXTERNAL):
            # Dvr local router and dvr_no_external agent do not process
            # gateway IPs.
            return

        self._handle_router_gateway_rate_limit(context, router_info)
Ejemplo n.º 7
0
class DistributedPortBinding(PortBindingBase):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
    # Version 1.0: Initial version
    VERSION = '1.0'

    db_model = ml2_models.DistributedPortBinding

    fields = {
        'port_id': common_types.UUIDField(),
        'host': obj_fields.StringField(),
        'profile': common_types.DictOfMiscValuesField(),
        'vif_type': obj_fields.StringField(),
        'vif_details': common_types.DictOfMiscValuesField(nullable=True),
        'vnic_type': obj_fields.StringField(),
        # NOTE(ihrachys): Fields below are specific to this type of binding. In
        # the future, we could think of converging different types of bindings
        # into a single field
        'status': obj_fields.StringField(),
        'router_id': obj_fields.StringField(nullable=True),
    }

    primary_keys = ['host', 'port_id']
Ejemplo n.º 8
0
    def start_of_controller(self, conf):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        self.br_int_cls = None
        self.br_tun_cls = None
        self.br_phys_cls = None
        self.init_done = False
        self.init_done_ev = eventlet.event.Event()
        self.main_ev = eventlet.event.Event()
        self.addCleanup(self._kill_main)
        retry_count = 3
        while True:
            # Try a few different ports as a port conflict
            # causes the test to fail.
            conf.set_override('of_listen_port',
                              net_helpers.get_free_namespace_port(
                                  n_const.PROTO_NAME_TCP),
                              group='OVS')
            cfg.CONF.set_override('of_listen_port',
                                  conf.OVS.of_listen_port,
                                  group='OVS')
            main_mod.init_config()
            self._main_thread = eventlet.spawn(self._kick_main)

            # Wait for _kick_main -> openflow main -> _agent_main
            # NOTE(yamamoto): This complexity came from how we run openflow
            # controller. Main routine blocks while running the embedded
            # openflow controller.  In that case, the agent rpc_loop runs in
            # another thread.  However, for FT we need to run setUp() and
            # test_xxx() in the same thread.  So I made this run openflow main
            # in a separate thread instead.
            try:
                while not self.init_done:
                    self.init_done_ev.wait()
                break
            except fixtures.TimeoutException:
                self._kill_main()
            retry_count -= 1
            if retry_count < 0:
                raise Exception('port allocation failed')
Ejemplo n.º 9
0
    def validate_rule_for_port(self, rule, port):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        port_binding = utils.get_port_binding_by_status_and_host(
            port.bindings,
            lib_constants.ACTIVE,
            raise_if_not_found=True,
            port_id=port['id'])
        for driver in self._drivers:
            vif_type = port_binding.vif_type
            if vif_type not in SKIPPED_VIF_TYPES:
                if not self._validate_vif_type(driver, vif_type, port['id']):
                    continue
            else:
                vnic_type = port_binding.vnic_type
                if not self._validate_vnic_type(driver, vnic_type, port['id']):
                    continue

            if driver.is_rule_supported(rule):
                return True

        return False
Ejemplo n.º 10
0
def add_tc_policy_class(device,
                        parent,
                        classid,
                        min_kbps=1,
                        max_kbps=None,
                        burst_kb=None,
                        namespace=None):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
             log_utils.get_fname(2))
    """Add a TC policy class

    :param device: (string) device name
    :param parent: (string) qdisc parent class ('root', 'ingress', '2:10')
    :param classid: (string) major:minor handler identifier ('10:20')
    :param min_kbps: (int) (optional) minimum bandwidth in kbps
    :param max_kbps: (int) (optional) maximum bandwidth in kbps
    :param burst_kb: (int) (optional) burst size in kb
    :param namespace: (string) (optional) namespace name
    :return:
    """
    parent = TC_QDISC_PARENT.get(parent, parent)
    # NOTE(ralonsoh): pyroute2 input parameters and units [1]:
    #   - rate (min bw): bytes/second
    #   - ceil (max bw): bytes/second
    #   - burst: bytes
    # [1] https://www.systutorials.com/docs/linux/man/8-tc/
    if int(min_kbps) < 1:
        raise TcLibPolicyClassInvalidMinKbpsValue()
    args = {'rate': int(min_kbps * 1024 / 8)}
    if max_kbps:
        args['ceil'] = int(max_kbps * 1024 / 8)
    if burst_kb:
        args['burst'] = int(burst_kb * 1024 / 8)
    priv_tc_lib.add_tc_policy_class(device,
                                    parent,
                                    classid,
                                    'htb',
                                    namespace=namespace,
                                    **args)
Ejemplo n.º 11
0
class Manager(periodic_task.PeriodicTasks):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
             log_utils.get_fname(2))
    __trace_args__ = {"name": "rpc"}

    # Set RPC API version to 1.0 by default.
    target = oslo_messaging.Target(version='1.0')

    def __init__(self, host=None):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        if not host:
            host = cfg.CONF.host
        self.host = host
        conf = getattr(self, "conf", cfg.CONF)
        super(Manager, self).__init__(conf)

    def periodic_tasks(self, context, raise_on_error=False):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        self.run_periodic_tasks(context, raise_on_error=raise_on_error)

    def init_host(self):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        """Handle initialization if this is a standalone service.

        Child classes should override this method.

        """
        pass

    def after_start(self):
        """Handler post initialization stuff.

        Child classes can override this method.
        """
        pass
Ejemplo n.º 12
0
    def _exclude_attributes_by_policy(self, context, data):
        """Identifies attributes to exclude according to authZ policies.

        Return a list of attribute names which should be stripped from the
        response returned to the user because the user is not authorized
        to see them.
        """
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        attributes_to_exclude = []
        for attr_name in data.keys():
            # TODO(amotoki): At now, all attribute maps have tenant_id and
            # determine excluded attributes based on tenant_id.
            # We need to migrate tenant_id to project_id later
            # as attr_info is referred to in various places and we need
            # to check all logis carefully.
            if attr_name == 'project_id':
                continue
            attr_data = self._attr_info.get(attr_name)
            if attr_data and attr_data['is_visible']:
                if policy.check(context,
                                '%s:%s' %
                                (self._plugin_handlers[self.SHOW], attr_name),
                                data,
                                might_not_exist=True,
                                pluralized=self._collection):
                    # this attribute is visible, check next one
                    continue
            # if the code reaches this point then either the policy check
            # failed or the attribute was not visible in the first place
            attributes_to_exclude.append(attr_name)
            # TODO(amotoki): As mentioned in the above TODO,
            # we treat project_id and tenant_id equivalently.
            # This should be migrated to project_id in Ocata.
            if attr_name == 'tenant_id':
                attributes_to_exclude.append('project_id')

        return attributes_to_exclude
Ejemplo n.º 13
0
    def check_network_ports_by_binding_types(
            cls, context, network_id, binding_types, negative_search=False):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        """This method is to check whether networks have ports with given
        binding_types.

        :param context:
        :param network_id: ID of network to check
        :param binding_types: list of binding types to look for
        :param negative_search: if set to true, ports with with binding_type
                                other than "binding_types" will be counted
        :return: True if any port is found, False otherwise
        """
        query = context.session.query(models_v2.Port).join(
            ml2_models.PortBinding)
        query = query.filter(models_v2.Port.network_id == network_id)
        if negative_search:
            query = query.filter(
                ml2_models.PortBinding.vif_type.notin_(binding_types))
        else:
            query = query.filter(
                ml2_models.PortBinding.vif_type.in_(binding_types))
        return bool(query.count())
Ejemplo n.º 14
0
    def from_db_object(self, db_obj):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        super(Port, self).from_db_object(db_obj)
        # extract security group bindings
        if db_obj.get('security_groups', []):
            self.security_group_ids = {
                sg.security_group_id
                for sg in db_obj.security_groups
            }
        else:
            self.security_group_ids = set()
        fields_to_change = ['security_group_ids']

        # extract qos policy binding
        if db_obj.get('qos_policy_binding'):
            self.qos_policy_id = db_obj.qos_policy_binding.policy_id
            fields_to_change.append('qos_policy_id')
        if db_obj.get('qos_network_policy_binding'):
            self.qos_network_policy_id = (
                db_obj.qos_network_policy_binding.policy_id)
            fields_to_change.append('qos_network_policy_binding')

        self.obj_reset_changes(fields_to_change)
Ejemplo n.º 15
0
    def trunk_add_subports(self, tenant_id, trunk_id, sub_ports):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        """Add subports to the trunk.

        :param tenant_id: ID of the tenant.
        :param trunk_id: ID of the trunk.
        :param sub_ports: List of subport dictionaries to be added in format
                {'port_id': <ID of neutron port for subport>,
                 'segmentation_type': 'vlan',
                 'segmentation_id': <VLAN tag>}
        """
        spec = {
            'tenant_id': tenant_id,
            'sub_ports': sub_ports,
        }
        trunk = self.client.trunk_add_subports(trunk_id, spec)

        sub_ports_to_remove = [
            sub_port for sub_port in trunk['sub_ports']
            if sub_port in sub_ports]
        self.addCleanup(
            _safe_method(self.trunk_remove_subports), tenant_id, trunk_id,
            sub_ports_to_remove)
Ejemplo n.º 16
0
class QosMinimumBandwidthRule(model_base.HasId, model_base.BASEV2):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
             log_utils.get_fname(2))
    __tablename__ = 'qos_minimum_bandwidth_rules'
    qos_policy_id = sa.Column(sa.String(36),
                              sa.ForeignKey('qos_policies.id',
                                            ondelete='CASCADE'),
                              nullable=False,
                              index=True)
    min_kbps = sa.Column(sa.Integer)
    direction = sa.Column(sa.Enum(constants.EGRESS_DIRECTION,
                                  constants.INGRESS_DIRECTION,
                                  name='directions'),
                          nullable=False,
                          server_default=constants.EGRESS_DIRECTION)
    revises_on_change = ('qos_policy', )
    qos_policy = sa.orm.relationship(QosPolicy, load_on_pending=True)

    __table_args__ = (sa.UniqueConstraint(
        qos_policy_id,
        direction,
        name='qos_minimum_bandwidth_rules0qos_policy_id0direction'),
                      model_base.BASEV2.__table_args__)
Ejemplo n.º 17
0
 def install_dvr_dst_mac_for_arp(self, network_type, vlan_tag, gateway_mac,
                                 dvr_mac, rtr_port):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
              log_utils.get_fname(2))
     table_id = self._dvr_dst_mac_table_id(network_type)
     # Match the destination MAC with the DVR MAC
     (_dp, ofp, ofpp) = self._get_dp()
     match = self._arp_dvr_dst_mac_match(ofp, ofpp, vlan_tag, dvr_mac)
     # Incoming packet will come with destination MAC of DVR host MAC from
     # the ARP Responder. The Source MAC in this case will have the source
     # MAC of the port MAC that responded from the ARP responder.
     # So just remove the DVR host MAC from the 'eth_dst' and replace it
     # with the gateway-mac. The packet should end up in the right the table
     # for the packet to reach the router interface.
     actions = [
         ofpp.OFPActionSetField(eth_dst=gateway_mac),
         ofpp.OFPActionPopVlan(),
         ofpp.OFPActionOutput(rtr_port, 0)
     ]
     self.install_apply_actions(table_id=table_id,
                                priority=5,
                                match=match,
                                actions=actions)
Ejemplo n.º 18
0
 def provision_local_vlan(self, port, lvid, segmentation_id):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
              log_utils.get_fname(2))
     (_dp, ofp, ofpp) = self._get_dp()
     if segmentation_id is None:
         vlan_vid = ofp.OFPVID_NONE
         actions = [ofpp.OFPActionPushVlan()]
     else:
         vlan_vid = segmentation_id | ofp.OFPVID_PRESENT
         actions = []
     match = self._local_vlan_match(ofp, ofpp, port, vlan_vid)
     actions += [
         ofpp.OFPActionSetField(vlan_vid=lvid | ofp.OFPVID_PRESENT),
     ]
     instructions = [
         ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions),
         ofpp.OFPInstructionGotoTable(table_id=constants.TRANSIENT_TABLE),
     ]
     self.install_instructions(
         instructions=instructions,
         priority=3,
         match=match,
     )
Ejemplo n.º 19
0
def v2_factory(global_config, **local_config):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
    # Processing Order:
    #   As request enters lower priority called before higher.
    #   Response from controller is passed from higher priority to lower.
    app_hooks = [
        hooks.UserFilterHook(),  # priority 90
        hooks.ContextHook(),  # priority 95
        hooks.ExceptionTranslationHook(),  # priority 100
        hooks.BodyValidationHook(),  # priority 120
        hooks.OwnershipValidationHook(),  # priority 125
        hooks.QuotaEnforcementHook(),  # priority 130
        hooks.NotifierHook(),  # priority 135
        hooks.QueryParametersHook(),  # priority 139
        hooks.PolicyHook(),  # priority 140
    ]
    app = pecan.make_app(root.V2Controller(),
                         debug=True,
                         force_canonical=False,
                         hooks=app_hooks,
                         guess_content_type_from_ext=True)
    startup.initialize_all()
    return app
Ejemplo n.º 20
0
class RequestExtensionController(wsgi.Controller):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
             log_utils.get_fname(2))

    def __init__(self, application):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        self.application = application
        self.handlers = []

    def add_handler(self, handler):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        self.handlers.append(handler)

    def process(self, request, *args, **kwargs):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        res = request.get_response(self.application)
        # currently request handlers are un-ordered
        for handler in self.handlers:
            response = handler(request, res)
        return response
Ejemplo n.º 21
0
 def __init__(self,
              collection,
              resource,
              item,
              controller,
              collection_actions=None,
              member_actions=None,
              action_status=None):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
              log_utils.get_fname(2))
     super(ShimItemController,
           self).__init__(collection,
                          resource,
                          collection_actions=collection_actions,
                          member_actions=member_actions,
                          item=item,
                          action_status=action_status)
     self.controller = controller
     self.controller_delete = getattr(controller, 'delete', None)
     self.controller_update = getattr(controller, 'update', None)
     self.controller_show = getattr(controller, 'show', None)
     self.inverted_collection_actions = invert_dict(
         self._collection_actions)
Ejemplo n.º 22
0
class RootController(object):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))

    @utils.expose(generic=True)
    def index(self):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        version_objs = [
            {
                "id": "v2.0",
                "status": "CURRENT",
            },
        ]
        builder = versions_view.get_view_builder(pecan.request)
        versions = [builder.build(version) for version in version_objs]
        return dict(versions=versions)

    @utils.when(index, method='HEAD')
    @utils.when(index, method='POST')
    @utils.when(index, method='PATCH')
    @utils.when(index, method='PUT')
    @utils.when(index, method='DELETE')
    def not_supported(self):
        pecan.abort(405)
Ejemplo n.º 23
0
 def __init__(self,
              collection,
              controller,
              parent=None,
              path_prefix="",
              collection_actions=None,
              member_actions=None,
              attr_map=None,
              collection_methods=None):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
              log_utils.get_fname(2))
     collection_actions = collection_actions or {}
     collection_methods = collection_methods or {}
     member_actions = member_actions or {}
     attr_map = attr_map or {}
     self.collection = collection
     self.controller = controller
     self.parent = parent
     self.collection_actions = collection_actions
     self.collection_methods = collection_methods
     self.member_actions = member_actions
     self.path_prefix = path_prefix
     self.attr_map = attr_map
Ejemplo n.º 24
0
    def setup_host_with_linuxbridge_agent(self):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        # First we need to provide connectivity for agent to prepare proper
        # bridge mappings in agent's config:
        self.host_namespace = self.useFixture(
            net_helpers.NamespaceFixture(prefix="host-")
        ).name

        self.connect_namespace_to_control_network()

        agent_cfg_fixture = config.LinuxBridgeConfigFixture(
            self.env_desc, self.host_desc,
            self.neutron_config.temp_dir,
            self.local_ip,
            physical_device_name=self.host_port.name
        )
        self.useFixture(agent_cfg_fixture)

        self.linuxbridge_agent = self.useFixture(
            process.LinuxBridgeAgentFixture(
                self.env_desc, self.host_desc,
                self.test_name, self.neutron_config, agent_cfg_fixture,
                namespace=self.host_namespace
            )
        )

        if self.host_desc.l3_agent:
            self.l3_agent_cfg_fixture = self.useFixture(
                config.L3ConfigFixture(
                    self.env_desc, self.host_desc,
                    self.neutron_config.temp_dir))

        if self.host_desc.dhcp_agent:
            self.dhcp_agent_cfg_fixture = self.useFixture(
                config.DhcpConfigFixture(
                    self.env_desc, self.host_desc,
                    self.neutron_config.temp_dir))
Ejemplo n.º 25
0
    def setup_host_with_ovs_agent(self):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
        log_utils.log_qos_msg("sfssdfsdf")
        agent_cfg_fixture = config.OVSConfigFixture(
            self.env_desc, self.host_desc, self.neutron_config.temp_dir,
            self.local_ip, test_name=self.test_name)
        self.useFixture(agent_cfg_fixture)

        self.br_phys = self.useFixture(
            net_helpers.OVSBridgeFixture(
                agent_cfg_fixture.get_br_phys_name())).bridge
        if self.env_desc.tunneling_enabled:
            self.useFixture(
                net_helpers.OVSBridgeFixture(
                    agent_cfg_fixture.get_br_tun_name())).bridge
            self.connect_to_central_network_via_tunneling()
        else:
            self.connect_to_central_network_via_vlans(self.br_phys)

        self.ovs_agent = self.useFixture(
            process.OVSAgentFixture(
                self.env_desc, self.host_desc,
                self.test_name, self.neutron_config, agent_cfg_fixture))

        if self.host_desc.l3_agent:
            self.l3_agent_cfg_fixture = self.useFixture(
                config.L3ConfigFixture(
                    self.env_desc, self.host_desc,
                    self.neutron_config.temp_dir,
                    self.ovs_agent.agent_cfg_fixture.get_br_int_name()))

        if self.host_desc.dhcp_agent:
            self.dhcp_agent_cfg_fixture = self.useFixture(
                config.DhcpConfigFixture(
                    self.env_desc, self.host_desc,
                    self.neutron_config.temp_dir,
                    self.ovs_agent.agent_cfg_fixture.get_br_int_name()))
Ejemplo n.º 26
0
 def set_allowed_macs_for_port(self,
                               port,
                               mac_addresses=None,
                               allow_all=False):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
              log_utils.get_fname(2))
     if allow_all:
         self.uninstall_flows(table_id=constants.LOCAL_SWITCHING,
                              in_port=port)
         self.uninstall_flows(table_id=constants.MAC_SPOOF_TABLE,
                              in_port=port)
         return
     mac_addresses = mac_addresses or []
     for address in mac_addresses:
         self.install_goto(table_id=constants.MAC_SPOOF_TABLE,
                           priority=2,
                           eth_src=address,
                           in_port=port,
                           dest_table_id=constants.TRANSIENT_TABLE)
     # normalize so we can see if macs are the same
     mac_addresses = {netaddr.EUI(mac) for mac in mac_addresses}
     flows = self.dump_flows(constants.MAC_SPOOF_TABLE)
     for flow in flows:
         matches = dict(flow.match.items())
         if matches.get('in_port') != port:
             continue
         if not matches.get('eth_src'):
             continue
         flow_mac = matches['eth_src']
         if netaddr.EUI(flow_mac) not in mac_addresses:
             self.uninstall_flows(table_id=constants.MAC_SPOOF_TABLE,
                                  in_port=port,
                                  eth_src=flow_mac)
     self.install_goto(table_id=constants.LOCAL_SWITCHING,
                       priority=9,
                       in_port=port,
                       dest_table_id=constants.MAC_SPOOF_TABLE)
Ejemplo n.º 27
0
    def _get_dp(self):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        """Get (dp, ofp, ofpp) tuple for the switch.

        A convenient method for openflow message composers.
        """
        while True:
            if self._cached_dpid is None:
                dpid = self.get_datapath_id()
                LOG.info("Bridge %(br_name)s has datapath-ID %(dpid)s", {
                    "br_name": self.br_name,
                    "dpid": dpid
                })
                if dpid is None:
                    raise RuntimeError(_("Unknown datapath id."))
                self._cached_dpid = int(dpid, 16)
            try:
                dp = self._get_dp_by_dpid(self._cached_dpid)
                return dp, dp.ofproto, dp.ofproto_parser
            except RuntimeError:
                with excutils.save_and_reraise_exception() as ctx:
                    # Retry if dpid has been changed.
                    # NOTE(yamamoto): Open vSwitch change its dpid on
                    # some events.
                    # REVISIT(yamamoto): Consider to set dpid statically.
                    new_dpid = int(self.get_datapath_id(), 16)
                    if new_dpid != self._cached_dpid:
                        LOG.info(
                            "Bridge %(br_name)s changed its "
                            "datapath-ID from %(old)x to %(new)x", {
                                "br_name": self.br_name,
                                "old": self._cached_dpid,
                                "new": new_dpid,
                            })
                        ctx.reraise = False
                    self._cached_dpid = new_dpid
Ejemplo n.º 28
0
    def update_device_down(self, rpc_context, **kwargs):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        """Device no longer exists on agent."""
        # TODO(garyk) - live migration and port status
        agent_id, host, device = self._get_request_details(kwargs)
        LOG.debug(
            "Device %(device)s no longer exists at agent "
            "%(agent_id)s", {
                'device': device,
                'agent_id': agent_id
            })
        plugin = directory.get_plugin()
        port_id = plugin._device_to_port_id(rpc_context, device)
        port_exists = True
        if (host
                and not plugin.port_bound_to_host(rpc_context, port_id, host)):
            LOG.debug(
                "Device %(device)s not bound to the"
                " agent host %(host)s", {
                    'device': device,
                    'host': host
                })
        else:
            try:
                port_exists = bool(
                    plugin.update_port_status(rpc_context, port_id,
                                              n_const.PORT_STATUS_DOWN, host))
            except exc.StaleDataError:
                port_exists = False
                LOG.debug("delete_port and update_device_down are being "
                          "executed concurrently. Ignoring StaleDataError.")
                return {'device': device, 'exists': port_exists}
        self.notify_l2pop_port_wiring(port_id, rpc_context,
                                      n_const.PORT_STATUS_DOWN, host)

        return {'device': device, 'exists': port_exists}
Ejemplo n.º 29
0
    def update_device_list(self, rpc_context, **kwargs):
        LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
                 log_utils.get_fname(2))
        devices_up = []
        failed_devices_up = []
        devices_down = []
        failed_devices_down = []
        devices = kwargs.get('devices_up')
        if devices:
            for device in devices:
                try:
                    self.update_device_up(rpc_context, device=device, **kwargs)
                except Exception:
                    failed_devices_up.append(device)
                    LOG.error("Failed to update device %s up", device)
                else:
                    devices_up.append(device)

        devices = kwargs.get('devices_down')
        if devices:
            for device in devices:
                try:
                    dev = self.update_device_down(rpc_context,
                                                  device=device,
                                                  **kwargs)
                except Exception:
                    failed_devices_down.append(device)
                    LOG.error("Failed to update device %s down", device)
                else:
                    devices_down.append(dev)

        return {
            'devices_up': devices_up,
            'failed_devices_up': failed_devices_up,
            'devices_down': devices_down,
            'failed_devices_down': failed_devices_down
        }
Ejemplo n.º 30
0
def add_tc_filter_policy(device,
                         parent,
                         rate_kbps,
                         burst_kb,
                         mtu,
                         action,
                         priority=0,
                         protocol=None,
                         namespace=None):
    LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
             log_utils.get_fname(2))
    """Add a TC filter in a device to set a policy.

    :param device: (string) device name
    :param parent: (string) qdisc parent class ('root', 'ingress', '2:10')
    :param rate_kbps: (int) rate in kbits/second
    :param burst_kb: (int) burst in kbits
    :param mtu: (int) MTU size (bytes)
    :param action: (string) filter policy action
    :param priority: (int) (optional) filter priority (lower priority, higher
                     preference)
    :param protocol: (int) (optional) traffic filter protocol; if None, all
                     will be matched.
    :param namespace: (string) (optional) namespace name

    """
    rate = int(rate_kbps * 1024 / 8)
    burst = int(burst_kb * 1024 / 8)
    priv_tc_lib.add_tc_filter_policy(device,
                                     parent,
                                     priority,
                                     rate,
                                     burst,
                                     mtu,
                                     action,
                                     protocol=protocol,
                                     namespace=namespace)