Merge pull request #16396 from yuwata/network-configured-flag

network: about xxx_configured flags
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-07-15 15:45:38 +02:00 committed by GitHub
commit 95b29f3267
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 559 additions and 260 deletions

View File

@ -288,7 +288,7 @@ int link_set_bond(Link *link) {
r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);

View File

@ -218,7 +218,7 @@ int link_set_bridge(Link *link) {
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
}
if (link->network->allow_port_to_be_root >= 0) {
if (link->network->allow_port_to_be_root >= 0) {
r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");

View File

@ -1662,7 +1662,7 @@ static int link_status_one(
r = table_add_many(table,
TABLE_EMPTY,
TABLE_STRING, "Mode:",
TABLE_STRING, bond_mode_to_string(info->mode),
TABLE_STRING, bond_mode_to_string(info->mode),
TABLE_EMPTY,
TABLE_STRING, "Miimon:",
TABLE_TIMESPAN_MSEC, jiffies_to_usec(info->miimon),

View File

@ -444,6 +444,8 @@ static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EADDRNOTAVAIL)
log_link_message_warning_errno(link, m, r, "Could not drop address");
else
(void) manager_rtnl_process_address(rtnl, m, link->manager);
return 1;
}

View File

@ -20,12 +20,12 @@
#include "sysctl-util.h"
#include "web-util.h"
static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all, link_netlink_message_handler_t callback);
static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all, link_netlink_message_handler_t callback);
static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all, link_netlink_message_handler_t callback);
static int dhcp_remove_address(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, link_netlink_message_handler_t callback);
static int dhcp_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link);
static int dhcp_lease_renew(sd_dhcp_client *client, Link *link);
static int dhcp4_update_address(Link *link, bool announce);
static int dhcp4_remove_all(Link *link);
void dhcp4_release_old_lease(Link *link) {
struct in_addr address = {}, address_old = {};
@ -40,9 +40,9 @@ void dhcp4_release_old_lease(Link *link) {
(void) sd_dhcp_lease_get_address(link->dhcp_lease_old, &address_old);
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
(void) dhcp_remove_routes(link, link->dhcp_lease_old, &address_old, false);
(void) dhcp_remove_router(link, link->dhcp_lease_old, &address_old, false);
(void) dhcp_remove_dns_routes(link, link->dhcp_lease_old, &address_old, false);
(void) dhcp_remove_routes(link, link->dhcp_lease_old, &address_old, false, NULL);
(void) dhcp_remove_router(link, link->dhcp_lease_old, &address_old, false, NULL);
(void) dhcp_remove_dns_routes(link, link->dhcp_lease_old, &address_old, false, NULL);
if (!in4_addr_equal(&address_old, &address))
(void) dhcp_remove_address(link, link->dhcp_lease_old, &address_old, NULL);
@ -88,17 +88,12 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
if (link->dhcp4_messages == 0) {
if (link->dhcp4_route_failed) {
struct in_addr address = {};
link->dhcp4_route_failed = false;
link->dhcp4_route_retrying = true;
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
(void) dhcp_remove_routes(link, link->dhcp_lease, &address, true);
(void) dhcp_remove_router(link, link->dhcp_lease, &address, true);
(void) dhcp_remove_dns_routes(link, link->dhcp_lease, &address, true);
(void) dhcp_remove_address(link, link->dhcp_lease, &address, dhcp_remove_address_handler);
r = dhcp4_remove_all(link);
if (r < 0)
link_enter_failed(link);
return 1;
}
if (!link->network->dhcp_send_decline)
@ -177,7 +172,7 @@ static int link_set_dns_routes(Link *link, const struct in_addr *address) {
r = route_new(&route);
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
return log_link_error_errno(link, r, "Could not allocate route: %m");
/* Set routes to DNS servers. */
@ -266,7 +261,7 @@ static int link_set_dhcp_routes(Link *link) {
r = dhcp_prefix_route_from_lease(link->dhcp_lease, table, &address, &prefix_route);
if (r < 0)
return log_link_error_errno(link, r, "Could not create prefix route: %m");
return log_link_error_errno(link, r, "Could not create prefix route: %m");
r = dhcp_route_configure(&prefix_route, link);
if (r < 0)
@ -344,7 +339,7 @@ static int link_set_dhcp_routes(Link *link) {
r = route_new(&route_gw);
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
return log_link_error_errno(link, r, "Could not allocate route: %m");
/* The dhcp netmask may mask out the gateway. Add an explicit
* route for the gw host so that we can route no matter the
@ -401,7 +396,26 @@ static int link_set_dhcp_routes(Link *link) {
return link_set_dns_routes(link, &address);
}
static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all) {
static int dhcp_route_remove(Route *route, Link *link, link_netlink_message_handler_t callback) {
int r;
r = route_remove(route, link, callback);
if (r < 0)
return r;
if (callback)
link->dhcp4_remove_messages++;
return 0;
}
static int dhcp_remove_routes(
Link *link,
sd_dhcp_lease *lease,
const struct in_addr *address,
bool remove_all,
link_netlink_message_handler_t callback) {
_cleanup_free_ sd_dhcp_route **routes = NULL;
uint32_t table;
int n, i, r;
@ -440,13 +454,21 @@ static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, const struct in_
if (!remove_all && set_contains(link->dhcp_routes, route))
continue;
(void) route_remove(route, link, NULL);
r = dhcp_route_remove(route, link, callback);
if (r < 0)
return r;
}
return n;
}
static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all) {
static int dhcp_remove_router(
Link *link,
sd_dhcp_lease *lease,
const struct in_addr *address,
bool remove_all,
link_netlink_message_handler_t callback) {
_cleanup_(route_freep) Route *route_gw = NULL, *route = NULL;
const struct in_addr *router;
uint32_t table;
@ -484,8 +506,11 @@ static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_
route_gw->priority = link->network->dhcp_route_metric;
route_gw->table = table;
if (remove_all || !set_contains(link->dhcp_routes, route_gw))
(void) route_remove(route_gw, link, NULL);
if (remove_all || !set_contains(link->dhcp_routes, route_gw)) {
r = dhcp_route_remove(route_gw, link, callback);
if (r < 0)
return r;
}
r = route_new(&route);
if (r < 0)
@ -498,8 +523,11 @@ static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_
route->priority = link->network->dhcp_route_metric;
route->table = table;
if (remove_all || !set_contains(link->dhcp_routes, route))
(void) route_remove(route, link, NULL);
if (remove_all || !set_contains(link->dhcp_routes, route)) {
r = dhcp_route_remove(route, link, callback);
if (r < 0)
return r;
}
Route *rt;
LIST_FOREACH(routes, rt, link->network->static_routes) {
@ -512,13 +540,21 @@ static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_
if (!remove_all && in4_addr_equal(router, &rt->gw.in))
continue;
(void) route_remove(rt, link, NULL);
r = dhcp_route_remove(rt, link, callback);
if (r < 0)
return r;
}
return 0;
}
static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all) {
static int dhcp_remove_dns_routes(
Link *link,
sd_dhcp_lease *lease,
const struct in_addr *address,
bool remove_all,
link_netlink_message_handler_t callback) {
const struct in_addr *dns;
uint32_t table;
int i, n, r;
@ -544,7 +580,7 @@ static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct
r = route_new(&route);
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
return log_link_error_errno(link, r, "Could not allocate route: %m");
route->family = AF_INET;
route->dst.in = dns[i];
@ -558,7 +594,9 @@ static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct
if (!remove_all && set_contains(link->dhcp_routes, route))
continue;
(void) route_remove(route, link, NULL);
r = dhcp_route_remove(route, link, callback);
if (r < 0)
return r;
}
if (!link_prefixroute(link)) {
@ -566,36 +604,18 @@ static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct
r = dhcp_prefix_route_from_lease(lease, table, address, &prefix_route);
if (r < 0)
return log_link_warning_errno(link, r, "Could not delete prefix route: %m");
return log_link_warning_errno(link, r, "Could not create prefix route: %m");
if (remove_all || !set_contains(link->dhcp_routes, prefix_route))
(void) route_remove(prefix_route, link, NULL);
if (remove_all || !set_contains(link->dhcp_routes, prefix_route)) {
r = dhcp_route_remove(prefix_route, link, callback);
if (r < 0)
return r;
}
}
return 0;
}
static int dhcp_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
/* This is only used when retrying to assign the address received from DHCPv4 server.
* See dhcp4_route_handler(). */
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0)
log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 address, ignoring");
else
(void) manager_rtnl_process_address(rtnl, m, link->manager);
(void) dhcp_lease_renew(link->dhcp_client, link);
return 1;
}
static int dhcp_remove_address(
Link *link, sd_dhcp_lease *lease,
const struct in_addr *address,
@ -621,7 +641,12 @@ static int dhcp_remove_address(
if (sd_dhcp_lease_get_netmask(lease, &netmask) >= 0)
a->prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
(void) address_remove(a, link, callback);
r = address_remove(a, link, callback);
if (r < 0)
return r;
if (callback)
link->dhcp4_remove_messages++;
return 0;
}
@ -676,8 +701,90 @@ static int dhcp_reset_hostname(Link *link) {
return 0;
}
static int dhcp4_remove_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(m);
assert(link);
assert(link->dhcp4_remove_messages > 0);
link->dhcp4_remove_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -ESRCH)
log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 route, ignoring");
if (link->dhcp4_remove_messages == 0) {
r = dhcp4_update_address(link, false);
if (r < 0)
link_enter_failed(link);
}
return 1;
}
static int dhcp4_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(m);
assert(link);
assert(link->dhcp4_remove_messages > 0);
link->dhcp4_remove_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EADDRNOTAVAIL)
log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 address, ignoring");
else
(void) manager_rtnl_process_address(rtnl, m, link->manager);
if (link->dhcp4_remove_messages == 0) {
r = dhcp4_update_address(link, false);
if (r < 0)
link_enter_failed(link);
}
return 1;
}
static int dhcp4_remove_all(Link *link) {
struct in_addr address;
int r;
assert(link);
assert(link->dhcp_lease);
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
if (r < 0)
return log_link_error_errno(link, r, "Failed to get DHCPv4 address: %m");
r = dhcp_remove_routes(link, link->dhcp_lease, &address, true, dhcp4_remove_route_handler);
if (r < 0)
return r;
r = dhcp_remove_router(link, link->dhcp_lease, &address, true, dhcp4_remove_route_handler);
if (r < 0)
return r;
r = dhcp_remove_dns_routes(link, link->dhcp_lease, &address, true, dhcp4_remove_route_handler);
if (r < 0)
return r;
r = dhcp_remove_address(link, link->dhcp_lease, &address, dhcp4_remove_address_handler);
if (r < 0)
return r;
return 0;
}
static int dhcp_lease_lost(Link *link) {
struct in_addr address = {};
int r;
assert(link);
assert(link->dhcp_lease);
@ -686,13 +793,17 @@ static int dhcp_lease_lost(Link *link) {
link->dhcp4_configured = false;
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
(void) dhcp_remove_routes(link, link->dhcp_lease, &address, true);
(void) dhcp_remove_router(link, link->dhcp_lease, &address, true);
(void) dhcp_remove_dns_routes(link, link->dhcp_lease, &address, true);
(void) dhcp_remove_address(link, link->dhcp_lease, &address, NULL);
(void) dhcp_reset_mtu(link);
(void) dhcp_reset_hostname(link);
r = dhcp4_remove_all(link);
if (r < 0)
return r;
r = dhcp_reset_mtu(link);
if (r < 0)
return r;
r = dhcp_reset_hostname(link);
if (r < 0)
return r;
link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
link_dirty(link);
@ -830,30 +941,81 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
return 1;
}
static int dhcp4_update_address(Link *link,
struct in_addr *address,
struct in_addr *netmask,
uint32_t lifetime) {
static int dhcp4_update_address(Link *link, bool announce) {
_cleanup_(address_freep) Address *addr = NULL;
uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
struct in_addr address, netmask;
unsigned prefixlen;
int r;
assert(address);
assert(netmask);
assert(lifetime);
assert(link);
assert(link->network);
prefixlen = in4_addr_netmask_to_prefixlen(netmask);
if (!link->dhcp_lease)
return 0;
link_set_state(link, LINK_STATE_CONFIGURING);
link->dhcp4_configured = false;
/* address_handler calls link_request_set_routes() and link_request_set_nexthop(). Before they
* are called, the related flags must be cleared. Otherwise, the link becomes configured state
* before routes are configured. */
link->static_routes_configured = false;
link->static_nexthops_configured = false;
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no address: %m");
r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no netmask: %m");
if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
}
prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
if (announce) {
const struct in_addr *router;
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
if (r < 0 && r != -ENODATA)
return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
if (r > 0 && !in4_addr_is_null(&router[0]))
log_struct(LOG_INFO,
LOG_LINK_INTERFACE(link),
LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
ADDRESS_FMT_VAL(address),
prefixlen,
ADDRESS_FMT_VAL(router[0])),
"ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
"PREFIXLEN=%u", prefixlen,
"GATEWAY=%u.%u.%u.%u", ADDRESS_FMT_VAL(router[0]));
else
log_struct(LOG_INFO,
LOG_LINK_INTERFACE(link),
LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u",
ADDRESS_FMT_VAL(address),
prefixlen),
"ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
"PREFIXLEN=%u", prefixlen);
}
r = address_new(&addr);
if (r < 0)
return r;
return log_oom();
addr->family = AF_INET;
addr->in_addr.in.s_addr = address->s_addr;
addr->in_addr.in.s_addr = address.s_addr;
addr->cinfo.ifa_prefered = lifetime;
addr->cinfo.ifa_valid = lifetime;
addr->prefixlen = prefixlen;
addr->broadcast.s_addr = address->s_addr | ~netmask->s_addr;
addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
addr->prefix_route = link_prefixroute(link);
/* allow reusing an existing address and simply update its lifetime
@ -867,102 +1029,34 @@ static int dhcp4_update_address(Link *link,
static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
sd_dhcp_lease *lease;
struct in_addr address;
struct in_addr netmask;
uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
int r;
assert(link);
assert(client);
assert(link->network);
r = sd_dhcp_client_get_lease(client, &lease);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no lease: %m");
sd_dhcp_lease_unref(link->dhcp_lease);
link->dhcp4_configured = false;
link->dhcp_lease = sd_dhcp_lease_ref(lease);
link_dirty(link);
r = sd_dhcp_lease_get_address(lease, &address);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no address: %m");
r = sd_dhcp_lease_get_netmask(lease, &netmask);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no netmask: %m");
if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
}
r = dhcp4_update_address(link, &address, &netmask, lifetime);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update IP address: %m");
return 0;
return dhcp4_update_address(link, false);
}
static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
const struct in_addr *router;
sd_dhcp_lease *lease;
struct in_addr address;
struct in_addr netmask;
unsigned prefixlen;
uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
int r;
assert(client);
assert(link);
link->dhcp4_configured = false;
r = sd_dhcp_client_get_lease(client, &lease);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: No lease: %m");
r = sd_dhcp_lease_get_address(lease, &address);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: No address: %m");
r = sd_dhcp_lease_get_netmask(lease, &netmask);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: No netmask: %m");
prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
r = sd_dhcp_lease_get_lifetime(lease, &lifetime);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
}
r = sd_dhcp_lease_get_router(lease, &router);
if (r < 0 && r != -ENODATA)
return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
if (r > 0 && !in4_addr_is_null(&router[0]))
log_struct(LOG_INFO,
LOG_LINK_INTERFACE(link),
LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
ADDRESS_FMT_VAL(address),
prefixlen,
ADDRESS_FMT_VAL(router[0])),
"ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
"PREFIXLEN=%u", prefixlen,
"GATEWAY=%u.%u.%u.%u", ADDRESS_FMT_VAL(router[0]));
else
log_struct(LOG_INFO,
LOG_LINK_INTERFACE(link),
LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u",
ADDRESS_FMT_VAL(address),
prefixlen),
"ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
"PREFIXLEN=%u", prefixlen);
sd_dhcp_lease_unref(link->dhcp_lease);
link->dhcp_lease = sd_dhcp_lease_ref(lease);
link_dirty(link);
@ -1013,9 +1107,14 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
}
}
r = dhcp4_update_address(link, &address, &netmask, lifetime);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update IP address: %m");
if (link->dhcp4_remove_messages == 0) {
r = dhcp4_update_address(link, true);
if (r < 0)
return r;
} else
log_link_debug(link,
"The link has previously assigned DHCPv4 address or routes. "
"The newly assigned address and routes will set up after old ones are removed.");
return 0;
}

View File

@ -24,7 +24,6 @@
#include "radv-internal.h"
#include "web-util.h"
static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
static Link *dhcp6_prefix_get(Manager *m, struct in6_addr *addr);
static int dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link);
static int dhcp6_prefix_remove_all(Manager *m, Link *link);
@ -33,7 +32,7 @@ static int dhcp6_assign_delegated_prefix(Link *link, const struct in6_addr *pref
uint32_t lifetime_preferred,
uint32_t lifetime_valid);
static bool dhcp6_get_prefix_delegation(Link *link) {
bool dhcp6_get_prefix_delegation(Link *link) {
if (!link->network)
return false;
@ -125,7 +124,7 @@ static int dhcp6_get_preferred_delegated_prefix(
r = in_addr_prefix_next(AF_INET6, &prefix, 64);
if (r < 0)
return log_link_error_errno(link, r, "Can't allocate another prefix. Out of address space?");
return log_link_error_errno(link, r, "Can't allocate another prefix. Out of address space?: %m");
}
return log_link_warning_errno(link, SYNTHETIC_ERRNO(ERANGE), "Couldn't find a suitable prefix. Ran out of address space.");
@ -172,11 +171,9 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix,
if (r < 0)
return r;
if (link->network->dhcp6_pd_assign_prefix) {
r = dhcp6_assign_delegated_prefix(link, prefix, prefix_len, lifetime_preferred, lifetime_valid);
if (r < 0)
return r;
}
r = dhcp6_assign_delegated_prefix(link, prefix, prefix_len, lifetime_preferred, lifetime_valid);
if (r < 0)
return r;
return 0;
}
@ -324,13 +321,25 @@ static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link
int r;
assert(link);
assert(link->dhcp6_route_messages > 0);
link->dhcp6_route_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST)
log_link_message_warning_errno(link, m, r, "Received error when adding unreachable route for DHCPv6 delegated subnet");
if (r < 0 && r != -EEXIST) {
log_link_message_warning_errno(link, m, r, "Failed to add unreachable route for DHCPv6 delegated subnet");
link_enter_failed(link);
return 1;
}
if (link->dhcp6_route_messages == 0) {
log_link_debug(link, "Unreachable routes for DHCPv6 delegated subnets set");
link->dhcp6_route_configured = true;
link_check_ready(link);
}
return 1;
}
@ -342,6 +351,8 @@ static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) {
uint8_t pd_prefix_len;
int r;
link->dhcp6_route_configured = false;
r = sd_dhcp6_client_get_lease(client, &lease);
if (r < 0)
return r;
@ -386,6 +397,8 @@ static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) {
pd_prefix_len);
continue;
}
if (r > 0)
link->dhcp6_route_messages++;
log_link_debug(link, "Configuring unreachable route for %s/%u",
strnull(buf), pd_prefix_len);
@ -435,6 +448,14 @@ static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) {
* fulfill those with the next available pd delegated prefix. */
}
if (link->dhcp6_route_messages == 0) {
link->dhcp6_route_configured = true;
link_check_ready(link);
} else {
log_link_debug(link, "Setting unreachable routes for DHCPv6 delegated subnets");
link_set_state(link, LINK_STATE_CONFIGURING);
}
return 0;
}
@ -461,14 +482,14 @@ int dhcp6_request_prefix_delegation(Link *link) {
r = sd_dhcp6_client_get_prefix_delegation(l->dhcp6_client, &enabled);
if (r < 0) {
log_link_warning_errno(l, r, "Cannot get prefix delegation when adding new link");
log_link_warning_errno(l, r, "Cannot get prefix delegation when adding new link: %m");
continue;
}
if (enabled == 0) {
r = sd_dhcp6_client_set_prefix_delegation(l->dhcp6_client, 1);
if (r < 0) {
log_link_warning_errno(l, r, "Cannot enable prefix delegation when adding new link");
log_link_warning_errno(l, r, "Cannot enable prefix delegation when adding new link: 5m");
continue;
}
}
@ -486,13 +507,13 @@ int dhcp6_request_prefix_delegation(Link *link) {
r = sd_dhcp6_client_stop(l->dhcp6_client);
if (r < 0) {
log_link_warning_errno(l, r, "Cannot stop DHCPv6 prefix delegation client after adding new link");
log_link_warning_errno(l, r, "Cannot stop DHCPv6 prefix delegation client after adding new link: %m");
continue;
}
r = sd_dhcp6_client_start(l->dhcp6_client);
if (r < 0) {
log_link_warning_errno(l, r, "Cannot restart DHCPv6 prefix delegation client after adding new link");
log_link_warning_errno(l, r, "Cannot restart DHCPv6 prefix delegation client after adding new link: %m");
continue;
}
@ -506,6 +527,9 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
int r;
assert(link);
assert(link->dhcp6_address_messages > 0);
link->dhcp6_address_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
@ -518,10 +542,14 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
} else if (r >= 0)
(void) manager_rtnl_process_address(rtnl, m, link->manager);
r = link_request_set_routes(link);
if (r < 0) {
link_enter_failed(link);
return 1;
if (link->dhcp6_address_messages == 0) {
log_link_debug(link, "DHCPv6 addresses set");
link->dhcp6_address_configured = true;
r = link_request_set_routes(link);
if (r < 0) {
link_enter_failed(link);
return 1;
}
}
return 1;
@ -556,6 +584,8 @@ static int dhcp6_address_change(
r = address_configure(addr, link, dhcp6_address_handler, true);
if (r < 0)
return log_link_warning_errno(link, r, "Could not assign DHCPv6 address: %m");
if (r > 0)
link->dhcp6_address_messages++;
return 0;
}
@ -566,12 +596,13 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) {
struct in6_addr ip6_addr;
uint32_t lifetime_preferred, lifetime_valid;
link->dhcp6_address_configured = false;
r = sd_dhcp6_client_get_lease(client, &lease);
if (r < 0)
return r;
sd_dhcp6_lease_reset_address_iter(lease);
while (sd_dhcp6_lease_get_address(lease, &ip6_addr,
&lifetime_preferred,
&lifetime_valid) >= 0) {
@ -581,6 +612,19 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) {
return r;
}
if (link->dhcp6_address_messages == 0) {
link->dhcp6_address_configured = true;
return link_request_set_routes(link);
} else {
log_link_debug(link, "Setting DHCPv6 addresses");
/* address_handler calls link_request_set_routes() and link_request_set_nexthop().
* Before they are called, the related flags must be cleared. Otherwise, the link
* becomes configured state before routes are configured. */
link->static_routes_configured = false;
link->static_nexthops_configured = false;
link_set_state(link, LINK_STATE_CONFIGURING);
}
return 0;
}
@ -605,7 +649,6 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
(void) dhcp6_prefix_remove_all(link->manager, link);
link_dirty(link);
link->dhcp6_configured = false;
break;
case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
@ -617,7 +660,7 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
r = dhcp6_lease_pd_prefix_acquired(client, link);
if (r < 0)
log_link_debug(link, "DHCPv6 did not receive prefixes to delegate");
log_link_debug_errno(link, r, "DHCPv6 did not receive prefixes to delegate: %m");
_fallthrough_;
case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST:
@ -628,7 +671,6 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
}
link_dirty(link);
link->dhcp6_configured = true;
break;
default:
@ -665,7 +707,7 @@ int dhcp6_request_address(Link *link, int ir) {
r = sd_dhcp6_client_set_address_request(link->dhcp6_client,
false);
if (r < 0 )
if (r < 0)
return r;
ir = false;
@ -812,7 +854,6 @@ int dhcp6_configure(Link *link) {
log_link_debug(link, "DHCP6 CLIENT: Failed to set request flag for '%u' already exists, ignoring.", option);
continue;
}
if (r < 0)
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set request flag for '%u': %m", option);
}
@ -865,21 +906,30 @@ static Link *dhcp6_prefix_get(Manager *m, struct in6_addr *addr) {
return hashmap_get(m->dhcp6_prefixes, addr);
}
static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
static int dhcp6_pd_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
assert(link->dhcp6_pd_route_messages > 0);
link->dhcp6_pd_route_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_message_warning_errno(link, m, r, "Received error adding DHCPv6 Prefix Delegation route");
log_link_message_warning_errno(link, m, r, "Failed to add DHCPv6 Prefix Delegation route");
link_enter_failed(link);
return 1;
}
if (link->dhcp6_pd_route_messages == 0) {
log_link_debug(link, "DHCPv6 prefix delegation routes set");
link->dhcp6_pd_route_configured = true;
link_check_ready(link);
}
return 1;
}
@ -901,9 +951,14 @@ static int dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) {
route->dst.in6 = *addr;
route->dst_prefixlen = 64;
r = route_configure(route, link, dhcp6_route_add_handler);
link->dhcp6_pd_route_configured = false;
link_set_state(link, LINK_STATE_CONFIGURING);
r = route_configure(route, link, dhcp6_pd_route_handler);
if (r < 0)
return r;
if (r > 0)
link->dhcp6_pd_route_messages++;
(void) in_addr_to_string(AF_INET6, (union in_addr_union *) addr, &buf);
log_link_debug(link, "Adding prefix route %s/64", strnull(buf));
@ -998,26 +1053,33 @@ static int dhcp6_prefix_remove_all(Manager *m, Link *link) {
return 0;
}
static int dhcp6_assign_delegeted_prefix_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
assert(link->dhcp6_pd_address_messages > 0);
link->dhcp6_pd_address_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 delegated prefix address ");
log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 delegated prefix address");
link_enter_failed(link);
return 1;
} else if (r >= 0)
(void) manager_rtnl_process_address(rtnl, m, link->manager);
r = link_request_set_routes(link);
if (r < 0) {
link_enter_failed(link);
return 1;
if (link->dhcp6_pd_address_messages == 0) {
log_link_debug(link, "DHCPv6 delegated prefix addresses set");
link->dhcp6_pd_address_configured = true;
r = link_request_set_routes(link);
if (r < 0) {
link_enter_failed(link);
return 1;
}
}
return 1;
@ -1036,8 +1098,10 @@ static int dhcp6_assign_delegated_prefix(Link *link,
assert(link->network);
assert(prefix);
if (!link->network->dhcp6_pd_assign_prefix)
if (!link->network->dhcp6_pd_assign_prefix) {
link->dhcp6_pd_address_configured = true;
return 0;
}
r = address_new(&address);
if (r < 0)
@ -1058,11 +1122,19 @@ static int dhcp6_assign_delegated_prefix(Link *link,
address->cinfo.ifa_prefered = lifetime_preferred;
address->cinfo.ifa_valid = lifetime_valid;
/* address_handler calls link_request_set_routes() and link_request_set_nexthop(). Before they
* are called, the related flags must be cleared. Otherwise, the link becomes configured state
* before routes are configured. */
link->static_routes_configured = false;
link->static_nexthops_configured = false;
link->dhcp6_pd_address_configured = false;
link_set_state(link, LINK_STATE_CONFIGURING);
r = address_configure(address, link, dhcp6_assign_delegeted_prefix_address_handler, true);
r = address_configure(address, link, dhcp6_pd_address_handler, true);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to set acquired DHCPv6 delegated prefix address: %m");
if (r > 0)
link->dhcp6_pd_address_messages++;
return 0;
}

View File

@ -17,6 +17,7 @@ typedef enum DHCP6ClientStartMode {
typedef struct Link Link;
typedef struct Manager Manager;
bool dhcp6_get_prefix_delegation(Link *link);
int dhcp6_request_prefix_delegation(Link *link);
int dhcp6_configure(Link *link);
int dhcp6_request_address(Link *link, int ir);

View File

@ -932,10 +932,9 @@ static int link_request_set_routing_policy_rule(Link *link) {
}
routing_policy_rule_purge(link->manager, link);
if (link->routing_policy_rule_messages == 0) {
if (link->routing_policy_rule_messages == 0)
link->routing_policy_rules_configured = true;
link_check_ready(link);
} else {
else {
log_link_debug(link, "Setting routing policy rules");
link_set_state(link, LINK_STATE_CONFIGURING);
}
@ -972,10 +971,12 @@ static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
return 1;
}
int link_request_set_nexthop(Link *link) {
static int link_request_set_nexthop(Link *link) {
NextHop *nh;
int r;
link->static_nexthops_configured = false;
LIST_FOREACH(nexthops, nh, link->network->static_nexthops) {
r = nexthop_configure(nh, link, nexthop_handler);
if (r < 0)
@ -1018,7 +1019,7 @@ static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
if (link->route_messages == 0) {
log_link_debug(link, "Routes set");
link->static_routes_configured = true;
link_check_ready(link);
link_request_set_nexthop(link);
}
return 1;
@ -1040,7 +1041,6 @@ int link_request_set_routes(Link *link) {
assert(link->state != _LINK_STATE_INVALID);
link->static_routes_configured = false;
link->static_routes_ready = false;
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
/* During configuring addresses, the link lost its carrier. As networkd is dropping
@ -1069,7 +1069,7 @@ int link_request_set_routes(Link *link) {
if (link->route_messages == 0) {
link->static_routes_configured = true;
link_check_ready(link);
link_request_set_nexthop(link);
} else {
log_link_debug(link, "Setting routes");
link_set_state(link, LINK_STATE_CONFIGURING);
@ -1085,70 +1085,107 @@ void link_check_ready(Link *link) {
assert(link);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
log_link_debug(link, "%s(): link is in failed or linger state.", __func__);
return;
}
if (!link->network)
return;
if (!link->addresses_configured)
if (!link->addresses_configured) {
log_link_debug(link, "%s(): static addresses are not configured.", __func__);
return;
}
if (!link->neighbors_configured)
if (!link->neighbors_configured) {
log_link_debug(link, "%s(): static neighbors are not configured.", __func__);
return;
}
SET_FOREACH(a, link->addresses, i)
if (!address_is_ready(a))
if (!address_is_ready(a)) {
_cleanup_free_ char *str = NULL;
(void) in_addr_to_string(a->family, &a->in_addr, &str);
log_link_debug(link, "%s(): an address %s/%d is not ready.", __func__, strnull(str), a->prefixlen);
return;
}
if (!link->addresses_ready) {
link->addresses_ready = true;
r = link_request_set_routes(link);
if (r < 0)
link_enter_failed(link);
log_link_debug(link, "%s(): static addresses are configured. Configuring static routes.", __func__);
return;
}
if (!link->static_routes_configured)
return;
if (!link->static_routes_ready) {
link->static_routes_ready = true;
r = link_request_set_nexthop(link);
if (r < 0)
link_enter_failed(link);
if (!link->static_routes_configured) {
log_link_debug(link, "%s(): static routes are not configured.", __func__);
return;
}
if (!link->static_nexthops_configured)
if (!link->static_nexthops_configured) {
log_link_debug(link, "%s(): static nexthops are not configured.", __func__);
return;
}
if (!link->routing_policy_rules_configured)
if (!link->routing_policy_rules_configured) {
log_link_debug(link, "%s(): static routing policy rules are not configured.", __func__);
return;
}
if (!link->tc_configured)
if (!link->tc_configured) {
log_link_debug(link, "%s(): traffic controls are not configured.", __func__);
return;
}
if (!link->sr_iov_configured)
if (!link->sr_iov_configured) {
log_link_debug(link, "%s(): SR-IOV is not configured.", __func__);
return;
}
if (link_has_carrier(link) || !link->network->configure_without_carrier) {
if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4) && !link->ipv4ll_address)
if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4) && !link->ipv4ll_address) {
log_link_debug(link, "%s(): IPv4LL is not configured.", __func__);
return;
}
if (link_ipv6ll_enabled(link) &&
in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address))
in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address)) {
log_link_debug(link, "%s(): IPv6LL is not configured.", __func__);
return;
}
if ((link_dhcp4_enabled(link) || link_dhcp6_enabled(link) || link_ipv6_accept_ra_enabled(link)) &&
!link->dhcp4_configured &&
!link->dhcp6_configured &&
!link->ndisc_configured &&
!(link_ipv4ll_enabled(link, ADDRESS_FAMILY_FALLBACK_IPV4) && link->ipv4ll_address))
/* When DHCP or RA is enabled, at least one protocol must provide an address, or
* an IPv4ll fallback address must be configured. */
if ((link_dhcp4_enabled(link) || link_dhcp6_enabled(link)) && set_isempty(link->addresses)) {
log_link_debug(link, "%s(): DHCP4 or DHCP6 is enabled but no address is assigned yet.", __func__);
return;
}
if (link_dhcp4_enabled(link) || link_dhcp6_enabled(link) || dhcp6_get_prefix_delegation(link) || link_ipv6_accept_ra_enabled(link)) {
if (!link->dhcp4_configured &&
!(link->dhcp6_address_configured && link->dhcp6_route_configured) &&
!(link->dhcp6_pd_address_configured && link->dhcp6_pd_route_configured) &&
!(link->ndisc_addresses_configured && link->ndisc_routes_configured) &&
!(link_ipv4ll_enabled(link, ADDRESS_FAMILY_FALLBACK_IPV4) && link->ipv4ll_address)) {
/* When DHCP or RA is enabled, at least one protocol must provide an address, or
* an IPv4ll fallback address must be configured. */
log_link_debug(link, "%s(): dynamic addresses or routes are not configured.", __func__);
return;
}
log_link_debug(link, "%s(): dhcp4:%s dhcp6_addresses:%s dhcp_routes:%s dhcp_pd_addresses:%s dhcp_pd_routes:%s ndisc_addresses:%s ndisc_routes:%s",
__func__,
yes_no(link->dhcp4_configured),
yes_no(link->dhcp6_address_configured),
yes_no(link->dhcp6_route_configured),
yes_no(link->dhcp6_pd_address_configured),
yes_no(link->dhcp6_pd_route_configured),
yes_no(link->ndisc_addresses_configured),
yes_no(link->ndisc_routes_configured));
}
}
if (link->state != LINK_STATE_CONFIGURED)
@ -1245,7 +1282,6 @@ static int link_request_set_addresses(Link *link) {
link->addresses_ready = false;
link->neighbors_configured = false;
link->static_routes_configured = false;
link->static_routes_ready = false;
link->static_nexthops_configured = false;
link->routing_policy_rules_configured = false;

View File

@ -100,13 +100,23 @@ typedef struct Link {
char *lease_file;
uint32_t original_mtu;
unsigned dhcp4_messages;
unsigned dhcp4_remove_messages;
unsigned dhcp6_address_messages;
unsigned dhcp6_route_messages;
unsigned dhcp6_pd_address_messages;
unsigned dhcp6_pd_route_messages;
bool dhcp4_route_failed:1;
bool dhcp4_route_retrying:1;
bool dhcp4_configured:1;
bool dhcp6_configured:1;
bool dhcp6_address_configured:1;
bool dhcp6_route_configured:1;
bool dhcp6_pd_address_configured:1;
bool dhcp6_pd_route_configured:1;
unsigned ndisc_messages;
bool ndisc_configured;
unsigned ndisc_addresses_messages;
unsigned ndisc_routes_messages;
bool ndisc_addresses_configured:1;
bool ndisc_routes_configured:1;
sd_ipv4ll *ipv4ll;
bool ipv4ll_address:1;
@ -115,7 +125,6 @@ typedef struct Link {
bool addresses_ready:1;
bool neighbors_configured:1;
bool static_routes_configured:1;
bool static_routes_ready:1;
bool static_nexthops_configured:1;
bool routing_policy_rules_configured:1;
bool tc_configured:1;
@ -217,7 +226,6 @@ uint32_t link_get_vrf_table(Link *link);
uint32_t link_get_dhcp_route_table(Link *link);
uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
int link_request_set_routes(Link *link);
int link_request_set_nexthop(Link *link);
int link_reconfigure(Link *link, bool force);

View File

@ -82,64 +82,60 @@ static int make_stableprivate_address(Link *link, const struct in6_addr *prefix,
return 0;
}
static int ndisc_netlink_route_message_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
assert(link->ndisc_messages > 0);
assert(link->ndisc_routes_messages > 0);
link->ndisc_messages--;
link->ndisc_routes_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_message_error_errno(link, m, r, "Could not set NDisc route or address");
log_link_message_error_errno(link, m, r, "Could not set NDisc route");
link_enter_failed(link);
return 1;
}
if (link->ndisc_messages == 0) {
link->ndisc_configured = true;
r = link_request_set_routes(link);
if (r < 0) {
link_enter_failed(link);
return 1;
}
if (link->ndisc_routes_messages == 0) {
log_link_debug(link, "NDisc routes set.");
link->ndisc_routes_configured = true;
link_check_ready(link);
}
return 1;
}
static int ndisc_netlink_address_message_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
assert(link->ndisc_messages > 0);
assert(link->ndisc_addresses_messages > 0);
link->ndisc_messages--;
link->ndisc_addresses_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_message_error_errno(link, m, r, "Could not set NDisc route or address");
log_link_message_error_errno(link, m, r, "Could not set NDisc address");
link_enter_failed(link);
return 1;
} else if (r >= 0)
(void) manager_rtnl_process_address(rtnl, m, link->manager);
if (link->ndisc_messages == 0) {
link->ndisc_configured = true;
if (link->ndisc_addresses_messages == 0) {
log_link_debug(link, "NDisc SLAAC addresses set.");
link->ndisc_addresses_configured = true;
r = link_request_set_routes(link);
if (r < 0) {
link_enter_failed(link);
return 1;
}
link_check_ready(link);
}
return 1;
@ -223,14 +219,14 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
route->lifetime = time_now + lifetime * USEC_PER_SEC;
route->mtu = mtu;
r = route_configure(route, link, ndisc_netlink_route_message_handler);
r = route_configure(route, link, ndisc_route_handler);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set default route: %m");
link_enter_failed(link);
return r;
}
if (r > 0)
link->ndisc_messages++;
link->ndisc_routes_messages++;
Route *route_gw;
LIST_FOREACH(routes, route_gw, link->network->static_routes) {
@ -242,14 +238,14 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
route_gw->gw = gateway;
r = route_configure(route_gw, link, ndisc_netlink_route_message_handler);
r = route_configure(route_gw, link, ndisc_route_handler);
if (r < 0) {
log_link_error_errno(link, r, "Could not set gateway: %m");
link_enter_failed(link);
return r;
}
if (r > 0)
link->ndisc_messages++;
link->ndisc_routes_messages++;
}
return 0;
@ -404,20 +400,19 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
} else if (lifetime_valid > 0)
a->cinfo.ifa_valid = lifetime_valid;
else
return 0; /* see RFC4862 section 5.5.3.d */
continue; /* see RFC4862 section 5.5.3.d */
if (a->cinfo.ifa_valid == 0)
continue;
r = address_configure(a, link, ndisc_netlink_address_message_handler, true);
r = address_configure(a, link, ndisc_address_handler, true);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set SLAAC address: %m");
link_enter_failed(link);
return r;
}
if (r > 0)
link->ndisc_messages++;
link->ndisc_addresses_messages++;
}
return 0;
@ -461,14 +456,14 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
if (r < 0)
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
r = route_configure(route, link, ndisc_netlink_route_message_handler);
r = route_configure(route, link, ndisc_route_handler);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set prefix route: %m");
link_enter_failed(link);
return r;
}
if (r > 0)
link->ndisc_messages++;
link->ndisc_routes_messages++;
return 0;
}
@ -523,14 +518,14 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
if (r < 0)
return log_link_error_errno(link, r, "Failed to get route address: %m");
r = route_configure(route, link, ndisc_netlink_route_message_handler);
r = route_configure(route, link, ndisc_route_handler);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set additional route: %m");
link_enter_failed(link);
return r;
}
if (r > 0)
link->ndisc_messages++;
link->ndisc_routes_messages++;
return 0;
}
@ -816,11 +811,38 @@ static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *r
switch (event) {
case SD_NDISC_EVENT_ROUTER:
link->ndisc_addresses_configured = false;
link->ndisc_routes_configured = false;
(void) ndisc_router_handler(link, rt);
if (link->ndisc_addresses_messages == 0)
link->ndisc_addresses_configured = true;
else {
log_link_debug(link, "Setting SLAAC addresses.");
/* address_handler calls link_request_set_routes() and link_request_set_nexthop().
* Before they are called, the related flags must be cleared. Otherwise, the link
* becomes configured state before routes are configured. */
link->static_routes_configured = false;
link->static_nexthops_configured = false;
}
if (link->ndisc_routes_messages == 0)
link->ndisc_routes_configured = true;
else
log_link_debug(link, "Setting NDisc routes.");
if (link->ndisc_addresses_configured && link->ndisc_routes_configured)
link_check_ready(link);
else
link_set_state(link, LINK_STATE_CONFIGURING);
break;
case SD_NDISC_EVENT_TIMEOUT:
link->ndisc_configured = true;
log_link_debug(link, "NDISC handler get timeout event");
link->ndisc_addresses_configured = true;
link->ndisc_routes_configured = true;
link_check_ready(link);
break;

View File

@ -52,7 +52,7 @@ void network_apply_anonymize_if_set(Network *network) {
/* RFC7844 section 3.6.:
The client intending to protect its privacy SHOULD only request a
minimal number of options in the PRL and SHOULD also randomly shuffle
the ordering of option codes in the PRL. If this random ordering
the ordering of option codes in the PRL. If this random ordering
cannot be implemented, the client MAY order the option codes in the
PRL by option code number (lowest to highest).
*/

View File

@ -26,7 +26,7 @@ int tc_init(double *ret_ticks_in_usec, uint32_t *ret_hz) {
if (r < 4)
return -EIO;
clock_factor = (double) clock_resolution / USEC_PER_SEC;
clock_factor = (double) clock_resolution / USEC_PER_SEC;
ticks_in_usec = (double) ticks_to_usec / usec_to_ticks * clock_factor;
}
@ -57,7 +57,7 @@ int tc_time_to_tick(usec_t t, uint32_t *ret) {
return 0;
}
int parse_tc_percent(const char *s, uint32_t *percent) {
int parse_tc_percent(const char *s, uint32_t *percent) {
int r;
assert(s);

View File

@ -323,7 +323,7 @@ int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
if (r < 0)
return r;
(void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
(void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
(void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
if (timeout > 0) {

View File

@ -376,7 +376,7 @@ DHCP={}
# IPv6, but we want to wait for both
for _ in range(10):
out = subprocess.check_output(['ip', 'a', 'show', 'dev', self.iface])
if b'state UP' in out and b'inet6 2600' in out and b'inet 192.168' in out:
if b'state UP' in out and b'inet6 2600' in out and b'inet 192.168' in out and b'tentative' not in out:
break
time.sleep(1)
else:

View File

@ -1,2 +1,5 @@
[Match]
Name=bond199
[Network]
IPv6AcceptRA=no

View File

@ -2,4 +2,5 @@
Name=veth-peer
[Network]
IPv6AcceptRA=no
EmitLLDP=yes

View File

@ -2,4 +2,5 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
KeepConfiguration=static

View File

@ -2,4 +2,5 @@
Name=veth99
[Network]
IPv6AcceptRA=no
LLDP=yes

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Address=192.168.42.100/24
DNS=192.168.42.1
Domains= one two three four five six seven eight nine ten

View File

@ -3,3 +3,6 @@ Name=dummy98
[Link]
MACAddress=00:01:02:aa:bb:cc
[Network]
IPv6AcceptRA=no

View File

@ -2,6 +2,8 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
# these lines are ignored
Address=hogehoge
Address=foofoo

View File

@ -1,6 +1,9 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
[RoutingPolicyRule]
TypeOfService=0x08
Table=7

View File

@ -1,6 +1,9 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
[RoutingPolicyRule]
TypeOfService=0x08
Table=7

View File

@ -1,6 +1,9 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
[RoutingPolicyRule]
TypeOfService=0x08
Table=7

View File

@ -2,5 +2,6 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Address=149.10.124.58/28
Gateway=149.10.124.60

View File

@ -2,5 +2,6 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Address=149.10.124.58/28
Gateway=149.10.124.59

View File

@ -1,6 +1,9 @@
[Match]
Name=dummy98
[Network]
IPv6AcceptRA=no
[IPv6AddressLabel]
Label=4444
Prefix=2004:da8:1:0::/64

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
VRF=vrf99
Address=192.168.100.2/24
Gateway=192.168.100.1

View File

@ -1,2 +1,5 @@
[Match]
Name=vrf99
[Network]
IPv6AcceptRA=no

View File

@ -2,4 +2,5 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=sittun99

View File

@ -2,5 +2,6 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=erspan99
Tunnel=erspan98

View File

@ -2,5 +2,6 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=gretap99
Tunnel=gretap98

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=gretun99
Tunnel=gretun98
Tunnel=gretun97

View File

@ -2,5 +2,6 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=ip6gretap99
Tunnel=ip6gretap98

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=ip6gretun99
Tunnel=ip6gretun98
Tunnel=ip6gretun97

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=ip6tnl99
Tunnel=ip6tnl98
Tunnel=ip6tnl97

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=ipiptun99
Tunnel=ipiptun98
Tunnel=ipiptun97

View File

@ -2,4 +2,5 @@
Name=test1
[Network]
IPv6AcceptRA=no
IPVLAN=ipvlan99

View File

@ -2,4 +2,5 @@
Name=test1
[Network]
IPv6AcceptRA=no
IPVTAP=ipvtap99

View File

@ -2,4 +2,5 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=isataptun99

View File

@ -2,4 +2,5 @@
Name=test1
[Network]
IPv6AcceptRA=no
MACVLAN=macvlan99

View File

@ -2,4 +2,5 @@
Name=test1
[Network]
IPv6AcceptRA=no
MACVTAP=macvtap99

View File

@ -1,6 +1,9 @@
[Match]
Name=dummy98
[Network]
IPv6AcceptRA=no
[RoutingPolicyRule]
TypeOfService=0x08
Table=8

View File

@ -1,6 +1,9 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
[RoutingPolicyRule]
TypeOfService=0x08
Table=7

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=sittun99
Tunnel=sittun98
Tunnel=sittun97

View File

@ -5,6 +5,7 @@ Name=dummy98
RequiredForOnline=routable
[Network]
IPv6AcceptRA=no
DNS=10.10.10.10 10.10.10.11
NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org
Domains=hogehoge ~foofoo

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=vtitun99
Tunnel=vtitun98
Tunnel=vtitun97

View File

@ -2,6 +2,7 @@
Name=dummy98
[Network]
IPv6AcceptRA=no
Tunnel=vti6tun99
Tunnel=vti6tun98
Tunnel=vti6tun97

View File

@ -557,7 +557,7 @@ class Utilities():
if i > 0:
time.sleep(1)
output = check_output(f'ip {ipv} address show dev {link} scope {scope}')
if re.search(address_regex, output):
if re.search(address_regex, output) and 'tentative' not in output:
break
else:
self.assertRegex(output, address_regex)
@ -3168,6 +3168,12 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.assertRegex(output, '2600::')
self.assertNotRegex(output, '192.168.5')
output = check_output('ip addr show dev veth99')
print(output)
self.assertRegex(output, '2600::')
self.assertNotRegex(output, '192.168.5')
self.assertNotRegex(output, 'tentative')
# Confirm that ipv6 token is not set in the kernel
output = check_output('ip token show dev veth99')
print(output)