Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- lib/odp-util.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++------- tests/odp.at | 3 +- 2 files changed, 100 insertions(+), 13 deletions(-)
diff --git a/lib/odp-util.c b/lib/odp-util.c index 08823e2..b86de0a 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -658,6 +658,52 @@ ovs_frag_type_to_string(enum ovs_frag_type type) } } +static const char * +tun_flag_to_string(uint32_t flags) +{ + switch (flags) { + case OVS_TNL_F_DONT_FRAGMENT: + return "dont_fragment"; + case OVS_TNL_F_CSUM: + return "csum"; + case OVS_TNL_F_KEY: + return "key_present"; + default: + return NULL; + } +} + +static void +format_tun_flags(struct ds *ds, uint32_t flags) +{ + uint32_t bad = 0; + + ds_put_format(ds, "flags="); + + if (!flags) { + ds_put_format(ds, "0"); + return; + } + while (flags) { + uint32_t bit = rightmost_1bit(flags); + const char *s; + + s = tun_flag_to_string(bit); + if (s) { + ds_put_format(ds, "%s,", s); + } else { + bad |= bit; + } + + flags &= ~bit; + } + + if (bad) { + ds_put_format(ds, "0x%"PRIx32",", bad); + } + ds_chomp(ds, ','); +} + static void format_odp_key_attr(const struct nlattr *a, struct ds *ds) { @@ -703,12 +749,16 @@ format_odp_key_attr(const struct nlattr *a, struct ds *ds) case OVS_KEY_ATTR_IPV4_TUNNEL: ipv4_tun_key = nl_attr_get(a); - ds_put_format(ds, "(tun_id=0x%"PRIx64",flags=0x%"PRIx32 - ",src="IP_FMT",dst="IP_FMT",tos=0x%"PRIx8",ttl=%"PRIu8")", - ntohll(ipv4_tun_key->tun_id), ipv4_tun_key->tun_flags, + ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT"," + "tos=0x%"PRIx8",ttl=%"PRIu8",", + ntohll(ipv4_tun_key->tun_id), IP_ARGS(&ipv4_tun_key->ipv4_src), IP_ARGS(&ipv4_tun_key->ipv4_dst), ipv4_tun_key->ipv4_tos, ipv4_tun_key->ipv4_ttl); + + format_tun_flags(ds, ipv4_tun_key->tun_flags); + ds_put_format(ds, ")"); + break; case OVS_KEY_ATTR_IN_PORT: @@ -926,25 +976,61 @@ parse_odp_key_attr(const char *s, const struct simap *port_names, { char tun_id_s[32]; - unsigned long long int flags; int tos, ttl; struct ovs_key_ipv4_tunnel tun_key; - int n = -1; + int n0 = -1; if (sscanf(s, "ipv4_tunnel(tun_id=%31[x0123456789abcdefABCDEF]," - "flags=%lli,src="IP_SCAN_FMT",dst="IP_SCAN_FMT - ",tos=%i,ttl=%i)%n", tun_id_s, &flags, + "src="IP_SCAN_FMT",dst="IP_SCAN_FMT + ",tos=%i,ttl=%i,%n", tun_id_s, IP_SCAN_ARGS(&tun_key.ipv4_src), IP_SCAN_ARGS(&tun_key.ipv4_dst), &tos, &ttl, - &n) > 0 && n > 0) { + &n0) > 0 && n0 > 0) { + int n = -1; + tun_key.tun_id = htonll(strtoull(tun_id_s, NULL, 0)); - tun_key.tun_flags = flags; tun_key.ipv4_tos = tos; tun_key.ipv4_ttl = ttl; memset(&tun_key.pad, 0, sizeof tun_key.pad); - nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV4_TUNNEL, &tun_key, - sizeof tun_key); - return n; + + s += n0; + if (sscanf(s, "flags=%n", &n) == 0 && n > 0) { + + tun_key.tun_flags = 0; + + while (s[n] != ')') { + uint32_t bit; + + for (bit = 1; bit; bit <<= 1) { + const char *flag = tun_flag_to_string(bit); + size_t len = strlen(flag); + + if (flag + && !strncmp(s + n, flag, len) + && (s[n + len] == ',' || s[n + len] == ')')) + { + tun_key.tun_flags |= bit; + n += len + (s[n + len] == ','); + break; + } + } + + if (!bit) { + if (s[n] == '0' && s[n + 1] == ')') { + n++; + break; + } + return -EINVAL; + } + } + if (s[n + 1] != ')') { + return -EINVAL; + } + + nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV4_TUNNEL, &tun_key, + sizeof tun_key); + return n0 + n + 1; + } } } diff --git a/tests/odp.at b/tests/odp.at index 505e4c8..42b2ae6 100644 --- a/tests/odp.at +++ b/tests/odp.at @@ -91,7 +91,8 @@ push_vlan(tpid=0x9100,vid=13,pcp=5) push_vlan(tpid=0x9100,vid=13,pcp=5,cfi=0) pop_vlan sample(sample=9.7%,actions(1,2,3,push_vlan(vid=1,pcp=2))) -set(ipv4_tunnel(tun_id=0xabcdef1234567890,flags=0x0,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64)) +set(ipv4_tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64,flags=dont_fragment,csum,key_present)) +set(ipv4_tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64,flags=0)) ]) AT_CHECK_UNQUOTED([test-odp parse-actions < actions.txt], [0], [`cat actions.txt` -- 1.7.10 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev