@@ -60,46 +60,57 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg)
60
60
}
61
61
EXPORT_SYMBOL (nf_unregister_sockopt );
62
62
63
- /* Call get/setsockopt() */
64
- static int nf_sockopt (struct sock * sk , int pf , int val ,
65
- char __user * opt , int * len , int get )
63
+ static struct nf_sockopt_ops * nf_sockopt_find (struct sock * sk , int pf ,
64
+ int val , int get )
66
65
{
67
66
struct nf_sockopt_ops * ops ;
68
- int ret ;
69
67
70
68
if (sk -> sk_net != & init_net )
71
- return - ENOPROTOOPT ;
69
+ return ERR_PTR ( - ENOPROTOOPT ) ;
72
70
73
71
if (mutex_lock_interruptible (& nf_sockopt_mutex ) != 0 )
74
- return - EINTR ;
72
+ return ERR_PTR ( - EINTR ) ;
75
73
76
74
list_for_each_entry (ops , & nf_sockopts , list ) {
77
75
if (ops -> pf == pf ) {
78
76
if (!try_module_get (ops -> owner ))
79
77
goto out_nosup ;
78
+
80
79
if (get ) {
81
- if (val >= ops -> get_optmin
82
- && val < ops -> get_optmax ) {
83
- mutex_unlock (& nf_sockopt_mutex );
84
- ret = ops -> get (sk , val , opt , len );
80
+ if (val >= ops -> get_optmin &&
81
+ val < ops -> get_optmax )
85
82
goto out ;
86
- }
87
83
} else {
88
- if (val >= ops -> set_optmin
89
- && val < ops -> set_optmax ) {
90
- mutex_unlock (& nf_sockopt_mutex );
91
- ret = ops -> set (sk , val , opt , * len );
84
+ if (val >= ops -> set_optmin &&
85
+ val < ops -> set_optmax )
92
86
goto out ;
93
- }
94
87
}
95
88
module_put (ops -> owner );
96
89
}
97
90
}
98
- out_nosup :
91
+ out_nosup :
92
+ ops = ERR_PTR (- ENOPROTOOPT );
93
+ out :
99
94
mutex_unlock (& nf_sockopt_mutex );
100
- return - ENOPROTOOPT ;
95
+ return ops ;
96
+ }
97
+
98
+ /* Call get/setsockopt() */
99
+ static int nf_sockopt (struct sock * sk , int pf , int val ,
100
+ char __user * opt , int * len , int get )
101
+ {
102
+ struct nf_sockopt_ops * ops ;
103
+ int ret ;
104
+
105
+ ops = nf_sockopt_find (sk , pf , val , get );
106
+ if (IS_ERR (ops ))
107
+ return PTR_ERR (ops );
108
+
109
+ if (get )
110
+ ret = ops -> get (sk , val , opt , len );
111
+ else
112
+ ret = ops -> set (sk , val , opt , * len );
101
113
102
- out :
103
114
module_put (ops -> owner );
104
115
return ret ;
105
116
}
@@ -124,51 +135,22 @@ static int compat_nf_sockopt(struct sock *sk, int pf, int val,
124
135
struct nf_sockopt_ops * ops ;
125
136
int ret ;
126
137
127
- if (sk -> sk_net != & init_net )
128
- return - ENOPROTOOPT ;
129
-
130
-
131
- if (mutex_lock_interruptible (& nf_sockopt_mutex ) != 0 )
132
- return - EINTR ;
133
-
134
- list_for_each_entry (ops , & nf_sockopts , list ) {
135
- if (ops -> pf == pf ) {
136
- if (!try_module_get (ops -> owner ))
137
- goto out_nosup ;
138
-
139
- if (get ) {
140
- if (val >= ops -> get_optmin
141
- && val < ops -> get_optmax ) {
142
- mutex_unlock (& nf_sockopt_mutex );
143
- if (ops -> compat_get )
144
- ret = ops -> compat_get (sk ,
145
- val , opt , len );
146
- else
147
- ret = ops -> get (sk ,
148
- val , opt , len );
149
- goto out ;
150
- }
151
- } else {
152
- if (val >= ops -> set_optmin
153
- && val < ops -> set_optmax ) {
154
- mutex_unlock (& nf_sockopt_mutex );
155
- if (ops -> compat_set )
156
- ret = ops -> compat_set (sk ,
157
- val , opt , * len );
158
- else
159
- ret = ops -> set (sk ,
160
- val , opt , * len );
161
- goto out ;
162
- }
163
- }
164
- module_put (ops -> owner );
165
- }
138
+ ops = nf_sockopt_find (sk , pf , val , get );
139
+ if (IS_ERR (ops ))
140
+ return PTR_ERR (ops );
141
+
142
+ if (get ) {
143
+ if (ops -> compat_get )
144
+ ret = ops -> compat_get (sk , val , opt , len );
145
+ else
146
+ ret = ops -> get (sk , val , ops , len );
147
+ } else {
148
+ if (ops -> compat_set )
149
+ ret = ops -> compat_set (sk , val , ops , * len );
150
+ else
151
+ ret = ops -> set (sk , val , ops , * len );
166
152
}
167
- out_nosup :
168
- mutex_unlock (& nf_sockopt_mutex );
169
- return - ENOPROTOOPT ;
170
153
171
- out :
172
154
module_put (ops -> owner );
173
155
return ret ;
174
156
}
0 commit comments