summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2021-09-20 21:50:56 +0200
committerChristian Poessinger <christian@poessinger.com>2021-09-20 21:50:56 +0200
commit081e23996feb60ad903caf8b0a4587f5dacc69bf (patch)
tree2bf405bac832b8c4354f2a247e46431dfbcd2dde
parent672a70613aa6c987bca417f93b587eddccbfd53a (diff)
downloadvyos-1x-081e23996feb60ad903caf8b0a4587f5dacc69bf.tar.gz
vyos-1x-081e23996feb60ad903caf8b0a4587f5dacc69bf.zip
vyos.ifconfig: get_mac_synthetic() must generate a stable "MAC"
Commit b7d30137b1 ("vyos.ifconfig: provide generic get_mac_synthetic() method") provided a common helper to generate MAC addresses used by EUI64 addresses for interfaces not having a layer2 interface (WireGuard or ip tunnel). The problem is that every call to the helper always yielded a new MAC address. This becomes problematic when IPv6 link-local addresses are generated and modified on the interface as multiple link-local (fe80::/64) addresses can easily be added to the interface leaving ... a mess. This commit changes the way how the "synthetic" MAC is generated, we generate a UUID which is stable as it is based on the interface name. We take out the last 48 bits of the UUID and form the "MAC" address.
-rwxr-xr-xpython/vyos/ifconfig/interface.py14
1 files changed, 10 insertions, 4 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 963f47c89..0256ca5df 100755
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -27,6 +27,8 @@ 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
@@ -56,7 +58,6 @@ from vyos.ifconfig import Section
from netaddr import EUI
from netaddr import mac_unix_expanded
-from random import getrandbits
class Interface(Control):
# This is the class which will be used to create
@@ -458,9 +459,14 @@ class Interface(Control):
>>> Interface('eth0').get_mac()
'00:50:ab:cd:ef:00'
"""
- # we choose 40 random bytes for the MAC address, this gives
- # us e.g. EUI('00-EA-EE-D6-A3-C8') or EUI('00-41-B9-0D-F2-2A')
- tmp = EUI(getrandbits(48)).value
+ # 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]
+ # Convert pseudo random string into EUI format which now represents a
+ # MAC address
+ tmp = EUI(tmp).value
# set locally administered bit in MAC address
tmp |= 0xf20000000000
# convert integer to "real" MAC address representation