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

Reply via email to