Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/netinet Pull up revisions 1.131, 1.133 (requested by...



details:   https://anonhg.NetBSD.org/src/rev/b36ca60d9800
branches:  netbsd-1-5
changeset: 491337:b36ca60d9800
user:      he <he%NetBSD.org@localhost>
date:      Tue Apr 24 22:21:20 2001 +0000

description:
Pull up revisions 1.131,1.133 (requested by itojun):
  Introduce net.inet.ip.maxfragpackets, which controls the maximum
  number of IPv4 fragment reassembly queue entries.  Defends against
  certain DoS attacks.

diffstat:

 sys/netinet/ip_input.c |  32 +++++++++++++++++++++++++++++++-
 1 files changed, 31 insertions(+), 1 deletions(-)

diffs (81 lines):

diff -r 5089cbf171dd -r b36ca60d9800 sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c    Tue Apr 24 21:36:30 2001 +0000
+++ b/sys/netinet/ip_input.c    Tue Apr 24 22:21:20 2001 +0000
@@ -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 @@
 
 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 @@
         * 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 @@
        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 @@
        }
        LIST_REMOVE(fp, ipq_q);
        FREE(fp, M_FTABLE);
+       ip_nfragpackets--;
 }
 
 /*
@@ -933,6 +948,17 @@
                        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 @@
                return (error);
 #endif
 
+       case IPCTL_MAXFRAGPACKETS:
+               return (sysctl_int(oldp, oldlenp, newp, newlen,
+                   &ip_maxfragpackets));
+
        default:
                return (EOPNOTSUPP);
        }



Home | Main Index | Thread Index | Old Index