diff --git a/sys/netpfil/ipfw/ip_fw_dynamic.c b/sys/netpfil/ipfw/ip_fw_dynamic.c
index 00b54fa463a..3a029855704 100644
--- a/sys/netpfil/ipfw/ip_fw_dynamic.c
+++ b/sys/netpfil/ipfw/ip_fw_dynamic.c
@@ -1868,6 +1868,7 @@ dyn_install_state(const struct ipfw_flow_id *pkt, uint32_t zoneid,
struct ipfw_flow_id id;
uint32_t hashval, parent_hashval, ruleid, rulenum;
int ret;
+ struct ipfw_dyn_hook_extdata edat;
MPASS(type == O_LIMIT || type == O_KEEP_STATE);
@@ -1959,6 +1960,17 @@ dyn_install_state(const struct ipfw_flow_id *pkt, uint32_t zoneid,
#endif
}
}
+
+ if (type == O_KEEP_STATE && !ret && V_hook_state) {
+ memset(&edat, 0, sizeof edat);
+ edat.ruleid = ruleid;
+ edat.rulenum = rulenum;
+ edat.fibnum = fibnum;
+ edat.kidx = kidx;
+ edat.cmdtype = type;
+ V_hook_state(pkt, &edat);
+ }
+
/*
* EEXIST means that simultaneous thread has created this
* state. Consider this as success.
@@ -2783,6 +2795,7 @@ dyn_tick(void *vnetx)
#endif
NET_EPOCH_EXIT(et);
}
+
/*
* Check if we need to resize the hash:
* if current number of states exceeds number of buckets in hash,
@@ -2816,6 +2829,31 @@ ipfw_expire_dyn_states(struct ip_fw_chain *chain, ipfw_range_tlv *rt)
dyn_expire_states(chain, rt);
}
+int
+ipfw_dyn_install_sync_state(const struct ipfw_flow_id *pkt, void *rule, uint32_t ruleid,
+ uint16_t rulenum, uint16_t kidx, uint8_t cmdtype)
+{
+ int ret = 0;
+ uint32_t hashval = 0;
+ struct ipfw_dyn_info info;
+
+ DYN_INFO_INIT(&info);
+
+ hashval = hash_packet(pkt);
+ if (IS_IP4_FLOW_ID(pkt))
+ ret = dyn_add_ipv4_state(rule, ruleid, rulenum, pkt,
+ NULL, 0, hashval, &info, pkt->fib, kidx, cmdtype);
+#ifdef INET6
+ else if (IS_IP6_FLOW_ID(pkt))
+ ret = dyn_add_ipv6_state(rule, ruleid, rulenum, pkt,
+ pkt->flow_id6, NULL, 0, hashval, &info, pkt->fib, kidx, cmdtype);
+#endif /* INET6 */
+ else
+ ret = EAFNOSUPPORT;
+
+ return ret;
+}
+
/*
* Pass through all states and reset eaction for orphaned rules.
*/
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>