mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-28 04:25:19 +08:00
Add a -N --renew option to renew any existing address early, similar to the
-n --rebind option. However, configuration is not reloaded. Fixes [6cf818eeab].
This commit is contained in:
parent
9a42ed94b4
commit
56a660173f
39
dhcp.c
39
dhcp.c
@ -1829,23 +1829,39 @@ dhcp_decline(struct interface *ifp)
|
||||
}
|
||||
|
||||
static void
|
||||
dhcp_renew(void *arg)
|
||||
dhcp_startrenew(void *arg)
|
||||
{
|
||||
struct interface *ifp = arg;
|
||||
struct dhcp_state *state = D_STATE(ifp);
|
||||
struct dhcp_lease *lease = &state->lease;
|
||||
struct dhcp_state *state;
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
if ((state = D_STATE(ifp)) == NULL)
|
||||
return;
|
||||
|
||||
/* Only renew in the bound or renew states */
|
||||
if (state->state != DHS_BOUND &&
|
||||
state->state != DHS_RENEW)
|
||||
return;
|
||||
|
||||
/* Remove the timeout as the renew may have been forced. */
|
||||
eloop_timeout_delete(ifp->ctx->eloop, dhcp_startrenew, ifp);
|
||||
|
||||
lease = &state->lease;
|
||||
logger(ifp->ctx, LOG_DEBUG, "%s: renewing lease of %s",
|
||||
ifp->name, inet_ntoa(lease->addr));
|
||||
logger(ifp->ctx, LOG_DEBUG, "%s: rebind in %"PRIu32" seconds,"
|
||||
" expire in %"PRIu32" seconds",
|
||||
ifp->name, lease->rebindtime - lease->renewaltime,
|
||||
lease->leasetime - lease->renewaltime);
|
||||
state->state = DHS_RENEW;
|
||||
state->xid = dhcp_xid(ifp);
|
||||
state->interval = 0;
|
||||
send_renew(ifp);
|
||||
}
|
||||
|
||||
void
|
||||
dhcp_renew(struct interface *ifp)
|
||||
{
|
||||
|
||||
dhcp_startrenew(ifp);
|
||||
}
|
||||
|
||||
static void
|
||||
dhcp_arp_announced(struct arp_state *astate)
|
||||
{
|
||||
@ -1867,6 +1883,7 @@ dhcp_rebind(void *arg)
|
||||
state->state = DHS_REBIND;
|
||||
eloop_timeout_delete(ifp->ctx->eloop, send_renew, ifp);
|
||||
state->lease.server.s_addr = 0;
|
||||
state->interval = 0;
|
||||
ifp->options->options &= ~(DHCPCD_CSR_WARNED |
|
||||
DHCPCD_ROUTER_HOST_ROUTE_WARNED);
|
||||
send_rebind(ifp);
|
||||
@ -2085,7 +2102,7 @@ dhcp_bind(struct interface *ifp)
|
||||
lease->renewaltime = lease->rebindtime = lease->leasetime;
|
||||
else {
|
||||
eloop_timeout_add_sec(ifp->ctx->eloop,
|
||||
(time_t)lease->renewaltime, dhcp_renew, ifp);
|
||||
(time_t)lease->renewaltime, dhcp_startrenew, ifp);
|
||||
eloop_timeout_add_sec(ifp->ctx->eloop,
|
||||
(time_t)lease->rebindtime, dhcp_rebind, ifp);
|
||||
eloop_timeout_add_sec(ifp->ctx->eloop,
|
||||
@ -2598,11 +2615,9 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
|
||||
log_dhcp(LOG_ERR, "Force Renew from", ifp, dhcp, from);
|
||||
/* The rebind and expire timings are still the same, we just
|
||||
* enter the renew state early */
|
||||
if (state->state == DHS_BOUND) {
|
||||
eloop_timeout_delete(ifp->ctx->eloop,
|
||||
dhcp_renew, ifp);
|
||||
if (state->state == DHS_BOUND)
|
||||
dhcp_renew(ifp);
|
||||
} else {
|
||||
else {
|
||||
eloop_timeout_delete(ifp->ctx->eloop,
|
||||
send_inform, ifp);
|
||||
dhcp_inform(ifp);
|
||||
|
2
dhcp.h
2
dhcp.h
@ -266,6 +266,7 @@ void dhcp_start(struct interface *);
|
||||
void dhcp_abort(struct interface *);
|
||||
void dhcp_discover(void *);
|
||||
void dhcp_inform(struct interface *);
|
||||
void dhcp_renew(struct interface *);
|
||||
void dhcp_bind(struct interface *);
|
||||
void dhcp_reboot_newopts(struct interface *, unsigned long long);
|
||||
void dhcp_close(struct interface *);
|
||||
@ -275,6 +276,7 @@ int dhcp_dump(struct interface *);
|
||||
#define dhcp_drop(a, b) {}
|
||||
#define dhcp_start(a) {}
|
||||
#define dhcp_abort(a) {}
|
||||
#define dhcp_renew(a) {}
|
||||
#define dhcp_reboot(a, b) (b = b)
|
||||
#define dhcp_reboot_newopts(a, b) (b = b)
|
||||
#define dhcp_close(a) {}
|
||||
|
20
dhcp6.c
20
dhcp6.c
@ -1251,7 +1251,17 @@ dhcp6_startrenew(void *arg)
|
||||
struct dhcp6_state *state;
|
||||
|
||||
ifp = arg;
|
||||
state = D6_STATE(ifp);
|
||||
if ((state = D6_STATE(ifp)) == NULL)
|
||||
return;
|
||||
|
||||
/* Only renew in the bound or renew states */
|
||||
if (state->state != DH6S_BOUND &&
|
||||
state->state != DH6S_RENEW)
|
||||
return;
|
||||
|
||||
/* Remove the timeout as the renew may have been forced. */
|
||||
eloop_timeout_delete(ifp->ctx->eloop, dhcp6_startrenew, ifp);
|
||||
|
||||
state->state = DH6S_RENEW;
|
||||
state->RTC = 0;
|
||||
state->IRT = REN_TIMEOUT;
|
||||
@ -1265,6 +1275,12 @@ dhcp6_startrenew(void *arg)
|
||||
dhcp6_sendrenew(ifp);
|
||||
}
|
||||
|
||||
void dhcp6_renew(struct interface *ifp)
|
||||
{
|
||||
|
||||
dhcp6_startrenew(ifp);
|
||||
}
|
||||
|
||||
int
|
||||
dhcp6_dadcompleted(const struct interface *ifp)
|
||||
{
|
||||
@ -2894,8 +2910,6 @@ dhcp6_handledata(void *arg)
|
||||
ifp->name, op);
|
||||
return;
|
||||
}
|
||||
eloop_timeout_delete(ifp->ctx->eloop,
|
||||
dhcp6_startrenew, ifp);
|
||||
dhcp6_startrenew(ifp);
|
||||
break;
|
||||
case DHCP6_INFORMATION_REQ:
|
||||
|
1
dhcp6.h
1
dhcp6.h
@ -241,6 +241,7 @@ size_t dhcp6_find_delegates(struct interface *);
|
||||
int dhcp6_has_public_addr(const struct interface *);
|
||||
int dhcp6_start(struct interface *, enum DH6S);
|
||||
void dhcp6_reboot(struct interface *);
|
||||
void dhcp6_renew(struct interface *);
|
||||
ssize_t dhcp6_env(char **, const char *, const struct interface *,
|
||||
const struct dhcp6_message *, size_t);
|
||||
void dhcp6_free(struct interface *);
|
||||
|
20
dhcpcd.8.in
20
dhcpcd.8.in
@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd September 30, 2015
|
||||
.Dd November 13, 2015
|
||||
.Dt DHCPCD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -30,7 +30,7 @@
|
||||
.Nd a DHCP client
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 46ABbDdEGgHJKLMpqTV
|
||||
.Op Fl 46ABbDdEGgHJKLMNpqTV
|
||||
.Op Fl C , Fl Fl nohook Ar hook
|
||||
.Op Fl c , Fl Fl script Ar script
|
||||
.Op Fl e , Fl Fl env Ar value
|
||||
@ -378,6 +378,22 @@ is not running, then it starts up as normal.
|
||||
This may also cause
|
||||
.Xr wpa_supplicant 8
|
||||
to reload its configuration for each interface as well.
|
||||
.It Fl N , Fl Fl renew Op Ar interface
|
||||
Notifies
|
||||
.Nm
|
||||
to renew existing addresses on the specified
|
||||
.Ar interface .
|
||||
If no interface is specified then this applies to all interfaces.
|
||||
If
|
||||
.Nm
|
||||
is not running, then it starts up as normal.
|
||||
Unlike the
|
||||
.Fl n , Fl Fl rebind
|
||||
option above, the configuration for
|
||||
.Nm
|
||||
and
|
||||
.Xr wpa_supplicant 8
|
||||
is not reloaded.
|
||||
.It Fl o , Fl Fl option Ar option
|
||||
Request the DHCP
|
||||
.Ar option
|
||||
|
60
dhcpcd.c
60
dhcpcd.c
@ -1165,13 +1165,37 @@ stop_all_interfaces(struct dhcpcd_ctx *ctx, unsigned long long opts)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dhcpcd_ifrenew(struct interface *ifp)
|
||||
{
|
||||
|
||||
#define DHCPCD_RARENEW (DHCPCD_IPV6 | DHCPCD_IPV6RS)
|
||||
if (ifp->options->options & DHCPCD_LINK &&
|
||||
ifp->carrier != LINK_DOWN)
|
||||
{
|
||||
dhcp_renew(ifp);
|
||||
if ((ifp->options->options & DHCPCD_RARENEW) == DHCPCD_RARENEW)
|
||||
ipv6nd_startrs(ifp);
|
||||
dhcp6_renew(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dhcpcd_renew(struct dhcpcd_ctx *ctx)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
|
||||
dhcpcd_ifrenew(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_SIGNALS
|
||||
#define sigmsg "received %s, %s"
|
||||
static void
|
||||
signal_cb(int sig, void *arg)
|
||||
{
|
||||
struct dhcpcd_ctx *ctx = arg;
|
||||
struct interface *ifp;
|
||||
unsigned long long opts;
|
||||
int exit_code;
|
||||
|
||||
@ -1199,10 +1223,8 @@ signal_cb(int sig, void *arg)
|
||||
ctx->argc - ctx->ifc);
|
||||
return;
|
||||
case SIGUSR1:
|
||||
logger(ctx, LOG_INFO, sigmsg, "SIGUSR1", "reconfiguring");
|
||||
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
|
||||
ipv4_applyaddr(ifp);
|
||||
}
|
||||
logger(ctx, LOG_INFO, sigmsg, "SIGUSR1", "renewing");
|
||||
dhcpcd_renew(ctx);
|
||||
return;
|
||||
case SIGUSR2:
|
||||
logger_close(ctx);
|
||||
@ -1261,7 +1283,7 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
|
||||
{
|
||||
struct interface *ifp;
|
||||
unsigned long long opts;
|
||||
int opt, oi, do_reboot;
|
||||
int opt, oi, do_reboot, do_renew;
|
||||
size_t len, l;
|
||||
char *tmp, *p;
|
||||
|
||||
@ -1312,7 +1334,7 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
|
||||
optind = 0;
|
||||
oi = 0;
|
||||
opts = 0;
|
||||
do_reboot = 0;
|
||||
do_reboot = do_renew = 0;
|
||||
while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
|
||||
{
|
||||
switch (opt) {
|
||||
@ -1331,6 +1353,9 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
|
||||
case 'x':
|
||||
opts |= DHCPCD_EXITING;
|
||||
break;
|
||||
case 'N':
|
||||
do_renew = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1351,6 +1376,19 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (do_renew) {
|
||||
if (optind == argc) {
|
||||
dhcpcd_renew(ctx);
|
||||
return 0;
|
||||
}
|
||||
for (oi = optind; oi < argc; oi++) {
|
||||
if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
|
||||
continue;
|
||||
dhcpcd_ifrenew(ifp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
reload_config(ctx);
|
||||
/* XXX: Respect initial commandline options? */
|
||||
reconf_reboot(ctx, do_reboot, argc, argv, optind - 1);
|
||||
@ -1451,6 +1489,10 @@ main(int argc, char **argv)
|
||||
sig = SIGTERM;
|
||||
siga = "TERM";
|
||||
break;
|
||||
case 'N':
|
||||
sig = SIGUSR1;
|
||||
siga = "USR1";
|
||||
break;
|
||||
#endif
|
||||
case 'T':
|
||||
i = 1;
|
||||
@ -1669,14 +1711,14 @@ main(int argc, char **argv)
|
||||
logger(&ctx, LOG_INFO, "sending signal %s to pid %d",
|
||||
siga, pid);
|
||||
if (pid == 0 || kill(pid, sig) != 0) {
|
||||
if (sig != SIGHUP && errno != EPERM)
|
||||
if (sig != SIGHUP && sig != SIGUSR1 && errno != EPERM)
|
||||
logger(&ctx, LOG_ERR, ""PACKAGE" not running");
|
||||
if (pid != 0 && errno != ESRCH) {
|
||||
logger(&ctx, LOG_ERR, "kill: %m");
|
||||
goto exit_failure;
|
||||
}
|
||||
unlink(ctx.pidfile);
|
||||
if (sig != SIGHUP)
|
||||
if (sig != SIGHUP && sig != SIGUSR1)
|
||||
goto exit_failure;
|
||||
} else {
|
||||
struct timespec ts;
|
||||
|
@ -144,6 +144,7 @@ const struct option cf_options[] = {
|
||||
{"nolink", no_argument, NULL, 'K'},
|
||||
{"noipv4ll", no_argument, NULL, 'L'},
|
||||
{"master", no_argument, NULL, 'M'},
|
||||
{"renew", no_argument, NULL, 'N'},
|
||||
{"nooption", optional_argument, NULL, 'O'},
|
||||
{"require", required_argument, NULL, 'Q'},
|
||||
{"static", required_argument, NULL, 'S'},
|
||||
@ -684,6 +685,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
|
||||
case 'g': /* FALLTHROUGH */
|
||||
case 'n': /* FALLTHROUGH */
|
||||
case 'x': /* FALLTHROUGH */
|
||||
case 'N': /* FALLTHROUGH */
|
||||
case 'T': /* FALLTHROUGH */
|
||||
case 'U': /* FALLTHROUGH */
|
||||
case 'V': /* We need to handle non interface options */
|
||||
|
@ -42,7 +42,7 @@
|
||||
/* Don't set any optional arguments here so we retain POSIX
|
||||
* compatibility with getopt */
|
||||
#define IF_OPTS "46bc:de:f:gh:i:j:kl:m:no:pqr:s:t:u:v:wxy:z:" \
|
||||
"ABC:DEF:GHI:JKLMO:Q:S:TUVW:X:Z:"
|
||||
"ABC:DEF:GHI:JKLMNO:Q:S:TUVW:X:Z:"
|
||||
|
||||
#define DEFAULT_TIMEOUT 30
|
||||
#define DEFAULT_REBOOT 5
|
||||
|
Loading…
Reference in New Issue
Block a user