The "ipfix" upcall is used to per-bridge packet sampling to IPFIX collectors.
Signed-off-by: Romain Lenglet <rleng...@vmware.com> --- lib/odp-util.c | 11 +++++++++++ lib/odp-util.h | 7 ++++++- ofproto/ofproto-dpif.c | 26 +++++++++++++++++++++++++- tests/odp.at | 1 + 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/odp-util.c b/lib/odp-util.c index 52923fc..b755c7a 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -300,6 +300,9 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr) cookie.flow_sample.collector_set_id, cookie.flow_sample.obs_domain_id, cookie.flow_sample.obs_point_id); + } else if (userdata_len == sizeof cookie.ipfix + && cookie.type == USER_ACTION_COOKIE_IPFIX) { + ds_put_format(ds, ",ipfix"); } else { userdata_unspec = true; } @@ -535,6 +538,14 @@ parse_odp_action(const char *s, const struct simap *port_names, odp_put_userspace_action(pid, &cookie, sizeof cookie.flow_sample, actions); return n; + } else if (sscanf(s, "userspace(pid=%lli,ipfix)%n", &pid, &n) > 0 + && n > 0) { + union user_action_cookie cookie; + + cookie.type = USER_ACTION_COOKIE_IPFIX; + odp_put_userspace_action(pid, &cookie, sizeof cookie.ipfix, + actions); + return n; } else if (sscanf(s, "userspace(pid=%lli,userdata(%n", &pid, &n) > 0 && n > 0) { struct ofpbuf buf; diff --git a/lib/odp-util.h b/lib/odp-util.h index 0198a54..0b34383 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -127,9 +127,10 @@ void commit_odp_actions(const struct flow *, struct flow *base, enum user_action_cookie_type { USER_ACTION_COOKIE_UNSPEC, - USER_ACTION_COOKIE_SFLOW, /* Packet for sFlow sampling. */ + USER_ACTION_COOKIE_SFLOW, /* Packet for per-bridge sFlow sampling. */ USER_ACTION_COOKIE_SLOW_PATH, /* Userspace must process this flow. */ USER_ACTION_COOKIE_FLOW_SAMPLE, /* Packet for per-flow sampling. */ + USER_ACTION_COOKIE_IPFIX, /* Packet for per-bridge IPFIX sampling. */ }; /* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE. @@ -156,6 +157,10 @@ union user_action_cookie { uint32_t obs_domain_id; /* Observation Domain ID. */ uint32_t obs_point_id; /* Observation Point ID. */ } flow_sample; + + struct { + uint16_t type; /* USER_ACTION_COOKIE_IPFIX. */ + } ipfix; }; BUILD_ASSERT_DECL(sizeof(union user_action_cookie) == 16); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 8708d0f..c11e3c3 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -4007,7 +4007,8 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls, hmap_destroy(&todo); } -static enum { SFLOW_UPCALL, MISS_UPCALL, BAD_UPCALL, FLOW_SAMPLE_UPCALL } +static enum { SFLOW_UPCALL, MISS_UPCALL, BAD_UPCALL, FLOW_SAMPLE_UPCALL, + IPFIX_UPCALL } classify_upcall(const struct dpif_upcall *upcall) { size_t userdata_len; @@ -4050,6 +4051,9 @@ classify_upcall(const struct dpif_upcall *upcall) } else if (userdata_len == sizeof cookie.flow_sample && cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) { return FLOW_SAMPLE_UPCALL; + } else if (userdata_len == sizeof cookie.ipfix + && cookie.type == USER_ACTION_COOKIE_IPFIX) { + return IPFIX_UPCALL; } else { VLOG_WARN_RL(&rl, "invalid user cookie of type %"PRIu16 " and size %zu", cookie.type, userdata_len); @@ -4085,6 +4089,13 @@ handle_flow_sample_upcall(struct dpif_backer *backer OVS_UNUSED, /* TODO: Send a IPFIX flow record to each IPFIX collector. */ } +static void +handle_ipfix_upcall(struct dpif_backer *backer OVS_UNUSED, + const struct dpif_upcall *upcall OVS_UNUSED) +{ + /* TODO: Send IPFIX flow records. */ +} + static int handle_upcalls(struct dpif_backer *backer, unsigned int max_batch) { @@ -4127,6 +4138,11 @@ handle_upcalls(struct dpif_backer *backer, unsigned int max_batch) ofpbuf_uninit(buf); break; + case IPFIX_UPCALL: + handle_ipfix_upcall(backer, upcall); + ofpbuf_uninit(buf); + break; + case BAD_UPCALL: ofpbuf_uninit(buf); break; @@ -5933,6 +5949,14 @@ compose_flow_sample_cookie(uint16_t probability, uint32_t collector_set_id, cookie->flow_sample.obs_point_id = obs_point_id; } +static void compose_ipfix_cookie(union user_action_cookie *) OVS_UNUSED; + +static void +compose_ipfix_cookie(union user_action_cookie *cookie) +{ + cookie->type = USER_ACTION_COOKIE_IPFIX; +} + /* SAMPLE action must be first action in any given list of actions. * At this point we do not have all information required to build it. So try to * build sample action as complete as possible. */ diff --git a/tests/odp.at b/tests/odp.at index ec99ec5..a6bcdf5 100644 --- a/tests/odp.at +++ b/tests/odp.at @@ -90,6 +90,7 @@ userspace(pid=9765,slow_path(cfm)) userspace(pid=9765,slow_path(cfm,match)) userspace(pid=1234567,userdata(0102030405060708090a0b0c0d0e0f)) userspace(pid=6633,flow_sample(probability=123,collector_set_id=1234,obs_domain_id=2345,obs_point_id=3456)) +userspace(pid=6633,ipfix) set(in_port(2)) set(eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15)) set(eth_type(0x1234)) -- 1.8.1.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev