diff options
author | Alexandr Nedvedicky <Alexandr.Nedvedicky@Sun.COM> | 2009-09-21 11:09:02 +0200 |
---|---|---|
committer | Alexandr Nedvedicky <Alexandr.Nedvedicky@Sun.COM> | 2009-09-21 11:09:02 +0200 |
commit | 14d3298ea5ac04e3c29e86a4769ff92a49e9f4af (patch) | |
tree | cb14b8f94b1fe79ac1e9272959045176c519e271 /usr/src | |
parent | 92e8aa2f28291f13555b38cb0adf7e84b2b83cae (diff) | |
download | illumos-gate-14d3298ea5ac04e3c29e86a4769ff92a49e9f4af.tar.gz |
6859313 large number of rules in ipfilter decreases throughput performance
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/inet/ipf/fil.c | 45 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ipf/ip_fil_solaris.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ipf/netinet/ipf_stack.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ipf/solaris.c | 5 |
4 files changed, 51 insertions, 4 deletions
diff --git a/usr/src/uts/common/inet/ipf/fil.c b/usr/src/uts/common/inet/ipf/fil.c index 360516b692..9cb19345b6 100644 --- a/usr/src/uts/common/inet/ipf/fil.c +++ b/usr/src/uts/common/inet/ipf/fil.c @@ -2151,6 +2151,7 @@ fr_info_t *fin; u_32_t *passp; { frentry_t *fr; + fr_info_t *fc; u_32_t pass; int out; ipf_stack_t *ifs = fin->fin_ifs; @@ -2164,13 +2165,51 @@ u_32_t *passp; else #endif fin->fin_fr = ifs->ifs_ipfilter[out][ifs->ifs_fr_active]; - if (fin->fin_fr != NULL) + + /* + * If there are no rules loaded skip all checks and return. + */ + if (fin->fin_fr == NULL) { + + if ((pass & FR_NOMATCH)) { + IPF_BUMP(ifs->ifs_frstats[out].fr_nom); + } + + return (NULL); + } + + fc = &ifs->ifs_frcache[out][CACHE_HASH(fin)]; + READ_ENTER(&ifs->ifs_ipf_frcache); + if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) { + /* + * copy cached data so we can unlock the mutexes earlier. + */ + bcopy((char *)fc, (char *)fin, FI_COPYSIZE); + RWLOCK_EXIT(&ifs->ifs_ipf_frcache); + IPF_BUMP(ifs->ifs_frstats[out].fr_chit); + + if ((fr = fin->fin_fr) != NULL) { + IPF_BUMP(fr->fr_hits); + pass = fr->fr_flags; + } + } else { + RWLOCK_EXIT(&ifs->ifs_ipf_frcache); + pass = fr_scanlist(fin, ifs->ifs_fr_pass); + if (((pass & FR_KEEPSTATE) == 0) && + ((fin->fin_flx & FI_DONTCACHE) == 0)) { + WRITE_ENTER(&ifs->ifs_ipf_frcache); + bcopy((char *)fin, (char *)fc, FI_COPYSIZE); + RWLOCK_EXIT(&ifs->ifs_ipf_frcache); + } + + fr = fin->fin_fr; + } + if ((pass & FR_NOMATCH)) { IPF_BUMP(ifs->ifs_frstats[out].fr_nom); } - fr = fin->fin_fr; /* * Apply packets per second rate-limiting to a rule as required. @@ -3520,6 +3559,7 @@ ipf_stack_t *ifs; int flushed = 0, set; WRITE_ENTER(&ifs->ifs_ipf_mutex); + bzero((char *)ifs->ifs_frcache, sizeof (ifs->ifs_frcache)); set = ifs->ifs_fr_active; if ((flags & FR_INACTIVE) == FR_INACTIVE) @@ -4504,6 +4544,7 @@ ipf_stack_t *ifs; fp->fr_cksum += *p; WRITE_ENTER(&ifs->ifs_ipf_mutex); + bzero((char *)ifs->ifs_frcache, sizeof (ifs->ifs_frcache)); for (; (f = *ftail) != NULL; ftail = &f->fr_next) { if ((fp->fr_cksum != f->fr_cksum) || diff --git a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c index 15a189239a..912efb0826 100644 --- a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c +++ b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c @@ -260,6 +260,7 @@ ipf_stack_t *ifs; ifs->ifs_fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH; #endif + bzero((char *)ifs->ifs_frcache, sizeof(ifs->ifs_frcache)); MUTEX_INIT(&ifs->ifs_ipf_rw, "ipf rw mutex"); MUTEX_INIT(&ifs->ifs_ipf_timeoutlock, "ipf timeout lock mutex"); RWLOCK_INIT(&ifs->ifs_ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); @@ -643,6 +644,8 @@ int *rp; error = EPERM; else { WRITE_ENTER(&ifs->ifs_ipf_mutex); + bzero((char *)ifs->ifs_frcache, + sizeof (ifs->ifs_frcache)); error = COPYOUT((caddr_t)&ifs->ifs_fr_active, (caddr_t)data, sizeof(ifs->ifs_fr_active)); diff --git a/usr/src/uts/common/inet/ipf/netinet/ipf_stack.h b/usr/src/uts/common/inet/ipf/netinet/ipf_stack.h index 35b646c301..75703994a5 100644 --- a/usr/src/uts/common/inet/ipf/netinet/ipf_stack.h +++ b/usr/src/uts/common/inet/ipf/netinet/ipf_stack.h @@ -45,6 +45,7 @@ struct ipf_stack { zoneid_t ifs_zone; /* ipf module */ + fr_info_t ifs_frcache[2][8]; filterstats_t ifs_frstats[2]; frentry_t *ifs_ipfilter[2][2]; @@ -91,6 +92,7 @@ struct ipf_stack { ipfmutex_t ifs_ipf_timeoutlock; ipfrwlock_t ifs_ipf_mutex; ipfrwlock_t ifs_ipf_global; + ipfrwlock_t ifs_ipf_frcache; ipfrwlock_t ifs_ip_poolrw; ipfrwlock_t ifs_ipf_frag; ipfrwlock_t ifs_ipf_state; diff --git a/usr/src/uts/common/inet/ipf/solaris.c b/usr/src/uts/common/inet/ipf/solaris.c index f6a39aeb60..1a1d94def5 100644 --- a/usr/src/uts/common/inet/ipf/solaris.c +++ b/usr/src/uts/common/inet/ipf/solaris.c @@ -3,7 +3,7 @@ * * See the IPFILTER.LICENCE file for details on licencing. * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -396,7 +396,7 @@ ipf_stack_create(const netid_t id) */ RWLOCK_INIT(&ifs->ifs_ipf_global, "ipf filter load/unload mutex"); RWLOCK_INIT(&ifs->ifs_ipf_mutex, "ipf filter rwlock"); - + RWLOCK_INIT(&ifs->ifs_ipf_frcache, "ipf cache rwlock"); ifs->ifs_netid = id; ifs->ifs_zone = net_getzoneidbynetid(id); ipf_kstat_init(ifs); @@ -553,6 +553,7 @@ ipf_stack_destroy(const netid_t id, void *arg) RWLOCK_EXIT(&ifs->ifs_ipf_global); RW_DESTROY(&ifs->ifs_ipf_mutex); + RW_DESTROY(&ifs->ifs_ipf_frcache); RW_DESTROY(&ifs->ifs_ipf_global); KFREE(ifs); |