Author: luigi
Date: Wed Jun 10 10:34:59 2009
New Revision: 193894
URL: http://svn.freebsd.org/changeset/base/193894

Log:
  small simplifications to the code in charge of reaping deleted rules:
  - clear the head pointer immediately before using it, so there is
    no chance of mistakes;
  - call reap_rules() unconditionally. The function can handle a NULL
    argument just fine, and the cost of the extra call is hardly
    significant given that we do it rarely and outside the lock.
  
  MFC after:    3 days

Modified:
  head/sys/netinet/ipfw/ip_fw2.c

Modified: head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw2.c      Wed Jun 10 10:31:11 2009        
(r193893)
+++ head/sys/netinet/ipfw/ip_fw2.c      Wed Jun 10 10:34:59 2009        
(r193894)
@@ -3631,6 +3631,7 @@ remove_rule(struct ip_fw_chain *chain, s
 /*
  * Reclaim storage associated with a list of rules.  This is
  * typically the list created using remove_rule.
+ * A NULL pointer on input is handled correctly.
  */
 static void
 reap_rules(struct ip_fw *head)
@@ -3655,6 +3656,7 @@ free_chain(struct ip_fw_chain *chain, in
 
        IPFW_WLOCK_ASSERT(chain);
 
+       chain->reap = NULL;
        flush_rule_ptrs(chain); /* more efficient to do outside the loop */
        for (prev = NULL, rule = chain->rules; rule ; )
                if (kill_default || rule->set != RESVD_SET)
@@ -3701,8 +3703,8 @@ del_entry(struct ip_fw_chain *chain, u_i
        }
 
        IPFW_WLOCK(chain);
-       rule = chain->rules;
-       chain->reap = NULL;
+       rule = chain->rules;    /* common starting point */
+       chain->reap = NULL;     /* prepare for deletions */
        switch (cmd) {
        case 0: /* delete rules with given number */
                /*
@@ -3726,18 +3728,17 @@ del_entry(struct ip_fw_chain *chain, u_i
 
        case 1: /* delete all rules with given set number */
                flush_rule_ptrs(chain);
-               rule = chain->rules;
-               while (rule->rulenum < IPFW_DEFAULT_RULE)
+               while (rule->rulenum < IPFW_DEFAULT_RULE) {
                        if (rule->set == rulenum)
                                rule = remove_rule(chain, rule, prev);
                        else {
                                prev = rule;
                                rule = rule->next;
                        }
+               }
                break;
 
        case 2: /* move rules with given number to new set */
-               rule = chain->rules;
                for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
                        if (rule->rulenum == rulenum)
                                rule->set = new_set;
@@ -3756,6 +3757,7 @@ del_entry(struct ip_fw_chain *chain, u_i
                        else if (rule->set == new_set)
                                rule->set = rulenum;
                break;
+
        case 5: /* delete rules with given number and with given set number.
                 * rulenum - given rule number;
                 * new_set - given set number.
@@ -3782,10 +3784,8 @@ del_entry(struct ip_fw_chain *chain, u_i
         * avoid a LOR with dummynet.
         */
        rule = chain->reap;
-       chain->reap = NULL;
        IPFW_WUNLOCK(chain);
-       if (rule)
-               reap_rules(rule);
+       reap_rules(rule);
        return 0;
 }
 
@@ -4315,6 +4315,8 @@ ipfw_ctl(struct sockopt *sopt)
                if (V_ipfw_dyn_v)               /* add size of dyn.rules */
                        size += (V_dyn_count * sizeof(ipfw_dyn_rule));
 
+               if (size >= sopt->sopt_valsize)
+                       break;
                /*
                 * XXX todo: if the user passes a short length just to know
                 * how much room is needed, do not bother filling up the
@@ -4341,13 +4343,10 @@ ipfw_ctl(struct sockopt *sopt)
                 */
 
                IPFW_WLOCK(&V_layer3_chain);
-               V_layer3_chain.reap = NULL;
                free_chain(&V_layer3_chain, 0 /* keep default rule */);
                rule = V_layer3_chain.reap;
-               V_layer3_chain.reap = NULL;
                IPFW_WUNLOCK(&V_layer3_chain);
-               if (rule != NULL)
-                       reap_rules(rule);
+               reap_rules(rule);
                break;
 
        case IP_FW_ADD:
@@ -4735,12 +4734,10 @@ ipfw_destroy(void)
        callout_drain(&V_ipfw_timeout);
        IPFW_WLOCK(&V_layer3_chain);
        flush_tables(&V_layer3_chain);
-       V_layer3_chain.reap = NULL;
        free_chain(&V_layer3_chain, 1 /* kill default rule */);
-       reap = V_layer3_chain.reap, V_layer3_chain.reap = NULL;
+       reap = V_layer3_chain.reap;
        IPFW_WUNLOCK(&V_layer3_chain);
-       if (reap != NULL)
-               reap_rules(reap);
+       reap_rules(reap);
        IPFW_DYN_LOCK_DESTROY();
        uma_zdestroy(ipfw_dyn_rule_zone);
        if (V_ipfw_dyn_v != NULL)
_______________________________________________
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