#define ELOOP_IPV6ND 6
#define ELOOP_IPV6RA_EXPIRE 7
#define ELOOP_DHCP6 8
+#define ELOOP_IF 9
#ifndef HOSTNAME_MAX_LEN
#define HOSTNAME_MAX_LEN 250 /* 255 - 3 (FQDN) - 2 (DNS enc) */
{
struct interface *ifp = arg;
struct if_options *ifo = ifp->options;
- int carrier;
if (ifo->options & DHCPCD_LINK) {
switch (ifp->carrier) {
case LINK_UNKNOWN:
/* No media state available.
* Loop until both IFF_UP and IFF_RUNNING are set */
- carrier = if_carrier(ifp);
- if (carrier == LINK_UNKNOWN) {
- if (IF_UPANDRUNNING(ifp))
- carrier = LINK_UP;
- else {
- eloop_timeout_add_msec(ifp->ctx->eloop,
- IF_POLL_UP * MSEC_PER_SEC,
- dhcpcd_startinterface, ifp);
- return;
- }
- }
- dhcpcd_handlecarrier(ifp->ctx, carrier,
- ifp->flags, ifp->name);
+ if_pollinit(ifp);
return;
}
}
dhcpcd_prestartinterface(void *arg)
{
struct interface *ifp = arg;
+ struct dhcpcd_ctx *ctx = ifp->ctx;
bool anondown;
+ if (ifp->options->poll != 0)
+ if_pollinit(ifp);
+
if (ifp->carrier == LINK_DOWN &&
ifp->options->options & DHCPCD_ANONYMOUS &&
ifp->flags & IFF_UP)
} else
anondown = false;
- if ((!(ifp->ctx->options & DHCPCD_MASTER) ||
+ if ((!(ctx->options & DHCPCD_MASTER) ||
ifp->options->options & DHCPCD_IF_UP || anondown) &&
!(ifp->flags & IFF_UP))
{
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 12, 2020
+.Dd June 18, 2020
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
detects an address added to a point to point interface (PPP, TUN, etc) then
it will set the listed DHCP options to the destination address of the
interface.
+.It Ic poll Op Ar time
+Polls the interface every
+.Ar time
+milliseconds (default of 100) to check flags and carrier status.
+This option should only be used if the driver does not report link state
+changes but can report the link state.
.It Ic profile Ar name
Subsequent options are only parsed for this profile
.Ar name .
#define IF_DATA_DHCP6 6
#define IF_DATA_MAX 7
-/* If the interface does not support carrier status (ie PPP),
- * dhcpcd can poll it for the relevant flags periodically */
-#define IF_POLL_UP 100 /* milliseconds */
-
#ifdef __QNX__
/* QNX carries defines for, but does not actually support PF_LINK */
#undef IFLR_ACTIVE
{
struct ifmediareq ifmr = { .ifm_status = 0 };
+ /* Not really needed, but the other OS update flags here also */
+ if (if_getflags(ifp) == -1)
+ return LINK_UNKNOWN;
+
strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) == -1 ||
!(ifmr.ifm_status & IFM_AVALID))
{"inactive", no_argument, NULL, O_INACTIVE},
{"mudurl", required_argument, NULL, O_MUDURL},
{"link_rcvbuf", required_argument, NULL, O_LINK_RCVBUF},
+ {"poll", optional_argument, NULL, O_POLL},
{NULL, 0, NULL, '\0'}
};
}
#endif
break;
+ case O_POLL:
+ if (arg == NULL) {
+ ifo->poll = IF_POLL_UP;
+ break;
+ }
+ ifo->poll = (unsigned long)
+ strtou(arg, NULL, 0, 0, ULONG_MAX, &e);
+ if (e) {
+ logerrx("failed to convert poll %s", arg);
+ return -1;
+ }
+ break;
default:
return 0;
}
#define O_INACTIVE O_BASE + 47
#define O_MUDURL O_BASE + 48
#define O_MSUSERCLASS O_BASE + 49
+#define O_POLL O_BASE + 50
extern const struct option cf_options[];
time_t mtime;
uint8_t iaid[4];
int metric;
+ unsigned long poll;
uint8_t requestmask[256 / NBBY];
uint8_t requiremask[256 / NBBY];
uint8_t nomask[256 / NBBY];
#include <syslog.h>
#include <unistd.h>
+#define ELOOP_QUEUE ELOOP_IF
#include "common.h"
+#include "eloop.h"
#include "dev.h"
#include "dhcp.h"
#include "dhcp6.h"
return ifs;
}
+static void
+if_poll(void *arg)
+{
+ struct interface *ifp = arg;
+ unsigned int flags = ifp->flags;
+ int carrier;
+
+ carrier = if_carrier(ifp); /* if_carrier will update ifp->flags */
+ if (ifp->carrier != carrier || ifp->flags != flags)
+ dhcpcd_handlecarrier(ifp->ctx, carrier, ifp->flags, ifp->name);
+
+ if (ifp->options->poll != 0 || ifp->carrier != LINK_UP)
+ if_pollinit(ifp);
+}
+
+int
+if_pollinit(struct interface *ifp)
+{
+ unsigned long msec;
+
+ msec = ifp->options->poll != 0 ? ifp->options->poll : IF_POLL_UP;
+ return eloop_timeout_add_msec(ifp->ctx->eloop, msec, if_poll, ifp);
+}
+
/*
* eth0.100:2 OR eth0i100:2 (seems to be NetBSD xvif(4) only)
*
#include <ifaddrs.h>
+/* If the interface does not support carrier status (ie PPP),
+ * dhcpcd can poll it for the relevant flags periodically */
+#define IF_POLL_UP 100 /* milliseconds */
+
/* Some systems have in-built IPv4 DAD.
* However, we need them to do DAD at carrier up as well. */
#ifdef IN_IFF_TENTATIVE
#define if_getmtu(ifp) if_domtu((ifp), 0)
#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
int if_carrier(struct interface *);
+int if_pollinit(struct interface *ifp);
#ifdef ALIAS_ADDR
int if_makealias(char *, size_t, const char *, int);