diff options
author | Rodolfo Alonso Hernandez <ralonsoh@redhat.com> | 2023-03-05 22:12:55 +0100 |
---|---|---|
committer | Rodolfo Alonso <ralonsoh@redhat.com> | 2023-03-16 12:33:48 +0000 |
commit | 1e244c57c51f02ac9e10e91740da67fb88bdd9ec (patch) | |
tree | 3701f5afb316bb645f1ba5674d69896e17990848 | |
parent | 7ca09bfc2e7b489bd541895a6d35164022905284 (diff) | |
download | neutron-1e244c57c51f02ac9e10e91740da67fb88bdd9ec.tar.gz |
[OVS] Allow custom ethertype traffic in the ingress table
This patch is a partial revert of [1], reinstantiating the code merged
in [2]. This patch is the complementary to [1]: the traffic with
custom ethertypes is allowed in the ingress processing tables, same
as [1] is allowing all traffic from the virtual machine ports in this
host to leave the node. Both, this patch and [1], are bypassing the
OVS firewall just for the traffic with the configured allowed
ethertypes and just for/to the local ports and MAC addresses.
Any other traffic not coming from a local port or with destination
a local port, will be blocked as is now.
[1]https://review.opendev.org/c/openstack/neutron/+/678021
[2]https://review.opendev.org/c/openstack/neutron/+/668224/
Conflicts:
doc/source/admin/config-ovsfwdriver.rst
neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py
Closes-Bug: #2009221
Related-Bug: #1832758
Change-Id: Ib8340d9430b946a446edf80886c49fbac729073c
(cherry picked from commit 008277b8c12d99438951a308b278203fa7a7c3ef)
-rw-r--r-- | doc/source/admin/config-ovsfwdriver.rst | 12 | ||||
-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, 53 insertions, 0 deletions
diff --git a/doc/source/admin/config-ovsfwdriver.rst b/doc/source/admin/config-ovsfwdriver.rst index e915700b46..061c77cea6 100644 --- a/doc/source/admin/config-ovsfwdriver.rst +++ b/doc/source/admin/config-ovsfwdriver.rst @@ -88,6 +88,18 @@ not true and there may be slight differences between those drivers. | (please check [3]_ for details) | | rule. | +----------------------------------------+-----------------------+-----------------------+ + +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 d30d99cdd1..db72ffdbfc 100644 --- a/neutron/agent/linux/openvswitch_firewall/firewall.py +++ b/neutron/agent/linux/openvswitch_firewall/firewall.py @@ -1366,6 +1366,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 0976b2f646..4824ca3c9f 100644 --- a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py +++ b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py @@ -30,6 +30,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.common import constants \ as ovs_consts from neutron.plugins.ml2.drivers.openvswitch.agent.openflow.native \ @@ -514,6 +515,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() @@ -840,6 +842,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', |