This will make it easier to use a convenient set of members for each possible format, instead of being stuck with a single layout.
An upcoming commit will add a new member to the 'controller' case. Signed-off-by: Ben Pfaff <b...@nicira.com> --- lib/odp-util.c | 35 +++++++++++++++++++---------------- lib/odp-util.h | 25 ++++++++++++++++--------- ofproto/ofproto-dpif-sflow.c | 16 +++++++++------- ofproto/ofproto-dpif-sflow.h | 4 ++-- ofproto/ofproto-dpif.c | 42 +++++++++++++++++++++--------------------- 5 files changed, 67 insertions(+), 55 deletions(-) diff --git a/lib/odp-util.c b/lib/odp-util.c index ee1c378..6fafe79 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -185,17 +185,20 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr) if (a[OVS_USERSPACE_ATTR_USERDATA]) { uint64_t userdata = nl_attr_get_u64(a[OVS_USERSPACE_ATTR_USERDATA]); - struct user_action_cookie cookie; + union user_action_cookie cookie; memcpy(&cookie, &userdata, sizeof cookie); if (cookie.type == USER_ACTION_COOKIE_CONTROLLER) { - ds_put_format(ds, ",controller,length=%"PRIu32, cookie.data); + ds_put_format(ds, ",controller,length=%"PRIu16, + cookie.controller.max_len); } else if (cookie.type == USER_ACTION_COOKIE_SFLOW) { ds_put_format(ds, ",sFlow,n_output=%"PRIu8"," "vid=%"PRIu16",pcp=%"PRIu8",ifindex=%"PRIu32, - cookie.n_output, vlan_tci_to_vid(cookie.vlan_tci), - vlan_tci_to_pcp(cookie.vlan_tci), cookie.data); + cookie.sflow.n_output, + vlan_tci_to_vid(cookie.sflow.vlan_tci), + vlan_tci_to_pcp(cookie.sflow.vlan_tci), + cookie.sflow.ifindex); } else { ds_put_format(ds, ",userdata=0x%"PRIx64, userdata); } @@ -340,18 +343,17 @@ parse_odp_action(const char *s, const struct shash *port_names, return n; } else if (sscanf(s, "userspace(pid=%lli,controller,length=%lli)%n", &pid, &length, &n) > 0 && n > 0) { - struct user_action_cookie cookie; + union user_action_cookie cookie; - cookie.type = USER_ACTION_COOKIE_CONTROLLER; - cookie.n_output = 0; - cookie.vlan_tci = htons(0); - cookie.data = length; + memset(&cookie, 0, sizeof cookie); + cookie.controller.type = USER_ACTION_COOKIE_CONTROLLER; + cookie.controller.max_len = length; odp_put_userspace_action(pid, &cookie, actions); return n; } else if (sscanf(s, "userspace(pid=%lli,sFlow,n_output=%i,vid=%i," "pcp=%i,ifindex=%lli)%n", &pid, &n_output, &vid, &pcp, &ifindex, &n) > 0 && n > 0) { - struct user_action_cookie cookie; + union user_action_cookie cookie; uint16_t tci; tci = vid | (pcp << VLAN_PCP_SHIFT); @@ -359,16 +361,17 @@ parse_odp_action(const char *s, const struct shash *port_names, tci |= VLAN_CFI; } - cookie.type = USER_ACTION_COOKIE_SFLOW; - cookie.n_output = n_output; - cookie.vlan_tci = htons(tci); - cookie.data = ifindex; + memset(&cookie, 0, sizeof cookie); + cookie.sflow.type = USER_ACTION_COOKIE_SFLOW; + cookie.sflow.n_output = n_output; + cookie.sflow.vlan_tci = htons(tci); + cookie.sflow.ifindex = ifindex; odp_put_userspace_action(pid, &cookie, actions); return n; } else if (sscanf(s, "userspace(pid=%lli,userdata=" "%31[x0123456789abcdefABCDEF])%n", &pid, userdata_s, &n) > 0 && n > 0) { - struct user_action_cookie cookie; + union user_action_cookie cookie; uint64_t userdata; userdata = strtoull(userdata_s, NULL, 0); @@ -1706,7 +1709,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len, * the start of the cookie. (If 'cookie' is null, then the return value is not * meaningful.) */ size_t -odp_put_userspace_action(uint32_t pid, const struct user_action_cookie *cookie, +odp_put_userspace_action(uint32_t pid, const union user_action_cookie *cookie, struct ofpbuf *odp_actions) { size_t offset; diff --git a/lib/odp-util.h b/lib/odp-util.h index 7c9b588..245e292 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -123,18 +123,25 @@ enum user_action_cookie_type { /* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE. * Since is it passed to kernel as u64, its size has to be 8 bytes. */ -struct user_action_cookie { - uint8_t type; /* enum user_action_cookie_type. */ - uint8_t n_output; /* No of output ports. used by sflow. */ - ovs_be16 vlan_tci; /* Used by sFlow */ - uint32_t data; /* Data is len for OFPP_CONTROLLER action. - For sFlow it is port_ifindex. */ +union user_action_cookie { + uint8_t type; /* enum user_action_cookie_type. */ + + struct { + uint8_t type; /* USER_ACTION_COOKIE_SFLOW. */ + uint8_t n_output; /* Number of output ports. */ + ovs_be16 vlan_tci; /* VLAN TCI value. */ + uint32_t ifindex; /* sFlow notion for output port. */ + } sflow; + + struct { + uint8_t type; /* USER_ACTION_COOKIE_CONTROLLER. */ + uint16_t max_len; /* Maximum number of bytes to send. */ + } controller; }; - -BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 8); +BUILD_ASSERT_DECL(sizeof(union user_action_cookie) == 8); size_t odp_put_userspace_action(uint32_t pid, - const struct user_action_cookie *, + const union user_action_cookie *, struct ofpbuf *odp_actions); void commit_odp_actions(const struct flow *, struct flow *base, diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index 5825636..d777591 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -491,7 +491,7 @@ dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *ds, void dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet, const struct flow *flow, - const struct user_action_cookie *cookie) + const union user_action_cookie *cookie) { SFL_FLOW_SAMPLE_TYPE fs; SFLFlow_sample_element hdrElem; @@ -500,6 +500,7 @@ dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet, SFLSampler *sampler; struct dpif_sflow_port *in_dsp; struct netdev_stats stats; + ovs_be16 vlan_tci; int error; /* Build a flow sample */ @@ -549,20 +550,21 @@ dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet, switchElem.flowType.sw.src_priority = vlan_tci_to_pcp(flow->vlan_tci); /* Retrieve data from user_action_cookie. */ - switchElem.flowType.sw.dst_vlan = vlan_tci_to_vid(cookie->vlan_tci); - switchElem.flowType.sw.dst_priority = vlan_tci_to_pcp(cookie->vlan_tci); + vlan_tci = cookie->sflow.vlan_tci; + switchElem.flowType.sw.dst_vlan = vlan_tci_to_vid(vlan_tci); + switchElem.flowType.sw.dst_priority = vlan_tci_to_pcp(vlan_tci); /* Set output port, as defined by http://www.sflow.org/sflow_version_5.txt (search for "Input/output port information"). */ - if (!cookie->n_output) { + if (!cookie->sflow.n_output) { /* This value indicates that the packet was dropped for an unknown * reason. */ fs.output = 0x40000000 | 256; - } else if (cookie->n_output > 1 || !cookie->data) { + } else if (cookie->sflow.n_output > 1 || !cookie->sflow.ifindex) { /* Setting the high bit means "multiple output ports". */ - fs.output = 0x80000000 | cookie->n_output; + fs.output = 0x80000000 | cookie->sflow.n_output; } else { - fs.output = cookie->data; + fs.output = cookie->sflow.ifindex; } /* Submit the flow sample to be encoded into the next datagram. */ diff --git a/ofproto/ofproto-dpif-sflow.h b/ofproto/ofproto-dpif-sflow.h index 0b6c1b4..9726310 100644 --- a/ofproto/ofproto-dpif-sflow.h +++ b/ofproto/ofproto-dpif-sflow.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2009, 2010 InMon Corp. - * Copyright (c) 2009 Nicira Networks. + * Copyright (c) 2009, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ void dpif_sflow_wait(struct dpif_sflow *); void dpif_sflow_received(struct dpif_sflow *, struct ofpbuf *, const struct flow *, - const struct user_action_cookie *); + const union user_action_cookie *); int dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *, uint16_t); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 2840123..2bd76a6 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -2397,7 +2397,7 @@ send_packet_in_action(struct ofproto_dpif *ofproto, struct ofpbuf *packet, uint64_t userdata, const struct flow *flow, bool clone) { struct ofputil_packet_in pin; - struct user_action_cookie cookie; + union user_action_cookie cookie; memcpy(&cookie, &userdata, sizeof(cookie)); @@ -2405,7 +2405,7 @@ send_packet_in_action(struct ofproto_dpif *ofproto, struct ofpbuf *packet, pin.in_port = flow->in_port; pin.reason = OFPR_ACTION; pin.buffer_id = 0; /* not yet known */ - pin.send_len = cookie.data; + pin.send_len = cookie.controller.max_len; connmgr_send_packet_in(ofproto->up.connmgr, &pin, flow, clone ? NULL : packet); } @@ -2706,7 +2706,7 @@ static void handle_userspace_upcall(struct ofproto_dpif *ofproto, struct dpif_upcall *upcall) { - struct user_action_cookie cookie; + union user_action_cookie cookie; enum odp_key_fitness fitness; ovs_be16 initial_tci; struct flow flow; @@ -4006,7 +4006,7 @@ static size_t put_userspace_action(const struct ofproto_dpif *ofproto, struct ofpbuf *odp_actions, const struct flow *flow, - const struct user_action_cookie *cookie) + const union user_action_cookie *cookie) { uint32_t pid; @@ -4025,7 +4025,7 @@ compose_sflow_action(const struct ofproto_dpif *ofproto, { uint32_t port_ifindex; uint32_t probability; - struct user_action_cookie cookie; + union user_action_cookie cookie; size_t sample_offset, actions_offset; int cookie_offset, n_output; @@ -4049,10 +4049,10 @@ compose_sflow_action(const struct ofproto_dpif *ofproto, actions_offset = nl_msg_start_nested(odp_actions, OVS_SAMPLE_ATTR_ACTIONS); - cookie.type = USER_ACTION_COOKIE_SFLOW; - cookie.data = port_ifindex; - cookie.n_output = n_output; - cookie.vlan_tci = 0; + cookie.sflow.type = USER_ACTION_COOKIE_SFLOW; + cookie.sflow.ifindex = port_ifindex; + cookie.sflow.n_output = n_output; + cookie.sflow.vlan_tci = htons(0); cookie_offset = put_userspace_action(ofproto, odp_actions, flow, &cookie); nl_msg_end_nested(odp_actions, actions_offset); @@ -4080,27 +4080,27 @@ static void fix_sflow_action(struct action_xlate_ctx *ctx) { const struct flow *base = &ctx->base_flow; - struct user_action_cookie *cookie; + union user_action_cookie *cookie; if (!ctx->user_cookie_offset) { return; } cookie = ofpbuf_at(ctx->odp_actions, ctx->user_cookie_offset, - sizeof(*cookie)); + sizeof *cookie); assert(cookie != NULL); assert(cookie->type == USER_ACTION_COOKIE_SFLOW); if (ctx->sflow_n_outputs) { - cookie->data = dpif_sflow_odp_port_to_ifindex(ctx->ofproto->sflow, - ctx->sflow_odp_port); + cookie->sflow.ifindex = dpif_sflow_odp_port_to_ifindex( + ctx->ofproto->sflow, ctx->sflow_odp_port); } if (ctx->sflow_n_outputs >= 255) { - cookie->n_output = 255; + cookie->sflow.n_output = 255; } else { - cookie->n_output = ctx->sflow_n_outputs; + cookie->sflow.n_output = ctx->sflow_n_outputs; } - cookie->vlan_tci = base->vlan_tci; + cookie->sflow.vlan_tci = base->vlan_tci; } static void @@ -4246,13 +4246,13 @@ flood_packets(struct action_xlate_ctx *ctx, bool all) static void compose_controller_action(struct action_xlate_ctx *ctx, int len) { - struct user_action_cookie cookie; + union user_action_cookie cookie; commit_odp_actions(&ctx->flow, &ctx->base_flow, ctx->odp_actions); - cookie.type = USER_ACTION_COOKIE_CONTROLLER; - cookie.data = len; - cookie.n_output = 0; - cookie.vlan_tci = 0; + + memset(&cookie, 0, sizeof cookie); + cookie.controller.type = USER_ACTION_COOKIE_CONTROLLER; + cookie.controller.max_len = len; put_userspace_action(ctx->ofproto, ctx->odp_actions, &ctx->flow, &cookie); } -- 1.7.2.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev