NMX selection method
Signed-off-by: Simon Horman <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev