Update to dhcpcd-9.3.2 with the following changes:

* DHCP: Add support for IPv6-Only Preferred option, RFC 8925.
 * BSD: `LINK_STATE_UNKNOWN` is treated as UP once again
 * privsep: pass logging to the privileged actioneer
 * privsep: allow logfile re-opening to work
 * privsep: close BPF socket on ENXIO
 * privsep: don't leave a BOOTP BPF listener rebooting in non master mode
This commit is contained in:
roy 2020-11-01 14:23:02 +00:00
parent 777f324a0e
commit 545ab76352
12 changed files with 96 additions and 24 deletions

View File

@ -29,7 +29,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
#define VERSION "9.3.1"
#define VERSION "9.3.2"
#ifndef PRIVSEP_USER
# define PRIVSEP_USER "_" PACKAGE

View File

@ -116,6 +116,7 @@ enum DHO {
DHO_RAPIDCOMMIT = 80, /* RFC 4039 */
DHO_FQDN = 81,
DHO_AUTHENTICATION = 90, /* RFC 3118 */
DHO_IPV6_PREFERRED_ONLY = 108, /* RFC 8925 */
DHO_AUTOCONFIGURE = 116, /* RFC 2563 */
DHO_DNSSEARCH = 119, /* RFC 3397 */
DHO_CSR = 121, /* RFC 3442 */
@ -139,6 +140,8 @@ enum FQDN {
FQDN_BOTH = 0x31
};
#define MIN_V6ONLY_WAIT 300 /* seconds, RFC 8925 */
/* Sizes for BOOTP options */
#define BOOTP_CHADDR_LEN 16
#define BOOTP_SNAME_LEN 64

View File

@ -234,6 +234,7 @@ const char dhcpcd_embedded_conf[] =
"embed uint16 country_code\n"
"define 100 string posix_timezone\n"
"define 101 string tzdb_timezone\n"
"define 108 uint32 ipv6_only_preferred\n"
"define 116 byte auto_configure\n"
"define 117 array uint16 name_service_search\n"
"define 118 ipaddress subnet_selection\n"

View File

@ -30,7 +30,7 @@
#define INITDEFINENDS 6
#define INITDEFINE6S 14
#else
#define INITDEFINES 124
#define INITDEFINES 125
#define INITDEFINENDS 7
#define INITDEFINE6S 69
#endif

View File

@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd September 28, 2020
.Dd October 25, 2020
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
@ -606,18 +606,24 @@ Suppress any dhcpcd output to the console, except for errors.
.It Ic reboot Ar seconds
Allow
.Ar reboot
seconds before moving to the DISCOVER phase if we have an old lease to use
and moving from DISCOVER to IPv4LL if no reply.
seconds before moving to the DISCOVER phase if we have an old lease to use.
Allow
.Ar reboot
seconds before starting fallback states from the DISCOVER phase.
IPv4LL is started when the first
.Ar reboot
timeout is reached.
The default is 5 seconds.
A setting of 0 seconds causes
.Nm dhcpcd
to skip the REBOOT phase and go straight into DISCOVER.
.Nm
to skip the reboot phase and go straight into DISCOVER.
This is desirable for mobile users because if you change from network A to
network B and they use the same subnet and the address from network A isn't
in use on network B, then the DHCP server will remain silent even if
authoritative which means
.Nm dhcpcd
will timeout before moving back to the DISCOVER phase.
This has no effect on DHCPv6 other than skipping the reboot phase.
.It Ic release
.Nm dhcpcd
will release the lease prior to stopping the interface.

View File

@ -199,6 +199,7 @@ struct dhcpcd_ctx {
struct passwd *ps_user; /* struct passwd for privsep user */
pid_t ps_root_pid;
int ps_root_fd; /* Privileged Actioneer commands */
int ps_log_fd; /* chroot logging */
int ps_data_fd; /* Data from root spawned processes */
struct eloop *ps_eloop; /* eloop for polling root data */
struct ps_process_head ps_processes; /* List of spawned processes */

View File

@ -198,10 +198,8 @@ if_is_link_up(const struct interface *ifp)
{
return ifp->flags & IFF_UP &&
(ifp->carrier == LINK_UP ||
(ifp->carrier == LINK_UNKNOWN &&
!(ifp->options == NULL ||
ifp->options->options & DHCPCD_LINK)));
(ifp->carrier != LINK_DOWN ||
(ifp->options != NULL && !(ifp->options->options & DHCPCD_LINK)));
}
int

View File

@ -76,6 +76,11 @@ __printflike(2, 3) void logerrmessage(int pri, const char *fmt, ...);
#define logerr(...) log_err(__VA_ARGS__)
#define logerrx(...) log_errx(__VA_ARGS__)
/* For logging in a chroot */
int loggetfd(void);
void logsetfd(int);
int logreadfd(int);
unsigned int loggetopts(void);
void logsetopts(unsigned int);
#define LOGERR_DEBUG (1U << 6)
@ -97,8 +102,10 @@ void logsetopts(unsigned int);
void logsettag(const char *);
#endif
/* Can be called more than once. */
int logopen(const char *);
/* Should only be called at program exit. */
void logclose(void);
int logreopen(void);
#endif

View File

@ -70,9 +70,21 @@ ps_bpf_recvbpf(void *arg)
* This mechanism allows us to read each packet from the buffer. */
while (!(bpf->bpf_flags & BPF_EOF)) {
len = bpf_read(bpf, buf, sizeof(buf));
if (len == -1)
logerr(__func__);
if (len == -1 || len == 0)
if (len == -1) {
int error = errno;
logerr("%s: %s", psp->psp_ifname, __func__);
if (error != ENXIO)
break;
/* If the interface has departed, close the BPF
* socket. This stops log spam if RTM_IFANNOUNCE is
* delayed in announcing the departing interface. */
eloop_event_delete(psp->psp_ctx->eloop, bpf->bpf_fd);
bpf_close(bpf);
psp->psp_bpf = NULL;
break;
}
if (len == 0)
break;
psm.ps_flags = bpf->bpf_flags;
len = ps_sendpsmdata(psp->psp_ctx, psp->psp_ctx->ps_data_fd,
@ -107,6 +119,12 @@ ps_bpf_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg)
return -1;
}
/* We might have had an earlier ENXIO error. */
if (psp->psp_bpf == NULL) {
errno = ENXIO;
return -1;
}
return bpf_send(psp->psp_bpf, psp->psp_proto,
iov->iov_base, iov->iov_len);
}

View File

@ -561,6 +561,9 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg)
rlen = sizeof(mtime);
}
break;
case PS_LOGREOPEN:
err = logopen(ctx->logfile);
break;
#ifdef AUTH
case PS_AUTH_MONORDM:
err = ps_root_monordm(data, len);
@ -780,18 +783,34 @@ ps_root_dispatch(void *arg)
logerr(__func__);
}
static void
ps_root_log(void *arg)
{
struct dhcpcd_ctx *ctx = arg;
if (logreadfd(ctx->ps_log_fd) == -1)
logerr(__func__);
}
pid_t
ps_root_start(struct dhcpcd_ctx *ctx)
{
int fd[2];
int logfd[2], datafd[2];
pid_t pid;
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1)
return -1;
if (ps_setbuf_fdpair(fd) == -1)
if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, logfd) == -1)
return -1;
#ifdef PRIVSEP_RIGHTS
if (ps_rights_limit_fdpair(fd) == -1)
if (ps_rights_limit_fdpair(logfd) == -1)
return -1;
#endif
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, datafd) == -1)
return -1;
if (ps_setbuf_fdpair(datafd) == -1)
return -1;
#ifdef PRIVSEP_RIGHTS
if (ps_rights_limit_fdpair(datafd) == -1)
return -1;
#endif
@ -800,14 +819,22 @@ ps_root_start(struct dhcpcd_ctx *ctx)
ps_root_startcb, ps_root_signalcb, 0);
if (pid == 0) {
ctx->ps_data_fd = fd[1];
close(fd[0]);
ctx->ps_log_fd = logfd[1];
if (eloop_event_add(ctx->eloop, ctx->ps_log_fd,
ps_root_log, ctx) == -1)
return -1;
close(logfd[0]);
ctx->ps_data_fd = datafd[1];
close(datafd[0]);
return 0;
} else if (pid == -1)
return -1;
ctx->ps_data_fd = fd[0];
close(fd[1]);
logsetfd(logfd[0]);
close(logfd[1]);
ctx->ps_data_fd = datafd[0];
close(datafd[1]);
if (eloop_event_add(ctx->eloop, ctx->ps_data_fd,
ps_root_dispatch, ctx) == -1)
return -1;
@ -906,6 +933,15 @@ ps_root_filemtime(struct dhcpcd_ctx *ctx, const char *file, time_t *time)
return ps_root_readerror(ctx, time, sizeof(*time));
}
ssize_t
ps_root_logreopen(struct dhcpcd_ctx *ctx)
{
if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_LOGREOPEN, 0, NULL, 0) == -1)
return -1;
return ps_root_readerror(ctx, NULL, 0);
}
#ifdef PRIVSEP_GETIFADDRS
int
ps_root_getifaddrs(struct dhcpcd_ctx *ctx, struct ifaddrs **ifahead)

View File

@ -47,6 +47,7 @@ ssize_t ps_root_filemtime(struct dhcpcd_ctx *, const char *, time_t *);
ssize_t ps_root_readfile(struct dhcpcd_ctx *, const char *, void *, size_t);
ssize_t ps_root_writefile(struct dhcpcd_ctx *, const char *, mode_t,
const void *, size_t);
ssize_t ps_root_logreopen(struct dhcpcd_ctx *);
ssize_t ps_root_script(struct dhcpcd_ctx *, const void *, size_t);
int ps_root_getauthrdm(struct dhcpcd_ctx *, uint64_t *);
#ifdef PRIVSEP_GETIFADDRS

View File

@ -52,6 +52,7 @@
#define PS_AUTH_MONORDM 0x0017
#define PS_CTL 0x0018
#define PS_CTL_EOF 0x0019
#define PS_LOGREOPEN 0x0020
/* BSD Commands */
#define PS_IOCTLLINK 0x0101