"\"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 *
}
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
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:
}
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
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;
}
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, "),");
}
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;
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) {
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) {
dnl Tunnel CE and encapsulated packet CE
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,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=3,ttl=64,frag=no),tcp(src=8,dst=9)'], [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=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_ecn=3,nw_frag=no
+ [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,0,in_port=1,nw_ecn=3,nw_frag=no
Datapath actions: 2
])
dnl Tunnel CE and encapsulated packet ECT(1)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,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=1,ttl=64,frag=no),tcp(src=8,dst=9)'], [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=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_ecn=1,nw_frag=no
+ [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,0,in_port=1,nw_ecn=1,nw_frag=no
Datapath actions: set(ipv4(tos=0x3/0x3)),2
])
dnl Tunnel CE and encapsulated packet ECT(2)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,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=2,ttl=64,frag=no),tcp(src=8,dst=9)'], [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=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_ecn=2,nw_frag=no
+ [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,0,in_port=1,nw_ecn=2,nw_frag=no
Datapath actions: set(ipv4(tos=0x3/0x3)),2
])
dnl Tunnel CE and encapsulated packet Non-ECT
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,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 -2 stdout], [0],
- [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,,in_port=1,nw_ecn=0,nw_frag=no
+ [Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_ttl=64,0,in_port=1,nw_ecn=0,nw_frag=no
Datapath actions: drop
])
OVS_VSWITCHD_STOP(["/dropping tunnel packet marked ECN CE but is not ECN capable/d"])
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
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
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
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])
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
])
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
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