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
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)
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()
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'])
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)
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)
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']
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')
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
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)
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
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
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())
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)
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)
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__)
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)
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, )
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
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
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)
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)
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
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))
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()))
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)
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
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}
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 }
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)