diff options
author | Zuul <zuul@review.opendev.org> | 2023-03-20 10:49:39 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2023-03-20 10:49:39 +0000 |
commit | 67b4ff3850c90bc73f5536f8a14d803144bbb700 (patch) | |
tree | c29b64ece83b0844ef48aafbae661631d24ab02c | |
parent | 6a69019fb5bed6ac490a64d4f5357e7a68c3975c (diff) | |
parent | 138a47bfd62252ddea8ff7ccdedff265e99cfb0e (diff) | |
download | neutron-67b4ff3850c90bc73f5536f8a14d803144bbb700.tar.gz |
Merge "[OVS] Allow custom ethertype traffic in the ingress table" into stable/zed
-rw-r--r-- | doc/source/admin/config-ovsfwdriver.rst | 10 | ||||
-rw-r--r-- | neutron/agent/linux/openvswitch_firewall/firewall.py | 19 | ||||
-rw-r--r-- | neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py | 22 |
3 files changed, 51 insertions, 0 deletions
diff --git a/doc/source/admin/config-ovsfwdriver.rst b/doc/source/admin/config-ovsfwdriver.rst index 594a5e8536..59af75d03c 100644 --- a/doc/source/admin/config-ovsfwdriver.rst +++ b/doc/source/admin/config-ovsfwdriver.rst @@ -168,6 +168,16 @@ the default ``_constants.AGENT_RES_PROCESSING_STEP``: # (6) Check the OVS agent restart time, checking the "iteration" time and # number. +Permitted ethertypes +~~~~~~~~~~~~~~~~~~~~ + +The OVS Firewall blocks traffic that does not have either the IPv4 or IPv6 +ethertypes at present. This is a behavior change compared to the +"iptables_hybrid" firewall, which only operates on IP packets and thus does +not address other ethertypes. With the configuration option +``permitted_ethertypes`` it is possible to define a set of allowed ethertypes. +Any traffic with these allowed ethertypes with destination to a local port or +generated from a local port and MAC address, will be allowed. References ~~~~~~~~~~ diff --git a/neutron/agent/linux/openvswitch_firewall/firewall.py b/neutron/agent/linux/openvswitch_firewall/firewall.py index 3f24dab9ce..a08d4fa24a 100644 --- a/neutron/agent/linux/openvswitch_firewall/firewall.py +++ b/neutron/agent/linux/openvswitch_firewall/firewall.py @@ -1388,6 +1388,25 @@ class OVSFirewallDriver(firewall.FirewallDriver): actions='output:{:d}'.format(port.ofport) ) + # Allow custom ethertypes + for permitted_ethertype in self.permitted_ethertypes: + if permitted_ethertype[:2] == '0x': + try: + hex_ethertype = hex(int(permitted_ethertype, base=16)) + self._add_flow( + table=ovs_consts.BASE_INGRESS_TABLE, + priority=100, + dl_type=hex_ethertype, + reg_port=port.ofport, + actions='output:{:d}'.format(port.ofport) + ) + continue + except ValueError: + pass + LOG.warning('Custom ethertype %(permitted_ethertype)s is not ' + 'a hexadecimal number.', + {'permitted_ethertype': permitted_ethertype}) + self._initialize_ingress_ipv6_icmp(port) # DHCP offers diff --git a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py index abc3942e49..8eee3a4bf3 100644 --- a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py +++ b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py @@ -31,6 +31,7 @@ from neutron.agent.linux.openvswitch_firewall import constants as ovsfw_consts from neutron.agent.linux.openvswitch_firewall import exceptions from neutron.agent.linux.openvswitch_firewall import firewall as ovsfw from neutron.conf.agent import securitygroups_rpc +from neutron.conf.plugins.ml2.drivers import ovs_conf from neutron.plugins.ml2.drivers.openvswitch.agent.openflow.native \ import ovs_bridge from neutron.tests import base @@ -518,6 +519,7 @@ class FakeOVSPort(object): class TestOVSFirewallDriver(base.BaseTestCase): def setUp(self): super(TestOVSFirewallDriver, self).setUp() + ovs_conf.register_ovs_agent_opts(cfg=cfg.CONF) mock_bridge = mock.patch.object( ovs_lib, 'OVSBridge', autospec=True).start() securitygroups_rpc.register_securitygroups_opts() @@ -844,6 +846,26 @@ class TestOVSFirewallDriver(base.BaseTestCase): return_value={"vlan1": "br-vlan1"}): self.firewall.initialize_port_flows(port) + def test_initialize_port_flows_permitted_ethertypes(self): + self.firewall.permitted_ethertypes = ['0x1234', '0x5678'] + port_dict = {'device': 'port-id', + 'security_groups': [1]} + of_port = create_ofport(port_dict, + network_type=constants.TYPE_VLAN, + physical_network='vlan1') + self.firewall.sg_port_map.ports[of_port.id] = of_port + port = self.firewall.get_or_create_ofport(port_dict) + with mock.patch.object(self.firewall, '_add_flow') as mock_add_flow: + self.firewall.initialize_port_flows(port) + + calls = [mock.call(table=ovs_consts.BASE_INGRESS_TABLE, + priority=100, dl_type='0x1234', + reg_port=1, actions='output:1'), + mock.call(table=ovs_consts.BASE_INGRESS_TABLE, + priority=100, dl_type='0x5678', + reg_port=1, actions='output:1')] + mock_add_flow.assert_has_calls(calls, any_order=True) + def test_delete_all_port_flows(self): port_dict = { 'device': 'port-id', |