svn commit: r273035 - in head/sys: netinet netpfil/ipfw

Alexander V. Chernikov melifaro at FreeBSD.org
Mon Oct 13 13:49:29 UTC 2014


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) {


More information about the svn-src-all mailing list