Acked-by: Ethan Jackson <et...@nicira.com>
On Thu, Sep 12, 2013 at 12:39 AM, Ben Pfaff <b...@nicira.com> wrote: > The long lists of parameters for all these "collect" functions was starting > to get to me. This reduces the number of such functions to one. > > Signed-off-by: Ben Pfaff <b...@nicira.com> > --- > ofproto/ofproto.c | 205 > +++++++++++++++++++++++++++++++++-------------------- > 1 file changed, 130 insertions(+), 75 deletions(-) > > diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c > index 4ab6e1b..98a0752 100644 > --- a/ofproto/ofproto.c > +++ b/ofproto/ofproto.c > @@ -190,6 +190,38 @@ static uint32_t rule_eviction_priority(struct rule *); > static void eviction_group_add_rule(struct rule *); > static void eviction_group_remove_rule(struct rule *); > > +/* Criteria that flow_mod and other operations use for selecting rules on > + * which to operate. */ > +struct rule_criteria { > + /* An OpenFlow table or 255 for all tables. */ > + uint8_t table_id; > + > + /* OpenFlow matching criteria. Interpreted different in "loose" way by > + * collect_rules_loose() and "strict" way by collect_rules_strict(), as > + * defined in the OpenFlow spec. */ > + struct cls_rule cr; > + > + /* Matching criteria for the OpenFlow cookie. Consider a bit B in a > rule's > + * cookie and the corresponding bits C in 'cookie' and M in > 'cookie_mask'. > + * The rule will not be selected if M is 1 and B != C. */ > + ovs_be64 cookie; > + ovs_be64 cookie_mask; > + > + /* Selection based on actions within a rule: > + * > + * If out_port != OFPP_ANY, selects only rules that output to out_port. > + * If out_group != OFPG_ALL, select only rules that output to out_group. > */ > + ofp_port_t out_port; > + uint32_t out_group; > +}; > + > +static void rule_criteria_init(struct rule_criteria *, uint8_t table_id, > + const struct match *match, > + unsigned int priority, > + ovs_be64 cookie, ovs_be64 cookie_mask, > + ofp_port_t out_port, uint32_t out_group); > +static void rule_criteria_destroy(struct rule_criteria *); > + > /* ofport. */ > static void ofport_destroy__(struct ofport *); > static void ofport_destroy(struct ofport *); > @@ -2935,79 +2967,94 @@ next_matching_table(const struct ofproto *ofproto, > (TABLE) != NULL; \ > (TABLE) = next_matching_table(OFPROTO, TABLE, TABLE_ID)) > > +/* Initializes 'criteria' in a straightforward way based on the other > + * parameters. > + * > + * For "loose" matching, the 'priority' parameter is unimportant and may be > + * supplied as 0. */ > +static void > +rule_criteria_init(struct rule_criteria *criteria, uint8_t table_id, > + const struct match *match, unsigned int priority, > + ovs_be64 cookie, ovs_be64 cookie_mask, > + ofp_port_t out_port, uint32_t out_group) > +{ > + criteria->table_id = table_id; > + cls_rule_init(&criteria->cr, match, priority); > + criteria->cookie = cookie; > + criteria->cookie_mask = cookie_mask; > + criteria->out_port = out_port; > + criteria->out_group = out_group; > +} > + > +static void > +rule_criteria_destroy(struct rule_criteria *criteria) > +{ > + cls_rule_destroy(&criteria->cr); > +} > + > 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) > +collect_rule(struct rule *rule, const struct rule_criteria *c, > + 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)) { > + if ((c->table_id == rule->table_id || c->table_id == 0xff) > + && ofproto_rule_has_out_port(rule, c->out_port) > + && ofproto_rule_has_out_group(rule, c->out_group) > + && !((rule->flow_cookie ^ c->cookie) & c->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 > +/* Searches 'ofproto' for rules that match the criteria in 'criteria'. > Matches > + * on classifiers rules are done in the "loose" way required for OpenFlow > + * OFPFC_MODIFY and OFPFC_DELETE requests. Puts the selected rules on list > * 'rules'. > * > - * If 'out_port' is anything other than OFPP_ANY, then only rules that output > - * to 'out_port' are included. > - * > * Hidden rules are always omitted. > * > * Returns 0 on success, otherwise an OpenFlow error code. */ > static enum ofperr > -collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, > - const struct match *match, > - ovs_be64 cookie, ovs_be64 cookie_mask, > - ofp_port_t out_port, uint32_t out_group, > - struct list *rules) > +collect_rules_loose(struct ofproto *ofproto, > + const struct rule_criteria *criteria, struct list *rules) > { > struct oftable *table; > - struct cls_rule cr; > enum ofperr error; > > - error = check_table_id(ofproto, table_id); > + error = check_table_id(ofproto, criteria->table_id); > if (error) { > return error; > } > > list_init(rules); > - cls_rule_init(&cr, match, 0); > > - if (cookie_mask == htonll(UINT64_MAX)) { > + if (criteria->cookie_mask == htonll(UINT64_MAX)) { > struct rule *rule; > > - HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie), > + HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, > + hash_cookie(criteria->cookie), > &ofproto->cookies) { > - if (cls_rule_is_loose_match(&rule->cr, &cr.match)) { > - error = collect_rule(rule, table_id, cookie, cookie_mask, > - out_port, out_group, rules); > + if (cls_rule_is_loose_match(&rule->cr, &criteria->cr.match)) { > + error = collect_rule(rule, criteria, rules); > if (error) { > break; > } > } > } > } else { > - FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) { > + FOR_EACH_MATCHING_TABLE (table, criteria->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_init(&cursor, &table->cls, &criteria->cr); > CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { > - error = collect_rule(rule, table_id, cookie, cookie_mask, > - out_port, out_group, rules); > + error = collect_rule(rule, criteria, rules); > if (error) { > break; > } > @@ -3016,64 +3063,54 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t > table_id, > } > } > > - cls_rule_destroy(&cr); > return error; > } > > -/* Searches 'ofproto' for rules in table 'table_id' (or in all tables, if > - * 'table_id' is 0xff) that match 'match' in the "strict" way required for > - * OpenFlow OFPFC_MODIFY_STRICT and OFPFC_DELETE_STRICT requests and puts > them > - * on list 'rules'. > - * > - * If 'out_port' is anything other than OFPP_ANY, then only rules that output > - * to 'out_port' are included. > +/* Searches 'ofproto' for rules that match the criteria in 'criteria'. > Matches > + * on classifiers rules are done in the "strict" way required for OpenFlow > + * OFPFC_MODIFY_STRICT and OFPFC_DELETE_STRICT requests. Puts the selected > + * rules on list 'rules'. > * > * Hidden rules are always omitted. > * > * Returns 0 on success, otherwise an OpenFlow error code. */ > static enum ofperr > -collect_rules_strict(struct ofproto *ofproto, uint8_t table_id, > - const struct match *match, unsigned int priority, > - ovs_be64 cookie, ovs_be64 cookie_mask, > - ofp_port_t out_port, uint32_t out_group, > - struct list *rules) > +collect_rules_strict(struct ofproto *ofproto, > + const struct rule_criteria *criteria, struct list > *rules) > { > struct oftable *table; > - struct cls_rule cr; > int error; > > - error = check_table_id(ofproto, table_id); > + error = check_table_id(ofproto, criteria->table_id); > if (error) { > return error; > } > > list_init(rules); > - cls_rule_init(&cr, match, priority); > > - if (cookie_mask == htonll(UINT64_MAX)) { > + if (criteria->cookie_mask == htonll(UINT64_MAX)) { > struct rule *rule; > > - HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie), > + HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, > + hash_cookie(criteria->cookie), > &ofproto->cookies) { > - if (cls_rule_equal(&rule->cr, &cr)) { > - error = collect_rule(rule, table_id, cookie, cookie_mask, > - out_port, out_group, rules); > + if (cls_rule_equal(&rule->cr, &criteria->cr)) { > + error = collect_rule(rule, criteria, rules); > if (error) { > break; > } > } > } > } else { > - FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) { > + FOR_EACH_MATCHING_TABLE (table, criteria->table_id, ofproto) { > struct rule *rule; > > ovs_rwlock_rdlock(&table->cls.rwlock); > - rule = > rule_from_cls_rule(classifier_find_rule_exactly(&table->cls, > - &cr)); > + rule = rule_from_cls_rule(classifier_find_rule_exactly( > + &table->cls, &criteria->cr)); > ovs_rwlock_unlock(&table->cls.rwlock); > if (rule) { > - error = collect_rule(rule, table_id, cookie, cookie_mask, > - out_port, out_group, rules); > + error = collect_rule(rule, criteria, rules); > if (error) { > break; > } > @@ -3081,7 +3118,6 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t > table_id, > } > } > > - cls_rule_destroy(&cr); > return error; > } > > @@ -3101,6 +3137,7 @@ handle_flow_stats_request(struct ofconn *ofconn, > { > struct ofproto *ofproto = ofconn_get_ofproto(ofconn); > struct ofputil_flow_stats_request fsr; > + struct rule_criteria criteria; > struct list replies; > struct list rules; > struct rule *rule; > @@ -3111,9 +3148,10 @@ handle_flow_stats_request(struct ofconn *ofconn, > return error; > } > > - error = collect_rules_loose(ofproto, fsr.table_id, &fsr.match, > - fsr.cookie, fsr.cookie_mask, > - fsr.out_port, fsr.out_group, &rules); > + rule_criteria_init(&criteria, fsr.table_id, &fsr.match, 0, fsr.cookie, > + fsr.cookie_mask, fsr.out_port, fsr.out_group); > + error = collect_rules_loose(ofproto, &criteria, &rules); > + rule_criteria_destroy(&criteria); > if (error) { > return error; > } > @@ -3224,6 +3262,7 @@ handle_aggregate_stats_request(struct ofconn *ofconn, > struct ofputil_flow_stats_request request; > struct ofputil_aggregate_stats stats; > bool unknown_packets, unknown_bytes; > + struct rule_criteria criteria; > struct ofpbuf *reply; > struct list rules; > struct rule *rule; > @@ -3234,9 +3273,11 @@ handle_aggregate_stats_request(struct ofconn *ofconn, > return error; > } > > - error = collect_rules_loose(ofproto, request.table_id, &request.match, > - request.cookie, request.cookie_mask, > - request.out_port, request.out_group, &rules); > + rule_criteria_init(&criteria, request.table_id, &request.match, 0, > + request.cookie, request.cookie_mask, > + request.out_port, request.out_group); > + error = collect_rules_loose(ofproto, &criteria, &rules); > + rule_criteria_destroy(&criteria); > if (error) { > return error; > } > @@ -3698,12 +3739,15 @@ modify_flows_loose(struct ofproto *ofproto, struct > ofconn *ofconn, > struct ofputil_flow_mod *fm, > const struct ofp_header *request) > { > + struct rule_criteria criteria; > struct list rules; > int error; > > - error = collect_rules_loose(ofproto, fm->table_id, &fm->match, > - fm->cookie, fm->cookie_mask, > - OFPP_ANY, OFPG11_ANY, &rules); > + rule_criteria_init(&criteria, fm->table_id, &fm->match, 0, > + fm->cookie, fm->cookie_mask, OFPP_ANY, OFPG11_ANY); > + error = collect_rules_loose(ofproto, &criteria, &rules); > + rule_criteria_destroy(&criteria); > + > if (error) { > return error; > } else if (list_is_empty(&rules)) { > @@ -3723,12 +3767,15 @@ modify_flow_strict(struct ofproto *ofproto, struct > ofconn *ofconn, > struct ofputil_flow_mod *fm, > const struct ofp_header *request) > { > + struct rule_criteria criteria; > struct list rules; > int error; > > - error = collect_rules_strict(ofproto, fm->table_id, &fm->match, > - fm->priority, fm->cookie, fm->cookie_mask, > - OFPP_ANY, OFPG11_ANY, &rules); > + rule_criteria_init(&criteria, fm->table_id, &fm->match, fm->priority, > + fm->cookie, fm->cookie_mask, OFPP_ANY, OFPG11_ANY); > + error = collect_rules_strict(ofproto, &criteria, &rules); > + rule_criteria_destroy(&criteria); > + > if (error) { > return error; > } else if (list_is_empty(&rules)) { > @@ -3782,12 +3829,16 @@ delete_flows_loose(struct ofproto *ofproto, struct > ofconn *ofconn, > const struct ofputil_flow_mod *fm, > const struct ofp_header *request) > { > + struct rule_criteria criteria; > struct list rules; > enum ofperr error; > > - error = collect_rules_loose(ofproto, fm->table_id, &fm->match, > - fm->cookie, fm->cookie_mask, > - fm->out_port, fm->out_group, &rules); > + rule_criteria_init(&criteria, fm->table_id, &fm->match, 0, > + fm->cookie, fm->cookie_mask, > + fm->out_port, fm->out_group); > + error = collect_rules_loose(ofproto, &criteria, &rules); > + rule_criteria_destroy(&criteria); > + > return (error ? error > : !list_is_empty(&rules) ? delete_flows__(ofproto, ofconn, > request, > &rules, OFPRR_DELETE) > @@ -3800,12 +3851,16 @@ delete_flow_strict(struct ofproto *ofproto, struct > ofconn *ofconn, > const struct ofputil_flow_mod *fm, > const struct ofp_header *request) > { > + struct rule_criteria criteria; > struct list rules; > enum ofperr error; > > - error = collect_rules_strict(ofproto, fm->table_id, &fm->match, > - fm->priority, fm->cookie, fm->cookie_mask, > - fm->out_port, fm->out_group, &rules); > + rule_criteria_init(&criteria, fm->table_id, &fm->match, fm->priority, > + fm->cookie, fm->cookie_mask, > + fm->out_port, fm->out_group); > + error = collect_rules_strict(ofproto, &criteria, &rules); > + rule_criteria_destroy(&criteria); > + > return (error ? error > : list_is_singleton(&rules) ? delete_flows__(ofproto, ofconn, > request, &rules, > -- > 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