I'm not sure collect_rule() is a great name for the function, but on
the other hand I'm not sure what I'd call it either.  At any rate I
like how much duplicate code this removes.

Acked-by: Ethan Jackson <et...@nicira.com>


On Tue, Sep 10, 2013 at 10:27 PM, Ben Pfaff <b...@nicira.com> wrote:
> Signed-off-by: Ben Pfaff <b...@nicira.com>
> ---
>  ofproto/ofproto.c |  125 
> +++++++++++++++++++++++------------------------------
>  1 file changed, 55 insertions(+), 70 deletions(-)
>
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index e7ee60e..81b6c43 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -2935,6 +2935,26 @@ next_matching_table(const struct ofproto *ofproto,
>           (TABLE) != NULL;                                         \
>           (TABLE) = next_matching_table(OFPROTO, TABLE, TABLE_ID))
>
> +static enum ofperr
> +collect_rule(struct rule *rule, uint8_t table_id,
> +             ovs_be64 cookie, ovs_be64 cookie_mask,
> +             ofp_port_t out_port, uint32_t out_group, struct list *rules)
> +{
> +    if (ofproto_rule_is_hidden(rule)) {
> +        return 0;
> +    } else if (rule->pending) {
> +        return OFPROTO_POSTPONE;
> +    } else {
> +        if ((table_id == rule->table_id || table_id == 0xff)
> +            && ofproto_rule_has_out_port(rule, out_port)
> +            && ofproto_rule_has_out_group(rule, out_group)
> +            && !((rule->flow_cookie ^ cookie) & cookie_mask)) {
> +            list_push_back(rules, &rule->ofproto_node);
> +        }
> +        return 0;
> +    }
> +}
> +
>  /* Searches 'ofproto' for rules in table 'table_id' (or in all tables, if
>   * 'table_id' is 0xff) that match 'match' in the "loose" way required for
>   * OpenFlow OFPFC_MODIFY and OFPFC_DELETE requests and puts them on list
> @@ -2970,50 +2990,32 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t 
> table_id,
>
>          HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie),
>                                     &ofproto->cookies) {
> -            if (table_id != rule->table_id && table_id != 0xff) {
> -                continue;
> -            }
> -            if (ofproto_rule_is_hidden(rule)) {
> -                continue;
> -            }
>              if (cls_rule_is_loose_match(&rule->cr, &cr.match)) {
> -                if (rule->pending) {
> -                    error = OFPROTO_POSTPONE;
> -                    goto exit;
> -                }
> -                if (rule->flow_cookie == cookie /* Hash collisions possible. 
> */
> -                    && ofproto_rule_has_out_port(rule, out_port)
> -                    && ofproto_rule_has_out_group(rule, out_group)) {
> -                    list_push_back(rules, &rule->ofproto_node);
> +                error = collect_rule(rule, table_id, cookie, cookie_mask,
> +                                     out_port, out_group, rules);
> +                if (error) {
> +                    break;
>                  }
>              }
>          }
> -        goto exit;
> -    }
> -
> -    FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) {
> -        struct cls_cursor cursor;
> -        struct rule *rule;
> +    } else {
> +        FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) {
> +            struct cls_cursor cursor;
> +            struct rule *rule;
>
> -        ovs_rwlock_rdlock(&table->cls.rwlock);
> -        cls_cursor_init(&cursor, &table->cls, &cr);
> -        CLS_CURSOR_FOR_EACH (rule, cr, &cursor) {
> -            if (rule->pending) {
> -                ovs_rwlock_unlock(&table->cls.rwlock);
> -                error = OFPROTO_POSTPONE;
> -                goto exit;
> -            }
> -            if (!ofproto_rule_is_hidden(rule)
> -                && ofproto_rule_has_out_port(rule, out_port)
> -                && ofproto_rule_has_out_group(rule, out_group)
> -                    && !((rule->flow_cookie ^ cookie) & cookie_mask)) {
> -                list_push_back(rules, &rule->ofproto_node);
> +            ovs_rwlock_rdlock(&table->cls.rwlock);
> +            cls_cursor_init(&cursor, &table->cls, &cr);
> +            CLS_CURSOR_FOR_EACH (rule, cr, &cursor) {
> +                error = collect_rule(rule, table_id, cookie, cookie_mask,
> +                                     out_port, out_group, rules);
> +                if (error) {
> +                    break;
> +                }
>              }
> +            ovs_rwlock_unlock(&table->cls.rwlock);
>          }
> -        ovs_rwlock_unlock(&table->cls.rwlock);
>      }
>
> -exit:
>      cls_rule_destroy(&cr);
>      return error;
>  }
> @@ -3053,51 +3055,34 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t 
> table_id,
>
>          HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie),
>                                     &ofproto->cookies) {
> -            if (table_id != rule->table_id && table_id != 0xff) {
> -                continue;
> -            }
> -            if (ofproto_rule_is_hidden(rule)) {
> -                continue;
> -            }
>              if (cls_rule_equal(&rule->cr, &cr)) {
> -                if (rule->pending) {
> -                    error = OFPROTO_POSTPONE;
> -                    goto exit;
> -                }
> -                if (rule->flow_cookie == cookie /* Hash collisions possible. 
> */
> -                    && ofproto_rule_has_out_port(rule, out_port)
> -                    && ofproto_rule_has_out_group(rule, out_group)) {
> -                    list_push_back(rules, &rule->ofproto_node);
> +                error = collect_rule(rule, table_id, cookie, cookie_mask,
> +                                     out_port, out_group, rules);
> +                if (error) {
> +                    break;
>                  }
>              }
>          }
> -        goto exit;
> -    }
> -
> -    FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) {
> -        struct rule *rule;
> +    } else {
> +        FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) {
> +            struct rule *rule;
>
> -        ovs_rwlock_rdlock(&table->cls.rwlock);
> -        rule = rule_from_cls_rule(classifier_find_rule_exactly(&table->cls,
> -                                                               &cr));
> -        ovs_rwlock_unlock(&table->cls.rwlock);
> -        if (rule) {
> -            if (rule->pending) {
> -                error = OFPROTO_POSTPONE;
> -                goto exit;
> -            }
> -            if (!ofproto_rule_is_hidden(rule)
> -                && ofproto_rule_has_out_port(rule, out_port)
> -                && ofproto_rule_has_out_group(rule, out_group)
> -                    && !((rule->flow_cookie ^ cookie) & cookie_mask)) {
> -                list_push_back(rules, &rule->ofproto_node);
> +            ovs_rwlock_rdlock(&table->cls.rwlock);
> +            rule = 
> rule_from_cls_rule(classifier_find_rule_exactly(&table->cls,
> +                                                                   &cr));
> +            ovs_rwlock_unlock(&table->cls.rwlock);
> +            if (rule) {
> +                error = collect_rule(rule, table_id, cookie, cookie_mask,
> +                                     out_port, out_group, rules);
> +                if (error) {
> +                    break;
> +                }
>              }
>          }
>      }
>
> -exit:
>      cls_rule_destroy(&cr);
> -    return 0;
> +    return error;
>  }
>
>  /* Returns 'age_ms' (a duration in milliseconds), converted to seconds and
> --
> 1.7.10.4
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to