Skip to content

Commit

Permalink
ofproto-dpif: Use a fixed size userspace cookie.
Browse files Browse the repository at this point in the history
This simplifies the cookie handling a bit.

Signed-off-by: Justin Pettit <jpettit@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
justinpettit committed Jan 11, 2018
1 parent ae9f2ce commit 8de6ff3
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 122 deletions.
35 changes: 11 additions & 24 deletions lib/odp-util.c
Expand Up @@ -437,31 +437,25 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr,
const uint8_t *userdata = nl_attr_get(userdata_attr);
size_t userdata_len = nl_attr_get_size(userdata_attr);
bool userdata_unspec = true;
union user_action_cookie cookie;
struct user_action_cookie cookie;

if (userdata_len >= sizeof cookie.type
&& userdata_len <= sizeof cookie) {

memset(&cookie, 0, sizeof cookie);
memcpy(&cookie, userdata, userdata_len);
if (userdata_len == sizeof cookie) {
memcpy(&cookie, userdata, sizeof cookie);

userdata_unspec = false;

if (userdata_len == sizeof cookie.sflow
&& cookie.type == USER_ACTION_COOKIE_SFLOW) {
if (cookie.type == USER_ACTION_COOKIE_SFLOW) {
ds_put_format(ds, ",sFlow("
"vid=%"PRIu16",pcp=%d,output=%"PRIu32")",
vlan_tci_to_vid(cookie.sflow.vlan_tci),
vlan_tci_to_pcp(cookie.sflow.vlan_tci),
cookie.sflow.output);
} else if (userdata_len == sizeof cookie.slow_path
&& cookie.type == USER_ACTION_COOKIE_SLOW_PATH) {
} else if (cookie.type == USER_ACTION_COOKIE_SLOW_PATH) {
ds_put_cstr(ds, ",slow_path(");
format_flags(ds, slow_path_reason_to_string,
cookie.slow_path.reason, ',');
ds_put_format(ds, ")");
} else if (userdata_len == sizeof cookie.flow_sample
&& cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) {
} else if (cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) {
ds_put_format(ds, ",flow_sample(probability=%"PRIu16
",collector_set_id=%"PRIu32
",obs_domain_id=%"PRIu32
Expand All @@ -479,8 +473,7 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr,
ds_put_cstr(ds, ",egress");
}
ds_put_char(ds, ')');
} else if (userdata_len >= sizeof cookie.ipfix
&& cookie.type == USER_ACTION_COOKIE_IPFIX) {
} else if (cookie.type == USER_ACTION_COOKIE_IPFIX) {
ds_put_format(ds, ",ipfix(output_port=");
odp_portno_name_format(portno_names,
cookie.ipfix.output_odp_port, ds);
Expand Down Expand Up @@ -1111,7 +1104,7 @@ static int
parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
{
uint32_t pid;
union user_action_cookie cookie;
struct user_action_cookie cookie;
struct ofpbuf buf;
odp_port_t tunnel_out_port;
int n = -1;
Expand All @@ -1125,7 +1118,10 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
}

ofpbuf_init(&buf, 16);
memset(&cookie, 0, sizeof cookie);

user_data = &cookie;
user_data_size = sizeof cookie;
{
uint32_t output;
uint32_t probability;
Expand All @@ -1148,8 +1144,6 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
cookie.type = USER_ACTION_COOKIE_SFLOW;
cookie.sflow.vlan_tci = htons(tci);
cookie.sflow.output = output;
user_data = &cookie;
user_data_size = sizeof cookie.sflow;
} else if (ovs_scan(&s[n], ",slow_path(%n",
&n1)) {
n += n1;
Expand All @@ -1164,9 +1158,6 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
goto out;
}
n += res + 1;

user_data = &cookie;
user_data_size = sizeof cookie.slow_path;
} else if (ovs_scan(&s[n], ",flow_sample(probability=%"SCNi32","
"collector_set_id=%"SCNi32","
"obs_domain_id=%"SCNi32","
Expand All @@ -1183,8 +1174,6 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
cookie.flow_sample.obs_domain_id = obs_domain_id;
cookie.flow_sample.obs_point_id = obs_point_id;
cookie.flow_sample.output_odp_port = u32_to_odp(output);
user_data = &cookie;
user_data_size = sizeof cookie.flow_sample;

if (ovs_scan(&s[n], ",ingress%n", &n1)) {
cookie.flow_sample.direction = NX_ACTION_SAMPLE_INGRESS;
Expand All @@ -1205,8 +1194,6 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
n += n1;
cookie.type = USER_ACTION_COOKIE_IPFIX;
cookie.ipfix.output_odp_port = u32_to_odp(output);
user_data = &cookie;
user_data_size = sizeof cookie.ipfix;
} else if (ovs_scan(&s[n], ",userdata(%n",
&n1)) {
char *end;
Expand Down
58 changes: 30 additions & 28 deletions lib/odp-util.h
Expand Up @@ -300,37 +300,39 @@ enum user_action_cookie_type {
};

/* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE. */
union user_action_cookie {
struct user_action_cookie {
uint16_t type; /* enum user_action_cookie_type. */

struct {
uint16_t type; /* USER_ACTION_COOKIE_SFLOW. */
ovs_be16 vlan_tci; /* Destination VLAN TCI. */
uint32_t output; /* SFL_FLOW_SAMPLE_TYPE 'output' value. */
} sflow;

struct {
uint16_t type; /* USER_ACTION_COOKIE_SLOW_PATH. */
uint16_t unused;
uint32_t reason; /* enum slow_path_reason. */
} slow_path;

struct {
uint16_t type; /* USER_ACTION_COOKIE_FLOW_SAMPLE. */
uint16_t probability; /* Sampling probability. */
uint32_t collector_set_id; /* ID of IPFIX collector set. */
uint32_t obs_domain_id; /* Observation Domain ID. */
uint32_t obs_point_id; /* Observation Point ID. */
odp_port_t output_odp_port; /* The output odp port. */
enum nx_action_sample_direction direction;
} flow_sample;

struct {
uint16_t type; /* USER_ACTION_COOKIE_IPFIX. */
odp_port_t output_odp_port; /* The output odp port. */
} ipfix;
union {
struct {
/* USER_ACTION_COOKIE_SFLOW. */
ovs_be16 vlan_tci; /* Destination VLAN TCI. */
uint32_t output; /* SFL_FLOW_SAMPLE_TYPE 'output' value. */
} sflow;

struct {
/* USER_ACTION_COOKIE_SLOW_PATH. */
uint16_t unused;
uint32_t reason; /* enum slow_path_reason. */
} slow_path;

struct {
/* USER_ACTION_COOKIE_FLOW_SAMPLE. */
uint16_t probability; /* Sampling probability. */
uint32_t collector_set_id; /* ID of IPFIX collector set. */
uint32_t obs_domain_id; /* Observation Domain ID. */
uint32_t obs_point_id; /* Observation Point ID. */
odp_port_t output_odp_port; /* The output odp port. */
enum nx_action_sample_direction direction;
} flow_sample;

struct {
/* USER_ACTION_COOKIE_IPFIX. */
odp_port_t output_odp_port; /* The output odp port. */
} ipfix;
};
};
BUILD_ASSERT_DECL(sizeof(union user_action_cookie) == 24);
BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 28);

size_t odp_put_userspace_action(uint32_t pid,
const void *userdata, size_t userdata_size,
Expand Down
2 changes: 1 addition & 1 deletion ofproto/ofproto-dpif-ipfix.c
Expand Up @@ -2732,7 +2732,7 @@ dpif_ipfix_bridge_sample(struct dpif_ipfix *di, const struct dp_packet *packet,
void
dpif_ipfix_flow_sample(struct dpif_ipfix *di, const struct dp_packet *packet,
const struct flow *flow,
const union user_action_cookie *cookie,
const struct user_action_cookie *cookie,
odp_port_t input_odp_port,
const struct flow_tnl *output_tunnel_key,
const struct dpif_ipfix_actions *ipfix_actions)
Expand Down
3 changes: 2 additions & 1 deletion ofproto/ofproto-dpif-ipfix.h
Expand Up @@ -60,7 +60,8 @@ void dpif_ipfix_bridge_sample(struct dpif_ipfix *, const struct dp_packet *,
odp_port_t, odp_port_t, const struct flow_tnl *,
const struct dpif_ipfix_actions *);
void dpif_ipfix_flow_sample(struct dpif_ipfix *, const struct dp_packet *,
const struct flow *, const union user_action_cookie *,
const struct flow *,
const struct user_action_cookie *,
odp_port_t, const struct flow_tnl *,
const struct dpif_ipfix_actions *);

Expand Down
14 changes: 7 additions & 7 deletions ofproto/ofproto-dpif-sflow.c
Expand Up @@ -1233,7 +1233,7 @@ dpif_sflow_encode_mpls_stack(SFLLabelStack *stack,
* See http://sflow.org/sflow_version_5.txt "Input/Output port information"
*/
static uint32_t
dpif_sflow_cookie_num_outputs(const union user_action_cookie *cookie)
dpif_sflow_cookie_num_outputs(const struct user_action_cookie *cookie)
{
uint32_t format = cookie->sflow.output & 0xC0000000;
uint32_t port_n = cookie->sflow.output & 0x3FFFFFFF;
Expand All @@ -1248,9 +1248,9 @@ dpif_sflow_cookie_num_outputs(const union user_action_cookie *cookie)

void
dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet,
const struct flow *flow, odp_port_t odp_in_port,
const union user_action_cookie *cookie,
const struct dpif_sflow_actions *sflow_actions)
const struct flow *flow, odp_port_t odp_in_port,
const struct user_action_cookie *cookie,
const struct dpif_sflow_actions *sflow_actions)
OVS_EXCLUDED(mutex)
{
SFL_FLOW_SAMPLE_TYPE fs;
Expand Down Expand Up @@ -1283,9 +1283,9 @@ dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet,
fs.input = SFL_DS_INDEX(in_dsp->dsi);
}

/* Make the assumption that the random number generator in the datapath converges
* to the configured mean, and just increment the samplePool by the configured
* sampling rate every time. */
/* Make the assumption that the random number generator in the
* datapath converges to the configured mean, and just increment the
* samplePool by the configured sampling rate every time. */
sampler->samplePool += sfl_sampler_get_sFlowFsPacketSamplingRate(sampler);

/* Sampled header. */
Expand Down
8 changes: 4 additions & 4 deletions ofproto/ofproto-dpif-sflow.h
Expand Up @@ -70,13 +70,13 @@ void dpif_sflow_run(struct dpif_sflow *);
void dpif_sflow_wait(struct dpif_sflow *);

void dpif_sflow_read_actions(const struct flow *,
const struct nlattr *actions, size_t actions_len,
struct dpif_sflow_actions *);
const struct nlattr *actions, size_t actions_len,
struct dpif_sflow_actions *);

void dpif_sflow_received(struct dpif_sflow *, const struct dp_packet *,
const struct flow *, odp_port_t odp_port,
const union user_action_cookie *,
const struct dpif_sflow_actions *);
const struct user_action_cookie *,
const struct dpif_sflow_actions *);

int dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *,
odp_port_t odp_port);
Expand Down
53 changes: 26 additions & 27 deletions ofproto/ofproto-dpif-upcall.c
Expand Up @@ -971,9 +971,6 @@ udpif_revalidator(void *arg)
static enum upcall_type
classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata)
{
union user_action_cookie cookie;
size_t userdata_len;

/* First look at the upcall type. */
switch (type) {
case DPIF_UC_ACTION:
Expand All @@ -993,26 +990,22 @@ classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata)
VLOG_WARN_RL(&rl, "action upcall missing cookie");
return BAD_UPCALL;
}
userdata_len = nl_attr_get_size(userdata);
if (userdata_len < sizeof cookie.type
|| userdata_len > sizeof cookie) {

struct user_action_cookie cookie;
size_t userdata_len = nl_attr_get_size(userdata);
if (userdata_len != sizeof cookie) {
VLOG_WARN_RL(&rl, "action upcall cookie has unexpected size %"PRIuSIZE,
userdata_len);
return BAD_UPCALL;
}
memset(&cookie, 0, sizeof cookie);
memcpy(&cookie, nl_attr_get(userdata), userdata_len);
if (userdata_len == MAX(8, sizeof cookie.sflow)
&& cookie.type == USER_ACTION_COOKIE_SFLOW) {
memcpy(&cookie, nl_attr_get(userdata), sizeof cookie);
if (cookie.type == USER_ACTION_COOKIE_SFLOW) {
return SFLOW_UPCALL;
} else if (userdata_len == MAX(8, sizeof cookie.slow_path)
&& cookie.type == USER_ACTION_COOKIE_SLOW_PATH) {
} else if (cookie.type == USER_ACTION_COOKIE_SLOW_PATH) {
return MISS_UPCALL;
} else if (userdata_len == MAX(8, sizeof cookie.flow_sample)
&& cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) {
} else if (cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) {
return FLOW_SAMPLE_UPCALL;
} else if (userdata_len == MAX(8, sizeof cookie.ipfix)
&& cookie.type == USER_ACTION_COOKIE_IPFIX) {
} else if (cookie.type == USER_ACTION_COOKIE_IPFIX) {
return IPFIX_UPCALL;
} else {
VLOG_WARN_RL(&rl, "invalid user cookie of type %"PRIu16
Expand All @@ -1029,7 +1022,7 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout,
struct ofpbuf *buf, uint32_t slowpath_meter_id,
uint32_t controller_meter_id)
{
union user_action_cookie cookie;
struct user_action_cookie cookie;
odp_port_t port;
uint32_t pid;

Expand All @@ -1056,7 +1049,7 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout,
nl_msg_put_u32(buf, OVS_ACTION_ATTR_METER, meter_id);
}

odp_put_userspace_action(pid, &cookie, sizeof cookie.slow_path,
odp_put_userspace_action(pid, &cookie, sizeof cookie,
ODPP_NONE, false, buf);

if (meter_id != UINT32_MAX) {
Expand Down Expand Up @@ -1349,12 +1342,14 @@ process_upcall(struct udpif *udpif, struct upcall *upcall,

case SFLOW_UPCALL:
if (upcall->sflow) {
union user_action_cookie cookie;
struct user_action_cookie cookie;
struct dpif_sflow_actions sflow_actions;

if (nl_attr_get_size(userdata) != sizeof cookie) {
return EINVAL;
}
memcpy(&cookie, nl_attr_get(userdata), sizeof cookie);
memset(&sflow_actions, 0, sizeof sflow_actions);
memset(&cookie, 0, sizeof cookie);
memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.sflow);

actions_len = dpif_read_actions(udpif, upcall, flow, upcall_type,
&sflow_actions);
Expand All @@ -1366,12 +1361,14 @@ process_upcall(struct udpif *udpif, struct upcall *upcall,

case IPFIX_UPCALL:
if (upcall->ipfix) {
union user_action_cookie cookie;
struct user_action_cookie cookie;
struct flow_tnl output_tunnel_key;
struct dpif_ipfix_actions ipfix_actions;

memset(&cookie, 0, sizeof cookie);
memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.ipfix);
if (nl_attr_get_size(userdata) != sizeof cookie) {
return EINVAL;
}
memcpy(&cookie, nl_attr_get(userdata), sizeof cookie);
memset(&ipfix_actions, 0, sizeof ipfix_actions);

if (upcall->out_tun_key) {
Expand All @@ -1391,12 +1388,14 @@ process_upcall(struct udpif *udpif, struct upcall *upcall,

case FLOW_SAMPLE_UPCALL:
if (upcall->ipfix) {
union user_action_cookie cookie;
struct user_action_cookie cookie;
struct flow_tnl output_tunnel_key;
struct dpif_ipfix_actions ipfix_actions;

memset(&cookie, 0, sizeof cookie);
memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.flow_sample);
if (nl_attr_get_size(userdata) != sizeof cookie) {
return EINVAL;
}
memcpy(&cookie, nl_attr_get(userdata), sizeof cookie);
memset(&ipfix_actions, 0, sizeof ipfix_actions);

if (upcall->out_tun_key) {
Expand Down

0 comments on commit 8de6ff3

Please sign in to comment.