* Use 2 32-bits field inside rule instead of 2 pointer to save skipto state.
* Introduce ipfw_reap_add() to unify unlinking rules/adding it to reap queue * Unbreak FreeBSD7 export format.
This commit is contained in:
parent
720ee730c6
commit
030b184f10
@ -810,8 +810,8 @@ jump_fast(struct ip_fw_chain *chain, struct ip_fw *f, int num,
|
||||
* whose version is written in f->next_rule
|
||||
* (horrible hacks to avoid changing the ABI).
|
||||
*/
|
||||
if (num != IP_FW_TABLEARG && (uintptr_t)f->x_next == chain->id)
|
||||
f_pos = (uintptr_t)f->next_rule;
|
||||
if (num != IP_FW_TABLEARG && f->cached_id == chain->id)
|
||||
f_pos = f->cached_pos;
|
||||
else {
|
||||
int i = IP_FW_ARG_TABLEARG(num);
|
||||
/* make sure we do not jump backward */
|
||||
@ -823,8 +823,8 @@ jump_fast(struct ip_fw_chain *chain, struct ip_fw *f, int num,
|
||||
f_pos = ipfw_find_rule(chain, i, 0);
|
||||
/* update the cache */
|
||||
if (num != IP_FW_TABLEARG) {
|
||||
f->next_rule = (void *)(uintptr_t)f_pos;
|
||||
f->x_next = (void *)(uintptr_t)chain->id;
|
||||
f->cached_id = chain->id;
|
||||
f->cached_pos = f_pos;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2746,7 +2746,7 @@ vnet_ipfw_init(const void *unused)
|
||||
static int
|
||||
vnet_ipfw_uninit(const void *unused)
|
||||
{
|
||||
struct ip_fw *reap, *rule;
|
||||
struct ip_fw *reap;
|
||||
struct ip_fw_chain *chain = &V_layer3_chain;
|
||||
int i;
|
||||
|
||||
@ -2768,11 +2768,8 @@ vnet_ipfw_uninit(const void *unused)
|
||||
|
||||
reap = NULL;
|
||||
IPFW_WLOCK(chain);
|
||||
for (i = 0; i < chain->n_rules; i++) {
|
||||
rule = chain->map[i];
|
||||
rule->x_next = reap;
|
||||
reap = rule;
|
||||
}
|
||||
for (i = 0; i < chain->n_rules; i++)
|
||||
ipfw_reap_add(chain, &reap, chain->map[i]);
|
||||
free(chain->map, M_IPFW);
|
||||
ipfw_destroy_skipto_cache(chain);
|
||||
IPFW_WUNLOCK(chain);
|
||||
|
@ -251,8 +251,8 @@ struct ip_fw {
|
||||
counter_u64_t cntr; /* Pointer to rule counters */
|
||||
uint32_t timestamp; /* tv_sec of last match */
|
||||
uint32_t id; /* rule id */
|
||||
struct ip_fw *x_next; /* linked list of rules */
|
||||
struct ip_fw *next_rule; /* ptr to next [skipto] rule */
|
||||
uint32_t cached_id; /* used by jump_fast */
|
||||
uint32_t cached_pos; /* used by jump_fast */
|
||||
|
||||
ipfw_insn cmd[1]; /* storage for commands */
|
||||
};
|
||||
@ -502,6 +502,8 @@ void ipfw_destroy_skipto_cache(struct ip_fw_chain *chain);
|
||||
int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
|
||||
int ipfw_ctl3(struct sockopt *sopt);
|
||||
int ipfw_chk(struct ip_fw_args *args);
|
||||
void ipfw_reap_add(struct ip_fw_chain *chain, struct ip_fw **head,
|
||||
struct ip_fw *rule);
|
||||
void ipfw_reap_rules(struct ip_fw *head);
|
||||
void ipfw_init_counters(void);
|
||||
void ipfw_destroy_counters(void);
|
||||
|
@ -667,6 +667,23 @@ commit_rules(struct ip_fw_chain *chain, struct rule_check_info *rci, int count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds @rule to the list of rules to reap
|
||||
*/
|
||||
void
|
||||
ipfw_reap_add(struct ip_fw_chain *chain, struct ip_fw **head,
|
||||
struct ip_fw *rule)
|
||||
{
|
||||
|
||||
IPFW_UH_WLOCK_ASSERT(chain);
|
||||
|
||||
/* Unlink rule from everywhere */
|
||||
ipfw_unbind_table_rule(chain, rule);
|
||||
|
||||
*((struct ip_fw **)rule) = *head;
|
||||
*head = rule;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim storage associated with a list of rules. This is
|
||||
* typically the list created using remove_rule.
|
||||
@ -678,7 +695,7 @@ ipfw_reap_rules(struct ip_fw *head)
|
||||
struct ip_fw *rule;
|
||||
|
||||
while ((rule = head) != NULL) {
|
||||
head = head->x_next;
|
||||
head = *((struct ip_fw **)head);
|
||||
free_rule(rule);
|
||||
}
|
||||
}
|
||||
@ -796,12 +813,10 @@ delete_range(struct ip_fw_chain *chain, ipfw_range_tlv *rt, int *ndel)
|
||||
if (ipfw_match_range(rule, rt) == 0)
|
||||
continue;
|
||||
chain->static_len -= RULEUSIZE0(rule);
|
||||
rule->x_next = reap;
|
||||
reap = rule;
|
||||
ipfw_reap_add(chain, &reap, rule);
|
||||
}
|
||||
|
||||
ipfw_unbind_table_list(chain, reap);
|
||||
IPFW_UH_WUNLOCK(chain);
|
||||
|
||||
ipfw_reap_rules(reap);
|
||||
if (map != NULL)
|
||||
free(map, M_IPFW);
|
||||
@ -2779,7 +2794,7 @@ convert_rule_to_7(struct ip_fw_rule0 *rule)
|
||||
/* Used to modify original rule */
|
||||
struct ip_fw7 *rule7 = (struct ip_fw7 *)rule;
|
||||
/* copy of original rule, version 8 */
|
||||
struct ip_fw *tmp;
|
||||
struct ip_fw_rule0 *tmp;
|
||||
|
||||
/* Used to copy commands */
|
||||
ipfw_insn *ccmd, *dst;
|
||||
@ -2798,9 +2813,10 @@ convert_rule_to_7(struct ip_fw_rule0 *rule)
|
||||
rule7->cmd_len = tmp->cmd_len;
|
||||
rule7->act_ofs = tmp->act_ofs;
|
||||
rule7->next_rule = (struct ip_fw7 *)tmp->next_rule;
|
||||
rule7->next = (struct ip_fw7 *)tmp->x_next;
|
||||
rule7->cmd_len = tmp->cmd_len;
|
||||
export_cntr1_base(tmp, (struct ip_fw_bcounter *)&rule7->pcnt);
|
||||
rule7->pcnt = tmp->pcnt;
|
||||
rule7->bcnt = tmp->bcnt;
|
||||
rule7->timestamp = tmp->timestamp;
|
||||
|
||||
/* Copy commands */
|
||||
for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule7->cmd ;
|
||||
@ -2869,7 +2885,6 @@ convert_rule_to_8(struct ip_fw_rule0 *rule)
|
||||
rule->cmd_len = tmp->cmd_len;
|
||||
rule->act_ofs = tmp->act_ofs;
|
||||
rule->next_rule = (struct ip_fw *)tmp->next_rule;
|
||||
rule->x_next = (struct ip_fw *)tmp->next;
|
||||
rule->cmd_len = tmp->cmd_len;
|
||||
rule->id = 0; /* XXX see if is ok = 0 */
|
||||
rule->pcnt = tmp->pcnt;
|
||||
|
@ -2909,6 +2909,7 @@ ipfw_unbind_table_rule(struct ip_fw_chain *chain, struct ip_fw *rule)
|
||||
uint16_t kidx;
|
||||
uint8_t type;
|
||||
|
||||
IPFW_UH_WLOCK_ASSERT(chain);
|
||||
ni = CHAIN_TO_NI(chain);
|
||||
|
||||
l = rule->cmd_len;
|
||||
@ -2932,20 +2933,4 @@ ipfw_unbind_table_rule(struct ip_fw_chain *chain, struct ip_fw *rule)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Removes table bindings for every rule in rule chain @head.
|
||||
*/
|
||||
void
|
||||
ipfw_unbind_table_list(struct ip_fw_chain *chain, struct ip_fw *head)
|
||||
{
|
||||
struct ip_fw *rule;
|
||||
|
||||
while ((rule = head) != NULL) {
|
||||
head = head->x_next;
|
||||
ipfw_unbind_table_rule(chain, rule);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
@ -171,7 +171,6 @@ int ipfw_mark_table_kidx(struct ip_fw_chain *chain, struct ip_fw *rule,
|
||||
int ipfw_export_table_ntlv(struct ip_fw_chain *ch, uint16_t kidx,
|
||||
struct sockopt_data *sd);
|
||||
void ipfw_unbind_table_rule(struct ip_fw_chain *chain, struct ip_fw *rule);
|
||||
void ipfw_unbind_table_list(struct ip_fw_chain *chain, struct ip_fw *head);
|
||||
|
||||
/* utility functions */
|
||||
int ipfw_check_table_name(char *name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user