]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Respect each kernel message on carrier change instead of checking carrier
authorRoy Marples <roy@marples.name>
Wed, 23 Nov 2011 09:03:24 +0000 (09:03 +0000)
committerRoy Marples <roy@marples.name>
Wed, 23 Nov 2011 09:03:24 +0000 (09:03 +0000)
after receiving the message as it's possible for the kernel to react faster
than dhcpcd.

dhcpcd.c
dhcpcd.h
if-bsd.c
if-linux.c

index 97ad6c6e8cf0c0b96ef23a8a7c961a7cf7fe073d..80aa04ad858a89ea351966102ee99fb09586163a 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -871,8 +871,8 @@ configure_interface(struct interface *iface, int argc, char **argv)
        configure_interface1(iface);
 }
 
-static void
-handle_carrier(const char *ifname)
+void
+handle_carrier(int action, int flags, const char *ifname)
 {
        struct interface *iface;
        int carrier;
@@ -882,9 +882,19 @@ handle_carrier(const char *ifname)
        for (iface = ifaces; iface; iface = iface->next)
                if (strcmp(iface->name, ifname) == 0)
                        break;
-       if (!iface || !(iface->state->options->options & DHCPCD_LINK))
+       if (!iface) {
+               if (options & DHCPCD_LINK)
+                       handle_interface(1, ifname);
+               return;
+       }
+       if (!(iface->state->options->options & DHCPCD_LINK))
                return;
-       carrier = carrier_status(iface);
+       if (action == 0)
+               carrier = carrier_status(iface);
+       else {
+               carrier = action == 1 ? 1 : 0;
+               iface->flags = flags;
+       }
        if (carrier == -1)
                syslog(LOG_ERR, "%s: carrier_status: %m", ifname);
        else if (carrier == 0 || !(iface->flags & IFF_RUNNING)) {
@@ -1127,7 +1137,7 @@ start_interface(void *arg)
        uint32_t l;
        int nolease;
 
-       handle_carrier(iface->name);
+       handle_carrier(0, 0, iface->name);
        if (iface->carrier == LINK_DOWN) {
                syslog(LOG_INFO, "%s: waiting for carrier", iface->name);
                return;
@@ -1255,9 +1265,6 @@ handle_interface(int action, const char *ifname)
                if (ifp != NULL)
                        stop_interface(ifp);
                return;
-       } else if (action == 0) {
-               handle_carrier(ifname);
-               return;
        }
 
        /* If running off an interface list, check it's in it. */
@@ -2030,7 +2037,7 @@ main(int argc, char **argv)
                        ts.tv_nsec = 0;
                        nanosleep(&ts, NULL);
                        for (iface = ifaces; iface; iface = iface->next) {
-                               handle_carrier(iface->name);
+                               handle_carrier(0, 0, iface->name);
                                if (iface->carrier != LINK_DOWN) {
                                        opt = 1;
                                        break;
index ec3247466b41c6a7966c5d2e1f9c1d33aa35ece2..1f6ae059988a64339985af81f087ccfe4b3be9a2 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -1,6 +1,6 @@
 /* 
  * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2010 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2011 Roy Marples <roy@marples.name>
  * All rights reserved
 
  * Redistribution and use in source and binary forms, with or without
@@ -122,6 +122,7 @@ extern struct interface *ifaces;
 
 struct interface *find_interface(const char *);
 int handle_args(struct fd_list *, int, char **);
+void handle_carrier(int, int, const char *);
 void handle_interface(int, const char *);
 void handle_hwaddr(const char *, unsigned char *, size_t);
 void handle_ifa(int, const char *,
index c63d969ddee682d277aca698987e6aeb79f6a7be..56585bfc0900b3df901243e691872b20ea0421bd 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -362,8 +362,21 @@ manage_link(int fd)
                        case RTM_IFINFO:
                                ifm = (struct if_msghdr *)(void *)p;
                                memset(ifname, 0, sizeof(ifname));
-                               if (if_indextoname(ifm->ifm_index, ifname))
-                                       handle_interface(0, ifname);
+                               if (!(if_indextoname(ifm->ifm_index, ifname)))
+                                       break;
+                               switch (ifm->ifm_data.ifi_link_state) {
+                               case LINK_STATE_DOWN:
+                                       len = 1;
+                                       break;
+                               case LINK_STATE_UP:
+                                       len = -1;
+                                       break;
+                               default:
+                                       len = ifm->ifm_flags & IFF_RUNNING
+                                           ? 1 : -1;
+                                       break;
+                               }
+                               handle_carrier(len, ifm->ifm_flags, ifname);
                                break;
                        case RTM_DELETE:
                                if (!(rtm->rtm_addrs & RTA_DST) ||
index 4a06259d1a7bb842bdad359daa53365d1083fb52..4b7ac682c471bbd80cd5b5eb259ef819b4276b1b 100644 (file)
@@ -1,6 +1,6 @@
 /* 
  * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2010 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2011 Roy Marples <roy@marples.name>
  * All rights reserved
 
  * Redistribution and use in source and binary forms, with or without
@@ -371,11 +371,14 @@ link_netlink(struct nlmsghdr *nlm)
                }
                rta = RTA_NEXT(rta, len);
        }
-       if (nlm->nlmsg_type == RTM_NEWLINK)
-               len = ifi->ifi_change == ~0U ? 1 : 0;
-       else
-               len = -1;
-       handle_interface(len, ifn);
+
+       if (nlm->nlmsg_type == RTM_DELLINK) {
+               handle_interface(-1, ifn);
+               return 1;
+       }
+
+       handle_carrier(ifi->ifi_flags & IFF_RUNNING ? 1 : -1,
+           ifi->ifi_flags, ifn);
        return 1;
 }