diff options
Diffstat (limited to 'net/key/af_key.c')
-rw-r--r-- | net/key/af_key.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index b7f5a1c353ee..7ae641df70bd 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -58,6 +58,7 @@ struct pfkey_sock { | |||
58 | struct xfrm_policy_walk policy; | 58 | struct xfrm_policy_walk policy; |
59 | struct xfrm_state_walk state; | 59 | struct xfrm_state_walk state; |
60 | } u; | 60 | } u; |
61 | struct sk_buff *skb; | ||
61 | } dump; | 62 | } dump; |
62 | }; | 63 | }; |
63 | 64 | ||
@@ -76,6 +77,10 @@ static int pfkey_can_dump(struct sock *sk) | |||
76 | static void pfkey_terminate_dump(struct pfkey_sock *pfk) | 77 | static void pfkey_terminate_dump(struct pfkey_sock *pfk) |
77 | { | 78 | { |
78 | if (pfk->dump.dump) { | 79 | if (pfk->dump.dump) { |
80 | if (pfk->dump.skb) { | ||
81 | kfree_skb(pfk->dump.skb); | ||
82 | pfk->dump.skb = NULL; | ||
83 | } | ||
79 | pfk->dump.done(pfk); | 84 | pfk->dump.done(pfk); |
80 | pfk->dump.dump = NULL; | 85 | pfk->dump.dump = NULL; |
81 | pfk->dump.done = NULL; | 86 | pfk->dump.done = NULL; |
@@ -308,12 +313,25 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, | |||
308 | 313 | ||
309 | static int pfkey_do_dump(struct pfkey_sock *pfk) | 314 | static int pfkey_do_dump(struct pfkey_sock *pfk) |
310 | { | 315 | { |
316 | struct sadb_msg *hdr; | ||
311 | int rc; | 317 | int rc; |
312 | 318 | ||
313 | rc = pfk->dump.dump(pfk); | 319 | rc = pfk->dump.dump(pfk); |
314 | if (rc == -ENOBUFS) | 320 | if (rc == -ENOBUFS) |
315 | return 0; | 321 | return 0; |
316 | 322 | ||
323 | if (pfk->dump.skb) { | ||
324 | if (!pfkey_can_dump(&pfk->sk)) | ||
325 | return 0; | ||
326 | |||
327 | hdr = (struct sadb_msg *) pfk->dump.skb->data; | ||
328 | hdr->sadb_msg_seq = 0; | ||
329 | hdr->sadb_msg_errno = rc; | ||
330 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | ||
331 | &pfk->sk); | ||
332 | pfk->dump.skb = NULL; | ||
333 | } | ||
334 | |||
317 | pfkey_terminate_dump(pfk); | 335 | pfkey_terminate_dump(pfk); |
318 | return rc; | 336 | return rc; |
319 | } | 337 | } |
@@ -1744,9 +1762,14 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) | |||
1744 | out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); | 1762 | out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); |
1745 | out_hdr->sadb_msg_errno = 0; | 1763 | out_hdr->sadb_msg_errno = 0; |
1746 | out_hdr->sadb_msg_reserved = 0; | 1764 | out_hdr->sadb_msg_reserved = 0; |
1747 | out_hdr->sadb_msg_seq = count; | 1765 | out_hdr->sadb_msg_seq = count + 1; |
1748 | out_hdr->sadb_msg_pid = pfk->dump.msg_pid; | 1766 | out_hdr->sadb_msg_pid = pfk->dump.msg_pid; |
1749 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); | 1767 | |
1768 | if (pfk->dump.skb) | ||
1769 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | ||
1770 | &pfk->sk); | ||
1771 | pfk->dump.skb = out_skb; | ||
1772 | |||
1750 | return 0; | 1773 | return 0; |
1751 | } | 1774 | } |
1752 | 1775 | ||
@@ -2245,7 +2268,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2245 | return 0; | 2268 | return 0; |
2246 | 2269 | ||
2247 | out: | 2270 | out: |
2248 | xp->dead = 1; | 2271 | xp->walk.dead = 1; |
2249 | xfrm_policy_destroy(xp); | 2272 | xfrm_policy_destroy(xp); |
2250 | return err; | 2273 | return err; |
2251 | } | 2274 | } |
@@ -2583,9 +2606,14 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) | |||
2583 | out_hdr->sadb_msg_type = SADB_X_SPDDUMP; | 2606 | out_hdr->sadb_msg_type = SADB_X_SPDDUMP; |
2584 | out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; | 2607 | out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; |
2585 | out_hdr->sadb_msg_errno = 0; | 2608 | out_hdr->sadb_msg_errno = 0; |
2586 | out_hdr->sadb_msg_seq = count; | 2609 | out_hdr->sadb_msg_seq = count + 1; |
2587 | out_hdr->sadb_msg_pid = pfk->dump.msg_pid; | 2610 | out_hdr->sadb_msg_pid = pfk->dump.msg_pid; |
2588 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); | 2611 | |
2612 | if (pfk->dump.skb) | ||
2613 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | ||
2614 | &pfk->sk); | ||
2615 | pfk->dump.skb = out_skb; | ||
2616 | |||
2589 | return 0; | 2617 | return 0; |
2590 | } | 2618 | } |
2591 | 2619 | ||