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