dd ipfw_get_action() function to get the pointer to action opcode.
ACTION_PTR() returns pointer to the start of rule action section, but rule can keep several rule modifiers like O_LOG, O_TAG and O_ALTQ, and only then real action opcode is stored. ipfw_get_action() function inspects the rule action section, skips all modifiers and returns action opcode. Use this function in ipfw_reset_eaction() and flush_nat_ptrs(). MFC after: 1 week Sponsored by: Yandex LLC
This commit is contained in:
parent
52bb6100e9
commit
e758846c09
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=350417
@ -377,33 +377,30 @@ ipfw_reset_eaction(struct ip_fw_chain *ch, struct ip_fw *rule,
|
|||||||
uint16_t eaction_id, uint16_t default_id, uint16_t instance_id)
|
uint16_t eaction_id, uint16_t default_id, uint16_t instance_id)
|
||||||
{
|
{
|
||||||
ipfw_insn *cmd, *icmd;
|
ipfw_insn *cmd, *icmd;
|
||||||
int l, cmdlen;
|
int l;
|
||||||
|
|
||||||
IPFW_UH_WLOCK_ASSERT(ch);
|
IPFW_UH_WLOCK_ASSERT(ch);
|
||||||
IPFW_WLOCK_ASSERT(ch);
|
IPFW_WLOCK_ASSERT(ch);
|
||||||
|
|
||||||
cmd = ACTION_PTR(rule);
|
|
||||||
l = rule->cmd_len - rule->act_ofs;
|
|
||||||
while (l > 0) {
|
|
||||||
cmdlen = F_LEN(cmd);
|
|
||||||
l -= cmdlen;
|
|
||||||
if (cmd->opcode == O_EXTERNAL_ACTION || l <= 0)
|
|
||||||
break;
|
|
||||||
cmd += cmdlen;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Return if there is not O_EXTERNAL_ACTION or its id is
|
* Return if there is not O_EXTERNAL_ACTION or its id is
|
||||||
* different.
|
* different.
|
||||||
*/
|
*/
|
||||||
|
cmd = ipfw_get_action(rule);
|
||||||
if (cmd->opcode != O_EXTERNAL_ACTION ||
|
if (cmd->opcode != O_EXTERNAL_ACTION ||
|
||||||
cmd->arg1 != eaction_id)
|
cmd->arg1 != eaction_id)
|
||||||
return (0);
|
return (0);
|
||||||
/*
|
/*
|
||||||
* If instance_id is specified, we need to truncate the
|
* If instance_id is specified, we need to truncate the
|
||||||
* rule length. Check if there is O_EXTERNAL_INSTANCE opcode.
|
* rule length. Check if there is O_EXTERNAL_INSTANCE opcode.
|
||||||
|
*
|
||||||
|
* NOTE: F_LEN(cmd) must be 1 for O_EXTERNAL_ACTION opcode,
|
||||||
|
* and rule length should be enough to keep O_EXTERNAL_INSTANCE
|
||||||
|
* opcode, thus we do check for l > 1.
|
||||||
*/
|
*/
|
||||||
if (instance_id != 0 && l > 0) {
|
l = rule->cmd + rule->cmd_len - cmd;
|
||||||
MPASS(cmdlen == 1);
|
if (instance_id != 0 && l > 1) {
|
||||||
|
MPASS(F_LEN(cmd) == 1);
|
||||||
icmd = cmd + 1;
|
icmd = cmd + 1;
|
||||||
if (icmd->opcode != O_EXTERNAL_INSTANCE ||
|
if (icmd->opcode != O_EXTERNAL_INSTANCE ||
|
||||||
icmd->arg1 != instance_id)
|
icmd->arg1 != instance_id)
|
||||||
@ -415,8 +412,9 @@ ipfw_reset_eaction(struct ip_fw_chain *ch, struct ip_fw *rule,
|
|||||||
* opcode.
|
* opcode.
|
||||||
*/
|
*/
|
||||||
EACTION_DEBUG("truncate rule %d: len %u -> %u",
|
EACTION_DEBUG("truncate rule %d: len %u -> %u",
|
||||||
rule->rulenum, rule->cmd_len, rule->cmd_len - l);
|
rule->rulenum, rule->cmd_len,
|
||||||
rule->cmd_len -= l;
|
rule->cmd_len - F_LEN(icmd));
|
||||||
|
rule->cmd_len -= F_LEN(icmd);
|
||||||
MPASS(((uint32_t *)icmd -
|
MPASS(((uint32_t *)icmd -
|
||||||
(uint32_t *)rule->cmd) == rule->cmd_len);
|
(uint32_t *)rule->cmd) == rule->cmd_len);
|
||||||
}
|
}
|
||||||
|
@ -140,13 +140,12 @@ ifaddr_change(void *arg __unused, struct ifnet *ifp)
|
|||||||
static void
|
static void
|
||||||
flush_nat_ptrs(struct ip_fw_chain *chain, const int ix)
|
flush_nat_ptrs(struct ip_fw_chain *chain, const int ix)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
ipfw_insn_nat *cmd;
|
ipfw_insn_nat *cmd;
|
||||||
|
int i;
|
||||||
|
|
||||||
IPFW_WLOCK_ASSERT(chain);
|
IPFW_WLOCK_ASSERT(chain);
|
||||||
for (i = 0; i < chain->n_rules; i++) {
|
for (i = 0; i < chain->n_rules; i++) {
|
||||||
cmd = (ipfw_insn_nat *)ACTION_PTR(chain->map[i]);
|
cmd = (ipfw_insn_nat *)ipfw_get_action(chain->map[i]);
|
||||||
/* XXX skip log and the like ? */
|
|
||||||
if (cmd->o.opcode == O_NAT && cmd->nat != NULL &&
|
if (cmd->o.opcode == O_NAT && cmd->nat != NULL &&
|
||||||
(ix < 0 || cmd->nat->id == ix))
|
(ix < 0 || cmd->nat->id == ix))
|
||||||
cmd->nat = NULL;
|
cmd->nat = NULL;
|
||||||
|
@ -665,6 +665,7 @@ struct ip_fw *ipfw_alloc_rule(struct ip_fw_chain *chain, size_t rulesize);
|
|||||||
void ipfw_free_rule(struct ip_fw *rule);
|
void ipfw_free_rule(struct ip_fw *rule);
|
||||||
int ipfw_match_range(struct ip_fw *rule, ipfw_range_tlv *rt);
|
int ipfw_match_range(struct ip_fw *rule, ipfw_range_tlv *rt);
|
||||||
int ipfw_mark_object_kidx(uint32_t *bmask, uint16_t etlv, uint16_t kidx);
|
int ipfw_mark_object_kidx(uint32_t *bmask, uint16_t etlv, uint16_t kidx);
|
||||||
|
ipfw_insn *ipfw_get_action(struct ip_fw *);
|
||||||
|
|
||||||
typedef int (sopt_handler_f)(struct ip_fw_chain *ch,
|
typedef int (sopt_handler_f)(struct ip_fw_chain *ch,
|
||||||
ip_fw3_opheader *op3, struct sockopt_data *sd);
|
ip_fw3_opheader *op3, struct sockopt_data *sd);
|
||||||
|
@ -1217,6 +1217,35 @@ move_range(struct ip_fw_chain *chain, ipfw_range_tlv *rt)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns pointer to action instruction, skips all possible rule
|
||||||
|
* modifiers like O_LOG, O_TAG, O_ALTQ.
|
||||||
|
*/
|
||||||
|
ipfw_insn *
|
||||||
|
ipfw_get_action(struct ip_fw *rule)
|
||||||
|
{
|
||||||
|
ipfw_insn *cmd;
|
||||||
|
int l, cmdlen;
|
||||||
|
|
||||||
|
cmd = ACTION_PTR(rule);
|
||||||
|
l = rule->cmd_len - rule->act_ofs;
|
||||||
|
while (l > 0) {
|
||||||
|
switch (cmd->opcode) {
|
||||||
|
case O_ALTQ:
|
||||||
|
case O_LOG:
|
||||||
|
case O_TAG:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (cmd);
|
||||||
|
}
|
||||||
|
cmdlen = F_LEN(cmd);
|
||||||
|
l -= cmdlen;
|
||||||
|
cmd += cmdlen;
|
||||||
|
}
|
||||||
|
panic("%s: rule (%p) has not action opcode", __func__, rule);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear counters for a specific rule.
|
* Clear counters for a specific rule.
|
||||||
* Normally run under IPFW_UH_RLOCK, but these are idempotent ops
|
* Normally run under IPFW_UH_RLOCK, but these are idempotent ops
|
||||||
|
Loading…
Reference in New Issue
Block a user