return -1;
}
+/* Returns a string form of 'attr'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'namebuf'. 'bufsize'
+ * should be at least OVS_KEY_ATTR_BUFSIZE. */
+enum { OVS_KEY_ATTR_BUFSIZE = 3 + INT_STRLEN(unsigned int) + 1 };
static const char *
-ovs_key_attr_to_string(enum ovs_key_attr attr)
+ovs_key_attr_to_string(enum ovs_key_attr attr, char *namebuf, size_t bufsize)
{
- static char unknown_attr[3 + INT_STRLEN(unsigned int) + 1];
-
switch (attr) {
case OVS_KEY_ATTR_UNSPEC: return "unspec";
case OVS_KEY_ATTR_ENCAP: return "encap";
case __OVS_KEY_ATTR_MAX:
default:
- snprintf(unknown_attr, sizeof unknown_attr, "key%u",
- (unsigned int) attr);
- return unknown_attr;
+ snprintf(namebuf, bufsize, "key%u", (unsigned int) attr);
+ return namebuf;
}
}
}
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)
cookie.sflow.output);
} else if (userdata_len == sizeof cookie.slow_path
&& 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, ")");
+ 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
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.slow_path,
actions);
return -1;
}
-static enum odp_key_fitness
-tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
+enum odp_key_fitness
+odp_tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
{
unsigned int left;
const struct nlattr *a;
const struct ovs_key_nd *nd_key;
struct flow_tnl tun_key;
enum ovs_key_attr attr = nl_attr_type(a);
+ char namebuf[OVS_KEY_ATTR_BUFSIZE];
int expected_len;
- ds_put_cstr(ds, ovs_key_attr_to_string(attr));
+ ds_put_cstr(ds, ovs_key_attr_to_string(attr, namebuf, sizeof namebuf));
expected_len = odp_flow_key_attr_len(nl_attr_type(a));
if (expected_len != -2 && nl_attr_get_size(a) != expected_len) {
ds_put_format(ds, "(bad length %zu, expected %d)",
case OVS_KEY_ATTR_TUNNEL:
memset(&tun_key, 0, sizeof tun_key);
- if (tun_key_from_attr(a, &tun_key) == ODP_FIT_ERROR) {
+ if (odp_tun_key_from_attr(a, &tun_key) == ODP_FIT_ERROR) {
ds_put_format(ds, "(error)");
} else {
ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
ds_init(&s);
for (i = 0; i < 64; i++) {
if (attrs & (UINT64_C(1) << i)) {
- ds_put_format(&s, " %s", ovs_key_attr_to_string(i));
+ char namebuf[OVS_KEY_ATTR_BUFSIZE];
+
+ ds_put_format(&s, " %s",
+ ovs_key_attr_to_string(i, namebuf, sizeof namebuf));
}
}
if (out_of_range_attr) {
int expected_len = odp_flow_key_attr_len(type);
if (len != expected_len && expected_len >= 0) {
+ char namebuf[OVS_KEY_ATTR_BUFSIZE];
+
VLOG_ERR_RL(&rl, "attribute %s has length %zu but should have "
- "length %d", ovs_key_attr_to_string(type),
+ "length %d", ovs_key_attr_to_string(type, namebuf,
+ sizeof namebuf),
len, expected_len);
return false;
}
*out_of_range_attrp = type;
} else {
if (present_attrs & (UINT64_C(1) << type)) {
+ char namebuf[OVS_KEY_ATTR_BUFSIZE];
+
VLOG_ERR_RL(&rl, "duplicate %s attribute in flow key",
- ovs_key_attr_to_string(type));
+ ovs_key_attr_to_string(type,
+ namebuf, sizeof namebuf));
return false;
}
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,
if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TUNNEL)) {
enum odp_key_fitness res;
- res = tun_key_from_attr(attrs[OVS_KEY_ATTR_TUNNEL], &flow->tunnel);
+ res = odp_tun_key_from_attr(attrs[OVS_KEY_ATTR_TUNNEL], &flow->tunnel);
if (res == ODP_FIT_ERROR) {
return ODP_FIT_ERROR;
} else if (res == ODP_FIT_PERFECT) {
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.
*/