in a RFC compliant or incompliant way by choice.
struct interface *ifp = arg;
logger(ifp->ctx, LOG_ERR, "%s: DHCP lease expired", ifp->name);
- if (ifp->options->options & DHCPCD_LASTLEASE) {
+ if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) {
if (dhcp_leaseextend(ifp) == 0)
return;
logger(ifp->ctx, LOG_ERR, "%s: dhcp_leaseextend: %m",
if (ifp->ctx->options & DHCPCD_FORKED)
return;
state->interval = 0;
- if (dhcp_leaseextend(ifp) == -1) {
+ if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND &&
+ dhcp_leaseextend(ifp) == -1)
+ {
logger(ifp->ctx, LOG_ERR, "%s: dhcp_leaseextend: %m",
ifp->name);
dhcp_expire(ifp);
free(state->offer);
state->offer = NULL;
}
- } else if (!(ifo->options & DHCPCD_LASTLEASE) &&
+ } else if (!(ifo->options & DHCPCD_LASTLEASE_EXTEND) &&
state->lease.leasetime != ~0U &&
stat(state->leasefile, &st) == 0)
{
if (!(ifp->options->options & DHCPCD_IPV4))
return;
+ /* If we violate RFC2131 section 3.7 then require ARP
+ * to detect if any other client wants our address. */
+ if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND)
+ ifp->options->options |= DHCPCD_ARP;
+
/* No point in delaying a static configuration */
if (ifp->options->options & DHCPCD_STATIC ||
!(ifp->options->options & DHCPCD_INITIAL_DELAY))
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 27, 2016
+.Dd April 30, 2016
.Dt DHCPCD 8
.Os
.Sh NAME
.Nm
cannot obtain a lease, then try to use the last lease acquired for the
interface.
-If the
-.Fl p, Fl Fl persistent
-option is not given then the lease is used if it hasn't expired.
+.It Fl Fl lastleaseextend
+Same as the above, but he lease will be retained even if it expires.
+.Nm
+will give it up if any other host tries to claim it for their own via ARP.
+This is does violate RFC2131 section 3.7 which states the lease should be
+dropped once it has expired.
.It Fl e , Fl Fl env Ar value
Push
.Ar value
#define O_DEFINEND O_BASE + 43
#define O_NODELAY O_BASE + 44
#define O_INFORM6 O_BASE + 45
+#define O_LASTLEASE_EXTEND O_BASE + 46
const struct option cf_options[] = {
{"background", no_argument, NULL, 'b'},
{"bootp", no_argument, NULL, O_BOOTP},
{"nodelay", no_argument, NULL, O_NODELAY},
{"noup", no_argument, NULL, O_NOUP},
+ {"lastleaseextend", no_argument, NULL, O_LASTLEASE_EXTEND},
{NULL, 0, NULL, '\0'}
};
case O_NODELAY:
ifo->options &= ~DHCPCD_INITIAL_DELAY;
break;
+ case O_LASTLEASE_EXTEND:
+ ifo->options |= DHCPCD_LASTLEASE | DHCPCD_LASTLEASE_EXTEND;
+ break;
default:
return 0;
}
#define DHCPCD_RTM_PPID (1ULL << 53)
#define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54)
#define DHCPCD_ROUTER_HOST_ROUTE_WARNED (1ULL << 55)
-// unassigned (1ULL << 56)
+#define DHCPCD_LASTLEASE_EXTEND (1ULL << 56)
#define DHCPCD_BOOTP (1ULL << 57)
#define DHCPCD_INITIAL_DELAY (1ULL << 58)
#define DHCPCD_PRINT_PIDFILE (1ULL << 59)