Re: CURRENT: kernel panic in IPFW while stopping jails

Gleb Smirnoff <[email protected]>
Newsgroups gmane.os.freebsd.current
Message-ID <[email protected]>
  Hi,

I have found the problem, thanks to Alastair for a core file.

The problem affects rules with automatic rule numbers and logging.

The attached patch should fix the problem, but it is not a final version.

Dan & Alastair, if any of you can confirm that the patch heals your setup - I
will appreciate.

Again very sorry for this breakage.

-- 
Gleb Smirnoff
ipfw-log.diff (text/x-diff, 1.7 KB)
diff --git a/sys/netpfil/ipfw/ip_fw_bpf.c b/sys/netpfil/ipfw/ip_fw_bpf.c
index d9897f700d57..2a9f8d889f43 100644
--- a/sys/netpfil/ipfw/ip_fw_bpf.c
+++ b/sys/netpfil/ipfw/ip_fw_bpf.c
@@ -81,6 +81,8 @@ ipfw_tap_alloc(uint32_t rule)
 	struct ipfw_tap	*tap, key = { .rule = rule };
 	int n __diagused;
 
+	MPASS(rule > 0);
+
 	tap = RB_FIND(tap_tree, &V_tap_tree, &key);
 	if (tap != NULL) {
 		MPASS(tap->rule == rule);
@@ -106,9 +108,10 @@ ipfw_tap_alloc(uint32_t rule)
 void
 ipfw_tap_free(uint32_t rule)
 {
-
 	struct ipfw_tap	*tap, key = { .rule = rule };
 
+	MPASS(rule > 0);
+
 	tap = RB_FIND(tap_tree, &V_tap_tree, &key);
 	MPASS(tap != NULL);
 	if (--tap->refs == 0) {
diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c
index a91fb2e84da9..38e134a21141 100644
--- a/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ b/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -210,7 +210,7 @@ ipfw_free_rule(struct ip_fw *rule)
 	 */
 	if (rule->refcnt > 1)
 		return;
-	if (ACTION_PTR(rule)->opcode == O_LOG)
+	if (ACTION_PTR(rule)->opcode == O_LOG && rule->rulenum != 0)
 		ipfw_tap_free(rule->rulenum);
 	uma_zfree_pcpu(V_ipfw_cntr_zone, rule->cntr);
 	free(rule, M_IPFW);
@@ -552,6 +552,8 @@ ipfw_commit_rules(struct ip_fw_chain *chain, struct rule_check_info *rci,
 			memcpy((char *)ci->urule + ci->urule_numoff, &rulenum,
 			    sizeof(rulenum));
 		}
+		if (ACTION_PTR(krule)->opcode == O_LOG)
+			ipfw_tap_alloc(krule->rulenum);
 	}
 
 	/* duplicate the remaining part, we always have the default rule */
@@ -2513,9 +2515,6 @@ import_rule_v1(struct ip_fw_chain *chain, struct rule_check_info *ci)
 
 	/* Copy opcodes */
 	memcpy(krule->cmd, urule->cmd, krule->cmd_len * sizeof(uint32_t));
-
-	if (ACTION_PTR(krule)->opcode == O_LOG)
-		ipfw_tap_alloc(krule->rulenum);
 }
 
 /*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.