diff options
Diffstat (limited to 'net/key')
-rw-r--r-- | net/key/af_key.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index 79d2c0f3c334..b3faede9a4f6 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -1712,6 +1712,23 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
1712 | return 0; | 1712 | return 0; |
1713 | } | 1713 | } |
1714 | 1714 | ||
1715 | static int unicast_flush_resp(struct sock *sk, struct sadb_msg *ihdr) | ||
1716 | { | ||
1717 | struct sk_buff *skb; | ||
1718 | struct sadb_msg *hdr; | ||
1719 | |||
1720 | skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC); | ||
1721 | if (!skb) | ||
1722 | return -ENOBUFS; | ||
1723 | |||
1724 | hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); | ||
1725 | memcpy(hdr, ihdr, sizeof(struct sadb_msg)); | ||
1726 | hdr->sadb_msg_errno = (uint8_t) 0; | ||
1727 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | ||
1728 | |||
1729 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); | ||
1730 | } | ||
1731 | |||
1715 | static int key_notify_sa_flush(struct km_event *c) | 1732 | static int key_notify_sa_flush(struct km_event *c) |
1716 | { | 1733 | { |
1717 | struct sk_buff *skb; | 1734 | struct sk_buff *skb; |
@@ -1740,7 +1757,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1740 | unsigned proto; | 1757 | unsigned proto; |
1741 | struct km_event c; | 1758 | struct km_event c; |
1742 | struct xfrm_audit audit_info; | 1759 | struct xfrm_audit audit_info; |
1743 | int err; | 1760 | int err, err2; |
1744 | 1761 | ||
1745 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); | 1762 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); |
1746 | if (proto == 0) | 1763 | if (proto == 0) |
@@ -1750,8 +1767,10 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1750 | audit_info.sessionid = audit_get_sessionid(current); | 1767 | audit_info.sessionid = audit_get_sessionid(current); |
1751 | audit_info.secid = 0; | 1768 | audit_info.secid = 0; |
1752 | err = xfrm_state_flush(net, proto, &audit_info); | 1769 | err = xfrm_state_flush(net, proto, &audit_info); |
1753 | if (err) | 1770 | err2 = unicast_flush_resp(sk, hdr); |
1754 | return err; | 1771 | if (err || err2) |
1772 | return err ? err : err2; | ||
1773 | |||
1755 | c.data.proto = proto; | 1774 | c.data.proto = proto; |
1756 | c.seq = hdr->sadb_msg_seq; | 1775 | c.seq = hdr->sadb_msg_seq; |
1757 | c.pid = hdr->sadb_msg_pid; | 1776 | c.pid = hdr->sadb_msg_pid; |
@@ -2706,14 +2725,16 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2706 | struct net *net = sock_net(sk); | 2725 | struct net *net = sock_net(sk); |
2707 | struct km_event c; | 2726 | struct km_event c; |
2708 | struct xfrm_audit audit_info; | 2727 | struct xfrm_audit audit_info; |
2709 | int err; | 2728 | int err, err2; |
2710 | 2729 | ||
2711 | audit_info.loginuid = audit_get_loginuid(current); | 2730 | audit_info.loginuid = audit_get_loginuid(current); |
2712 | audit_info.sessionid = audit_get_sessionid(current); | 2731 | audit_info.sessionid = audit_get_sessionid(current); |
2713 | audit_info.secid = 0; | 2732 | audit_info.secid = 0; |
2714 | err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); | 2733 | err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); |
2715 | if (err) | 2734 | err2 = unicast_flush_resp(sk, hdr); |
2716 | return err; | 2735 | if (err || err2) |
2736 | return err ? err : err2; | ||
2737 | |||
2717 | c.data.type = XFRM_POLICY_TYPE_MAIN; | 2738 | c.data.type = XFRM_POLICY_TYPE_MAIN; |
2718 | c.event = XFRM_MSG_FLUSHPOLICY; | 2739 | c.event = XFRM_MSG_FLUSHPOLICY; |
2719 | c.pid = hdr->sadb_msg_pid; | 2740 | c.pid = hdr->sadb_msg_pid; |