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