Fix NPTv6 rule counters when one_pass is not enabled.

Consider the rule matching when both @done and @retval values
returned from ipfw_run_eaction() are zero. And modify ipfw_nptv6()
to return IP_FW_DENY and @done=0 when addresses do not match.

Obtained from:	Yandex LLC
Sponsored by:	Yandex LLC
This commit is contained in:
ae 2017-03-01 20:00:19 +00:00
parent 10eed1ae8d
commit 36064af69a
2 changed files with 23 additions and 14 deletions

View File

@ -2565,6 +2565,13 @@ do { \
l = 0; /* in any case exit inner loop */
retval = ipfw_run_eaction(chain, args,
cmd, &done);
/*
* If both @retval and @done are zero,
* consider this as rule matching and
* update counters.
*/
if (retval == 0 && done == 0)
IPFW_INC_RULE_COUNTER(f, pktlen);
break;
default:

View File

@ -352,24 +352,24 @@ ipfw_nptv6(struct ip_fw_chain *chain, struct ip_fw_args *args,
int ret;
*done = 0; /* try next rule if not matched */
ret = IP_FW_DENY;
icmd = cmd + 1;
if (cmd->opcode != O_EXTERNAL_ACTION ||
cmd->arg1 != V_nptv6_eid ||
icmd->opcode != O_EXTERNAL_INSTANCE ||
(cfg = NPTV6_LOOKUP(chain, icmd)) == NULL)
return (0);
return (ret);
/*
* We need act as router, so when forwarding is disabled -
* do nothing.
*/
if (V_ip6_forwarding == 0 || args->f_id.addr_type != 6)
return (0);
return (ret);
/*
* NOTE: we expect ipfw_chk() did m_pullup() up to upper level
* protocol's headers. Also we skip some checks, that ip6_input(),
* ip6_forward(), ip6_fastfwd() and ipfw_chk() already did.
*/
ret = IP_FW_DENY;
ip6 = mtod(args->m, struct ip6_hdr *);
NPTV6_IPDEBUG("eid %u, oid %u, %s -> %s %d",
cmd->arg1, icmd->arg1,
@ -384,15 +384,15 @@ ipfw_nptv6(struct ip_fw_chain *chain, struct ip_fw_args *args,
*/
if (IN6_ARE_MASKED_ADDR_EQUAL(&ip6->ip6_dst,
&cfg->internal, &cfg->mask))
return (0);
return (ret);
ret = nptv6_rewrite_internal(cfg, &args->m, 0);
} else if (IN6_ARE_MASKED_ADDR_EQUAL(&ip6->ip6_dst,
&cfg->external, &cfg->mask))
ret = nptv6_rewrite_external(cfg, &args->m, 0);
else
return (0);
return (ret);
/*
* If address wasn't rewrited - free mbuf.
* If address wasn't rewrited - free mbuf and terminate the search.
*/
if (ret != 0) {
if (args->m != NULL) {
@ -400,14 +400,16 @@ ipfw_nptv6(struct ip_fw_chain *chain, struct ip_fw_args *args,
args->m = NULL; /* mark mbuf as consumed */
}
NPTV6STAT_INC(cfg, dropped);
}
/* Terminate the search if one_pass is set */
*done = V_fw_one_pass;
/* Update args->f_id when one_pass is off */
if (*done == 0 && ret == 0) {
ip6 = mtod(args->m, struct ip6_hdr *);
args->f_id.src_ip6 = ip6->ip6_src;
args->f_id.dst_ip6 = ip6->ip6_dst;
*done = 1;
} else {
/* Terminate the search if one_pass is set */
*done = V_fw_one_pass;
/* Update args->f_id when one_pass is off */
if (*done == 0) {
ip6 = mtod(args->m, struct ip6_hdr *);
args->f_id.src_ip6 = ip6->ip6_src;
args->f_id.dst_ip6 = ip6->ip6_dst;
}
}
return (ret);
}