#include <netinet/ether.h>
#include <linux/if.h>
#include <unistd.h>
+#include <stdio_ext.h>
#include "alloc-util.h"
#include "bus-util.h"
if (!link->network)
return false;
+ if (streq_ptr(link->kind, "wireguard"))
+ return false;
+
return link->network->link_local & ADDRESS_FAMILY_IPV4;
}
if (!link->network)
return false;
+ if (streq_ptr(link->kind, "wireguard"))
+ return false;
+
return link->network->link_local & ADDRESS_FAMILY_IPV6;
}
if (!link_ipv6ll_enabled(link))
return false;
- return link->network->router_prefix_delegation;
+ return link->network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE;
}
static bool link_lldp_rx_enabled(Link *link) {
if (r < 0)
return r;
- *ret = link;
- link = NULL;
+ *ret = TAKE_PTR(link);
return 0;
}
if (!link->network)
return;
- if (!link->static_configured)
+ if (!link->static_routes_configured)
+ return;
+
+ if (!link->routing_policy_rules_configured)
return;
if (link_ipv4ll_enabled(link))
return r;
}
- link->link_messages++;
+ link->routing_policy_rule_messages++;
}
routing_policy_rule_purge(link->manager, link);
+ if (link->routing_policy_rule_messages == 0) {
+ link->routing_policy_rules_configured = true;
+ link_check_ready(link);
+ } else
+ log_link_debug(link, "Setting routing policy rules");
return 0;
}
_cleanup_link_unref_ Link *link = userdata;
int r;
- assert(link->link_messages > 0);
+ assert(link->route_messages > 0);
assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
LINK_STATE_LINGER));
- link->link_messages--;
+ link->route_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
if (r < 0 && r != -EEXIST)
log_link_warning_errno(link, r, "Could not set route: %m");
- if (link->link_messages == 0) {
+ if (link->route_messages == 0) {
log_link_debug(link, "Routes set");
- link->static_configured = true;
+ link->static_routes_configured = true;
link_check_ready(link);
}
assert(link->network);
assert(link->state == LINK_STATE_SETTING_ADDRESSES);
+ (void) link_set_routing_policy_rule(link);
+
link_set_state(link, LINK_STATE_SETTING_ROUTES);
LIST_FOREACH(routes, rt, link->network->static_routes) {
return r;
}
- link->link_messages++;
+ link->route_messages++;
}
- if (link->link_messages == 0) {
- link->static_configured = true;
+ if (link->route_messages == 0) {
+ link->static_routes_configured = true;
link_check_ready(link);
} else
log_link_debug(link, "Setting routes");
assert(m);
assert(link);
assert(link->ifname);
- assert(link->link_messages > 0);
+ assert(link->address_messages > 0);
assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
LINK_STATE_FAILED, LINK_STATE_LINGER));
- link->link_messages--;
+ link->address_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
else if (r >= 0)
manager_rtnl_process_address(rtnl, m, link->manager);
- if (link->link_messages == 0) {
+ if (link->address_messages == 0) {
log_link_debug(link, "Addresses set");
link_enter_set_routes(link);
}
assert(m);
assert(link);
assert(link->ifname);
- assert(link->link_messages > 0);
+ assert(link->address_label_messages > 0);
- link->link_messages--;
+ link->address_label_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
else if (r >= 0)
manager_rtnl_process_address(rtnl, m, link->manager);
- if (link->link_messages == 0)
+ if (link->address_label_messages == 0)
log_link_debug(link, "Addresses label set");
return 1;
return r;
}
- link->link_messages++;
+ link->address_messages++;
}
LIST_FOREACH(labels, label, link->network->address_labels) {
return r;
}
- link->link_messages++;
+ link->address_label_messages++;
}
/* now that we can figure out a default address for the dhcp server,
log_link_debug(link, "Offering DHCPv4 leases");
}
- if (link->link_messages == 0)
+ if (link->address_messages == 0)
link_enter_set_routes(link);
else
log_link_debug(link, "Setting addresses");
return r;
}
- (void) link_set_routing_policy_rule(link);
-
if (link_has_carrier(link) || link->network->configure_without_carrier) {
r = link_acquire_conf(link);
if (r < 0)
if (r < 0)
return log_link_error_errno(link, r, "Failed to add route: %m");
- if (lifetime != USEC_INFINITY) {
+ if (lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
0, route_expire_handler, route);
if (r < 0)
route->lifetime = lifetime;
sd_event_source_unref(route->expire);
- route->expire = expire;
- expire = NULL;
+ route->expire = TAKE_PTR(expire);
}
}
assert(link);
+ /* Some devices reset itself while setting the MTU. This causes the DHCP client fall into a loop.
+ setting_mtu keep track whether the device got reset because of setting MTU and does not drop the
+ configuration and stop the clients as well. */
if (link->setting_mtu)
return 0;
return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m");
break;
}
+ case DHCP_CLIENT_ID_DUID_ONLY: {
+ const DUID *duid = link_duid(link);
+
+ r = sd_dhcp_client_set_duid(link->dhcp_client,
+ duid->type,
+ duid->raw_data_len > 0 ? duid->raw_data : NULL,
+ duid->raw_data_len);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update DUID in DHCP client: %m");
+ break;
+ }
case DHCP_CLIENT_ID_MAC:
r = sd_dhcp_client_set_client_id(link->dhcp_client,
ARPHRD_ETHER,
(const uint8_t *)&link->mac,
sizeof(link->mac));
- if(r < 0)
+ if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC client id in DHCP client: %m");
break;
default:
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC for Router Advertisement: %m");
}
+
+ if (link->ndisc) {
+ r = sd_ndisc_set_mac(link->ndisc, &link->mac);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update MAC for ndisc: %m");
+ }
}
}
if (hashmap_isempty(h))
return;
- fputs_unlocked(prefix, f);
+ fputs(prefix, f);
HASHMAP_FOREACH(link, h, i) {
if (space)
- fputc_unlocked(' ', f);
+ fputc(' ', f);
fprintf(f, "%i", link->ifindex);
space = true;
}
- fputc_unlocked('\n', f);
+ fputc('\n', f);
}
int link_save(Link *link) {
if (r < 0)
goto fail;
+ (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
(void) fchmod(fileno(f), 0644);
fprintf(f,
char **dhcp_domains = NULL;
unsigned j;
+ fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
+ yes_no(link->network->required_for_online));
+
if (link->dhcp6_client) {
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
if (r < 0 && r != -ENOMSG)
fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
- fputs_unlocked("DNS=", f);
+ fputs("DNS=", f);
space = false;
for (j = 0; j < link->network->n_dns; j++) {
}
if (space)
- fputc_unlocked(' ', f);
- fputs_unlocked(b, f);
+ fputc(' ', f);
+ fputs(b, f);
space = true;
}
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
if (r > 0) {
if (space)
- fputc_unlocked(' ', f);
+ fputc(' ', f);
serialize_in_addrs(f, addresses, r);
space = true;
}
r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
if (r > 0) {
if (space)
- fputc_unlocked(' ', f);
+ fputc(' ', f);
serialize_in6_addrs(f, in6_addrs, r);
space = true;
}
SET_FOREACH(dd, link->ndisc_rdnss, i) {
if (space)
- fputc_unlocked(' ', f);
+ fputc(' ', f);
serialize_in6_addrs(f, &dd->address, 1);
space = true;
}
}
- fputc_unlocked('\n', f);
+ fputc('\n', f);
- fputs_unlocked("NTP=", f);
+ fputs("NTP=", f);
space = false;
fputstrv(f, link->network->ntp, NULL, &space);
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
if (r > 0) {
if (space)
- fputc_unlocked(' ', f);
+ fputc(' ', f);
serialize_in_addrs(f, addresses, r);
space = true;
}
&in6_addrs);
if (r > 0) {
if (space)
- fputc_unlocked(' ', f);
+ fputc(' ', f);
serialize_in6_addrs(f, in6_addrs, r);
space = true;
}
fputstrv(f, hosts, NULL, &space);
}
- fputc_unlocked('\n', f);
+ fputc('\n', f);
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
if (link->dhcp_lease) {
(void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
}
- fputs_unlocked("DOMAINS=", f);
+ fputs("DOMAINS=", f);
space = false;
fputstrv(f, link->network->search_domains, NULL, &space);
fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
}
- fputc_unlocked('\n', f);
+ fputc('\n', f);
- fputs_unlocked("ROUTE_DOMAINS=", f);
+ fputs("ROUTE_DOMAINS=", f);
space = false;
fputstrv(f, link->network->route_domains, NULL, &space);
fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
}
- fputc_unlocked('\n', f);
+ fputc('\n', f);
fprintf(f, "LLMNR=%s\n",
resolve_support_to_string(link->network->llmnr));
if (!set_isempty(link->network->dnssec_negative_trust_anchors)) {
const char *n;
- fputs_unlocked("DNSSEC_NTA=", f);
+ fputs("DNSSEC_NTA=", f);
space = false;
SET_FOREACH(n, link->network->dnssec_negative_trust_anchors, i)
fputs_with_space(f, n, NULL, &space);
- fputc_unlocked('\n', f);
+ fputc('\n', f);
}
- fputs_unlocked("ADDRESSES=", f);
+ fputs("ADDRESSES=", f);
space = false;
SET_FOREACH(a, link->addresses, i) {
_cleanup_free_ char *address_str = NULL;
fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
space = true;
}
- fputc_unlocked('\n', f);
+ fputc('\n', f);
- fputs_unlocked("ROUTES=", f);
+ fputs("ROUTES=", f);
space = false;
SET_FOREACH(route, link->routes, i) {
_cleanup_free_ char *route_str = NULL;
space = true;
}
- fputc_unlocked('\n', f);
+ fputc('\n', f);
}
print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
if (r >= 0) {
- fputs_unlocked("DHCP4_ADDRESS=", f);
+ fputs("DHCP4_ADDRESS=", f);
serialize_in_addrs(f, &address, 1);
- fputc_unlocked('\n', f);
+ fputc('\n', f);
}
r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
r = sd_ipv4ll_get_address(link->ipv4ll, &address);
if (r >= 0) {
- fputs_unlocked("IPV4LL_ADDRESS=", f);
+ fputs("IPV4LL_ADDRESS=", f);
serialize_in_addrs(f, &address, 1);
- fputc_unlocked('\n', f);
+ fputc('\n', f);
}
}