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.130.2.16 retrieving revision 1.131 diff -u -p -r1.130.2.16 -r1.131 --- src/sys/netinet/ip_input.c 2002/12/11 06:46:37 1.130.2.16 +++ src/sys/netinet/ip_input.c 2001/03/27 02:24:38 1.131 @@ -1,9 +1,9 @@ -/* $NetBSD: ip_input.c,v 1.130.2.16 2002/12/11 06:46:37 thorpej Exp $ */ +/* $NetBSD: ip_input.c,v 1.131 2001/03/27 02:24:38 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +15,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -101,14 +101,10 @@ * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 */ -#include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.130.2.16 2002/12/11 06:46:37 thorpej Exp $"); - #include "opt_gateway.h" #include "opt_pfil_hooks.h" #include "opt_ipsec.h" #include "opt_mrouting.h" -#include "opt_inet_csum.h" #include #include @@ -121,7 +117,11 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v #include #include #include +#include #include + +#include + #include #include @@ -139,8 +139,6 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v /* just for gif_ttl */ #include #include "gif.h" -#include -#include "gre.h" #ifdef MROUTING #include @@ -168,7 +166,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v #define IPALLOWSRCRT 1 /* allow source-routed packets */ #endif #ifndef IPMTUDISC -#define IPMTUDISC 1 +#define IPMTUDISC 0 #endif #ifndef IPMTUDISCTIMEOUT #define IPMTUDISCTIMEOUT (10 * 60) /* as per RFC 1191 */ @@ -192,7 +190,7 @@ int ip_forwsrcrt = IPFORWSRCRT; int ip_directedbcast = IPDIRECTEDBCAST; int ip_allowsrcrt = IPALLOWSRCRT; int ip_mtudisc = IPMTUDISC; -int ip_mtudisc_timeout = IPMTUDISCTIMEOUT; +u_int ip_mtudisc_timeout = IPMTUDISCTIMEOUT; #ifdef DIAGNOSTIC int ipprintfs = 0; #endif @@ -201,8 +199,6 @@ struct rttimer_queue *ip_mtudisc_timeout extern struct domain inetdomain; int ipqmaxlen = IFQ_MAXLEN; -u_long in_ifaddrhash; /* size of hash table - 1 */ -int in_ifaddrentries; /* total number of addrs */ struct in_ifaddrhead in_ifaddr; struct in_ifaddrhashhead *in_ifaddrhashtbl; struct ifqueue ipintrq; @@ -216,7 +212,7 @@ struct pfil_head inet_pfil_hook; struct ipqhead ipq; int ipq_locked; int ip_nfragpackets = 0; -int ip_maxfragpackets = 200; +int ip_maxfragpackets = -1; static __inline int ipq_lock_try __P((void)); static __inline void ipq_unlock __P((void)); @@ -226,11 +222,7 @@ ipq_lock_try() { int s; - /* - * Use splvm() -- we're blocking things that would cause - * mbuf allocation. - */ - s = splvm(); + s = splimp(); if (ipq_locked) { splx(s); return (0); @@ -245,7 +237,7 @@ ipq_unlock() { int s; - s = splvm(); + s = splimp(); ipq_locked = 0; splx(s); } @@ -257,14 +249,14 @@ do { \ printf("%s:%d: ipq already locked\n", __FILE__, __LINE__); \ panic("ipq_lock"); \ } \ -} while (/*CONSTCOND*/ 0) +} while (0) #define IPQ_LOCK_CHECK() \ do { \ if (ipq_locked == 0) { \ printf("%s:%d: ipq lock not held\n", __FILE__, __LINE__); \ panic("ipq lock check"); \ } \ -} while (/*CONSTCOND*/ 0) +} while (0) #else #define IPQ_LOCK() (void) ipq_lock_try() #define IPQ_LOCK_CHECK() /* nothing */ @@ -274,24 +266,6 @@ do { \ struct pool ipqent_pool; -#ifdef INET_CSUM_COUNTERS -#include - -struct evcnt ip_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, - NULL, "inet", "hwcsum bad"); -struct evcnt ip_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, - NULL, "inet", "hwcsum ok"); -struct evcnt ip_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, - NULL, "inet", "swcsum"); - -#define INET_CSUM_COUNTER_INCR(ev) (ev)->ev_count++ - -#else - -#define INET_CSUM_COUNTER_INCR(ev) /* nothing */ - -#endif /* INET_CSUM_COUNTERS */ - /* * We need to save the IP options in case a protocol wants to respond * to an incoming packet over the same route if the packet got here @@ -320,7 +294,7 @@ ip_init() int i; pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl", - NULL); + 0, NULL, NULL, M_IPQ); pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW); if (pr == 0) @@ -338,7 +312,9 @@ ip_init() TAILQ_INIT(&in_ifaddr); in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IFADDR, M_WAITOK, &in_ifaddrhash); - ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); + if (ip_mtudisc != 0) + ip_mtudisc_timeout_q = + rt_timer_queue_create(ip_mtudisc_timeout); #ifdef GATEWAY ipflow_init(); #endif @@ -352,12 +328,6 @@ ip_init() printf("ip_init: WARNING: unable to register pfil hook, " "error %d\n", i); #endif /* PFIL_HOOKS */ - -#ifdef INET_CSUM_COUNTERS - evcnt_attach_static(&ip_hwcsum_bad); - evcnt_attach_static(&ip_hwcsum_ok); - evcnt_attach_static(&ip_swcsum); -#endif /* INET_CSUM_COUNTERS */ } struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET }; @@ -373,7 +343,7 @@ ipintr() struct mbuf *m; while (1) { - s = splnet(); + s = splimp(); IF_DEQUEUE(&ipintrq, m); splx(s); if (m == 0) @@ -415,27 +385,13 @@ ip_input(struct mbuf *m) * If no IP addresses have been set yet but the interfaces * are receiving, can't do anything with incoming packets yet. */ - if (TAILQ_FIRST(&in_ifaddr) == 0) + if (in_ifaddr.tqh_first == 0) goto bad; ipstat.ips_total++; - /* - * If the IP header is not aligned, slurp it up into a new - * mbuf with space for link headers, in the event we forward - * it. Otherwise, if it is aligned, make sure the entire - * base IP header is in the first mbuf of the chain. - */ - if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { - if ((m = m_copyup(m, sizeof(struct ip), - (max_linkhdr + 3) & ~3)) == NULL) { - /* XXXJRT new stat, please */ - ipstat.ips_toosmall++; - return; - } - } else if (__predict_false(m->m_len < sizeof (struct ip))) { - if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { - ipstat.ips_toosmall++; - return; - } + if (m->m_len < sizeof (struct ip) && + (m = m_pullup(m, sizeof (struct ip))) == 0) { + ipstat.ips_toosmall++; + return; } ip = mtod(m, struct ip *); if (ip->ip_v != IPVERSION) { @@ -473,24 +429,9 @@ ip_input(struct mbuf *m) } } - switch (m->m_pkthdr.csum_flags & - ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) | - M_CSUM_IPv4_BAD)) { - case M_CSUM_IPv4|M_CSUM_IPv4_BAD: - INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); - goto badcsum; - - case M_CSUM_IPv4: - /* Checksum was okay. */ - INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); - break; - - default: - /* Must compute it ourselves. */ - INET_CSUM_COUNTER_INCR(&ip_swcsum); - if (in_cksum(m, hlen) != 0) - goto bad; - break; + if (in_cksum(m, hlen) != 0) { + ipstat.ips_badsum++; + goto bad; } /* Retrieve the packet length. */ @@ -523,7 +464,7 @@ ip_input(struct mbuf *m) } #ifdef IPSEC - /* ipflow (IP fast forwarding) is not compatible with IPsec. */ + /* ipflow (IP fast fowarding) is not compatible with IPsec. */ m->m_flags &= ~M_CANFASTFWD; #else /* @@ -546,7 +487,7 @@ ip_input(struct mbuf *m) * not the decapsulated packet. */ #ifdef IPSEC - if (!ipsec_getnhist(m)) + if (!ipsec_gethist(m, NULL)) #else if (1) #endif @@ -557,7 +498,6 @@ ip_input(struct mbuf *m) if (m == NULL) return; ip = mtod(m, struct ip *); - hlen = ip->ip_hl << 2; } #endif /* PFIL_HOOKS */ @@ -570,6 +510,12 @@ ip_input(struct mbuf *m) #endif /* + * Convert fields to host representation. + */ + NTOHS(ip->ip_len); + NTOHS(ip->ip_off); + + /* * Process options and, if not destined for us, * ship it on. ip_dooptions returns 1 when an * error was detected (causing an icmp message @@ -587,7 +533,9 @@ ip_input(struct mbuf *m) * as not mine. */ downmatch = 0; - LIST_FOREACH(ia, &IN_IFADDR_HASH(ip->ip_dst.s_addr), ia_hash) { + for (ia = IN_IFADDR_HASH(ip->ip_dst.s_addr).lh_first; + ia != NULL; + ia = ia->ia_hash.le_next) { if (in_hosteq(ia->ia_addr.sin_addr, ip->ip_dst)) { if ((ia->ia_ifp->if_flags & IFF_UP) != 0) break; @@ -598,9 +546,9 @@ ip_input(struct mbuf *m) if (ia != NULL) goto ours; if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) { - TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrlist, ifa_list) { - if (ifa->ifa_addr->sa_family != AF_INET) - continue; + for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first; + ifa != NULL; ifa = ifa->ifa_list.tqe_next) { + if (ifa->ifa_addr->sa_family != AF_INET) continue; ia = ifatoia(ifa); if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) || in_hosteq(ip->ip_dst, ia->ia_netbroadcast) || @@ -624,7 +572,7 @@ ip_input(struct mbuf *m) #ifdef MROUTING extern struct socket *ip_mrouter; - if (M_READONLY(m)) { + if (m->m_flags & M_EXT) { if ((m = m_pullup(m, hlen)) == 0) { ipstat.ips_toosmall++; return; @@ -695,13 +643,6 @@ ip_input(struct mbuf *m) ipstat.ips_cantforward++; return; } -#ifdef IPSEC - if (ipsec4_in_reject(m, NULL)) { - ipsecstat.in_polvio++; - goto bad; - } -#endif - ip_forward(m, 0); } return; @@ -714,21 +655,13 @@ ours: * if the packet was previously fragmented, * but it's not worth the time; just let them time out.) */ - if (ip->ip_off & ~htons(IP_DF|IP_RF)) { - if (M_READONLY(m)) { - if ((m = m_pullup(m, hlen)) == NULL) { - ipstat.ips_toosmall++; - goto bad; - } - ip = mtod(m, struct ip *); - } - + if (ip->ip_off & ~(IP_DF|IP_RF)) { /* * Look for queue of fragments * of this datagram. */ IPQ_LOCK(); - LIST_FOREACH(fp, &ipq, ipq_q) + for (fp = ipq.lh_first; fp != NULL; fp = fp->ipq_q.le_next) if (ip->ip_id == fp->ipq_id && in_hosteq(ip->ip_src, fp->ipq_src) && in_hosteq(ip->ip_dst, fp->ipq_dst) && @@ -742,28 +675,27 @@ found: * set ipqe_mff if more fragments are expected, * convert offset of this to bytes. */ - ip->ip_len = htons(ntohs(ip->ip_len) - hlen); - mff = (ip->ip_off & htons(IP_MF)) != 0; + ip->ip_len -= hlen; + mff = (ip->ip_off & IP_MF) != 0; if (mff) { /* * Make sure that fragments have a data length * that's a non-zero multiple of 8 bytes. */ - if (ntohs(ip->ip_len) == 0 || - (ntohs(ip->ip_len) & 0x7) != 0) { + if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) { ipstat.ips_badfrags++; IPQ_UNLOCK(); goto bad; } } - ip->ip_off = htons((ntohs(ip->ip_off) & IP_OFFMASK) << 3); + ip->ip_off <<= 3; /* * If datagram marked as having more fragments * or if this is not the first fragment, * attempt reassembly; if it succeeds, proceed. */ - if (mff || ip->ip_off != htons(0)) { + if (mff || ip->ip_off) { ipstat.ips_fragments++; ipqe = pool_get(&ipqent_pool, PR_NOWAIT); if (ipqe == NULL) { @@ -782,7 +714,7 @@ found: ipstat.ips_reassembled++; ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; - ip->ip_len = htons(ntohs(ip->ip_len) + hlen); + ip->ip_len += hlen; } else if (fp) ip_freef(fp); @@ -807,7 +739,7 @@ found: */ #if IFA_STATS if (ia && ip) - ia->ia_ifa.ifa_data.ifad_inbytes += ntohs(ip->ip_len); + ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len; #endif ipstat.ips_delivered++; { @@ -818,11 +750,6 @@ found: } bad: m_freem(m); - return; - -badcsum: - ipstat.ips_badsum++; - m_freem(m); } /* @@ -875,7 +802,7 @@ ip_reass(ipqe, fp) fp->ipq_ttl = IPFRAGTTL; fp->ipq_p = ipqe->ipqe_ip->ip_p; fp->ipq_id = ipqe->ipqe_ip->ip_id; - TAILQ_INIT(&fp->ipq_fragq); + LIST_INIT(&fp->ipq_fragq); fp->ipq_src = ipqe->ipqe_ip->ip_src; fp->ipq_dst = ipqe->ipqe_ip->ip_dst; p = NULL; @@ -885,9 +812,9 @@ ip_reass(ipqe, fp) /* * Find a segment which begins after this one does. */ - for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; - p = q, q = TAILQ_NEXT(q, ipqe_q)) - if (ntohs(q->ipqe_ip->ip_off) > ntohs(ipqe->ipqe_ip->ip_off)) + for (p = NULL, q = fp->ipq_fragq.lh_first; q != NULL; + p = q, q = q->ipqe_q.le_next) + if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off) break; /* @@ -896,16 +823,14 @@ ip_reass(ipqe, fp) * segment. If it provides all of our data, drop us. */ if (p != NULL) { - i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) - - ntohs(ipqe->ipqe_ip->ip_off); + i = p->ipqe_ip->ip_off + p->ipqe_ip->ip_len - + ipqe->ipqe_ip->ip_off; if (i > 0) { - if (i >= ntohs(ipqe->ipqe_ip->ip_len)) + if (i >= ipqe->ipqe_ip->ip_len) goto dropfrag; m_adj(ipqe->ipqe_m, i); - ipqe->ipqe_ip->ip_off = - htons(ntohs(ipqe->ipqe_ip->ip_off) + i); - ipqe->ipqe_ip->ip_len = - htons(ntohs(ipqe->ipqe_ip->ip_len) - i); + ipqe->ipqe_ip->ip_off += i; + ipqe->ipqe_ip->ip_len -= i; } } @@ -913,22 +838,19 @@ ip_reass(ipqe, fp) * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - for (; q != NULL && - ntohs(ipqe->ipqe_ip->ip_off) + ntohs(ipqe->ipqe_ip->ip_len) > - ntohs(q->ipqe_ip->ip_off); q = nq) { - i = (ntohs(ipqe->ipqe_ip->ip_off) + - ntohs(ipqe->ipqe_ip->ip_len)) - ntohs(q->ipqe_ip->ip_off); - if (i < ntohs(q->ipqe_ip->ip_len)) { - q->ipqe_ip->ip_len = - htons(ntohs(q->ipqe_ip->ip_len) - i); - q->ipqe_ip->ip_off = - htons(ntohs(q->ipqe_ip->ip_off) + i); + for (; q != NULL && ipqe->ipqe_ip->ip_off + ipqe->ipqe_ip->ip_len > + q->ipqe_ip->ip_off; q = nq) { + i = (ipqe->ipqe_ip->ip_off + ipqe->ipqe_ip->ip_len) - + q->ipqe_ip->ip_off; + if (i < q->ipqe_ip->ip_len) { + q->ipqe_ip->ip_len -= i; + q->ipqe_ip->ip_off += i; m_adj(q->ipqe_m, i); break; } - nq = TAILQ_NEXT(q, ipqe_q); + nq = q->ipqe_q.le_next; m_freem(q->ipqe_m); - TAILQ_REMOVE(&fp->ipq_fragq, q, ipqe_q); + LIST_REMOVE(q, ipqe_q); pool_put(&ipqent_pool, q); } @@ -938,16 +860,16 @@ insert: * check for complete reassembly. */ if (p == NULL) { - TAILQ_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q); + LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q); } else { - TAILQ_INSERT_AFTER(&fp->ipq_fragq, p, ipqe, ipqe_q); + LIST_INSERT_AFTER(p, ipqe, ipqe_q); } next = 0; - for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; - p = q, q = TAILQ_NEXT(q, ipqe_q)) { - if (ntohs(q->ipqe_ip->ip_off) != next) + for (p = NULL, q = fp->ipq_fragq.lh_first; q != NULL; + p = q, q = q->ipqe_q.le_next) { + if (q->ipqe_ip->ip_off != next) return (0); - next += ntohs(q->ipqe_ip->ip_len); + next += q->ipqe_ip->ip_len; } if (p->ipqe_mff) return (0); @@ -956,7 +878,7 @@ insert: * Reassembly is complete. Check for a bogus message size and * concatenate fragments. */ - q = TAILQ_FIRST(&fp->ipq_fragq); + q = fp->ipq_fragq.lh_first; ip = q->ipqe_ip; if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) { ipstat.ips_toolong++; @@ -967,11 +889,11 @@ insert: t = m->m_next; m->m_next = 0; m_cat(m, t); - nq = TAILQ_NEXT(q, ipqe_q); + nq = q->ipqe_q.le_next; pool_put(&ipqent_pool, q); for (q = nq; q != NULL; q = nq) { t = q->ipqe_m; - nq = TAILQ_NEXT(q, ipqe_q); + nq = q->ipqe_q.le_next; pool_put(&ipqent_pool, q); m_cat(m, t); } @@ -982,7 +904,7 @@ insert: * dequeue and discard fragment reassembly header. * Make header visible. */ - ip->ip_len = htons(next); + ip->ip_len = next; ip->ip_src = fp->ipq_src; ip->ip_dst = fp->ipq_dst; LIST_REMOVE(fp, ipq_q); @@ -1018,10 +940,10 @@ ip_freef(fp) IPQ_LOCK_CHECK(); - for (q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; q = p) { - p = TAILQ_NEXT(q, ipqe_q); + for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) { + p = q->ipqe_q.le_next; m_freem(q->ipqe_m); - TAILQ_REMOVE(&fp->ipq_fragq, q, ipqe_q); + LIST_REMOVE(q, ipqe_q); pool_put(&ipqent_pool, q); } LIST_REMOVE(fp, ipq_q); @@ -1041,8 +963,8 @@ ip_slowtimo() int s = splsoftnet(); IPQ_LOCK(); - for (fp = LIST_FIRST(&ipq); fp != NULL; fp = nfp) { - nfp = LIST_NEXT(fp, ipq_q); + for (fp = ipq.lh_first; fp != NULL; fp = nfp) { + nfp = fp->ipq_q.le_next; if (--fp->ipq_ttl == 0) { ipstat.ips_fragtimeout++; ip_freef(fp); @@ -1056,8 +978,8 @@ ip_slowtimo() if (ip_maxfragpackets < 0) ; else { - while (ip_nfragpackets > ip_maxfragpackets && LIST_FIRST(&ipq)) - ip_freef(LIST_FIRST(&ipq)); + while (ip_nfragpackets > ip_maxfragpackets && ipq.lh_first) + ip_freef(ipq.lh_first); } IPQ_UNLOCK(); #ifdef GATEWAY @@ -1080,9 +1002,9 @@ ip_drain() if (ipq_lock_try() == 0) return; - while (LIST_FIRST(&ipq) != NULL) { + while (ipq.lh_first != NULL) { ipstat.ips_fragdropped++; - ip_freef(LIST_FIRST(&ipq)); + ip_freef(ipq.lh_first); } IPQ_UNLOCK(); @@ -1465,11 +1387,11 @@ ip_stripoptions(m, mopt) m->m_len -= olen; if (m->m_flags & M_PKTHDR) m->m_pkthdr.len -= olen; - ip->ip_len = htons(ntohs(ip->ip_len) - olen); + ip->ip_len -= olen; ip->ip_hl = sizeof (struct ip) >> 2; } -const int inetctlerrmap[PRC_NCMDS] = { +int inetctlerrmap[PRC_NCMDS] = { 0, 0, 0, 0, 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, @@ -1508,11 +1430,6 @@ ip_forward(m, srcrt) struct ifnet dummyifp; #endif - /* - * Clear any in-bound checksum flags for this packet. - */ - m->m_pkthdr.csum_flags = 0; - dest = 0; #ifdef DIAGNOSTIC if (ipprintfs) @@ -1555,7 +1472,7 @@ ip_forward(m, srcrt) * we need to generate an ICMP message to the src. * Pullup to avoid sharing mbuf cluster between m and mcopy. */ - mcopy = m_copym(m, 0, imin(ntohs(ip->ip_len), 68), M_DONTWAIT); + mcopy = m_copym(m, 0, imin((int)ip->ip_len, 68), M_DONTWAIT); if (mcopy) mcopy = m_pullup(mcopy, ip->ip_hl << 2); @@ -1593,7 +1510,7 @@ ip_forward(m, srcrt) } #ifdef IPSEC - /* Don't lookup socket in forwarding case */ + /* Don't lookup socket in forwading case */ (void)ipsec_setsocket(m, NULL); #endif error = ip_output(m, (struct mbuf *)0, &ipforward_rt, @@ -1682,8 +1599,6 @@ ip_forward(m, srcrt) ro = &sp->req->sav->sah->sa_route; if (ro->ro_rt && ro->ro_rt->rt_ifp) { dummyifp.if_mtu = - ro->ro_rt->rt_rmx.rmx_mtu ? - ro->ro_rt->rt_rmx.rmx_mtu : ro->ro_rt->rt_ifp->if_mtu; dummyifp.if_mtu -= ipsechdr; destifp = &dummyifp; @@ -1698,21 +1613,9 @@ ip_forward(m, srcrt) break; case ENOBUFS: -#if 1 - /* - * a router should not generate ICMP_SOURCEQUENCH as - * required in RFC1812 Requirements for IP Version 4 Routers. - * source quench could be a big problem under DoS attacks, - * or if the underlying interface is rate-limited. - */ - if (mcopy) - m_freem(mcopy); - return; -#else type = ICMP_SOURCEQUENCH; code = 0; break; -#endif } icmp_error(mcopy, type, code, dest, destifp); } @@ -1826,8 +1729,13 @@ ip_sysctl(name, namelen, oldp, oldlenp, case IPCTL_MTUDISC: error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc); - if (error == 0 && ip_mtudisc == 0) - rt_timer_queue_remove_all(ip_mtudisc_timeout_q, TRUE); + if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) { + ip_mtudisc_timeout_q = + rt_timer_queue_create(ip_mtudisc_timeout); + } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) { + rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE); + ip_mtudisc_timeout_q = NULL; + } return error; case IPCTL_ANONPORTMIN: old = anonportmin; @@ -1856,15 +1764,10 @@ ip_sysctl(name, namelen, oldp, oldlenp, } return (error); case IPCTL_MTUDISCTIMEOUT: - old = ip_mtudisc_timeout; error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc_timeout); - if (ip_mtudisc_timeout < 0) { - ip_mtudisc_timeout = old; - return (EINVAL); - } - if (error == 0) - rt_timer_queue_change(ip_mtudisc_timeout_q, + if (ip_mtudisc_timeout_q != NULL) + rt_timer_queue_change(ip_mtudisc_timeout_q, ip_mtudisc_timeout); return (error); #ifdef GATEWAY @@ -1885,16 +1788,10 @@ ip_sysctl(name, namelen, oldp, oldlenp, &hostzeroisbroadcast)); #if NGIF > 0 case IPCTL_GIF_TTL: - return (sysctl_int(oldp, oldlenp, newp, newlen, + return(sysctl_int(oldp, oldlenp, newp, newlen, &ip_gif_ttl)); #endif -#if NGRE > 0 - case IPCTL_GRE_TTL: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &ip_gre_ttl)); -#endif - #ifndef IPNOPRIVPORTS case IPCTL_LOWPORTMIN: old = lowportmin;