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.
Unified · Split
| @@ -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 | ||
| 384 | extern const struct nf_nat_hook __rcu *nf_nat_hook; | 385 | extern const struct nf_nat_hook __rcu *nf_nat_hook; |
| @@ -79,9 +79,6 @@ void nf_ct_ext_destroy(struct nf_conn *ct); · 78 unmodified lines | |||
| 79 | void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp); | 79 | void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp); |
| 80 | 80 | ||
| 81 | struct nf_ct_ext_type { | 81 | struct 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 | ||
| @@ -594,7 +594,7 @@ EXPORT_SYMBOL_GPL(nf_ct_tmpl_alloc); · 593 unmodified lines | |||
| 594 | 594 | ||
| 595 | void nf_ct_tmpl_free(struct nf_conn *tmpl) | 595 | void 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 | ||
| @@ -89,27 +89,6 @@ static __always_inline unsigned int total_extension_size(void) · 88 unmodified lines | |||
| 89 | ; | 89 | ; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | void 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 | |||
| 113 | void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) | 92 | void *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; |
| @@ -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 | ||
| 841 | static void __nf_nat_cleanup_conntrack(struct nf_conn *ct) | 841 | static 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 lot | 865 | /* 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. */ | ||
| 872 | static 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 | |||
| 878 | static struct nf_ct_ext_type nat_extend __read_mostly = { | 871 | static 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 | #endif | 1164 | #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 | ||
| 1176 | static int __init nf_nat_init(void) | 1169 | static int __init nf_nat_init(void) |