[ovs-dev] [PATCH 1/2] flow: Factor out flag parsing and formatting routines.
Jesse Gross
jesse at nicira.com
Mon Jul 13 21:53:56 UTC 2015
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 <jesse at 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
More information about the dev
mailing list