summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorsmh <smh@FreeBSD.org>2015-12-17 14:41:30 +0000
committersmh <smh@FreeBSD.org>2015-12-17 14:41:30 +0000
commit45d5617154226a3aec179038a1be774c890a4f26 (patch)
treed5286aaab1a7faa0613aa42f51b270bccb17fab2 /sys/netinet6
parent61fca2bcde6ebd90840d20ccd6bc580e1e3e3968 (diff)
downloadFreeBSD-src-45d5617154226a3aec179038a1be774c890a4f26.zip
FreeBSD-src-45d5617154226a3aec179038a1be774c890a4f26.tar.gz
Revert r292275 & r292379
glebius has concerns about these changes so reverting those can be discussed and addressed. Sponsored by: Multiplay
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c2
-rw-r--r--sys/netinet6/in6_var.h10
-rw-r--r--sys/netinet6/nd6.c36
-rw-r--r--sys/netinet6/nd6.h4
-rw-r--r--sys/netinet6/nd6_nbr.c144
5 files changed, 30 insertions, 166 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index c2f4397..aedaf7f 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -114,7 +114,7 @@ VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix);
#define V_icmp6_nodeinfo_oldmcprefix VNET(icmp6_nodeinfo_oldmcprefix)
/*
- * Definitions of some constant IP6 addresses.
+ * Definitions of some costant IP6 addresses.
*/
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
index 54fa1f5..007fd66 100644
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -399,16 +399,6 @@ struct in6_rrenumreq {
#define IA6_SIN6(ia) (&((ia)->ia_addr))
#define IA6_DSTSIN6(ia) (&((ia)->ia_dstaddr))
#define IFA_IN6(x) (&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr)
-#define IFA_IN6_FLAGS(ifa) ((struct in6_ifaddr *)ifa)->ia6_flags
-#define IFA_ND6_NA_BASE_FLAGS(ifp, ifa) \
- (IFA_IN6_FLAGS(ifa) & IN6_IFF_ANYCAST ? 0 : ND_NA_FLAG_OVERRIDE) | \
- ((V_ip6_forwarding && !(ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && \
- V_ip6_norbit_raif)) ? ND_NA_FLAG_ROUTER : 0)
-#define IFA_ND6_NA_UNSOLICITED_SKIP(ifa) \
- (IFA_IN6_FLAGS(ifa) & (IN6_IFF_DUPLICATED | IN6_IFF_DEPRECATED | \
- IN6_IFF_TENTATIVE)) != 0
-#define IN6_MAX_ANYCAST_DELAY_TIME_MS 1000000
-#define IN6_BROADCAST_DELAY_TIME_MS 1000
#define IFA_DSTIN6(x) (&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr)
#define IFPR_IN6(x) (&((struct sockaddr_in6 *)((x)->ifpr_prefix))->sin6_addr)
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index d2a457d..7ca172c 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/callout.h>
-#include <sys/random.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@@ -103,12 +102,8 @@ VNET_DEFINE(int, nd6_maxnudhint) = 0; /* max # of subsequent upper
* layer hints */
static VNET_DEFINE(int, nd6_maxqueuelen) = 1; /* max pkts cached in unresolved
* ND entries */
-
-static VNET_DEFINE(int, nd6_on_link) = 1; /* Send unsolicited ND's on link up */
-
#define V_nd6_maxndopt VNET(nd6_maxndopt)
#define V_nd6_maxqueuelen VNET(nd6_maxqueuelen)
-#define V_nd6_on_link VNET(nd6_on_link)
#ifdef ND6_DEBUG
VNET_DEFINE(int, nd6_debug) = 1;
@@ -117,7 +112,6 @@ VNET_DEFINE(int, nd6_debug) = 0;
#endif
static eventhandler_tag lle_event_eh;
-static eventhandler_tag ifnet_link_event_eh;
/* for debugging? */
#if 0
@@ -202,14 +196,6 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
type == RTM_ADD ? RTF_UP: 0), 0, RT_DEFAULT_FIB);
}
-static void
-nd6_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int linkstate)
-{
-
- if (linkstate == LINK_STATE_UP && V_nd6_on_link)
- nd6_na_output_unsolicited(ifp);
-}
-
void
nd6_init(void)
{
@@ -225,12 +211,9 @@ nd6_init(void)
nd6_slowtimo, curvnet);
nd6_dad_init();
- if (IS_DEFAULT_VNET(curvnet)) {
+ if (IS_DEFAULT_VNET(curvnet))
lle_event_eh = EVENTHANDLER_REGISTER(lle_event, nd6_lle_event,
NULL, EVENTHANDLER_PRI_ANY);
- ifnet_link_event_eh = EVENTHANDLER_REGISTER(ifnet_link_event,
- nd6_ifnet_link_event, NULL, EVENTHANDLER_PRI_ANY);
- }
}
#ifdef VIMAGE
@@ -240,10 +223,8 @@ nd6_destroy()
callout_drain(&V_nd6_slowtimo_ch);
callout_drain(&V_nd6_timer_ch);
- if (IS_DEFAULT_VNET(curvnet)) {
+ if (IS_DEFAULT_VNET(curvnet))
EVENTHANDLER_DEREGISTER(lle_event, lle_event_eh);
- EVENTHANDLER_DEREGISTER(ifnet_link_event, ifnet_link_event_eh);
- }
}
#endif
@@ -2476,18 +2457,13 @@ static int nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS);
SYSCTL_DECL(_net_inet6_icmp6);
#endif
SYSCTL_NODE(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
- CTLFLAG_RD, nd6_sysctl_drlist, "List default routers");
+ CTLFLAG_RD, nd6_sysctl_drlist, "");
SYSCTL_NODE(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist,
- CTLFLAG_RD, nd6_sysctl_prlist, "List prefixes");
+ CTLFLAG_RD, nd6_sysctl_prlist, "");
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1,
- "Max packets cached in unresolved ND entries");
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, "");
SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24),
- "Interface in seconds between garbage collection passes");
-SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_on_link, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(nd6_on_link), 0,
- "Send unsolicited neighbor discovery on interface link up events");
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), "");
static int
nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index 710a1ad..8a0a56e 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -398,10 +398,6 @@ void nd6_init(void);
#ifdef VIMAGE
void nd6_destroy(void);
#endif
-void nd6_na_output_unsolicited(struct ifnet *);
-void nd6_na_output_unsolicited_addr(struct ifnet *, const struct in6_addr *,
- u_long);
-int nd6_na_unsolicited_addr_delay(struct ifaddr *);
struct nd_ifinfo *nd6_ifattach(struct ifnet *);
void nd6_ifdetach(struct nd_ifinfo *);
int nd6_is_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 07ad0cc..bf43fb6 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -124,16 +124,20 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
struct in6_addr saddr6 = ip6->ip6_src;
struct in6_addr daddr6 = ip6->ip6_dst;
struct in6_addr taddr6;
+ struct in6_addr myaddr6;
char *lladdr = NULL;
struct ifaddr *ifa = NULL;
- u_long flags;
int lladdrlen = 0;
- int proxy = 0;
+ int anycast = 0, proxy = 0, tentative = 0;
int tlladdr;
+ int rflag;
union nd_opts ndopts;
struct sockaddr_dl proxydl;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
+ if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
+ rflag = 0;
#ifndef PULLDOWN_TEST
IP6_EXTHDR_CHECK(m, off, icmp6len,);
nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
@@ -225,7 +229,10 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
* In implementation, we add target link-layer address by default.
* We do not add one in MUST NOT cases.
*/
- tlladdr = !IN6_IS_ADDR_MULTICAST(&daddr6);
+ if (!IN6_IS_ADDR_MULTICAST(&daddr6))
+ tlladdr = 0;
+ else
+ tlladdr = 1;
/*
* Target address (taddr6) must be either:
@@ -282,6 +289,9 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
*/
goto freeit;
}
+ myaddr6 = *IFA_IN6(ifa);
+ anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST;
+ tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE;
if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED)
goto freeit;
@@ -293,7 +303,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
goto bad;
}
- if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &saddr6)) {
+ if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
nd6log((LOG_INFO, "nd6_ns_input: duplicate IP6 address %s\n",
ip6_sprintf(ip6bufs, &saddr6)));
goto freeit;
@@ -311,7 +321,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
*
* The processing is defined in RFC 2462.
*/
- if (IFA_IN6_FLAGS(ifa) & IN6_IFF_TENTATIVE) {
+ if (tentative) {
/*
* If source address is unspecified address, it is for
* duplicate address detection.
@@ -325,10 +335,6 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
goto freeit;
}
- flags = IFA_ND6_NA_BASE_FLAGS(ifp, ifa);
- if (proxy || !tlladdr)
- flags &= ~ND_NA_FLAG_OVERRIDE;
-
/*
* If the source address is unspecified address, entries must not
* be created or updated.
@@ -343,16 +349,20 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
in6_all = in6addr_linklocal_allnodes;
if (in6_setscope(&in6_all, ifp, NULL) != 0)
goto bad;
- nd6_na_output_fib(ifp, &in6_all, &taddr6, flags, tlladdr,
- proxy ? (struct sockaddr *)&proxydl : NULL, M_GETFIB(m));
+ nd6_na_output_fib(ifp, &in6_all, &taddr6,
+ ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
+ rflag, tlladdr, proxy ? (struct sockaddr *)&proxydl : NULL,
+ M_GETFIB(m));
goto freeit;
}
nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen,
ND_NEIGHBOR_SOLICIT, 0);
- nd6_na_output_fib(ifp, &saddr6, &taddr6, flags | ND_NA_FLAG_SOLICITED,
- tlladdr, proxy ? (struct sockaddr *)&proxydl : NULL, M_GETFIB(m));
+ nd6_na_output_fib(ifp, &saddr6, &taddr6,
+ ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
+ rflag | ND_NA_FLAG_SOLICITED, tlladdr,
+ proxy ? (struct sockaddr *)&proxydl : NULL, M_GETFIB(m));
freeit:
if (ifa != NULL)
ifa_free(ifa);
@@ -1587,111 +1597,3 @@ nd6_dad_na_input(struct ifaddr *ifa)
nd6_dad_rele(dp);
}
}
-
-/*
- * Send unsolicited neighbor advertisements for all interface addresses to
- * notify other nodes of changes.
- *
- * This is a noop if the interface isn't up.
- */
-void __noinline
-nd6_na_output_unsolicited(struct ifnet *ifp)
-{
- int i, cnt, entries;
- struct ifaddr *ifa;
- struct ann {
- struct in6_addr addr;
- u_long flags;
- int delay;
- } *ann1, *head;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
-
- entries = 8;
- cnt = 0;
- head = malloc(sizeof(struct ann) * entries, M_TEMP, M_WAITOK);
-
- /* Take a copy then process to avoid locking issues. */
- IF_ADDR_RLOCK(ifp);
- TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (ifa->ifa_addr->sa_family != AF_INET6 ||
- IFA_ND6_NA_UNSOLICITED_SKIP(ifa))
- continue;
-
- if (cnt == entries) {
- ann1 = (struct ann*)realloc(head, sizeof(struct ann) *
- (entries + 8), M_TEMP, M_NOWAIT);
- if (ann1 == NULL) {
- log(LOG_INFO, "nd6_announce: realloc to %d "
- "entries failed\n", entries + 8);
- /* Process what we have. */
- break;
- }
- entries += 8;
- head = ann1;
- }
-
- ann1 = head + cnt;
- bcopy(IFA_IN6(ifa), &ann1->addr, sizeof(ann1->addr));
- ann1->flags = IFA_ND6_NA_BASE_FLAGS(ifp, ifa);
- ann1->delay = nd6_na_unsolicited_addr_delay(ifa);
- cnt++;
- }
- IF_ADDR_RUNLOCK(ifp);
-
- for (i = 0; i < cnt;) {
- ann1 = head + i;
- nd6_na_output_unsolicited_addr(ifp, &ann1->addr, ann1->flags);
- i++;
- if (i == cnt)
- break;
- /* XXX DELAY needs to be done in taskqueue to avoid stalling. */
- //DELAY(ann1->delay);
- }
- free(head, M_TEMP);
-}
-
-/*
- * Return the delay required for announcements of the address as per RFC 4861.
- */
-int
-nd6_na_unsolicited_addr_delay(struct ifaddr *ifa)
-{
-
- if (IFA_IN6_FLAGS(ifa) & IN6_IFF_ANYCAST) {
- /*
- * Random value between 0 and MAX_ANYCAST_DELAY_TIME
- * as per section 7.2.7.
- */
- return (random() % IN6_MAX_ANYCAST_DELAY_TIME_MS);
- }
-
- /* Small delay as per section 7.2.6. */
- return (IN6_BROADCAST_DELAY_TIME_MS);
-}
-
-/*
- * Send an unsolicited neighbor advertisement for an address to notify other
- * nodes of changes.
- */
-void __noinline
-nd6_na_output_unsolicited_addr(struct ifnet *ifp, const struct in6_addr *addr,
- u_long flags)
-{
- int error;
- struct in6_addr mcast;
-
- mcast = in6addr_linklocal_allnodes;
- if ((error = in6_setscope(&mcast, ifp, NULL)) != 0) {
- /*
- * This shouldn't by possible as the only error is for loopback
- * address which we're not using.
- */
- log(LOG_INFO, "in6_setscope: on mcast failed: %d\n", error);
- return;
- }
- nd6_na_output(ifp, &mcast, addr, flags, 1, NULL);
-}
-
-
OpenPOWER on IntegriCloud