summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authoralex <alex@FreeBSD.org>1998-01-04 22:36:12 +0000
committeralex <alex@FreeBSD.org>1998-01-04 22:36:12 +0000
commit44f7a5e2007f5b380ee895ff9c5050b692521544 (patch)
tree95567f46358ee834652563bd479d03e8edfe57d4 /sys/netinet
parentee72d26c0d2f312136d421affd8cf6033f616502 (diff)
downloadFreeBSD-src-44f7a5e2007f5b380ee895ff9c5050b692521544.zip
FreeBSD-src-44f7a5e2007f5b380ee895ff9c5050b692521544.tar.gz
Reduce the amount of time that network interrupts are blocked while
zeroing & deleting rules. Return EINVAL when zeroing an nonexistent entry.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index abcdf42..1a4523d 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -12,7 +12,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.c,v 1.66 1997/12/19 03:36:15 julian Exp $
+ * $Id: ip_fw.c,v 1.67 1997/12/27 18:44:56 alex Exp $
*/
/*
@@ -690,24 +690,30 @@ static int
del_entry(struct ip_fw_head *chainptr, u_short number)
{
struct ip_fw_chain *fcp;
- int s;
-
- s = splnet();
fcp = chainptr->lh_first;
if (number != (u_short)-1) {
for (; fcp; fcp = fcp->chain.le_next) {
if (fcp->rule->fw_number == number) {
- LIST_REMOVE(fcp, chain);
+ int s;
+
+ /* prevent access to rules while removing them */
+ s = splnet();
+ while (fcp && fcp->rule->fw_number == number) {
+ struct ip_fw_chain *next;
+
+ next = LIST_NEXT(fcp, chain);
+ LIST_REMOVE(fcp, chain);
+ free(fcp->rule, M_IPFW);
+ free(fcp, M_IPFW);
+ fcp = next;
+ }
splx(s);
- free(fcp->rule, M_IPFW);
- free(fcp, M_IPFW);
return 0;
}
}
}
- splx(s);
return (EINVAL);
}
@@ -726,18 +732,37 @@ zero_entry(struct mbuf *m)
else
frwl = NULL;
- /*
- * It's possible to insert multiple chain entries with the
- * same number, so we don't stop after finding the first
- * match if zeroing a specific entry.
- */
- s = splnet();
- for (fcp = ip_fw_chain.lh_first; fcp; fcp = fcp->chain.le_next)
- if (!frwl || frwl->fw_number == fcp->rule->fw_number) {
+ if (!frwl) {
+ s = splnet();
+ for (fcp = ip_fw_chain.lh_first; fcp; fcp = fcp->chain.le_next) {
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
fcp->rule->timestamp = 0;
}
- splx(s);
+ splx(s);
+ }
+ else {
+ int cleared = 0;
+
+ /*
+ * It's possible to insert multiple chain entries with the
+ * same number, so we don't stop after finding the first
+ * match if zeroing a specific entry.
+ */
+ for (fcp = ip_fw_chain.lh_first; fcp; fcp = fcp->chain.le_next)
+ if (frwl->fw_number == fcp->rule->fw_number) {
+ s = splnet();
+ while (fcp && frwl->fw_number == fcp->rule->fw_number) {
+ fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
+ fcp->rule->timestamp = 0;
+ fcp = LIST_NEXT(fcp, chain);
+ }
+ splx(s);
+ cleared = 1;
+ break;
+ }
+ if (!cleared)
+ return(EINVAL); /* we didn't find any matching rules */
+ }
if (fw_verbose) {
if (frwl)
OpenPOWER on IntegriCloud