summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2019-08-05 11:28:23 +0200
committerChristian Poessinger <christian@poessinger.com>2019-08-05 11:28:25 +0200
commitd765eef461e53241cf57bcb6b409dc6fec0efc92 (patch)
tree893e4f9ac72042d6a1cc3bd98bafa4c54db07601
parent6e9a0162f84a1baca9acf0ca675ab3c574c7e297 (diff)
downloadvyos-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.py28
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