-W seconds will wait for the detached flag to clear on addresses on

interfaces marked up to allow time for the carrier to appear on the
interface.

This does not extend the -w option duration.
This commit is contained in:
roy 2016-01-07 11:32:21 +00:00
parent 056eaaa80c
commit 74efc0b2e3
5 changed files with 101 additions and 29 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: af_inet.c,v 1.17 2015/05/12 14:05:29 roy Exp $ */
/* $NetBSD: af_inet.c,v 1.18 2016/01/07 11:32:21 roy Exp $ */
/*
* Copyright (c) 1983, 1993
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: af_inet.c,v 1.17 2015/05/12 14:05:29 roy Exp $");
__RCSID("$NetBSD: af_inet.c,v 1.18 2016/01/07 11:32:21 roy Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -62,14 +62,17 @@ __RCSID("$NetBSD: af_inet.c,v 1.17 2015/05/12 14:05:29 roy Exp $");
static void in_constructor(void) __attribute__((constructor));
static void in_status(prop_dictionary_t, prop_dictionary_t, bool);
static void in_commit_address(prop_dictionary_t, prop_dictionary_t);
static bool in_addr_tentative(struct ifaddrs *ifa);
static bool in_addr_flags(struct ifaddrs *, int);
static bool in_addr_tentative(struct ifaddrs *);
static bool in_addr_tentative_or_detached(struct ifaddrs *);
static void in_alias(const char *, prop_dictionary_t, prop_dictionary_t,
struct in_aliasreq *);
static struct afswtch af = {
.af_name = "inet", .af_af = AF_INET, .af_status = in_status,
.af_addr_commit = in_commit_address,
.af_addr_tentative = in_addr_tentative
.af_addr_tentative = in_addr_tentative,
.af_addr_tentative_or_detached = in_addr_tentative_or_detached
};
static void
@ -220,10 +223,10 @@ in_commit_address(prop_dictionary_t env, prop_dictionary_t oenv)
commit_address(env, oenv, &inparam);
}
#ifdef SIOCGIFAFLAG_IN
static bool
in_addr_tentative(struct ifaddrs *ifa)
in_addr_flags(struct ifaddrs *ifa, int flags)
{
#ifdef IN_IFF_TENTATIVE
int s;
struct ifreq ifr;
@ -234,7 +237,28 @@ in_addr_tentative(struct ifaddrs *ifa)
err(EXIT_FAILURE, "%s: getsock", __func__);
if (prog_ioctl(s, SIOCGIFAFLAG_IN, &ifr) == -1)
err(EXIT_FAILURE, "SIOCGIFAFLAG_IN");
return ifr.ifr_addrflags & IN_IFF_TENTATIVE ? true : false;
return ifr.ifr_addrflags & flags ? true : false;
return false;
}
#endif
static bool
in_addr_tentative(struct ifaddrs *ifa)
{
#ifdef IN_IFF_TENTATIVE
return in_addr_flags(ifa, IN_IFF_TENTATIVE);
#else
return false;
#endif
}
static bool
in_addr_tentative_or_detached(struct ifaddrs *ifa)
{
#ifdef IN_IFF_TENTATIVE
return in_addr_flags(ifa, IN_IFF_TENTATIVE | IN_IFF_DETACHED);
#else
return false;
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: af_inet6.c,v 1.33 2015/05/12 14:05:29 roy Exp $ */
/* $NetBSD: af_inet6.c,v 1.34 2016/01/07 11:32:21 roy Exp $ */
/*
* Copyright (c) 1983, 1993
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: af_inet6.c,v 1.33 2015/05/12 14:05:29 roy Exp $");
__RCSID("$NetBSD: af_inet6.c,v 1.34 2016/01/07 11:32:21 roy Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -72,7 +72,9 @@ static int setia6vltime_impl(prop_dictionary_t, struct in6_aliasreq *);
static int setia6lifetime(prop_dictionary_t, int64_t, time_t *, uint32_t *);
static void in6_status(prop_dictionary_t, prop_dictionary_t, bool);
static bool in6_addr_flags(struct ifaddrs *ifa, int);
static bool in6_addr_tentative(struct ifaddrs *ifa);
static bool in6_addr_tentative_or_detached(struct ifaddrs *ifa);
static struct usage_func usage;
static cmdloop_branch_t branch[2];
@ -103,7 +105,8 @@ struct pkw inet6 = PKW_INITIALIZER(&inet6, "IPv6 keywords", NULL,
static struct afswtch in6af = {
.af_name = "inet6", .af_af = AF_INET6, .af_status = in6_status,
.af_addr_commit = in6_commit_address,
.af_addr_tentative = in6_addr_tentative
.af_addr_tentative = in6_addr_tentative,
.af_addr_tentative_or_detached = in6_addr_tentative_or_detached
};
static int
@ -477,7 +480,7 @@ in6_commit_address(prop_dictionary_t env, prop_dictionary_t oenv)
}
static bool
in6_addr_tentative(struct ifaddrs *ifa)
in6_addr_flags(struct ifaddrs *ifa, int flags)
{
int s;
struct in6_ifreq ifr;
@ -489,7 +492,21 @@ in6_addr_tentative(struct ifaddrs *ifa)
ifr.ifr_addr = *(struct sockaddr_in6 *)ifa->ifa_addr;
if (prog_ioctl(s, SIOCGIFAFLAG_IN6, &ifr) == -1)
err(EXIT_FAILURE, "SIOCGIFAFLAG_IN6");
return ifr.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE ? true : false;
return ifr.ifr_ifru.ifru_flags6 & flags ? true : false;
}
static bool
in6_addr_tentative(struct ifaddrs *ifa)
{
return in6_addr_flags(ifa, IN6_IFF_TENTATIVE);
}
static bool
in6_addr_tentative_or_detached(struct ifaddrs *ifa)
{
return in6_addr_flags(ifa, IN6_IFF_TENTATIVE | IN6_IFF_DETACHED);
}
static void

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ifconfig.8,v 1.109 2014/10/20 14:50:09 roy Exp $
.\" $NetBSD: ifconfig.8,v 1.110 2016/01/07 11:32:21 roy Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94
.\"
.Dd October 12, 2014
.Dd January 7, 2016
.Dt IFCONFIG 8
.Os
.Sh NAME
@ -61,6 +61,7 @@
.Nm
.Fl w
.Ar secs
.Op Fl W Ar secs
.Nm
.Fl C
.Sh DESCRIPTION
@ -872,6 +873,13 @@ flag to be removed from all addresses.
0 seconds means to wait indefinitely until all addresses no longer have the
.Cm tentative
flag.
The optional
.Fl W
flag may be used to wait
.Ar seconds
seconds during the above time for the detached flag to be removed from all
addresses whose interface is marked ``up'' as well.
The detached flag is set when the interface does not have a carrier.
.Pp
The
.Fl N

View File

@ -1,4 +1,4 @@
/* $NetBSD: ifconfig.c,v 1.235 2015/07/29 07:42:27 ozaki-r Exp $ */
/* $NetBSD: ifconfig.c,v 1.236 2016/01/07 11:32:21 roy Exp $ */
/*-
* Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
@ -63,7 +63,7 @@
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1983, 1993\
The Regents of the University of California. All rights reserved.");
__RCSID("$NetBSD: ifconfig.c,v 1.235 2015/07/29 07:42:27 ozaki-r Exp $");
__RCSID("$NetBSD: ifconfig.c,v 1.236 2016/01/07 11:32:21 roy Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -104,11 +104,11 @@ __RCSID("$NetBSD: ifconfig.c,v 1.235 2015/07/29 07:42:27 ozaki-r Exp $");
#define WAIT_DAD 10000000 /* nanoseconds between each poll, 10ms */
static bool bflag, dflag, hflag, sflag, uflag, wflag;
static bool bflag, dflag, hflag, sflag, uflag, Wflag, wflag;
bool lflag, Nflag, vflag, zflag;
static long wflag_secs;
static long wflag_secs, Wflag_secs;
static char gflags[10 + 26 * 2 + 1] = "AabCdhlNsuvw:z";
static char gflags[10 + 26 * 2 + 1] = "AabCdhlNsuvW:w:z";
bool gflagset[10 + 26 * 2];
static int carrier(prop_dictionary_t);
@ -518,14 +518,25 @@ wait_dad_exec(prop_dictionary_t env, prop_dictionary_t oenv)
bool waiting;
struct ifaddrs *ifaddrs, *ifa;
const struct timespec ts = { .tv_sec = 0, .tv_nsec = WAIT_DAD };
const struct timespec add = { .tv_sec = wflag_secs, .tv_nsec = 0};
struct timespec now, end = { .tv_sec = wflag_secs, .tv_nsec = 0};
struct timespec now, end_det, end;
const struct afswtch *afp;
if (wflag_secs) {
const struct timespec tent =
{ .tv_sec = wflag_secs, .tv_nsec = 0};
const struct timespec det =
{ .tv_sec = Wflag_secs, .tv_nsec = 0};
if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
err(EXIT_FAILURE, "clock_gettime");
timespecadd(&now, &add, &end);
timespecadd(&now, &tent, &end);
if (Wflag_secs)
timespecadd(&now, &det, &end_det);
else
timespecclear(&end_det);
} else {
timespecclear(&end_det);
timespecclear(&end);
}
if (getifaddrs(&ifaddrs) == -1)
@ -537,8 +548,14 @@ wait_dad_exec(prop_dictionary_t env, prop_dictionary_t oenv)
if (ifa->ifa_addr == NULL)
continue;
afp = lookup_af_bynum(ifa->ifa_addr->sa_family);
if (afp && afp->af_addr_tentative &&
afp->af_addr_tentative(ifa))
if (afp &&
((afp->af_addr_tentative_or_detached &&
ifa->ifa_flags & IFF_UP &&
timespecisset(&end_det) &&
timespeccmp(&now, &end_det, <) &&
afp->af_addr_tentative_or_detached(ifa)) ||
(afp->af_addr_tentative &&
afp->af_addr_tentative(ifa))))
{
waiting = true;
break;
@ -595,7 +612,7 @@ int
main(int argc, char **argv)
{
const struct afswtch *afp;
int af, s;
int af, s, e;
bool aflag = false, Cflag = false;
struct match match[32];
size_t nmatch;
@ -603,7 +620,6 @@ main(int argc, char **argv)
int ch, narg = 0, rc;
prop_dictionary_t env, oenv;
const char *ifname;
char *end;
memset(match, 0, sizeof(match));
@ -662,9 +678,15 @@ main(int argc, char **argv)
case 'w':
wflag = true;
wflag_secs = strtol(optarg, &end, 10);
if ((end != NULL && *end != '\0') ||
wflag_secs < 0 || wflag_secs >= INT32_MAX)
wflag_secs = strtoi(optarg, NULL, 10, 0, INT32_MAX, &e);
if (e)
errx(EXIT_FAILURE, "%s: not a number", optarg);
break;
case 'W':
Wflag = true;
Wflag_secs = strtoi(optarg, NULL, 10, 0, INT32_MAX, &e);
if (e)
errx(EXIT_FAILURE, "%s: not a number", optarg);
break;

View File

@ -14,6 +14,7 @@ struct afswtch {
void (*af_status)(prop_dictionary_t, prop_dictionary_t, bool);
void (*af_addr_commit)(prop_dictionary_t, prop_dictionary_t);
bool (*af_addr_tentative)(struct ifaddrs *);
bool (*af_addr_tentative_or_detached)(struct ifaddrs *);
SIMPLEQ_ENTRY(afswtch) af_next;
};