aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-18 00:33:12 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-18 00:33:12 -0400
commit17c2a42a24e1e8dd6aa7cea4f84e034ab1bfff31 (patch)
tree3ee494a16a43f575f8c4900deaab894b73b2953a /net/xfrm
parent1bfcb10f670f5ff5e1d9f53e59680573524cb142 (diff)
[IPSEC]: Store afinfo pointer in xfrm_mode
It is convenient to have a pointer from xfrm_state to address-specific functions such as the output function for a family. Currently the address-specific policy code calls out to the xfrm state code to get those pointers when we could get it in an easier way via the state itself. This patch adds an xfrm_state_afinfo to xfrm_mode (since they're address-specific) and changes the policy code to use it. I've also added an owner field to do reference counting on the module providing the afinfo even though it isn't strictly necessary today since IPv6 can't be unloaded yet. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-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{