From: Simon Horman Date: Wed, 30 Oct 2013 09:17:06 +0000 (+0900) Subject: ofproto: Fail flow mod if it references a non-existent group X-Git-Tag: sliver-openvswitch-2.0.90-1~6^2~47 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=84d685662cadf68ae8d112faa7dd13160b6ccff2 ofproto: Fail flow mod if it references a non-existent group As per the OpenFlow1.3.2 specification, a flow mod should fail if it references a non-existent group. The change in this patch appears to be necessary to satisfy that constraint. It is unclear to me whether or not is is sufficient. Signed-off-by: Simon Horman Signed-off-by: Ben Pfaff --- diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index bf145e0bc..ddbab6cfd 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -271,6 +271,9 @@ static enum ofperr modify_flows__(struct ofproto *, struct ofconn *, static void delete_flow__(struct rule *rule, struct ofopgroup *, enum ofp_flow_removed_reason) OVS_REQUIRES(ofproto_mutex); +static bool ofproto_group_exists(const struct ofproto *ofproto, + uint32_t group_id) + OVS_REQ_RDLOCK(ofproto->groups_rwlock); static enum ofperr add_group(struct ofproto *, struct ofputil_group_mod *); static bool handle_openflow(struct ofconn *, const struct ofpbuf *); static enum ofperr handle_flow_mod__(struct ofproto *, struct ofconn *, @@ -2837,6 +2840,7 @@ ofproto_check_ofpacts(struct ofproto *ofproto, const struct ofp_header *oh) { enum ofperr error; + const struct ofpact *a; uint32_t mid; error = ofpacts_check(ofpacts, ofpacts_len, flow, @@ -2846,6 +2850,21 @@ ofproto_check_ofpacts(struct ofproto *ofproto, return error; } + OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { + if (a->type == OFPACT_GROUP) { + bool exists; + + ovs_rwlock_rdlock(&ofproto->groups_rwlock); + exists = ofproto_group_exists(ofproto, + ofpact_get_GROUP(a)->group_id); + ovs_rwlock_unlock(&ofproto->groups_rwlock); + + if (!exists) { + return OFPERR_OFPBAC_BAD_OUT_GROUP; + } + } + } + mid = ofpacts_get_meter(ofpacts, ofpacts_len); if (mid && get_provider_meter_id(ofproto, mid) == UINT32_MAX) { return OFPERR_OFPMMFC_INVALID_METER;