Add constraint for unique encapsulation

if any sub-int exists with a certain [dot1q,dot1ad,inner-dot1q], no
other sub-int in the same parent may exist with the same encapsulation.

- refactor sub-int mtu check to use get_mtu()
- if a sub-int has no config, raise a validation error
This commit is contained in:
Pim van Pelt
2022-03-13 13:06:44 +00:00
parent 29fcdaefe9
commit 2ced42e97a

View File

@ -108,6 +108,51 @@ def has_lcp(yaml, ifname):
return False return False
def unique_encapsulation(yaml, sub_ifname):
""" Ensures that for the sub_ifname specified, there exist no other sub-ints on the
parent with the same encapsulation. """
iface = get_by_name(yaml, sub_ifname)
parent_iface = get_parent_by_name(yaml, sub_ifname)
if not iface or not parent_iface:
return False
parent_ifname, subid = sub_ifname.split('.')
dot1q = 0
dot1ad = 0
inner_dot1q = 0
if not 'encapsulation' in iface:
dot1q = int(subid)
else:
if 'dot1q' in iface['encapsulation']:
dot1q = iface['encapsulation']['dot1q']
elif 'dot1ad' in iface['encapsulation']:
dot1ad = iface['encapsulation']['dot1ad']
if 'inner-dot1q' in iface['encapsulation']:
inner_dot1q = iface['encapsulation']['inner-dot1q']
ncount = 0
for subid, sibling_iface in parent_iface['sub-interfaces'].items():
sibling_dot1q = 0
sibling_dot1ad = 0
sibling_inner_dot1q = 0
sibling_ifname = "%s.%d" % (parent_ifname, subid)
if not 'encapsulation' in sibling_iface:
sibling_dot1q = subid
else:
if 'dot1q' in sibling_iface['encapsulation']:
sibling_dot1q = sibling_iface['encapsulation']['dot1q']
elif 'dot1ad' in sibling_iface['encapsulation']:
sibling_dot1ad = sibling_iface['encapsulation']['dot1ad']
if 'inner-dot1q' in sibling_iface['encapsulation']:
sibling_inner_dot1q = sibling_iface['encapsulation']['inner-dot1q']
if (dot1q,dot1ad,inner_dot1q) == (sibling_dot1q, sibling_dot1ad, sibling_inner_dot1q) and sub_ifname != sibling_ifname:
## print("%s overlaps with %s: [%d,%d,%d]" % (sub_ifname, sibling_ifname, dot1q, dot1ad, inner_dot1q))
ncount = ncount + 1
if (ncount == 0):
return True
return False
def valid_encapsulation(yaml, sub_ifname): def valid_encapsulation(yaml, sub_ifname):
try: try:
ifname, subid = sub_ifname.split('.') ifname, subid = sub_ifname.split('.')
@ -221,16 +266,21 @@ def validate_interfaces(args, yaml):
if has_sub(yaml, ifname): if has_sub(yaml, ifname):
for sub_id, sub_iface in yaml['interfaces'][ifname]['sub-interfaces'].items(): for sub_id, sub_iface in yaml['interfaces'][ifname]['sub-interfaces'].items():
sub_ifname = "%s.%d" % (ifname, sub_id)
logger.debug("sub-interface %s" % sub_iface) logger.debug("sub-interface %s" % sub_iface)
sub_ifname = "%s.%d" % (ifname, sub_id)
if not sub_iface:
msgs.append("sub-interface %s has no config" % (sub_ifname))
result = False
continue
sub_lcp = get_lcp(yaml, sub_ifname) sub_lcp = get_lcp(yaml, sub_ifname)
if sub_lcp and len(sub_lcp)>15: if sub_lcp and len(sub_lcp)>15:
msgs.append("sub-interface %s has LCP with too long name '%s'" % (sub_ifname, sub_lcp)) msgs.append("sub-interface %s has LCP with too long name '%s'" % (sub_ifname, sub_lcp))
result = False result = False
if 'mtu' in sub_iface: sub_mtu = get_mtu(yaml, sub_ifname)
if sub_iface['mtu'] > iface_mtu: if sub_mtu > iface_mtu:
msgs.append("sub-interface %s has MTU %d higher than parent MTU %d" % (sub_ifname, sub_iface['mtu'], iface_mtu)) msgs.append("sub-interface %s has MTU %d higher than parent MTU %d" % (sub_ifname, sub_iface['mtu'], iface_mtu))
result = False result = False
if has_lcp(yaml, sub_ifname): if has_lcp(yaml, sub_ifname):
if not iface_lcp: if not iface_lcp:
msgs.append("sub-interface %s has LCP but %s does not have LCP" % (sub_ifname, ifname)) msgs.append("sub-interface %s has LCP but %s does not have LCP" % (sub_ifname, ifname))
@ -243,5 +293,8 @@ def validate_interfaces(args, yaml):
if not valid_encapsulation(yaml, sub_ifname): if not valid_encapsulation(yaml, sub_ifname):
msgs.append("sub-interface %s has invalid encapsulation" % (sub_ifname)) msgs.append("sub-interface %s has invalid encapsulation" % (sub_ifname))
result = False result = False
elif not unique_encapsulation(yaml, sub_ifname):
msgs.append("sub-interface %s doesn't have unique encapsulation" % (sub_ifname))
result = False
return result, msgs return result, msgs