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.114.4.4 retrieving revision 1.114.4.10 diff -u -p -r1.114.4.4 -r1.114.4.10 --- src/sys/netinet/ip_input.c 2001/03/11 21:10:34 1.114.4.4 +++ src/sys/netinet/ip_input.c 2002/11/13 00:34:59 1.114.4.10 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.114.4.4 2001/03/11 21:10:34 he Exp $ */ +/* $NetBSD: ip_input.c,v 1.114.4.10 2002/11/13 00:34:59 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -138,6 +138,8 @@ /* just for gif_ttl */ #include #include "gif.h" +#include +#include "gre.h" #ifdef MROUTING #include @@ -207,6 +209,8 @@ u_int16_t ip_id; struct ipqhead ipq; int ipq_locked; +int ip_nfragpackets = 0; +int ip_maxfragpackets = 200; static __inline int ipq_lock_try __P((void)); static __inline void ipq_unlock __P((void)); @@ -306,9 +310,7 @@ ip_init() TAILQ_INIT(&in_ifaddr); in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, M_IFADDR, M_WAITOK, &in_ifaddrhash); - if (ip_mtudisc != 0) - ip_mtudisc_timeout_q = - rt_timer_queue_create(ip_mtudisc_timeout); + ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); #ifdef GATEWAY ipflow_init(); #endif @@ -459,6 +461,14 @@ ip_input(struct mbuf *m) #endif #ifdef PFIL_HOOKS +#ifdef IPSEC + /* + * let ipfilter look at packet on the wire, + * not the decapsulated packet. + */ + if (ipsec_gethist(m, NULL)) + goto nofilt; +#endif /* * Run through list of hooks for input packets. If there are any * filters which require that additional packets in the flow are @@ -479,6 +489,9 @@ ip_input(struct mbuf *m) return; ip = mtod(m, struct ip *); } +#ifdef IPSEC +nofilt:; +#endif #endif /* PFIL_HOOKS */ /* @@ -609,6 +622,13 @@ 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; @@ -748,6 +768,17 @@ ip_reass(ipqe, fp) * If first fragment to arrive, create a reassembly queue. */ if (fp == 0) { + /* + * Enforce upper bound on number of fragmented packets + * for which we attempt reassembly; + * If maxfrag is 0, never accept fragments. + * If maxfrag is -1, accept all fragments without limitation. + */ + if (ip_maxfragpackets < 0) + ; + else if (ip_nfragpackets >= ip_maxfragpackets) + goto dropfrag; + ip_nfragpackets++; MALLOC(fp, struct ipq *, sizeof (struct ipq), M_FTABLE, M_NOWAIT); if (fp == NULL) @@ -863,6 +894,7 @@ insert: ip->ip_dst = fp->ipq_dst; LIST_REMOVE(fp, ipq_q); FREE(fp, M_FTABLE); + ip_nfragpackets--; m->m_len += (ip->ip_hl << 2); m->m_data -= (ip->ip_hl << 2); /* some debugging cruft by sklower, below, will go away soon */ @@ -901,6 +933,7 @@ ip_freef(fp) } LIST_REMOVE(fp, ipq_q); FREE(fp, M_FTABLE); + ip_nfragpackets--; } /* @@ -922,6 +955,17 @@ ip_slowtimo() ip_freef(fp); } } + /* + * If we are over the maximum number of fragments + * (due to the limit being lowered), drain off + * enough to get down to the new limit. + */ + if (ip_maxfragpackets < 0) + ; + else { + while (ip_nfragpackets > ip_maxfragpackets && ipq.lh_first) + ip_freef(ipq.lh_first); + } IPQ_UNLOCK(); #ifdef GATEWAY ipflow_slowtimo(); @@ -1452,7 +1496,7 @@ ip_forward(m, srcrt) #ifdef IPSEC /* Don't lookup socket in forwading case */ - ipsec_setsocket(m, NULL); + (void)ipsec_setsocket(m, NULL); #endif error = ip_output(m, (struct mbuf *)0, &ipforward_rt, (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0); @@ -1670,13 +1714,8 @@ ip_sysctl(name, namelen, oldp, oldlenp, case IPCTL_MTUDISC: error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc); - 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; - } + if (error == 0 && ip_mtudisc == 0) + rt_timer_queue_remove_all(ip_mtudisc_timeout_q, TRUE); return error; case IPCTL_ANONPORTMIN: old = anonportmin; @@ -1707,8 +1746,8 @@ ip_sysctl(name, namelen, oldp, oldlenp, case IPCTL_MTUDISCTIMEOUT: error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc_timeout); - if (ip_mtudisc_timeout_q != NULL) - rt_timer_queue_change(ip_mtudisc_timeout_q, + if (error == 0) + rt_timer_queue_change(ip_mtudisc_timeout_q, ip_mtudisc_timeout); return (error); #ifdef GATEWAY @@ -1733,6 +1772,12 @@ ip_sysctl(name, namelen, oldp, oldlenp, &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; @@ -1758,6 +1803,10 @@ ip_sysctl(name, namelen, oldp, oldlenp, return (error); #endif + case IPCTL_MAXFRAGPACKETS: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &ip_maxfragpackets)); + default: return (EOPNOTSUPP); }