summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2021-09-26 12:28:37 +0200
committerChristian Poessinger <christian@poessinger.com>2021-09-26 12:36:19 +0200
commite4812d266ea841f8baf5ad6c7cfae1c7eba664b6 (patch)
tree0e659ded033cf139f86be067874d6c2d47852e56
parentbfe59076f8075083920143cfb4ae22617aa0c663 (diff)
downloadvyos-1x-e4812d266ea841f8baf5ad6c7cfae1c7eba664b6.tar.gz
vyos-1x-e4812d266ea841f8baf5ad6c7cfae1c7eba664b6.zip
vyos.ifconfig: T3860: bugfix in get_mac_synthetic()
Commit 081e23996f (vyos.ifconfig: get_mac_synthetic() must generate a stable "MAC") calculated a "stable" synthetic MAC address per the interface based on UUID and the interface name. The problem is that this calculation is too stable when run on multiple instances of VyOS on different hosts/hypervisors. Having R1 and R2 setup a connection both via "tun10" interface will become the same "synthetic" MAC address manifesting in the same link-local IPv6 address. This e.g. breaks OSPFv3 badly as both neighbors communicate using the same link-local address. As workaround one can: set interfaces tunnel tun1337 address 'fe80::1:1337/64' set interfaces tunnel tun1337 ipv6 address no-default-link-local This commit changes the way in how the synthetic MAC address is generated. It's based on the first 48 bits of a sha256 sum build from a CPU ID retrieved via DMI, the MAC address of eth0 and the interface name as used before. This should add enough entropy to get a stable pseudo MAC address. (cherry picked from commit 8d6861290f39298701b0a89bd358545763cee14b)
-rw-r--r--python/vyos/ifconfig/interface.py23
1 files changed, 16 insertions, 7 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 76f1e158a..709c70b65 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -27,8 +27,6 @@ from netifaces import ifaddresses
# this is not the same as socket.AF_INET/INET6
from netifaces import AF_INET
from netifaces import AF_INET6
-from uuid import uuid3
-from uuid import NAMESPACE_DNS
from vyos import ConfigError
from vyos.configdict import list_diff
@@ -439,11 +437,22 @@ class Interface(Control):
>>> Interface('eth0').get_mac()
'00:50:ab:cd:ef:00'
"""
- # calculate a UUID based on the interface name - this is as predictable
- # as an interface MAC address and thus can be used in the same way
- tmp = uuid3(NAMESPACE_DNS, self.ifname)
- # take the last 48 bits from the UUID string
- tmp = str(tmp).split('-')[-1]
+ from hashlib import sha256
+
+ # Get processor ID number
+ cpu_id = self._cmd('sudo dmidecode -t 4 | grep ID | head -n1 | sed "s/.*ID://;s/ //g"')
+ # Get system eth0 base MAC address - every system has eth0
+ eth0_mac = Interface('eth0').get_mac()
+
+ sha = sha256()
+ # Calculate SHA256 sum based on the CPU ID number, eth0 mac address and
+ # this interface identifier - this is as predictable as an interface
+ # MAC address and thus can be used in the same way
+ sha.update(cpu_id.encode())
+ sha.update(eth0_mac.encode())
+ sha.update(self.ifname.encode())
+ # take the most significant 48 bits from the SHA256 string
+ tmp = sha.hexdigest()[:12]
# Convert pseudo random string into EUI format which now represents a
# MAC address
tmp = EUI(tmp).value