summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodolfo Alonso Hernandez <ralonsoh@redhat.com>2023-03-05 22:12:55 +0100
committerRodolfo Alonso <ralonsoh@redhat.com>2023-03-16 12:33:48 +0000
commit1e244c57c51f02ac9e10e91740da67fb88bdd9ec (patch)
tree3701f5afb316bb645f1ba5674d69896e17990848
parent7ca09bfc2e7b489bd541895a6d35164022905284 (diff)
downloadneutron-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.rst12
-rw-r--r--neutron/agent/linux/openvswitch_firewall/firewall.py19
-rw-r--r--neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py22
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',