Follow the RFC6980 and silently ignore following IPv6 NDP messages

that had the IPv6 fragmentation header:
 o  Neighbor Solicitation
 o  Neighbor Advertisement
 o  Router Solicitation
 o  Router Advertisement
 o  Redirect

Introduce M_FRAGMENTED mbuf flag, and set it after IPv6 fragment reassembly
is completed. Then check the presence of this flag in correspondig ND6
handling routines.

PR:		224247
MFC after:	2 weeks
This commit is contained in:
Andrey V. Elsukov 2017-12-15 12:37:32 +00:00
parent 502742f35a
commit a406128960
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326876
5 changed files with 23 additions and 0 deletions

View File

@ -227,6 +227,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
*offp = offset;
m->m_flags |= M_FRAGMENTED;
return (ip6f->ip6f_nxt);
}
@ -827,5 +828,6 @@ ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
m_cat(m, t);
}
m->m_flags |= M_FRAGMENTED;
return (0);
}

View File

@ -2252,6 +2252,10 @@ icmp6_redirect_input(struct mbuf *m, int off)
if (!V_icmp6_rediraccept)
goto freeit;
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
#ifndef PULLDOWN_TEST
IP6_EXTHDR_CHECK(m, off, icmp6len,);
nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);

View File

@ -658,6 +658,7 @@ struct ip6_mtuinfo {
#define M_LOOP M_PROTO6
#define M_AUTHIPDGM M_PROTO7
#define M_RTALERT_MLD M_PROTO8
#define M_FRAGMENTED M_PROTO9 /* contained fragment header */
#ifdef _KERNEL
struct cmsghdr;

View File

@ -137,6 +137,10 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
struct sockaddr_dl proxydl;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
rflag = 0;
@ -631,6 +635,10 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
int lladdr_off;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",

View File

@ -139,6 +139,10 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
if (!V_ip6_forwarding || ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV)
goto freeit;
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
/* Sanity checks */
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
@ -229,6 +233,10 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV))
goto freeit;
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",