net.inet.ip.maxfragpackets defines the maximum size of ip reass queue

(prevents fragment flood from chewing up mbuf memory space).
derived from KAME net.inet6.ip6.maxfragpackets.
This commit is contained in:
itojun 2001-03-27 02:24:38 +00:00
parent eb5ddb38e4
commit 4b72eeeee5
4 changed files with 44 additions and 5 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sysctl.3,v 1.74 2001/02/08 16:07:39 itojun Exp $
.\" $NetBSD: sysctl.3,v 1.75 2001/03/27 02:24:40 itojun Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@ -677,6 +677,7 @@ The currently defined protocols and names are:
.It ip gifttl integer yes
.It ip lowportmin integer yes
.It ip lowportmax integer yes
.It ip maxfragpacket integer yes
.It icmp maskrepl integer yes
.It icmp errppslimit integer yes
.It tcp rfc1323 integer yes
@ -758,6 +759,11 @@ The highest port number to use for TCP and UDP reserved port allocation.
This cannot be set to less than 0 or greater than 1024, and must
be greater than
.Li ip.lowportmin .
.It Li ip.maxfragpackets
The maximum number of fragmented packets the node will accept.
0 means that the node will not accept any fragmented packets.
-1 means that the node will accept as many fragmented packets as it receives.
The flag is provided basically for avoiding possible DoS attacks.
.It Li icmp.maskrepl
Returns 1 if ICMP network mask requests are to be answered.
.It Li icmp.errppslimit

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sysctl.8,v 1.65 2001/03/09 01:02:10 chs Exp $
.\" $NetBSD: sysctl.8,v 1.66 2001/03/27 02:24:39 itojun Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@ -218,6 +218,7 @@ privilege can change the value.
.It net.inet.ip.directed-broadcast integer yes
.It net.inet.ip.forwarding integer yes
.It net.inet.ip.forwsrcrt integer yes
.It net.inet.ip.maxfragpacket integer yes
.It net.inet.ip.lowportmax integer yes
.It net.inet.ip.lowportmin integer yes
.It net.inet.ip.mtudisc integer yes

View File

@ -1,4 +1,4 @@
/* $NetBSD: in.h,v 1.52 2001/01/19 09:01:48 kleink Exp $ */
/* $NetBSD: in.h,v 1.53 2001/03/27 02:24:39 itojun Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -355,7 +355,8 @@ struct ip_mreq {
#define IPCTL_GIF_TTL 15 /* default TTL for gif encap packet */
#define IPCTL_LOWPORTMIN 16 /* minimum reserved port */
#define IPCTL_LOWPORTMAX 17 /* maximum reserved port */
#define IPCTL_MAXID 18
#define IPCTL_MAXFRAGPACKETS 18 /* max packets reassembly queue */
#define IPCTL_MAXID 19
#define IPCTL_NAMES { \
{ 0, 0 }, \
@ -376,6 +377,7 @@ struct ip_mreq {
{ "gifttl", CTLTYPE_INT }, \
{ "lowportmin", CTLTYPE_INT }, \
{ "lowportmax", CTLTYPE_INT }, \
{ "maxfragpackets", CTLTYPE_INT }, \
}
#endif /* !_XOPEN_SOURCE */

View File

@ -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, newp, newlen)
return (error);
#endif
case IPCTL_MAXFRAGPACKETS:
return (sysctl_int(oldp, oldlenp, newp, newlen,
&ip_maxfragpackets));
default:
return (EOPNOTSUPP);
}