summaryrefslogtreecommitdiffstats
path: root/build/neutron-patch-NSDriver.patch
blob: d5889e38a37ac8ae0d239504e51d96675f085a76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
From ff4e918d21970a81604a0aaa2af888141f93cdac Mon Sep 17 00:00:00 2001
From: Feng Pan <fpan@redhat.com>
Date: Sun, 5 Feb 2017 21:34:19 -0500
Subject: [PATCH] Add NSDriver

---
 neutron/agent/l3/namespaces.py   |  6 ++--
 neutron/agent/l3/router_info.py  | 14 ++++----
 neutron/agent/linux/interface.py | 76 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/neutron/agent/l3/namespaces.py b/neutron/agent/l3/namespaces.py
index e70d7bb..3c932a8 100644
--- a/neutron/agent/l3/namespaces.py
+++ b/neutron/agent/l3/namespaces.py
@@ -18,6 +18,7 @@ import functools
 from oslo_log import log as logging
 from oslo_utils import excutils
 
+from neutron.agent.linux.interface import OVSInterfaceDriver
 from neutron._i18n import _LE, _LW
 from neutron.agent.linux import ip_lib
 
@@ -110,8 +111,9 @@ class Namespace(object):
 
 class RouterNamespace(Namespace):
 
-    def __init__(self, router_id, agent_conf, driver, use_ipv6):
+    def __init__(self, router_id, agent_conf, driver, use_ipv6, ovs_driver):
         self.router_id = router_id
+        self.ovs_driver = ovs_driver
         name = self._get_ns_name(router_id)
         super(RouterNamespace, self).__init__(
             name, agent_conf, driver, use_ipv6)
@@ -131,7 +133,7 @@ class RouterNamespace(Namespace):
             elif d.name.startswith(ROUTER_2_FIP_DEV_PREFIX):
                 ns_ip.del_veth(d.name)
             elif d.name.startswith(EXTERNAL_DEV_PREFIX):
-                self.driver.unplug(
+                self.ovs_driver.unplug(
                     d.name,
                     bridge=self.agent_conf.external_network_bridge,
                     namespace=self.name,
diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py
index 3fd3934..b33fb7e 100644
--- a/neutron/agent/l3/router_info.py
+++ b/neutron/agent/l3/router_info.py
@@ -27,6 +27,7 @@ from neutron.common import exceptions as n_exc
 from neutron.common import ipv6_utils
 from neutron.common import utils as common_utils
 from neutron.ipam import utils as ipam_utils
+from neutron.agent.linux.interface import OVSInterfaceDriver
 
 LOG = logging.getLogger(__name__)
 INTERNAL_DEV_PREFIX = namespaces.INTERNAL_DEV_PREFIX
@@ -47,6 +48,7 @@ class RouterInfo(object):
                  agent_conf,
                  interface_driver,
                  use_ipv6=False):
+        self.ovs_driver = OVSInterfaceDriver(agent_conf)
         self.router_id = router_id
         self.ex_gw_port = None
         self._snat_enabled = None
@@ -57,7 +59,7 @@ class RouterInfo(object):
         self.router = router
         self.use_ipv6 = use_ipv6
         ns = self.create_router_namespace_object(
-            router_id, agent_conf, interface_driver, use_ipv6)
+            router_id, agent_conf, interface_driver, use_ipv6, self.ovs_driver)
         self.router_namespace = ns
         self.ns_name = ns.name
         self.available_mark_ids = set(range(ADDRESS_SCOPE_MARK_ID_MIN,
@@ -94,9 +96,9 @@ class RouterInfo(object):
         self.router_namespace.create()
 
     def create_router_namespace_object(
-            self, router_id, agent_conf, iface_driver, use_ipv6):
+            self, router_id, agent_conf, iface_driver, use_ipv6, ovs_driver):
         return namespaces.RouterNamespace(
-            router_id, agent_conf, iface_driver, use_ipv6)
+            router_id, agent_conf, iface_driver, use_ipv6, ovs_driver)
 
     @property
     def router(self):
@@ -583,7 +585,7 @@ class RouterInfo(object):
                 for ip in floating_ips]
 
     def _plug_external_gateway(self, ex_gw_port, interface_name, ns_name):
-        self.driver.plug(ex_gw_port['network_id'],
+        self.ovs_driver.plug(ex_gw_port['network_id'],
                          ex_gw_port['id'],
                          interface_name,
                          ex_gw_port['mac_address'],
@@ -641,7 +643,7 @@ class RouterInfo(object):
 
         self._add_route_to_gw(ex_gw_port, device_name=interface_name,
                               namespace=ns_name, preserve_ips=preserve_ips)
-        self.driver.init_router_port(
+        self.ovs_driver.init_router_port(
             interface_name,
             ip_cidrs,
             namespace=ns_name,
@@ -735,7 +737,7 @@ class RouterInfo(object):
         for stale_dev in stale_devs:
             LOG.debug('Deleting stale external router device: %s', stale_dev)
             pd.remove_gw_interface(self.router['id'])
-            self.driver.unplug(stale_dev,
+            self.ovs_driver.unplug(stale_dev,
                                bridge=self.agent_conf.external_network_bridge,
                                namespace=self.ns_name,
                                prefix=EXTERNAL_DEV_PREFIX)
diff --git a/neutron/agent/linux/interface.py b/neutron/agent/linux/interface.py
index c2eb06e..80da16f 100644
--- a/neutron/agent/linux/interface.py
+++ b/neutron/agent/linux/interface.py
@@ -15,7 +15,7 @@
 
 import abc
 import time
-
+import eventlet
 import netaddr
 from neutron_lib import constants
 from oslo_config import cfg
@@ -288,6 +288,80 @@ class NullDriver(LinuxInterfaceDriver):
     def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
         pass
 
+class NSDriver(LinuxInterfaceDriver):
+    """Device independent driver enabling creation of a non device specific
+    interface in network spaces.  Attachment to the device is not performed.
+    """
+    MAX_TIME_FOR_DEVICE_EXISTENCE = 30
+
+    @classmethod
+    def _device_is_created_in_time(cls, device_name):
+        """See if device is created, within time limit."""
+        attempt = 0
+        while attempt < NSDriver.MAX_TIME_FOR_DEVICE_EXISTENCE:
+            if ip_lib.device_exists(device_name):
+                return True
+            attempt += 1
+            eventlet.sleep(1)
+        LOG.error(_LE("Device %(dev)s was not created in %(time)d seconds"),
+                  {'dev': device_name,
+                   'time': NSDriver.MAX_TIME_FOR_DEVICE_EXISTENCE})
+        return False
+
+    def _configure_mtu(self, ns_dev, mtu=None):
+        # Need to set MTU, after added to namespace. See review
+        # https://review.openstack.org/327651
+        try:
+            # Note: network_device_mtu will be deprecated in future
+            mtu_override = self.conf.network_device_mtu
+        except cfg.NoSuchOptError:
+            LOG.warning(_LW("Config setting for MTU deprecated - any "
+                            "override will be ignored."))
+            mtu_override = None
+        if mtu_override:
+            mtu = mtu_override
+            LOG.debug("Overriding MTU to %d", mtu)
+        if mtu:
+            ns_dev.link.set_mtu(mtu)
+        else:
+            LOG.debug("No MTU provided - skipping setting value")
+
+    def plug(self, network_id, port_id, device_name, mac_address,
+             bridge=None, namespace=None, prefix=None, mtu=None):
+
+        # Overriding this, we still want to add an existing device into the
+        # namespace.
+        self.plug_new(network_id, port_id, device_name, mac_address,
+                      bridge, namespace, prefix, mtu)
+
+    def plug_new(self, network_id, port_id, device_name, mac_address,
+                 bridge=None, namespace=None, prefix=None, mtu=None):
+
+        ip = ip_lib.IPWrapper()
+        ns_dev = ip.device(device_name)
+
+        LOG.debug("Plugging dev: '%s' into namespace: '%s' ",
+                  device_name, namespace)
+
+        # Wait for device creation
+        if not self._device_is_created_in_time(device_name):
+            return
+
+        ns_dev.link.set_address(mac_address)
+
+        if namespace:
+            namespace_obj = ip.ensure_namespace(namespace)
+            namespace_obj.add_device_to_namespace(ns_dev)
+
+        self._configure_mtu(ns_dev, mtu)
+
+        ns_dev.link.set_up()
+
+    def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
+        # Device removal is done externally. Just remove the namespace
+        LOG.debug("Removing namespace: '%s'", namespace)
+        ip_lib.IPWrapper(namespace).garbage_collect_namespace()
+
 
 class OVSInterfaceDriver(LinuxInterfaceDriver):
     """Driver for creating an internal interface on an OVS bridge."""
diff --git a/neutron/agent/l3/ha_router.py b/usr/lib/python2.7/site-packages/neutron/agent/l3/ha_router.py
index ca0e50d..2c4fdad 100644
--- a/neutron/agent/l3/ha_router.py
+++ b/usr/lib/python2.7/site-packages/neutron/agent/l3/ha_router.py
@@ -52,15 +52,14 @@ class HaRouterNamespace(namespaces.RouterNamespace):
 class HaRouter(router.RouterInfo):
     def __init__(self, state_change_callback, *args, **kwargs):
         super(HaRouter, self).__init__(*args, **kwargs)
-
         self.ha_port = None
         self.keepalived_manager = None
         self.state_change_callback = state_change_callback
 
     def create_router_namespace_object(
-            self, router_id, agent_conf, iface_driver, use_ipv6):
+            self, router_id, agent_conf, iface_driver, use_ipv6, ovs_driver):
         return HaRouterNamespace(
-            router_id, agent_conf, iface_driver, use_ipv6)
+            router_id, agent_conf, iface_driver, use_ipv6, ovs_driver)
 
     @property
     def ha_priority(self):

-- 
2.9.3