aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/x_tables.h8
-rw-r--r--net/bridge/netfilter/ebtables.c19
-rw-r--r--net/ipv4/netfilter/arp_tables.c9
-rw-r--r--net/ipv4/netfilter/ip_tables.c10
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c6
-rw-r--r--net/ipv6/netfilter/ip6_tables.c10
-rw-r--r--net/netfilter/xt_CONNMARK.c5
-rw-r--r--net/netfilter/xt_CONNSECMARK.c5
-rw-r--r--net/netfilter/xt_RATEEST.c5
-rw-r--r--net/netfilter/xt_SECMARK.c2
-rw-r--r--net/sched/act_ipt.c10
11 files changed, 57 insertions, 32 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 8daeb496ba7a..e3b3b669a143 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -251,6 +251,12 @@ struct xt_tgchk_param {
251 unsigned int hook_mask; 251 unsigned int hook_mask;
252}; 252};
253 253
254/* Target destructor parameters */
255struct xt_tgdtor_param {
256 const struct xt_target *target;
257 void *targinfo;
258};
259
254struct xt_match 260struct xt_match
255{ 261{
256 struct list_head list; 262 struct list_head list;
@@ -311,7 +317,7 @@ struct xt_target
311 bool (*checkentry)(const struct xt_tgchk_param *); 317 bool (*checkentry)(const struct xt_tgchk_param *);
312 318
313 /* Called when entry of this type deleted. */ 319 /* Called when entry of this type deleted. */
314 void (*destroy)(const struct xt_target *target, void *targinfo); 320 void (*destroy)(const struct xt_tgdtor_param *);
315 321
316 /* Called when userspace align differs from kernel space one */ 322 /* Called when userspace align differs from kernel space one */
317 void (*compat_from_user)(void *dst, void *src); 323 void (*compat_from_user)(void *dst, void *src);
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index cf823c21c166..29d8061fa153 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -581,18 +581,23 @@ ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
581static inline int 581static inline int
582ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) 582ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
583{ 583{
584 struct xt_tgdtor_param par;
585
584 if (i && (*i)-- == 0) 586 if (i && (*i)-- == 0)
585 return 1; 587 return 1;
586 if (w->u.watcher->destroy)
587 w->u.watcher->destroy(w->u.watcher, w->data);
588 module_put(w->u.watcher->me);
589 588
589 par.target = w->u.watcher;
590 par.targinfo = w->data;
591 if (par.target->destroy != NULL)
592 par.target->destroy(&par);
593 module_put(par.target->me);
590 return 0; 594 return 0;
591} 595}
592 596
593static inline int 597static inline int
594ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) 598ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
595{ 599{
600 struct xt_tgdtor_param par;
596 struct ebt_entry_target *t; 601 struct ebt_entry_target *t;
597 602
598 if (e->bitmask == 0) 603 if (e->bitmask == 0)
@@ -603,10 +608,12 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
603 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); 608 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
604 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); 609 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
605 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 610 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
606 if (t->u.target->destroy)
607 t->u.target->destroy(t->u.target, t->data);
608 module_put(t->u.target->me);
609 611
612 par.target = t->u.target;
613 par.targinfo = t->data;
614 if (par.target->destroy != NULL)
615 par.target->destroy(&par);
616 module_put(par.target->me);
610 return 0; 617 return 0;
611} 618}
612 619
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b3238d0101cc..3bab78330cf8 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -557,15 +557,18 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
557 557
558static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) 558static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
559{ 559{
560 struct xt_tgdtor_param par;
560 struct arpt_entry_target *t; 561 struct arpt_entry_target *t;
561 562
562 if (i && (*i)-- == 0) 563 if (i && (*i)-- == 0)
563 return 1; 564 return 1;
564 565
565 t = arpt_get_target(e); 566 t = arpt_get_target(e);
566 if (t->u.kernel.target->destroy) 567 par.target = t->u.kernel.target;
567 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 568 par.targinfo = t->data;
568 module_put(t->u.kernel.target->me); 569 if (par.target->destroy != NULL)
570 par.target->destroy(&par);
571 module_put(par.target->me);
569 return 0; 572 return 0;
570} 573}
571 574
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e592c54d4992..50b9a6c34c38 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -768,6 +768,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
768static int 768static int
769cleanup_entry(struct ipt_entry *e, unsigned int *i) 769cleanup_entry(struct ipt_entry *e, unsigned int *i)
770{ 770{
771 struct xt_tgdtor_param par;
771 struct ipt_entry_target *t; 772 struct ipt_entry_target *t;
772 773
773 if (i && (*i)-- == 0) 774 if (i && (*i)-- == 0)
@@ -776,9 +777,12 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
776 /* Cleanup all matches */ 777 /* Cleanup all matches */
777 IPT_MATCH_ITERATE(e, cleanup_match, NULL); 778 IPT_MATCH_ITERATE(e, cleanup_match, NULL);
778 t = ipt_get_target(e); 779 t = ipt_get_target(e);
779 if (t->u.kernel.target->destroy) 780
780 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 781 par.target = t->u.kernel.target;
781 module_put(t->u.kernel.target->me); 782 par.targinfo = t->data;
783 if (par.target->destroy != NULL)
784 par.target->destroy(&par);
785 module_put(par.target->me);
782 return 0; 786 return 0;
783} 787}
784 788
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 6c7254e02561..7ac1677419a9 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -411,9 +411,9 @@ static bool clusterip_tg_check(const struct xt_tgchk_param *par)
411} 411}
412 412
413/* drop reference count of cluster config when rule is deleted */ 413/* drop reference count of cluster config when rule is deleted */
414static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) 414static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
415{ 415{
416 const struct ipt_clusterip_tgt_info *cipinfo = targinfo; 416 const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
417 417
418 /* if no more entries are referencing the config, remove it 418 /* if no more entries are referencing the config, remove it
419 * from the list and destroy the proc entry */ 419 * from the list and destroy the proc entry */
@@ -421,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
421 421
422 clusterip_config_put(cipinfo->config); 422 clusterip_config_put(cipinfo->config);
423 423
424 nf_ct_l3proto_module_put(target->family); 424 nf_ct_l3proto_module_put(par->target->family);
425} 425}
426 426
427#ifdef CONFIG_COMPAT 427#ifdef CONFIG_COMPAT
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index ca14fb8bd362..d934a6994632 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -793,6 +793,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
793static int 793static int
794cleanup_entry(struct ip6t_entry *e, unsigned int *i) 794cleanup_entry(struct ip6t_entry *e, unsigned int *i)
795{ 795{
796 struct xt_tgdtor_param par;
796 struct ip6t_entry_target *t; 797 struct ip6t_entry_target *t;
797 798
798 if (i && (*i)-- == 0) 799 if (i && (*i)-- == 0)
@@ -801,9 +802,12 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
801 /* Cleanup all matches */ 802 /* Cleanup all matches */
802 IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 803 IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
803 t = ip6t_get_target(e); 804 t = ip6t_get_target(e);
804 if (t->u.kernel.target->destroy) 805
805 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 806 par.target = t->u.kernel.target;
806 module_put(t->u.kernel.target->me); 807 par.targinfo = t->data;
808 if (par.target->destroy != NULL)
809 par.target->destroy(&par);
810 module_put(par.target->me);
807 return 0; 811 return 0;
808} 812}
809 813
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 8fc9f35e67df..c5a5072e005d 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -146,10 +146,9 @@ static bool connmark_tg_check(const struct xt_tgchk_param *par)
146 return true; 146 return true;
147} 147}
148 148
149static void 149static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
150connmark_tg_destroy(const struct xt_target *target, void *targinfo)
151{ 150{
152 nf_ct_l3proto_module_put(target->family); 151 nf_ct_l3proto_module_put(par->target->family);
153} 152}
154 153
155#ifdef CONFIG_COMPAT 154#ifdef CONFIG_COMPAT
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 2041a3d4b4d8..b6e3f3f125fd 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -114,10 +114,9 @@ static bool connsecmark_tg_check(const struct xt_tgchk_param *par)
114 return true; 114 return true;
115} 115}
116 116
117static void 117static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
118connsecmark_tg_destroy(const struct xt_target *target, void *targinfo)
119{ 118{
120 nf_ct_l3proto_module_put(target->family); 119 nf_ct_l3proto_module_put(par->target->family);
121} 120}
122 121
123static struct xt_target connsecmark_tg_reg[] __read_mostly = { 122static struct xt_target connsecmark_tg_reg[] __read_mostly = {
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
index edf4ab1f30ff..43f5676b1af4 100644
--- a/net/netfilter/xt_RATEEST.c
+++ b/net/netfilter/xt_RATEEST.c
@@ -139,10 +139,9 @@ err1:
139 return false; 139 return false;
140} 140}
141 141
142static void xt_rateest_tg_destroy(const struct xt_target *target, 142static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par)
143 void *targinfo)
144{ 143{
145 struct xt_rateest_target_info *info = targinfo; 144 struct xt_rateest_target_info *info = par->targinfo;
146 145
147 xt_rateest_put(info->est); 146 xt_rateest_put(info->est);
148} 147}
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index e5777227192c..7a6f9e6f5dfa 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -113,7 +113,7 @@ static bool secmark_tg_check(const struct xt_tgchk_param *par)
113 return true; 113 return true;
114} 114}
115 115
116static void secmark_tg_destroy(const struct xt_target *target, void *targinfo) 116static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
117{ 117{
118 switch (mode) { 118 switch (mode) {
119 case SECMARK_MODE_SEL: 119 case SECMARK_MODE_SEL:
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index a54dc3f8234f..b951d422db9b 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -67,9 +67,13 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
67 67
68static void ipt_destroy_target(struct ipt_entry_target *t) 68static void ipt_destroy_target(struct ipt_entry_target *t)
69{ 69{
70 if (t->u.kernel.target->destroy) 70 struct xt_tgdtor_param par = {
71 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 71 .target = t->u.kernel.target,
72 module_put(t->u.kernel.target->me); 72 .targinfo = t->data,
73 };
74 if (par.target->destroy != NULL)
75 par.target->destroy(&par);
76 module_put(par.target->me);
73} 77}
74 78
75static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) 79static int tcf_ipt_release(struct tcf_ipt *ipt, int bind)