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 <je...@kernel.org> --- tests/ovs-ofctl.at | 18 +++++++++++++++++- utilities/ovs-ofctl.c | 24 ++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index d966fc2..8747a06 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -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 @@ -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 @@ -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 ]) @@ -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 @@ -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 @@ -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 diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index dbeeebf..cf27d26 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -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_) { @@ -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); } } -- 2.7.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev