Also allow loopback interfaces to be unnumbered
This commit is contained in:
@ -16,6 +16,7 @@ import logging
|
||||
from . import lcp
|
||||
from . import address
|
||||
from . import mac
|
||||
from . import interface
|
||||
|
||||
|
||||
def get_loopbacks(yaml):
|
||||
@ -53,6 +54,32 @@ def is_loopback(yaml, ifname):
|
||||
return iface is not None
|
||||
|
||||
|
||||
def get_unnumbered_loopbacks(yaml):
|
||||
"""Returns a list of all loopbacks that are unnumbered"""
|
||||
ret = []
|
||||
if not "loopbacks" in yaml:
|
||||
return ret
|
||||
for ifname, iface in yaml["loopbacks"].items():
|
||||
if "unnumbered" in iface:
|
||||
ret.append(ifname)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def is_unnumbered(yaml, ifname):
|
||||
"""Returns True if the loopback exists and is unnumbered"""
|
||||
return ifname in get_unnumbered_loopbacks(yaml)
|
||||
|
||||
|
||||
def has_address(yaml, ifname):
|
||||
"""Returns True if this loopback has one or more addresses"""
|
||||
|
||||
ifname, iface = get_by_name(yaml, ifname)
|
||||
if not iface:
|
||||
return False
|
||||
return "addresses" in iface
|
||||
|
||||
|
||||
def validate_loopbacks(yaml):
|
||||
"""Validate the semantics of all YAML 'loopbacks' entries"""
|
||||
result = True
|
||||
@ -76,6 +103,31 @@ def validate_loopbacks(yaml):
|
||||
f"loopback {ifname} does not have a unique LCP name {iface['lcp']}"
|
||||
)
|
||||
result = False
|
||||
if "unnumbered" in iface:
|
||||
target = iface["unnumbered"]
|
||||
_, target_iface = get_by_name(yaml, target)
|
||||
if not target_iface:
|
||||
_, target_iface = interface.get_by_name(yaml, target)
|
||||
if not target_iface:
|
||||
msgs.append(
|
||||
f"loopback {ifname} unnumbered target {target} does not exist"
|
||||
)
|
||||
result = False
|
||||
if is_unnumbered(yaml, target):
|
||||
msgs.append(
|
||||
f"loopback {ifname} unnumbered target {target} cannot also be unnumbered"
|
||||
)
|
||||
result = False
|
||||
if ifname == target:
|
||||
msgs.append(
|
||||
f"loopback {ifname} unnumbered target cannot point to itself"
|
||||
)
|
||||
result = False
|
||||
if has_address(yaml, ifname):
|
||||
msgs.append(
|
||||
f"loopback {ifname} cannot also have addresses when it is unnumbered"
|
||||
)
|
||||
result = False
|
||||
if "addresses" in iface:
|
||||
for addr in iface["addresses"]:
|
||||
if not address.is_allowed(yaml, ifname, iface["addresses"], addr):
|
||||
|
@ -35,6 +35,7 @@ loopback:
|
||||
lcp: str(max=15,matches='[a-z]+[a-z0-9-]*',required=False)
|
||||
mtu: int(min=128,max=9216,required=False)
|
||||
addresses: list(ip_interface(),min=1,max=6,required=False)
|
||||
unnumbered: str(required=False)
|
||||
mpls: bool(required=False)
|
||||
---
|
||||
bondethernet:
|
||||
|
@ -7,6 +7,18 @@ loopbacks:
|
||||
loop0:
|
||||
mtu: 9216
|
||||
addresses: [ 192.0.2.1/32, 2001:db8:1::1/128 ]
|
||||
loop1:
|
||||
mtu: 1500
|
||||
addresses: [ 192.0.2.17/32, 2001:db8:10::1/128 ]
|
||||
loop2:
|
||||
mtu: 1500
|
||||
unnumbered: loop1
|
||||
loop3:
|
||||
mtu: 1500
|
||||
unnumbered: GigabitEthernet1/0/0
|
||||
loop4:
|
||||
mtu: 1500
|
||||
unnumbered: GigabitEthernet3/0/0.100
|
||||
|
||||
interfaces:
|
||||
GigabitEthernet1/0/0:
|
||||
|
@ -2,21 +2,27 @@ test:
|
||||
description: "Nonexistent unnumbered target"
|
||||
errors:
|
||||
expected:
|
||||
- "^sub-interface .* unnumbered target .* does not exist"
|
||||
- "^interface .* unnumbered target .* does not exist"
|
||||
count: 4
|
||||
- "(sub-)?interface .* unnumbered target .* does not exist"
|
||||
- "loopback .* unnumbered target .* does not exist"
|
||||
count: 6
|
||||
---
|
||||
loopbacks:
|
||||
loop0:
|
||||
mtu: 9216
|
||||
addresses: [ 192.0.2.1/32, 2001:db8:1::1/128 ]
|
||||
loop1:
|
||||
mtu: 9216
|
||||
unnumbered: loop2
|
||||
loop3:
|
||||
mtu: 9216
|
||||
unnumbered: GigabitEthernet0/0/0
|
||||
|
||||
interfaces:
|
||||
GigabitEthernet1/0/0:
|
||||
sub-interfaces:
|
||||
101:
|
||||
description: "Error: non existent loopback device"
|
||||
unnumbered: loop1
|
||||
unnumbered: loop2
|
||||
|
||||
GigabitEthernet2/0/0:
|
||||
addresses: [ 192.0.2.5/30, 2001:db8:2::1/64 ]
|
||||
|
@ -4,8 +4,18 @@ test:
|
||||
expected:
|
||||
- "(sub-)?interface .* unnumbered target cannot point to itself"
|
||||
- "(sub-)?interface .* unnumbered target .* cannot also be unnumbered"
|
||||
count: 8
|
||||
- "loopback .* unnumbered target cannot point to itself"
|
||||
- "loopback .* unnumbered target .* cannot also be unnumbered"
|
||||
count: 12
|
||||
---
|
||||
loopbacks:
|
||||
loop0:
|
||||
unnumbered: loop1
|
||||
loop1:
|
||||
unnumbered: loop0
|
||||
loop2:
|
||||
unnumbered: loop2
|
||||
|
||||
interfaces:
|
||||
GigabitEthernet1/0/0:
|
||||
description: "Cannot point to the same interface"
|
||||
|
@ -3,12 +3,17 @@ test:
|
||||
errors:
|
||||
expected:
|
||||
- "(sub-)?interface .* cannot also have addresses when it is unnumbered"
|
||||
count: 3
|
||||
- "loopback .* cannot also have addresses when it is unnumbered"
|
||||
count: 4
|
||||
---
|
||||
loopbacks:
|
||||
loop0:
|
||||
mtu: 9216
|
||||
addresses: [ 192.0.2.1/32, 2001:db8:1::1/128 ]
|
||||
loop1:
|
||||
mtu: 9216
|
||||
unnumbered: loop0
|
||||
addresses: [ 192.0.2.13/32, 2001:db8:4::1/128 ]
|
||||
|
||||
interfaces:
|
||||
GigabitEthernet1/0/0:
|
||||
|
Reference in New Issue
Block a user