Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 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
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to