Merge "[OVS] Allow custom ethertype traffic in the ingress table"

This commit is contained in:
Zuul 2023-03-13 12:57:27 +00:00 committed by Gerrit Code Review
commit bc6aa149d0
3 changed files with 51 additions and 0 deletions

View File

@ -175,6 +175,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
~~~~~~~~~~

View File

@ -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

View File

@ -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',