<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>
<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>
#include "sd-id128.h"
+#include "arphrd-util.h"
#include "id128-util.h"
#include "memory-util.h"
#include "networkd-address-generation.h"
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];
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) {
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:
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)