Compare commits
9 Commits
15dd451535
...
1283366a90
Author | SHA1 | Date |
---|---|---|
Lennart Poettering | 1283366a90 | |
Lennart Poettering | a177f05a5c | |
Zbigniew Jędrzejewski-Szmek | 10b20e5a93 | |
Zbigniew Jędrzejewski-Szmek | d273579667 | |
Susant Sahani | a6f1848a23 | |
Susant Sahani | 7f20a9e5b9 | |
Zbigniew Jędrzejewski-Szmek | f198303902 | |
Zbigniew Jędrzejewski-Szmek | 5dc31db7c1 | |
Zbigniew Jędrzejewski-Szmek | a27060759b |
|
@ -193,6 +193,16 @@
|
||||||
This happens when multicast routing is enabled.</para>
|
This happens when multicast routing is enabled.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>IPv6LinkLocalAddressGenerationMode=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Specifies how IPv6 link local address is generated. Takes one of <literal>eui64</literal>,
|
||||||
|
<literal>none</literal>, <literal>stable-privacy</literal> and <literal>random</literal>.
|
||||||
|
When unset, the kernel's default will be used. Note that if <varname>LinkLocalAdressing=</varname>
|
||||||
|
not configured as <literal>ipv6</literal> then <varname>IPv6LinkLocalAddressGenerationMode=</varname>
|
||||||
|
is ignored.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Unmanaged=</varname></term>
|
<term><varname>Unmanaged=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -624,7 +624,7 @@ static int get_search(uint64_t type, char ***list) {
|
||||||
case SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH:
|
case SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH:
|
||||||
case SD_PATH_SYSTEMD_USER_GENERATOR_PATH: {
|
case SD_PATH_SYSTEMD_USER_GENERATOR_PATH: {
|
||||||
char **t;
|
char **t;
|
||||||
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH ?
|
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH ?
|
||||||
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
||||||
|
|
||||||
t = generator_binary_paths(scope);
|
t = generator_binary_paths(scope);
|
||||||
|
|
|
@ -453,7 +453,11 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns, b
|
||||||
r = sd_netlink_message_enter_container(m, AF_INET6);
|
r = sd_netlink_message_enter_container(m, AF_INET6);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
r = sd_netlink_message_read_u8(m, IFLA_INET6_ADDR_GEN_MODE, &info->addr_gen_mode);
|
r = sd_netlink_message_read_u8(m, IFLA_INET6_ADDR_GEN_MODE, &info->addr_gen_mode);
|
||||||
if (r >= 0)
|
if (r >= 0 && IN_SET(info->addr_gen_mode,
|
||||||
|
IN6_ADDR_GEN_MODE_EUI64,
|
||||||
|
IN6_ADDR_GEN_MODE_NONE,
|
||||||
|
IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
|
||||||
|
IN6_ADDR_GEN_MODE_RANDOM))
|
||||||
info->has_ipv6_address_generation_mode = true;
|
info->has_ipv6_address_generation_mode = true;
|
||||||
|
|
||||||
(void) sd_netlink_message_exit_container(m);
|
(void) sd_netlink_message_exit_container(m);
|
||||||
|
|
|
@ -954,7 +954,7 @@ int config_parse_lifetime(const char *unit,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
Network *network = userdata;
|
Network *network = userdata;
|
||||||
_cleanup_(address_free_or_set_invalidp) Address *n = NULL;
|
_cleanup_(address_free_or_set_invalidp) Address *n = NULL;
|
||||||
unsigned k;
|
uint32_t k;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
|
@ -967,8 +967,8 @@ int config_parse_lifetime(const char *unit,
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* We accept only "forever", "infinity", or "0". */
|
/* We accept only "forever", "infinity", empty, or "0". */
|
||||||
if (STR_IN_SET(rvalue, "forever", "infinity"))
|
if (STR_IN_SET(rvalue, "forever", "infinity", ""))
|
||||||
k = CACHE_INFO_INFINITY_LIFE_TIME;
|
k = CACHE_INFO_INFINITY_LIFE_TIME;
|
||||||
else if (streq(rvalue, "0"))
|
else if (streq(rvalue, "0"))
|
||||||
k = 0;
|
k = 0;
|
||||||
|
@ -979,7 +979,7 @@ int config_parse_lifetime(const char *unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
n->cinfo.ifa_prefered = k;
|
n->cinfo.ifa_prefered = k;
|
||||||
n = NULL;
|
TAKE_PTR(n);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,24 +21,15 @@ static Address* link_find_dhcp_server_address(Link *link) {
|
||||||
assert(link->network);
|
assert(link->network);
|
||||||
|
|
||||||
/* The first statically configured address if there is any */
|
/* The first statically configured address if there is any */
|
||||||
LIST_FOREACH(addresses, address, link->network->static_addresses) {
|
LIST_FOREACH(addresses, address, link->network->static_addresses)
|
||||||
|
if (address->family == AF_INET &&
|
||||||
if (address->family != AF_INET)
|
!in_addr_is_null(address->family, &address->in_addr))
|
||||||
continue;
|
|
||||||
|
|
||||||
if (in_addr_is_null(address->family, &address->in_addr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
|
||||||
|
|
||||||
/* If that didn't work, find a suitable address we got from the pool */
|
/* If that didn't work, find a suitable address we got from the pool */
|
||||||
LIST_FOREACH(addresses, address, link->pool_addresses) {
|
LIST_FOREACH(addresses, address, link->pool_addresses)
|
||||||
if (address->family != AF_INET)
|
if (address->family == AF_INET)
|
||||||
continue;
|
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -46,9 +37,8 @@ static Address* link_find_dhcp_server_address(Link *link) {
|
||||||
static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||||
_cleanup_free_ struct in_addr *addresses = NULL;
|
_cleanup_free_ struct in_addr *addresses = NULL;
|
||||||
size_t n_addresses = 0, n_allocated = 0;
|
size_t n_addresses = 0, n_allocated = 0;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < link->network->n_dns; i++) {
|
for (unsigned i = 0; i < link->network->n_dns; i++) {
|
||||||
struct in_addr ia;
|
struct in_addr ia;
|
||||||
|
|
||||||
/* Only look for IPv4 addresses */
|
/* Only look for IPv4 addresses */
|
||||||
|
@ -68,16 +58,14 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (link->network->dhcp_use_dns && link->dhcp_lease) {
|
if (link->network->dhcp_use_dns && link->dhcp_lease) {
|
||||||
const struct in_addr *da = NULL;
|
const struct in_addr *da;
|
||||||
int j, n;
|
|
||||||
|
|
||||||
n = sd_dhcp_lease_get_dns(link->dhcp_lease, &da);
|
int n = sd_dhcp_lease_get_dns(link->dhcp_lease, &da);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
|
|
||||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
|
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
for (j = 0; j < n; j++)
|
for (int j = 0; j < n; j++)
|
||||||
if (in4_addr_is_non_local(&da[j]))
|
if (in4_addr_is_non_local(&da[j]))
|
||||||
addresses[n_addresses++] = da[j];
|
addresses[n_addresses++] = da[j];
|
||||||
}
|
}
|
||||||
|
@ -160,12 +148,12 @@ static int link_push_uplink_to_dhcp_server(
|
||||||
if (lease_condition && link->dhcp_lease) {
|
if (lease_condition && link->dhcp_lease) {
|
||||||
const struct in_addr *da;
|
const struct in_addr *da;
|
||||||
|
|
||||||
size_t n = sd_dhcp_lease_get_servers(link->dhcp_lease, what, &da);
|
int n = sd_dhcp_lease_get_servers(link->dhcp_lease, what, &da);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
|
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
for (unsigned i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
if (in4_addr_is_non_local(&da[i]))
|
if (in4_addr_is_non_local(&da[i]))
|
||||||
addresses[n_addresses++] = da[i];
|
addresses[n_addresses++] = da[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1691,7 +1691,7 @@ int config_parse_dhcp_fallback_lease_lifetime(const char *unit,
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
Network *network = userdata;
|
Network *network = userdata;
|
||||||
unsigned k;
|
uint32_t k;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
assert(section);
|
assert(section);
|
||||||
|
|
|
@ -1692,12 +1692,18 @@ static int link_configure_addrgen_mode(Link *link) {
|
||||||
|
|
||||||
if (!link_ipv6ll_enabled(link))
|
if (!link_ipv6ll_enabled(link))
|
||||||
ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
|
ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
|
||||||
else if (sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL) < 0)
|
else if (link->network->ipv6_address_gen_mode < 0) {
|
||||||
|
r = sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL);
|
||||||
|
if (r < 0) {
|
||||||
/* The file may not exist. And even if it exists, when stable_secret is unset,
|
/* The file may not exist. And even if it exists, when stable_secret is unset,
|
||||||
* reading the file fails with EIO. */
|
* reading the file fails with EIO. */
|
||||||
|
log_link_debug_errno(link, r, "Failed to read sysctl property stable_secret: %m");
|
||||||
|
|
||||||
ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
|
ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
|
||||||
else
|
} else
|
||||||
ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
|
ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
|
||||||
|
} else
|
||||||
|
ipv6ll_mode = link->network->ipv6_address_gen_mode;
|
||||||
|
|
||||||
r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
|
r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -4434,6 +4440,16 @@ void link_clean(Link *link) {
|
||||||
link_unref(set_remove(link->manager->dirty_links, link));
|
link_unref(set_remove(link->manager->dirty_links, link));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* const link_ipv6_address_gen_mode_table[_LINK_IPV6_ADDRESS_GEN_MODE_MAX] = {
|
||||||
|
[LINK_IPV6_ADDRESSS_GEN_MODE_EUI64] = "eui64",
|
||||||
|
[LINK_IPV6_ADDRESSS_GEN_MODE_NONE] = "none",
|
||||||
|
[LINK_IPV6_ADDRESSS_GEN_MODE_STABLE_PRIVACY] = "stable-privacy",
|
||||||
|
[LINK_IPV6_ADDRESSS_GEN_MODE_RANDOM] = "random",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(link_ipv6_address_gen_mode, LinkIPv6AddressGenMode);
|
||||||
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_ipv6_address_gen_mode, link_ipv6_address_gen_mode, LinkIPv6AddressGenMode, "Failed to parse link IPv6 address generation mode");
|
||||||
|
|
||||||
static const char* const link_state_table[_LINK_STATE_MAX] = {
|
static const char* const link_state_table[_LINK_STATE_MAX] = {
|
||||||
[LINK_STATE_PENDING] = "pending",
|
[LINK_STATE_PENDING] = "pending",
|
||||||
[LINK_STATE_INITIALIZED] = "initialized",
|
[LINK_STATE_INITIALIZED] = "initialized",
|
||||||
|
|
|
@ -35,6 +35,15 @@ typedef enum LinkState {
|
||||||
_LINK_STATE_INVALID = -1
|
_LINK_STATE_INVALID = -1
|
||||||
} LinkState;
|
} LinkState;
|
||||||
|
|
||||||
|
typedef enum LinkIPv6AddressGenMode {
|
||||||
|
LINK_IPV6_ADDRESSS_GEN_MODE_EUI64 = IN6_ADDR_GEN_MODE_EUI64,
|
||||||
|
LINK_IPV6_ADDRESSS_GEN_MODE_NONE = IN6_ADDR_GEN_MODE_NONE,
|
||||||
|
LINK_IPV6_ADDRESSS_GEN_MODE_STABLE_PRIVACY = IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
|
||||||
|
LINK_IPV6_ADDRESSS_GEN_MODE_RANDOM = IN6_ADDR_GEN_MODE_RANDOM,
|
||||||
|
_LINK_IPV6_ADDRESS_GEN_MODE_MAX,
|
||||||
|
_LINK_IPV6_ADDRESS_GEN_MODE_INVALID = -1
|
||||||
|
} LinkIPv6AddressGenMode;
|
||||||
|
|
||||||
typedef struct Manager Manager;
|
typedef struct Manager Manager;
|
||||||
typedef struct Network Network;
|
typedef struct Network Network;
|
||||||
typedef struct Address Address;
|
typedef struct Address Address;
|
||||||
|
@ -209,6 +218,9 @@ int link_stop_clients(Link *link, bool may_keep_dhcp);
|
||||||
const char* link_state_to_string(LinkState s) _const_;
|
const char* link_state_to_string(LinkState s) _const_;
|
||||||
LinkState link_state_from_string(const char *s) _pure_;
|
LinkState link_state_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
const char* link_ipv6_address_gen_mode_to_string(LinkIPv6AddressGenMode s) _const_;
|
||||||
|
LinkIPv6AddressGenMode link_ipv6_address_gen_mode_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
uint32_t link_get_vrf_table(Link *link);
|
uint32_t link_get_vrf_table(Link *link);
|
||||||
uint32_t link_get_dhcp_route_table(Link *link);
|
uint32_t link_get_dhcp_route_table(Link *link);
|
||||||
uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
|
uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
|
||||||
|
@ -217,6 +229,8 @@ int link_request_set_nexthop(Link *link);
|
||||||
|
|
||||||
int link_reconfigure(Link *link, bool force);
|
int link_reconfigure(Link *link, bool force);
|
||||||
|
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_link_ipv6_address_gen_mode);
|
||||||
|
|
||||||
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
|
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
|
||||||
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg)
|
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg)
|
||||||
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
|
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
|
||||||
|
|
|
@ -51,6 +51,7 @@ Link.ARP, config_parse_tristate,
|
||||||
Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast)
|
Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast)
|
||||||
Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
|
Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
|
||||||
Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
|
Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
|
||||||
|
Link.IPv6LinkLocalAddressGenerationMode, config_parse_link_ipv6_address_gen_mode, 0, offsetof(Network, ipv6_address_gen_mode)
|
||||||
Link.RequiredForOnline, config_parse_required_for_online, 0, 0
|
Link.RequiredForOnline, config_parse_required_for_online, 0, 0
|
||||||
Network.Description, config_parse_string, 0, offsetof(Network, description)
|
Network.Description, config_parse_string, 0, offsetof(Network, description)
|
||||||
Network.Bridge, config_parse_ifname, 0, offsetof(Network, bridge_name)
|
Network.Bridge, config_parse_ifname, 0, offsetof(Network, bridge_name)
|
||||||
|
|
|
@ -461,7 +461,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||||
.ipv6_accept_ra_start_dhcp6_client = true,
|
.ipv6_accept_ra_start_dhcp6_client = true,
|
||||||
|
|
||||||
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
|
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
|
||||||
|
.ipv6_address_gen_mode = _LINK_IPV6_ADDRESS_GEN_MODE_INVALID,
|
||||||
.can_triple_sampling = -1,
|
.can_triple_sampling = -1,
|
||||||
.can_termination = -1,
|
.can_termination = -1,
|
||||||
.ip_service_type = -1,
|
.ip_service_type = -1,
|
||||||
|
|
|
@ -259,6 +259,7 @@ struct Network {
|
||||||
bool configure_without_carrier;
|
bool configure_without_carrier;
|
||||||
bool ignore_carrier_loss;
|
bool ignore_carrier_loss;
|
||||||
KeepConfiguration keep_configuration;
|
KeepConfiguration keep_configuration;
|
||||||
|
LinkIPv6AddressGenMode ipv6_address_gen_mode;
|
||||||
uint32_t iaid;
|
uint32_t iaid;
|
||||||
DUID duid;
|
DUID duid;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ MTUBytes=
|
||||||
Multicast=
|
Multicast=
|
||||||
MACAddress=
|
MACAddress=
|
||||||
Group=
|
Group=
|
||||||
|
IPv6LinkLocalAddressGenerationMode=
|
||||||
[BridgeFDB]
|
[BridgeFDB]
|
||||||
VLANId=
|
VLANId=
|
||||||
MACAddress=
|
MACAddress=
|
||||||
|
|
Loading…
Reference in New Issue