Ensure that extended ethertypes still work by name

When the change to add support for extended ethertypes was introduced,
one scenario for backwards compatibility was not addressed in the
validator: using the canonical string names for ethertypes.  This was
previously supported in the original implementation, using 'IPv4' or
'IPv6' for example.

Since the list of canonical ethertype names is available from os-ken we
consume it from there, which adds an additional dependency for
neutron-lib.

Related-Bug: #1838473
Change-Id: I53c6538dfbeea9691d95c6c555f0c56ae13d1a33
This commit is contained in:
Nate Johnston 2019-07-30 17:15:24 -04:00
parent aaae83acaa
commit 24aef1398b
4 changed files with 30 additions and 6 deletions

View File

@ -37,6 +37,7 @@ netifaces==0.10.4
openstackdocstheme==1.18.1
os-api-ref==1.4.0
os-client-config==1.28.0
os-ken==0.3.0
os-traits==0.9.0
oslo.concurrency==3.26.0
oslo.config==5.2.0

View File

@ -16,6 +16,7 @@ import inspect
import re
import netaddr
from os_ken.lib.packet import ether_types
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import netutils
@ -1126,11 +1127,26 @@ def validate_subnet_service_types(service_types, valid_values=None):
def validate_ethertype(ethertype, valid_values=None):
"""Validates ethertype is a valid ethertype.
:param ethertype: Ethertype to validate
:param ethertype: Ethertype to validate.
:returns: None if data is a valid ethertype. Otherwise a human-readable
message indicating that the data is not a valid ethertype.
"""
if cfg.CONF.sg_filter_ethertypes:
os_ken_ethertypes = ether_types.__dict__
try:
# Use the ethertype constants from os_ken with the special
# exception of 'IPv4', which appears as 'ETH_TYPE_IP' in os_ken.
# Be case-insensitive.
ethertype_str = str(ethertype).upper()
if ethertype_str == "IPV4":
ethertype_str = "IP"
ethertype_name = 'ETH_TYPE_' + ethertype_str
if ethertype_name in os_ken_ethertypes:
ethertype = os_ken_ethertypes[ethertype_name]
except TypeError:
# Value of ethertype cannot be coerced into a string, like None
pass
try:
if isinstance(ethertype, six.string_types):
ethertype = int(ethertype, 16)
@ -1141,7 +1157,7 @@ def validate_ethertype(ethertype, valid_values=None):
except ValueError:
pass
msg = _("Ethertype %s is not a two octet hexadecimal "
"number.") % ethertype
"number or ethertype name.") % ethertype
LOG.debug(msg)
return msg
else:

View File

@ -1108,7 +1108,13 @@ class TestAttributeValidation(base.BaseTestCase):
self.assertIsNone(validators.validate_subports(body))
@mock.patch('oslo_config.cfg.CONF')
def test_validate_ethertype_valid_string(self, CONF):
def test_validate_ethertype_valid_string_new(self, CONF):
CONF.sg_filter_ethertypes = True
self.assertIsNone(validators.validate_ethertype('IPv4'))
self.assertIsNone(validators.validate_ethertype('IPv6'))
@mock.patch('oslo_config.cfg.CONF')
def test_validate_ethertype_valid_string_old(self, CONF):
CONF.sg_filter_ethertypes = False
self.assertIsNone(validators.validate_ethertype('IPv4'))
self.assertIsNone(validators.validate_ethertype('IPv6'))
@ -1134,21 +1140,21 @@ class TestAttributeValidation(base.BaseTestCase):
def test_validate_ethertype_extended_invalid_negative(self, CONF):
CONF.sg_filter_ethertypes = True
self.assertEqual(("Ethertype -16392 is not a two octet "
"hexadecimal number."),
"hexadecimal number or ethertype name."),
validators.validate_ethertype('-0x4008'))
@mock.patch('oslo_config.cfg.CONF')
def test_validate_ethertype_extended_invalid_nonhex(self, CONF):
CONF.sg_filter_ethertypes = True
self.assertEqual(("Ethertype invalid is not a two octet "
"hexadecimal number."),
"hexadecimal number or ethertype name."),
validators.validate_ethertype('invalid'))
@mock.patch('oslo_config.cfg.CONF')
def test_validate_ethertype_extended_invalid_toobig(self, CONF):
CONF.sg_filter_ethertypes = True
self.assertEqual(("Ethertype 3735928559 is not a two octet "
"hexadecimal number."),
"hexadecimal number or ethertype name."),
validators.validate_ethertype('0xdeadbeef'))

View File

@ -10,6 +10,7 @@ keystoneauth1>=3.4.0 # Apache-2.0
netaddr>=0.7.18 # BSD
six>=1.10.0 # MIT
stevedore>=1.20.0 # Apache-2.0
os-ken >= 0.3.0 # Apache-2.0
oslo.concurrency>=3.26.0 # Apache-2.0
oslo.config>=5.2.0 # Apache-2.0
oslo.context>=2.19.2 # Apache-2.0