Page MenuHomeFreeBSD

D51459.id159674.diff
No OneTemporary

D51459.id159674.diff

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
@@ -1323,6 +1323,33 @@
#endif /* INET6 */
+static int
+dyn_handle_orphaned(struct ip_fw *old_rule, struct dyn_data *data)
+{
+ struct ip_fw *rule;
+ const ipfw_insn *cmd, *old_cmd;
+
+ old_cmd = ACTION_PTR(old_rule);
+ switch (old_cmd->opcode) {
+ case O_SETMARK:
+ case O_SKIPTO:
+ /*
+ * Rule pointer was changed. For O_SKIPTO action it can be
+ * dangerous to keep use old rule. If new rule has the same
+ * action and the same destination number, then use this dynamic
+ * state. Otherwise it is better to create new one.
+ */
+ rule = V_layer3_chain.map[data->f_pos];
+ cmd = ACTION_PTR(rule);
+ if (cmd->opcode != old_cmd->opcode ||
+ cmd->len != old_cmd->len || cmd->arg1 != old_cmd->arg1 ||
+ insntoc(cmd, u32)->d[0] != insntoc(old_cmd, u32)->d[0])
+ return (-1);
+ break;
+ }
+ return (0);
+}
+
/*
* Lookup dynamic state.
* pkt - filled by ipfw_chk() ipfw_flow_id;
@@ -1426,8 +1453,13 @@
* changed to point to the penultimate rule.
*/
MPASS(V_layer3_chain.n_rules > 1);
- data->chain_id = V_layer3_chain.id;
- data->f_pos = V_layer3_chain.n_rules - 2;
+ if (dyn_handle_orphaned(rule, data) == 0) {
+ data->chain_id = V_layer3_chain.id;
+ data->f_pos = V_layer3_chain.n_rules - 2;
+ } else {
+ rule = NULL;
+ info->direction = MATCH_NONE;
+ }
} else {
rule = NULL;
info->direction = MATCH_NONE;

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 4, 3:38 AM (18 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28430100
Default Alt Text
D51459.id159674.diff (1 KB)

Event Timeline