Author: melifaro
Date: Mon Oct 13 13:49:28 2014
New Revision: 273035
URL: https://svnweb.freebsd.org/changeset/base/273035

Log:
  Fix matching default rule on clear/show commands.
  
  Found by:     Oleg Ginzburg

Modified:
  head/sys/netinet/ip_fw.h
  head/sys/netpfil/ipfw/ip_fw_sockopt.c

Modified: head/sys/netinet/ip_fw.h
==============================================================================
--- head/sys/netinet/ip_fw.h    Mon Oct 13 13:13:42 2014        (r273034)
+++ head/sys/netinet/ip_fw.h    Mon Oct 13 13:49:28 2014        (r273035)
@@ -886,6 +886,11 @@ typedef struct _ipfw_range_tlv {
 #define        IPFW_RCFLAG_RANGE       0x01    /* rule range is set            
*/
 #define        IPFW_RCFLAG_ALL         0x02    /* match ALL rules              
*/
 #define        IPFW_RCFLAG_SET         0x04    /* match rules in given set     
*/
+/* User-settable flags */
+#define        IPFW_RCFLAG_USER        (IPFW_RCFLAG_RANGE | IPFW_RCFLAG_ALL | \
+       IPFW_RCFLAG_SET)
+/* Internally used flags */
+#define        IPFW_RCFLAG_DEFAULT     0x0100  /* Do not skip defaul rule      
*/
 
 typedef struct _ipfw_ta_tinfo {
        uint32_t        flags;          /* Format flags                 */

Modified: head/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_sockopt.c       Mon Oct 13 13:13:42 2014        
(r273034)
+++ head/sys/netpfil/ipfw/ip_fw_sockopt.c       Mon Oct 13 13:49:28 2014        
(r273035)
@@ -833,8 +833,9 @@ int
 ipfw_match_range(struct ip_fw *rule, ipfw_range_tlv *rt)
 {
 
-       /* Don't match default rule regardless of query */
-       if (rule->rulenum == IPFW_DEFAULT_RULE)
+       /* Don't match default rule for modification queries */
+       if (rule->rulenum == IPFW_DEFAULT_RULE &&
+           (rt->flags & IPFW_RCFLAG_DEFAULT) == 0)
                return (0);
 
        /* Don't match rules in reserved set for flush requests */
@@ -965,7 +966,7 @@ move_range(struct ip_fw_chain *chain, ip
        }
 
        /* XXX: We have to do swap holding WLOCK */
-       for (i = 0; i < chain->n_rules - 1; i++) {
+       for (i = 0; i < chain->n_rules; i++) {
                rule = chain->map[i];
                if (ipfw_match_range(rule, rt) == 0)
                        continue;
@@ -1006,9 +1007,10 @@ clear_range(struct ip_fw_chain *chain, i
        int i;
 
        num = 0;
+       rt->flags |= IPFW_RCFLAG_DEFAULT;
 
        IPFW_UH_WLOCK(chain);   /* arbitrate writers */
-       for (i = 0; i < chain->n_rules - 1; i++) {
+       for (i = 0; i < chain->n_rules; i++) {
                rule = chain->map[i];
                if (ipfw_match_range(rule, rt) == 0)
                        continue;
@@ -1031,6 +1033,9 @@ check_range_tlv(ipfw_range_tlv *rt)
        if (rt->set >= IPFW_MAX_SETS || rt->new_set >= IPFW_MAX_SETS)
                return (1);
 
+       if ((rt->flags & IPFW_RCFLAG_USER) != rt->flags)
+               return (1);
+
        return (0);
 }
 
@@ -2012,7 +2017,7 @@ dump_config(struct ip_fw_chain *chain, i
                da.b = ipfw_find_rule(chain, rnum, 0);
                rnum = hdr->end_rule;
                rnum = (rnum < IPFW_DEFAULT_RULE) ? rnum+1 : IPFW_DEFAULT_RULE;
-               da.e = ipfw_find_rule(chain, rnum, 0);
+               da.e = ipfw_find_rule(chain, rnum, 0) + 1;
        }
 
        if (hdr->flags & IPFW_CFG_GET_STATIC) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to