aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-09-09 22:58:29 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-09 22:58:29 -0400
commitabb81c4f3cb9b8d421f1e5474811ef1d461d341c (patch)
tree71a08df3a53eb9e19a62c673d77084e4d81f708b /include
parentdacc62dbf56e872ad96edde0393b9deb56d80cd5 (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')
-rw-r--r--include/net/xfrm.h15
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. */
121struct xfrm_state 121struct 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
1289static 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
1297extern int xfrm_state_walk(struct xfrm_state_walk *walk, 1291extern 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 *);
1293extern void xfrm_state_walk_done(struct xfrm_state_walk *walk);
1299extern struct xfrm_state *xfrm_state_alloc(void); 1294extern struct xfrm_state *xfrm_state_alloc(void);
1300extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 1295extern 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,