diff options
author | Umut Tezduyar Lindskog <umut.tezduyar@axis.com> | 2014-03-21 19:23:35 +0100 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-03-21 20:24:10 +0100 |
commit | b5db00e52ee2e20578839e4e4488f7b9af9abc38 (patch) | |
tree | b17e48e7d09372e8d7e9b4e86356711d169a16cf /src/shared | |
parent | 18bb8adb06002a5963a3373fa30c12cfa89b9724 (diff) |
sd-ipv4ll/networkd: generate predictable addresses
Increase the chance of using the same link local address between reboots. The
pseudo random sequence of addresses we attempt is now seeded with data that is
very likely to stay the same between reboots, but at the same time be unique
to the specific machine/nic.
First we try to use the ID_NET_NAME_* data from the udev db combined with the
machin-id, which is guaranteed to be unique and persistent, if available. If
that is not possible (e.g., in containers where we don't have access to the
udev db) we fallback to using the MAC address of the interface, which is
guaranteed to be unique, and likely to be persistent.
[tomegun: three minor changes:
- don't expose HASH_KEY in the siphash24 header
- get rid of some compile-warnings (and some casts at the same time),
by using uint8_t[8] rather than uint64_t in the api
- added commit message]
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/net-util.c | 39 | ||||
-rw-r--r-- | src/shared/net-util.h | 2 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/shared/net-util.c b/src/shared/net-util.c index 50cfa2c3f3..1c223117b8 100644 --- a/src/shared/net-util.c +++ b/src/shared/net-util.c @@ -24,6 +24,9 @@ #include <arpa/inet.h> #include <fnmatch.h> +#include "strv.h" +#include "siphash24.h" +#include "libudev-private.h" #include "net-util.h" #include "log.h" #include "utf8.h" @@ -31,6 +34,42 @@ #include "conf-parser.h" #include "condition.h" +#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a) + +int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]) { + size_t l, sz = 0; + const char *name, *field = NULL; + int r; + uint8_t *v; + + /* fetch some persistent data unique (on this machine) to this device */ + FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") { + name = udev_device_get_property_value(device, field); + if (name) + break; + } + + if (!name) + return -ENOENT; + + l = strlen(name); + sz = sizeof(sd_id128_t) + l; + v = alloca(sz); + + /* fetch some persistent data unique to this machine */ + r = sd_id128_get_machine((sd_id128_t*) v); + if (r < 0) + return r; + memcpy(v + sizeof(sd_id128_t), name, l); + + /* Let's hash the machine ID plus the device name. We + * use a fixed, but originally randomly created hash + * key here. */ + siphash24(result, v, sz, HASH_KEY.bytes); + + return 0; +} + bool net_match_config(const struct ether_addr *match_mac, const char *match_path, const char *match_driver, diff --git a/src/shared/net-util.h b/src/shared/net-util.h index 99479e1f5c..4a8d3f9fdf 100644 --- a/src/shared/net-util.h +++ b/src/shared/net-util.h @@ -62,3 +62,5 @@ int config_parse_ifalias(const char *unit, const char *filename, unsigned line, int ltype, const char *rvalue, void *data, void *userdata); int net_parse_inaddr(const char *address, unsigned char *family, void *dst); + +int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]); |