Skip to content

Commit 5588065

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVS] Allow custom ethertype traffic in the ingress table" into stable/yoga
2 parents 5cc0bdb + 8c7f3b6 commit 5588065

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

doc/source/admin/config-ovsfwdriver.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ not true and there may be slight differences between those drivers.
8888
| (please check [3]_ for details) | | rule. |
8989
+----------------------------------------+-----------------------+-----------------------+
9090

91+
92+
Permitted ethertypes
93+
~~~~~~~~~~~~~~~~~~~~
94+
95+
The OVS Firewall blocks traffic that does not have either the IPv4 or IPv6
96+
ethertypes at present. This is a behavior change compared to the
97+
"iptables_hybrid" firewall, which only operates on IP packets and thus does
98+
not address other ethertypes. With the configuration option
99+
``permitted_ethertypes`` it is possible to define a set of allowed ethertypes.
100+
Any traffic with these allowed ethertypes with destination to a local port or
101+
generated from a local port and MAC address, will be allowed.
102+
91103
References
92104
~~~~~~~~~~
93105

neutron/agent/linux/openvswitch_firewall/firewall.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,25 @@ def _initialize_ingress(self, port):
13711371
actions='output:{:d}'.format(port.ofport)
13721372
)
13731373

1374+
# Allow custom ethertypes
1375+
for permitted_ethertype in self.permitted_ethertypes:
1376+
if permitted_ethertype[:2] == '0x':
1377+
try:
1378+
hex_ethertype = hex(int(permitted_ethertype, base=16))
1379+
self._add_flow(
1380+
table=ovs_consts.BASE_INGRESS_TABLE,
1381+
priority=100,
1382+
dl_type=hex_ethertype,
1383+
reg_port=port.ofport,
1384+
actions='output:{:d}'.format(port.ofport)
1385+
)
1386+
continue
1387+
except ValueError:
1388+
pass
1389+
LOG.warning('Custom ethertype %(permitted_ethertype)s is not '
1390+
'a hexadecimal number.',
1391+
{'permitted_ethertype': permitted_ethertype})
1392+
13741393
self._initialize_ingress_ipv6_icmp(port)
13751394

13761395
# DHCP offers

neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from neutron.agent.linux.openvswitch_firewall import exceptions
3131
from neutron.agent.linux.openvswitch_firewall import firewall as ovsfw
3232
from neutron.conf.agent import securitygroups_rpc
33+
from neutron.conf.plugins.ml2.drivers import ovs_conf
3334
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants \
3435
as ovs_consts
3536
from neutron.plugins.ml2.drivers.openvswitch.agent.openflow.native \
@@ -514,6 +515,7 @@ def __init__(self, name, port, mac):
514515
class TestOVSFirewallDriver(base.BaseTestCase):
515516
def setUp(self):
516517
super(TestOVSFirewallDriver, self).setUp()
518+
ovs_conf.register_ovs_agent_opts(cfg=cfg.CONF)
517519
mock_bridge = mock.patch.object(
518520
ovs_lib, 'OVSBridge', autospec=True).start()
519521
securitygroups_rpc.register_securitygroups_opts()
@@ -840,6 +842,26 @@ def test_initialize_port_flows_vlan_dvr_conntrack_direct_vlan(self):
840842
return_value={"vlan1": "br-vlan1"}):
841843
self.firewall.initialize_port_flows(port)
842844

845+
def test_initialize_port_flows_permitted_ethertypes(self):
846+
self.firewall.permitted_ethertypes = ['0x1234', '0x5678']
847+
port_dict = {'device': 'port-id',
848+
'security_groups': [1]}
849+
of_port = create_ofport(port_dict,
850+
network_type=constants.TYPE_VLAN,
851+
physical_network='vlan1')
852+
self.firewall.sg_port_map.ports[of_port.id] = of_port
853+
port = self.firewall.get_or_create_ofport(port_dict)
854+
with mock.patch.object(self.firewall, '_add_flow') as mock_add_flow:
855+
self.firewall.initialize_port_flows(port)
856+
857+
calls = [mock.call(table=ovs_consts.BASE_INGRESS_TABLE,
858+
priority=100, dl_type='0x1234',
859+
reg_port=1, actions='output:1'),
860+
mock.call(table=ovs_consts.BASE_INGRESS_TABLE,
861+
priority=100, dl_type='0x5678',
862+
reg_port=1, actions='output:1')]
863+
mock_add_flow.assert_has_calls(calls, any_order=True)
864+
843865
def test_delete_all_port_flows(self):
844866
port_dict = {
845867
'device': 'port-id',

0 commit comments

Comments
 (0)