Browse Source

OSP-217: handle iptable remove/refresh filter correctly

 - as per previous code, refresh_firewall and remove_device_filter
   would try to remove the iptable chain/rule for misnamed device_id
 - this adds proper overrides to handle those methods
 - also updates service file to pick up the ml2_conf.ini, without
   which, firewall_driver is not set and causes runtime issues

Change-Id: Ie71a125677b015505c50566cc4de571e19b97f91
tags/14.0.0
Aditya Prakash Vaja 3 months ago
parent
commit
64356dcafe

+ 56
- 19
networking_bigswitch/plugins/bigswitch/agent/restproxy_agent.py View File

@@ -29,9 +29,9 @@ from oslo_config import cfg
29 29
 from oslo_log import log
30 30
 from oslo_service import loopingcall
31 31
 from oslo_utils import excutils
32
-from oslo_utils import importutils
33 32
 
34 33
 from networking_bigswitch.plugins.bigswitch import config as pl_config
34
+from networking_bigswitch.plugins.bigswitch.i18n import _LI
35 35
 from neutron.agent.common import ovs_lib
36 36
 from neutron.agent.linux import utils
37 37
 from neutron.agent import rpc as agent_rpc
@@ -42,6 +42,7 @@ from neutron.extensions import securitygroup as ext_sg
42 42
 
43 43
 eventlet.monkey_patch()
44 44
 
45
+
45 46
 IVS_PORT_MTU = 9000
46 47
 IVS_VM_PORT_PREFIX = 'qvo'
47 48
 IVS_VM_PORT_IFACE_PREFIXES = [IVS_VM_PORT_PREFIX, 'qvb', 'tap', 'qbr']
@@ -136,21 +137,30 @@ class NFVSwitchBridge(object):
136 137
 
137 138
 
138 139
 class FilterDeviceIDMixin(sg_rpc.SecurityGroupAgentRpc):
140
+    """Override SecurityGroupAgentRpc methods that call firewall_driver.
141
+
142
+    This is to ensure that device ID sent to firewall driver is always without
143
+    any prefixes. Since the firewall_driver adds the prefix regardless of
144
+    whether it already has or not AND when reading local maps/dicts in
145
+    firewall driver, it tries to match the start of device ID _without_ prefix,
146
+    it fails and goes in an inconsistent state when adding and removing
147
+    interfaces and doing firewall operations.
139 148
 
140
-    def init_firewall(self, defer_refresh_firewall=False,
141
-                      integration_bridge=None):
142
-        super(FilterDeviceIDMixin, self).init_firewall(defer_refresh_firewall,
143
-                                                       integration_bridge)
144
-        firewall_driver = ('neutron.agent.linux.iptables_firewall.'
145
-                           'OVSHybridIptablesFirewallDriver')
146
-        self.firewall = importutils.import_object(firewall_driver)
149
+    Hence the name FilterDeviceIDMixin :)
150
+
151
+    """
147 152
 
148 153
     def prepare_devices_filter(self, device_ids):
149 154
         if not device_ids:
150 155
             return
156
+        LOG.info(_LI("Preparing filters for devices %r"), device_ids)
157
+        self._apply_port_filter(device_ids)
158
+
159
+    def _apply_port_filter(self, device_ids, update_filter=False):
151 160
         # use tap as a prefix because ml2 is hard-coded to expect that
152 161
         device_ids = [d.replace('qvo', 'tap') for d in device_ids]
153
-        LOG.info("Preparing filters for devices %s", device_ids)
162
+        LOG.info(_LI("Applying port filter for devices %r"), device_ids)
163
+
154 164
         if self.use_enhanced_rpc:
155 165
             devices_info = self.plugin_rpc.security_group_info_for_devices(
156 166
                 self.context, list(device_ids))
@@ -162,21 +172,48 @@ class FilterDeviceIDMixin(sg_rpc.SecurityGroupAgentRpc):
162 172
                 self.context, list(device_ids))
163 173
 
164 174
         with self.firewall.defer_apply():
165
-            for device in devices.values():
166
-                # strip tap back off since prepare_port_filter will apply it
167
-                device['device'] = device['device'].replace('tap', '')
168
-                # fuel backport fix with conntrack,
169
-                # which may not exist in other installers
170
-                try:
171
-                    self.set_local_zone(device)
172
-                except AttributeError:
173
-                    LOG.debug("set_local_zone is not defined.")
174
-                self.firewall.prepare_port_filter(device)
175 175
             if self.use_enhanced_rpc:
176 176
                 LOG.debug("Update security group information for ports %s",
177 177
                           list(devices.keys()))
178 178
                 self._update_security_group_info(
179 179
                     security_groups, security_group_member_ips)
180
+            for device in devices.values():
181
+                # strip off 'tap' prefix from device. all calls to
182
+                # self.firewall i.e. firewall_driver must pass plain device-id
183
+                # without annotations. firewall_driver adds the appropriate
184
+                # prefix
185
+                device['device'] = device['device'].replace('tap', '')
186
+                if update_filter:
187
+                    LOG.debug("Update port filter for %s", device['device'])
188
+                    self.firewall.update_port_filter(device)
189
+                else:
190
+                    LOG.debug("Prepare port filter for %s", device['device'])
191
+                    self.firewall.prepare_port_filter(device)
192
+
193
+    def refresh_firewall(self, device_ids=None):
194
+        LOG.info(_LI("Refresh firewall rules"))
195
+        if not device_ids:
196
+            device_ids = self.firewall.ports.keys()
197
+            if not device_ids:
198
+                LOG.info(_LI("No ports here to refresh firewall"))
199
+                return
200
+        self._apply_port_filter(device_ids, update_filter=True)
201
+
202
+    def remove_devices_filter(self, device_ids):
203
+        if not device_ids:
204
+            return
205
+        # strip off 'qvo' prefix from device. all calls to
206
+        # self.firewall i.e. firewall_driver must pass plain device-id
207
+        # without annotations. firewall_driver adds the appropriate
208
+        # prefix
209
+        device_ids = [d.replace('qvo', '') for d in device_ids]
210
+        LOG.info(_LI("Remove device filter for %r"), device_ids)
211
+        with self.firewall.defer_apply():
212
+            for device_id in device_ids:
213
+                device = self.firewall.ports.get(device_id)
214
+                if not device:
215
+                    continue
216
+                self.firewall.remove_port_filter(device)
180 217
 
181 218
 
182 219
 class RestProxyAgent(api_sg_rpc.SecurityGroupAgentRpcCallbackMixin):

+ 7
- 1
rhel/neutron-bsn-agent.service View File

@@ -5,7 +5,13 @@ After=syslog.target network.target
5 5
 [Service]
6 6
 Type=simple
7 7
 User=neutron
8
-ExecStart=/usr/bin/neutron-bsn-agent --config-file /usr/share/neutron/neutron-dist.conf --config-file /etc/neutron/neutron.conf --config-dir /etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-bsn-agent --log-file /var/log/neutron/bsn-agent.log
8
+ExecStart=/usr/bin/neutron-bsn-agent \
9
+ --config-file /usr/share/neutron/neutron-dist.conf \
10
+ --config-file /etc/neutron/neutron.conf \
11
+ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \
12
+ --config-dir /etc/neutron/conf.d/common \
13
+ --config-dir /etc/neutron/conf.d/neutron-bsn-agent \
14
+ --log-file /var/log/neutron/bsn-agent.log
9 15
 PrivateTmp=true
10 16
 KillMode=process
11 17
 

Loading…
Cancel
Save