summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-12-06 09:33:14 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-12-06 21:07:12 +0900
commitab106a609bc253c0dc49667e981108110b3a87a5 (patch)
tree1d573660001669101b176be85ee13bdf1a5c7563
parentec1574cd8ed6a7ca3386eca61aae92ce989b1f05 (diff)
downloadsystemd-ab106a609bc253c0dc49667e981108110b3a87a5.tar.gz
network: eui64 address is supported only ethernet or infiniband
So, this makes prefixstable mode will be used for other interface types.
-rw-r--r--man/systemd.network.xml8
-rw-r--r--src/network/networkd-address-generation.c25
2 files changed, 25 insertions, 8 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 82d50c9569..0714ebcd77 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2208,7 +2208,8 @@ Table=1234</programlisting></para>
<term><option>eui64</option></term>
<listitem>
<para>
- The EUI-64 algorithm will be used to generate an address for that prefix.
+ The EUI-64 algorithm will be used to generate an address for that prefix. Only
+ supported by Ethernet or InfiniBand interfaces.
</para>
</listitem>
</varlistentry>
@@ -2267,8 +2268,9 @@ Table=1234</programlisting></para>
<para>If no address generation mode is specified (which is the default), or a received
prefix does not match any of the addresses provided in <literal>prefixstable</literal>
- mode, then the EUI-64 algorithm will be used to form an interface identifier for that
- prefix.</para>
+ mode, then the EUI-64 algorithm will be used for Ethernet or InfiniBand interfaces,
+ otherwise <literal>prefixstable</literal> will be used to form an interface identifier for
+ that prefix.</para>
<para>This setting can be specified multiple times. If an empty string is assigned, then
the all previous assignments are cleared.</para>
diff --git a/src/network/networkd-address-generation.c b/src/network/networkd-address-generation.c
index 0d7d3ee653..1e119732c5 100644
--- a/src/network/networkd-address-generation.c
+++ b/src/network/networkd-address-generation.c
@@ -4,6 +4,7 @@
#include "sd-id128.h"
+#include "arphrd-util.h"
#include "id128-util.h"
#include "memory-util.h"
#include "networkd-address-generation.h"
@@ -39,17 +40,19 @@ typedef struct IPv6Token {
sd_id128_t secret_key;
} IPv6Token;
-static void generate_eui64_address(const Link *link, const struct in6_addr *prefix, struct in6_addr *ret) {
+static int generate_eui64_address(const Link *link, const struct in6_addr *prefix, struct in6_addr *ret) {
assert(link);
assert(prefix);
assert(ret);
memcpy(ret->s6_addr, prefix, 8);
- if (link->iftype == ARPHRD_INFINIBAND)
+ switch (link->iftype) {
+ case ARPHRD_INFINIBAND:
/* Use last 8 byte. See RFC4391 section 8 */
memcpy(&ret->s6_addr[8], &link->hw_addr.infiniband[INFINIBAND_ALEN - 8], 8);
- else {
+ break;
+ case ARPHRD_ETHER:
/* see RFC4291 section 2.5.1 */
ret->s6_addr[8] = link->hw_addr.ether.ether_addr_octet[0];
ret->s6_addr[9] = link->hw_addr.ether.ether_addr_octet[1];
@@ -59,9 +62,15 @@ static void generate_eui64_address(const Link *link, const struct in6_addr *pref
ret->s6_addr[13] = link->hw_addr.ether.ether_addr_octet[3];
ret->s6_addr[14] = link->hw_addr.ether.ether_addr_octet[4];
ret->s6_addr[15] = link->hw_addr.ether.ether_addr_octet[5];
+ break;
+ default:
+ return log_link_debug_errno(link, SYNTHETIC_ERRNO(EINVAL),
+ "Token=eui64 is not supported for interface type %s, ignoring.",
+ strna(arphrd_to_name(link->iftype)));
}
ret->s6_addr[8] ^= 1 << 1;
+ return 0;
}
static bool stable_private_address_is_valid(const struct in6_addr *addr) {
@@ -188,7 +197,8 @@ static int generate_addresses(
switch (j->type) {
case ADDRESS_GENERATION_EUI64:
- generate_eui64_address(link, &masked, &addr);
+ if (generate_eui64_address(link, &masked, &addr) < 0)
+ continue;
break;
case ADDRESS_GENERATION_STATIC:
@@ -226,7 +236,12 @@ static int generate_addresses(
if (!addr)
return -ENOMEM;
- generate_eui64_address(link, &masked, addr);
+ if (IN_SET(link->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND))
+ r = generate_eui64_address(link, &masked, addr);
+ else
+ r = generate_stable_private_address(link, app_id, &SD_ID128_NULL, &masked, addr);
+ if (r < 0)
+ return r;
r = set_ensure_consume(&addresses, &in6_addr_hash_ops_free, addr);
if (r < 0)