]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add --noconfigure option
authorRoy Marples <roy@marples.name>
Wed, 4 Nov 2020 14:18:48 +0000 (14:18 +0000)
committerRoy Marples <roy@marples.name>
Wed, 4 Nov 2020 14:18:48 +0000 (14:18 +0000)
With this set dhcpcd will not configure anything on the host.
The expectation is that a 3rd party script will instead.

17 files changed:
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

index ac04c652f1b20cc674524c2f1bfe9fe749b40ce5..3d5173286335d745e46f2e1de44eca67e0a88a03 100644 (file)
@@ -42,6 +42,6 @@ BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
        ;;
 esac
 
-if $if_up; then
+if $if_configured && $if_up; then
        set_zoneinfo
 fi
index 03e846fa2d50ed5b264196f0c45614091a258de0..73d33386cd91cb4ec438e499c64cc0d2b34f1dbd 100644 (file)
@@ -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
index b515e4c13789d56100262cd7ed9e7f32f287b764..abeb369672210351bf2d6253cb14c8dd5ff2fe09 100644 (file)
@@ -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
index fd3945187e24af1b4cc0199769a92c7d7c0246ad..046ab6b33a06cb5b98057d1db6cf1aa86576cd71 100644 (file)
@@ -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
index abe6a4334eebed20f2380cb068cfa2bd8bb990b2..c5cdad90260d69a1dbffb2d526a5194db6199b5f 100644 (file)
@@ -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
index 5bd5eacf9e41d28e76015c638807fd7b3c095e81..09a12b97dcd8ac5073f8c2bfcfc637db1507f29e 100644 (file)
@@ -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
index 647a0aaa78b4ab2310269debcf588987e270af85..e2e9accdcfc3d65a7061be1ba9243c422de8f792 100644 (file)
@@ -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);
index eda42e209bf1ddb6fae71a64632cd77f23045e8b..ec6d7738005d9d8848ebe0621fea008bfc631178 100644 (file)
@@ -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",
index 509645659f66725a87637497a305c36fef7351ea..bfd03cdcc8bd9aa9de56b1802f82e169ebf56085 100644 (file)
@@ -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
index 23797bb1087e561a34d996ac7645ab46cceb4445..9a261c077c87293833ce537efe1eeb3cb64448ee 100644 (file)
@@ -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) {
index a73ba0d2b83ac792e6f69391fe623d3f6bbe8050..689d9344ba9e1eb8acbc610ab70dadd0146f4593 100644 (file)
@@ -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)
 #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[];
 
index fee115f25069ae94a9d6ef8a12ef0ea44f2f6c3a..93898109f7abb090968a4aba102ca7ea5b133d16 100644 (file)
@@ -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);
index 3f0c1d8cf941f2c0d758e51b4674ac8409fb4723..c9150c07cb271a56370a8522b9d91fa13f3d2f05 100644 (file)
@@ -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) {
index 1c082ae4a2b2be3a60d11518815417763fdd3892..f0a79d5145b46e3f10da363b4a8d2b56e143aad4 100644 (file)
@@ -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);
index 6e76902afc2855a693f4aabed06792665d16aedb..f43e7ef20260f952ef64f0481910181911dba06b 100644 (file)
@@ -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;
index 83bc37c7773159958be6585e2df167bd4fafffd4..f5f4f83cf278879724c630f62710023eb9ac73fb 100644 (file)
@@ -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);
index ce48b3bac53d8b52151e6ae9aa2678862eb59ac6..0260845e6a3e89e20744b9665fca6f2ccc2874f6 100644 (file)
@@ -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)