From fcb9579be3c7717744e63a343a86a0dbcf0d3d78 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Tue, 3 Oct 2017 17:31:34 -0700 Subject: [PATCH] ofproto: Add 'ofproto_uuid' and 'ofp_in_port' to user action cookie. Previously, the ofproto instance and OpenFlow port have been derived based on the datapath port number. This change explicitly declares them both, which will be helpful in future commits that no longer can depend on having a unique datapath port (e.g., a source port that represents the controller). Signed-off-by: Justin Pettit Acked-by: Ben Pfaff --- lib/odp-util.c | 9 ++++++- lib/odp-util.h | 5 +++- ofproto/ofproto-dpif-upcall.c | 49 ++++++++++++++++++++++++----------- ofproto/ofproto-dpif-xlate.c | 13 +++++++--- 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/lib/odp-util.c b/lib/odp-util.c index 2910e151498..a2a8d615f70 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -1142,13 +1142,16 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions) } cookie.type = USER_ACTION_COOKIE_SFLOW; + cookie.ofp_in_port = OFPP_NONE; + cookie.ofproto_uuid = UUID_ZERO; cookie.sflow.vlan_tci = htons(tci); cookie.sflow.output = output; } else if (ovs_scan(&s[n], ",slow_path(%n", &n1)) { n += n1; cookie.type = USER_ACTION_COOKIE_SLOW_PATH; - cookie.slow_path.unused = 0; + cookie.ofp_in_port = OFPP_NONE; + cookie.ofproto_uuid = UUID_ZERO; cookie.slow_path.reason = 0; res = parse_odp_flags(&s[n], slow_path_reason_to_string, @@ -1169,6 +1172,8 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions) n += n1; cookie.type = USER_ACTION_COOKIE_FLOW_SAMPLE; + cookie.ofp_in_port = OFPP_NONE; + cookie.ofproto_uuid = UUID_ZERO; cookie.flow_sample.probability = probability; cookie.flow_sample.collector_set_id = collector_set_id; cookie.flow_sample.obs_domain_id = obs_domain_id; @@ -1193,6 +1198,8 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions) &output, &n1) ) { n += n1; cookie.type = USER_ACTION_COOKIE_IPFIX; + cookie.ofp_in_port = OFPP_NONE; + cookie.ofproto_uuid = UUID_ZERO; cookie.ipfix.output_odp_port = u32_to_odp(output); } else if (ovs_scan(&s[n], ",userdata(%n", &n1)) { diff --git a/lib/odp-util.h b/lib/odp-util.h index b08ff719016..2a4b3d13812 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -25,6 +25,7 @@ #include "hash.h" #include "openvswitch/hmap.h" #include "openvswitch/ofp-actions.h" +#include "openvswitch/uuid.h" #include "odp-netlink.h" #include "openflow/openflow.h" #include "util.h" @@ -302,6 +303,8 @@ enum user_action_cookie_type { /* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE. */ struct user_action_cookie { uint16_t type; /* enum user_action_cookie_type. */ + ofp_port_t ofp_in_port; /* OpenFlow in port, or OFPP_NONE. */ + struct uuid ofproto_uuid; /* UUID of ofproto-dpif. */ union { struct { @@ -332,7 +335,7 @@ struct user_action_cookie { } ipfix; }; }; -BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 28); +BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 48); size_t odp_put_userspace_action(uint32_t pid, const void *userdata, size_t userdata_size, diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 5ba1006893d..bd7dc9e7b71 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -38,6 +38,7 @@ #include "packets.h" #include "openvswitch/poll-loop.h" #include "seq.h" +#include "tunnel.h" #include "unixctl.h" #include "openvswitch/vlog.h" @@ -207,7 +208,7 @@ struct upcall { const ovs_u128 *ufid; /* Unique identifier for 'flow'. */ unsigned pmd_id; /* Datapath poll mode driver id. */ const struct dp_packet *packet; /* Packet associated with this upcall. */ - ofp_port_t in_port; /* OpenFlow in port, or OFPP_NONE. */ + ofp_port_t ofp_in_port; /* OpenFlow in port, or OFPP_NONE. */ uint16_t mru; /* If !0, Maximum receive unit of fragmented IP packet */ @@ -1021,16 +1022,18 @@ classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata, * initialized with at least 128 bytes of space. */ static void compose_slow_path(struct udpif *udpif, struct xlate_out *xout, - const struct flow *flow, odp_port_t odp_in_port, + const struct flow *flow, + odp_port_t odp_in_port, ofp_port_t ofp_in_port, struct ofpbuf *buf, uint32_t slowpath_meter_id, - uint32_t controller_meter_id) + uint32_t controller_meter_id, struct uuid *ofproto_uuid) { struct user_action_cookie cookie; odp_port_t port; uint32_t pid; cookie.type = USER_ACTION_COOKIE_SLOW_PATH; - cookie.slow_path.unused = 0; + cookie.ofp_in_port = ofp_in_port; + cookie.ofproto_uuid = *ofproto_uuid; cookie.slow_path.reason = xout->slow; port = xout->slow & (SLOW_CFM | SLOW_BFD | SLOW_LACP | SLOW_STP) @@ -1077,12 +1080,23 @@ upcall_receive(struct upcall *upcall, const struct dpif_backer *backer, upcall->type = classify_upcall(type, userdata, &upcall->cookie); if (upcall->type == BAD_UPCALL) { return EAGAIN; - } - - error = xlate_lookup(backer, flow, &upcall->ofproto, &upcall->ipfix, - &upcall->sflow, NULL, &upcall->in_port); - if (error) { - return error; + } else if (upcall->type == MISS_UPCALL) { + error = xlate_lookup(backer, flow, &upcall->ofproto, &upcall->ipfix, + &upcall->sflow, NULL, &upcall->ofp_in_port); + if (error) { + return error; + } + } else { + struct ofproto_dpif *ofproto + = ofproto_dpif_lookup_by_uuid(&upcall->cookie.ofproto_uuid); + if (!ofproto) { + VLOG_INFO_RL(&rl, "upcall could not find ofproto"); + return ENODEV; + } + upcall->ofproto = ofproto; + upcall->ipfix = ofproto->ipfix; + upcall->sflow = ofproto->sflow; + upcall->ofp_in_port = upcall->cookie.ofp_in_port; } upcall->recirc = NULL; @@ -1123,7 +1137,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall, xlate_in_init(&xin, upcall->ofproto, ofproto_dpif_get_tables_version(upcall->ofproto), - upcall->flow, upcall->in_port, NULL, + upcall->flow, upcall->ofp_in_port, NULL, stats.tcp_flags, upcall->packet, wc, odp_actions); if (upcall->type == MISS_UPCALL) { @@ -1168,8 +1182,9 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall, uint32_t cmid = upcall->ofproto->up.controller_meter_id; /* upcall->put_actions already initialized by upcall_receive(). */ compose_slow_path(udpif, &upcall->xout, upcall->flow, - upcall->flow->in_port.odp_port, - &upcall->put_actions, smid, cmid); + upcall->flow->in_port.odp_port, upcall->ofp_in_port, + &upcall->put_actions, smid, cmid, + &upcall->ofproto->uuid); } /* This function is also called for slow-pathed flows. As we are only @@ -2025,13 +2040,17 @@ revalidate_ukey__(struct udpif *udpif, const struct udpif_key *ukey, if (xoutp->slow) { struct ofproto_dpif *ofproto; - ofproto = xlate_lookup_ofproto(udpif->backer, &ctx.flow, NULL); + ofp_port_t ofp_in_port; + + ofproto = xlate_lookup_ofproto(udpif->backer, &ctx.flow, + &ofp_in_port); uint32_t smid = ofproto ? ofproto->up.slowpath_meter_id : UINT32_MAX; uint32_t cmid = ofproto ? ofproto->up.controller_meter_id : UINT32_MAX; ofpbuf_clear(odp_actions); compose_slow_path(udpif, xoutp, &ctx.flow, ctx.flow.in_port.odp_port, - odp_actions, smid, cmid); + ofp_in_port, odp_actions, smid, cmid, + &ofproto->uuid); } if (odp_flow_key_to_mask(ukey->mask, ukey->mask_len, &dp_mask, &ctx.flow) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 94bdac14a7f..625063a3193 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -2927,7 +2927,11 @@ compose_sflow_action(struct xlate_ctx *ctx) return 0; } - struct user_action_cookie cookie = { .type = USER_ACTION_COOKIE_SFLOW }; + struct user_action_cookie cookie = { + .type = USER_ACTION_COOKIE_SFLOW, + .ofp_in_port = ctx->xin->flow.in_port.ofp_port, + .ofproto_uuid = ctx->xbridge->ofproto->uuid + }; return compose_sample_action(ctx, dpif_sflow_get_probability(sflow), &cookie, ODPP_NONE, true); } @@ -2969,7 +2973,9 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port) struct user_action_cookie cookie = { .type = USER_ACTION_COOKIE_IPFIX, - .ipfix.output_odp_port = output_odp_port, + .ofp_in_port = ctx->xin->flow.in_port.ofp_port, + .ofproto_uuid = ctx->xbridge->ofproto->uuid, + .ipfix.output_odp_port = output_odp_port }; compose_sample_action(ctx, dpif_ipfix_get_bridge_exporter_probability(ipfix), @@ -2990,7 +2996,6 @@ fix_sflow_action(struct xlate_ctx *ctx, unsigned int user_cookie_offset) cookie = ofpbuf_at(ctx->odp_actions, user_cookie_offset, sizeof *cookie); ovs_assert(cookie->type == USER_ACTION_COOKIE_SFLOW); - cookie->type = USER_ACTION_COOKIE_SFLOW; cookie->sflow.vlan_tci = base->vlans[0].tci; /* See http://www.sflow.org/sflow_version_5.txt (search for "Input/output @@ -5270,6 +5275,8 @@ xlate_sample_action(struct xlate_ctx *ctx, struct user_action_cookie cookie = { .type = USER_ACTION_COOKIE_FLOW_SAMPLE, + .ofp_in_port = ctx->xin->flow.in_port.ofp_port, + .ofproto_uuid = ctx->xbridge->ofproto->uuid, .flow_sample = { .probability = os->probability, .collector_set_id = os->collector_set_id,