]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Allow the release keyword in dhcpcd.conf to release the lease on shutdown.
authorRoy Marples <roy@marples.name>
Tue, 16 Sep 2008 13:17:23 +0000 (13:17 +0000)
committerRoy Marples <roy@marples.name>
Tue, 16 Sep 2008 13:17:23 +0000 (13:17 +0000)
dhcpcd.c
dhcpcd.conf.5.in
if-options.c
if-options.h

index c313bc4088652920a267681631e41e41c1038a1e..5450cd49e28bfc9f39ed029abc7161cad29007e2 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -96,6 +96,8 @@ static const struct dhcp_op const dhcp_ops[] = {
        { 0, NULL }
 };
 
+static void send_release(struct interface *);
+
 static const char *
 get_dhcp_op(uint8_t type)
 {
@@ -207,13 +209,18 @@ close_sockets(struct interface *iface)
        }
 }
 
+
 static void
 stop_interface(struct interface *iface, const char *reason)
 {
        struct interface *ifp, *ifl = NULL;
 
        syslog(LOG_INFO, "%s: removing interface", iface->name);
+       if (iface->state->options->options & DHCPCD_RELEASE)
+               send_release(iface);
        drop_config(iface, reason ? reason : "STOP");
+       if (iface->state->options->options & DHCPCD_RELEASE)
+               unlink(iface->leasefile);
        close_sockets(iface);
        delete_timeout(NULL, iface);
        for (ifp = ifaces; ifp; ifp = ifp->next) {
@@ -347,6 +354,7 @@ start_expire(void *arg)
        syslog(LOG_ERR, "%s: lease expired", iface->name);
        delete_timeout(NULL, iface);
        drop_config(iface, "EXPIRE");
+       unlink(iface->leasefile);
        iface->state->interval = 0;
        if (iface->carrier != LINK_DOWN) {
                if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
@@ -434,6 +442,7 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp)
        if (type == DHCP_NAK) {
                log_dhcp(LOG_WARNING, "NAK:", iface, dhcp);
                drop_config(iface, "EXPIRE");
+               unlink(iface->leasefile);
                delete_event(iface->raw_fd);
                close(iface->raw_fd);
                iface->raw_fd = -1;
@@ -604,6 +613,19 @@ open_sockets(struct interface *iface)
                add_event(iface->raw_fd, handle_dhcp_packet, iface);
 }
 
+static void
+send_release(struct interface *iface)
+{
+       if (iface->state->lease.addr.s_addr &&
+           !IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
+       {
+               syslog(LOG_INFO, "%s: releasing lease of %s",
+                      iface->name, inet_ntoa(iface->state->lease.addr));
+               open_sockets(iface);
+               send_message(iface, DHCP_RELEASE, NULL);
+       }
+}
+
 static void
 handle_carrier(const char *ifname)
 {
@@ -721,19 +743,6 @@ start_reboot(struct interface *iface)
                send_request(iface);
 }
 
-static void
-send_release(struct interface *iface)
-{
-       if (iface->state->lease.addr.s_addr &&
-           !IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
-       {
-               syslog(LOG_INFO, "%s: releasing lease of %s",
-                      iface->name, inet_ntoa(iface->state->lease.addr));
-               open_sockets(iface);
-               send_message(iface, DHCP_RELEASE, NULL);
-       }
-}
-
 void
 start_interface(void *arg)
 {
@@ -960,10 +969,12 @@ handle_signal(_unused void *arg)
                                ifl = iface;
                if (!ifl)
                        break;
-               if (do_release)
+               if (do_release || ifl->state->options->options & DHCPCD_RELEASE)
                        send_release(ifl);
                if (!(ifl->state->options->options & DHCPCD_PERSISTENT))
                        drop_config(ifl, do_release ? "RELEASE" : "STOP");
+               if (do_release || ifl->state->options->options & DHCPCD_RELEASE)
+                       unlink(ifl->leasefile);
        }
        exit(EXIT_FAILURE);
 }
@@ -1004,7 +1015,7 @@ handle_args(int argc, char **argv)
                        if (!ifp)
                                continue;
                        if (do_release)
-                               send_release(ifp);
+                               ifp->state->options->options |= DHCPCD_RELEASE;
                        if (do_exit || do_release) {
                                stop_interface(ifp, do_release ? "RELEASE" : "STOP");
                        } else if (do_reboot) {
index d70313107ec10c506ff927796d6fb05c8f1e5256..19676c19dac5c4926bd2058cb1c2cd7dcbb11a24 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd September 15, 2008
+.Dd September 16, 2008
 .Dt DHCPCD.CONF 5 SMM
 .Sh NAME
 .Nm dhcpcd.conf
@@ -132,6 +132,9 @@ The default is 10 seconds.
 A setting if 0 seconds causes
 .Nm dhcpcd
 to skip the reboot phase and go straight into discover.
+.It Ic release
+.Nm dhcpcd
+will release the lease prior to stopping the interface.
 .It Ic require Ar option
 Requires the
 .Ar option
index 26fef05940b202b84727b86d4df6f1981aad6d90..84200803a746053c13d4e361f4bdeabe533cea56 100644 (file)
@@ -273,7 +273,6 @@ parse_option(struct if_options *ifo, int opt, const char *arg)
 
        switch(opt) {
        case 'd': /* FALLTHROUGH */
-       case 'k': /* FALLTHROUGH */
        case 'n': /* FALLTHROUGH */
        case 'x': /* FALLTHROUGH */
        case 'T': /* We need to handle non interface options */
@@ -312,6 +311,9 @@ parse_option(struct if_options *ifo, int opt, const char *arg)
                }
                *ifo->vendorclassid = (uint8_t)s;
                break;
+       case 'k':
+               ifo->options |= DHCPCD_RELEASE;
+               break;
        case 'l':
                if (*arg == '-') {
                        syslog(LOG_ERR,
index 62f65da3224d457bc179ceec78e3234f4ffa5d9c..8d39a31dded710601640306dadcc408d4e3d97de 100644 (file)
@@ -50,6 +50,7 @@
 #define VENDOR_MAX_LEN         255
 
 #define DHCPCD_ARP             (1 << 0)
+#define DHCPCD_RELEASE         (1 << 1)
 #define DHCPCD_DOMAIN          (1 << 2)
 #define DHCPCD_GATEWAY         (1 << 3)
 #define DHCPCD_LASTLEASE       (1 << 7)