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.292 retrieving revision 1.305 diff -u -p -r1.292 -r1.305 --- src/sys/netinet/ip_input.c 2010/12/11 22:37:46 1.292 +++ src/sys/netinet/ip_input.c 2013/06/08 13:50:22 1.305 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.292 2010/12/11 22:37:46 matt Exp $ */ +/* $NetBSD: ip_input.c,v 1.305 2013/06/08 13:50:22 rmind Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.292 2010/12/11 22:37:46 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.305 2013/06/08 13:50:22 rmind Exp $"); #include "opt_inet.h" #include "opt_compat_netbsd.h" @@ -139,16 +139,11 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v #ifdef MROUTING #include #endif +#include #ifdef IPSEC -#include -#include -#include -#endif -#ifdef FAST_IPSEC #include -#include -#endif /* FAST_IPSEC*/ +#endif #ifndef IPFORWARDING #ifdef GATEWAY @@ -221,7 +216,6 @@ int ip_checkinterface = 0; struct rttimer_queue *ip_mtudisc_timeout_q = NULL; -int ipqmaxlen = IFQ_MAXLEN; u_long in_ifaddrhash; /* size of hash table - 1 */ int in_ifaddrentries; /* total number of addrs */ struct in_ifaddrhead in_ifaddrhead; @@ -279,6 +273,8 @@ static struct ip_srcrt { struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)]; } ip_srcrt; +static int ip_drainwanted; + static void save_rte(u_char *, struct in_addr); #ifdef MBUFTRACE @@ -319,7 +315,7 @@ ip_init(void) ip_ids = ip_id_init(); ip_id = time_second & 0xfffff; - ipintrq.ifq_maxlen = ipqmaxlen; + ipintrq.ifq_maxlen = IFQ_MAXLEN; TAILQ_INIT(&in_ifaddrhead); in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true, @@ -366,7 +362,6 @@ ipintr(void) struct ifqueue lcl_intrq; memset(&lcl_intrq, 0, sizeof(lcl_intrq)); - ipintrq.ifq_maxlen = ipqmaxlen; mutex_enter(softnet_lock); KERNEL_LOCK(1, NULL); @@ -390,9 +385,7 @@ ipintr(void) IF_DEQUEUE(&lcl_intrq, m); if (m == NULL) break; - KERNEL_UNLOCK_ONE(NULL); ip_input(m); - KERNEL_LOCK(1, NULL); } mutex_exit(softnet_lock); } @@ -411,12 +404,6 @@ ip_input(struct mbuf *m) int downmatch; int checkif; int srcrt = 0; -#ifdef FAST_IPSEC - struct m_tag *mtag; - struct tdb_ident *tdbi; - struct secpolicy *sp; - int error, s; -#endif /* FAST_IPSEC */ MCLAIM(m, &ip_rx_mowner); KASSERT((m->m_flags & M_PKTHDR) != 0); @@ -458,7 +445,7 @@ ip_input(struct mbuf *m) goto bad; } if (hlen > m->m_len) { - if ((m = m_pullup(m, hlen)) == 0) { + if ((m = m_pullup(m, hlen)) == NULL) { IP_STATINC(IP_STAT_BADHLEN); return; } @@ -538,16 +525,11 @@ ip_input(struct mbuf *m) m_adj(m, len - m->m_pkthdr.len); } -#if defined(IPSEC) - /* ipflow (IP fast forwarding) is not compatible with IPsec. */ - m->m_flags &= ~M_CANFASTFWD; -#else /* * Assume that we can create a fast-forward IP flow entry * based on this packet. */ m->m_flags |= M_CANFASTFWD; -#endif #ifdef PFIL_HOOKS /* @@ -561,9 +543,7 @@ ip_input(struct mbuf *m) * let ipfilter look at packet on the wire, * not the decapsulated packet. */ -#ifdef IPSEC - if (!ipsec_getnhist(m)) -#elif defined(FAST_IPSEC) +#if defined(IPSEC) if (!ipsec_indone(m)) #else if (1) @@ -746,60 +726,12 @@ ip_input(struct mbuf *m) return; } #ifdef IPSEC - if (ipsec4_in_reject(m, NULL)) { - IPSEC_STATINC(IPSEC_STAT_IN_POLVIO); + /* Perform IPsec, if any. */ + if (ipsec4_input(m, IP_FORWARDING | (ip_directedbcast ? + IP_ALLOWBROADCAST : 0)) != 0) { goto bad; } #endif -#ifdef FAST_IPSEC - mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); - s = splsoftnet(); - if (mtag != NULL) { - tdbi = (struct tdb_ident *)(mtag + 1); - sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND); - } else { - sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, - IP_FORWARDING, &error); - } - if (sp == NULL) { /* NB: can happen if error */ - splx(s); - /*XXX error stat???*/ - DPRINTF(("ip_input: no SP for forwarding\n")); /*XXX*/ - goto bad; - } - - /* - * Check security policy against packet attributes. - */ - error = ipsec_in_reject(sp, m); - KEY_FREESP(&sp); - splx(s); - if (error) { - IP_STATINC(IP_STAT_CANTFORWARD); - goto bad; - } - - /* - * Peek at the outbound SP for this packet to determine if - * it's a Fast Forward candidate. - */ - mtag = m_tag_find(m, PACKET_TAG_IPSEC_PENDING_TDB, NULL); - if (mtag != NULL) - m->m_flags &= ~M_CANFASTFWD; - else { - s = splsoftnet(); - sp = ipsec4_checkpolicy(m, IPSEC_DIR_OUTBOUND, - (IP_FORWARDING | - (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), - &error, NULL); - if (sp != NULL) { - m->m_flags &= ~M_CANFASTFWD; - KEY_FREESP(&sp); - } - splx(s); - } -#endif /* FAST_IPSEC */ - ip_forward(m, srcrt); } return; @@ -828,56 +760,18 @@ ours: hlen = ip->ip_hl << 2; } -#if defined(IPSEC) - /* - * enforce IPsec policy checking if we are seeing last header. - * note that we do not visit this with protocols with pcb layer - * code - like udp/tcp/raw ip. - */ - if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0 && - ipsec4_in_reject(m, NULL)) { - IPSEC_STATINC(IPSEC_STAT_IN_POLVIO); - goto bad; - } -#endif -#ifdef FAST_IPSEC +#ifdef IPSEC /* - * enforce IPsec policy checking if we are seeing last header. - * note that we do not visit this with protocols with pcb layer - * code - like udp/tcp/raw ip. + * Enforce IPsec policy checking if we are seeing last header. + * Note that we do not visit this with protocols with PCB layer + * code - like UDP/TCP/raw IP. */ if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0) { - /* - * Check if the packet has already had IPsec processing - * done. If so, then just pass it along. This tag gets - * set during AH, ESP, etc. input handling, before the - * packet is returned to the ip input queue for delivery. - */ - mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); - s = splsoftnet(); - if (mtag != NULL) { - tdbi = (struct tdb_ident *)(mtag + 1); - sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND); - } else { - sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, - IP_FORWARDING, &error); - } - if (sp != NULL) { - /* - * Check security policy against packet attributes. - */ - error = ipsec_in_reject(sp, m); - KEY_FREESP(&sp); - } else { - /* XXX error stat??? */ - error = EINVAL; -DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/ - } - splx(s); - if (error) + if (ipsec4_input(m, 0) != 0) { goto bad; + } } -#endif /* FAST_IPSEC */ +#endif /* * Switch out to protocol's input routine. @@ -1286,6 +1180,21 @@ const int inetctlerrmap[PRC_NCMDS] = { [PRC_PARAMPROB] = ENOPROTOOPT, }; +void +ip_fasttimo(void) +{ + if (ip_drainwanted) { + ip_drain(); + ip_drainwanted = 0; + } +} + +void +ip_drainstub(void) +{ + ip_drainwanted = 1; +} + /* * Forward a packet. If some error occurs return the sender * an icmp packet. Note we can't always generate a meaningful @@ -1392,7 +1301,7 @@ ip_forward(struct mbuf *m, int srcrt) error = ip_output(m, NULL, &ipforward_rt, (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), - (struct ip_moptions *)NULL, (struct socket *)NULL); + NULL, NULL); if (error) IP_STATINC(IP_STAT_CANTFORWARD); @@ -1438,57 +1347,9 @@ ip_forward(struct mbuf *m, int srcrt) if ((rt = rtcache_validate(&ipforward_rt)) != NULL) destmtu = rt->rt_ifp->if_mtu; - -#if defined(IPSEC) || defined(FAST_IPSEC) - { - /* - * If the packet is routed over IPsec tunnel, tell the - * originator the tunnel MTU. - * tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz - * XXX quickhack!!! - */ - - struct secpolicy *sp; - int ipsecerror; - size_t ipsechdr; - struct route *ro; - - sp = ipsec4_getpolicybyaddr(mcopy, - IPSEC_DIR_OUTBOUND, IP_FORWARDING, - &ipsecerror); - - if (sp != NULL) { - /* count IPsec header size */ - ipsechdr = ipsec4_hdrsiz(mcopy, - IPSEC_DIR_OUTBOUND, NULL); - - /* - * find the correct route for outer IPv4 - * header, compute tunnel MTU. - */ - - if (sp->req != NULL - && sp->req->sav != NULL - && sp->req->sav->sah != NULL) { - ro = &sp->req->sav->sah->sa_route; - rt = rtcache_validate(ro); - if (rt && rt->rt_ifp) { - destmtu = - rt->rt_rmx.rmx_mtu ? - rt->rt_rmx.rmx_mtu : - rt->rt_ifp->if_mtu; - destmtu -= ipsechdr; - } - } - -#ifdef IPSEC - key_freesp(sp); -#else - KEY_FREESP(&sp); +#ifdef IPSEC + (void)ipsec4_forward(mcopy, &destmtu); #endif - } - } -#endif /*defined(IPSEC) || defined(FAST_IPSEC)*/ IP_STATINC(IP_STAT_CANTFRAG); break; @@ -1816,7 +1677,7 @@ sysctl_net_inet_ip_setup(struct sysctllo CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "mtudisctimeout", SYSCTL_DESCR("Lifetime of a Path MTU Discovered route"), - sysctl_net_inet_ip_pmtudto, 0, &ip_mtudisc_timeout, 0, + sysctl_net_inet_ip_pmtudto, 0, (void *)&ip_mtudisc_timeout, 0, CTL_NET, PF_INET, IPPROTO_IP, IPCTL_MTUDISCTIMEOUT, CTL_EOL); #ifdef GATEWAY @@ -1907,6 +1768,33 @@ sysctl_net_inet_ip_setup(struct sysctllo sysctl_net_inet_ip_stats, 0, NULL, 0, CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS, CTL_EOL); + + /* anonportalgo RFC6056 subtree */ + const struct sysctlnode *portalgo_node; + sysctl_createv(clog, 0, NULL, &portalgo_node, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "anonportalgo", + SYSCTL_DESCR("Anonymous Port Algorithm Selection (RFC 6056)"), + NULL, 0, NULL, 0, + CTL_NET, PF_INET, IPPROTO_IP, CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, &portalgo_node, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_STRING, "available", + SYSCTL_DESCR("available algorithms"), + sysctl_portalgo_available, 0, NULL, PORTALGO_MAXLEN, + CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, &portalgo_node, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_STRING, "selected", + SYSCTL_DESCR("selected algorithm"), + sysctl_portalgo_selected4, 0, NULL, PORTALGO_MAXLEN, + CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, &portalgo_node, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_STRUCT, "reserve", + SYSCTL_DESCR("bitmap of reserved ports"), + sysctl_portalgo_reserve4, 0, NULL, 0, + CTL_CREATE, CTL_EOL); } void