diff --git a/neutron/agent/common/ovs_lib.py b/neutron/agent/common/ovs_lib.py index 98f8535d964..b77fdc18295 100644 --- a/neutron/agent/common/ovs_lib.py +++ b/neutron/agent/common/ovs_lib.py @@ -118,6 +118,7 @@ class BaseOVS(object): def __init__(self): self.ovsdb_timeout = cfg.CONF.OVS.ovsdb_timeout self.ovsdb = impl_idl.api_factory() + self._hw_offload = None def add_manager(self, connection_uri, timeout=_SENTINEL): """Have ovsdb-server listen for manager connections @@ -198,6 +199,13 @@ class BaseOVS(object): _cfg = self.config return {k: _cfg.get(k, OVS_DEFAULT_CAPS[k]) for k in OVS_DEFAULT_CAPS} + @property + def is_hw_offload_enabled(self): + if self._hw_offload is None: + self._hw_offload = self.config.get('other_config', + {}).get('hw-offload', '').lower() == 'true' + return self._hw_offload + # Map from version string to on-the-wire protocol version encoding: OF_PROTOCOL_TO_VERSION = { @@ -508,7 +516,11 @@ class OVSBridge(BaseOVS): options['local_ip'] = local_ip options['in_key'] = 'flow' options['out_key'] = 'flow' - options['egress_pkt_mark'] = '0' + # NOTE(moshele): pkt_mark is not upported when using ovs hw-offload, + # therefore avoid clear mark on encapsulating packets when it's + # enabled + if not self.is_hw_offload_enabled: + options['egress_pkt_mark'] = '0' if tunnel_csum: options['csum'] = str(tunnel_csum).lower() if tos: diff --git a/neutron/tests/unit/agent/common/test_ovs_lib.py b/neutron/tests/unit/agent/common/test_ovs_lib.py index b14a20a13de..8a3cf88e00b 100644 --- a/neutron/tests/unit/agent/common/test_ovs_lib.py +++ b/neutron/tests/unit/agent/common/test_ovs_lib.py @@ -578,6 +578,27 @@ class OVS_Lib_Test(base.BaseTestCase): set_ctrl_field_mock.assert_called_once_with( 'controller_burst_limit', ovs_lib.CTRL_BURST_LIMIT_MIN) + def test_hw_offload_enabled_false(self): + config_mock1 = mock.PropertyMock(return_value={"other_config": {}}) + config_mock2 = mock.PropertyMock( + return_value={"other_config": {"hw-offload": "false"}}) + config_mock3 = mock.PropertyMock( + return_value={"other_config": {"hw-offload": "False"}}) + for config_mock in (config_mock1, config_mock2, config_mock3): + with mock.patch("neutron.agent.common.ovs_lib.OVSBridge.config", + new_callable=config_mock): + self.assertFalse(self.br.is_hw_offload_enabled) + + def test_hw_offload_enabled_true(self): + config_mock1 = mock.PropertyMock( + return_value={"other_config": {"hw-offload": "true"}}) + config_mock2 = mock.PropertyMock( + return_value={"other_config": {"hw-offload": "True"}}) + for config_mock in (config_mock1, config_mock2): + with mock.patch("neutron.agent.common.ovs_lib.OVSBridge.config", + new_callable=config_mock): + self.assertTrue(self.br.is_hw_offload_enabled) + class TestDeferredOVSBridge(base.BaseTestCase): diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py index 574a4f2062b..0dbad4a37a0 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py @@ -308,12 +308,14 @@ class OVSTunnelBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase, self.assertEqual([call(port_name)], delete_port.mock_calls) def test_add_tunnel_port(self): + self.br._hw_offload = False self._mock_add_tunnel_port() def test_delete_port(self): self._mock_delete_port() def test_deferred_br_add_tunnel_port(self): + self.br._hw_offload = False self._mock_add_tunnel_port(True) def test_deferred_br_delete_port(self):