changeset 5535:a0d828e25482 draft

Add --noconfigure option With this set dhcpcd will not configure anything on the host. The expectation is that a 3rd party script will instead.
author Roy Marples <roy@marples.name>
date Wed, 04 Nov 2020 14:18:48 +0000
parents 605f7f9a20c0
children ddb1318a21e8
files hooks/15-timezone hooks/20-resolv.conf hooks/30-hostname.in hooks/50-ntp.conf hooks/50-yp.conf hooks/50-ypbind.in src/dhcp.c src/dhcp6.c src/dhcpcd.8.in src/if-options.c src/if-options.h src/ipv4ll.c src/ipv6.c src/ipv6nd.c src/privsep.c src/route.c src/script.c
diffstat 17 files changed, 138 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/hooks/15-timezone	Wed Nov 04 11:31:40 2020 +1300
+++ b/hooks/15-timezone	Wed Nov 04 14:18:48 2020 +0000
@@ -42,6 +42,6 @@
 	;;
 esac
 
-if $if_up; then
+if $if_configured && $if_up; then
  	set_zoneinfo
 fi
--- a/hooks/20-resolv.conf	Wed Nov 04 11:31:40 2020 +1300
+++ b/hooks/20-resolv.conf	Wed Nov 04 14:18:48 2020 +0000
@@ -198,8 +198,10 @@
 	;;
 esac
 
-if $if_up || [ "$reason" = ROUTERADVERT ]; then
-	add_resolv_conf
-elif $if_down; then
-	remove_resolv_conf
+if $if_configured; then
+	if $if_up || [ "$reason" = ROUTERADVERT ]; then
+		add_resolv_conf
+	elif $if_down; then
+		remove_resolv_conf
+	fi
 fi
--- a/hooks/30-hostname.in	Wed Nov 04 11:31:40 2020 +1300
+++ b/hooks/30-hostname.in	Wed Nov 04 14:18:48 2020 +0000
@@ -153,6 +153,6 @@
 	;;
 esac
 
-if $if_up && [ "$reason" != ROUTERADVERT ]; then
+if $if_configured && $if_up && [ "$reason" != ROUTERADVERT ]; then
 	set_hostname
 fi
--- a/hooks/50-ntp.conf	Wed Nov 04 11:31:40 2020 +1300
+++ b/hooks/50-ntp.conf	Wed Nov 04 14:18:48 2020 +0000
@@ -135,8 +135,10 @@
 ;;
 esac
 
-if $if_up; then
-	add_ntp_conf
-elif $if_down; then
-	remove_ntp_conf
+if $if_configured; then
+	if $if_up; then
+		add_ntp_conf
+	elif $if_down; then
+		remove_ntp_conf
+	fi
 fi
--- a/hooks/50-yp.conf	Wed Nov 04 11:31:40 2020 +1300
+++ b/hooks/50-yp.conf	Wed Nov 04 14:18:48 2020 +0000
@@ -50,8 +50,10 @@
 	fi
 }
 
-if $if_up; then
-	make_yp_conf
-elif $if_down; then
-	restore_yp_conf
+if $if_configured; then
+	if $if_up; then
+		make_yp_conf
+	elif $if_down; then
+		restore_yp_conf
+	fi
 fi
--- a/hooks/50-ypbind.in	Wed Nov 04 11:31:40 2020 +1300
+++ b/hooks/50-ypbind.in	Wed Nov 04 14:18:48 2020 +0000
@@ -68,7 +68,9 @@
 	fi
 }
 
-if [ "$reason" = PREINIT ]; then
+if ! $if_configured; then
+	;
+elif [ "$reason" = PREINIT ]; then
 	rm -f "$ypbind_dir/$interface".*
 elif $if_up || $if_down; then
 	if [ -n "$new_nis_domain" ]; then
--- a/src/dhcp.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/dhcp.c	Wed Nov 04 14:18:48 2020 +0000
@@ -2346,6 +2346,24 @@
 
 	old_state = state->added;
 
+	if (!(ifo->options & DHCPCD_CONFIGURE)) {
+		struct ipv4_addr *ia;
+
+		script_runreason(ifp, state->reason);
+		dhcpcd_daemonise(ifp->ctx);
+
+		/* We we are not configuring the address, we need to keep
+		 * the BPF socket open if the address does not exist. */
+		ia = ipv4_iffindaddr(ifp, &state->lease.addr, NULL);
+		if (ia != NULL) {
+			state->addr = ia;
+			state->added = STATE_ADDED;
+			dhcp_closebpf(ifp);
+			goto openudp;
+		}
+		return;
+	}
+
 	/* Close the BPF filter as we can now receive DHCP messages
 	 * on a UDP socket. */
 	dhcp_closebpf(ifp);
@@ -2353,6 +2371,7 @@
 	/* Add the address */
 	ipv4_applyaddr(ifp);
 
+openudp:
 	/* If not in master mode, open an address specific socket. */
 	if (ctx->options & DHCPCD_MASTER ||
 	    (state->old != NULL &&
@@ -2361,7 +2380,6 @@
 		return;
 
 	dhcp_closeinet(ifp);
-
 #ifdef PRIVSEP
 	if (IN_PRIVSEP_SE(ctx)) {
 		if (ps_inet_openbootp(state->addr) == -1)
@@ -2805,7 +2823,13 @@
 	state->new = NULL;
 	state->new_len = 0;
 	state->reason = reason;
-	ipv4_applyaddr(ifp);
+	if (ifp->options->options & DHCPCD_CONFIGURE)
+		ipv4_applyaddr(ifp);
+	else {
+		state->addr = NULL;
+		state->added = 0;
+		script_runreason(ifp, state->reason);
+	}
 	free(state->old);
 	state->old = NULL;
 	state->old_len = 0;
@@ -4219,6 +4243,20 @@
 #endif
 
 	ifo = ifp->options;
+
+#ifdef PRIVSEP
+	if (IN_PRIVSEP_SE(ifp->ctx) &&
+	    !(ifp->ctx->options & (DHCPCD_MASTER | DHCPCD_CONFIGURE)) &&
+	    IN_ARE_ADDR_EQUAL(&state->lease.addr, &ia->addr))
+	{
+		state->addr = ia;
+		state->added = STATE_ADDED;
+		dhcp_closebpf(ifp);
+		if (ps_inet_openbootp(ia) == -1)
+		    logerr(__func__);
+	}
+#endif
+
 	if (ifo->options & DHCPCD_INFORM) {
 		if (state->state != DHS_INFORM)
 			dhcp_inform(ifp);
--- a/src/dhcp6.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/dhcp6.c	Wed Nov 04 14:18:48 2020 +0000
@@ -2877,6 +2877,8 @@
 	TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) {
 		if (!ifd->active)
 			continue;
+		if (!(ifd->options->options & DHCPCD_CONFIGURE))
+			continue;
 		k = 0;
 		carrier_warned = false;
 		TAILQ_FOREACH(ap, &state->addrs, next) {
@@ -2970,6 +2972,10 @@
 	struct if_sla *sla;
 	struct interface *ifd;
 
+	if (ifp->options != NULL &&
+	    !(ifp->options->options & DHCPCD_CONFIGURE))
+		return 0;
+
 	k = 0;
 	TAILQ_FOREACH(ifd, ifp->ctx->ifaces, next) {
 		ifo = ifd->options;
@@ -3195,9 +3201,11 @@
 			eloop_timeout_add_sec(ifp->ctx->eloop,
 			    state->expire, dhcp6_startexpire, ifp);
 
-		ipv6_addaddrs(&state->addrs);
-		if (!timedout)
-			dhcp6_deprecateaddrs(&state->addrs);
+		if (ifp->options->options & DHCPCD_CONFIGURE) {
+			ipv6_addaddrs(&state->addrs);
+			if (!timedout)
+				dhcp6_deprecateaddrs(&state->addrs);
+		}
 
 		if (state->state == DH6S_INFORMED)
 			logmessage(loglevel, "%s: refresh in %"PRIu32" seconds",
--- a/src/dhcpcd.8.in	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/dhcpcd.8.in	Wed Nov 04 14:18:48 2020 +0000
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd October 30, 2020
+.Dd November 3, 2020
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -62,6 +62,8 @@
 .Op Fl Z , Fl Fl denyinterfaces Ar pattern
 .Op Fl z , Fl Fl allowinterfaces Ar pattern
 .Op Fl Fl inactive
+.Op Fl Fl configure
+.Op Fl Fl noconfigure
 .Op interface
 .Op ...
 .Nm
@@ -737,6 +739,25 @@
 to be started in Master mode and then wait for subsequent
 .Nm
 commands to start each interface as required.
+.It Fl Fl configure
+Allows
+.Nm
+to configure the system.
+This is the default behaviour and sets
+.Ev if_configured=true .
+.It Fl Fl noconfigure
+.Nm
+will not configure the system add all.
+This is only of use if the
+.Fl Fl script
+that
+.Nm
+calls at each network event configures the system instead.
+This is different from
+.Fl T , Fl Fl test
+mode in that it's not one shot and the only change to the environment is the
+addition of
+.Ev if_configured=false .
 .It Fl Fl nodev
 Don't load any
 .Pa /dev
--- a/src/if-options.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/if-options.c	Wed Nov 04 14:18:48 2020 +0000
@@ -165,6 +165,8 @@
 	{"inactive",        no_argument,       NULL, O_INACTIVE},
 	{"mudurl",          required_argument, NULL, O_MUDURL},
 	{"link_rcvbuf",     required_argument, NULL, O_LINK_RCVBUF},
+	{"configure",       no_argument,       NULL, O_CONFIGURE},
+	{"noconfigure",     no_argument,       NULL, O_NOCONFIGURE},
 	{NULL,              0,                 NULL, '\0'}
 };
 
@@ -2244,6 +2246,12 @@
 		}
 #endif
 		break;
+	case O_CONFIGURE:
+		ifo->options |= DHCPCD_CONFIGURE;
+		break;
+	case O_NOCONFIGURE:
+		ifo->options &= ~DHCPCD_CONFIGURE;
+		break;
 	default:
 		return 0;
 	}
@@ -2363,7 +2371,8 @@
 	if ((ifo = default_config(ctx)) == NULL)
 		return NULL;
 	if (default_options == 0) {
-		default_options |= DHCPCD_DAEMONISE | DHCPCD_GATEWAY;
+		default_options |= DHCPCD_DAEMONISE |
+			DHCPCD_CONFIGURE | DHCPCD_GATEWAY;
 #ifdef INET
 		skip = socket(PF_INET, SOCK_DGRAM, 0);
 		if (skip != -1) {
--- a/src/if-options.h	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/if-options.h	Wed Nov 04 14:18:48 2020 +0000
@@ -91,7 +91,7 @@
 #define DHCPCD_IPV6RS			(1ULL << 31)
 #define DHCPCD_IPV6RA_REQRDNSS		(1ULL << 32)
 #define DHCPCD_PRIVSEP			(1ULL << 33)
-#define DHCPCD_UNPRIV			(1ULL << 34)
+#define DHCPCD_CONFIGURE		(1ULL << 34)
 #define DHCPCD_IPV4			(1ULL << 35)
 #define DHCPCD_FORKED			(1ULL << 36)
 #define DHCPCD_IPV6			(1ULL << 37)
@@ -180,6 +180,8 @@
 #define O_INACTIVE		O_BASE + 47
 #define O_MUDURL		O_BASE + 48
 #define O_MSUSERCLASS		O_BASE + 49
+#define O_CONFIGURE		O_BASE + 50
+#define O_NOCONFIGURE		O_BASE + 51
 
 extern const struct option cf_options[];
 
--- a/src/ipv4ll.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/ipv4ll.c	Wed Nov 04 14:18:48 2020 +0000
@@ -228,6 +228,8 @@
 #endif
 		loginfox("%s: using IPv4LL address %s",
 		  ifp->name, inet_ntoa(state->pickedaddr));
+	if (!(ifp->options->options & DHCPCD_CONFIGURE))
+		goto run;
 	if (ia == NULL) {
 		if (ifp->ctx->options & DHCPCD_TEST)
 			goto test;
@@ -252,6 +254,7 @@
 		return;
 	}
 	rt_build(ifp->ctx, AF_INET);
+run:
 	astate = arp_announceaddr(ifp->ctx, &ia->addr);
 	if (astate != NULL)
 		astate->announced_cb = ipv4ll_announced_arp;
@@ -281,7 +284,8 @@
 	struct ipv4ll_state *state = IPV4LL_STATE(ifp);
 
 	ipv4ll_freearp(ifp);
-	ipv4_deladdr(state->addr, 1);
+	if (ifp->options->options & DHCPCD_CONFIGURE)
+		ipv4_deladdr(state->addr, 1);
 	state->addr = NULL;
 	rt_build(ifp->ctx, AF_INET);
 	script_runreason(ifp, "IPV4LL");
@@ -373,7 +377,8 @@
 	if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) {
 		state->pickedaddr = ia->addr; /* So it's not picked again. */
 		repick = true;
-		ipv4_deladdr(ia, 0);
+		if (ifp->options->options & DHCPCD_CONFIGURE)
+			ipv4_deladdr(ia, 0);
 		ia = NULL;
 	}
 #endif
@@ -431,7 +436,8 @@
 
 	state = IPV4LL_STATE(ifp);
 	if (state && state->addr != NULL) {
-		ipv4_deladdr(state->addr, 1);
+		if (ifp->options->options & DHCPCD_CONFIGURE)
+			ipv4_deladdr(state->addr, 1);
 		state->addr = NULL;
 		dropped = true;
 	}
@@ -442,7 +448,8 @@
 
 		TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
 			if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
-				ipv4_deladdr(ia, 0);
+				if (ifp->options->options & DHCPCD_CONFIGURE)
+					ipv4_deladdr(ia, 0);
 				dropped = true;
 			}
 		}
@@ -534,7 +541,8 @@
 	else if (ia->addr_flags & IN_IFF_DUPLICATED) {
 		logerrx("%s: DAD detected %s", ifp->name, ia->saddr);
 		ipv4ll_freearp(ifp);
-		ipv4_deladdr(ia, 1);
+		if (ifp->options->options & DHCPCD_CONFIGURE)
+			ipv4_deladdr(ia, 1);
 		state->addr = NULL;
 		rt_build(ifp->ctx, AF_INET);
 		ipv4ll_found(ifp);
--- a/src/ipv6.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/ipv6.c	Wed Nov 04 14:18:48 2020 +0000
@@ -1416,6 +1416,9 @@
 	struct ipv6_addr *ap, *ap2;
 	int dadcounter;
 
+	if (!(ifp->options->options & DHCPCD_CONFIGURE))
+		return 0;
+
 	/* Check sanity before malloc */
 	if (!(ifp->options->options & DHCPCD_SLAACPRIVATE)) {
 		switch (ifp->hwtype) {
--- a/src/ipv6nd.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/ipv6nd.c	Wed Nov 04 14:18:48 2020 +0000
@@ -1494,13 +1494,18 @@
 		script_runreason(ifp, "TEST");
 		goto handle_flag;
 	}
+
+	if (!(ifp->options->options & DHCPCD_CONFIGURE))
+		goto run;
+
 	ipv6nd_applyra(ifp);
 	ipv6_addaddrs(&rap->addrs);
 #ifdef IPV6_MANAGETEMPADDR
 	ipv6_addtempaddrs(ifp, &rap->acquired);
 #endif
+	rt_build(ifp->ctx, AF_INET6);
 
-	rt_build(ifp->ctx, AF_INET6);
+run:
 	ipv6nd_scriptrun(rap);
 
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
--- a/src/privsep.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/privsep.c	Wed Nov 04 14:18:48 2020 +0000
@@ -362,7 +362,7 @@
 		return pid;
 	}
 
-	ctx->options |= DHCPCD_UNPRIV | DHCPCD_FORKED;
+	ctx->options |= DHCPCD_FORKED;
 	if (ctx->fork_fd != -1) {
 		close(ctx->fork_fd);
 		ctx->fork_fd = -1;
--- a/src/route.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/route.c	Wed Nov 04 14:18:48 2020 +0000
@@ -713,6 +713,9 @@
 #endif
 
 	RB_TREE_FOREACH_SAFE(rt, &routes, rtn) {
+		if (rt->rt_ifp && rt->rt_ifp->options &&
+		    !(rt->rt_ifp->options->options & DHCPCD_CONFIGURE))
+			continue;
 #ifdef BSD
 		if (rt_is_default(rt) &&
 		    if_missfilter(rt->rt_ifp, &rt->rt_gateway) == -1)
@@ -771,7 +774,6 @@
 		}
 	}
 
-
 getfail:
 	rt_headclear(&routes, AF_UNSPEC);
 	rt_headclear(&kroutes, AF_UNSPEC);
--- a/src/script.c	Wed Nov 04 11:31:40 2020 +1300
+++ b/src/script.c	Wed Nov 04 14:18:48 2020 +0000
@@ -350,6 +350,9 @@
 	}
 	if (ifp->ctx->options & DHCPCD_DUMPLEASE && protocol != PROTO_LINK)
 		goto dumplease;
+	if (efprintf(fp, "if_configured=%s",
+	    ifo->options & DHCPCD_CONFIGURE ? "true" : "false") == -1)
+		goto eexit;
 	if (efprintf(fp, "ifcarrier=%s",
 	    ifp->carrier == LINK_UNKNOWN ? "unknown" :
 	    ifp->carrier == LINK_UP ? "up" : "down") == -1)