diff options
author | Mike Silbersack <silby@FreeBSD.org> | 2003-02-22 06:41:47 +0000 |
---|---|---|
committer | Mike Silbersack <silby@FreeBSD.org> | 2003-02-22 06:41:47 +0000 |
commit | 375386e284b734aa8e16ad8ecf6b8b5bca72eb53 (patch) | |
tree | cbeddee447e399a02ac9205d707c9b970aedfb06 /sys/netinet | |
parent | 750a91d8b1d767af02a509406cd7ec72e4ec7fb1 (diff) | |
download | src-test2-375386e284b734aa8e16ad8ecf6b8b5bca72eb53.tar.gz src-test2-375386e284b734aa8e16ad8ecf6b8b5bca72eb53.zip |
Notes
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_input.c | 32 | ||||
-rw-r--r-- | sys/netinet/ip_var.h | 1 |
2 files changed, 29 insertions, 4 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 3e1f8a508dc1..04aa1c37f379 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -125,6 +125,11 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragpackets, CTLFLAG_RW, &maxnipq, 0, "Maximum number of IPv4 fragment reassembly queue entries"); +static int maxfragsperpacket; +SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragsperpacket, CTLFLAG_RW, + &maxfragsperpacket, 0, + "Maximum number of IPv4 fragments allowed per packet"); + static int ip_sendsourcequench = 0; SYSCTL_INT(_net_inet_ip, OID_AUTO, sendsourcequench, CTLFLAG_RW, &ip_sendsourcequench, 0, @@ -256,7 +261,8 @@ ip_init() for (i = 0; i < IPREASS_NHASH; i++) TAILQ_INIT(&ipq[i]); - maxnipq = nmbclusters / 4; + maxnipq = nmbclusters / 32; + maxfragsperpacket = 16; #ifndef RANDOM_IP_ID ip_id = time_second & 0xffff; @@ -994,6 +1000,7 @@ ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp, #endif TAILQ_INSERT_HEAD(head, fp, ipq_list); nipq++; + fp->ipq_nfrags = 1; fp->ipq_ttl = IPFRAGTTL; fp->ipq_p = ip->ip_p; fp->ipq_id = ip->ip_id; @@ -1007,6 +1014,7 @@ ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp, #endif goto inserted; } else { + fp->ipq_nfrags++; #ifdef MAC mac_update_ipq(m, fp); #endif @@ -1064,6 +1072,7 @@ ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp, } nq = q->m_nextpkt; m->m_nextpkt = nq; + fp->ipq_nfrags--; m_freem(q); } @@ -1083,17 +1092,30 @@ inserted: #endif /* - * Check for complete reassembly. + * Check for complete reassembly and perform frag per packet + * limiting. + * + * Frag limiting is performed here so that the nth frag has + * a chance to complete the packet before we drop the packet. + * As a result, n+1 frags are actually allowed per packet, but + * only n will ever be stored. (n = maxfragsperpacket.) + * */ next = 0; for (p = NULL, q = fp->ipq_frags; q; p = q, q = q->m_nextpkt) { - if (GETIP(q)->ip_off != next) + if (GETIP(q)->ip_off != next) { + if (fp->ipq_nfrags > maxfragsperpacket) + ip_freef(head, fp); return (0); + } next += GETIP(q)->ip_len; } /* Make sure the last packet didn't have the IP_MF flag */ - if (p->m_flags & M_FRAG) + if (p->m_flags & M_FRAG) { + if (fp->ipq_nfrags > maxfragsperpacket) + ip_freef(head, fp); return (0); + } /* * Reassembly is complete. Make sure the packet is a sane size. @@ -1160,6 +1182,8 @@ dropfrag: *divert_rule = 0; #endif ipstat.ips_fragdropped++; + if (fp != 0) + fp->ipq_nfrags--; m_freem(m); return (0); diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index c03c44658252..c8df2e673e4a 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -68,6 +68,7 @@ struct ipq { u_short ipq_id; /* sequence id for reassembly */ struct mbuf *ipq_frags; /* to ip headers of fragments */ struct in_addr ipq_src,ipq_dst; + u_char ipq_nfrags; /* # frags in this packet */ u_int32_t ipq_div_info; /* ipfw divert port & flags */ u_int16_t ipq_div_cookie; /* ipfw divert cookie */ struct label ipq_label; /* MAC label */ |