]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/netfilter/xt_repldata.h
Merge branch 'for-4.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj...
[karo-tx-linux.git] / net / netfilter / xt_repldata.h
index 6efe4e5a81c62b3962771508b4b5483f68108945..8fd324116e6f127e63205339f2bc9345a26d74ea 100644 (file)
@@ -5,23 +5,35 @@
  * they serve as the hanging-off data accessed through repl.data[].
  */
 
+/* tbl has the following structure equivalent, but is C99 compliant:
+ * struct {
+ *     struct type##_replace repl;
+ *     struct type##_standard entries[nhooks];
+ *     struct type##_error term;
+ * } *tbl;
+ */
+
 #define xt_alloc_initial_table(type, typ2) ({ \
        unsigned int hook_mask = info->valid_hooks; \
        unsigned int nhooks = hweight32(hook_mask); \
        unsigned int bytes = 0, hooknum = 0, i = 0; \
        struct { \
                struct type##_replace repl; \
-               struct type##_standard entries[nhooks]; \
-               struct type##_error term; \
-       } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \
+               struct type##_standard entries[]; \
+       } *tbl; \
+       struct type##_error *term; \
+       size_t term_offset = (offsetof(typeof(*tbl), entries[nhooks]) + \
+               __alignof__(*term) - 1) & ~(__alignof__(*term) - 1); \
+       tbl = kzalloc(term_offset + sizeof(*term), GFP_KERNEL); \
        if (tbl == NULL) \
                return NULL; \
+       term = (struct type##_error *)&(((char *)tbl)[term_offset]); \
        strncpy(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \
-       tbl->term = (struct type##_error)typ2##_ERROR_INIT;  \
+       *term = (struct type##_error)typ2##_ERROR_INIT;  \
        tbl->repl.valid_hooks = hook_mask; \
        tbl->repl.num_entries = nhooks + 1; \
        tbl->repl.size = nhooks * sizeof(struct type##_standard) + \
-                        sizeof(struct type##_error); \
+                        sizeof(struct type##_error); \
        for (; hook_mask != 0; hook_mask >>= 1, ++hooknum) { \
                if (!(hook_mask & 1)) \
                        continue; \