]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
-n, --rebind now re-reads the configuration file, removes stale
authorRoy Marples <roy@marples.name>
Wed, 9 Jun 2010 15:26:55 +0000 (15:26 +0000)
committerRoy Marples <roy@marples.name>
Wed, 9 Jun 2010 15:26:55 +0000 (15:26 +0000)
interfaces and rebinds existing ones.

dhcpcd.8.in
dhcpcd.c

index 3ab005777ca8900ecd1c5f0e3c9987ae63ea2d75..ecd147de27ebe12f9de5226f875901728fd5b962 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 18, 2010
+.Dd June 9, 2010
 .Dt DHCPCD 8 SMM
 .Os
 .Sh NAME
@@ -254,26 +254,12 @@ Request the DHCP
 variable for use in
 .Pa @SCRIPT@ .
 .It Fl n , -rebind
-Notifies an existing
+Notifies
 .Nm
-process running on the
-.Ar interface
-to rebind its lease.
-.Nm
-will not re-configure itself or use any other command line arguments.
-.Nm
-will timeout the rebind after 30 seconds at which point the lease will be
-expired and
-.Nm
-will enter the discovery state to obtain a new lease.
-Use the
-.Fl t , -timeout
-option to change this.
+to reload its configuration and rebind its interfaces.
 If
 .Nm
 is not running, then it starts up as normal.
-This option used to be renew, but rebind is more accurate as we need to
-broadcast the request instead of unicasting.
 .It Fl p , -persistent
 .Nm
 normally de-configures the
index 81ca9ee1ac924cbd87b25f63e3716d154a270b35..0d7d830cc3cc0ca7d34507e1e9a2e89aae8d35b7 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -1324,14 +1324,93 @@ handle_link(_unused void *arg)
                syslog(LOG_ERR, "manage_link: %m");
 }
 
+static void
+reboot(struct interface *iface, int argc, char **argv)
+{
+       const struct if_options *ifo;
+       int opt;
+       
+       ifo = iface->state->options;
+       opt = ifo->options;
+       configure_interface(iface, argc, argv);
+       ifo = iface->state->options;
+       iface->state->interval = 0;
+       if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
+               iface->addr.s_addr != ifo->req_addr.s_addr) ||
+           (opt & (DHCPCD_INFORM | DHCPCD_STATIC) &&
+               !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
+       {
+               drop_config(iface, "EXPIRE");
+       } else {
+               free(iface->state->offer);
+               iface->state->offer = NULL;
+       }
+       start_interface(iface);
+}
+
+static void
+reconf_reboot(int action, int argc, char **argv, int oi)
+{
+       struct interface *ifl, *ifn, *ifp, *ifs, *ift;
+       
+       ifs = discover_interfaces(argc - oi, argv + oi);
+       if (ifs == NULL)
+               return;
+
+       /* Remove any old interfaces */
+       if (ifaces) {
+               for (ifl = NULL; ifl != ifaces;) {
+                       /* Work our way backwards */
+                       for (ifp = ifaces; ifp; ifp = ifp->next)
+                               if (ifp->next == ifl) {
+                                       ifl = ifp;
+                                       break;
+                               }
+                       for (ifn = ifs; ifn; ifn = ifn->next)
+                               if (strcmp(ifn->name, ifp->name) == 0)
+                                       break;
+                       if (ifn == NULL)
+                               stop_interface(ifp);
+               }
+       }
+       
+       for (ifp = ifs; ifp && (ift = ifp->next, 1); ifp = ift) {
+               ifl = NULL;
+               for (ifn = ifaces; ifn; ifn = ifn->next) {
+                       if (strcmp(ifn->name, ifp->name) == 0)
+                               break;
+                       ifl = ifn;
+               }
+               if (ifn) {
+                       if (action)
+                               reboot(ifn, argc, argv);
+                       else if (ifn->state->new)
+                               configure(ifn);
+                       free_interface(ifp);
+               } else {
+                       ifp->next = NULL;
+                       init_state(ifp, argc, argv);
+                       start_interface(ifp);
+                       if (ifl)
+                               ifl->next = ifp;
+                       else
+                               ifaces = ifp;
+               }
+       }
+
+       sort_interfaces();
+}
+
 /* ARGSUSED */
 static void
 handle_signal(_unused void *arg)
 {
-       struct interface *iface, *ifl;
+       struct interface *ifp, *ifl;
+       struct if_options *ifo;
        int sig = signal_read();
-       int do_release = 0;
+       int do_release, do_rebind;
 
+       do_rebind = do_release = 0;
        switch (sig) {
        case SIGINT:
                syslog(LOG_INFO, "received SIGINT, stopping");
@@ -1340,19 +1419,26 @@ handle_signal(_unused void *arg)
                syslog(LOG_INFO, "received SIGTERM, stopping");
                break;
        case SIGALRM:
-               syslog(LOG_INFO, "received SIGALRM, rebinding lease");
-               for (iface = ifaces; iface; iface = iface->next)
-                       start_interface(iface);
+               syslog(LOG_INFO, "received SIGALRM, rebinding");
+               ifo = read_config(cffile, NULL, NULL, NULL);
+               /* We need to preserve these two options. */
+               if (options & DHCPCD_MASTER)
+                       ifo->options |= DHCPCD_MASTER;
+               if (options & DHCPCD_DAEMONISED)
+                       ifo->options |= DHCPCD_DAEMONISED;
+               options = ifo->options;
+               free_options(ifo);
+               reconf_reboot(1, 0, NULL, 0);
                return;
        case SIGHUP:
-               syslog(LOG_INFO, "received SIGHUP, releasing lease");
+               syslog(LOG_INFO, "received SIGHUP, releasing");
                do_release = 1;
                break;
        case SIGUSR1:
                syslog(LOG_INFO, "received SIGUSR, reconfiguring");
-               for (iface = ifaces; iface; iface = iface->next)
-                       if (iface->state->new)
-                               configure(iface);
+               for (ifp = ifaces; ifp; ifp = ifp->next)
+                       if (ifp->state->new)
+                               configure(ifp);
                return;
        case SIGPIPE:
                syslog(LOG_WARNING, "received SIGPIPE");
@@ -1371,50 +1457,26 @@ handle_signal(_unused void *arg)
        for (;;) {
                /* Be sane and drop the last config first */
                ifl = NULL;
-               for (iface = ifaces; iface; iface = iface->next) {
-                       if (iface->next == NULL)
+               for (ifp = ifaces; ifp; ifp = ifp->next) {
+                       if (ifp->next == NULL)
                                break;
-                       ifl = iface;
+                       ifl = ifp;
                }
-               if (iface == NULL)
+               if (ifp == NULL)
                        break;
-               if (iface->carrier != LINK_DOWN &&
+               if (ifp->carrier != LINK_DOWN &&
                    (do_release ||
-                       iface->state->options->options & DHCPCD_RELEASE))
-                       send_release(iface);
-               stop_interface(iface);
+                       ifp->state->options->options & DHCPCD_RELEASE))
+                       send_release(ifp);
+               stop_interface(ifp);
        }
        exit(EXIT_FAILURE);
 }
 
-static void
-reconf_reboot(struct interface *iface, int argc, char **argv)
-{
-       const struct if_options *ifo;
-       int opt;
-       
-       ifo = iface->state->options;
-       opt = ifo->options;
-       configure_interface(iface, argc, argv);
-       ifo = iface->state->options;
-       iface->state->interval = 0;
-       if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
-               iface->addr.s_addr != ifo->req_addr.s_addr) ||
-           (opt & (DHCPCD_INFORM | DHCPCD_STATIC) &&
-               !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
-       {
-               drop_config(iface, "EXPIRE");
-       } else {
-               free(iface->state->offer);
-               iface->state->offer = NULL;
-       }
-       start_interface(iface);
-}
-
 int
 handle_args(struct fd_list *fd, int argc, char **argv)
 {
-       struct interface *ifs, *ifp, *ifl, *ifn, *ift;
+       struct interface *ifp;
        int do_exit = 0, do_release = 0, do_reboot = 0, do_reconf = 0;
        int opt, oi = 0;
        ssize_t len;
@@ -1537,32 +1599,7 @@ handle_args(struct fd_list *fd, int argc, char **argv)
                return 0;
        }
 
-       if ((ifs = discover_interfaces(argc - optind, argv + optind))) {
-               for (ifp = ifs; ifp && (ift = ifp->next, 1); ifp = ift) {
-                       ifl = NULL;
-                       for (ifn = ifaces; ifn; ifn = ifn->next) {
-                               if (strcmp(ifn->name, ifp->name) == 0)
-                                       break;
-                               ifl = ifn;
-                       }
-                       if (ifn) {
-                               if (do_reboot)
-                                       reconf_reboot(ifn, argc, argv);
-                               else if (do_reconf && ifn->state->new)
-                                       configure(ifn);
-                               free_interface(ifp);
-                       } else {
-                               ifp->next = NULL;
-                               init_state(ifp, argc, argv);
-                               start_interface(ifp);
-                               if (ifl)
-                                       ifl->next = ifp;
-                               else
-                                       ifaces = ifp;
-                       }
-               }
-               sort_interfaces();
-       }
+       reconf_reboot(do_reboot, argc, argv, optind);
        return 0;
 }