1 From d51e6ba77c3f40c7c04c97b1de06bf9344c95929 Mon Sep 17 00:00:00 2001
2 From: Feng Pan <fpan@redhat.com>
3 Date: Thu, 20 Jul 2017 16:12:45 -0400
4 Subject: [PATCH] Add NSDriver
7 neutron/agent/l3/namespaces.py | 6 ++--
8 neutron/agent/l3/router_info.py | 12 ++++---
9 neutron/agent/linux/interface.py | 76 +++++++++++++++++++++++++++++++++++++++-
10 3 files changed, 86 insertions(+), 8 deletions(-)
12 diff --git a/neutron/agent/l3/namespaces.py b/neutron/agent/l3/namespaces.py
13 index f65c706..e9fc4b7 100644
14 --- a/neutron/agent/l3/namespaces.py
15 +++ b/neutron/agent/l3/namespaces.py
16 @@ -18,6 +18,7 @@ import functools
17 from oslo_log import log as logging
18 from oslo_utils import excutils
20 +from neutron.agent.linux.interface import OVSInterfaceDriver
21 from neutron._i18n import _LE, _LW
22 from neutron.agent.linux import ip_lib
24 @@ -110,8 +111,9 @@ class Namespace(object):
26 class RouterNamespace(Namespace):
28 - def __init__(self, router_id, agent_conf, driver, use_ipv6):
29 + def __init__(self, router_id, agent_conf, driver, use_ipv6, ovs_driver):
30 self.router_id = router_id
31 + self.ovs_driver = ovs_driver
32 name = self._get_ns_name(router_id)
33 super(RouterNamespace, self).__init__(
34 name, agent_conf, driver, use_ipv6)
35 @@ -132,7 +134,7 @@ class RouterNamespace(Namespace):
36 elif d.name.startswith(ROUTER_2_FIP_DEV_PREFIX):
37 ns_ip.del_veth(d.name)
38 elif d.name.startswith(EXTERNAL_DEV_PREFIX):
40 + self.ovs_driver.unplug(
42 bridge=self.agent_conf.external_network_bridge,
44 diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py
45 index 46db6a5..6775882 100644
46 --- a/neutron/agent/l3/router_info.py
47 +++ b/neutron/agent/l3/router_info.py
48 @@ -30,6 +30,7 @@ from neutron.common import exceptions as n_exc
49 from neutron.common import ipv6_utils
50 from neutron.common import utils as common_utils
51 from neutron.ipam import utils as ipam_utils
52 +from neutron.agent.linux.interface import OVSInterfaceDriver
54 LOG = logging.getLogger(__name__)
55 INTERNAL_DEV_PREFIX = namespaces.INTERNAL_DEV_PREFIX
56 @@ -52,6 +53,7 @@ class RouterInfo(object):
60 + self.ovs_driver = OVSInterfaceDriver(agent_conf)
61 self.router_id = router_id
62 self.ex_gw_port = None
63 self._snat_enabled = None
64 @@ -63,7 +65,7 @@ class RouterInfo(object):
66 self.use_ipv6 = use_ipv6
67 ns = self.create_router_namespace_object(
68 - router_id, agent_conf, interface_driver, use_ipv6)
69 + router_id, agent_conf, interface_driver, use_ipv6, self.ovs_driver)
70 self.router_namespace = ns
71 self.ns_name = ns.name
72 self.available_mark_ids = set(range(ADDRESS_SCOPE_MARK_ID_MIN,
73 @@ -100,9 +102,9 @@ class RouterInfo(object):
74 self.router_namespace.create()
76 def create_router_namespace_object(
77 - self, router_id, agent_conf, iface_driver, use_ipv6):
78 + self, router_id, agent_conf, iface_driver, use_ipv6, ovs_driver):
79 return namespaces.RouterNamespace(
80 - router_id, agent_conf, iface_driver, use_ipv6)
81 + router_id, agent_conf, iface_driver, use_ipv6, ovs_driver)
85 @@ -609,7 +611,7 @@ class RouterInfo(object):
86 for ip in floating_ips]
88 def _plug_external_gateway(self, ex_gw_port, interface_name, ns_name):
89 - self.driver.plug(ex_gw_port['network_id'],
90 + self.ovs_driver.plug(ex_gw_port['network_id'],
93 ex_gw_port['mac_address'],
94 @@ -679,7 +681,7 @@ class RouterInfo(object):
96 self._add_route_to_gw(ex_gw_port, device_name=interface_name,
97 namespace=ns_name, preserve_ips=preserve_ips)
98 - self.driver.init_router_port(
99 + self.ovs_driver.init_router_port(
103 diff --git a/neutron/agent/linux/interface.py b/neutron/agent/linux/interface.py
104 index 1f1ed39..b7781e2 100644
105 --- a/neutron/agent/linux/interface.py
106 +++ b/neutron/agent/linux/interface.py
114 from neutron_lib import constants
115 from oslo_config import cfg
116 @@ -317,6 +317,80 @@ class NullDriver(LinuxInterfaceDriver):
117 def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
120 +class NSDriver(LinuxInterfaceDriver):
121 + """Device independent driver enabling creation of a non device specific
122 + interface in network spaces. Attachment to the device is not performed.
124 + MAX_TIME_FOR_DEVICE_EXISTENCE = 30
127 + def _device_is_created_in_time(cls, device_name):
128 + """See if device is created, within time limit."""
130 + while attempt < NSDriver.MAX_TIME_FOR_DEVICE_EXISTENCE:
131 + if ip_lib.device_exists(device_name):
135 + LOG.error(_LE("Device %(dev)s was not created in %(time)d seconds"),
136 + {'dev': device_name,
137 + 'time': NSDriver.MAX_TIME_FOR_DEVICE_EXISTENCE})
140 + def _configure_mtu(self, ns_dev, mtu=None):
141 + # Need to set MTU, after added to namespace. See review
142 + # https://review.openstack.org/327651
144 + # Note: network_device_mtu will be deprecated in future
145 + mtu_override = self.conf.network_device_mtu
146 + except cfg.NoSuchOptError:
147 + LOG.warning(_LW("Config setting for MTU deprecated - any "
148 + "override will be ignored."))
149 + mtu_override = None
152 + LOG.debug("Overriding MTU to %d", mtu)
154 + ns_dev.link.set_mtu(mtu)
156 + LOG.debug("No MTU provided - skipping setting value")
158 + def plug(self, network_id, port_id, device_name, mac_address,
159 + bridge=None, namespace=None, prefix=None, mtu=None):
161 + # Overriding this, we still want to add an existing device into the
163 + self.plug_new(network_id, port_id, device_name, mac_address,
164 + bridge, namespace, prefix, mtu)
166 + def plug_new(self, network_id, port_id, device_name, mac_address,
167 + bridge=None, namespace=None, prefix=None, mtu=None):
169 + ip = ip_lib.IPWrapper()
170 + ns_dev = ip.device(device_name)
172 + LOG.debug("Plugging dev: '%s' into namespace: '%s' ",
173 + device_name, namespace)
175 + # Wait for device creation
176 + if not self._device_is_created_in_time(device_name):
179 + ns_dev.link.set_address(mac_address)
182 + namespace_obj = ip.ensure_namespace(namespace)
183 + namespace_obj.add_device_to_namespace(ns_dev)
185 + self._configure_mtu(ns_dev, mtu)
187 + ns_dev.link.set_up()
189 + def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
190 + # Device removal is done externally. Just remove the namespace
191 + LOG.debug("Removing namespace: '%s'", namespace)
192 + ip_lib.IPWrapper(namespace).garbage_collect_namespace()
195 class OVSInterfaceDriver(LinuxInterfaceDriver):
196 """Driver for creating an internal interface on an OVS bridge."""