These functions are used in next patch. Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- 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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev