1313#include <linux/skbuff.h>
1414#include <net/netfilter/nf_conntrack_extend.h>
1515
16+ #include <net/netfilter/nf_conntrack_helper.h>
17+ #include <net/netfilter/nf_conntrack_acct.h>
18+ #include <net/netfilter/nf_conntrack_seqadj.h>
19+ #include <net/netfilter/nf_conntrack_ecache.h>
20+ #include <net/netfilter/nf_conntrack_zones.h>
21+ #include <net/netfilter/nf_conntrack_timestamp.h>
22+ #include <net/netfilter/nf_conntrack_timeout.h>
23+ #include <net/netfilter/nf_conntrack_labels.h>
24+ #include <net/netfilter/nf_conntrack_synproxy.h>
25+ #include <net/netfilter/nf_conntrack_act_ct.h>
26+ #include <net/netfilter/nf_nat.h>
27+
1628static struct nf_ct_ext_type __rcu * nf_ct_ext_types [NF_CT_EXT_NUM ];
1729static DEFINE_MUTEX (nf_ct_ext_type_mutex );
1830#define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */
1931
32+ static const u8 nf_ct_ext_type_len [NF_CT_EXT_NUM ] = {
33+ [NF_CT_EXT_HELPER ] = sizeof (struct nf_conn_help ),
34+ #if IS_ENABLED (CONFIG_NF_NAT )
35+ [NF_CT_EXT_NAT ] = sizeof (struct nf_conn_nat ),
36+ #endif
37+ [NF_CT_EXT_SEQADJ ] = sizeof (struct nf_conn_seqadj ),
38+ [NF_CT_EXT_ACCT ] = sizeof (struct nf_conn_acct ),
39+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
40+ [NF_CT_EXT_ECACHE ] = sizeof (struct nf_conntrack_ecache ),
41+ #endif
42+ #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
43+ [NF_CT_EXT_TSTAMP ] = sizeof (struct nf_conn_acct ),
44+ #endif
45+ #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
46+ [NF_CT_EXT_TIMEOUT ] = sizeof (struct nf_conn_tstamp ),
47+ #endif
48+ #ifdef CONFIG_NF_CONNTRACK_LABELS
49+ [NF_CT_EXT_LABELS ] = sizeof (struct nf_conn_labels ),
50+ #endif
51+ #if IS_ENABLED (CONFIG_NETFILTER_SYNPROXY )
52+ [NF_CT_EXT_SYNPROXY ] = sizeof (struct nf_conn_synproxy ),
53+ #endif
54+ #if IS_ENABLED (CONFIG_NET_ACT_CT )
55+ [NF_CT_EXT_ACT_CT ] = sizeof (struct nf_conn_act_ct_ext ),
56+ #endif
57+ };
58+
59+ static __always_inline unsigned int total_extension_size (void )
60+ {
61+ /* remember to add new extensions below */
62+ BUILD_BUG_ON (NF_CT_EXT_NUM > 10 );
63+
64+ return sizeof (struct nf_ct_ext ) +
65+ sizeof (struct nf_conn_help )
66+ #if IS_ENABLED (CONFIG_NF_NAT )
67+ + sizeof (struct nf_conn_nat )
68+ #endif
69+ + sizeof (struct nf_conn_seqadj )
70+ + sizeof (struct nf_conn_acct )
71+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
72+ + sizeof (struct nf_conntrack_ecache )
73+ #endif
74+ #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
75+ + sizeof (struct nf_conn_tstamp )
76+ #endif
77+ #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
78+ + sizeof (struct nf_conn_timeout )
79+ #endif
80+ #ifdef CONFIG_NF_CONNTRACK_LABELS
81+ + sizeof (struct nf_conn_labels )
82+ #endif
83+ #if IS_ENABLED (CONFIG_NETFILTER_SYNPROXY )
84+ + sizeof (struct nf_conn_synproxy )
85+ #endif
86+ #if IS_ENABLED (CONFIG_NET_ACT_CT )
87+ + sizeof (struct nf_conn_act_ct_ext )
88+ #endif
89+ ;
90+ }
91+
2092void nf_ct_ext_destroy (struct nf_conn * ct )
2193{
2294 unsigned int i ;
@@ -41,7 +113,6 @@ void nf_ct_ext_destroy(struct nf_conn *ct)
41113void * nf_ct_ext_add (struct nf_conn * ct , enum nf_ct_ext_id id , gfp_t gfp )
42114{
43115 unsigned int newlen , newoff , oldlen , alloc ;
44- struct nf_ct_ext_type * t ;
45116 struct nf_ct_ext * new ;
46117
47118 /* Conntrack must not be confirmed to avoid races on reallocation. */
@@ -58,16 +129,8 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
58129 oldlen = sizeof (* new );
59130 }
60131
61- rcu_read_lock ();
62- t = rcu_dereference (nf_ct_ext_types [id ]);
63- if (!t ) {
64- rcu_read_unlock ();
65- return NULL ;
66- }
67-
68132 newoff = ALIGN (oldlen , __alignof__(struct nf_ct_ext ));
69- newlen = newoff + t -> len ;
70- rcu_read_unlock ();
133+ newlen = newoff + nf_ct_ext_type_len [id ];
71134
72135 alloc = max (newlen , NF_CT_EXT_PREALLOC );
73136 new = krealloc (ct -> ext , alloc , gfp );
@@ -91,6 +154,9 @@ int nf_ct_extend_register(const struct nf_ct_ext_type *type)
91154{
92155 int ret = 0 ;
93156
157+ /* struct nf_ct_ext uses u8 to store offsets/size */
158+ BUILD_BUG_ON (total_extension_size () > 255u );
159+
94160 mutex_lock (& nf_ct_ext_type_mutex );
95161 if (nf_ct_ext_types [type -> id ]) {
96162 ret = - EBUSY ;
0 commit comments