NMX selection method Signed-off-by: Simon Horman <simon.hor...@netronome.com> --- ofproto/ofproto.c | 63 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 23 deletions(-)
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 00e668a..b749ca6 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -268,9 +268,6 @@ static enum ofperr send_buffered_packet(struct ofconn *, uint32_t buffer_id, static bool ofproto_group_exists__(const struct ofproto *ofproto, uint32_t group_id) OVS_REQ_RDLOCK(ofproto->groups_rwlock); -static bool ofproto_group_exists(const struct ofproto *ofproto, - uint32_t group_id) - OVS_EXCLUDED(ofproto->groups_rwlock); static enum ofperr add_group(struct ofproto *, struct ofputil_group_mod *); static void handle_openflow(struct ofconn *, const struct ofpbuf *); static enum ofperr handle_flow_mod__(struct ofproto *, @@ -3112,12 +3109,15 @@ reject_slave_controller(struct ofconn *ofconn) * * - If they use a meter, then 'ofproto' has that meter configured. * - * - If they use any groups, then 'ofproto' has that group configured. + * - If they use any groups, then 'ofproto' has that group configured + * and if it has selection method fields their pre-requisites are met + * by 'flow'. * * Returns 0 if successful, otherwise an OpenFlow error. */ static enum ofperr ofproto_check_ofpacts(struct ofproto *ofproto, - const struct ofpact ofpacts[], size_t ofpacts_len) + const struct ofpact ofpacts[], size_t ofpacts_len, + const struct flow *flow) { const struct ofpact *a; uint32_t mid; @@ -3128,9 +3128,38 @@ ofproto_check_ofpacts(struct ofproto *ofproto, } OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { - if (a->type == OFPACT_GROUP - && !ofproto_group_exists(ofproto, ofpact_get_GROUP(a)->group_id)) { - return OFPERR_OFPBAC_BAD_OUT_GROUP; + if (a->type == OFPACT_GROUP) { + struct ofgroup *group; + bool ok = true; + int i; + + ofproto_group_lookup(ofproto, ofpact_get_GROUP(a)->group_id, + &group); + if (!group) { + return OFPERR_OFPBAC_BAD_OUT_GROUP; + } + + if (group->selection_method[0]) { + for (i = 0; i < MFF_N_IDS; i++) { + const struct mf_field *mf; + + if (!bitmap_is_set(group->fields.bm.bm, i)) { + continue; + } + + mf = mf_from_id(i); + if (!mf_are_prereqs_ok(mf, flow)) { + ok = false; + break; + } + } + } + + ofproto_group_unref(group); + + if (!ok) { + return OFPERR_OFPBAC_BAD_OUT_GROUP; + } } } @@ -3181,7 +3210,7 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) /* Verify actions against packet, then send packet if successful. */ flow_extract(payload, NULL, &flow); flow.in_port.ofp_port = po.in_port; - error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len); + error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len, &flow); if (!error) { error = p->ofproto_class->packet_out(p, payload, &flow, po.ofpacts, po.ofpacts_len); @@ -4703,7 +4732,8 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh) u16_to_ofp(ofproto->max_ports), ofproto->n_tables); if (!error) { - error = ofproto_check_ofpacts(ofproto, fm.ofpacts, fm.ofpacts_len); + error = ofproto_check_ofpacts(ofproto, fm.ofpacts, fm.ofpacts_len, + &fm.match.flow); } if (!error) { struct flow_mod_requester req; @@ -5533,19 +5563,6 @@ ofproto_group_exists__(const struct ofproto *ofproto, uint32_t group_id) return false; } -static bool -ofproto_group_exists(const struct ofproto *ofproto, uint32_t group_id) - OVS_EXCLUDED(ofproto->groups_rwlock) -{ - bool exists; - - ovs_rwlock_rdlock(&ofproto->groups_rwlock); - exists = ofproto_group_exists__(ofproto, group_id); - ovs_rwlock_unlock(&ofproto->groups_rwlock); - - return exists; -} - static uint32_t group_get_ref_count(struct ofgroup *group) OVS_EXCLUDED(ofproto_mutex) -- 2.1.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev