summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-11-04 14:18:48 +0000
committerRoy Marples <roy@marples.name>2020-11-04 14:18:48 +0000
commite9dfc2416bc5ff97166905cbb69e71dd2be6411a (patch)
treedf5dadc4500f91e4b559efb8cc82a8e4e23f44be
parentd5565ba4c5306332c2b6f00aef184579beb31e33 (diff)
downloaddhcpcd-e9dfc2416bc5ff97166905cbb69e71dd2be6411a.tar.xz
Add --noconfigure option
With this set dhcpcd will not configure anything on the host. The expectation is that a 3rd party script will instead.
-rw-r--r--hooks/15-timezone2
-rw-r--r--hooks/20-resolv.conf10
-rw-r--r--hooks/30-hostname.in2
-rw-r--r--hooks/50-ntp.conf10
-rw-r--r--hooks/50-yp.conf10
-rw-r--r--hooks/50-ypbind.in4
-rw-r--r--src/dhcp.c42
-rw-r--r--src/dhcp6.c14
-rw-r--r--src/dhcpcd.8.in23
-rw-r--r--src/if-options.c11
-rw-r--r--src/if-options.h4
-rw-r--r--src/ipv4ll.c18
-rw-r--r--src/ipv6.c3
-rw-r--r--src/ipv6nd.c7
-rw-r--r--src/privsep.c2
-rw-r--r--src/route.c4
-rw-r--r--src/script.c3
17 files changed, 138 insertions, 31 deletions
diff --git a/hooks/15-timezone b/hooks/15-timezone
index ac04c652..3d517328 100644
--- a/hooks/15-timezone
+++ b/hooks/15-timezone
@@ -42,6 +42,6 @@ BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
;;
esac
-if $if_up; then
+if $if_configured && $if_up; then
set_zoneinfo
fi
diff --git a/hooks/20-resolv.conf b/hooks/20-resolv.conf
index 03e846fa..73d33386 100644
--- a/hooks/20-resolv.conf
+++ b/hooks/20-resolv.conf
@@ -198,8 +198,10 @@ BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
;;
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
diff --git a/hooks/30-hostname.in b/hooks/30-hostname.in
index b515e4c1..abeb3696 100644
--- a/hooks/30-hostname.in
+++ b/hooks/30-hostname.in
@@ -153,6 +153,6 @@ BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
;;
esac
-if $if_up && [ "$reason" != ROUTERADVERT ]; then
+if $if_configured && $if_up && [ "$reason" != ROUTERADVERT ]; then
set_hostname
fi
diff --git a/hooks/50-ntp.conf b/hooks/50-ntp.conf
index fd394518..046ab6b3 100644
--- a/hooks/50-ntp.conf
+++ b/hooks/50-ntp.conf
@@ -135,8 +135,10 @@ BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
;;
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
diff --git a/hooks/50-yp.conf b/hooks/50-yp.conf
index abe6a433..c5cdad90 100644
--- a/hooks/50-yp.conf
+++ b/hooks/50-yp.conf
@@ -50,8 +50,10 @@ restore_yp_conf()
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
diff --git a/hooks/50-ypbind.in b/hooks/50-ypbind.in
index 5bd5eacf..09a12b97 100644
--- a/hooks/50-ypbind.in
+++ b/hooks/50-ypbind.in
@@ -68,7 +68,9 @@ restore_yp_binding()
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
diff --git a/src/dhcp.c b/src/dhcp.c
index 647a0aaa..e2e9accd 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -2346,6 +2346,24 @@ dhcp_bind(struct interface *ifp)
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 @@ dhcp_bind(struct interface *ifp)
/* 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 @@ dhcp_bind(struct interface *ifp)
return;
dhcp_closeinet(ifp);
-
#ifdef PRIVSEP
if (IN_PRIVSEP_SE(ctx)) {
if (ps_inet_openbootp(state->addr) == -1)
@@ -2805,7 +2823,13 @@ dhcp_drop(struct interface *ifp, const char *reason)
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 @@ dhcp_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid)
#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);
diff --git a/src/dhcp6.c b/src/dhcp6.c
index eda42e20..ec6d7738 100644
--- a/src/dhcp6.c
+++ b/src/dhcp6.c
@@ -2877,6 +2877,8 @@ dhcp6_delegate_prefix(struct interface *ifp)
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 @@ dhcp6_find_delegates(struct interface *ifp)
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 @@ dhcp6_bind(struct interface *ifp, const char *op, const char *sfrom)
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",
diff --git a/src/dhcpcd.8.in b/src/dhcpcd.8.in
index 50964565..bfd03cdc 100644
--- a/src/dhcpcd.8.in
+++ b/src/dhcpcd.8.in
@@ -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 @@ This allows
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
diff --git a/src/if-options.c b/src/if-options.c
index 23797bb1..9a261c07 100644
--- a/src/if-options.c
+++ b/src/if-options.c
@@ -165,6 +165,8 @@ const struct option cf_options[] = {
{"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 @@ invalid_token:
}
#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 @@ read_config(struct dhcpcd_ctx *ctx,
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) {
diff --git a/src/if-options.h b/src/if-options.h
index a73ba0d2..689d9344 100644
--- a/src/if-options.h
+++ b/src/if-options.h
@@ -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[];
diff --git a/src/ipv4ll.c b/src/ipv4ll.c
index fee115f2..93898109 100644
--- a/src/ipv4ll.c
+++ b/src/ipv4ll.c
@@ -228,6 +228,8 @@ ipv4ll_not_found(struct interface *ifp)
#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 @@ test:
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 @@ ipv4ll_defend_failed(struct interface *ifp)
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 @@ ipv4ll_start(void *arg)
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 @@ ipv4ll_drop(struct interface *ifp)
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 @@ ipv4ll_drop(struct interface *ifp)
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 @@ ipv4ll_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid)
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);
diff --git a/src/ipv6.c b/src/ipv6.c
index 3f0c1d8c..c9150c07 100644
--- a/src/ipv6.c
+++ b/src/ipv6.c
@@ -1416,6 +1416,9 @@ ipv6_addlinklocal(struct interface *ifp)
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) {
diff --git a/src/ipv6nd.c b/src/ipv6nd.c
index 1c082ae4..f0a79d51 100644
--- a/src/ipv6nd.c
+++ b/src/ipv6nd.c
@@ -1494,13 +1494,18 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
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);
+
+run:
ipv6nd_scriptrun(rap);
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
diff --git a/src/privsep.c b/src/privsep.c
index 6e76902a..f43e7ef2 100644
--- a/src/privsep.c
+++ b/src/privsep.c
@@ -362,7 +362,7 @@ ps_dostart(struct dhcpcd_ctx *ctx,
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;
diff --git a/src/route.c b/src/route.c
index 83bc37c7..f5f4f83c 100644
--- a/src/route.c
+++ b/src/route.c
@@ -713,6 +713,9 @@ rt_build(struct dhcpcd_ctx *ctx, int af)
#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 @@ rt_build(struct dhcpcd_ctx *ctx, int af)
}
}
-
getfail:
rt_headclear(&routes, AF_UNSPEC);
rt_headclear(&kroutes, AF_UNSPEC);
diff --git a/src/script.c b/src/script.c
index ce48b3ba..0260845e 100644
--- a/src/script.c
+++ b/src/script.c
@@ -350,6 +350,9 @@ make_env(struct dhcpcd_ctx *ctx, const struct interface *ifp,
}
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)