diff options
author | Christian Poessinger <christian@poessinger.com> | 2019-08-05 11:28:23 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2019-08-05 11:28:25 +0200 |
commit | d765eef461e53241cf57bcb6b409dc6fec0efc92 (patch) | |
tree | 893e4f9ac72042d6a1cc3bd98bafa4c54db07601 | |
parent | 6e9a0162f84a1baca9acf0ca675ab3c574c7e297 (diff) | |
download | vyos-1x-d765eef461e53241cf57bcb6b409dc6fec0efc92.tar.gz vyos-1x-d765eef461e53241cf57bcb6b409dc6fec0efc92.zip |
Python/VyOS validate: extend is_intf_addr_assigned()
Verify if the given IPv4/IPv6 address is assigned to specific interface. It can
check both a single IP address (e.g. 192.0.2.1 or a assigned CIDR address
192.0.2.1/24.
Used testbench:
===============
20: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
inet 192.0.2.1/24 brd 192.0.2.255 scope global br0
inet 192.0.3.1/24 brd 192.0.3.255 scope global br0
inet6 2001:db8:2::ffff/64 scope global tentative
inet6 2001:db8:1::ffff/64 scope global tentative
is_intf_addr_assigned('br0', '192.0.2.1/24') -> True
is_intf_addr_assigned('br0', '192.0.2.1') -> True
is_intf_addr_assigned('br0', '2001:db8:2::ffff/64') -> True
is_intf_addr_assigned('br0', '2001:db8:2::ffff') -> True
is_intf_addr_assigned('br0', '192.0.100.1/24') -> False
is_intf_addr_assigned('br0', '192.0.100.1') -> False
is_intf_addr_assigned('br0', '2001:db8:100::ffff/64') -> False
is_intf_addr_assigned('br0', '2001:db8:100::ffff') -> False
-rw-r--r-- | python/vyos/validate.py | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/python/vyos/validate.py b/python/vyos/validate.py index fb7fa3051..97a401423 100644 --- a/python/vyos/validate.py +++ b/python/vyos/validate.py @@ -42,7 +42,9 @@ def is_ipv6(addr): def is_intf_addr_assigned(intf, addr): """ - Verify if the given IPv4/IPv6 address is assigned to specific interface + Verify if the given IPv4/IPv6 address is assigned to specific interface. + It can check both a single IP address (e.g. 192.0.2.1 or a assigned CIDR + address 192.0.2.1/24. """ # determine IP version (AF_INET or AF_INET6) depending on passed address @@ -61,8 +63,28 @@ def is_intf_addr_assigned(intf, addr): # Check every IP address on this interface for a match for ip in netifaces.ifaddresses(intf)[addr_type]: # Check if it matches to the address requested - if ip['addr'] == addr: - return True + # If passed address contains a '/' indicating a normalized IP + # address we have to take this into account, too + if r'/' in addr: + prefixlen = '' + if is_ipv6(addr): + # Note that currently expanded netmasks are not supported. That means + # 2001:db00::0/24 is a valid argument while 2001:db00::0/ffff:ff00:: not. + # see https://docs.python.org/3/library/ipaddress.html + bits = bin( int(ip['netmask'].replace(':',''), 16) ).count('1') + prefixlen = '/' + str(bits) + + else: + prefixlen = '/' + str(ipaddress.IPv4Network('0.0.0.0/' + ip['netmask']).prefixlen) + + # construct temporary variable holding IPv6 address and netmask + # in CIDR notation + tmp = ip['addr'] + prefixlen + if addr == tmp: + return True + + elif ip['addr'] == addr: + return True return False |