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.130 retrieving revision 1.131 diff -u -p -r1.130 -r1.131 --- src/sys/netinet/ip_input.c 2001/03/02 04:26:10 1.130 +++ src/sys/netinet/ip_input.c 2001/03/27 02:24:38 1.131 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.130 2001/03/02 04:26:10 itojun 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. @@ -211,6 +211,8 @@ struct pfil_head inet_pfil_hook; struct ipqhead ipq; int ipq_locked; +int ip_nfragpackets = 0; +int ip_maxfragpackets = -1; static __inline int ipq_lock_try __P((void)); static __inline void ipq_unlock __P((void)); @@ -781,6 +783,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) @@ -896,6 +909,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 */ @@ -934,6 +948,7 @@ ip_freef(fp) } LIST_REMOVE(fp, ipq_q); FREE(fp, M_FTABLE); + ip_nfragpackets--; } /* @@ -955,6 +970,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(); @@ -1791,6 +1817,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); }