Skip to content

Commit

Permalink
ovs-ofctl: Extract tunnel metadata correctly when sorting flows.
Browse files Browse the repository at this point in the history
When flow fields are sorted before dumping in ovs-ofctl, each
significant field is extracted for sorting. However, in the case of
tunnel metadata a mapping table is necessary to know where each
field begins and ends. This information is current stripped off before
fetching the field data and returned field is simply zeroed. This
makes sorting based on tunnel metadata non-deterministic.

We have the tunnel allocation stored in match metadata with each
flow, so we can simply extract the data from there rather than
trying to build and populate a global mapping table.

Signed-off-by: Jesse Gross <[email protected]>
Acked-by: Ben Pfaff <[email protected]>
  • Loading branch information
jessegross committed Aug 30, 2016
1 parent f681214 commit 5bc39e9
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
18 changes: 17 additions & 1 deletion tests/ovs-ofctl.at
Original file line number Diff line number Diff line change
Expand Up @@ -2639,10 +2639,14 @@ priority=6,in_port=1027 actions=output:64
priority=2,in_port=1025 actions=output:47
priority=8,tcp,tp_src=5 actions=drop
priority=9,tcp,tp_src=6 actions=drop
priority=10,tun_metadata0=0xab actions=drop
priority=11,tun_metadata0=0xcd actions=drop
]])

AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0"])
AT_CHECK([ovs-ofctl add-flows br0 allflows.txt
], [0], [ignore])

AT_CHECK([ovs-ofctl --sort dump-flows br0 | ofctl_strip], [0], [dnl
priority=1,in_port=1026 actions=output:45
priority=2,in_port=1025 actions=output:47
Expand All @@ -2653,8 +2657,12 @@ AT_CHECK([ovs-ofctl --sort dump-flows br0 | ofctl_strip], [0], [dnl
priority=7,in_port=1029 actions=output:43
priority=8,tcp,tp_src=5 actions=drop
priority=9,tcp,tp_src=6 actions=drop
priority=10,tun_metadata0=0xab actions=drop
priority=11,tun_metadata0=0xcd actions=drop
])
AT_CHECK([ovs-ofctl --rsort dump-flows br0 | ofctl_strip], [0], [dnl
priority=11,tun_metadata0=0xcd actions=drop
priority=10,tun_metadata0=0xab actions=drop
priority=9,tcp,tp_src=6 actions=drop
priority=8,tcp,tp_src=5 actions=drop
priority=7,in_port=1029 actions=output:43
Expand All @@ -2673,6 +2681,8 @@ AT_CHECK([ovs-ofctl --sort=in_port dump-flows br0 | ofctl_strip], [0], [dnl
priority=7,in_port=1029 actions=output:43
priority=5,in_port=1029 actions=output:43
priority=4,in_port=23213 actions=output:42
priority=11,tun_metadata0=0xcd actions=drop
priority=10,tun_metadata0=0xab actions=drop
priority=9,tcp,tp_src=6 actions=drop
priority=8,tcp,tp_src=5 actions=drop
])
Expand All @@ -2684,12 +2694,16 @@ AT_CHECK([ovs-ofctl --rsort=in_port dump-flows br0 | ofctl_strip], [0], [dnl
priority=6,in_port=1027 actions=output:64
priority=1,in_port=1026 actions=output:45
priority=2,in_port=1025 actions=output:47
priority=11,tun_metadata0=0xcd actions=drop
priority=10,tun_metadata0=0xab actions=drop
priority=9,tcp,tp_src=6 actions=drop
priority=8,tcp,tp_src=5 actions=drop
])
AT_CHECK([ovs-ofctl --sort=tcp_src dump-flows br0 | ofctl_strip], [0], [dnl
priority=8,tcp,tp_src=5 actions=drop
priority=9,tcp,tp_src=6 actions=drop
priority=11,tun_metadata0=0xcd actions=drop
priority=10,tun_metadata0=0xab actions=drop
priority=7,in_port=1029 actions=output:43
priority=6,in_port=1027 actions=output:64
priority=5,in_port=1029 actions=output:43
Expand All @@ -2699,7 +2713,7 @@ AT_CHECK([ovs-ofctl --sort=tcp_src dump-flows br0 | ofctl_strip], [0], [dnl
priority=1,in_port=1026 actions=output:45
])
AT_CHECK(
[ovs-ofctl --sort=in_port --sort=tcp_src dump-flows br0 | ofctl_strip], [0],
[ovs-ofctl --sort=in_port --sort=tcp_src --sort=tun_metadata0 dump-flows br0 | ofctl_strip], [0],
[ priority=2,in_port=1025 actions=output:47
priority=1,in_port=1026 actions=output:45
priority=6,in_port=1027 actions=output:64
Expand All @@ -2709,6 +2723,8 @@ AT_CHECK(
priority=4,in_port=23213 actions=output:42
priority=8,tcp,tp_src=5 actions=drop
priority=9,tcp,tp_src=6 actions=drop
priority=10,tun_metadata0=0xab actions=drop
priority=11,tun_metadata0=0xcd actions=drop
])
OVS_VSWITCHD_STOP
AT_CLEANUP
Expand Down
24 changes: 22 additions & 2 deletions utilities/ovs-ofctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,26 @@ ofctl_dump_flows__(int argc, char *argv[], bool aggregate)
vconn_close(vconn);
}

static void
get_match_field(const struct mf_field *field, const struct match *match,
union mf_value *value)
{
if (!match->tun_md.valid || (field->id < MFF_TUN_METADATA0 ||
field->id >= MFF_TUN_METADATA0 +
TUN_METADATA_NUM_OPTS)) {
mf_get_value(field, &match->flow, value);
} else {
const struct tun_metadata_loc *loc = &match->tun_md.entry[field->id -
MFF_TUN_METADATA0].loc;

/* Since we don't have a tunnel mapping table, extract the value
* from the locally allocated location in the match. */
memset(value, 0, field->n_bytes - loc->len);
memcpy(value->tun_metadata + field->n_bytes - loc->len,
match->flow.tunnel.metadata.opts.u8 + loc->c.offset, loc->len);
}
}

static int
compare_flows(const void *afs_, const void *bfs_)
{
Expand Down Expand Up @@ -1226,8 +1246,8 @@ compare_flows(const void *afs_, const void *bfs_)
} else {
union mf_value aval, bval;

mf_get_value(f, &a->flow, &aval);
mf_get_value(f, &b->flow, &bval);
get_match_field(f, a, &aval);
get_match_field(f, b, &bval);
ret = memcmp(&aval, &bval, f->n_bytes);
}
}
Expand Down

0 comments on commit 5bc39e9

Please sign in to comment.