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.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index dc438f2b9442..48b4a06b3d1a 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,
@@ -289,11 +292,18 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family)
289 292
290 err = -EEXIST; 293 err = -EEXIST;
291 modemap = afinfo->mode_map; 294 modemap = afinfo->mode_map;
292 if (likely(modemap[mode->encap] == NULL)) { 295 if (modemap[mode->encap])
293 modemap[mode->encap] = mode; 296 goto out;
294 err = 0;
295 }
296 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:
297 xfrm_state_unlock_afinfo(afinfo); 307 xfrm_state_unlock_afinfo(afinfo);
298 return err; 308 return err;
299} 309}
@@ -316,6 +326,7 @@ int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
316 modemap = afinfo->mode_map; 326 modemap = afinfo->mode_map;
317 if (likely(modemap[mode->encap] == mode)) { 327 if (likely(modemap[mode->encap] == mode)) {
318 modemap[mode->encap] = NULL; 328 modemap[mode->encap] = NULL;
329 module_put(mode->afinfo->owner);
319 err = 0; 330 err = 0;
320 } 331 }
321 332
@@ -1869,7 +1880,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
1869} 1880}
1870EXPORT_SYMBOL(xfrm_state_unregister_afinfo); 1881EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
1871 1882
1872struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family) 1883static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
1873{ 1884{
1874 struct xfrm_state_afinfo *afinfo; 1885 struct xfrm_state_afinfo *afinfo;
1875 if (unlikely(family >= NPROTO)) 1886 if (unlikely(family >= NPROTO))
@@ -1881,14 +1892,11 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
1881 return afinfo; 1892 return afinfo;
1882} 1893}
1883 1894
1884void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) 1895static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
1885{ 1896{
1886 read_unlock(&xfrm_state_afinfo_lock); 1897 read_unlock(&xfrm_state_afinfo_lock);
1887} 1898}
1888 1899
1889EXPORT_SYMBOL(xfrm_state_get_afinfo);
1890EXPORT_SYMBOL(xfrm_state_put_afinfo);
1891
1892/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ 1900/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
1893void xfrm_state_delete_tunnel(struct xfrm_state *x) 1901void xfrm_state_delete_tunnel(struct xfrm_state *x)
1894{ 1902{