diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c index cb509365e152..0b382b4b9a01 100644 --- a/sys/netpfil/ipfw/ip_fw_table.c +++ b/sys/netpfil/ipfw/ip_fw_table.c @@ -1600,17 +1600,45 @@ find_table_algo(struct tables_config *tcfg, struct tid_info *ti, char *name) return (NULL); } -void -ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta) +int +ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta, size_t size, + int *idx) { struct tables_config *tcfg; + struct table_algo *ta_new; + + if (size > sizeof(struct table_algo)) + return (EINVAL); + + ta_new = malloc(sizeof(struct table_algo), M_IPFW, M_WAITOK | M_ZERO); + memcpy(ta_new, ta, size); tcfg = CHAIN_TO_TCFG(ch); KASSERT(tcfg->algo_count < 255, ("Increase algo array size")); - tcfg->algo[++tcfg->algo_count] = ta; - ta->idx = tcfg->algo_count; + tcfg->algo[++tcfg->algo_count] = ta_new; + ta_new->idx = tcfg->algo_count; + + *idx = ta_new->idx; + + return (0); +} + +void +ipfw_del_table_algo(struct ip_fw_chain *ch, int idx) +{ + struct tables_config *tcfg; + struct table_algo *ta; + + tcfg = CHAIN_TO_TCFG(ch); + + KASSERT(idx <= tcfg->algo_count, ("algo idx %d out of rage 1..%d", idx, + tcfg->algo_count)); + + ta = tcfg->algo[idx]; + KASSERT(ta != NULL, ("algo idx %d is NULL", idx)); + free(ta, M_IPFW); } diff --git a/sys/netpfil/ipfw/ip_fw_table.h b/sys/netpfil/ipfw/ip_fw_table.h index 95d49542f48f..079aac50aa1d 100644 --- a/sys/netpfil/ipfw/ip_fw_table.h +++ b/sys/netpfil/ipfw/ip_fw_table.h @@ -100,7 +100,6 @@ struct table_algo { int idx; ta_init *init; ta_destroy *destroy; - table_lookup_t *lookup; ta_prepare_add *prepare_add; ta_prepare_del *prepare_del; ta_add *add; @@ -117,7 +116,9 @@ struct table_algo { ta_change_ti *change_ti; }; -void ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta); +int ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta, + size_t size, int *idx); +void ipfw_del_table_algo(struct ip_fw_chain *ch, int idx); extern struct table_algo cidr_radix, iface_idx; void ipfw_table_algo_init(struct ip_fw_chain *chain); diff --git a/sys/netpfil/ipfw/ip_fw_table_algo.c b/sys/netpfil/ipfw/ip_fw_table_algo.c index 1fbdc5db6b67..9b7c2b6ee849 100644 --- a/sys/netpfil/ipfw/ip_fw_table_algo.c +++ b/sys/netpfil/ipfw/ip_fw_table_algo.c @@ -516,7 +516,6 @@ ta_flush_cidr_entry(struct ip_fw_chain *ch, struct tentry_info *tei, struct table_algo cidr_radix = { .name = "cidr:radix", - .lookup = ta_lookup_radix, .init = ta_init_radix, .destroy = ta_destroy_radix, .prepare_add = ta_prepare_add_cidr, @@ -1195,7 +1194,6 @@ ta_flush_chash_entry(struct ip_fw_chain *ch, struct tentry_info *tei, struct table_algo cidr_hash = { .name = "cidr:hash", - .lookup = ta_lookup_chash_slow, .init = ta_init_chash, .destroy = ta_destroy_chash, .prepare_add = ta_prepare_add_chash, @@ -1848,7 +1846,6 @@ ta_foreach_ifidx(void *ta_state, struct table_info *ti, ta_foreach_f *f, struct table_algo iface_idx = { .name = "iface:array", - .lookup = ta_lookup_ifidx, .init = ta_init_ifidx, .destroy = ta_destroy_ifidx, .prepare_add = ta_prepare_add_ifidx, @@ -1867,20 +1864,26 @@ struct table_algo iface_idx = { }; void -ipfw_table_algo_init(struct ip_fw_chain *chain) +ipfw_table_algo_init(struct ip_fw_chain *ch) { + size_t sz; + /* * Register all algorithms presented here. */ - ipfw_add_table_algo(chain, &cidr_radix); - ipfw_add_table_algo(chain, &cidr_hash); - ipfw_add_table_algo(chain, &iface_idx); + sz = sizeof(struct table_algo); + ipfw_add_table_algo(ch, &cidr_radix, sz, &cidr_radix.idx); + ipfw_add_table_algo(ch, &cidr_hash, sz, &cidr_hash.idx); + ipfw_add_table_algo(ch, &iface_idx, sz, &iface_idx.idx); } void -ipfw_table_algo_destroy(struct ip_fw_chain *chain) +ipfw_table_algo_destroy(struct ip_fw_chain *ch) { - /* Do nothing */ + + ipfw_del_table_algo(ch, cidr_radix.idx); + ipfw_del_table_algo(ch, cidr_hash.idx); + ipfw_del_table_algo(ch, iface_idx.idx); }