summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2003-09-05 00:10:33 +0000
committersam <sam@FreeBSD.org>2003-09-05 00:10:33 +0000
commit7bc9af7ebb66a587ff51554c03e76739020f82ac (patch)
tree91e635f8fd26b919ee26363186d7860f2847eb80
parentbca2780311827f606a067be95887532624a79a89 (diff)
downloadFreeBSD-src-7bc9af7ebb66a587ff51554c03e76739020f82ac.zip
FreeBSD-src-7bc9af7ebb66a587ff51554c03e76739020f82ac.tar.gz
lock ip fragment queues
Submitted by: Robert Watson <rwatson@freebsd.org> Obtained from: BSD/OS
-rw-r--r--sys/netinet/ip_input.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index b06ab8a..eefe26f 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -182,6 +182,12 @@ SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RW,
(((((x) & 0xF) | ((((x) >> 8) & 0xF) << 4)) ^ (y)) & IPREASS_HMASK)
static TAILQ_HEAD(ipqhead, ipq) ipq[IPREASS_NHASH];
+struct mtx ipqlock;
+
+#define IPQ_LOCK() mtx_lock(&ipqlock)
+#define IPQ_UNLOCK() mtx_unlock(&ipqlock)
+#define IPQ_LOCK_INIT() mtx_init(&ipqlock, "ipqlock", NULL, MTX_DEF);
+#define IPQ_LOCK_ASSERT() mtx_assert(&ipqlock, MA_OWNED);
#ifdef IPCTL_DEFMTU
SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
@@ -257,6 +263,7 @@ ip_init()
pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
ip_protox[pr->pr_protocol] = pr - inetsw;
+ IPQ_LOCK_INIT();
for (i = 0; i < IPREASS_NHASH; i++)
TAILQ_INIT(&ipq[i]);
@@ -746,6 +753,7 @@ ours:
}
sum = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
+ IPQ_LOCK();
/*
* Look for queue of fragments
* of this datagram.
@@ -799,6 +807,7 @@ found:
* that's a non-zero multiple of 8 bytes.
*/
if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) {
+ IPQ_UNLOCK();
ipstat.ips_toosmall++; /* XXX */
goto bad;
}
@@ -816,6 +825,7 @@ found:
m->m_pkthdr.header = ip;
m = ip_reass(m,
&ipq[sum], fp, &divert_info, &args.divert_rule);
+ IPQ_UNLOCK();
if (m == 0)
return;
ipstat.ips_reassembled++;
@@ -974,6 +984,8 @@ ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp,
int hlen = ip->ip_hl << 2;
int i, next;
+ IPQ_LOCK_ASSERT();
+
/*
* Presence of header sizes in mbufs
* would confuse code below.
@@ -1203,6 +1215,8 @@ ip_freef(fhp, fp)
{
register struct mbuf *q;
+ IPQ_LOCK_ASSERT();
+
while (fp->ipq_frags) {
q = fp->ipq_frags;
fp->ipq_frags = q->m_nextpkt;
@@ -1225,6 +1239,7 @@ ip_slowtimo()
int s = splnet();
int i;
+ IPQ_LOCK();
for (i = 0; i < IPREASS_NHASH; i++) {
for(fp = TAILQ_FIRST(&ipq[i]); fp;) {
struct ipq *fpp;
@@ -1251,6 +1266,7 @@ ip_slowtimo()
}
}
}
+ IPQ_UNLOCK();
ipflow_slowtimo();
splx(s);
}
@@ -1263,6 +1279,7 @@ ip_drain()
{
int i;
+ IPQ_LOCK();
for (i = 0; i < IPREASS_NHASH; i++) {
while(!TAILQ_EMPTY(&ipq[i])) {
ipstat.ips_fragdropped +=
@@ -1270,6 +1287,7 @@ ip_drain()
ip_freef(&ipq[i], TAILQ_FIRST(&ipq[i]));
}
}
+ IPQ_UNLOCK();
in_rtqdrain();
}
OpenPOWER on IntegriCloud