There are several implementations of functions that parse/format flags and their binary representation. This factors them out into common routines. In addition to reducing code, it also makes things more consistent across different parts of OVS.
Signed-off-by: Jesse Gross <je...@nicira.com> --- lib/flow.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++- lib/flow.h | 5 +- lib/match.c | 17 +----- lib/meta-flow.c | 154 +++++++++---------------------------------------- lib/odp-util.c | 155 ++++++------------------------------------------- tests/odp.at | 8 +-- tests/ofproto-dpif.at | 2 +- tests/ovs-ofctl.at | 13 ----- tests/tunnel.at | 40 ++++++------- 9 files changed, 233 insertions(+), 318 deletions(-) diff --git a/lib/flow.c b/lib/flow.c index 3669228..80dcfcb 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -864,11 +864,22 @@ format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t), void format_flags_masked(struct ds *ds, const char *name, const char *(*bit_to_string)(uint32_t), uint32_t flags, - uint32_t mask) + uint32_t mask, uint32_t max_mask) { if (name) { ds_put_format(ds, "%s=", name); } + + if (mask == max_mask) { + if (flags) { + format_flags(ds, bit_to_string, flags, '|'); + } else { + ds_put_char(ds, '0'); + } + + return; + } + while (mask) { uint32_t bit = rightmost_1bit(mask); const char *s = bit_to_string(bit); @@ -879,6 +890,150 @@ format_flags_masked(struct ds *ds, const char *name, } } +int +parse_flags(const char *s, const char *(*bit_to_string)(uint32_t), + char end, const char *field_name, char **res_string, + uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask) +{ + uint32_t result = 0; + int n; + + /* Parse masked flags in numeric format? */ + if (res_mask && ovs_scan(s, "%"SCNi32"/%"SCNi32"%n", + res_flags, res_mask, &n) && n > 0) { + if (*res_flags & ~allowed || *res_mask & ~allowed) { + goto unknown; + } + return n; + } + + n = 0; + + if (res_mask && (*s == '+' || *s == '-')) { + uint32_t flags = 0, mask = 0; + + /* Parse masked flags. */ + while (s[0] != end) { + bool set; + uint32_t bit; + size_t len; + + if (s[0] == '+') { + set = true; + } else if (s[0] == '-') { + set = false; + } else { + if (res_string) { + *res_string = xasprintf("%s: %s must be preceed by '+' " + "(for SET) or '-' (NOT SET)", s, + field_name); + } + return -EINVAL; + } + s++; + n++; + + for (bit = 1; bit; bit <<= 1) { + const char *fname = bit_to_string(bit); + + if (!fname) { + continue; + } + + len = strlen(fname); + if (strncmp(s, fname, len) || + (s[len] != '+' && s[len] != '-' && s[len] != end)) { + continue; + } + + if (mask & bit) { + /* bit already set. */ + if (res_string) { + *res_string = xasprintf("%s: Each %s flag can be " + "specified only once", s, + field_name); + } + return -EINVAL; + } + if (!(bit & allowed)) { + goto unknown; + } + if (set) { + flags |= bit; + } + mask |= bit; + break; + } + + if (!bit) { + goto unknown; + } + s += len; + n += len; + } + + *res_flags = flags; + *res_mask = mask; + return n; + } + + /* Parse unmasked flags. If a flag is present, it is set, otherwise + * it is not set. */ + while (s[n] != end) { + unsigned long long int flags; + uint32_t bit; + int n0; + + if (ovs_scan(&s[n], "%lli%n", &flags, &n0)) { + if (flags & ~allowed) { + goto unknown; + } + 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] == end)) { + if (!(bit & allowed)) { + goto unknown; + } + result |= bit; + n += len + (s[n + len] == '|'); + break; + } + } + + if (!bit) { + goto unknown; + } + } + + *res_flags = result; + if (res_mask) { + *res_mask = UINT32_MAX; + } + if (res_string) { + *res_string = NULL; + } + return n; + +unknown: + if (res_string) { + *res_string = xasprintf("%s: unknown %s flag(s)", s, field_name); + } + return -EINVAL; +} + void flow_format(struct ds *ds, const struct flow *flow) { diff --git a/lib/flow.h b/lib/flow.h index 9779085..b961746 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -191,7 +191,10 @@ void format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t), uint32_t flags, char del); void format_flags_masked(struct ds *ds, const char *name, const char *(*bit_to_string)(uint32_t), - uint32_t flags, uint32_t mask); + uint32_t flags, uint32_t mask, uint32_t max_mask); +int parse_flags(const char *s, const char *(*bit_to_string)(uint32_t), + char end, const char *field_name, char **res_string, + uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask); void flow_format(struct ds *, const struct flow *); void flow_print(FILE *, const struct flow *); diff --git a/lib/match.c b/lib/match.c index ca9492f..6fd62e0 100644 --- a/lib/match.c +++ b/lib/match.c @@ -1150,20 +1150,9 @@ match_format(const struct match *match, struct ds *s, int priority) format_be16_masked(s, "tp_dst", f->tp_dst, wc->masks.tp_dst); } if (is_ip_any(f) && f->nw_proto == IPPROTO_TCP && wc->masks.tcp_flags) { - uint16_t mask = TCP_FLAGS(wc->masks.tcp_flags); - - if (mask == TCP_FLAGS(OVS_BE16_MAX)) { - ds_put_cstr(s, "tcp_flags="); - if (f->tcp_flags) { - format_flags(s, packet_tcp_flag_to_string, ntohs(f->tcp_flags), - '|'); - } else { - ds_put_cstr(s, "0"); /* Zero flags. */ - } - } else if (mask) { - format_flags_masked(s, "tcp_flags", packet_tcp_flag_to_string, - ntohs(f->tcp_flags), mask); - } + format_flags_masked(s, "tcp_flags", packet_tcp_flag_to_string, + ntohs(f->tcp_flags), TCP_FLAGS(wc->masks.tcp_flags), + TCP_FLAGS(OVS_BE16_MAX)); } if (s->length > start_len) { diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 21a13b4..e2a31e7 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -2014,144 +2014,44 @@ mf_from_frag_string(const char *s, uint8_t *valuep, uint8_t *maskp) "\"yes\", \"first\", \"later\", \"not_first\"", s); } -static int -parse_flow_tun_flags(const char *s_, const char *(*bit_to_string)(uint32_t), - ovs_be16 *res) +static char * +parse_mf_flags(const char *s, const char *(*bit_to_string)(uint32_t), + const char *field_name, ovs_be16 *flagsp, ovs_be16 allowed, + ovs_be16 *maskp) { - uint32_t result = 0; - char *save_ptr = NULL; - char *name; - int rc = 0; - char *s = xstrdup(s_); - - for (name = strtok_r((char *)s, " |", &save_ptr); name; - name = strtok_r(NULL, " |", &save_ptr)) { - int name_len; - unsigned long long int flags; - uint32_t bit; - - if (ovs_scan(name, "%lli", &flags)) { - result |= flags; - continue; - } - name_len = strlen(name); - for (bit = 1; bit; bit <<= 1) { - const char *fname = bit_to_string(bit); - size_t len; - - if (!fname) { - continue; - } + int err; + char *err_str; + uint32_t flags, mask; - len = strlen(fname); - if (len != name_len) { - continue; - } - if (!strncmp(name, fname, len)) { - result |= bit; - break; - } - } + err = parse_flags(s, bit_to_string, '\0', field_name, &err_str, + &flags, ntohs(allowed), maskp ? &mask : NULL); + if (err < 0) { + return err_str; + } - if (!bit) { - rc = -ENOENT; - goto out; - } + *flagsp = htons(flags); + if (maskp) { + *maskp = htons(mask); } - *res = htons(result); -out: - free(s); - return rc; + return NULL; } static char * -mf_from_tun_flags_string(const char *s, ovs_be16 *valuep, ovs_be16 *maskp) +mf_from_tcp_flags_string(const char *s, ovs_be16 *flagsp, ovs_be16 *maskp) { - if (!parse_flow_tun_flags(s, flow_tun_flag_to_string, valuep)) { - *maskp = OVS_BE16_MAX; - return NULL; - } - - return xasprintf("%s: unknown tunnel flags (valid flags are \"df\", " - "\"csum\", \"key\")", s); + return parse_mf_flags(s, packet_tcp_flag_to_string, "TCP", flagsp, + TCP_FLAGS_BE16(OVS_BE16_MAX), maskp); } static char * -mf_from_tcp_flags_string(const char *s, ovs_be16 *flagsp, ovs_be16 *maskp) +mf_from_tun_flags_string(const char *s, ovs_be16 *flagsp, ovs_be16 *maskp) { - uint16_t flags = 0; - uint16_t mask = 0; - uint16_t bit; - int n; - - if (ovs_scan(s, "%"SCNi16"/%"SCNi16"%n", &flags, &mask, &n) && !s[n]) { - *flagsp = htons(flags); - *maskp = htons(mask); - return NULL; - } - if (ovs_scan(s, "%"SCNi16"%n", &flags, &n) && !s[n]) { - *flagsp = htons(flags); - *maskp = OVS_BE16_MAX; - return NULL; - } - - while (*s != '\0') { - bool set; - int name_len; - - switch (*s) { - case '+': - set = true; - break; - case '-': - set = false; - break; - default: - return xasprintf("%s: TCP flag must be preceded by '+' (for SET) " - "or '-' (NOT SET)", s); - } - s++; - - name_len = strcspn(s,"+-"); - - for (bit = 1; bit; bit <<= 1) { - const char *fname = packet_tcp_flag_to_string(bit); - size_t len; - - if (!fname) { - continue; - } - - len = strlen(fname); - if (len != name_len) { - continue; - } - if (!strncmp(s, fname, len)) { - if (mask & bit) { - return xasprintf("%s: Each TCP flag can be specified only " - "once", s); - } - if (set) { - flags |= bit; - } - mask |= bit; - break; - } - } - - if (!bit) { - return xasprintf("%s: unknown TCP flag(s)", s); - } - s += name_len; - } - - *flagsp = htons(flags); - *maskp = htons(mask); - return NULL; + *maskp = OVS_BE16_MAX; + return parse_mf_flags(s, flow_tun_flag_to_string, "tunnel", flagsp, + htons(FLOW_TNL_F_MASK), NULL); } - /* Parses 's', a string value for field 'mf', into 'value' and 'mask'. Returns * NULL if successful, otherwise a malloc()'d string describing the error. */ char * @@ -2280,16 +2180,16 @@ mf_format_frag_string(uint8_t value, uint8_t mask, struct ds *s) } static void -mf_format_tnl_flags_string(const ovs_be16 *valuep, struct ds *s) +mf_format_tnl_flags_string(ovs_be16 value, struct ds *s) { - format_flags(s, flow_tun_flag_to_string, ntohs(*valuep), '|'); + format_flags(s, flow_tun_flag_to_string, ntohs(value), '|'); } static void mf_format_tcp_flags_string(ovs_be16 value, ovs_be16 mask, struct ds *s) { format_flags_masked(s, NULL, packet_tcp_flag_to_string, ntohs(value), - TCP_FLAGS(mask)); + TCP_FLAGS(mask), TCP_FLAGS(OVS_BE16_MAX)); } /* Appends to 's' a string representation of field 'mf' whose value is in @@ -2345,7 +2245,7 @@ mf_format(const struct mf_field *mf, break; case MFS_TNL_FLAGS: - mf_format_tnl_flags_string(&value->be16, s); + mf_format_tnl_flags_string(value->be16, s); break; case MFS_TCP_FLAGS: diff --git a/lib/odp-util.c b/lib/odp-util.c index 2eddb34..0e82b12 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -235,130 +235,11 @@ slow_path_reason_to_explanation(enum slow_path_reason reason) } static int -parse_flags(const char *s, const char *(*bit_to_string)(uint32_t), - uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask) +parse_odp_flags(const char *s, const char *(*bit_to_string)(uint32_t), + uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask) { - uint32_t result = 0; - int n; - - /* Parse masked flags in numeric format? */ - if (res_mask && ovs_scan(s, "%"SCNi32"/%"SCNi32"%n", - res_flags, res_mask, &n) && n > 0) { - if (*res_flags & ~allowed || *res_mask & ~allowed) { - return -EINVAL; - } - return n; - } - - n = 0; - - if (res_mask && (*s == '+' || *s == '-')) { - uint32_t flags = 0, mask = 0; - - /* Parse masked flags. */ - while (s[0] != ')') { - bool set; - uint32_t bit; - int name_len; - - if (s[0] == '+') { - set = true; - } else if (s[0] == '-') { - set = false; - } else { - return -EINVAL; - } - s++; - n++; - - name_len = strcspn(s, "+-)"); - - for (bit = 1; bit; bit <<= 1) { - const char *fname = bit_to_string(bit); - size_t len; - - if (!fname) { - continue; - } - - len = strlen(fname); - if (len != name_len) { - continue; - } - if (!strncmp(s, fname, len)) { - if (mask & bit) { - /* bit already set. */ - return -EINVAL; - } - if (!(bit & allowed)) { - return -EINVAL; - } - if (set) { - flags |= bit; - } - mask |= bit; - break; - } - } - - if (!bit) { - return -EINVAL; /* Unknown flag name */ - } - s += name_len; - n += name_len; - } - - *res_flags = flags; - *res_mask = mask; - return n; - } - - /* Parse unmasked flags. If a flag is present, it is set, otherwise - * it is not set. */ - while (s[n] != ')') { - unsigned long long int flags; - uint32_t bit; - int n0; - - if (ovs_scan(&s[n], "%lli%n", &flags, &n0)) { - if (flags & ~allowed) { - return -EINVAL; - } - 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] == ')')) { - if (!(bit & allowed)) { - return -EINVAL; - } - result |= bit; - n += len + (s[n + len] == ','); - break; - } - } - - if (!bit) { - return -EINVAL; - } - } - - *res_flags = result; - if (res_mask) { - *res_mask = UINT32_MAX; - } - return n; + return parse_flags(s, bit_to_string, ')', NULL, NULL, + res_flags, allowed, res_mask); } static void @@ -823,9 +704,9 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions) cookie.slow_path.unused = 0; cookie.slow_path.reason = 0; - res = parse_flags(&s[n], slow_path_reason_to_string, - &cookie.slow_path.reason, - SLOW_PATH_REASON_MASK, NULL); + res = parse_odp_flags(&s[n], slow_path_reason_to_string, + &cookie.slow_path.reason, + SLOW_PATH_REASON_MASK, NULL); if (res < 0 || s[n + res] != ')') { return res; } @@ -1791,14 +1672,13 @@ format_tun_flags(struct ds *ds, const char *name, uint16_t key, bool mask_empty = mask && !*mask; if (verbose || !mask_empty) { - bool mask_full = !mask || (*mask & FLOW_TNL_F_MASK) == FLOW_TNL_F_MASK; - ds_put_cstr(ds, name); ds_put_char(ds, '('); - if (!mask_full) { /* Partially masked. */ - format_flags_masked(ds, NULL, flow_tun_flag_to_string, key, *mask); + if (mask) { + format_flags_masked(ds, NULL, flow_tun_flag_to_string, key, + *mask & FLOW_TNL_F_MASK, FLOW_TNL_F_MASK); } else { /* Fully masked. */ - format_flags(ds, flow_tun_flag_to_string, key, ','); + format_flags(ds, flow_tun_flag_to_string, key, '|'); } ds_put_cstr(ds, "),"); } @@ -2277,10 +2157,11 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma, if (!is_exact) { format_flags_masked(ds, NULL, packet_tcp_flag_to_string, ntohs(nl_attr_get_be16(a)), - ntohs(nl_attr_get_be16(ma))); + TCP_FLAGS(nl_attr_get_be16(ma)), + TCP_FLAGS(OVS_BE16_MAX)); } else { format_flags(ds, packet_tcp_flag_to_string, - ntohs(nl_attr_get_be16(a)), ','); + ntohs(nl_attr_get_be16(a)), '|'); } break; @@ -2680,8 +2561,8 @@ scan_tun_flags(const char *s, uint16_t *key, uint16_t *mask) uint32_t flags, fmask; int n; - n = parse_flags(s, flow_tun_flag_to_string, &flags, - FLOW_TNL_F_MASK, mask ? &fmask : NULL); + n = parse_odp_flags(s, flow_tun_flag_to_string, &flags, + FLOW_TNL_F_MASK, mask ? &fmask : NULL); if (n >= 0 && s[n] == ')') { *key = flags; if (mask) { @@ -2698,8 +2579,8 @@ scan_tcp_flags(const char *s, ovs_be16 *key, ovs_be16 *mask) uint32_t flags, fmask; int n; - n = parse_flags(s, packet_tcp_flag_to_string, &flags, - TCP_FLAGS(OVS_BE16_MAX), mask ? &fmask : NULL); + n = parse_odp_flags(s, packet_tcp_flag_to_string, &flags, + TCP_FLAGS(OVS_BE16_MAX), mask ? &fmask : NULL); if (n >= 0) { *key = htons(flags); if (mask) { diff --git a/tests/odp.at b/tests/odp.at index 090b976..1d8b915 100644 --- a/tests/odp.at +++ b/tests/odp.at @@ -39,7 +39,7 @@ s/^/skb_priority(0),skb_mark(0),recirc_id(0),dp_hash(0),/ echo echo '# Valid forms with tunnel header.' - sed 's/^/skb_priority(0),tunnel(tun_id=0x7f10354,src=10.10.10.10,dst=20.20.20.20,ttl=64,flags(csum,key)),skb_mark(0x1234),recirc_id(0),dp_hash(0),/' odp-base.txt + sed 's/^/skb_priority(0),tunnel(tun_id=0x7f10354,src=10.10.10.10,dst=20.20.20.20,ttl=64,flags(csum|key)),skb_mark(0x1234),recirc_id(0),dp_hash(0),/' odp-base.txt echo echo '# Valid forms with VLAN header.' @@ -117,7 +117,7 @@ skb_mark(0x1234/0xfff0),in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14: echo echo '# Valid forms with tunnel header.' - sed 's/^/tunnel(tun_id=0x7f10354\/0xff,src=10.10.10.10\/255.255.255.0,dst=20.20.20.20\/255.255.255.0,ttl=64,vxlan(gbp(id=10\/0xff,flags=0xb)),flags(csum,key)),/' odp-base.txt + sed 's/^/tunnel(tun_id=0x7f10354\/0xff,src=10.10.10.10\/255.255.255.0,dst=20.20.20.20\/255.255.255.0,ttl=64,vxlan(gbp(id=10\/0xff,flags=0xb)),flags(csum|key)),/' odp-base.txt echo echo '# Valid forms with tunnel header (wildcard flag).' @@ -125,7 +125,7 @@ skb_mark(0x1234/0xfff0),in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14: echo echo '# Valid forms with Geneve header.' - sed 's/^/tunnel(tun_id=0x7f10354\/0xff,src=10.10.10.10\/255.255.255.0,dst=20.20.20.20\/255.255.255.0,ttl=64,geneve({class=0,type=0,len=4,0xa\/0xff}{class=0xffff,type=0x1,len=4,0xffffffff}),flags(csum,key)),/' odp-base.txt + sed 's/^/tunnel(tun_id=0x7f10354\/0xff,src=10.10.10.10\/255.255.255.0,dst=20.20.20.20\/255.255.255.0,ttl=64,geneve({class=0,type=0,len=4,0xa\/0xff}{class=0xffff,type=0x1,len=4,0xffffffff}),flags(csum|key)),/' odp-base.txt echo echo '# Valid forms with VLAN header.' @@ -284,7 +284,7 @@ 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(tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(df,csum,key))) +set(tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(df|csum|key))) set(tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(key))) tnl_pop(4) tnl_push(tnl_port(4),header(size=42,type=3,eth(dst=f8:bc:12:44:34:b6,src=f8:bc:12:46:58:e0,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos=0,ttl=64,frag=0x40),gre((flags=0x2000,proto=0x6558),key=0x1e241)),out_port(1)) diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index cbf5737..f9d92e0 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -960,7 +960,7 @@ AT_CHECK([ovs-ofctl -OOpenFlow12 add-flow br0 'table=0 actions=goto_table(1)']) AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log]) for i in 1 2 3 ; do - ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(urg,rst)' + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(urg|rst)' done OVS_WAIT_UNTIL([test `wc -l < ofctl_monitor.log` -ge 6]) OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index 28bca14..b4e638b 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -10,7 +10,6 @@ for test_case in \ 'tun_dst=1.2.3.4 NXM,OXM' \ 'tun_dst=1.2.3.4/0.0.0.1 NXM,OXM' \ 'tun_flags=0 none' \ - 'tun_flags=1/1 none' \ 'tun_tos=0 none' \ 'tun_ttl=0 none' \ 'tun_gbp_id=0 NXM,OXM' \ @@ -303,18 +302,6 @@ AT_CHECK([ovs-ofctl --protocols OpenFlow11 add-flow br0 'ip actions=mod_tp_dst:1 ]) AT_CLEANUP -AT_SETUP([ovs-ofctl parse-flows (With Tunnel-Parameters)]) -AT_DATA([flows.txt], [[ -tun_id=0x1234000056780000/0xffff0000ffff0000,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0x3,tun_ttl=20,tun_flags=key|csum actions=drop -]]) - -AT_CHECK([ovs-ofctl parse-flows flows.txt -], [1], [usable protocols: none -], [stderr]) - -AT_CLEANUP - - AT_SETUP([ovs-ofctl parse-flows (skb_priority)]) AT_DATA([flows.txt], [[ skb_priority=0x12341234,tcp,tp_src=123,actions=flood diff --git a/tests/tunnel.at b/tests/tunnel.at index ce4cb1e..b22a621 100644 --- a/tests/tunnel.at +++ b/tests/tunnel.at @@ -131,13 +131,13 @@ AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl dnl Basic AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=4,ttl=128,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], - [Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,ttl=64,flags(df,key))),1 + [Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,ttl=64,flags(df|key))),1 ]) dnl ECN AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=1,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], - [Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,tos=0x1,ttl=64,flags(df,key))),1 + [Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,tos=0x1,ttl=64,flags(df|key))),1 ]) OVS_VSWITCHD_STOP AT_CLEANUP @@ -208,10 +208,10 @@ AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(100),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], [Datapath actions: dnl -set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x2,dst=2.2.2.2,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x3,dst=3.3.3.3,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x5,dst=4.4.4.4,ttl=64,flags(df,key))),1 +set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x2,dst=2.2.2.2,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x3,dst=3.3.3.3,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x5,dst=4.4.4.4,ttl=64,flags(df|key))),1 ]) OVS_VSWITCHD_STOP AT_CLEANUP @@ -240,23 +240,23 @@ AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0x1,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(key)),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], [Datapath actions: dnl -set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x3,dst=1.1.1.1,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x5,dst=1.1.1.1,ttl=64,flags(df,key))),1 +set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x3,dst=1.1.1.1,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x5,dst=1.1.1.1,ttl=64,flags(df|key))),1 ]) AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0x2,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(key)),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], [Datapath actions: dnl -set(tunnel(tun_id=0x3,dst=1.1.1.1,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x5,dst=1.1.1.1,ttl=64,flags(df,key))),1 +set(tunnel(tun_id=0x3,dst=1.1.1.1,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x5,dst=1.1.1.1,ttl=64,flags(df|key))),1 ]) AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], [Datapath actions: dnl -set(tunnel(tun_id=0x5,dst=1.1.1.1,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df,key))),1,dnl -set(tunnel(tun_id=0x3,dst=1.1.1.1,ttl=64,flags(df,key))),1 +set(tunnel(tun_id=0x5,dst=1.1.1.1,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x1,dst=1.1.1.1,ttl=64,flags(df|key))),1,dnl +set(tunnel(tun_id=0x3,dst=1.1.1.1,ttl=64,flags(df|key))),1 ]) AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0xf,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(key)),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [2], [ignore], [dnl @@ -300,7 +300,7 @@ Datapath actions: 3 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0x3,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(key)),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], [dnl -Datapath actions: 4,3,set(tunnel(tun_id=0x3,dst=3.3.3.3,ttl=64,flags(df,key))),1,5 +Datapath actions: 4,3,set(tunnel(tun_id=0x3,dst=3.3.3.3,ttl=64,flags(df|key))),1,5 ]) AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0x3,src=3.3.3.3,dst=2.2.2.2,ttl=64,flags(key)),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout]) @@ -407,7 +407,7 @@ in_port=5 actions=set_field:5->tun_id AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(90),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], - [Datapath actions: set(tunnel(tun_id=0x2a,dst=1.1.1.1,ttl=64,flags(df,key))),1,set(tunnel(tun_id=0x2a,dst=3.3.3.3,ttl=64,flags(df,key))),1,set(tunnel(tun_id=0x2a,src=1.1.1.1,dst=4.4.4.4,ttl=64,flags(df,key))),1,set(tunnel(tun_id=0x3,dst=2.2.2.2,ttl=64,flags(df,key))),1 + [Datapath actions: set(tunnel(tun_id=0x2a,dst=1.1.1.1,ttl=64,flags(df|key))),1,set(tunnel(tun_id=0x2a,dst=3.3.3.3,ttl=64,flags(df|key))),1,set(tunnel(tun_id=0x2a,src=1.1.1.1,dst=4.4.4.4,ttl=64,flags(df|key))),1,set(tunnel(tun_id=0x3,dst=2.2.2.2,ttl=64,flags(df|key))),1 ]) OVS_VSWITCHD_STOP AT_CLEANUP @@ -434,14 +434,14 @@ AT_CHECK([tail -1 stdout], [0], ]) dnl Option match -AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}),flags(df,key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout]) AT_CHECK([tail -2 stdout], [0], [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_ttl=64,df|key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no Datapath actions: 2 ]) dnl Skip unknown option -AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}{class=0xffff,type=2,len=4,0xc}),flags(df,key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}{class=0xffff,type=2,len=4,0xc}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout]) AT_CHECK([tail -2 stdout], [0], [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_ttl=64,df|key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no Datapath actions: 2 @@ -466,7 +466,7 @@ AT_CHECK([ovs-ofctl del-geneve-map br0 "{class=0xffff,type=3,len=4}->tun_metadat AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=3,len=8}->tun_metadata3"]) AT_CHECK([ovs-ofctl add-flow br0 tun_metadata3=0x1234567890abcdef,actions=2]) -AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=3,len=8,0x1234567890abcdef}),flags(df,key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=3,len=8,0x1234567890abcdef}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout]) AT_CHECK([tail -2 stdout], [0], [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_ttl=64,df|key,tun_metadata0=0/0xf,tun_metadata3=0x1234567890abcdef,in_port=1,nw_frag=no Datapath actions: 2 -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev