Page MenuHomeFreeBSD

D51460.diff
No OneTemporary

D51460.diff

diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -3680,6 +3680,7 @@
IPFW_LOCK_INIT(chain);
+ ipfw_dyn_init(chain);
/* fill and insert the default rule */
rule = ipfw_alloc_rule(chain, sizeof(struct ip_fw));
rule->flags |= IPFW_RULE_NOOPT;
@@ -3689,7 +3690,6 @@
chain->default_rule = rule;
ipfw_add_protected_rule(chain, rule, 0);
- ipfw_dyn_init(chain);
ipfw_eaction_init(chain, first);
ipfw_init_skipto_cache(chain);
ipfw_bpf_init(first);
diff --git a/sys/netpfil/ipfw/ip_fw_dynamic.c b/sys/netpfil/ipfw/ip_fw_dynamic.c
--- a/sys/netpfil/ipfw/ip_fw_dynamic.c
+++ b/sys/netpfil/ipfw/ip_fw_dynamic.c
@@ -3141,6 +3141,43 @@
#undef DYN_EXPORT_STATES
}
+/*
+ * When we have enabled V_dyn_keep_states, states that become ORPHANED
+ * will keep pointer to original rule. Then this rule pointer is used
+ * to apply rule action after ipfw_dyn_lookup_state().
+ * Some rule actions use IPFW_INC_RULE_COUNTER() directly to this rule
+ * pointer, but other actions use chain->map[f_pos] instead. The last
+ * case leads to incrementing counters on the wrong rule, because
+ * ORPHANED states have not parent rule in chain->map[].
+ * To solve this we add protected rule:
+ * count ip from any to any not // comment
+ * It will be matched only by packets that are handled by ORPHANED states.
+ */
+static void
+dyn_add_protected_rule(struct ip_fw_chain *chain)
+{
+ static const char *comment =
+ "orphaned dynamic states counter";
+ struct ip_fw *rule;
+ ipfw_insn *cmd;
+ size_t l;
+
+ l = roundup(strlen(comment) + 1, sizeof(uint32_t));
+ rule = ipfw_alloc_rule(chain, sizeof(*rule) + sizeof(ipfw_insn) + l);
+ cmd = rule->cmd;
+ cmd->opcode = O_NOP;
+ cmd->len = 1 + l/sizeof(uint32_t);
+ cmd->len |= F_NOT; /* make rule to be not matched */
+ strcpy((char *)(cmd + 1), comment);
+ cmd += F_LEN(cmd);
+
+ cmd->len = 1;
+ cmd->opcode = O_COUNT;
+ rule->act_ofs = cmd - rule->cmd;
+ rule->cmd_len = rule->act_ofs + 1;
+ ipfw_add_protected_rule(chain, rule, 0);
+}
+
void
ipfw_dyn_init(struct ip_fw_chain *chain)
{
@@ -3203,6 +3240,8 @@
callout_init(&V_dyn_timeout, 1);
callout_reset(&V_dyn_timeout, hz, dyn_tick, curvnet);
IPFW_ADD_OBJ_REWRITER(IS_DEFAULT_VNET(curvnet), dyn_opcodes);
+
+ dyn_add_protected_rule(chain);
}
void

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 5:33 PM (3 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30731695
Default Alt Text
D51460.diff (2 KB)

Event Timeline