Signed-off-by: Jarno Rajahalme <[email protected]>
---
lib/dpif-netdev.c | 10 +++++++---
lib/dpif.c | 7 ++++---
lib/odp-execute.c | 8 +++-----
lib/odp-execute.h | 4 +++-
ofproto/ofproto-dpif-xlate.c | 24 ++++++++++++++++++------
5 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 975fd60..215de4f 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1325,7 +1325,7 @@ struct dp_netdev_execute_aux {
const struct flow *key;
};
-static void
+static bool
dp_execute_cb(void *aux_, struct ofpbuf *packet,
struct dpif_metadata *md OVS_UNUSED, const struct nlattr *a)
{
@@ -1335,7 +1335,7 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
switch ((enum ovs_action_attr)type) {
case OVS_ACTION_ATTR_OUTPUT:
dp_netdev_output_port(aux->dp, packet, nl_attr_get_u32(a));
- break;
+ return true;
case OVS_ACTION_ATTR_USERSPACE: {
const struct nlattr *userdata;
@@ -1343,9 +1343,11 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
userdata = nl_attr_find_nested(a, OVS_USERSPACE_ATTR_USERDATA);
dp_netdev_output_userspace(aux->dp, packet, DPIF_UC_ACTION, aux->key,
userdata);
- break;
+ return true;
}
case OVS_ACTION_ATTR_METER:
+ return true;
+
case OVS_ACTION_ATTR_PUSH_VLAN:
case OVS_ACTION_ATTR_POP_VLAN:
case OVS_ACTION_ATTR_PUSH_MPLS:
@@ -1356,6 +1358,8 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
case __OVS_ACTION_ATTR_MAX:
NOT_REACHED();
}
+
+ return false;
}
static void
diff --git a/lib/dpif.c b/lib/dpif.c
index df4b365..4a249e2 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1063,7 +1063,7 @@ struct dpif_execute_helper_aux {
int error;
};
-static void
+static bool
dpif_execute_helper_cb(void *aux_, struct ofpbuf *packet,
struct dpif_metadata *md, const struct nlattr *action)
{
@@ -1071,14 +1071,14 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf
*packet,
int type = nl_attr_type(action);
switch ((enum ovs_action_attr)type) {
+ case OVS_ACTION_ATTR_METER:
case OVS_ACTION_ATTR_OUTPUT:
case OVS_ACTION_ATTR_USERSPACE:
aux->error = dpif_execute(aux->dpif,
action, NLA_ALIGN(action->nla_len),
packet, md, false);
- break;
+ return aux->error == 0;
- case OVS_ACTION_ATTR_METER:
case OVS_ACTION_ATTR_PUSH_VLAN:
case OVS_ACTION_ATTR_POP_VLAN:
case OVS_ACTION_ATTR_PUSH_MPLS:
@@ -1089,6 +1089,7 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf *packet,
case __OVS_ACTION_ATTR_MAX:
NOT_REACHED();
}
+ return false;
}
/* Executes 'execute' by performing most of the actions in userspace and
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 3c38e95..bd3c48c 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -26,6 +26,7 @@
#include "ofpbuf.h"
#include "odp-util.h"
#include "packets.h"
+#include "timeval.h"
#include "unaligned.h"
#include "util.h"
@@ -186,13 +187,10 @@ odp_execute_actions(void *dp, struct ofpbuf *packet,
struct dpif_metadata *md,
switch ((enum ovs_action_attr) type) {
case OVS_ACTION_ATTR_METER:
- /* Not implemented yet. */
- break;
-
case OVS_ACTION_ATTR_OUTPUT:
case OVS_ACTION_ATTR_USERSPACE:
- if (callback) {
- callback(dp, packet, md, a);
+ if (callback && !callback(dp, packet, md, a)) {
+ return; /* Drop */
}
break;
diff --git a/lib/odp-execute.h b/lib/odp-execute.h
index 5ddc3d4..d076f82 100644
--- a/lib/odp-execute.h
+++ b/lib/odp-execute.h
@@ -18,6 +18,7 @@
#ifndef EXECUTE_ACTIONS_H
#define EXECUTE_ACTIONS_H 1
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "openvswitch/types.h"
@@ -26,7 +27,8 @@ struct nlattr;
struct ofpbuf;
struct dpif_metadata;
-typedef void (*odp_execute_callback)(void *dp, struct ofpbuf *packet,
+/* Packet is dropped if the callback returns false. */
+typedef bool (*odp_execute_callback)(void *dp, struct ofpbuf *packet,
struct dpif_metadata *,
const struct nlattr *action);
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index d47125e..efce8ef 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -216,6 +216,7 @@ static struct hmap xports = HMAP_INITIALIZER(&xports);
static bool may_receive(const struct xport *, struct xlate_ctx *);
static void do_xlate_actions(const struct ofpact *, size_t ofpacts_len,
+ const struct rule_actions *actions,
struct xlate_ctx *);
static void xlate_actions__(struct xlate_in *, struct xlate_out *)
OVS_REQ_RDLOCK(xlate_rwlock);
@@ -1812,7 +1813,7 @@ xlate_recursively(struct xlate_ctx *ctx, struct rule_dpif
*rule)
ctx->recurse++;
ctx->rule = rule;
actions = rule_dpif_get_actions(rule);
- do_xlate_actions(actions->ofpacts, actions->ofpacts_len, ctx);
+ do_xlate_actions(actions->ofpacts, actions->ofpacts_len, actions, ctx);
rule_actions_unref(actions);
ctx->rule = old_rule;
ctx->recurse--;
@@ -1900,7 +1901,7 @@ xlate_group_bucket(struct xlate_ctx *ctx, const struct
ofputil_bucket *bucket)
ofpacts_execute_action_set(&action_list, &action_set);
ctx->recurse++;
- do_xlate_actions(action_list.data, action_list.size, ctx);
+ do_xlate_actions(action_list.data, action_list.size, NULL, ctx);
ctx->recurse--;
ofpbuf_uninit(&action_set);
@@ -2500,6 +2501,14 @@ xlate_sample_action(struct xlate_ctx *ctx,
probability, &cookie, sizeof cookie.flow_sample);
}
+static void
+xlate_meter_action(struct xlate_ctx *ctx, uint32_t dp_mid)
+{
+ if (dp_mid != UINT32_MAX) {
+ nl_msg_put_u32(&ctx->xout->odp_actions, OVS_ACTION_ATTR_METER, dp_mid);
+ }
+}
+
static bool
may_receive(const struct xport *xport, struct xlate_ctx *ctx)
{
@@ -2536,13 +2545,13 @@ xlate_action_set(struct xlate_ctx *ctx)
ofpbuf_use_stub(&action_list, action_list_stub, sizeof action_list_stub);
ofpacts_execute_action_set(&action_list, &ctx->action_set);
- do_xlate_actions(action_list.data, action_list.size, ctx);
+ do_xlate_actions(action_list.data, action_list.size, NULL, ctx);
ofpbuf_uninit(&action_list);
}
static void
do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
- struct xlate_ctx *ctx)
+ const struct rule_actions *actions, struct xlate_ctx *ctx)
{
struct flow_wildcards *wc = &ctx->xout->wc;
struct flow *flow = &ctx->xin->flow;
@@ -2818,7 +2827,10 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t
ofpacts_len,
break;
case OFPACT_METER:
- /* Not implemented yet. */
+ /* METER instruction can not exist in a bare action list. */
+ if (actions) {
+ xlate_meter_action(ctx, actions->provider_meter_id);
+ }
break;
case OFPACT_GOTO_TABLE: {
@@ -3156,7 +3168,7 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out
*xout)
sample_actions_len = ctx.xout->odp_actions.size;
if (tnl_may_send && (!in_port || may_receive(in_port, &ctx))) {
- do_xlate_actions(ofpacts, ofpacts_len, &ctx);
+ do_xlate_actions(ofpacts, ofpacts_len, actions, &ctx);
/* We've let OFPP_NORMAL and the learning action look at the
* packet, so drop it now if forwarding is disabled. */
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev