1 From ff4e918d21970a81604a0aaa2af888141f93cdac Mon Sep 17 00:00:00 2001
2 From: Feng Pan <fpan@redhat.com>
3 Date: Sun, 5 Feb 2017 21:34:19 -0500
4 Subject: [PATCH] Add NSDriver
7 neutron/agent/l3/namespaces.py | 6 ++--
8 neutron/agent/l3/router_info.py | 14 ++++----
9 neutron/agent/linux/interface.py | 76 +++++++++++++++++++++++++++++++++++++++-
10 3 files changed, 87 insertions(+), 9 deletions(-)
12 diff --git a/neutron/agent/l3/namespaces.py b/neutron/agent/l3/namespaces.py
13 index e70d7bb..3c932a8 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 @@ -131,7 +133,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 3fd3934..b33fb7e 100644
46 --- a/neutron/agent/l3/router_info.py
47 +++ b/neutron/agent/l3/router_info.py
48 @@ -27,6 +27,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 @@ -47,6 +48,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 @@ -57,7 +59,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 @@ -94,9 +96,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 @@ -583,7 +585,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 @@ -641,7 +643,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 @@ -735,7 +737,7 @@ class RouterInfo(object):
104 for stale_dev in stale_devs:
105 LOG.debug('Deleting stale external router device: %s', stale_dev)
106 pd.remove_gw_interface(self.router['id'])
107 - self.driver.unplug(stale_dev,
108 + self.ovs_driver.unplug(stale_dev,
109 bridge=self.agent_conf.external_network_bridge,
110 namespace=self.ns_name,
111 prefix=EXTERNAL_DEV_PREFIX)
112 diff --git a/neutron/agent/linux/interface.py b/neutron/agent/linux/interface.py
113 index c2eb06e..80da16f 100644
114 --- a/neutron/agent/linux/interface.py
115 +++ b/neutron/agent/linux/interface.py
123 from neutron_lib import constants
124 from oslo_config import cfg
125 @@ -288,6 +288,80 @@ class NullDriver(LinuxInterfaceDriver):
126 def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
129 +class NSDriver(LinuxInterfaceDriver):
130 + """Device independent driver enabling creation of a non device specific
131 + interface in network spaces. Attachment to the device is not performed.
133 + MAX_TIME_FOR_DEVICE_EXISTENCE = 30
136 + def _device_is_created_in_time(cls, device_name):
137 + """See if device is created, within time limit."""
139 + while attempt < NSDriver.MAX_TIME_FOR_DEVICE_EXISTENCE:
140 + if ip_lib.device_exists(device_name):
144 + LOG.error(_LE("Device %(dev)s was not created in %(time)d seconds"),
145 + {'dev': device_name,
146 + 'time': NSDriver.MAX_TIME_FOR_DEVICE_EXISTENCE})
149 + def _configure_mtu(self, ns_dev, mtu=None):
150 + # Need to set MTU, after added to namespace. See review
151 + # https://review.openstack.org/327651
153 + # Note: network_device_mtu will be deprecated in future
154 + mtu_override = self.conf.network_device_mtu
155 + except cfg.NoSuchOptError:
156 + LOG.warning(_LW("Config setting for MTU deprecated - any "
157 + "override will be ignored."))
158 + mtu_override = None
161 + LOG.debug("Overriding MTU to %d", mtu)
163 + ns_dev.link.set_mtu(mtu)
165 + LOG.debug("No MTU provided - skipping setting value")
167 + def plug(self, network_id, port_id, device_name, mac_address,
168 + bridge=None, namespace=None, prefix=None, mtu=None):
170 + # Overriding this, we still want to add an existing device into the
172 + self.plug_new(network_id, port_id, device_name, mac_address,
173 + bridge, namespace, prefix, mtu)
175 + def plug_new(self, network_id, port_id, device_name, mac_address,
176 + bridge=None, namespace=None, prefix=None, mtu=None):
178 + ip = ip_lib.IPWrapper()
179 + ns_dev = ip.device(device_name)
181 + LOG.debug("Plugging dev: '%s' into namespace: '%s' ",
182 + device_name, namespace)
184 + # Wait for device creation
185 + if not self._device_is_created_in_time(device_name):
188 + ns_dev.link.set_address(mac_address)
191 + namespace_obj = ip.ensure_namespace(namespace)
192 + namespace_obj.add_device_to_namespace(ns_dev)
194 + self._configure_mtu(ns_dev, mtu)
196 + ns_dev.link.set_up()
198 + def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
199 + # Device removal is done externally. Just remove the namespace
200 + LOG.debug("Removing namespace: '%s'", namespace)
201 + ip_lib.IPWrapper(namespace).garbage_collect_namespace()
204 class OVSInterfaceDriver(LinuxInterfaceDriver):
205 """Driver for creating an internal interface on an OVS bridge."""
206 diff --git a/neutron/agent/l3/ha_router.py b/usr/lib/python2.7/site-packages/neutron/agent/l3/ha_router.py
207 index ca0e50d..2c4fdad 100644
208 --- a/neutron/agent/l3/ha_router.py
209 +++ b/usr/lib/python2.7/site-packages/neutron/agent/l3/ha_router.py
210 @@ -52,15 +52,14 @@ class HaRouterNamespace(namespaces.RouterNamespace):
211 class HaRouter(router.RouterInfo):
212 def __init__(self, state_change_callback, *args, **kwargs):
213 super(HaRouter, self).__init__(*args, **kwargs)
216 self.keepalived_manager = None
217 self.state_change_callback = state_change_callback
219 def create_router_namespace_object(
220 - self, router_id, agent_conf, iface_driver, use_ipv6):
221 + self, router_id, agent_conf, iface_driver, use_ipv6, ovs_driver):
222 return HaRouterNamespace(
223 - router_id, agent_conf, iface_driver, use_ipv6)
224 + router_id, agent_conf, iface_driver, use_ipv6, ovs_driver)
227 def ha_priority(self):