Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 lib/dpif-netdev.c            |    3 ++-
 lib/odp-execute.c            |   18 +++++++++++++-----
 lib/odp-execute.h            |    5 ++++-
 ofproto/ofproto-dpif-xlate.c |   22 +++++++++++++++++-----
 4 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 5e7ab42..c851d62 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1337,7 +1337,8 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
                           size_t actions_len)
 {
     odp_execute_actions(dp, packet, key, actions, actions_len,
-                        dp_netdev_output_port, dp_netdev_action_userspace);
+                        dp_netdev_output_port, dp_netdev_action_userspace,
+                        NULL);
 }
 
 const struct dpif_class dpif_netdev_class = {
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 4acafa3..3ac74ce 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -25,6 +25,7 @@
 #include "ofpbuf.h"
 #include "odp-util.h"
 #include "packets.h"
+#include "timeval.h"
 #include "util.h"
 
 static void
@@ -128,7 +129,9 @@ odp_execute_sample(void *dp, struct ofpbuf *packet, struct 
flow *key,
                                   uint32_t out_port),
                    void (*userspace)(void *dp, struct ofpbuf *packet,
                                      const struct flow *key,
-                                     const struct nlattr *a))
+                                     const struct nlattr *a),
+                   bool (*meter)(void *dp_, struct ofpbuf *packet,
+                                 uint32_t meter_id, long long int now))
 {
     const struct nlattr *subactions = NULL;
     const struct nlattr *a;
@@ -156,7 +159,8 @@ odp_execute_sample(void *dp, struct ofpbuf *packet, struct 
flow *key,
     }
 
     odp_execute_actions(dp, packet, key, nl_attr_get(subactions),
-                        nl_attr_get_size(subactions), output, userspace);
+                        nl_attr_get_size(subactions), output, userspace,
+                        meter);
 }
 
 void
@@ -166,7 +170,9 @@ odp_execute_actions(void *dp, struct ofpbuf *packet, struct 
flow *key,
                                    uint32_t out_port),
                     void (*userspace)(void *dp, struct ofpbuf *packet,
                                       const struct flow *key,
-                                      const struct nlattr *a))
+                                      const struct nlattr *a),
+                    bool (*meter)(void *dp_, struct ofpbuf *packet,
+                                  uint32_t meter_id, long long int now))
 {
     const struct nlattr *a;
     unsigned int left;
@@ -176,7 +182,9 @@ odp_execute_actions(void *dp, struct ofpbuf *packet, struct 
flow *key,
 
         switch ((enum ovs_action_attr) type) {
         case OVS_ACTION_ATTR_METER:
-            /* Not implemented yet. */
+            if (meter && meter(dp, packet, nl_attr_get_u32(a), time_msec())) {
+                return;  /* Drop */
+            }
             break;
 
         case OVS_ACTION_ATTR_OUTPUT:
@@ -219,7 +227,7 @@ odp_execute_actions(void *dp, struct ofpbuf *packet, struct 
flow *key,
             break;
 
         case OVS_ACTION_ATTR_SAMPLE:
-            odp_execute_sample(dp, packet, key, a, output, userspace);
+            odp_execute_sample(dp, packet, key, a, output, userspace, meter);
             break;
 
         case OVS_ACTION_ATTR_UNSPEC:
diff --git a/lib/odp-execute.h b/lib/odp-execute.h
index 89dd66b..f198e87 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>
 
@@ -32,5 +33,7 @@ odp_execute_actions(void *dp, struct ofpbuf *packet, struct 
flow *key,
                                    uint32_t out_port),
                     void (*userspace)(void *dp, struct ofpbuf *packet,
                                       const struct flow *key,
-                                      const struct nlattr *a));
+                                      const struct nlattr *a),
+                    bool (*meter)(void *dp_, struct ofpbuf *packet,
+                                  uint32_t meter_id, long long int now));
 #endif
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index a5b6814..ff90781 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -191,6 +191,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_normal(struct xlate_ctx *);
 static void xlate_report(struct xlate_ctx *, const char *);
@@ -1680,7 +1681,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--;
@@ -1803,7 +1804,7 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
                        &ctx->xout->odp_actions, &ctx->xout->wc);
 
     odp_execute_actions(NULL, packet, &key, ctx->xout->odp_actions.data,
-                        ctx->xout->odp_actions.size, NULL, NULL);
+                        ctx->xout->odp_actions.size, NULL, NULL, NULL);
 
     pin = xmalloc(sizeof *pin);
     pin->packet_len = packet->size;
@@ -2142,6 +2143,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)
 {
@@ -2164,7 +2173,7 @@ may_receive(const struct xport *xport, struct xlate_ctx 
*ctx)
 
 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;
@@ -2381,7 +2390,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: {
@@ -2660,7 +2672,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