network: make generate_ipv6_eui_64_address() take prefix

Also, rename the function.
This commit is contained in:
Yu Watanabe
2021-10-07 01:03:06 +09:00
parent 397c5418f0
commit 00f1261d39
4 changed files with 34 additions and 42 deletions
+21 -26
View File
@@ -37,30 +37,29 @@ typedef struct IPv6Token {
struct in6_addr prefix;
} IPv6Token;
int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret) {
void generate_eui64_address(const Link *link, const struct in6_addr *prefix, struct in6_addr *ret) {
assert(link);
assert(prefix);
assert(ret);
if (link->iftype == ARPHRD_INFINIBAND) {
/* see RFC4391 section 8 */
memcpy(&ret->s6_addr[8], &link->hw_addr.infiniband[12], 8);
ret->s6_addr[8] ^= 1 << 1;
memcpy(ret->s6_addr, prefix, 8);
return 0;
if (link->iftype == ARPHRD_INFINIBAND)
/* Use last 8 byte. See RFC4391 section 8 */
memcpy(&ret->s6_addr[8], &link->hw_addr.infiniband[INFINIBAND_ALEN - 8], 8);
else {
/* 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[10] = link->hw_addr.ether.ether_addr_octet[2];
ret->s6_addr[11] = 0xff;
ret->s6_addr[12] = 0xfe;
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];
}
/* see RFC4291 section 2.5.1 */
ret->s6_addr[8] = link->hw_addr.ether.ether_addr_octet[0];
ret->s6_addr[8] ^= 1 << 1;
ret->s6_addr[9] = link->hw_addr.ether.ether_addr_octet[1];
ret->s6_addr[10] = link->hw_addr.ether.ether_addr_octet[2];
ret->s6_addr[11] = 0xff;
ret->s6_addr[12] = 0xfe;
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];
return 0;
}
static bool stable_private_address_is_valid(const struct in6_addr *addr) {
@@ -176,21 +175,17 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_
/* fall back to EUI-64 if no tokens provided addresses */
if (set_isempty(addresses)) {
_cleanup_free_ struct in6_addr *new_address = NULL;
struct in6_addr *addr;
new_address = newdup(struct in6_addr, address, 1);
if (!new_address)
addr = new(struct in6_addr, 1);
if (!addr)
return log_oom();
r = generate_ipv6_eui_64_address(link, new_address);
if (r < 0)
return log_link_error_errno(link, r, "Failed to generate EUI64 address: %m");
generate_eui64_address(link, address, addr);
r = set_put(addresses, new_address);
r = set_consume(addresses, addr);
if (r < 0)
return log_link_error_errno(link, r, "Failed to store SLAAC address: %m");
TAKE_PTR(new_address);
}
*ret = TAKE_PTR(addresses);
+1 -1
View File
@@ -7,7 +7,7 @@
typedef struct Link Link;
int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret);
void generate_eui64_address(const Link *link, const struct in6_addr *prefix, struct in6_addr *ret);
int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_t prefixlen, Set **ret);
+4 -8
View File
@@ -377,15 +377,11 @@ static int dhcp6_pd_request_address(
if (r < 0)
return log_link_error_errno(link, r, "Failed to allocate address for DHCPv6 delegated prefix: %m");
address->in_addr.in6 = *prefix;
if (in6_addr_is_set(&link->network->dhcp6_pd_token))
if (in6_addr_is_set(&link->network->dhcp6_pd_token)) {
memcpy(address->in_addr.in6.s6_addr, prefix->s6_addr, 8);
memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_pd_token.s6_addr + 8, 8);
else {
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to generate EUI64 address for acquired DHCPv6 delegated prefix: %m");
}
} else
generate_eui64_address(link, prefix, &address->in_addr.in6);
address->source = NETWORK_CONFIG_SOURCE_DHCP6PD;
address->prefixlen = 64;
+8 -7
View File
@@ -205,24 +205,25 @@ int link_request_radv_addresses(Link *link) {
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
_cleanup_(address_freep) Address *address = NULL;
struct in6_addr prefix;
uint8_t prefixlen;
if (!p->assign)
continue;
r = sd_radv_prefix_get_prefix(p->radv_prefix, &prefix, &prefixlen);
if (r < 0)
return r;
r = address_new(&address);
if (r < 0)
return log_oom();
r = sd_radv_prefix_get_prefix(p->radv_prefix, &address->in_addr.in6, &address->prefixlen);
if (r < 0)
return r;
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
if (r < 0)
return r;
generate_eui64_address(link, &prefix, &address->in_addr.in6);
address->source = NETWORK_CONFIG_SOURCE_STATIC;
address->family = AF_INET6;
address->prefixlen = prefixlen;
address->route_metric = p->route_metric;
r = link_request_static_address(link, TAKE_PTR(address), true);