summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Mangin <thomas.mangin@exa.net.uk>2020-03-30 22:31:29 +0100
committerThomas Mangin <thomas.mangin@exa.net.uk>2020-03-30 22:31:29 +0100
commite2f80e57d9895d207edf0ad92c299dc7862087d6 (patch)
treef7f3fcb13a09d2632d7f5fa914ae2f2e35dcee19
parent272d6a0968fb22bda0c82068ed1cbf7d9ddd3fd9 (diff)
downloadvyos-1x-e2f80e57d9895d207edf0ad92c299dc7862087d6.tar.gz
vyos-1x-e2f80e57d9895d207edf0ad92c299dc7862087d6.zip
validate: T2182: IPv6 are not normalised when compared
Adding an already existing IP address on an interface would cause the 'ip addr add' command to fail. To prevent this, the code checks if the IP already exists on the interface. The code was not normalising the different ways of representing the IPv6 address (trailing 0, ::, etc.).
-rw-r--r--python/vyos/validate.py32
1 files changed, 18 insertions, 14 deletions
diff --git a/python/vyos/validate.py b/python/vyos/validate.py
index 0e6d34e7e..b110a62fa 100644
--- a/python/vyos/validate.py
+++ b/python/vyos/validate.py
@@ -13,6 +13,7 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+import socket
import netifaces
import ipaddress
@@ -83,6 +84,8 @@ def is_intf_addr_assigned(intf, addr):
print(e)
return False
+ addr_host, addr_mask = addr.split('/')
+
if addr_type in netifaces.ifaddresses(intf).keys():
# Check every IP address on this interface for a match
for ip in netifaces.ifaddresses(intf)[addr_type]:
@@ -92,23 +95,24 @@ def is_intf_addr_assigned(intf, addr):
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)
-
+ # 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)
+ 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
+ # the netmask are different
+ if prefixlen != addr_mask:
+ continue
- elif ip['addr'] == addr:
- return True
+ addr_af = socket.AF_INET if is_ipv4(addr_host) else socket.AF_INET6
+ ip_af = socket.AF_INET if is_ipv4(ip['addr']) else socket.AF_INET6
+
+ # compare the binary representation of the IP
+ if socket.inet_pton(addr_af, addr_host) == socket.inet_pton(ip_af, ip['addr']):
+ return True
return False