Well, we can do better, anyway, by adjusting test-odp.c and odp.at. Update appended
On Tue, May 15, 2012 at 11:19:04AM -0700, Ethan Jackson wrote: > Just out of curiosity, is there any way we can build assert, or unit > test these values? That seems like the most future proof way to > ensure they're correct, though I'm not sure what such a check would > look like. > > Ethan > > On Tue, May 15, 2012 at 10:42 AM, Justin Pettit <jpet...@nicira.com> wrote: > > On May 15, 2012, at 10:29 AM, Ben Pfaff wrote: > > > >>>>> Do you think it's worth having the total be a #define, and then do a > >>>>> build-time assertion that the total value is less than > >>>>> ODPUTIL_FLOW_KEY_BYTES? > >>>> > >>>> Can you explain how that would be different? > >>> > >>> Right now, we have a chart that maps out the total number of bytes > >>> needed to represent the largest flow. When updating that chart it's > >>> pretty obvious that the "total" field at the bottom needs to be > >>> updated. I feel like we've had issues in the past where "total" was > >>> updated, but ODPUTIL_FLOW_KEY_BYTES was not. This would serve as a > >>> reminder. It's pretty unlikely to occur, but I was thinking it would > >>> be a good sanity-check. We could also mandate a certain amount a > >>> slack. However, if you think it's unnecessary, I'm fine not adding > >>> one, too. > >> > >> Mostly I don't understand what you envision the code or comment looking > >> like. Can you show me? > > > > > > I was thinking of something like the following: > > > > -=-=-=-=-=-=-=-=-=-=- > > * struct pad nl hdr total > > * ------ --- ------ ----- > > * OVS_KEY_ATTR_PRIORITY 4 -- 4 8 > > ... > > * OVS_KEY_ATTR_ND 28 -- 4 32 > > * -------------------------------------------------*/ > > #define ODP_FLOW_KEY_MAX_TOTAL 156 > > > > /* We include some slack space in case the calculation isn't quite right or > > we > > * add another field and forget to adjust this value. > > */ > > #define ODPUTIL_FLOW_KEY_BYTES 200 > > > > BUILD_ASSERT_DECL(ODP_FLOW_KEY_MAX_TOTAL < ODPUTIL_FLOW_KEY_BYTES) > > -=-=-=-=-=-=-=-=-=-=- > > > > However, ODPUTIL_FLOW_KEY_BYTES is defined pretty close to "total", so it's > > probably pointless. I'll drop this, unless you've suddenly fallen in love > > with the idea. :-) --8<--------------------------cut here-------------------------->8-- From: Ben Pfaff <b...@nicira.com> Date: Tue, 15 May 2012 12:50:57 -0700 Subject: [PATCH] odp-util: Update ODPUTIL_FLOW_KEY_BYTES for current kernel flow format. Before we submitted the kernel module upstream, we updated the flow format by adding two fields to the description of packets with VLAN headers, but we forgot to update ODPUTIL_FLOW_KEY_BYTES to reflect these changes. The result was that a maximum-length flow did not fit in the given space. This fixes a crash processing IPv6 neighbor discovery packets with VLAN headers received in a tunnel configured with key=flow or in_key=flow. This updates some comments to better describe the implications of ODPUTIL_FLOW_KEY_BYTES (suggested by Justin). This also updates test-odp.c so that it would have caught this problem, and updates odp.at to demonstrate that a full 156 bytes are necessary. (To see that, revert the change to ODPUTIL_FLOW_KEY_BYTES and run the test.) Reported-by: Dan Wendlandt <d...@nicira.com> Signed-off-by: Ben Pfaff <b...@nicira.com> --- lib/odp-util.c | 7 +++++-- lib/odp-util.h | 25 +++++++++++++++++++------ tests/odp.at | 6 ++++++ tests/test-odp.c | 11 +++++++++-- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/lib/odp-util.c b/lib/odp-util.c index aae5cc7..7e5c12f 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1155,7 +1155,10 @@ ovs_to_odp_frag(uint8_t ovs_frag) : OVS_FRAG_TYPE_NONE); } -/* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'. */ +/* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'. + * + * 'buf' must have at least ODPUTIL_FLOW_KEY_BYTES bytes of space, or be + * capable of being expanded to allow for that much space. */ void odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow) { diff --git a/lib/odp-util.h b/lib/odp-util.h index 7c9b588..45d7d3f 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,8 +65,16 @@ void format_odp_actions(struct ds *, const struct nlattr *odp_actions, int odp_actions_from_string(const char *, const struct shash *port_names, struct ofpbuf *odp_actions); -/* Upper bound on the length of a nlattr-formatted flow key. The longest - * nlattr-formatted flow key would be: +/* The maximum number of bytes that odp_flow_key_from_flow() appends to a + * buffer. This is the upper bound on the length of a nlattr-formatted flow + * key that ovs-vswitchd fully understands. + * + * OVS doesn't insist that ovs-vswitchd and the datapath have exactly the same + * idea of a flow, so therefore this value isn't necessarily an upper bound on + * the length of a flow key that the datapath can pass to ovs-vswitchd. + * + * The longest nlattr-formatted flow key appended by odp_flow_key_from_flow() + * would be: * * struct pad nl hdr total * ------ --- ------ ----- @@ -74,15 +82,20 @@ int odp_actions_from_string(const char *, const struct shash *port_names, * OVS_KEY_ATTR_TUN_ID 8 -- 4 12 * OVS_KEY_ATTR_IN_PORT 4 -- 4 8 * OVS_KEY_ATTR_ETHERNET 12 -- 4 16 + * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype) * OVS_KEY_ATTR_8021Q 4 -- 4 8 - * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 + * OVS_KEY_ATTR_ENCAP 0 -- 4 4 (VLAN encapsulation) + * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (inner VLAN ethertype) * OVS_KEY_ATTR_IPV6 40 -- 4 44 * OVS_KEY_ATTR_ICMPV6 2 2 4 8 * OVS_KEY_ATTR_ND 28 -- 4 32 * ------------------------------------------------- - * total 144 + * total 156 + * + * We include some slack space in case the calculation isn't quite right or we + * add another field and forget to adjust this value. */ -#define ODPUTIL_FLOW_KEY_BYTES 144 +#define ODPUTIL_FLOW_KEY_BYTES 200 /* A buffer with sufficient size and alignment to hold an nlattr-formatted flow * key. An array of "struct nlattr" might not, in theory, be sufficiently diff --git a/tests/odp.at b/tests/odp.at index 90a1192..3e7a8ad 100644 --- a/tests/odp.at +++ b/tests/odp.at @@ -48,6 +48,12 @@ s/\(eth([[^)]]*)\),*/\1,eth_type(0x8100),vlan(vid=99,pcp=7),encap(/ s/$/)/' odp-base.txt echo + echo '# Valid forms with QOS priority, tun_id, and VLAN headers.' + sed 's/^/priority(1234),tun_id(0xfedcba9876543210),/ +s/\(eth([[^)]]*)\),*/\1,eth_type(0x8100),vlan(vid=99,pcp=7),encap(/ +s/$/)/' odp-base.txt + + echo echo '# Valid forms with IP first fragment.' sed -n 's/,frag=no),/,frag=first),/p' odp-base.txt diff --git a/tests/test-odp.c b/tests/test-odp.c index 9ae897c..cbf6004 100644 --- a/tests/test-odp.c +++ b/tests/test-odp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Nicira Networks. + * Copyright (c) 2011, 2012 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ int main(void) { + int exit_code = 0; struct ds in; ds_init(&in); @@ -85,6 +86,12 @@ main(void) ofpbuf_init(&odp_key, 0); odp_flow_key_from_flow(&odp_key, &flow); + if (odp_key.size > ODPUTIL_FLOW_KEY_BYTES) { + printf ("too long: %zu > %d\n", + odp_key.size, ODPUTIL_FLOW_KEY_BYTES); + exit_code = 1; + } + /* Convert odp_key to string. */ ds_init(&out); odp_flow_key_format(odp_key.data, odp_key.size, &out); @@ -96,5 +103,5 @@ main(void) } ds_destroy(&in); - return 0; + return exit_code; } -- 1.7.2.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev