Author: ae
Date: Wed Mar  1 20:00:19 2017
New Revision: 314507
URL: https://svnweb.freebsd.org/changeset/base/314507

Log:
  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

Modified:
  head/sys/netpfil/ipfw/ip_fw2.c
  head/sys/netpfil/ipfw/nptv6/nptv6.c

Modified: head/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw2.c      Wed Mar  1 19:55:04 2017        
(r314506)
+++ head/sys/netpfil/ipfw/ip_fw2.c      Wed Mar  1 20:00:19 2017        
(r314507)
@@ -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:

Modified: head/sys/netpfil/ipfw/nptv6/nptv6.c
==============================================================================
--- head/sys/netpfil/ipfw/nptv6/nptv6.c Wed Mar  1 19:55:04 2017        
(r314506)
+++ head/sys/netpfil/ipfw/nptv6/nptv6.c Wed Mar  1 20:00:19 2017        
(r314507)
@@ -352,24 +352,24 @@ ipfw_nptv6(struct ip_fw_chain *chain, st
        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, st
                 */
                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, st
                        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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to