}
static const char *
-slow_path_reason_to_string(uint32_t data)
+slow_path_reason_to_string(enum slow_path_reason reason)
{
- enum slow_path_reason bit = (enum slow_path_reason) data;
-
- switch (bit) {
+ switch (reason) {
case SLOW_CFM:
return "cfm";
case SLOW_LACP:
return "lacp";
case SLOW_STP:
return "stp";
- case SLOW_IN_BAND:
- return "in_band";
+ case SLOW_BFD:
+ return "bfd";
case SLOW_CONTROLLER:
return "controller";
- case SLOW_MATCH:
- return "match";
+ case __SLOW_MAX:
default:
return NULL;
}
}
+static enum slow_path_reason
+string_to_slow_path_reason(const char *string)
+{
+ enum slow_path_reason i;
+
+ for (i = 1; i < __SLOW_MAX; i++) {
+ if (!strcmp(string, slow_path_reason_to_string(i))) {
+ return i;
+ }
+ }
+
+ return 0;
+}
+
static int
parse_flags(const char *s, const char *(*bit_to_string)(uint32_t),
uint32_t *res)
nl_attr_get_u32(a[OVS_USERSPACE_ATTR_PID]));
userdata_attr = a[OVS_USERSPACE_ATTR_USERDATA];
- if (userdata_attr && nl_attr_get_size(userdata_attr) == sizeof(uint64_t)) {
- uint64_t userdata = nl_attr_get_u64(a[OVS_USERSPACE_ATTR_USERDATA]);
- union user_action_cookie cookie;
-
- memcpy(&cookie, &userdata, sizeof cookie);
- switch (cookie.type) {
- case USER_ACTION_COOKIE_SFLOW:
- ds_put_format(ds, ",sFlow("
- "vid=%"PRIu16",pcp=%"PRIu8",output=%"PRIu32")",
- vlan_tci_to_vid(cookie.sflow.vlan_tci),
- vlan_tci_to_pcp(cookie.sflow.vlan_tci),
- cookie.sflow.output);
- break;
-
- case 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, ")");
- break;
+ if (userdata_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;
- case USER_ACTION_COOKIE_UNSPEC:
- default:
- ds_put_format(ds, ",userdata=0x%"PRIx64, userdata);
- break;
+ if (userdata_len >= sizeof cookie.type
+ && userdata_len <= sizeof cookie) {
+
+ memset(&cookie, 0, sizeof cookie);
+ memcpy(&cookie, userdata, userdata_len);
+
+ userdata_unspec = false;
+
+ if (userdata_len == sizeof cookie.sflow
+ && cookie.type == USER_ACTION_COOKIE_SFLOW) {
+ ds_put_format(ds, ",sFlow("
+ "vid=%"PRIu16",pcp=%"PRIu8",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) {
+ const char *reason;
+ reason = slow_path_reason_to_string(cookie.slow_path.reason);
+ reason = reason ? reason : "";
+ ds_put_format(ds, ",slow_path(%s)", reason);
+ } else if (userdata_len == sizeof cookie.flow_sample
+ && cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) {
+ ds_put_format(ds, ",flow_sample(probability=%"PRIu16
+ ",collector_set_id=%"PRIu32
+ ",obs_domain_id=%"PRIu32
+ ",obs_point_id=%"PRIu32")",
+ cookie.flow_sample.probability,
+ 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;
+ }
}
- } else if (userdata_attr) {
- const uint8_t *userdata = nl_attr_get(userdata_attr);
- size_t len = nl_attr_get_size(userdata_attr);
- size_t i;
- ds_put_format(ds, ",userdata(");
- for (i = 0; i < len; i++) {
- ds_put_format(ds, "%02x", userdata[i]);
+ if (userdata_unspec) {
+ size_t i;
+ ds_put_format(ds, ",userdata(");
+ for (i = 0; i < userdata_len; i++) {
+ ds_put_format(ds, "%02x", userdata[i]);
+ }
+ ds_put_char(ds, ')');
}
- ds_put_char(ds, ')');
}
ds_put_char(ds, ')');
{
unsigned long long int pid;
unsigned long long int output;
- char userdata_s[32];
+ unsigned long long int probability;
+ unsigned long long int collector_set_id;
+ unsigned long long int obs_domain_id;
+ unsigned long long int obs_point_id;
int vid, pcp;
int n = -1;
cookie.type = USER_ACTION_COOKIE_SFLOW;
cookie.sflow.vlan_tci = htons(tci);
cookie.sflow.output = output;
- odp_put_userspace_action(pid, &cookie, sizeof cookie, actions);
+ odp_put_userspace_action(pid, &cookie, sizeof cookie.sflow,
+ actions);
return n;
- } else if (sscanf(s, "userspace(pid=%lli,slow_path%n", &pid, &n) > 0
+ } else if (sscanf(s, "userspace(pid=%lli,slow_path(%n", &pid, &n) > 0
&& n > 0) {
union user_action_cookie cookie;
- int res;
+ char reason[32];
+
+ if (s[n] == ')' && s[n + 1] == ')') {
+ reason[0] = '\0';
+ n += 2;
+ } else if (sscanf(s + n, "%31[^)]))", reason) > 0) {
+ n += strlen(reason) + 2;
+ } else {
+ return -EINVAL;
+ }
cookie.type = USER_ACTION_COOKIE_SLOW_PATH;
cookie.slow_path.unused = 0;
- cookie.slow_path.reason = 0;
+ cookie.slow_path.reason = string_to_slow_path_reason(reason);
- res = parse_flags(&s[n], slow_path_reason_to_string,
- &cookie.slow_path.reason);
- if (res < 0) {
- return res;
- }
- n += res;
- if (s[n] != ')') {
+ if (reason[0] && !cookie.slow_path.reason) {
return -EINVAL;
}
- n++;
- odp_put_userspace_action(pid, &cookie, sizeof cookie, actions);
+ odp_put_userspace_action(pid, &cookie, sizeof cookie.slow_path,
+ actions);
return n;
- } else if (sscanf(s, "userspace(pid=%lli,userdata="
- "%31[x0123456789abcdefABCDEF])%n", &pid, userdata_s,
- &n) > 0 && n > 0) {
- uint64_t userdata;
+ } else if (sscanf(s, "userspace(pid=%lli,flow_sample(probability=%lli,"
+ "collector_set_id=%lli,obs_domain_id=%lli,"
+ "obs_point_id=%lli))%n",
+ &pid, &probability, &collector_set_id,
+ &obs_domain_id, &obs_point_id, &n) > 0 && n > 0) {
+ union user_action_cookie cookie;
- userdata = strtoull(userdata_s, NULL, 0);
- odp_put_userspace_action(pid, &userdata, sizeof(userdata),
+ cookie.type = USER_ACTION_COOKIE_FLOW_SAMPLE;
+ cookie.flow_sample.probability = probability;
+ cookie.flow_sample.collector_set_id = collector_set_id;
+ cookie.flow_sample.obs_domain_id = obs_domain_id;
+ cookie.flow_sample.obs_point_id = obs_point_id;
+ 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
case OVS_KEY_ATTR_MPLS: {
const struct ovs_key_mpls *mpls_key = nl_attr_get(a);
ds_put_char(ds, '(');
- format_mpls_lse(ds, mpls_key->mpls_top_lse);
+ format_mpls_lse(ds, mpls_key->mpls_lse);
ds_put_char(ds, ')');
break;
}
mpls = nl_msg_put_unspec_uninit(key, OVS_KEY_ATTR_MPLS,
sizeof *mpls);
- mpls->mpls_top_lse = mpls_lse_from_components(label, tc, ttl, bos);
+ mpls->mpls_lse = mpls_lse_from_components(label, tc, ttl, bos);
return n;
}
}
mpls_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_MPLS,
sizeof *mpls_key);
- mpls_key->mpls_top_lse = flow->mpls_lse;
+ mpls_key->mpls_lse = flow->mpls_lse;
}
if (is_ip_any(flow) && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
enum odp_key_fitness fitness;
ovs_be16 tci;
- /* Calulate fitness of outer attributes. */
+ /* Calculate fitness of outer attributes. */
expected_attrs |= ((UINT64_C(1) << OVS_KEY_ATTR_VLAN) |
(UINT64_C(1) << OVS_KEY_ATTR_ENCAP));
fitness = check_expectations(present_attrs, out_of_range_attr,
commit_odp_tunnel_action(const struct flow *flow, struct flow *base,
struct ofpbuf *odp_actions)
{
- if (!memcmp(&base->tunnel, &flow->tunnel, sizeof base->tunnel)) {
- return;
- }
- memcpy(&base->tunnel, &flow->tunnel, sizeof base->tunnel);
-
/* A valid IPV4_TUNNEL must have non-zero ip_dst. */
if (flow->tunnel.ip_dst) {
+ if (!memcmp(&base->tunnel, &flow->tunnel, sizeof base->tunnel)) {
+ return;
+ }
+ memcpy(&base->tunnel, &flow->tunnel, sizeof base->tunnel);
odp_put_tunnel_action(&base->tunnel, odp_actions);
}
}
} else {
struct ovs_key_mpls mpls_key;
- mpls_key.mpls_top_lse = flow->mpls_lse;
+ mpls_key.mpls_lse = flow->mpls_lse;
commit_set_action(odp_actions, OVS_KEY_ATTR_MPLS,
&mpls_key, sizeof(mpls_key));
}
commit_vlan_action(flow, base, odp_actions);
commit_set_nw_action(flow, base, odp_actions);
commit_set_port_action(flow, base, odp_actions);
- /* Commiting MPLS actions should occur after committing nw and port
+ /* Committing MPLS actions should occur after committing nw and port
* actions. This is because committing MPLS actions may alter a packet so
* that it is no longer IP and thus nw and port actions are no longer valid.
*/