From: Roy Marples Date: Tue, 16 Sep 2008 13:17:23 +0000 (+0000) Subject: Allow the release keyword in dhcpcd.conf to release the lease on shutdown. X-Git-Tag: v5.0.0~241 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2662d5195f4c8200be223bad3656903e3db16548;p=thirdparty%2Fdhcpcd.git Allow the release keyword in dhcpcd.conf to release the lease on shutdown. --- diff --git a/dhcpcd.c b/dhcpcd.c index c313bc40..5450cd49 100644 --- 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) { diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index d7031310..19676c19 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -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 diff --git a/if-options.c b/if-options.c index 26fef059..84200803 100644 --- a/if-options.c +++ b/if-options.c @@ -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, diff --git a/if-options.h b/if-options.h index 62f65da3..8d39a31d 100644 --- a/if-options.h +++ b/if-options.h @@ -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)