summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/icmp6.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r--sys/netinet6/icmp6.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 866fee1..1c8a132 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -147,8 +147,6 @@ icmp6_init(void)
INIT_VNET_INET6(curvnet);
V_icmp6errpps_count = 0;
-
- mld6_init();
}
static void
@@ -429,6 +427,23 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
}
/*
+ * Check multicast group membership.
+ * Note: SSM filters are not applied for ICMPv6 traffic.
+ */
+ if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
+ struct ifnet *ifp;
+ struct in6_multi *inm;
+
+ ifp = m->m_pkthdr.rcvif;
+ inm = in6m_lookup(ifp, &ip6->ip6_dst);
+ if (inm == NULL) {
+ IP6STAT_INC(ip6s_notmember);
+ in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
+ goto freeit;
+ }
+ }
+
+ /*
* calculate the checksum
*/
#ifndef PULLDOWN_TEST
@@ -615,34 +630,20 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
case MLD_LISTENER_QUERY:
case MLD_LISTENER_REPORT:
- if (icmp6len < sizeof(struct mld_hdr))
- goto badlen;
- if (icmp6->icmp6_type == MLD_LISTENER_QUERY) /* XXX: ugly... */
- icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldquery);
- else
- icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mldreport);
- if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
- /* give up local */
- mld6_input(m, off);
- m = NULL;
+ case MLD_LISTENER_DONE:
+ case MLDV2_LISTENER_REPORT:
+ /*
+ * Drop MLD traffic which is not link-local.
+ * XXX Should we also sanity check that these messages
+ * were directed to a link-local multicast prefix?
+ */
+ if (ip6->ip6_hlim != 1)
goto freeit;
- }
- mld6_input(n, off);
+ if (mld_input(m, off, icmp6len) != 0)
+ return (IPPROTO_DONE);
/* m stays. */
break;
- case MLD_LISTENER_DONE:
- icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mlddone);
- if (icmp6len < sizeof(struct mld_hdr)) /* necessary? */
- goto badlen;
- break; /* nothing to be done in kernel */
-
- case MLD_MTRACE_RESP:
- case MLD_MTRACE:
- /* XXX: these two are experimental. not officially defined. */
- /* XXX: per-interface statistics? */
- break; /* just pass it to applications */
-
case ICMP6_WRUREQUEST: /* ICMP6_FQDN_QUERY */
{
enum { WRU, FQDN } mode;
@@ -2050,7 +2051,7 @@ icmp6_rip6_input(struct mbuf **mp, int off)
INP_RUNLOCK(last);
} else {
m_freem(m);
- V_ip6stat.ip6s_delivered--;
+ IP6STAT_DEC(ip6s_delivered);
}
return IPPROTO_DONE;
}
@@ -2222,7 +2223,14 @@ void
icmp6_fasttimo(void)
{
- return;
+ mld_fasttimo();
+}
+
+void
+icmp6_slowtimo(void)
+{
+
+ mld_slowtimo();
}
static const char *
OpenPOWER on IntegriCloud