mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
99 lines
3.3 KiB
C
99 lines
3.3 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include "netdev-util.h"
|
|
#include "networkd-address.h"
|
|
#include "networkd-link.h"
|
|
#include "set.h"
|
|
#include "string-table.h"
|
|
|
|
static const char * const netdev_local_address_type_table[_NETDEV_LOCAL_ADDRESS_TYPE_MAX] = {
|
|
[NETDEV_LOCAL_ADDRESS_IPV4LL] = "ipv4_link_local",
|
|
[NETDEV_LOCAL_ADDRESS_IPV6LL] = "ipv6_link_local",
|
|
[NETDEV_LOCAL_ADDRESS_DHCP4] = "dhcp4",
|
|
[NETDEV_LOCAL_ADDRESS_DHCP6] = "dhcp6",
|
|
[NETDEV_LOCAL_ADDRESS_SLAAC] = "slaac",
|
|
[NETDEV_LOCAL_ADDRESS_DHCP_PD] = "dhcp_pd",
|
|
};
|
|
|
|
DEFINE_STRING_TABLE_LOOKUP(netdev_local_address_type, NetDevLocalAddressType);
|
|
|
|
int link_get_local_address(
|
|
Link *link,
|
|
NetDevLocalAddressType type,
|
|
int family,
|
|
int *ret_family,
|
|
union in_addr_union *ret_address) {
|
|
|
|
Address *a;
|
|
|
|
assert(link);
|
|
|
|
switch (type) {
|
|
case NETDEV_LOCAL_ADDRESS_IPV4LL:
|
|
case NETDEV_LOCAL_ADDRESS_DHCP4:
|
|
assert(IN_SET(family, AF_UNSPEC, AF_INET));
|
|
family = AF_INET;
|
|
break;
|
|
case NETDEV_LOCAL_ADDRESS_IPV6LL:
|
|
case NETDEV_LOCAL_ADDRESS_DHCP6:
|
|
case NETDEV_LOCAL_ADDRESS_SLAAC:
|
|
case NETDEV_LOCAL_ADDRESS_DHCP_PD:
|
|
assert(IN_SET(family, AF_UNSPEC, AF_INET6));
|
|
family = AF_INET6;
|
|
break;
|
|
default:
|
|
assert_not_reached();
|
|
}
|
|
|
|
if (!link_is_ready_to_configure(link, /* allow_unmanaged = */ false))
|
|
return -EBUSY;
|
|
|
|
SET_FOREACH(a, link->addresses) {
|
|
if (!address_is_ready(a))
|
|
continue;
|
|
|
|
if (a->family != family)
|
|
continue;
|
|
|
|
if (in_addr_is_set(a->family, &a->in_addr_peer))
|
|
continue;
|
|
|
|
switch (type) {
|
|
case NETDEV_LOCAL_ADDRESS_IPV4LL:
|
|
if (a->source != NETWORK_CONFIG_SOURCE_IPV4LL)
|
|
continue;
|
|
break;
|
|
case NETDEV_LOCAL_ADDRESS_IPV6LL:
|
|
if (!in6_addr_is_link_local(&a->in_addr.in6))
|
|
continue;
|
|
break;
|
|
case NETDEV_LOCAL_ADDRESS_DHCP4:
|
|
if (a->source != NETWORK_CONFIG_SOURCE_DHCP4)
|
|
continue;
|
|
break;
|
|
case NETDEV_LOCAL_ADDRESS_DHCP6:
|
|
if (a->source != NETWORK_CONFIG_SOURCE_DHCP6)
|
|
continue;
|
|
break;
|
|
case NETDEV_LOCAL_ADDRESS_SLAAC:
|
|
if (a->source != NETWORK_CONFIG_SOURCE_NDISC)
|
|
continue;
|
|
break;
|
|
case NETDEV_LOCAL_ADDRESS_DHCP_PD:
|
|
if (a->source != NETWORK_CONFIG_SOURCE_DHCP_PD)
|
|
continue;
|
|
break;
|
|
default:
|
|
assert_not_reached();
|
|
}
|
|
|
|
if (ret_family)
|
|
*ret_family = a->family;
|
|
if (ret_address)
|
|
*ret_address = a->in_addr;
|
|
return 1;
|
|
}
|
|
|
|
return -ENXIO;
|
|
}
|