With this set dhcpcd will not configure anything on the host.
The expectation is that a 3rd party script will instead.
;;
esac
-if $if_up; then
+if $if_configured && $if_up; then
set_zoneinfo
fi
;;
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
;;
esac
-if $if_up && [ "$reason" != ROUTERADVERT ]; then
+if $if_configured && $if_up && [ "$reason" != ROUTERADVERT ]; then
set_hostname
fi
;;
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
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
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
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);
/* 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 &&
return;
dhcp_closeinet(ifp);
-
#ifdef PRIVSEP
if (IN_PRIVSEP_SE(ctx)) {
if (ps_inet_openbootp(state->addr) == -1)
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;
#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);
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) {
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;
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",
.\" 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
.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
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
{"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'}
};
}
#endif
break;
+ case O_CONFIGURE:
+ ifo->options |= DHCPCD_CONFIGURE;
+ break;
+ case O_NOCONFIGURE:
+ ifo->options &= ~DHCPCD_CONFIGURE;
+ break;
default:
return 0;
}
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) {
#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[];
#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;
return;
}
rt_build(ifp->ctx, AF_INET);
+run:
astate = arp_announceaddr(ifp->ctx, &ia->addr);
if (astate != NULL)
astate->announced_cb = ipv4ll_announced_arp;
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");
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
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;
}
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;
}
}
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);
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) {
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);
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;
#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)
}
}
-
getfail:
rt_headclear(&routes, AF_UNSPEC);
rt_headclear(&kroutes, AF_UNSPEC);
}
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)