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 retrieving revision 1.114.4.5 retrieving revision 1.114.4.6 diff -u -p -r1.114.4.5 -r1.114.4.6 --- src/sys/netinet/ip_input.c 2001/04/06 00:24:47 1.114.4.5 +++ src/sys/netinet/ip_input.c 2001/04/24 22:21:20 1.114.4.6 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.114.4.5 2001/04/06 00:24:47 he Exp $ */ +/* $NetBSD: ip_input.c,v 1.114.4.6 2001/04/24 22:21:20 he Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -207,6 +207,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)); @@ -759,6 +761,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) @@ -874,6 +887,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 */ @@ -912,6 +926,7 @@ ip_freef(fp) } LIST_REMOVE(fp, ipq_q); FREE(fp, M_FTABLE); + ip_nfragpackets--; } /* @@ -933,6 +948,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(); @@ -1769,6 +1795,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); }