From: Roy Marples Date: Wed, 4 Nov 2020 14:18:48 +0000 (+0000) Subject: Add --noconfigure option X-Git-Tag: v9.3.3~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e9dfc2416bc5ff97166905cbb69e71dd2be6411a;p=thirdparty%2Fdhcpcd.git Add --noconfigure option With this set dhcpcd will not configure anything on the host. The expectation is that a 3rd party script will instead. --- 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)