--- 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);