datapath: Better calculate max nlattr-formatted flow size.
authorJustin Pettit <jpettit@nicira.com>
Mon, 7 Feb 2011 06:46:27 +0000 (22:46 -0800)
committerJustin Pettit <jpettit@nicira.com>
Mon, 7 Feb 2011 23:40:35 +0000 (15:40 -0800)
Both userspace and the kernel allocate space based on the max size of a
nlattr-formatted flow.  It was easy to change the max size of a flow
definition and cause crashes by forgetting to update one or both of
those definitions.  This commit attempts to make that harder by
providing a better description of how the max size is calculated and a
build check to look for a common indication that it may have changed.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
datapath/flow.c
datapath/flow.h
lib/odp-util.h

index 4b0e6cc..fe05df3 100644 (file)
@@ -819,6 +819,11 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
        struct odp_key_ethernet *eth_key;
        struct nlattr *nla;
 
+       /* This is an imperfect sanity-check that FLOW_BUFSIZE doesn't need
+        * to be updated, but will at least raise awareness when new ODP key
+        * types are added. */
+       BUILD_BUG_ON(__ODP_KEY_ATTR_MAX != 14);
+
        if (swkey->tun_id != cpu_to_be64(0))
                NLA_PUT_BE64(skb, ODP_KEY_ATTR_TUN_ID, swkey->tun_id);
 
index 9cf5c67..a40073a 100644 (file)
@@ -107,8 +107,21 @@ u64 flow_used_time(unsigned long flow_jiffies);
 u32 flow_hash(const struct sw_flow_key *);
 int flow_cmp(const struct tbl_node *, void *target);
 
-/* By my calculations currently the longest valid nlattr-formatted flow key is
- * 132 bytes long.
+/* Upper bound on the length of a nlattr-formatted flow key.  The longest
+ * nlattr-formatted flow key would be:
+ *
+ *                         struct  pad  nl hdr  total
+ *                         ------  ---  ------  -----
+ *  ODP_KEY_ATTR_TUN_ID        8    --     4     12
+ *  ODP_KEY_ATTR_IN_PORT       4    --     4      8
+ *  ODP_KEY_ATTR_ETHERNET     12    --     4     16
+ *  ODP_KEY_ATTR_8021Q         4    --     4      8
+ *  ODP_KEY_ATTR_ETHERTYPE     2     2     4      8
+ *  ODP_KEY_ATTR_IPV6         34     2     4     40
+ *  ODP_KEY_ATTR_ICMPV6        2     2     4      8
+ *  ODP_KEY_ATTR_ND           28    --     4     32
+ *  -------------------------------------------------
+ *  total                                       132
  */
 #define FLOW_BUFSIZE 132
 
index d991b19..4020660 100644 (file)
@@ -63,14 +63,33 @@ void format_odp_action(struct ds *, const struct nlattr *);
 void format_odp_actions(struct ds *, const struct nlattr *odp_actions,
                         size_t actions_len);
 
-/* By my calculations currently the longest valid nlattr-formatted flow key is
- * 132 bytes long.
+/* Upper bound on the length of a nlattr-formatted flow key.  The longest
+ * nlattr-formatted flow key would be:
  *
- * We allocate temporary on-stack buffers for flow keys as arrays of uint32_t
+ *                         struct  pad  nl hdr  total
+ *                         ------  ---  ------  -----
+ *  ODP_KEY_ATTR_TUN_ID        8    --     4     12
+ *  ODP_KEY_ATTR_IN_PORT       4    --     4      8
+ *  ODP_KEY_ATTR_ETHERNET     12    --     4     16
+ *  ODP_KEY_ATTR_8021Q         4    --     4      8
+ *  ODP_KEY_ATTR_ETHERTYPE     2     2     4      8
+ *  ODP_KEY_ATTR_IPV6         34     2     4     40
+ *  ODP_KEY_ATTR_ICMPV6        2     2     4      8
+ *  ODP_KEY_ATTR_ND           28    --     4     32
+ *  -------------------------------------------------
+ *  total                                       132
+ */
+#define ODPUTIL_FLOW_KEY_BYTES 132
+
+/* This is an imperfect sanity-check that ODPUTIL_FLOW_KEY_BYTES doesn't
+ * need to be updated, but will at least raise awareness when new ODP
+ * key types are added. */
+BUILD_ASSERT_DECL(__ODP_KEY_ATTR_MAX == 14);
+
+/* We allocate temporary on-stack buffers for flow keys as arrays of uint32_t
  * to ensure proper 32-bit alignment for Netlink attributes.  (An array of
  * "struct nlattr" might not, in theory, be sufficiently aligned because it
  * only contains 16-bit types.) */
-#define ODPUTIL_FLOW_KEY_BYTES 132
 #define ODPUTIL_FLOW_KEY_U32S DIV_ROUND_UP(ODPUTIL_FLOW_KEY_BYTES, 4)
 
 void odp_flow_key_format(const struct nlattr *, size_t, struct ds *);