from neutron.plugins.nec.common import config
from neutron.plugins.nec.common import exceptions as nexc
from neutron.plugins.nec.db import api as ndb
-from neutron.plugins.nec.db import packetfilter as pf_db
from neutron.plugins.nec import ofc_manager
from neutron.plugins.nec import packet_filter
"no portinfo for this port."))
port_status = OperationalStatus.DOWN
- # activate packet_filters before creating port on OFC.
- if self.packet_filter_enabled:
- if port_status is OperationalStatus.ACTIVE:
- filters = dict(in_port=[port['id']],
- status=[pf_db.PF_STATUS_DOWN],
- admin_state_up=[True])
- pfs = self.get_packet_filters(context, filters=filters)
- for pf in pfs:
- self.activate_packet_filter_if_ready(context, pf)
-
if port_status in [OperationalStatus.ACTIVE]:
if self.ofc.exists_ofc_port(context, port['id']):
LOG.debug(_("activate_port_if_ready(): skip, "
port_status)
port['status'] = port_status
- # deactivate packet_filters after the port has deleted from OFC.
- if self.packet_filter_enabled:
- filters = dict(in_port=[port['id']],
- status=[pf_db.PF_STATUS_ACTIVE])
- pfs = self.get_packet_filters(context, filters=filters)
- for pf in pfs:
- self.deactivate_packet_filter(context, pf)
-
return port
def create_network(self, context, network):
mac=p.get('mac', ''))
port = self._get_port(rpc_context, id)
if port:
+ # NOTE: Make sure that packet filters on this port exist while
+ # the port is active to avoid unexpected packet transfer.
if portinfo:
self.plugin.deactivate_port(rpc_context, port)
+ self.plugin.deactivate_packet_filters_by_port(rpc_context,
+ id)
+ self.plugin.activate_packet_filters_by_port(rpc_context, id)
self.plugin.activate_port_if_ready(rpc_context, port)
for id in kwargs.get('port_removed', []):
portinfo = ndb.get_portinfo(session, id)
port = self._get_port(rpc_context, id)
if port:
self.plugin.deactivate_port(rpc_context, port)
+ self.plugin.deactivate_packet_filters_by_port(rpc_context, id)
def _get_port(self, context, port_id):
try:
packet_filter.update({'status': pf_status})
return packet_filter
+
+ def activate_packet_filters_by_port(self, context, port_id):
+ if not self.packet_filter_enabled:
+ return
+
+ filters = {'in_port': [port_id], 'admin_state_up': [True],
+ 'status': [pf_db.PF_STATUS_DOWN]}
+ pfs = self.get_packet_filters(context, filters=filters)
+ for pf in pfs:
+ self.activate_packet_filter_if_ready(context, pf)
+
+ def deactivate_packet_filters_by_port(self, context, port_id):
+ if not self.packet_filter_enabled:
+ return
+
+ filters = {'in_port': [port_id], 'status': [pf_db.PF_STATUS_ACTIVE]}
+ pfs = self.get_packet_filters(context, filters=filters)
+ for pf in pfs:
+ self.deactivate_packet_filter(context, pf)
self._show('packet_filters', pf_id,
expected_code=webob.exc.HTTPNotFound.code)
+
+ def test_no_pf_activation_while_port_operations(self):
+ with self.packet_filter_on_port() as pf:
+ in_port_id = pf['packet_filter']['in_port']
+ self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1)
+ self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 0)
+
+ data = {'port': {'admin_state_up': False}}
+ self._update('ports', in_port_id, data)
+ self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1)
+ self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 0)
+
+ data = {'port': {'admin_state_up': True}}
+ self._update('ports', in_port_id, data)
+ self.assertEqual(self.ofc.create_ofc_packet_filter.call_count, 1)
+ self.assertEqual(self.ofc.delete_ofc_packet_filter.call_count, 0)