Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet6/ip6_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet6/ip6_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.193.2.6 retrieving revision 1.218 diff -u -p -r1.193.2.6 -r1.218 --- src/sys/netinet6/ip6_input.c 2018/11/26 01:52:51 1.193.2.6 +++ src/sys/netinet6/ip6_input.c 2020/07/27 14:06:58 1.218 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_input.c,v 1.193.2.6 2018/11/26 01:52:51 pgoyette Exp $ */ +/* $NetBSD: ip6_input.c,v 1.218 2020/07/27 14:06:58 roy Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.193.2.6 2018/11/26 01:52:51 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.218 2020/07/27 14:06:58 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_gateway.h" @@ -134,11 +134,15 @@ percpu_t *ip6stat_percpu; percpu_t *ip6_forward_rt_percpu __cacheline_aligned; -static void ip6_init2(void); static void ip6intr(void *); +static void ip6_input(struct mbuf *, struct ifnet *); static bool ip6_badaddr(struct ip6_hdr *); static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *); +static struct m_tag *ip6_addaux(struct mbuf *); +static struct m_tag *ip6_findaux(struct mbuf *); +static void ip6_delaux(struct mbuf *); + static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *, u_int32_t *); static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); @@ -152,6 +156,20 @@ static void sysctl_net_inet6_ip6_setup(s #define SOFTNET_UNLOCK() KASSERT(mutex_owned(softnet_lock)) #endif +/* Ensure that non packed structures are the desired size. */ +__CTASSERT(sizeof(struct ip6_hdr) == 40); +__CTASSERT(sizeof(struct ip6_ext) == 2); +__CTASSERT(sizeof(struct ip6_hbh) == 2); +__CTASSERT(sizeof(struct ip6_dest) == 2); +__CTASSERT(sizeof(struct ip6_opt) == 2); +__CTASSERT(sizeof(struct ip6_opt_jumbo) == 6); +__CTASSERT(sizeof(struct ip6_opt_nsap) == 4); +__CTASSERT(sizeof(struct ip6_opt_tunnel) == 3); +__CTASSERT(sizeof(struct ip6_opt_router) == 4); +__CTASSERT(sizeof(struct ip6_rthdr) == 4); +__CTASSERT(sizeof(struct ip6_rthdr0) == 8); +__CTASSERT(sizeof(struct ip6_frag) == 8); + /* * IP6 initialization: fill in IP6 protocol switch table. * All protocols not implemented in kernel go to raw IP6 protocol handler. @@ -183,9 +201,7 @@ ip6_init(void) addrsel_policy_init(); nd6_init(); frag6_init(); - ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR; - ip6_init2(); #ifdef GATEWAY ip6flow_init(ip6_hashsize); #endif @@ -194,19 +210,7 @@ ip6_init(void) KASSERT(inet6_pfil_hook != NULL); ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS); - ip6_forward_rt_percpu = percpu_alloc(sizeof(struct route)); -} - -static void -ip6_init2(void) -{ - - /* timer for regeneration of temporary addresses randomize ID */ - callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE); - callout_reset(&in6_tmpaddrtimer_ch, - (ip6_temp_preferred_lifetime - ip6_desync_factor - - ip6_temp_regen_advance) * hz, - in6_tmpaddrtimer, NULL); + ip6_forward_rt_percpu = rtcache_percpu_alloc(); } /* @@ -240,7 +244,7 @@ ip6intr(void *arg __unused) SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); } -void +static void ip6_input(struct mbuf *m, struct ifnet *rcvif) { struct ip6_hdr *ip6; @@ -342,19 +346,27 @@ ip6_input(struct mbuf *m, struct ifnet * * IPsec (encapsulated, tunnel mode). */ #if defined(IPSEC) - if (!ipsec_used || !ipsec_indone(m)) + if (!ipsec_used || !ipsec_skip_pfil(m)) #else if (1) #endif { struct in6_addr odst; + int error; odst = ip6->ip6_dst; - if (pfil_run_hooks(inet6_pfil_hook, &m, rcvif, PFIL_IN) != 0) - return; - if (m == NULL) + error = pfil_run_hooks(inet6_pfil_hook, &m, rcvif, PFIL_IN); + if (error != 0 || m == NULL) { + IP6_STATINC(IP6_STAT_PFILDROP_IN); return; - KASSERT(m->m_len >= sizeof(struct ip6_hdr)); + } + if (m->m_len < sizeof(struct ip6_hdr)) { + if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { + IP6_STATINC(IP6_STAT_TOOSMALL); + in6_ifstat_inc(rcvif, ifs6_in_hdrerr); + return; + } + } ip6 = mtod(m, struct ip6_hdr *); srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); } @@ -397,7 +409,7 @@ ip6_input(struct mbuf *m, struct ifnet * goto bad; } - ro = percpu_getref(ip6_forward_rt_percpu); + ro = rtcache_percpu_getref(ip6_forward_rt_percpu); /* * Multicast check @@ -558,7 +570,7 @@ hbhcheck: /* m already freed */ in6_ifstat_inc(rcvif, ifs6_in_discard); rtcache_unref(rt, ro); - percpu_putref(ip6_forward_rt_percpu); + rtcache_percpu_putref(ip6_forward_rt_percpu); return; } @@ -583,7 +595,7 @@ hbhcheck: ICMP6_PARAMPROB_HEADER, (char *)&ip6->ip6_plen - (char *)ip6); rtcache_unref(rt, ro); - percpu_putref(ip6_forward_rt_percpu); + rtcache_percpu_putref(ip6_forward_rt_percpu); return; } IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), @@ -591,7 +603,7 @@ hbhcheck: if (hbh == NULL) { IP6_STATINC(IP6_STAT_TOOSHORT); rtcache_unref(rt, ro); - percpu_putref(ip6_forward_rt_percpu); + rtcache_percpu_putref(ip6_forward_rt_percpu); return; } KASSERT(IP6_HDR_ALIGNED_P(hbh)); @@ -645,7 +657,7 @@ hbhcheck: if (error != 0) { rtcache_unref(rt, ro); - percpu_putref(ip6_forward_rt_percpu); + rtcache_percpu_putref(ip6_forward_rt_percpu); IP6_STATINC(IP6_STAT_CANTFORWARD); goto bad; } @@ -654,7 +666,7 @@ hbhcheck: goto bad_unref; } else if (!ours) { rtcache_unref(rt, ro); - percpu_putref(ip6_forward_rt_percpu); + rtcache_percpu_putref(ip6_forward_rt_percpu); ip6_forward(m, srcrt); return; } @@ -695,7 +707,7 @@ hbhcheck: rtcache_unref(rt, ro); rt = NULL; } - percpu_putref(ip6_forward_rt_percpu); + rtcache_percpu_putref(ip6_forward_rt_percpu); rh_present = 0; frg_present = 0; @@ -739,7 +751,7 @@ hbhcheck: * header. Note that we do not visit this with * protocols with pcb layer code - like udp/tcp/raw ip. */ - if ((inet6sw[ip_protox[nxt]].pr_flags + if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0) { int error; @@ -756,7 +768,7 @@ hbhcheck: bad_unref: rtcache_unref(rt, ro); - percpu_putref(ip6_forward_rt_percpu); + rtcache_percpu_putref(ip6_forward_rt_percpu); bad: m_freem(m); return; @@ -1061,6 +1073,8 @@ ip6_savecontrol(struct in6pcb *in6p, str #define IS2292(x, y) (y) #endif + KASSERT(m->m_flags & M_PKTHDR); + if (SOOPT_TIMESTAMP(so->so_options)) mp = sbsavetimestamp(so->so_options, mp); @@ -1302,12 +1316,18 @@ ip6_pullexthdr(struct mbuf *m, size_t of size_t elen; struct mbuf *n; + if (off + sizeof(ip6e) > m->m_pkthdr.len) + return NULL; + m_copydata(m, off, sizeof(ip6e), (void *)&ip6e); if (nxt == IPPROTO_AH) elen = (ip6e.ip6e_len + 2) << 2; else elen = (ip6e.ip6e_len + 1) << 3; + if (off + elen > m->m_pkthdr.len) + return NULL; + MGET(n, M_DONTWAIT, MT_DATA); if (n && elen >= MLEN) { MCLGET(n, M_DONTWAIT); @@ -1478,7 +1498,7 @@ ip6_lasthdr(struct mbuf *m, int off, int } } -struct m_tag * +static struct m_tag * ip6_addaux(struct mbuf *m) { struct m_tag *mtag; @@ -1495,7 +1515,7 @@ ip6_addaux(struct mbuf *m) return mtag; } -struct m_tag * +static struct m_tag * ip6_findaux(struct mbuf *m) { struct m_tag *mtag; @@ -1504,7 +1524,7 @@ ip6_findaux(struct mbuf *m) return mtag; } -void +static void ip6_delaux(struct mbuf *m) { struct m_tag *mtag; @@ -1584,27 +1604,6 @@ sysctl_net_inet6_ip6_setup(struct sysctl IPV6CTL_MAXFRAGPACKETS, CTL_EOL); sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "accept_rtadv", - SYSCTL_DESCR("Accept router advertisements"), - NULL, 0, &ip6_accept_rtadv, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - IPV6CTL_ACCEPT_RTADV, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "rtadv_maxroutes", - SYSCTL_DESCR("Maximum number of routes accepted via router advertisements"), - NULL, 0, &ip6_rtadv_maxroutes, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - IPV6CTL_RTADV_MAXROUTES, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT, - CTLTYPE_INT, "rtadv_numroutes", - SYSCTL_DESCR("Current number of routes accepted via router advertisements"), - NULL, 0, &nd6_numroutes, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - IPV6CTL_RTADV_NUMROUTES, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "keepfaith", SYSCTL_DESCR("Activate faith interface"), NULL, 0, &ip6_keepfaith, 0, @@ -1663,12 +1662,6 @@ sysctl_net_inet6_ip6_setup(struct sysctl CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_USE_DEPRECATED, CTL_EOL); sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "rr_prune", NULL, - NULL, 0, &ip6_rr_prune, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - IPV6CTL_RR_PRUNE, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT #ifndef INET6_BINDV6ONLY |CTLFLAG_READWRITE, @@ -1730,13 +1723,6 @@ sysctl_net_inet6_ip6_setup(struct sysctl IPV6CTL_ADDRCTLPOLICY, CTL_EOL); sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "use_tempaddr", - SYSCTL_DESCR("Use temporary address"), - NULL, 0, &ip6_use_tempaddr, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "prefer_tempaddr", SYSCTL_DESCR("Prefer temporary address as source " "address"), @@ -1745,20 +1731,6 @@ sysctl_net_inet6_ip6_setup(struct sysctl CTL_CREATE, CTL_EOL); sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "temppltime", - SYSCTL_DESCR("preferred lifetime of a temporary address"), - NULL, 0, &ip6_temp_preferred_lifetime, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "tempvltime", - SYSCTL_DESCR("valid lifetime of a temporary address"), - NULL, 0, &ip6_temp_valid_lifetime, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "maxfrags", SYSCTL_DESCR("Maximum fragments in reassembly queue"), NULL, 0, &ip6_maxfrags, 0, @@ -1821,22 +1793,6 @@ sysctl_net_inet6_ip6_setup(struct sysctl CTL_CREATE, CTL_EOL); sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "maxifprefixes", - SYSCTL_DESCR("Maximum number of prefixes created by" - " route advertisement per interface"), - NULL, 1, &ip6_maxifprefixes, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "maxifdefrouters", - SYSCTL_DESCR("Maximum number of default routers created" - " by route advertisement per interface"), - NULL, 1, &ip6_maxifdefrouters, 0, - CTL_NET, PF_INET6, IPPROTO_IPV6, - CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "maxdynroutes", SYSCTL_DESCR("Maximum number of routes created via" " redirect"),