Mercurial > illumos > illumos-gate
changeset 10587:e0d280fab007
6859313 large number of rules in ipfilter decreases throughput performance
author | Alexandr Nedvedicky <Alexandr.Nedvedicky@Sun.COM> |
---|---|
date | Mon, 21 Sep 2009 11:09:02 +0200 |
parents | 252cfb0aebde |
children | dc03f981ea18 |
files | usr/src/uts/common/inet/ipf/fil.c usr/src/uts/common/inet/ipf/ip_fil_solaris.c usr/src/uts/common/inet/ipf/netinet/ipf_stack.h usr/src/uts/common/inet/ipf/solaris.c |
diffstat | 4 files changed, 51 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ipf/fil.c Sun Sep 20 07:48:31 2009 -0700 +++ b/usr/src/uts/common/inet/ipf/fil.c Mon Sep 21 11:09:02 2009 +0200 @@ -2151,6 +2151,7 @@ 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 @@ 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 @@ 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 @@ 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) ||
--- a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c Sun Sep 20 07:48:31 2009 -0700 +++ b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c Mon Sep 21 11:09:02 2009 +0200 @@ -260,6 +260,7 @@ 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 @@ 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));
--- a/usr/src/uts/common/inet/ipf/netinet/ipf_stack.h Sun Sep 20 07:48:31 2009 -0700 +++ b/usr/src/uts/common/inet/ipf/netinet/ipf_stack.h Mon Sep 21 11:09:02 2009 +0200 @@ -45,6 +45,7 @@ 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 @@ 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;
--- a/usr/src/uts/common/inet/ipf/solaris.c Sun Sep 20 07:48:31 2009 -0700 +++ b/usr/src/uts/common/inet/ipf/solaris.c Mon Sep 21 11:09:02 2009 +0200 @@ -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 @@ */ 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 @@ 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);