Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_ct_ext: support variable length extensions

We can now define conntrack extensions of variable size. This
patch is useful to get rid of these unions:

union nf_conntrack_help
union nf_conntrack_proto
union nf_conntrack_nat_help

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+15 -10
+6 -3
include/net/netfilter/nf_conntrack_extend.h
··· 80 80 } 81 81 82 82 /* Add this type, returns pointer to data or NULL. */ 83 - void * 84 - __nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp); 83 + void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, 84 + size_t var_alloc_len, gfp_t gfp); 85 + 85 86 #define nf_ct_ext_add(ct, id, gfp) \ 86 - ((id##_TYPE *)__nf_ct_ext_add((ct), (id), (gfp))) 87 + ((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), 0, (gfp))) 88 + #define nf_ct_ext_add_length(ct, id, len, gfp) \ 89 + ((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), (len), (gfp))) 87 90 88 91 #define NF_CT_EXT_F_PREALLOC 0x0001 89 92
+9 -7
net/netfilter/nf_conntrack_extend.c
··· 44 44 EXPORT_SYMBOL(__nf_ct_ext_destroy); 45 45 46 46 static void * 47 - nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) 47 + nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, 48 + size_t var_alloc_len, gfp_t gfp) 48 49 { 49 50 unsigned int off, len; 50 51 struct nf_ct_ext_type *t; ··· 55 54 t = rcu_dereference(nf_ct_ext_types[id]); 56 55 BUG_ON(t == NULL); 57 56 off = ALIGN(sizeof(struct nf_ct_ext), t->align); 58 - len = off + t->len; 59 - alloc_size = t->alloc_size; 57 + len = off + t->len + var_alloc_len; 58 + alloc_size = t->alloc_size + var_alloc_len; 60 59 rcu_read_unlock(); 61 60 62 61 *ext = kzalloc(alloc_size, gfp); ··· 69 68 return (void *)(*ext) + off; 70 69 } 71 70 72 - void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) 71 + void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, 72 + size_t var_alloc_len, gfp_t gfp) 73 73 { 74 74 struct nf_ct_ext *old, *new; 75 75 int i, newlen, newoff; ··· 81 79 82 80 old = ct->ext; 83 81 if (!old) 84 - return nf_ct_ext_create(&ct->ext, id, gfp); 82 + return nf_ct_ext_create(&ct->ext, id, var_alloc_len, gfp); 85 83 86 84 if (__nf_ct_ext_exist(old, id)) 87 85 return NULL; ··· 91 89 BUG_ON(t == NULL); 92 90 93 91 newoff = ALIGN(old->len, t->align); 94 - newlen = newoff + t->len; 92 + newlen = newoff + t->len + var_alloc_len; 95 93 rcu_read_unlock(); 96 94 97 95 new = __krealloc(old, newlen, gfp); ··· 119 117 memset((void *)new + newoff, 0, newlen - newoff); 120 118 return (void *)new + newoff; 121 119 } 122 - EXPORT_SYMBOL(__nf_ct_ext_add); 120 + EXPORT_SYMBOL(__nf_ct_ext_add_length); 123 121 124 122 static void update_alloc_size(struct nf_ct_ext_type *type) 125 123 {