aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2013-09-13 15:03:32 -0700
committerBen Pfaff <blp@nicira.com>2013-09-16 15:23:38 -0700
commit65efd2ab94a33555234449688f27b12d9ec3fd04 (patch)
tree10ed0cb538104d00e1f013db1b1ff8a460dae943
parente555eb7c38c38b170c165b2e4b9cd222f0fd20e8 (diff)
rule_ofpacts: keep datapath meter_id.
This allows datapaths to operate without referring to the ofproto-level meter configuration for mater ID mapping, which reduces needs for locking. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
-rw-r--r--ofproto/ofproto-provider.h5
-rw-r--r--ofproto/ofproto.c31
-rw-r--r--ofproto/ofproto.h3
3 files changed, 22 insertions, 17 deletions
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index bc3f9661..03b19c84 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -415,10 +415,11 @@ struct rule_actions {
* lifetime. */
struct ofpact *ofpacts; /* Sequence of "struct ofpacts". */
unsigned int ofpacts_len; /* Size of 'ofpacts', in bytes. */
- uint32_t meter_id; /* Non-zero OF meter_id, or zero. */
+ uint32_t provider_meter_id; /* Datapath meter_id, or UINT32_MAX. */
};
-struct rule_actions *rule_actions_create(const struct ofpact *, size_t);
+struct rule_actions *rule_actions_create(const struct ofproto *,
+ const struct ofpact *, size_t);
void rule_actions_ref(struct rule_actions *);
void rule_actions_unref(struct rule_actions *);
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index f97b9bc0..0ceb85f6 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2443,10 +2443,14 @@ ofproto_rule_destroy__(struct rule *rule)
rule->ofproto->ofproto_class->rule_dealloc(rule);
}
+static uint32_t get_provider_meter_id(const struct ofproto *,
+ uint32_t of_meter_id);
+
/* Creates and returns a new 'struct rule_actions', with a ref_count of 1,
* whose actions are a copy of from the 'ofpacts_len' bytes of 'ofpacts'. */
struct rule_actions *
-rule_actions_create(const struct ofpact *ofpacts, size_t ofpacts_len)
+rule_actions_create(const struct ofproto *ofproto,
+ const struct ofpact *ofpacts, size_t ofpacts_len)
{
struct rule_actions *actions;
@@ -2454,7 +2458,10 @@ rule_actions_create(const struct ofpact *ofpacts, size_t ofpacts_len)
atomic_init(&actions->ref_count, 1);
actions->ofpacts = xmemdup(ofpacts, ofpacts_len);
actions->ofpacts_len = ofpacts_len;
- actions->meter_id = ofpacts_get_meter(ofpacts, ofpacts_len);
+ actions->provider_meter_id
+ = get_provider_meter_id(ofproto,
+ ofpacts_get_meter(ofpacts, ofpacts_len));
+
return actions;
}
@@ -2744,7 +2751,7 @@ ofproto_check_ofpacts(struct ofproto *ofproto,
}
mid = ofpacts_get_meter(ofpacts, ofpacts_len);
- if (mid && ofproto_get_provider_meter_id(ofproto, mid) == UINT32_MAX) {
+ if (mid && get_provider_meter_id(ofproto, mid) == UINT32_MAX) {
return OFPERR_OFPMMFC_INVALID_METER;
}
return 0;
@@ -3898,7 +3905,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn,
*CONST_CAST(uint8_t *, &rule->table_id) = table - ofproto->tables;
rule->flags = fm->flags & OFPUTIL_FF_STATE;
- rule->actions = rule_actions_create(fm->ofpacts, fm->ofpacts_len);
+ rule->actions = rule_actions_create(ofproto, fm->ofpacts, fm->ofpacts_len);
list_init(&rule->meter_list_node);
rule->eviction_group = NULL;
list_init(&rule->expirable);
@@ -3999,7 +4006,8 @@ modify_flows__(struct ofproto *ofproto, struct ofconn *ofconn,
struct rule_actions *new_actions;
op->actions = rule->actions;
- new_actions = rule_actions_create(fm->ofpacts, fm->ofpacts_len);
+ new_actions = rule_actions_create(ofproto,
+ fm->ofpacts, fm->ofpacts_len);
ovs_mutex_lock(&rule->mutex);
rule->actions = new_actions;
@@ -4842,13 +4850,10 @@ struct meter {
/*
* This is used in instruction validation at flow set-up time,
* as flows may not use non-existing meters.
- * This is also used by ofproto-providers to translate OpenFlow meter_ids
- * in METER instructions to the corresponding provider meter IDs.
* Return value of UINT32_MAX signifies an invalid meter.
*/
-uint32_t
-ofproto_get_provider_meter_id(const struct ofproto * ofproto,
- uint32_t of_meter_id)
+static uint32_t
+get_provider_meter_id(const struct ofproto *ofproto, uint32_t of_meter_id)
{
if (of_meter_id && of_meter_id <= ofproto->meter_features.max_meters) {
const struct meter *meter = ofproto->meters[of_meter_id];
@@ -6535,8 +6540,10 @@ oftable_insert_rule(struct rule *rule)
cookies_insert(ofproto, rule);
- if (rule->actions->meter_id) {
- struct meter *meter = ofproto->meters[rule->actions->meter_id];
+ if (rule->actions->provider_meter_id != UINT32_MAX) {
+ uint32_t meter_id = ofpacts_get_meter(rule->actions->ofpacts,
+ rule->actions->ofpacts_len);
+ struct meter *meter = ofproto->meters[meter_id];
list_insert(&meter->rules, &rule->meter_list_node);
}
ovs_rwlock_wrlock(&table->cls.rwlock);
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index 9adda2cc..c42b068f 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -434,9 +434,6 @@ bool ofproto_has_vlan_usage_changed(const struct ofproto *);
int ofproto_port_set_realdev(struct ofproto *, ofp_port_t vlandev_ofp_port,
ofp_port_t realdev_ofp_port, int vid);
-uint32_t ofproto_get_provider_meter_id(const struct ofproto *,
- uint32_t of_meter_id);
-
#ifdef __cplusplus
}
#endif