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.82.2.6 retrieving revision 1.82.2.7 diff -u -p -r1.82.2.6 -r1.82.2.7 --- src/sys/netinet/ip_input.c 2000/05/06 16:43:25 1.82.2.6 +++ src/sys/netinet/ip_input.c 2001/05/30 09:44:09 1.82.2.7 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.82.2.6 2000/05/06 16:43:25 he Exp $ */ +/* $NetBSD: ip_input.c,v 1.82.2.7 2001/05/30 09:44:09 he Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -167,6 +167,8 @@ int ip_defttl; 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)); @@ -641,6 +643,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) @@ -756,6 +769,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 */ @@ -794,6 +808,7 @@ ip_freef(fp) } LIST_REMOVE(fp, ipq_q); FREE(fp, M_FTABLE); + ip_nfragpackets--; } /* @@ -815,6 +830,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(); @@ -1522,6 +1548,11 @@ ip_sysctl(name, namelen, oldp, oldlenp, return (error); } #endif + + case IPCTL_MAXFRAGPACKETS: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &ip_maxfragpackets)); + default: return (EOPNOTSUPP); }