struct flow has a union for the in_port field, and the two different members of the union have different sizes: ofp_port_t is 16 bits, odp_port_t is 32 bits. On little-endian machines this doesn't matter much, but on big-endian machines it's important to distinguish between them because a small number in odp_port_t will show up as zero when viewed through ofp_port_t.
There are in fact few parts of OVS that can handle a struct flow that has either formats; most parts of OVS work with one or the other but not both. match_format(), however, does need to handle both cases, and it did not: it displayed small odp_port_t values as zero on big-endian platforms. This commit fixes the problem by checking the mask, which indicates which format is in use, and displaying the appropriate field from the union. Reported-by: Dimitri John Ledkov <x...@ubuntu.com> Reported-at: http://openvswitch.org/pipermail/discuss/2016-January/020072.html Signed-off-by: Ben Pfaff <b...@ovn.org> --- lib/match.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/match.c b/lib/match.c index 95d34bc..5d4a9dc 100644 --- a/lib/match.c +++ b/lib/match.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1162,7 +1162,9 @@ match_format(const struct match *match, struct ds *s, int priority) format_be64_masked(s, "metadata", f->metadata, wc->masks.metadata); - if (wc->masks.in_port.ofp_port) { + if (wc->masks.in_port.odp_port == UINT32_MAX) { + ds_put_format(s, "in_port=%"PRIu32",", f->in_port.odp_port); + } else if (wc->masks.in_port.ofp_port) { ds_put_cstr(s, "in_port="); ofputil_format_port(f->in_port.ofp_port, s); ds_put_char(s, ','); -- 2.1.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev