summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet
diff options
context:
space:
mode:
authorcy <cy@FreeBSD.org>2017-02-25 08:07:28 +0000
committercy <cy@FreeBSD.org>2017-02-25 08:07:28 +0000
commit449680a078c785c21812a7c15bbedc4938ec0484 (patch)
tree32a817c4b491d5b1a3fba7bba00834200d39b43d /sys/contrib/ipfilter/netinet
parent51c89b98e6d1180067ad03454d5303e098ca812e (diff)
downloadFreeBSD-src-449680a078c785c21812a7c15bbedc4938ec0484.zip
FreeBSD-src-449680a078c785c21812a7c15bbedc4938ec0484.tar.gz
MFC r312787:
Currently the fragment info is placed at the top of the linked list under a shared read lock. This patch attempts to upgrade the lock to an exclusive write lock. If the exclusive write lock fails to be obtained, the current fragment is not placed at the head of the list. This portion of the patch was inspired by NetBSD ip_frag.c r1.4 (which effectively removed the section of code that performed the reordering). The patch to sys/contrib/ipfilter/netinet/ip_compat.h adds the MUTEX_TRY_UPGRADE macro to support the patch to ip_frag.c. The patch to contrib/ipfilter/lib/rwlock_emul.c supports this patch by emulating the mutex in userspace when exercised by ipftest(1). Inspired by: NetBSD ip_frag.c r1.4
Diffstat (limited to 'sys/contrib/ipfilter/netinet')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c3
2 files changed, 6 insertions, 1 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index caa8ca8..227d454 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -162,6 +162,7 @@ struct ether_addr {
# define READ_ENTER(x) rw_rlock(&(x)->ipf_lk)
# define WRITE_ENTER(x) rw_wlock(&(x)->ipf_lk)
# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk)
+# define MUTEX_TRY_UPGRADE(x) rw_try_upgrade(&(x)->ipf_lk)
# define RWLOCK_INIT(x,y) rw_init(&(x)->ipf_lk, (y))
# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk)
# define RWLOCK_EXIT(x) do { \
@@ -406,6 +407,8 @@ extern void freembt __P((mb_t *));
# define MUTEX_DOWNGRADE(x) eMrwlock_downgrade(&(x)->ipf_emu, \
__FILE__, __LINE__)
+# define MUTEX_TRY_UPGRADE(x) eMrwlock_try_upgrade(&(x)->ipf_emu, \
+ __FILE__, __LINE__)
# define READ_ENTER(x) eMrwlock_read_enter(&(x)->ipf_emu, \
__FILE__, __LINE__)
# define RWLOCK_INIT(x, y) eMrwlock_init(&(x)->ipf_emu, y)
@@ -656,6 +659,7 @@ extern char *ipf_getifname __P((struct ifnet *, char *));
# define READ_ENTER(x) ;
# define WRITE_ENTER(x) ;
# define MUTEX_DOWNGRADE(x) ;
+# define MUTEX_TRY_UPGRADE(x) ;
# define RWLOCK_INIT(x, y) ;
# define RWLOCK_EXIT(x) ;
# define RW_DESTROY(x) ;
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index b460f20..426353a 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -743,7 +743,7 @@ ipf_frag_lookup(softc, softf, fin, table
} else if (off == 0)
f->ipfr_seen0 = 1;
- if (f != table[idx]) {
+ if (f != table[idx] && MUTEX_TRY_UPGRADE(lock)) {
ipfr_t **fp;
/*
@@ -761,6 +761,7 @@ ipf_frag_lookup(softc, softf, fin, table
table[idx]->ipfr_hprev = &f->ipfr_hnext;
f->ipfr_hprev = table + idx;
table[idx] = f;
+ MUTEX_DOWNGRADE(lock);
}
/*
OpenPOWER on IntegriCloud