Separate packet filter activation from port operation in NEC Plugin

Fixes: bug #1209422
Change-Id: I5480e0798e64221f2f096732db6584634caddfb1
This commit is contained in:
Ryota MIBU 2013-08-05 15:15:56 +09:00
parent 55f2e31d9a
commit 1307d43b07
3 changed files with 41 additions and 19 deletions

View File

@ -41,7 +41,6 @@ from neutron.openstack.common.rpc import proxy
from neutron.plugins.nec.common import config from neutron.plugins.nec.common import config
from neutron.plugins.nec.common import exceptions as nexc from neutron.plugins.nec.common import exceptions as nexc
from neutron.plugins.nec.db import api as ndb 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 ofc_manager
from neutron.plugins.nec import packet_filter from neutron.plugins.nec import packet_filter
@ -176,16 +175,6 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
"no portinfo for this port.")) "no portinfo for this port."))
port_status = OperationalStatus.DOWN 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 port_status in [OperationalStatus.ACTIVE]:
if self.ofc.exists_ofc_port(context, port['id']): if self.ofc.exists_ofc_port(context, port['id']):
LOG.debug(_("activate_port_if_ready(): skip, " LOG.debug(_("activate_port_if_ready(): skip, "
@ -224,14 +213,6 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
port_status) port_status)
port['status'] = 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 return port
def create_network(self, context, network): def create_network(self, context, network):
@ -542,8 +523,13 @@ class NECPluginV2RPCCallbacks(object):
mac=p.get('mac', '')) mac=p.get('mac', ''))
port = self._get_port(rpc_context, id) port = self._get_port(rpc_context, id)
if port: if port:
# NOTE: Make sure that packet filters on this port exist while
# the port is active to avoid unexpected packet transfer.
if portinfo: if portinfo:
self.plugin.deactivate_port(rpc_context, port) 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) self.plugin.activate_port_if_ready(rpc_context, port)
for id in kwargs.get('port_removed', []): for id in kwargs.get('port_removed', []):
portinfo = ndb.get_portinfo(session, id) portinfo = ndb.get_portinfo(session, id)
@ -564,6 +550,7 @@ class NECPluginV2RPCCallbacks(object):
port = self._get_port(rpc_context, id) port = self._get_port(rpc_context, id)
if port: if port:
self.plugin.deactivate_port(rpc_context, 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): def _get_port(self, context, port_id):
try: try:

View File

@ -168,3 +168,22 @@ class PacketFilterMixin(pf_db.PacketFilterDbMixin):
packet_filter.update({'status': pf_status}) packet_filter.update({'status': pf_status})
return packet_filter 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)

View File

@ -465,3 +465,19 @@ class TestNecPluginPacketFilter(test_nec_plugin.NecPluginV2TestCase):
self._show('packet_filters', pf_id, self._show('packet_filters', pf_id,
expected_code=webob.exc.HTTPNotFound.code) 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)