These functions are used in next patch.
Signed-off-by: Pravin B Shelar <[email protected]>
---
lib/odp-util.c | 99 ++++++++++++++++++++++++++++++++++--------------
lib/odp-util.h | 1 +
ofproto/ofproto-dpif.c | 2 +
3 files changed, 73 insertions(+), 29 deletions(-)
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 08823e2..2a28504 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -167,8 +167,10 @@ format_odp_sample_action(struct ds *ds, const struct
nlattr *attr)
}
static const char *
-slow_path_reason_to_string(enum slow_path_reason bit)
+slow_path_reason_to_string(uint32_t data)
{
+ enum slow_path_reason bit = (enum slow_path_reason) data;
+
switch (bit) {
case SLOW_CFM:
return "cfm";
@@ -182,28 +184,34 @@ slow_path_reason_to_string(enum slow_path_reason bit)
return "controller";
case SLOW_MATCH:
return "match";
+ case SLOW_MAX:
default:
return NULL;
}
}
static void
-format_slow_path_reason(struct ds *ds, uint32_t slow)
+format_flags(struct ds *ds, const char * (*bit_to_string)(uint32_t),
+ uint32_t flags)
{
uint32_t bad = 0;
- while (slow) {
- uint32_t bit = rightmost_1bit(slow);
+ if (!flags) {
+ ds_put_format(ds, "0x0");
+ return;
+ }
+ while (flags) {
+ uint32_t bit = rightmost_1bit(flags);
const char *s;
- s = slow_path_reason_to_string(bit);
+ s = bit_to_string(bit);
if (s) {
ds_put_format(ds, "%s,", s);
} else {
bad |= bit;
}
- slow &= ~bit;
+ flags &= ~bit;
}
if (bad) {
@@ -212,6 +220,49 @@ format_slow_path_reason(struct ds *ds, uint32_t slow)
ds_chomp(ds, ',');
}
+static int
+parse_flags(const char *s, const char * (*bit_to_string)(uint32_t),
+ uint32_t *res)
+{
+ uint32_t result = 0;
+ int n = 0;
+
+ while (s[n] != ')') {
+ unsigned long long int flags;
+ uint32_t bit;
+ int n0;
+
+ if (sscanf(&s[n], "%lli%n", &flags, &n0) > 0 && n0 > 0) {
+ n += n0 + (s[n + n0] == ',');
+ result |= flags;
+ continue;
+ }
+
+ for (bit = 1; bit; bit <<= 1) {
+ const char *name = bit_to_string(bit);
+ size_t len;
+
+ if (!name) {
+ continue;
+ }
+
+ len = strlen(name);
+ if (!strncmp(s + n, name, len) &&
+ (s[n + len] == ',' || s[n + len] == ')')) {
+ result |= bit;
+ n += len + (s[n + len] == ',');
+ break;
+ }
+ }
+
+ if (!bit) {
+ return -EINVAL;
+ }
+ }
+ *res = result;
+ return n + 1;
+}
+
static void
format_odp_userspace_action(struct ds *ds, const struct nlattr *attr)
{
@@ -247,7 +298,8 @@ format_odp_userspace_action(struct ds *ds, const struct
nlattr *attr)
case USER_ACTION_COOKIE_SLOW_PATH:
ds_put_cstr(ds, ",slow_path(");
if (cookie.slow_path.reason) {
- format_slow_path_reason(ds, cookie.slow_path.reason);
+ format_flags(ds, slow_path_reason_to_string,
+ cookie.slow_path.reason);
}
ds_put_char(ds, ')');
break;
@@ -418,36 +470,25 @@ parse_odp_action(const char *s, const struct simap
*port_names,
} else if (sscanf(s, "userspace(pid=%lli,slow_path(%n", &pid, &n) > 0
&& n > 0) {
union user_action_cookie cookie;
+ int res;
cookie.type = USER_ACTION_COOKIE_SLOW_PATH;
cookie.slow_path.unused = 0;
cookie.slow_path.reason = 0;
- while (s[n] != ')') {
- uint32_t bit;
-
- for (bit = 1; bit; bit <<= 1) {
- const char *reason = slow_path_reason_to_string(bit);
- size_t len = strlen(reason);
-
- if (reason
- && !strncmp(s + n, reason, len)
- && (s[n + len] == ',' || s[n + len] == ')'))
- {
- cookie.slow_path.reason |= bit;
- n += len + (s[n + len] == ',');
- break;
- }
- }
-
- if (!bit) {
- return -EINVAL;
- }
+ res = parse_flags(&s[n], slow_path_reason_to_string,
+ &cookie.slow_path.reason);
+ if (res < 0) {
+ return res;
+ }
+ if (cookie.slow_path.reason & ~(SLOW_MAX - 1)) {
+ return -EINVAL;
}
- if (s[n + 1] != ')') {
+ n += res;
+ if (s[n] != ')') {
return -EINVAL;
}
- n += 2;
+ n += 1;
odp_put_userspace_action(pid, &cookie, actions);
return n;
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 5cdb204..e149f44 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -159,6 +159,7 @@ enum slow_path_reason {
/* This can appear on its own, or, theoretically at least, along with any
* other combination of reasons. */
SLOW_MATCH = 1 << 5, /* Datapath can't match specifically enough. */
+ SLOW_MAX = 1 << 6,
};
#endif /* odp-util.h */
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 283aea9..508bfc8 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -7322,6 +7322,8 @@ ofproto_trace(struct ofproto_dpif *ofproto, const struct
flow *flow,
ds_put_cstr(ds, "\n\t- Needs more specific matching "
"than the datapath supports.");
break;
+ case SLOW_MAX:
+ break;
}
slow &= ~bit;
--
1.7.10
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev