diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 2dcf317..354cccb9 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -66,13 +66,15 @@ static inline void nf_ct_ext_destroy(struct nf_conn *ct) __nf_ct_ext_destroy(ct); } +void __nf_ct_ext_free_rcu(struct rcu_head *head); + /* Free operation. If you want to free a object referred from private area, * please implement __nf_ct_ext_free() and call it. */ static inline void nf_ct_ext_free(struct nf_conn *ct) { if (ct->ext) - kfree(ct->ext); + call_rcu(&ct->ext->rcu, __nf_ct_ext_free_rcu); } /* Add this type, returns pointer to data or NULL. */ diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 80a23ed..3a47b76 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -68,11 +68,12 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) return (void *)(*ext) + off; } -static void __nf_ct_ext_free_rcu(struct rcu_head *head) +void __nf_ct_ext_free_rcu(struct rcu_head *head) { struct nf_ct_ext *ext = container_of(head, struct nf_ct_ext, rcu); kfree(ext); } +EXPORT_SYMBOL_GPL(__nf_ct_ext_free_rcu); void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) {