summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-04-12 12:05:43 +0200
committerTom Gundersen <teg@jklm.no>2014-04-12 12:06:28 +0200
commitffba61663aa5f11b2066928d74c09f00e60e9e20 (patch)
tree410a1b815b42d427a656c2bf1c7154b0df4e7e2e /src/network
parent730b3062088792ea0ad06655046d548be01a6d79 (diff)
networkd: wait for IFF_RUNNING rather than IFF_LOWER_UP
The interface is not fully ready until it enterns RUNNING. This was causing problems with sending out DHCP messages before the interface was ready, so they would get lost. In particular this affected DHCP INIT-REBOOT, as it relies on the first package sent being successful (or it will fall back to a full reboot). Also improve the logging a lot, to make future debugging of link state a lot easier.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-link.c77
1 files changed, 46 insertions, 31 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 31b4befd72..45276ba2dd 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1031,6 +1031,7 @@ static int link_acquire_conf(Link *link) {
}
static int link_update_flags(Link *link, unsigned flags) {
+ unsigned flags_added, flags_removed, generic_flags;
int r;
assert(link);
@@ -1042,44 +1043,58 @@ static int link_update_flags(Link *link, unsigned flags) {
if (link->flags == flags)
return 0;
- log_debug_link(link, "link status updated: %#.8x -> %#.8x",
- link->flags, flags);
+ flags_added = (link->flags ^ flags) & flags;
+ flags_removed = (link->flags ^ flags) & link->flags;
+ generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_RUNNING);
- if ((link->flags & IFF_UP) != (flags & IFF_UP))
- log_info_link(link,
- "link is %s", flags & IFF_UP ? "up": "down");
+ if (flags_added & generic_flags)
+ log_debug_link(link, "link flags gained: %#.8x",
+ flags_added & generic_flags);
- if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
- if (flags & IFF_LOWER_UP) {
- log_info_link(link, "carrier on");
+ if (flags_removed & generic_flags)
+ log_debug_link(link, "link flags lost: %#.8x",
+ flags_removed & generic_flags);
- if (link->network->dhcp || link->network->ipv4ll) {
- r = link_acquire_conf(link);
- if (r < 0) {
- log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
- link_enter_failed(link);
- return r;
- }
+ if (flags_added & IFF_UP)
+ log_info_link(link, "link is up");
+ else if (flags_removed & IFF_UP)
+ log_info_link(link, "link is down");
+
+ if (flags_added & IFF_LOWER_UP)
+ log_info_link(link, "carrier on");
+ else if (flags_removed & IFF_LOWER_UP)
+ log_info_link(link, "carrier off");
+
+
+ if (flags_added & IFF_RUNNING) {
+ log_info_link(link, "running");
+
+ if (link->network->dhcp || link->network->ipv4ll) {
+ r = link_acquire_conf(link);
+ if (r < 0) {
+ log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
+ link_enter_failed(link);
+ return r;
}
- } else {
- log_info_link(link, "carrier off");
+ }
+ } else if (flags_removed & IFF_RUNNING) {
+ log_info_link(link, "not running");
- if (link->network->dhcp) {
- r = sd_dhcp_client_stop(link->dhcp_client);
- if (r < 0) {
- log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
- link_enter_failed(link);
- return r;
- }
+ if (link->network->dhcp) {
+ r = sd_dhcp_client_stop(link->dhcp_client);
+ if (r < 0) {
+ log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
+ link_enter_failed(link);
+ return r;
}
+ }
- if (link->network->ipv4ll) {
- r = sd_ipv4ll_stop(link->ipv4ll);
- if (r < 0) {
- log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
- link_enter_failed(link);
- return r;
- }
+ if (link->network->ipv4ll) {
+ r = sd_ipv4ll_stop(link->ipv4ll);
+ if (r < 0) {
+ log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
+ link_enter_failed(link);
+ return r;
}
}
}