summaryrefslogtreecommitdiffstats
path: root/build/patches/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
puting similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=no [SPELLING] # Spelling dictionary name. Available dictionaries: none. To make it working # install python-enchant package. spelling-dict= # List of comma separated words that should not be checked. spelling-ignore-words= # A path to a file that contains private dictionary; one word per line. spelling-private-dict-file= # Tells whether to store unknown words to indicated private dictionary in # --spelling-private-dict-file option instead of raising a message. spelling-store-unknown-words=no [TYPECHECK] # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis ignored-modules= # List of classes names for which member attributes should not be checked # (useful for classes with attributes dynamically set). ignored-classes=SQLObject # When zope mode is activated, add a predefined set of Zope acquired attributes # to generated-members. zope=no # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E0201 when accessed. Python regular # expressions are accepted. generated-members=REQUEST,acl_users,aq_parent [VARIABLES] # Tells whether we should check for unused import in __init__ files. init-import=no # A regular expression matching the name of dummy variables (i.e. expectedly # not used). dummy-variables-rgx=_$|dummy # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= # List of strings which can identify a callback function by name. A callback # name must start or end with one of those strings. callbacks=cb_,_cb [CLASSES] # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=mcs # List of member names, which should be excluded from the protected access # warning. exclude-protected=_asdict,_fields,_replace,_source,_make [DESIGN] # Maximum number of arguments for function / method max-args=6 # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.* # Maximum number of locals for function / method body max-locals=20 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of branch for function / method body max-branches=15 # Maximum number of statements in function / method body max-statements=70 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=15 # Minimum number of public methods for a class (see R0903). min-public-methods=2 # Maximum number of public methods for a class (see R0904). max-public-methods=20 [IMPORTS] # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception" overgeneral-exceptions=Exception