Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Nov 2019 20:34:33 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354861 - head/sys/netinet6
Message-ID:  <201911192034.xAJKYXFB072450@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Tue Nov 19 20:34:33 2019
New Revision: 354861
URL: https://svnweb.freebsd.org/changeset/base/354861

Log:
  nd6_rtr: re-sort functions
  
  Resort functions within file in a way that they depend on each other as
  that makes it easier to rework various things.
  Also allows us to remove file local function declarations.
  
  No functional changes.
  
  MFC after:	3 weeks
  Sponsored by:	Netflix

Modified:
  head/sys/netinet6/nd6_rtr.c

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c	Tue Nov 19 19:05:05 2019	(r354860)
+++ head/sys/netinet6/nd6_rtr.c	Tue Nov 19 20:34:33 2019	(r354861)
@@ -73,25 +73,10 @@ __FBSDID("$FreeBSD$");
 #include <netinet/icmp6.h>
 #include <netinet6/scope6_var.h>
 
-static int rtpref(struct nd_defrouter *);
 static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *);
 static int prelist_update(struct nd_prefixctl *, struct nd_defrouter *,
     struct mbuf *, int);
-static struct in6_ifaddr *in6_ifadd(struct nd_prefixctl *, int);
-static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *,
-    struct nd_defrouter *);
-static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *);
-static void pfxrtr_del(struct nd_pfxrouter *);
-static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *);
-static void defrouter_delreq(struct nd_defrouter *);
-static void nd6_rtmsg(int, struct rtentry *);
 
-static int in6_init_prefix_ltimes(struct nd_prefix *);
-static void in6_init_address_ltimes(struct nd_prefix *,
-    struct in6_addrlifetime *);
-
-static int rt6_deleteroute(const struct rtentry *, void *);
-
 TAILQ_HEAD(nd6_drhead, nd_defrouter);
 VNET_DEFINE_STATIC(struct nd6_drhead, nd6_defrouter);
 #define	V_nd6_defrouter			VNET(nd6_defrouter)
@@ -115,6 +100,8 @@ VNET_DEFINE(int, ip6_temp_regen_advance) = TEMPADDR_RE
 VNET_DEFINE(int, nd6_ignore_ipv6_only_ra) = 1;
 #endif
 
+SYSCTL_DECL(_net_inet6_icmp6);
+
 /* RTPREF_MEDIUM has to be 0! */
 #define RTPREF_HIGH	1
 #define RTPREF_MEDIUM	0
@@ -644,11 +631,72 @@ nd6_rtmsg(int cmd, struct rtentry *rt)
 		ifa_free(ifa);
 }
 
-/*
- * default router list processing sub routines
- */
+/* PFXRTR */
+static struct nd_pfxrouter *
+pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
+{
+	struct nd_pfxrouter *search;
 
+	ND6_LOCK_ASSERT();
+
+	LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) {
+		if (search->router == dr)
+			break;
+	}
+	return (search);
+}
+
 static void
+pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
+{
+	struct nd_pfxrouter *new;
+	bool update;
+
+	ND6_UNLOCK_ASSERT();
+
+	ND6_RLOCK();
+	if (pfxrtr_lookup(pr, dr) != NULL) {
+		ND6_RUNLOCK();
+		return;
+	}
+	ND6_RUNLOCK();
+
+	new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
+	if (new == NULL)
+		return;
+	defrouter_ref(dr);
+	new->router = dr;
+
+	ND6_WLOCK();
+	if (pfxrtr_lookup(pr, dr) == NULL) {
+		LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
+		update = true;
+	} else {
+		/* We lost a race to add the reference. */
+		defrouter_rele(dr);
+		free(new, M_IP6NDP);
+		update = false;
+	}
+	ND6_WUNLOCK();
+
+	if (update)
+		pfxlist_onlink_check();
+}
+
+static void
+pfxrtr_del(struct nd_pfxrouter *pfr)
+{
+
+	ND6_WLOCK_ASSERT();
+
+	LIST_REMOVE(pfr, pfr_entry);
+	defrouter_rele(pfr->router);
+	free(pfr, M_IP6NDP);
+}
+
+
+/* Default router list processing sub routines. */
+static void
 defrouter_addreq(struct nd_defrouter *new)
 {
 	struct sockaddr_in6 def, mask, gate;
@@ -675,31 +723,6 @@ defrouter_addreq(struct nd_defrouter *new)
 		new->installed = 1;
 }
 
-struct nd_defrouter *
-defrouter_lookup_locked(struct in6_addr *addr, struct ifnet *ifp)
-{
-	struct nd_defrouter *dr;
-
-	ND6_LOCK_ASSERT();
-	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
-		if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) {
-			defrouter_ref(dr);
-			return (dr);
-		}
-	return (NULL);
-}
-
-struct nd_defrouter *
-defrouter_lookup(struct in6_addr *addr, struct ifnet *ifp)
-{
-	struct nd_defrouter *dr;
-
-	ND6_RLOCK();
-	dr = defrouter_lookup_locked(addr, ifp);
-	ND6_RUNLOCK();
-	return (dr);
-}
-
 /*
  * Remove the default route for a given router.
  * This is just a subroutine function for defrouter_select_fib(), and
@@ -731,49 +754,6 @@ defrouter_delreq(struct nd_defrouter *dr)
 	dr->installed = 0;
 }
 
-/*
- * Remove all default routes from default router list.
- */
-void
-defrouter_reset(void)
-{
-	struct nd_defrouter *dr, **dra;
-	int count, i;
-
-	count = i = 0;
-
-	/*
-	 * We can't delete routes with the ND lock held, so make a copy of the
-	 * current default router list and use that when deleting routes.
-	 */
-	ND6_RLOCK();
-	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
-		count++;
-	ND6_RUNLOCK();
-
-	dra = malloc(count * sizeof(*dra), M_TEMP, M_WAITOK | M_ZERO);
-
-	ND6_RLOCK();
-	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
-		if (i == count)
-			break;
-		defrouter_ref(dr);
-		dra[i++] = dr;
-	}
-	ND6_RUNLOCK();
-
-	for (i = 0; i < count && dra[i] != NULL; i++) {
-		defrouter_delreq(dra[i]);
-		defrouter_rele(dra[i]);
-	}
-	free(dra, M_TEMP);
-
-	/*
-	 * XXX should we also nuke any default routers in the kernel, by
-	 * going through them by rtalloc1()?
-	 */
-}
-
 static void
 defrouter_del(struct nd_defrouter *dr)
 {
@@ -826,7 +806,75 @@ defrouter_del(struct nd_defrouter *dr)
 }
 
 
+struct nd_defrouter *
+defrouter_lookup_locked(struct in6_addr *addr, struct ifnet *ifp)
+{
+	struct nd_defrouter *dr;
+
+	ND6_LOCK_ASSERT();
+	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
+		if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) {
+			defrouter_ref(dr);
+			return (dr);
+		}
+	return (NULL);
+}
+
+struct nd_defrouter *
+defrouter_lookup(struct in6_addr *addr, struct ifnet *ifp)
+{
+	struct nd_defrouter *dr;
+
+	ND6_RLOCK();
+	dr = defrouter_lookup_locked(addr, ifp);
+	ND6_RUNLOCK();
+	return (dr);
+}
+
 /*
+ * Remove all default routes from default router list.
+ */
+void
+defrouter_reset(void)
+{
+	struct nd_defrouter *dr, **dra;
+	int count, i;
+
+	count = i = 0;
+
+	/*
+	 * We can't delete routes with the ND lock held, so make a copy of the
+	 * current default router list and use that when deleting routes.
+	 */
+	ND6_RLOCK();
+	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
+		count++;
+	ND6_RUNLOCK();
+
+	dra = malloc(count * sizeof(*dra), M_TEMP, M_WAITOK | M_ZERO);
+
+	ND6_RLOCK();
+	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
+		if (i == count)
+			break;
+		defrouter_ref(dr);
+		dra[i++] = dr;
+	}
+	ND6_RUNLOCK();
+
+	for (i = 0; i < count && dra[i] != NULL; i++) {
+		defrouter_delreq(dra[i]);
+		defrouter_rele(dra[i]);
+	}
+	free(dra, M_TEMP);
+
+	/*
+	 * XXX should we also nuke any default routers in the kernel, by
+	 * going through them by rtalloc1()?
+	 */
+}
+
+/*
  * Look up a matching default router list entry and remove it. Returns true if a
  * matching entry was found, false otherwise.
  */
@@ -850,6 +898,33 @@ defrouter_remove(struct in6_addr *addr, struct ifnet *
 }
 
 /*
+ * for default router selection
+ * regards router-preference field as a 2-bit signed integer
+ */
+static int
+rtpref(struct nd_defrouter *dr)
+{
+	switch (dr->raflags & ND_RA_FLAG_RTPREF_MASK) {
+	case ND_RA_FLAG_RTPREF_HIGH:
+		return (RTPREF_HIGH);
+	case ND_RA_FLAG_RTPREF_MEDIUM:
+	case ND_RA_FLAG_RTPREF_RSV:
+		return (RTPREF_MEDIUM);
+	case ND_RA_FLAG_RTPREF_LOW:
+		return (RTPREF_LOW);
+	default:
+		/*
+		 * This case should never happen.  If it did, it would mean a
+		 * serious bug of kernel internal.  We thus always bark here.
+		 * Or, can we even panic?
+		 */
+		log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->raflags);
+		return (RTPREF_INVALID);
+	}
+	/* NOTREACHED */
+}
+
+/*
  * Default Router Selection according to Section 6.3.6 of RFC 2461 and
  * draft-ietf-ipngwg-router-selection:
  * 1) Routers that are reachable or probably reachable should be preferred.
@@ -987,33 +1062,6 @@ defrouter_select_fib(int fibnum)
 		defrouter_rele(selected_dr);
 }
 
-/*
- * for default router selection
- * regards router-preference field as a 2-bit signed integer
- */
-static int
-rtpref(struct nd_defrouter *dr)
-{
-	switch (dr->raflags & ND_RA_FLAG_RTPREF_MASK) {
-	case ND_RA_FLAG_RTPREF_HIGH:
-		return (RTPREF_HIGH);
-	case ND_RA_FLAG_RTPREF_MEDIUM:
-	case ND_RA_FLAG_RTPREF_RSV:
-		return (RTPREF_MEDIUM);
-	case ND_RA_FLAG_RTPREF_LOW:
-		return (RTPREF_LOW);
-	default:
-		/*
-		 * This case should never happen.  If it did, it would mean a
-		 * serious bug of kernel internal.  We thus always bark here.
-		 * Or, can we even panic?
-		 */
-		log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->raflags);
-		return (RTPREF_INVALID);
-	}
-	/* NOTREACHED */
-}
-
 static struct nd_defrouter *
 defrtrlist_update(struct nd_defrouter *new)
 {
@@ -1112,66 +1160,154 @@ restart:
 	return (n);
 }
 
-static struct nd_pfxrouter *
-pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
+static int
+in6_init_prefix_ltimes(struct nd_prefix *ndpr)
 {
-	struct nd_pfxrouter *search;
+	if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
+		ndpr->ndpr_preferred = 0;
+	else
+		ndpr->ndpr_preferred = time_uptime + ndpr->ndpr_pltime;
+	if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
+		ndpr->ndpr_expire = 0;
+	else
+		ndpr->ndpr_expire = time_uptime + ndpr->ndpr_vltime;
 
-	ND6_LOCK_ASSERT();
+	return 0;
+}
 
-	LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) {
-		if (search->router == dr)
-			break;
+static void
+in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6)
+{
+	/* init ia6t_expire */
+	if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
+		lt6->ia6t_expire = 0;
+	else {
+		lt6->ia6t_expire = time_uptime;
+		lt6->ia6t_expire += lt6->ia6t_vltime;
 	}
-	return (search);
+
+	/* init ia6t_preferred */
+	if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
+		lt6->ia6t_preferred = 0;
+	else {
+		lt6->ia6t_preferred = time_uptime;
+		lt6->ia6t_preferred += lt6->ia6t_pltime;
+	}
 }
 
-static void
-pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
+static struct in6_ifaddr *
+in6_ifadd(struct nd_prefixctl *pr, int mcast)
 {
-	struct nd_pfxrouter *new;
-	bool update;
+	struct ifnet *ifp = pr->ndpr_ifp;
+	struct ifaddr *ifa;
+	struct in6_aliasreq ifra;
+	struct in6_ifaddr *ia, *ib;
+	int error, plen0;
+	struct in6_addr mask;
+	int prefixlen = pr->ndpr_plen;
+	int updateflags;
+	char ip6buf[INET6_ADDRSTRLEN];
 
-	ND6_UNLOCK_ASSERT();
+	in6_prefixlen2mask(&mask, prefixlen);
 
-	ND6_RLOCK();
-	if (pfxrtr_lookup(pr, dr) != NULL) {
-		ND6_RUNLOCK();
-		return;
+	/*
+	 * find a link-local address (will be interface ID).
+	 * Is it really mandatory? Theoretically, a global or a site-local
+	 * address can be configured without a link-local address, if we
+	 * have a unique interface identifier...
+	 *
+	 * it is not mandatory to have a link-local address, we can generate
+	 * interface identifier on the fly.  we do this because:
+	 * (1) it should be the easiest way to find interface identifier.
+	 * (2) RFC2462 5.4 suggesting the use of the same interface identifier
+	 * for multiple addresses on a single interface, and possible shortcut
+	 * of DAD.  we omitted DAD for this reason in the past.
+	 * (3) a user can prevent autoconfiguration of global address
+	 * by removing link-local address by hand (this is partly because we
+	 * don't have other way to control the use of IPv6 on an interface.
+	 * this has been our design choice - cf. NRL's "ifconfig auto").
+	 * (4) it is easier to manage when an interface has addresses
+	 * with the same interface identifier, than to have multiple addresses
+	 * with different interface identifiers.
+	 */
+	ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0); /* 0 is OK? */
+	if (ifa)
+		ib = (struct in6_ifaddr *)ifa;
+	else
+		return NULL;
+
+	/* prefixlen + ifidlen must be equal to 128 */
+	plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL);
+	if (prefixlen != plen0) {
+		ifa_free(ifa);
+		nd6log((LOG_INFO, "in6_ifadd: wrong prefixlen for %s "
+		    "(prefix=%d ifid=%d)\n",
+		    if_name(ifp), prefixlen, 128 - plen0));
+		return NULL;
 	}
-	ND6_RUNLOCK();
 
-	new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
-	if (new == NULL)
-		return;
-	defrouter_ref(dr);
-	new->router = dr;
+	/* make ifaddr */
+	in6_prepare_ifra(&ifra, &pr->ndpr_prefix.sin6_addr, &mask);
 
-	ND6_WLOCK();
-	if (pfxrtr_lookup(pr, dr) == NULL) {
-		LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
-		update = true;
-	} else {
-		/* We lost a race to add the reference. */
-		defrouter_rele(dr);
-		free(new, M_IP6NDP);
-		update = false;
-	}
-	ND6_WUNLOCK();
+	IN6_MASK_ADDR(&ifra.ifra_addr.sin6_addr, &mask);
+	/* interface ID */
+	ifra.ifra_addr.sin6_addr.s6_addr32[0] |=
+	    (ib->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]);
+	ifra.ifra_addr.sin6_addr.s6_addr32[1] |=
+	    (ib->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]);
+	ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
+	    (ib->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]);
+	ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
+	    (ib->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]);
+	ifa_free(ifa);
 
-	if (update)
-		pfxlist_onlink_check();
-}
+	/* lifetimes. */
+	ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
+	ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
 
-static void
-pfxrtr_del(struct nd_pfxrouter *pfr)
-{
+	/* XXX: scope zone ID? */
 
-	ND6_WLOCK_ASSERT();
+	ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
 
-	LIST_REMOVE(pfr, pfr_entry);
-	defrouter_rele(pfr->router);
-	free(pfr, M_IP6NDP);
+	/*
+	 * Make sure that we do not have this address already.  This should
+	 * usually not happen, but we can still see this case, e.g., if we
+	 * have manually configured the exact address to be configured.
+	 */
+	ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp,
+	    &ifra.ifra_addr.sin6_addr);
+	if (ifa != NULL) {
+		ifa_free(ifa);
+		/* this should be rare enough to make an explicit log */
+		log(LOG_INFO, "in6_ifadd: %s is already configured\n",
+		    ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr));
+		return (NULL);
+	}
+
+	/*
+	 * Allocate ifaddr structure, link into chain, etc.
+	 * If we are going to create a new address upon receiving a multicasted
+	 * RA, we need to impose a random delay before starting DAD.
+	 * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2]
+	 */
+	updateflags = 0;
+	if (mcast)
+		updateflags |= IN6_IFAUPDATE_DADDELAY;
+	if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) {
+		nd6log((LOG_ERR,
+		    "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n",
+		    ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr),
+		    if_name(ifp), error));
+		return (NULL);	/* ifaddr must not have been allocated. */
+	}
+
+	ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
+	/*
+	 * XXXRW: Assumption of non-NULLness here might not be true with
+	 * fine-grained locking -- should we validate it?  Or just return
+	 * earlier ifa rather than looking it up again?
+	 */
+	return (ia);		/* this is always non-NULL  and referenced. */
 }
 
 static struct nd_prefix *
@@ -2171,121 +2307,6 @@ restart:
 	return (error);
 }
 
-static struct in6_ifaddr *
-in6_ifadd(struct nd_prefixctl *pr, int mcast)
-{
-	struct ifnet *ifp = pr->ndpr_ifp;
-	struct ifaddr *ifa;
-	struct in6_aliasreq ifra;
-	struct in6_ifaddr *ia, *ib;
-	int error, plen0;
-	struct in6_addr mask;
-	int prefixlen = pr->ndpr_plen;
-	int updateflags;
-	char ip6buf[INET6_ADDRSTRLEN];
-
-	in6_prefixlen2mask(&mask, prefixlen);
-
-	/*
-	 * find a link-local address (will be interface ID).
-	 * Is it really mandatory? Theoretically, a global or a site-local
-	 * address can be configured without a link-local address, if we
-	 * have a unique interface identifier...
-	 *
-	 * it is not mandatory to have a link-local address, we can generate
-	 * interface identifier on the fly.  we do this because:
-	 * (1) it should be the easiest way to find interface identifier.
-	 * (2) RFC2462 5.4 suggesting the use of the same interface identifier
-	 * for multiple addresses on a single interface, and possible shortcut
-	 * of DAD.  we omitted DAD for this reason in the past.
-	 * (3) a user can prevent autoconfiguration of global address
-	 * by removing link-local address by hand (this is partly because we
-	 * don't have other way to control the use of IPv6 on an interface.
-	 * this has been our design choice - cf. NRL's "ifconfig auto").
-	 * (4) it is easier to manage when an interface has addresses
-	 * with the same interface identifier, than to have multiple addresses
-	 * with different interface identifiers.
-	 */
-	ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0); /* 0 is OK? */
-	if (ifa)
-		ib = (struct in6_ifaddr *)ifa;
-	else
-		return NULL;
-
-	/* prefixlen + ifidlen must be equal to 128 */
-	plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL);
-	if (prefixlen != plen0) {
-		ifa_free(ifa);
-		nd6log((LOG_INFO, "in6_ifadd: wrong prefixlen for %s "
-		    "(prefix=%d ifid=%d)\n",
-		    if_name(ifp), prefixlen, 128 - plen0));
-		return NULL;
-	}
-
-	/* make ifaddr */
-	in6_prepare_ifra(&ifra, &pr->ndpr_prefix.sin6_addr, &mask);
-
-	IN6_MASK_ADDR(&ifra.ifra_addr.sin6_addr, &mask);
-	/* interface ID */
-	ifra.ifra_addr.sin6_addr.s6_addr32[0] |=
-	    (ib->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]);
-	ifra.ifra_addr.sin6_addr.s6_addr32[1] |=
-	    (ib->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]);
-	ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
-	    (ib->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]);
-	ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
-	    (ib->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]);
-	ifa_free(ifa);
-
-	/* lifetimes. */
-	ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
-	ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
-
-	/* XXX: scope zone ID? */
-
-	ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
-
-	/*
-	 * Make sure that we do not have this address already.  This should
-	 * usually not happen, but we can still see this case, e.g., if we
-	 * have manually configured the exact address to be configured.
-	 */
-	ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp,
-	    &ifra.ifra_addr.sin6_addr);
-	if (ifa != NULL) {
-		ifa_free(ifa);
-		/* this should be rare enough to make an explicit log */
-		log(LOG_INFO, "in6_ifadd: %s is already configured\n",
-		    ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr));
-		return (NULL);
-	}
-
-	/*
-	 * Allocate ifaddr structure, link into chain, etc.
-	 * If we are going to create a new address upon receiving a multicasted
-	 * RA, we need to impose a random delay before starting DAD.
-	 * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2]
-	 */
-	updateflags = 0;
-	if (mcast)
-		updateflags |= IN6_IFAUPDATE_DADDELAY;
-	if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) {
-		nd6log((LOG_ERR,
-		    "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n",
-		    ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr),
-		    if_name(ifp), error));
-		return (NULL);	/* ifaddr must not have been allocated. */
-	}
-
-	ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
-	/*
-	 * XXXRW: Assumption of non-NULLness here might not be true with
-	 * fine-grained locking -- should we validate it?  Or just return
-	 * earlier ifa rather than looking it up again?
-	 */
-	return (ia);		/* this is always non-NULL  and referenced. */
-}
-
 /*
  * ia0 - corresponding public address
  */
@@ -2411,58 +2432,6 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcege
 }
 
 static int
-in6_init_prefix_ltimes(struct nd_prefix *ndpr)
-{
-	if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
-		ndpr->ndpr_preferred = 0;
-	else
-		ndpr->ndpr_preferred = time_uptime + ndpr->ndpr_pltime;
-	if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
-		ndpr->ndpr_expire = 0;
-	else
-		ndpr->ndpr_expire = time_uptime + ndpr->ndpr_vltime;
-
-	return 0;
-}
-
-static void
-in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6)
-{
-	/* init ia6t_expire */
-	if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
-		lt6->ia6t_expire = 0;
-	else {
-		lt6->ia6t_expire = time_uptime;
-		lt6->ia6t_expire += lt6->ia6t_vltime;
-	}
-
-	/* init ia6t_preferred */
-	if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
-		lt6->ia6t_preferred = 0;
-	else {
-		lt6->ia6t_preferred = time_uptime;
-		lt6->ia6t_preferred += lt6->ia6t_pltime;
-	}
-}
-
-/*
- * Delete all the routing table entries that use the specified gateway.
- * XXX: this function causes search through all entries of routing table, so
- * it shouldn't be called when acting as a router.
- */
-void
-rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
-{
-
-	/* We'll care only link-local addresses */
-	if (!IN6_IS_ADDR_LINKLOCAL(gateway))
-		return;
-
-	/* XXX Do we really need to walk any but the default FIB? */
-	rt_foreach_fib_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway);
-}
-
-static int
 rt6_deleteroute(const struct rtentry *rt, void *arg)
 {
 #define SIN6(s)	((struct sockaddr_in6 *)s)
@@ -2494,6 +2463,23 @@ rt6_deleteroute(const struct rtentry *rt, void *arg)
 #undef SIN6
 }
 
+/*
+ * Delete all the routing table entries that use the specified gateway.
+ * XXX: this function causes search through all entries of routing table, so
+ * it shouldn't be called when acting as a router.
+ */
+void
+rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
+{
+
+	/* We'll care only link-local addresses */
+	if (!IN6_IS_ADDR_LINKLOCAL(gateway))
+		return;
+
+	/* XXX Do we really need to walk any but the default FIB? */
+	rt_foreach_fib_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway);
+}
+
 int
 nd6_setdefaultiface(int ifindex)
 {
@@ -2522,47 +2508,6 @@ nd6_setdefaultiface(int ifindex)
 	return (error);
 }
 
-static int
-nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
-{
-	struct in6_defrouter d;
-	struct nd_defrouter *dr;
-	int error;
-
-	if (req->newptr != NULL)
-		return (EPERM);
-
-	error = sysctl_wire_old_buffer(req, 0);
-	if (error != 0)
-		return (error);
-
-	bzero(&d, sizeof(d));
-	d.rtaddr.sin6_family = AF_INET6;
-	d.rtaddr.sin6_len = sizeof(d.rtaddr);
-
-	ND6_RLOCK();
-	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
-		d.rtaddr.sin6_addr = dr->rtaddr;
-		error = sa6_recoverscope(&d.rtaddr);
-		if (error != 0)
-			break;
-		d.flags = dr->raflags;
-		d.rtlifetime = dr->rtlifetime;
-		d.expire = dr->expire + (time_second - time_uptime);
-		d.if_index = dr->ifp->if_index;
-		error = SYSCTL_OUT(req, &d, sizeof(d));
-		if (error != 0)
-			break;
-	}
-	ND6_RUNLOCK();
-	return (error);
-}
-SYSCTL_DECL(_net_inet6_icmp6);
-SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
-	CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
-	NULL, 0, nd6_sysctl_drlist, "S,in6_defrouter",
-	"NDP default router list");
-
 bool
 nd6_defrouter_list_empty(void)
 {
@@ -2650,3 +2595,43 @@ nd6_defrouter_init(void)
 
 	TAILQ_INIT(&V_nd6_defrouter);
 }
+
+static int
+nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
+{
+	struct in6_defrouter d;
+	struct nd_defrouter *dr;
+	int error;
+
+	if (req->newptr != NULL)
+		return (EPERM);
+
+	error = sysctl_wire_old_buffer(req, 0);
+	if (error != 0)
+		return (error);
+
+	bzero(&d, sizeof(d));
+	d.rtaddr.sin6_family = AF_INET6;
+	d.rtaddr.sin6_len = sizeof(d.rtaddr);
+
+	ND6_RLOCK();
+	TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
+		d.rtaddr.sin6_addr = dr->rtaddr;
+		error = sa6_recoverscope(&d.rtaddr);
+		if (error != 0)
+			break;
+		d.flags = dr->raflags;
+		d.rtlifetime = dr->rtlifetime;
+		d.expire = dr->expire + (time_second - time_uptime);
+		d.if_index = dr->ifp->if_index;
+		error = SYSCTL_OUT(req, &d, sizeof(d));
+		if (error != 0)
+			break;
+	}
+	ND6_RUNLOCK();
+	return (error);
+}
+SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
+	CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
+	NULL, 0, nd6_sysctl_drlist, "S,in6_defrouter",
+	"NDP default router list");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911192034.xAJKYXFB072450>