return 0;
}
-bool link_has_carrier(unsigned flags, uint8_t operstate) {
+bool link_has_carrier(Link *link) {
/* see Documentation/networking/operstates.txt in the kernel sources */
- if (operstate == IF_OPER_UP)
+ if (link->kernel_operstate == IF_OPER_UP)
return true;
- if (operstate == IF_OPER_UNKNOWN)
+ if (link->kernel_operstate == IF_OPER_UNKNOWN)
/* operstate may not be implemented, so fall back to flags */
- if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
+ if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
return true;
return false;
static int link_update_flags(Link *link, sd_rtnl_message *m) {
unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
uint8_t operstate;
- bool carrier_gained = false, carrier_lost = false;
int r;
assert(link);
unknown_flags_removed);
}
- carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
- link_has_carrier(flags, operstate);
- carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
- !link_has_carrier(flags, operstate);
-
link->flags = flags;
link->kernel_operstate = operstate;
link_save(link);
- if (link->state == LINK_STATE_FAILED ||
- link->state == LINK_STATE_UNMANAGED)
- return 0;
-
- if (carrier_gained) {
- log_info_link(link, "gained carrier");
-
- if (link->network) {
- r = link_acquire_conf(link);
- if (r < 0) {
- link_enter_failed(link);
- return r;
- }
- }
- } else if (carrier_lost) {
- log_info_link(link, "lost carrier");
-
- r = link_stop_clients(link);
- if (r < 0) {
- link_enter_failed(link);
- return r;
- }
- }
-
return 0;
}
int r;
assert(link);
- assert(link->state == LINK_STATE_ENSLAVING);
assert(link->network);
if (!(link->flags & IFF_UP)) {
int r;
assert(link);
- assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
- LINK_STATE_LINGER));
assert(link->network);
link->enslaving --;
return r;
}
- if (link_has_carrier(link->flags, link->kernel_operstate)) {
+ if (link_has_carrier(link)) {
r = link_acquire_conf(link);
if (r < 0)
return r;
return 0;
}
+ r = sd_rtnl_message_addr_get_flags(message, &address->flags);
+ if (r < 0) {
+ log_warning_link(link,
+ "rtnl: received address with invalid flags, ignoring");
+ return 0;
+ }
+
switch (address->family) {
case AF_INET:
r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
struct ether_addr mac;
const char *ifname;
uint32_t mtu;
+ bool had_carrier, carrier_gained, carrier_lost;
int r;
assert(link);
}
}
- return link_update_flags(link, m);
+ had_carrier = link_has_carrier(link);
+
+ r = link_update_flags(link, m);
+ if (r < 0)
+ return r;
+
+ carrier_gained = !had_carrier && link_has_carrier(link);
+ carrier_lost = had_carrier && !link_has_carrier(link);
+
+ if (carrier_gained) {
+ log_info_link(link, "gained carrier");
+
+ if (link->network) {
+ r = link_acquire_conf(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return r;
+ }
+ }
+ } else if (carrier_lost) {
+ log_info_link(link, "lost carrier");
+
+ r = link_stop_clients(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return r;
+ }
+ }
+
+ return 0;
}
static void link_update_operstate(Link *link) {
if (link->kernel_operstate == IF_OPER_DORMANT)
link->operstate = LINK_OPERSTATE_DORMANT;
- else if (link_has_carrier(link->flags, link->kernel_operstate)) {
+ else if (link_has_carrier(link)) {
Address *address;
uint8_t scope = RT_SCOPE_NOWHERE;
/* if we have carrier, check what addresses we have */
LIST_FOREACH(addresses, address, link->addresses) {
+ if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
+ continue;
+
if (address->scope < scope)
scope = address->scope;
}
admin_state, oper_state);
if (link->network) {
- char **address;
- char **domain;
+ char **address, **domain;
+ bool space;
fputs("DNS=", f);
-
- STRV_FOREACH(address, link->network->dns)
- fprintf(f, "%s%s", *address,
- (address + 1 ? " " : ""));
+ space = false;
+ STRV_FOREACH(address, link->network->dns) {
+ if (space)
+ fputc(' ', f);
+ fputs(*address, f);
+ space = true;
+ }
if (link->network->dhcp_dns &&
link->dhcp_lease) {
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
if (r > 0) {
+ if (space)
+ fputc(' ', f);
serialize_in_addrs(f, addresses, r);
- if (link->network->dns)
- fputs(" ", f);
}
}
fputs("\n", f);
fprintf(f, "NTP=");
-
- STRV_FOREACH(address, link->network->ntp)
- fprintf(f, "%s%s", *address,
- (address + 1 ? " " : ""));
+ space = false;
+ STRV_FOREACH(address, link->network->ntp) {
+ if (space)
+ fputc(' ', f);
+ fputs(*address, f);
+ space = true;
+ }
if (link->network->dhcp_ntp &&
link->dhcp_lease) {
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
if (r > 0) {
+ if (space)
+ fputc(' ', f);
serialize_in_addrs(f, addresses, r);
- if (link->network->ntp)
- fputs(" ", f);
}
}
fputs("\n", f);
fprintf(f, "DOMAINS=");
-
- STRV_FOREACH(domain, link->network->domains)
- fprintf(f, "%s%s", *domain,
- (domain + 1 ? " " : ""));
+ space = false;
+ STRV_FOREACH(domain, link->network->domains) {
+ if (space)
+ fputc(' ', f);
+ fputs(*domain, f);
+ space = true;
+ }
if (link->network->dhcp_domains &&
link->dhcp_lease) {
r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
if (r >= 0) {
+ if (space)
+ fputc(' ', f);
fputs(domainname, f);
- if (link->network->domains)
- fputs(" ", f);
}
}