ofproto internally modifies 'modify_cookie' field, and adding a replica to ofproto_flow_mod allows the ofputil_flow_mod argument to be changed to a const.
Signed-off-by: Jarno Rajahalme <ja...@ovn.org> --- ofproto/ofproto-dpif.c | 27 +++++++++------------------ ofproto/ofproto-provider.h | 3 ++- ofproto/ofproto.c | 36 +++++++++++++++++++----------------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index aa933b1..fd2c2bd 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -362,16 +362,7 @@ void ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto, const struct ofputil_flow_mod *fm) { - struct ofproto_flow_mod ofm; - - /* Multiple threads may do this for the same 'fm' at the same time. - * Allocate ofproto_flow_mod with execution context from stack. - * - * Note: This copy could be avoided by making ofproto_flow_mod more - * complex, but that may not be desireable, and a learn action is not that - * fast to begin with. */ - ofm.fm = *fm; - ofproto_flow_mod(&ofproto->up, &ofm); + ofproto_flow_mod(&ofproto->up, fm); } /* Appends 'am' to the queue of asynchronous messages to be sent to the @@ -5546,11 +5537,11 @@ ofproto_dpif_add_internal_flow(struct ofproto_dpif *ofproto, const struct ofpbuf *ofpacts, struct rule **rulep) { - struct ofproto_flow_mod ofm; + struct ofputil_flow_mod fm; struct rule_dpif *rule; int error; - ofm.fm = (struct ofputil_flow_mod) { + fm = (struct ofputil_flow_mod) { .match = *match, .priority = priority, .table_id = TBL_INTERNAL, @@ -5561,7 +5552,7 @@ ofproto_dpif_add_internal_flow(struct ofproto_dpif *ofproto, .ofpacts_len = ofpacts->size, }; - error = ofproto_flow_mod(&ofproto->up, &ofm); + error = ofproto_flow_mod(&ofproto->up, &fm); if (error) { VLOG_ERR_RL(&rl, "failed to add internal flow (%s)", ofperr_to_string(error)); @@ -5571,8 +5562,8 @@ ofproto_dpif_add_internal_flow(struct ofproto_dpif *ofproto, rule = rule_dpif_lookup_in_table(ofproto, ofproto_dpif_get_tables_version(ofproto), - TBL_INTERNAL, &ofm.fm.match.flow, - &ofm.fm.match.wc); + TBL_INTERNAL, &fm.match.flow, + &fm.match.wc); if (rule) { *rulep = &rule->up; } else { @@ -5585,10 +5576,10 @@ int ofproto_dpif_delete_internal_flow(struct ofproto_dpif *ofproto, struct match *match, int priority) { - struct ofproto_flow_mod ofm; + struct ofputil_flow_mod fm; int error; - ofm.fm = (struct ofputil_flow_mod) { + fm = (struct ofputil_flow_mod) { .match = *match, .priority = priority, .table_id = TBL_INTERNAL, @@ -5596,7 +5587,7 @@ ofproto_dpif_delete_internal_flow(struct ofproto_dpif *ofproto, .command = OFPFC_DELETE_STRICT, }; - error = ofproto_flow_mod(&ofproto->up, &ofm); + error = ofproto_flow_mod(&ofproto->up, &fm); if (error) { VLOG_ERR_RL(&rl, "failed to delete internal flow (%s)", ofperr_to_string(error)); diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index fb5fc95..f328b4a 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -1911,6 +1911,7 @@ struct ofproto_flow_mod { /* Replicate needed fields from ofputil_flow_mod to not need it after the * flow has been created. */ uint32_t buffer_id; + bool modify_cookie; bool modify_may_add_flow; enum nx_flow_update_event event; @@ -1937,7 +1938,7 @@ struct ofproto_group_mod { struct group_collection old_groups; /* Affected groups. */ }; -enum ofperr ofproto_flow_mod(struct ofproto *, struct ofproto_flow_mod *) +enum ofperr ofproto_flow_mod(struct ofproto *, const struct ofputil_flow_mod *) OVS_EXCLUDED(ofproto_mutex); void ofproto_add_flow(struct ofproto *, const struct match *, int priority, const struct ofpact *ofpacts, size_t ofpacts_len) diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 853b2a3..47020b8 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -305,7 +305,7 @@ static void ofproto_flow_mod_finish(struct ofproto *, const struct openflow_mod_requester *) OVS_REQUIRES(ofproto_mutex); static enum ofperr handle_flow_mod__(struct ofproto *, - struct ofproto_flow_mod *, + const struct ofputil_flow_mod *, const struct openflow_mod_requester *) OVS_EXCLUDED(ofproto_mutex); static void calc_duration(long long int start, long long int now, @@ -2123,11 +2123,11 @@ simple_flow_mod(struct ofproto *ofproto, const struct ofpact *ofpacts, size_t ofpacts_len, enum ofp_flow_mod_command command) { - struct ofproto_flow_mod ofm; + struct ofputil_flow_mod fm; - flow_mod_init(&ofm.fm, match, priority, ofpacts, ofpacts_len, command); + flow_mod_init(&fm, match, priority, ofpacts, ofpacts_len, command); - return handle_flow_mod__(ofproto, &ofm, NULL); + return handle_flow_mod__(ofproto, &fm, NULL); } /* Adds a flow to OpenFlow flow table 0 in 'p' that matches 'cls_rule' and @@ -2179,11 +2179,9 @@ ofproto_add_flow(struct ofproto *ofproto, const struct match *match, * This is a helper function for in-band control and fail-open and the "learn" * action. */ enum ofperr -ofproto_flow_mod(struct ofproto *ofproto, struct ofproto_flow_mod *ofm) +ofproto_flow_mod(struct ofproto *ofproto, const struct ofputil_flow_mod *fm) OVS_EXCLUDED(ofproto_mutex) { - struct ofputil_flow_mod *fm = &ofm->fm; - /* Optimize for the most common case of a repeated learn action. * If an identical flow already exists we only need to update its * 'modified' time. */ @@ -2224,7 +2222,7 @@ ofproto_flow_mod(struct ofproto *ofproto, struct ofproto_flow_mod *ofm) } } - return handle_flow_mod__(ofproto, ofm, NULL); + return handle_flow_mod__(ofproto, fm, NULL); } /* Searches for a rule with matching criteria exactly equal to 'target' in @@ -4870,7 +4868,7 @@ add_flow_start(struct ofproto *ofproto, struct ofproto_flow_mod *ofm) *old_rule = rule; } } else { - fm->modify_cookie = true; + ofm->modify_cookie = true; } /* Allocate new rule. */ @@ -4979,7 +4977,7 @@ replace_rule_create(struct ofproto *ofproto, struct ofproto_flow_mod *ofm, /* Copy values from old rule for modify semantics. */ if (old_rule && old_rule->removed_reason != OFPRR_EVICTION) { - bool change_cookie = (fm->modify_cookie + bool change_cookie = (ofm->modify_cookie && fm->new_cookie != OVS_BE64_MAX && fm->new_cookie != old_rule->flow_cookie); @@ -5531,7 +5529,7 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh) OVS_EXCLUDED(ofproto_mutex) { struct ofproto *ofproto = ofconn_get_ofproto(ofconn); - struct ofproto_flow_mod ofm; + struct ofputil_flow_mod fm; uint64_t ofpacts_stub[1024 / 8]; struct ofpbuf ofpacts; enum ofperr error; @@ -5542,13 +5540,13 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh) } ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub); - error = ofputil_decode_flow_mod(&ofm.fm, oh, ofconn_get_protocol(ofconn), + error = ofputil_decode_flow_mod(&fm, oh, ofconn_get_protocol(ofconn), &ofpacts, u16_to_ofp(ofproto->max_ports), ofproto->n_tables); if (!error) { struct openflow_mod_requester req = { ofconn, oh }; - error = handle_flow_mod__(ofproto, &ofm, &req); + error = handle_flow_mod__(ofproto, &fm, &req); } ofpbuf_uninit(&ofpacts); @@ -5556,18 +5554,21 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh) } static enum ofperr -handle_flow_mod__(struct ofproto *ofproto, struct ofproto_flow_mod *ofm, +handle_flow_mod__(struct ofproto *ofproto, const struct ofputil_flow_mod *fm, const struct openflow_mod_requester *req) OVS_EXCLUDED(ofproto_mutex) { + struct ofproto_flow_mod ofm; enum ofperr error; + ofm.fm = *fm; + ovs_mutex_lock(&ofproto_mutex); - ofm->version = ofproto->tables_version + 1; - error = ofproto_flow_mod_start(ofproto, ofm); + ofm.version = ofproto->tables_version + 1; + error = ofproto_flow_mod_start(ofproto, &ofm); if (!error) { ofproto_bump_tables_version(ofproto); - ofproto_flow_mod_finish(ofproto, ofm, req); + ofproto_flow_mod_finish(ofproto, &ofm, req); } ofmonitor_flush(ofproto->connmgr); ovs_mutex_unlock(&ofproto_mutex); @@ -7140,6 +7141,7 @@ ofproto_flow_mod_start(struct ofproto *ofproto, struct ofproto_flow_mod *ofm) /* Forward flow mod fields we need later. */ ofm->buffer_id = ofm->fm.buffer_id; + ofm->modify_cookie = ofm->fm.modify_cookie; ofm->modify_may_add_flow = (ofm->fm.new_cookie != OVS_BE64_MAX && ofm->fm.cookie_mask == htonll(0)); -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev