summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/nd6.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/nd6.c')
-rw-r--r--sys/netinet6/nd6.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index a79922b..d0bcc9d 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -38,6 +38,7 @@ __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>
@@ -102,8 +103,12 @@ 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;
@@ -112,6 +117,7 @@ VNET_DEFINE(int, nd6_debug) = 0;
#endif
static eventhandler_tag lle_event_eh;
+static eventhandler_tag ifnet_link_event_eh;
/* for debugging? */
#if 0
@@ -196,6 +202,13 @@ 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)
{
@@ -211,9 +224,12 @@ 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
@@ -223,8 +239,10 @@ 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
@@ -285,6 +303,8 @@ nd6_ifdetach(struct nd_ifinfo *nd)
void
nd6_setmtu(struct ifnet *ifp)
{
+ if (ifp->if_afdata[AF_INET6] == NULL)
+ return;
nd6_setmtu0(ifp, ND_IFINFO(ifp));
}
@@ -2455,13 +2475,18 @@ 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, "");
+ CTLFLAG_RD, nd6_sysctl_drlist, "List default routers");
SYSCTL_NODE(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist,
- CTLFLAG_RD, nd6_sysctl_prlist, "");
+ CTLFLAG_RD, nd6_sysctl_prlist, "List prefixes");
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, "");
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1,
+ "Max packets cached in unresolved ND entries");
SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), "");
+ 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");
static int
nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
OpenPOWER on IntegriCloud