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/netinet/ip_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.355 retrieving revision 1.355.2.9 diff -u -p -r1.355 -r1.355.2.9 --- src/sys/netinet/ip_input.c 2017/06/01 02:45:14 1.355 +++ src/sys/netinet/ip_input.c 2021/03/07 19:13:24 1.355.2.9 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.355 2017/06/01 02:45:14 chs Exp $ */ +/* $NetBSD: ip_input.c,v 1.355.2.9 2021/03/07 19:13:24 martin Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.355 2017/06/01 02:45:14 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.355.2.9 2021/03/07 19:13:24 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -162,10 +162,10 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v #define IPSENDREDIRECTS 1 #endif #ifndef IPFORWSRCRT -#define IPFORWSRCRT 1 /* forward source-routed packets */ +#define IPFORWSRCRT 0 /* forward source-routed packets */ #endif #ifndef IPALLOWSRCRT -#define IPALLOWSRCRT 1 /* allow source-routed packets */ +#define IPALLOWSRCRT 0 /* allow source-routed packets */ #endif #ifndef IPMTUDISC #define IPMTUDISC 1 @@ -202,7 +202,7 @@ int ip_mtudisc_timeout = IPMTUDISCTIMEOU int ipprintfs = 0; #endif -int ip_do_randomid = 0; +int ip_do_randomid = 1; /* * XXX - Setting ip_checkinterface mostly implements the receive side of @@ -342,7 +342,7 @@ ip_init(void) #endif /* MBUFTRACE */ ipstat_percpu = percpu_alloc(sizeof(uint64_t) * IP_NSTATS); - ipforward_rt_percpu = percpu_alloc(sizeof(struct route)); + ipforward_rt_percpu = rtcache_percpu_alloc(); ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); } @@ -377,11 +377,14 @@ ip_match_our_address(struct ifnet *ifp, continue; if (checkif && ia->ia_ifp != ifp) continue; - if ((ia->ia_ifp->if_flags & IFF_UP) != 0 && - (ia->ia4_flags & IN_IFF_DETACHED) == 0) - break; - else + if ((ia->ia_ifp->if_flags & IFF_UP) == 0) { (*downmatch)++; + continue; + } + if (ia->ia4_flags & IN_IFF_DETACHED && + (ifp->if_flags & IFF_LOOPBACK) == 0) + continue; + break; } } @@ -398,7 +401,10 @@ ip_match_our_address_broadcast(struct if if (ifa->ifa_addr->sa_family != AF_INET) continue; ia = ifatoia(ifa); - if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) + if (ia->ia4_flags & IN_IFF_NOTREADY) + continue; + if (ia->ia4_flags & IN_IFF_DETACHED && + (ifp->if_flags & IFF_LOOPBACK) == 0) continue; if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) || in_hosteq(ip->ip_dst, ia->ia_netbroadcast) || @@ -432,15 +438,11 @@ ipintr(void *arg __unused) KASSERT(cpu_softintr_p()); -#ifndef NET_MPSAFE - mutex_enter(softnet_lock); -#endif + SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE(); while ((m = pktq_dequeue(ip_pktq)) != NULL) { ip_input(m); } -#ifndef NET_MPSAFE - mutex_exit(softnet_lock); -#endif + SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); } /* @@ -618,8 +620,25 @@ ip_input(struct mbuf *m) m = NULL; goto out; } + if (__predict_false(m->m_len < sizeof (struct ip))) { + if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { + IP_STATINC(IP_STAT_TOOSMALL); + goto out; + } + } ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; + if (hlen < sizeof(struct ip)) { /* minimum header length */ + IP_STATINC(IP_STAT_BADHLEN); + goto out; + } + if (hlen > m->m_len) { + if ((m = m_pullup(m, hlen)) == NULL) { + IP_STATINC(IP_STAT_BADHLEN); + goto out; + } + ip = mtod(m, struct ip *); + } /* * XXX The setting of "srcrt" here is to prevent ip_forward() @@ -758,15 +777,12 @@ ip_input(struct mbuf *m) return; } #ifdef IPSEC - /* Perform IPsec, if any. */ + /* Check the security policy (SP) for the packet */ if (ipsec_used) { - SOFTNET_LOCK(); if (ipsec4_input(m, IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)) != 0) { - SOFTNET_UNLOCK(); goto out; } - SOFTNET_UNLOCK(); } #endif ip_forward(m, srcrt, ifp); @@ -809,12 +825,9 @@ ours: */ if (ipsec_used && (inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0) { - SOFTNET_LOCK(); if (ipsec4_input(m, 0) != 0) { - SOFTNET_UNLOCK(); goto out; } - SOFTNET_UNLOCK(); } #endif @@ -838,9 +851,7 @@ ours: const int off = hlen, nh = ip->ip_p; - SOFTNET_LOCK(); (*inetsw[ip_protox[nh]].pr_input)(m, off, nh); - SOFTNET_UNLOCK(); return; out: @@ -856,17 +867,11 @@ void ip_slowtimo(void) { -#ifndef NET_MPSAFE - mutex_enter(softnet_lock); - KERNEL_LOCK(1, NULL); -#endif + SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE(); ip_reass_slowtimo(); -#ifndef NET_MPSAFE - KERNEL_UNLOCK_ONE(NULL); - mutex_exit(softnet_lock); -#endif + SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); } /* @@ -1200,16 +1205,16 @@ ip_rtaddr(struct in_addr dst, struct psr sockaddr_in_init(&u.dst4, &dst, 0); - ro = percpu_getref(ipforward_rt_percpu); + ro = rtcache_percpu_getref(ipforward_rt_percpu); rt = rtcache_lookup(ro, &u.dst); if (rt == NULL) { - percpu_putref(ipforward_rt_percpu); + rtcache_percpu_putref(ipforward_rt_percpu); return NULL; } ia4_acquire(ifatoia(rt->rt_ifa), psref); rtcache_unref(rt, ro); - percpu_putref(ipforward_rt_percpu); + rtcache_percpu_putref(ipforward_rt_percpu); return ifatoia(rt->rt_ifa); } @@ -1385,10 +1390,10 @@ ip_forward(struct mbuf *m, int srcrt, st sockaddr_in_init(&u.dst4, &ip->ip_dst, 0); - ro = percpu_getref(ipforward_rt_percpu); + ro = rtcache_percpu_getref(ipforward_rt_percpu); rt = rtcache_lookup(ro, &u.dst); if (rt == NULL) { - percpu_putref(ipforward_rt_percpu); + rtcache_percpu_putref(ipforward_rt_percpu); icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0); return; } @@ -1460,13 +1465,13 @@ ip_forward(struct mbuf *m, int srcrt, st m_freem(mcopy); } - percpu_putref(ipforward_rt_percpu); + rtcache_percpu_putref(ipforward_rt_percpu); return; redirect: error: if (mcopy == NULL) { - percpu_putref(ipforward_rt_percpu); + rtcache_percpu_putref(ipforward_rt_percpu); return; } @@ -1509,11 +1514,11 @@ error: */ if (mcopy) m_freem(mcopy); - percpu_putref(ipforward_rt_percpu); + rtcache_percpu_putref(ipforward_rt_percpu); return; } icmp_error(mcopy, type, code, dest, destmtu); - percpu_putref(ipforward_rt_percpu); + rtcache_percpu_putref(ipforward_rt_percpu); } void @@ -1558,15 +1563,6 @@ ip_savecontrol(struct inpcb *inp, struct } if (inpflags & INP_RECVPKTINFO) { struct in_pktinfo ipi; - ipi.ipi_addr = ip->ip_src; - ipi.ipi_ifindex = ifp->if_index; - *mp = sbcreatecontrol((void *) &ipi, - sizeof(ipi), IP_RECVPKTINFO, IPPROTO_IP); - if (*mp) - mp = &(*mp)->m_next; - } - if (inpflags & INP_PKTINFO) { - struct in_pktinfo ipi; ipi.ipi_addr = ip->ip_dst; ipi.ipi_ifindex = ifp->if_index; *mp = sbcreatecontrol((void *) &ipi,