ipsec: Put dumpers on the dump list
Subsystems (3)
PATCH 1/1 ipsec: Put dumpers on the dump list
Herbert Xu came up with the idea and the original patch to make xfrm_state dump list contain also dumpers:
As it is we go to extraordinary lengths to ensure that states don't go away while dumpers go to sleep. It's much easier if we just put the dumpers themselves on the list since they can't go away while they're going.
I've also changed the order of addition on new states to prevent a never-ending dump.
Timo Teräs improved the patch to apply cleanly to latest tree, modified iteration code to be more readable by using a common struct for entries in the list, implemented the same idea for xfrm_policy dumping and moved the af_key specific "last" entry caching to af_key.
---
Rebased to apply on top of "key: Free dumping state on socket close". No other changes compared to previous send.
include/linux/netlink.h | 2 +- include/net/xfrm.h | 70 ++++++++++++------------------ net/key/af_key.c | 38 ++++++++++++++-- net/xfrm/xfrm_policy.c | 111 +++++++++++++++++++++++++---------------------- net/xfrm/xfrm_state.c | 109 +++++++++++++++------------------------------- net/xfrm/xfrm_user.c | 4 +- 6 files changed, 159 insertions(+), 175 deletions(-)
include/linux/netlink.h +1 -1
@@ -220,7 +220,7 @@ struct netlink_callbackint (*dump)(struct sk_buff * skb,struct netlink_callback *cb);int (*done)(struct netlink_callback *cb);int family; -long args[7 ]; +long args[6 ]; };struct netlink_notify
include/net/xfrm.h +28 -42
119 lines not on this page · raw message
net/key/af_key.c +33 -5
@@ -58,6 +58,7 @@ struct pfkey_sock {struct xfrm_policy_walk policy;struct xfrm_state_walk state; } u; +struct sk_buff *skb; } dump; };
@@ -76,6 +77,10 @@ static int pfkey_can_dump(struct sock *sk)static void pfkey_terminate_dump (struct pfkey_sock *pfk) {if (pfk->dump.dump) { +if (pfk->dump.skb) { +kfree_skb (pfk->dump.skb); + pfk->dump.skb =NULL ; + } pfk->dump.done (pfk); pfk->dump.dump =NULL ; pfk->dump.done =NULL ;
@@ -308,12 +313,25 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,static int pfkey_do_dump (struct pfkey_sock *pfk) { +struct sadb_msg *hdr;int rc; rc = pfk->dump.dump (pfk);if (rc == -ENOBUFS )return 0 ; +if (pfk->dump.skb) { +if (!pfkey_can_dump (&pfk->sk)) +return 0 ; + + hdr = (struct sadb_msg *) pfk->dump.skb->data; + hdr->sadb_msg_seq =0 ; + hdr->sadb_msg_errno = rc; +pfkey_broadcast (pfk->dump.skb,GFP_ATOMIC ,BROADCAST_ONE , + &pfk->sk); + pfk->dump.skb =NULL ; + } +pfkey_terminate_dump (pfk);return rc; }
@@ -1744,9 +1762,14 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) out_hdr->sadb_msg_satype =pfkey_proto2satype (x->id.proto); out_hdr->sadb_msg_errno =0 ; out_hdr->sadb_msg_reserved =0 ; - out_hdr->sadb_msg_seq = count; + out_hdr->sadb_msg_seq = count +1 ; out_hdr->sadb_msg_pid = pfk->dump.msg_pid; -pfkey_broadcast (out_skb,GFP_ATOMIC ,BROADCAST_ONE , &pfk->sk); + +if (pfk->dump.skb) +pfkey_broadcast (pfk->dump.skb,GFP_ATOMIC ,BROADCAST_ONE , + &pfk->sk); + pfk->dump.skb = out_skb; +return 0 ; }
@@ -2245,7 +2268,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hreturn 0 ; out: - xp->dead =1 ; + xp->walk.dead =1 ;xfrm_policy_destroy (xp);return err; }
@@ -2583,9 +2606,14 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) out_hdr->sadb_msg_type =SADB_X_SPDDUMP ; out_hdr->sadb_msg_satype =SADB_SATYPE_UNSPEC ; out_hdr->sadb_msg_errno =0 ; - out_hdr->sadb_msg_seq = count; + out_hdr->sadb_msg_seq = count +1 ; out_hdr->sadb_msg_pid = pfk->dump.msg_pid; -pfkey_broadcast (out_skb,GFP_ATOMIC ,BROADCAST_ONE , &pfk->sk); + +if (pfk->dump.skb) +pfkey_broadcast (pfk->dump.skb,GFP_ATOMIC ,BROADCAST_ONE , + &pfk->sk); + pfk->dump.skb = out_skb; +return 0 ; }
net/xfrm/xfrm_policy.c +59 -52
232 lines not on this page · raw message
net/xfrm/xfrm_state.c +36 -73
203 lines not on this page · raw message
net/xfrm/xfrm_user.c +2 -2
@@ -1102,7 +1102,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,return xp; error: *errp = err; - xp->dead =1 ; + xp->walk.dead =1 ;xfrm_policy_destroy (xp);return NULL ; }
@@ -1595,7 +1595,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,return -ENOENT ;read_lock (&xp->lock); -if (xp->dead) { +if (xp->walk.dead) {read_unlock (&xp->lock); goto out; }
Signature · 1 line
1.5.4.3
From: Timo Teräs <[email protected]>
Date: Wed, 01 Oct 2008 13:58:14 +0300
Quoted 2 lines
Herbert Xu came up with the idea and the original patch to make
xfrm_statedump list contain also dumpers:
...
Quoted 2 lines
Rebased to apply on top of "key: Free dumping state on socket close". No other changes compared to previous send.
Applied, thanks Timo!