aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r--net/xfrm/xfrm_state.c206
1 files changed, 197 insertions, 9 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 344f0a6abec5..224b44e31a07 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -57,6 +57,9 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
57static unsigned int xfrm_state_num; 57static unsigned int xfrm_state_num;
58static unsigned int xfrm_state_genid; 58static unsigned int xfrm_state_genid;
59 59
60static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
61static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
62
60static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr, 63static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
61 xfrm_address_t *saddr, 64 xfrm_address_t *saddr,
62 u32 reqid, 65 u32 reqid,
@@ -187,6 +190,184 @@ int __xfrm_state_delete(struct xfrm_state *x);
187int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); 190int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
188void km_state_expired(struct xfrm_state *x, int hard, u32 pid); 191void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
189 192
193static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
194{
195 struct xfrm_state_afinfo *afinfo;
196 if (unlikely(family >= NPROTO))
197 return NULL;
198 write_lock_bh(&xfrm_state_afinfo_lock);
199 afinfo = xfrm_state_afinfo[family];
200 if (unlikely(!afinfo))
201 write_unlock_bh(&xfrm_state_afinfo_lock);
202 return afinfo;
203}
204
205static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
206{
207 write_unlock_bh(&xfrm_state_afinfo_lock);
208}
209
210int xfrm_register_type(struct xfrm_type *type, unsigned short family)
211{
212 struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
213 struct xfrm_type **typemap;
214 int err = 0;
215
216 if (unlikely(afinfo == NULL))
217 return -EAFNOSUPPORT;
218 typemap = afinfo->type_map;
219
220 if (likely(typemap[type->proto] == NULL))
221 typemap[type->proto] = type;
222 else
223 err = -EEXIST;
224 xfrm_state_unlock_afinfo(afinfo);
225 return err;
226}
227EXPORT_SYMBOL(xfrm_register_type);
228
229int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
230{
231 struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
232 struct xfrm_type **typemap;
233 int err = 0;
234
235 if (unlikely(afinfo == NULL))
236 return -EAFNOSUPPORT;
237 typemap = afinfo->type_map;
238
239 if (unlikely(typemap[type->proto] != type))
240 err = -ENOENT;
241 else
242 typemap[type->proto] = NULL;
243 xfrm_state_unlock_afinfo(afinfo);
244 return err;
245}
246EXPORT_SYMBOL(xfrm_unregister_type);
247
248static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
249{
250 struct xfrm_state_afinfo *afinfo;
251 struct xfrm_type **typemap;
252 struct xfrm_type *type;
253 int modload_attempted = 0;
254
255retry:
256 afinfo = xfrm_state_get_afinfo(family);
257 if (unlikely(afinfo == NULL))
258 return NULL;
259 typemap = afinfo->type_map;
260
261 type = typemap[proto];
262 if (unlikely(type && !try_module_get(type->owner)))
263 type = NULL;
264 if (!type && !modload_attempted) {
265 xfrm_state_put_afinfo(afinfo);
266 request_module("xfrm-type-%d-%d", family, proto);
267 modload_attempted = 1;
268 goto retry;
269 }
270
271 xfrm_state_put_afinfo(afinfo);
272 return type;
273}
274
275static void xfrm_put_type(struct xfrm_type *type)
276{
277 module_put(type->owner);
278}
279
280int xfrm_register_mode(struct xfrm_mode *mode, int family)
281{
282 struct xfrm_state_afinfo *afinfo;
283 struct xfrm_mode **modemap;
284 int err;
285
286 if (unlikely(mode->encap >= XFRM_MODE_MAX))
287 return -EINVAL;
288
289 afinfo = xfrm_state_lock_afinfo(family);
290 if (unlikely(afinfo == NULL))
291 return -EAFNOSUPPORT;
292
293 err = -EEXIST;
294 modemap = afinfo->mode_map;
295 if (modemap[mode->encap])
296 goto out;
297
298 err = -ENOENT;
299 if (!try_module_get(afinfo->owner))
300 goto out;
301
302 mode->afinfo = afinfo;
303 modemap[mode->encap] = mode;
304 err = 0;
305
306out:
307 xfrm_state_unlock_afinfo(afinfo);
308 return err;
309}
310EXPORT_SYMBOL(xfrm_register_mode);
311
312int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
313{
314 struct xfrm_state_afinfo *afinfo;
315 struct xfrm_mode **modemap;
316 int err;
317
318 if (unlikely(mode->encap >= XFRM_MODE_MAX))
319 return -EINVAL;
320
321 afinfo = xfrm_state_lock_afinfo(family);
322 if (unlikely(afinfo == NULL))
323 return -EAFNOSUPPORT;
324
325 err = -ENOENT;
326 modemap = afinfo->mode_map;
327 if (likely(modemap[mode->encap] == mode)) {
328 modemap[mode->encap] = NULL;
329 module_put(mode->afinfo->owner);
330 err = 0;
331 }
332
333 xfrm_state_unlock_afinfo(afinfo);
334 return err;
335}
336EXPORT_SYMBOL(xfrm_unregister_mode);
337
338static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
339{
340 struct xfrm_state_afinfo *afinfo;
341 struct xfrm_mode *mode;
342 int modload_attempted = 0;
343
344 if (unlikely(encap >= XFRM_MODE_MAX))
345 return NULL;
346
347retry:
348 afinfo = xfrm_state_get_afinfo(family);
349 if (unlikely(afinfo == NULL))
350 return NULL;
351
352 mode = afinfo->mode_map[encap];
353 if (unlikely(mode && !try_module_get(mode->owner)))
354 mode = NULL;
355 if (!mode && !modload_attempted) {
356 xfrm_state_put_afinfo(afinfo);
357 request_module("xfrm-mode-%d-%d", family, encap);
358 modload_attempted = 1;
359 goto retry;
360 }
361
362 xfrm_state_put_afinfo(afinfo);
363 return mode;
364}
365
366static void xfrm_put_mode(struct xfrm_mode *mode)
367{
368 module_put(mode->owner);
369}
370
190static void xfrm_state_gc_destroy(struct xfrm_state *x) 371static void xfrm_state_gc_destroy(struct xfrm_state *x)
191{ 372{
192 del_timer_sync(&x->timer); 373 del_timer_sync(&x->timer);
@@ -196,8 +377,10 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
196 kfree(x->calg); 377 kfree(x->calg);
197 kfree(x->encap); 378 kfree(x->encap);
198 kfree(x->coaddr); 379 kfree(x->coaddr);
199 if (x->mode) 380 if (x->inner_mode)
200 xfrm_put_mode(x->mode); 381 xfrm_put_mode(x->inner_mode);
382 if (x->outer_mode)
383 xfrm_put_mode(x->outer_mode);
201 if (x->type) { 384 if (x->type) {
202 x->type->destructor(x); 385 x->type->destructor(x);
203 xfrm_put_type(x->type); 386 xfrm_put_type(x->type);
@@ -1699,7 +1882,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
1699} 1882}
1700EXPORT_SYMBOL(xfrm_state_unregister_afinfo); 1883EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
1701 1884
1702struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family) 1885static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
1703{ 1886{
1704 struct xfrm_state_afinfo *afinfo; 1887 struct xfrm_state_afinfo *afinfo;
1705 if (unlikely(family >= NPROTO)) 1888 if (unlikely(family >= NPROTO))
@@ -1711,14 +1894,11 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
1711 return afinfo; 1894 return afinfo;
1712} 1895}
1713 1896
1714void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) 1897static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
1715{ 1898{
1716 read_unlock(&xfrm_state_afinfo_lock); 1899 read_unlock(&xfrm_state_afinfo_lock);
1717} 1900}
1718 1901
1719EXPORT_SYMBOL(xfrm_state_get_afinfo);
1720EXPORT_SYMBOL(xfrm_state_put_afinfo);
1721
1722/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ 1902/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
1723void xfrm_state_delete_tunnel(struct xfrm_state *x) 1903void xfrm_state_delete_tunnel(struct xfrm_state *x)
1724{ 1904{
@@ -1769,6 +1949,14 @@ int xfrm_init_state(struct xfrm_state *x)
1769 goto error; 1949 goto error;
1770 1950
1771 err = -EPROTONOSUPPORT; 1951 err = -EPROTONOSUPPORT;
1952 x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
1953 if (x->inner_mode == NULL)
1954 goto error;
1955
1956 if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
1957 family != x->sel.family)
1958 goto error;
1959
1772 x->type = xfrm_get_type(x->id.proto, family); 1960 x->type = xfrm_get_type(x->id.proto, family);
1773 if (x->type == NULL) 1961 if (x->type == NULL)
1774 goto error; 1962 goto error;
@@ -1777,8 +1965,8 @@ int xfrm_init_state(struct xfrm_state *x)
1777 if (err) 1965 if (err)
1778 goto error; 1966 goto error;
1779 1967
1780 x->mode = xfrm_get_mode(x->props.mode, family); 1968 x->outer_mode = xfrm_get_mode(x->props.mode, family);
1781 if (x->mode == NULL) 1969 if (x->outer_mode == NULL)
1782 goto error; 1970 goto error;
1783 1971
1784 x->km.state = XFRM_STATE_VALID; 1972 x->km.state = XFRM_STATE_VALID;