diff options
author | Christian Poessinger <christian@poessinger.com> | 2021-09-20 21:50:56 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2021-09-20 21:50:56 +0200 |
commit | 081e23996feb60ad903caf8b0a4587f5dacc69bf (patch) | |
tree | 2bf405bac832b8c4354f2a247e46431dfbcd2dde | |
parent | 672a70613aa6c987bca417f93b587eddccbfd53a (diff) | |
download | vyos-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-x | python/vyos/ifconfig/interface.py | 14 |
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 |