History

netfilter: conntrack: handle ->destroy hook via nat_ops instead

The nat module already exposes a few functions to the conntrack core. Move the nat extension destroy hook to it. After this, no conntrack extension needs a destroy hook. 'struct nf_ct_ext_type' and the register/unregister api can be removed in a followup patch.

Florian Westphal committed 4 years ago

Commit 1bc91a51 parent 5f31edc5 files · +16 −36Browse files

Unified · Split

5 files
  1. include/linux/netfilter.h +1 −0
  2. include/net/netfilter/nf_conntrack_extend.h +0 −3
  3. net/netfilter/nf_conntrack_core.c +12 −2
  4. net/netfilter/nf_conntrack_extend.c +0 −21
  5. net/netfilter/nf_nat_core.c +3 −10
include/linux/netfilter.h+1−0
@@ -379,6 +379,7 @@ struct nf_nat_hook { · 378 unmodified lines
379 unsigned int (*manip_pkt)(struct sk_buff *skb, struct nf_conn *ct,379 unsigned int (*manip_pkt)(struct sk_buff *skb, struct nf_conn *ct,
380 enum nf_nat_manip_type mtype,380 enum nf_nat_manip_type mtype,
381 enum ip_conntrack_dir dir);381 enum ip_conntrack_dir dir);
382 void (*remove_nat_bysrc)(struct nf_conn *ct);
382};383};
383 384
384extern const struct nf_nat_hook __rcu *nf_nat_hook;385extern const struct nf_nat_hook __rcu *nf_nat_hook;
include/net/netfilter/nf_conntrack_extend.h+0−3
@@ -79,9 +79,6 @@ void nf_ct_ext_destroy(struct nf_conn *ct); · 78 unmodified lines
79void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp);79void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp);
80 80
81struct nf_ct_ext_type {81struct nf_ct_ext_type {
82 /* Destroys relationships (can be NULL). */
83 void (*destroy)(struct nf_conn *ct);
84
85 enum nf_ct_ext_id id;82 enum nf_ct_ext_id id;
86};83};
87 84
net/netfilter/nf_conntrack_core.c+12−2
@@ -594,7 +594,7 @@ EXPORT_SYMBOL_GPL(nf_ct_tmpl_alloc); · 593 unmodified lines
594 594
595void nf_ct_tmpl_free(struct nf_conn *tmpl)595void nf_ct_tmpl_free(struct nf_conn *tmpl)
596{596{
597 nf_ct_ext_destroy(tmpl);597 kfree(tmpl->ext);
598 598
599 if (ARCH_KMALLOC_MINALIGN <= NFCT_INFOMASK)599 if (ARCH_KMALLOC_MINALIGN <= NFCT_INFOMASK)
600 kfree((char *)tmpl - tmpl->proto.tmpl_padto);600 kfree((char *)tmpl - tmpl->proto.tmpl_padto);
@@ -1597,7 +1597,17 @@ void nf_conntrack_free(struct nf_conn *ct) · 996 unmodified lines
1597 */1597 */
1598 WARN_ON(refcount_read(&ct->ct_general.use) != 0);1598 WARN_ON(refcount_read(&ct->ct_general.use) != 0);
1599 1599
1600 nf_ct_ext_destroy(ct);1600 if (ct->status & IPS_SRC_NAT_DONE) {
1601 const struct nf_nat_hook *nat_hook;
1602
1603 rcu_read_lock();
1604 nat_hook = rcu_dereference(nf_nat_hook);
1605 if (nat_hook)
1606 nat_hook->remove_nat_bysrc(ct);
1607 rcu_read_unlock();
1608 }
1609
1610 kfree(ct->ext);
1601 kmem_cache_free(nf_conntrack_cachep, ct);1611 kmem_cache_free(nf_conntrack_cachep, ct);
1602 cnet = nf_ct_pernet(net);1612 cnet = nf_ct_pernet(net);
1603 1613
net/netfilter/nf_conntrack_extend.c+0−21
@@ -89,27 +89,6 @@ static __always_inline unsigned int total_extension_size(void) · 88 unmodified lines
89 ;89 ;
90}90}
91 91
92void nf_ct_ext_destroy(struct nf_conn *ct)
93{
94 unsigned int i;
95 struct nf_ct_ext_type *t;
96
97 for (i = 0; i < NF_CT_EXT_NUM; i++) {
98 rcu_read_lock();
99 t = rcu_dereference(nf_ct_ext_types[i]);
100
101 /* Here the nf_ct_ext_type might have been unregisterd.
102 * I.e., it has responsible to cleanup private
103 * area in all conntracks when it is unregisterd.
104 */
105 if (t && t->destroy)
106 t->destroy(ct);
107 rcu_read_unlock();
108 }
109
110 kfree(ct->ext);
111}
112
113void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)92void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
114{93{
115 unsigned int newlen, newoff, oldlen, alloc;94 unsigned int newlen, newoff, oldlen, alloc;
net/netfilter/nf_nat_core.c+3−10
@@ -838,7 +838,7 @@ static int nf_nat_proto_remove(struct nf_conn *i, void *data) · 837 unmodified lines
838 return i->status & IPS_NAT_MASK ? 1 : 0;838 return i->status & IPS_NAT_MASK ? 1 : 0;
839}839}
840 840
841static void __nf_nat_cleanup_conntrack(struct nf_conn *ct)841static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
842{842{
843 unsigned int h;843 unsigned int h;
844 844
@@ -860,7 +860,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data) · 15 unmodified lines
860 * will delete entry from already-freed table.860 * will delete entry from already-freed table.
861 */861 */
862 if (test_and_clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status))862 if (test_and_clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status))
863 __nf_nat_cleanup_conntrack(ct);863 nf_nat_cleanup_conntrack(ct);
864 864
865 /* don't delete conntrack. Although that would make things a lot865 /* don't delete conntrack. Although that would make things a lot
866 * simpler, we'd end up flushing all conntracks on nat rmmod.866 * simpler, we'd end up flushing all conntracks on nat rmmod.
@@ -868,15 +868,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data) · 1 unmodified line
868 return 0;868 return 0;
869}869}
870 870
871/* No one using conntrack by the time this called. */
872static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
873{
874 if (ct->status & IPS_SRC_NAT_DONE)
875 __nf_nat_cleanup_conntrack(ct);
876}
877
878static struct nf_ct_ext_type nat_extend __read_mostly = {871static struct nf_ct_ext_type nat_extend __read_mostly = {
879 .destroy = nf_nat_cleanup_conntrack,
880 .id = NF_CT_EXT_NAT,872 .id = NF_CT_EXT_NAT,
881};873};
882 874
@@ -1171,6 +1163,7 @@ static const struct nf_nat_hook nat_hook = { · 288 unmodified lines
1171 .decode_session = __nf_nat_decode_session,1163 .decode_session = __nf_nat_decode_session,
1172#endif1164#endif
1173 .manip_pkt = nf_nat_manip_pkt,1165 .manip_pkt = nf_nat_manip_pkt,
1166 .remove_nat_bysrc = nf_nat_cleanup_conntrack,
1174};1167};
1175 1168
1176static int __init nf_nat_init(void)1169static int __init nf_nat_init(void)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t