Merge "nosdn-fdio scenarios fixes"
[apex.git] / build / patches / neutron-patch-NSDriver.patch
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
5
6 ---
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(-)
11
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
19  
20 +from neutron.agent.linux.interface import OVSInterfaceDriver
21  from neutron._i18n import _LE, _LW
22  from neutron.agent.linux import ip_lib
23  
24 @@ -110,8 +111,9 @@ class Namespace(object):
25  
26  class RouterNamespace(Namespace):
27  
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):
39 -                self.driver.unplug(
40 +                self.ovs_driver.unplug(
41                      d.name,
42                      bridge=self.agent_conf.external_network_bridge,
43                      namespace=self.name,
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
53  
54  LOG = logging.getLogger(__name__)
55  INTERNAL_DEV_PREFIX = namespaces.INTERNAL_DEV_PREFIX
56 @@ -52,6 +53,7 @@ class RouterInfo(object):
57                   interface_driver,
58                   use_ipv6=False):
59          self.agent = agent
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):
65          self.router = router
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()
75  
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)
82  
83      @property
84      def router(self):
85 @@ -609,7 +611,7 @@ class RouterInfo(object):
86                  for ip in floating_ips]
87  
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'],
91                           ex_gw_port['id'],
92                           interface_name,
93                           ex_gw_port['mac_address'],
94 @@ -679,7 +681,7 @@ class RouterInfo(object):
95  
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(
100              interface_name,
101              ip_cidrs,
102              namespace=ns_name,
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
107 @@ -15,7 +15,7 @@
108  
109  import abc
110  import time
111 -
112 +import eventlet
113  import netaddr
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):
118          pass
119  
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.
123 +    """
124 +    MAX_TIME_FOR_DEVICE_EXISTENCE = 30
125 +
126 +    @classmethod
127 +    def _device_is_created_in_time(cls, device_name):
128 +        """See if device is created, within time limit."""
129 +        attempt = 0
130 +        while attempt < NSDriver.MAX_TIME_FOR_DEVICE_EXISTENCE:
131 +            if ip_lib.device_exists(device_name):
132 +                return True
133 +            attempt += 1
134 +            eventlet.sleep(1)
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})
138 +        return False
139 +
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
143 +        try:
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
150 +        if mtu_override:
151 +            mtu = mtu_override
152 +            LOG.debug("Overriding MTU to %d", mtu)
153 +        if mtu:
154 +            ns_dev.link.set_mtu(mtu)
155 +        else:
156 +            LOG.debug("No MTU provided - skipping setting value")
157 +
158 +    def plug(self, network_id, port_id, device_name, mac_address,
159 +             bridge=None, namespace=None, prefix=None, mtu=None):
160 +
161 +        # Overriding this, we still want to add an existing device into the
162 +        # namespace.
163 +        self.plug_new(network_id, port_id, device_name, mac_address,
164 +                      bridge, namespace, prefix, mtu)
165 +
166 +    def plug_new(self, network_id, port_id, device_name, mac_address,
167 +                 bridge=None, namespace=None, prefix=None, mtu=None):
168 +
169 +        ip = ip_lib.IPWrapper()
170 +        ns_dev = ip.device(device_name)
171 +
172 +        LOG.debug("Plugging dev: '%s' into namespace: '%s' ",
173 +                  device_name, namespace)
174 +
175 +        # Wait for device creation
176 +        if not self._device_is_created_in_time(device_name):
177 +            return
178 +
179 +        ns_dev.link.set_address(mac_address)
180 +
181 +        if namespace:
182 +            namespace_obj = ip.ensure_namespace(namespace)
183 +            namespace_obj.add_device_to_namespace(ns_dev)
184 +
185 +        self._configure_mtu(ns_dev, mtu)
186 +
187 +        ns_dev.link.set_up()
188 +
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()
193 +
194  
195  class OVSInterfaceDriver(LinuxInterfaceDriver):
196      """Driver for creating an internal interface on an OVS bridge."""
197 -- 
198 2.9.3
199