diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-09-09 22:58:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-09 22:58:29 -0400 |
commit | abb81c4f3cb9b8d421f1e5474811ef1d461d341c (patch) | |
tree | 71a08df3a53eb9e19a62c673d77084e4d81f708b /include/net/xfrm.h | |
parent | dacc62dbf56e872ad96edde0393b9deb56d80cd5 (diff) |
ipsec: Use RCU-like construct for saved state within a walk
Now that we save states within a walk we need synchronisation
so that the list the saved state is on doesn't disappear from
under us.
As it stands this is done by keeping the state on the list which
is bad because it gets in the way of the management of the state
life-cycle.
An alternative is to make our own pseudo-RCU system where we use
counters to indicate which state can't be freed immediately as
it may be referenced by an ongoing walk when that resumes.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/xfrm.h')
-rw-r--r-- | include/net/xfrm.h | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 2933d7474a79..4bb94992b5fa 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -120,9 +120,11 @@ extern struct mutex xfrm_cfg_mutex; | |||
120 | /* Full description of state of transformer. */ | 120 | /* Full description of state of transformer. */ |
121 | struct xfrm_state | 121 | struct xfrm_state |
122 | { | 122 | { |
123 | /* Note: bydst is re-used during gc */ | ||
124 | struct list_head all; | 123 | struct list_head all; |
125 | struct hlist_node bydst; | 124 | union { |
125 | struct list_head gclist; | ||
126 | struct hlist_node bydst; | ||
127 | }; | ||
126 | struct hlist_node bysrc; | 128 | struct hlist_node bysrc; |
127 | struct hlist_node byspi; | 129 | struct hlist_node byspi; |
128 | 130 | ||
@@ -1286,16 +1288,9 @@ static inline void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto) | |||
1286 | walk->count = 0; | 1288 | walk->count = 0; |
1287 | } | 1289 | } |
1288 | 1290 | ||
1289 | static inline void xfrm_state_walk_done(struct xfrm_state_walk *walk) | ||
1290 | { | ||
1291 | if (walk->state != NULL) { | ||
1292 | xfrm_state_put(walk->state); | ||
1293 | walk->state = NULL; | ||
1294 | } | ||
1295 | } | ||
1296 | |||
1297 | extern int xfrm_state_walk(struct xfrm_state_walk *walk, | 1291 | extern int xfrm_state_walk(struct xfrm_state_walk *walk, |
1298 | int (*func)(struct xfrm_state *, int, void*), void *); | 1292 | int (*func)(struct xfrm_state *, int, void*), void *); |
1293 | extern void xfrm_state_walk_done(struct xfrm_state_walk *walk); | ||
1299 | extern struct xfrm_state *xfrm_state_alloc(void); | 1294 | extern struct xfrm_state *xfrm_state_alloc(void); |
1300 | extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | 1295 | extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, |
1301 | struct flowi *fl, struct xfrm_tmpl *tmpl, | 1296 | struct flowi *fl, struct xfrm_tmpl *tmpl, |