20
20
#include <linux/netfilter/xt_TEE.h>
21
21
22
22
struct xt_tee_priv {
23
- struct notifier_block notifier ;
23
+ struct list_head list ;
24
24
struct xt_tee_tginfo * tginfo ;
25
25
int oif ;
26
26
};
@@ -51,29 +51,35 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
51
51
}
52
52
#endif
53
53
54
+ static DEFINE_MUTEX (priv_list_mutex );
55
+ static LIST_HEAD (priv_list );
56
+
54
57
static int tee_netdev_event (struct notifier_block * this , unsigned long event ,
55
58
void * ptr )
56
59
{
57
60
struct net_device * dev = netdev_notifier_info_to_dev (ptr );
58
61
struct xt_tee_priv * priv ;
59
62
60
- priv = container_of (this , struct xt_tee_priv , notifier );
61
- switch (event ) {
62
- case NETDEV_REGISTER :
63
- if (!strcmp (dev -> name , priv -> tginfo -> oif ))
64
- priv -> oif = dev -> ifindex ;
65
- break ;
66
- case NETDEV_UNREGISTER :
67
- if (dev -> ifindex == priv -> oif )
68
- priv -> oif = -1 ;
69
- break ;
70
- case NETDEV_CHANGENAME :
71
- if (!strcmp (dev -> name , priv -> tginfo -> oif ))
72
- priv -> oif = dev -> ifindex ;
73
- else if (dev -> ifindex == priv -> oif )
74
- priv -> oif = -1 ;
75
- break ;
63
+ mutex_lock (& priv_list_mutex );
64
+ list_for_each_entry (priv , & priv_list , list ) {
65
+ switch (event ) {
66
+ case NETDEV_REGISTER :
67
+ if (!strcmp (dev -> name , priv -> tginfo -> oif ))
68
+ priv -> oif = dev -> ifindex ;
69
+ break ;
70
+ case NETDEV_UNREGISTER :
71
+ if (dev -> ifindex == priv -> oif )
72
+ priv -> oif = -1 ;
73
+ break ;
74
+ case NETDEV_CHANGENAME :
75
+ if (!strcmp (dev -> name , priv -> tginfo -> oif ))
76
+ priv -> oif = dev -> ifindex ;
77
+ else if (dev -> ifindex == priv -> oif )
78
+ priv -> oif = -1 ;
79
+ break ;
80
+ }
76
81
}
82
+ mutex_unlock (& priv_list_mutex );
77
83
78
84
return NOTIFY_DONE ;
79
85
}
@@ -89,8 +95,6 @@ static int tee_tg_check(const struct xt_tgchk_param *par)
89
95
return - EINVAL ;
90
96
91
97
if (info -> oif [0 ]) {
92
- int ret ;
93
-
94
98
if (info -> oif [sizeof (info -> oif )- 1 ] != '\0' )
95
99
return - EINVAL ;
96
100
@@ -100,14 +104,11 @@ static int tee_tg_check(const struct xt_tgchk_param *par)
100
104
101
105
priv -> tginfo = info ;
102
106
priv -> oif = -1 ;
103
- priv -> notifier .notifier_call = tee_netdev_event ;
104
107
info -> priv = priv ;
105
108
106
- ret = register_netdevice_notifier (& priv -> notifier );
107
- if (ret ) {
108
- kfree (priv );
109
- return ret ;
110
- }
109
+ mutex_lock (& priv_list_mutex );
110
+ list_add (& priv -> list , & priv_list );
111
+ mutex_unlock (& priv_list_mutex );
111
112
} else
112
113
info -> priv = NULL ;
113
114
@@ -120,7 +121,9 @@ static void tee_tg_destroy(const struct xt_tgdtor_param *par)
120
121
struct xt_tee_tginfo * info = par -> targinfo ;
121
122
122
123
if (info -> priv ) {
123
- unregister_netdevice_notifier (& info -> priv -> notifier );
124
+ mutex_lock (& priv_list_mutex );
125
+ list_del (& info -> priv -> list );
126
+ mutex_unlock (& priv_list_mutex );
124
127
kfree (info -> priv );
125
128
}
126
129
static_key_slow_dec (& xt_tee_enabled );
@@ -153,13 +156,29 @@ static struct xt_target tee_tg_reg[] __read_mostly = {
153
156
#endif
154
157
};
155
158
159
+ static struct notifier_block tee_netdev_notifier = {
160
+ .notifier_call = tee_netdev_event ,
161
+ };
162
+
156
163
static int __init tee_tg_init (void )
157
164
{
158
- return xt_register_targets (tee_tg_reg , ARRAY_SIZE (tee_tg_reg ));
165
+ int ret ;
166
+
167
+ ret = xt_register_targets (tee_tg_reg , ARRAY_SIZE (tee_tg_reg ));
168
+ if (ret )
169
+ return ret ;
170
+ ret = register_netdevice_notifier (& tee_netdev_notifier );
171
+ if (ret ) {
172
+ xt_unregister_targets (tee_tg_reg , ARRAY_SIZE (tee_tg_reg ));
173
+ return ret ;
174
+ }
175
+
176
+ return 0 ;
159
177
}
160
178
161
179
static void __exit tee_tg_exit (void )
162
180
{
181
+ unregister_netdevice_notifier (& tee_netdev_notifier );
163
182
xt_unregister_targets (tee_tg_reg , ARRAY_SIZE (tee_tg_reg ));
164
183
}
165
184
0 commit comments