Merge "dvr: Avoid installing non-dvr openflow rule on startup"

This commit is contained in:
Zuul 2023-08-01 21:10:46 +00:00 committed by Gerrit Code Review
commit 4554639cc2
6 changed files with 69 additions and 19 deletions

View File

@ -33,13 +33,19 @@ class OVSTunnelBridge(ovs_bridge.OVSAgentBridge,
dvr_process_next_table_id = constants.PATCH_LV_TO_TUN
of_tables = constants.TUN_BR_ALL_TABLES
def setup_default_table(self, patch_int_ofport, arp_responder_enabled):
def setup_default_table(
self, patch_int_ofport, arp_responder_enabled, dvr_enabled):
(dp, ofp, ofpp) = self._get_dp()
# Table 0 (default) will sort incoming traffic depending on in_port
self.install_goto(dest_table_id=constants.PATCH_LV_TO_TUN,
priority=1,
in_port=patch_int_ofport)
if not dvr_enabled:
# Table 0 (default) will sort incoming traffic depending on in_port
# This table is needed only for non-dvr environment because
# OVSDVRProcessMixin overwrites this flow in its
# install_dvr_process() method.
self.install_goto(dest_table_id=constants.PATCH_LV_TO_TUN,
priority=1,
in_port=patch_int_ofport)
self.install_drop() # default drop
if arp_responder_enabled:

View File

@ -264,16 +264,20 @@ class OVSDVRNeutronAgent(object):
if not self.enable_tunneling:
return
self.tun_br.install_goto(dest_table_id=ovs_constants.DVR_PROCESS,
priority=1,
in_port=self.patch_int_ofport)
self._setup_dvr_flows_on_tun_br(self.tun_br, self.patch_int_ofport)
@staticmethod
def _setup_dvr_flows_on_tun_br(tun_br, patch_int_ofport):
tun_br.install_goto(dest_table_id=ovs_constants.DVR_PROCESS,
priority=1,
in_port=patch_int_ofport)
# table-miss should be sent to learning table
self.tun_br.install_goto(table_id=ovs_constants.DVR_NOT_LEARN,
dest_table_id=ovs_constants.LEARN_FROM_TUN)
tun_br.install_goto(table_id=ovs_constants.DVR_NOT_LEARN,
dest_table_id=ovs_constants.LEARN_FROM_TUN)
self.tun_br.install_goto(table_id=ovs_constants.DVR_PROCESS,
dest_table_id=ovs_constants.PATCH_LV_TO_TUN)
tun_br.install_goto(table_id=ovs_constants.DVR_PROCESS,
dest_table_id=ovs_constants.PATCH_LV_TO_TUN)
def setup_dvr_flows_on_phys_br(self, bridge_mappings=None):
'''Setup up initial dvr flows into br-phys'''

View File

@ -1563,7 +1563,8 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
Add all flows to the tunnel bridge.
'''
self.tun_br.setup_default_table(self.patch_int_ofport,
self.arp_responder_enabled)
self.arp_responder_enabled,
self.enable_distributed_routing)
def _reconfigure_physical_bridges(self, bridges):
try:

View File

@ -24,6 +24,8 @@ from neutron.agent.common import utils
from neutron.agent.linux import ip_lib
from neutron.cmd.sanity import checks
from neutron.common import utils as common_utils
from neutron.plugins.ml2.drivers.openvswitch.agent \
import ovs_dvr_neutron_agent as ovsdvragt
from neutron.plugins.ml2.drivers.openvswitch.agent \
import ovs_neutron_agent as ovsagt
from neutron.tests.common import base as common_base
@ -311,8 +313,9 @@ class OVSFlowTestCase(OVSAgentTestBase):
"""
def setUp(self):
dvr_enabled = True
cfg.CONF.set_override('enable_distributed_routing',
True,
dvr_enabled,
group='AGENT')
super(OVSFlowTestCase, self).setUp()
self.phys_br = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
@ -334,7 +337,9 @@ class OVSFlowTestCase(OVSAgentTestBase):
prefix=cfg.CONF.OVS.tun_peer_patch_port),
common_utils.get_rand_device_name(
prefix=cfg.CONF.OVS.int_peer_patch_port))
self.br_tun.setup_default_table(self.tun_p, True)
self.br_tun.setup_default_table(self.tun_p, True, dvr_enabled)
ovsdvragt.OVSDVRNeutronAgent._setup_dvr_flows_on_tun_br(self.br_tun,
self.tun_p)
def test_provision_local_vlan(self):
kwargs = {'port': 123, 'lvid': 888, 'segmentation_id': 777}

View File

@ -52,7 +52,8 @@ class OVSTunnelBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
patch_int_ofport = 5555
arp_responder_enabled = False
self.br.setup_default_table(patch_int_ofport=patch_int_ofport,
arp_responder_enabled=arp_responder_enabled)
arp_responder_enabled=arp_responder_enabled,
dvr_enabled=False)
(dp, ofp, ofpp) = self._get_dp()
expected = [
call._send_msg(ofpp.OFPFlowMod(dp,
@ -160,7 +161,8 @@ class OVSTunnelBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
patch_int_ofport = 5555
arp_responder_enabled = True
self.br.setup_default_table(patch_int_ofport=patch_int_ofport,
arp_responder_enabled=arp_responder_enabled)
arp_responder_enabled=arp_responder_enabled,
dvr_enabled=False)
(dp, ofp, ofpp) = self._get_dp()
expected = [
call._send_msg(ofpp.OFPFlowMod(dp,
@ -280,6 +282,33 @@ class OVSTunnelBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
]
self.assertEqual(expected, self.mock.mock_calls)
def _test_setup_default_table_dvr_helper(self, dvr_enabled):
patch_int_ofport = 5555
arp_responder_enabled = True
self.br.setup_default_table(patch_int_ofport=patch_int_ofport,
arp_responder_enabled=arp_responder_enabled,
dvr_enabled=dvr_enabled)
(dp, ofp, ofpp) = self._get_dp()
non_dvr_specific_call = call._send_msg(
ofpp.OFPFlowMod(
dp,
cookie=self.stamp,
instructions=[ofpp.OFPInstructionGotoTable(table_id=2)],
match=ofpp.OFPMatch(in_port=patch_int_ofport),
priority=1, table_id=0),
active_bundle=None)
if dvr_enabled:
self.assertNotIn(non_dvr_specific_call, self.mock.mock_calls)
else:
self.assertIn(non_dvr_specific_call, self.mock.mock_calls)
def test_setup_default_table_dvr_enabled(self):
self._test_setup_default_table_dvr_helper(dvr_enabled=True)
def test_setup_default_table_dvr_disabled(self):
self._test_setup_default_table_dvr_helper(dvr_enabled=False)
def test_provision_local_vlan(self):
network_type = 'vxlan'
lvid = 888

View File

@ -188,7 +188,8 @@ class TunnelTest(object):
'_check_bridge_datapath_id').start()
self._define_expected_calls()
def _define_expected_calls(self, arp_responder=False, igmp_snooping=False):
def _define_expected_calls(
self, arp_responder=False, igmp_snooping=False):
self.mock_int_bridge_cls_expected = [
mock.call(self.INT_BRIDGE,
datapath_type=mock.ANY),
@ -268,7 +269,11 @@ class TunnelTest(object):
]
self.mock_tun_bridge_expected += [
mock.call.setup_default_table(self.INT_OFPORT, arp_responder),
# NOTE: Parameters passed to setup_default_table() method are named
# in the production code. That's why we can't use keyword parameter
# here. The last parameter passed below is dvr_enabled set to False
mock.call.setup_default_table(
self.INT_OFPORT, arp_responder, False),
]
self.ipdevice_expected = []