Lines 48-53
Link Here
|
48 |
struct sock sk; |
48 |
struct sock sk; |
49 |
int registered; |
49 |
int registered; |
50 |
int promisc; |
50 |
int promisc; |
|
|
51 |
|
52 |
struct { |
53 |
uint8_t msg_version; |
54 |
uint32_t msg_pid; |
55 |
int (*dump)(struct pfkey_sock *sk); |
56 |
void (*done)(struct pfkey_sock *sk); |
57 |
union { |
58 |
struct xfrm_policy_walk policy; |
59 |
struct xfrm_state_walk state; |
60 |
} u; |
61 |
} dump; |
51 |
}; |
62 |
}; |
52 |
|
63 |
|
53 |
static inline struct pfkey_sock *pfkey_sk(struct sock *sk) |
64 |
static inline struct pfkey_sock *pfkey_sk(struct sock *sk) |
Lines 55-60
Link Here
|
55 |
return (struct pfkey_sock *)sk; |
66 |
return (struct pfkey_sock *)sk; |
56 |
} |
67 |
} |
57 |
|
68 |
|
|
|
69 |
static int pfkey_can_dump(struct sock *sk) |
70 |
{ |
71 |
if (3 * atomic_read(&sk->sk_rmem_alloc) <= 2 * sk->sk_rcvbuf) |
72 |
return 1; |
73 |
return 0; |
74 |
} |
75 |
|
76 |
static int pfkey_do_dump(struct pfkey_sock *pfk) |
77 |
{ |
78 |
int rc; |
79 |
|
80 |
rc = pfk->dump.dump(pfk); |
81 |
if (rc == -ENOBUFS) |
82 |
return 0; |
83 |
|
84 |
pfk->dump.done(pfk); |
85 |
pfk->dump.dump = NULL; |
86 |
pfk->dump.done = NULL; |
87 |
return rc; |
88 |
} |
89 |
|
58 |
static void pfkey_sock_destruct(struct sock *sk) |
90 |
static void pfkey_sock_destruct(struct sock *sk) |
59 |
{ |
91 |
{ |
60 |
skb_queue_purge(&sk->sk_receive_queue); |
92 |
skb_queue_purge(&sk->sk_receive_queue); |
Lines 1709-1753
Link Here
|
1709 |
return 0; |
1741 |
return 0; |
1710 |
} |
1742 |
} |
1711 |
|
1743 |
|
1712 |
struct pfkey_dump_data |
|
|
1713 |
{ |
1714 |
struct sk_buff *skb; |
1715 |
struct sadb_msg *hdr; |
1716 |
struct sock *sk; |
1717 |
}; |
1718 |
|
1719 |
static int dump_sa(struct xfrm_state *x, int count, void *ptr) |
1744 |
static int dump_sa(struct xfrm_state *x, int count, void *ptr) |
1720 |
{ |
1745 |
{ |
1721 |
struct pfkey_dump_data *data = ptr; |
1746 |
struct pfkey_sock *pfk = ptr; |
1722 |
struct sk_buff *out_skb; |
1747 |
struct sk_buff *out_skb; |
1723 |
struct sadb_msg *out_hdr; |
1748 |
struct sadb_msg *out_hdr; |
1724 |
|
1749 |
|
|
|
1750 |
if (!pfkey_can_dump(&pfk->sk)) |
1751 |
return -ENOBUFS; |
1752 |
|
1725 |
out_skb = pfkey_xfrm_state2msg(x); |
1753 |
out_skb = pfkey_xfrm_state2msg(x); |
1726 |
if (IS_ERR(out_skb)) |
1754 |
if (IS_ERR(out_skb)) |
1727 |
return PTR_ERR(out_skb); |
1755 |
return PTR_ERR(out_skb); |
1728 |
|
1756 |
|
1729 |
out_hdr = (struct sadb_msg *) out_skb->data; |
1757 |
out_hdr = (struct sadb_msg *) out_skb->data; |
1730 |
out_hdr->sadb_msg_version = data->hdr->sadb_msg_version; |
1758 |
out_hdr->sadb_msg_version = pfk->dump.msg_version; |
1731 |
out_hdr->sadb_msg_type = SADB_DUMP; |
1759 |
out_hdr->sadb_msg_type = SADB_DUMP; |
1732 |
out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); |
1760 |
out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); |
1733 |
out_hdr->sadb_msg_errno = 0; |
1761 |
out_hdr->sadb_msg_errno = 0; |
1734 |
out_hdr->sadb_msg_reserved = 0; |
1762 |
out_hdr->sadb_msg_reserved = 0; |
1735 |
out_hdr->sadb_msg_seq = count; |
1763 |
out_hdr->sadb_msg_seq = count; |
1736 |
out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid; |
1764 |
out_hdr->sadb_msg_pid = pfk->dump.msg_pid; |
1737 |
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk); |
1765 |
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); |
1738 |
return 0; |
1766 |
return 0; |
1739 |
} |
1767 |
} |
1740 |
|
1768 |
|
|
|
1769 |
static int pfkey_dump_sa(struct pfkey_sock *pfk) |
1770 |
{ |
1771 |
return xfrm_state_walk(&pfk->dump.u.state, dump_sa, (void *) pfk); |
1772 |
} |
1773 |
|
1774 |
static void pfkey_dump_sa_done(struct pfkey_sock *pfk) |
1775 |
{ |
1776 |
xfrm_state_walk_done(&pfk->dump.u.state); |
1777 |
} |
1778 |
|
1741 |
static int pfkey_dump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1779 |
static int pfkey_dump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1742 |
{ |
1780 |
{ |
1743 |
u8 proto; |
1781 |
u8 proto; |
1744 |
struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk }; |
1782 |
struct pfkey_sock *pfk = pfkey_sk(sk); |
|
|
1783 |
|
1784 |
if (pfk->dump.dump != NULL) |
1785 |
return -EBUSY; |
1745 |
|
1786 |
|
1746 |
proto = pfkey_satype2proto(hdr->sadb_msg_satype); |
1787 |
proto = pfkey_satype2proto(hdr->sadb_msg_satype); |
1747 |
if (proto == 0) |
1788 |
if (proto == 0) |
1748 |
return -EINVAL; |
1789 |
return -EINVAL; |
1749 |
|
1790 |
|
1750 |
return xfrm_state_walk(proto, dump_sa, &data); |
1791 |
pfk->dump.msg_version = hdr->sadb_msg_version; |
|
|
1792 |
pfk->dump.msg_pid = hdr->sadb_msg_pid; |
1793 |
pfk->dump.dump = pfkey_dump_sa; |
1794 |
pfk->dump.done = pfkey_dump_sa_done; |
1795 |
xfrm_state_walk_init(&pfk->dump.u.state, proto); |
1796 |
|
1797 |
return pfkey_do_dump(pfk); |
1751 |
} |
1798 |
} |
1752 |
|
1799 |
|
1753 |
static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1800 |
static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
Lines 1780-1786
Link Here
|
1780 |
|
1827 |
|
1781 |
static u32 gen_reqid(void) |
1828 |
static u32 gen_reqid(void) |
1782 |
{ |
1829 |
{ |
|
|
1830 |
struct xfrm_policy_walk walk; |
1783 |
u32 start; |
1831 |
u32 start; |
|
|
1832 |
int rc; |
1784 |
static u32 reqid = IPSEC_MANUAL_REQID_MAX; |
1833 |
static u32 reqid = IPSEC_MANUAL_REQID_MAX; |
1785 |
|
1834 |
|
1786 |
start = reqid; |
1835 |
start = reqid; |
Lines 1788-1795
Link Here
|
1788 |
++reqid; |
1837 |
++reqid; |
1789 |
if (reqid == 0) |
1838 |
if (reqid == 0) |
1790 |
reqid = IPSEC_MANUAL_REQID_MAX+1; |
1839 |
reqid = IPSEC_MANUAL_REQID_MAX+1; |
1791 |
if (xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, check_reqid, |
1840 |
xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); |
1792 |
(void*)&reqid) != -EEXIST) |
1841 |
rc = xfrm_policy_walk(&walk, check_reqid, (void*)&reqid); |
|
|
1842 |
xfrm_policy_walk_done(&walk); |
1843 |
if (rc != -EEXIST) |
1793 |
return reqid; |
1844 |
return reqid; |
1794 |
} while (reqid != start); |
1845 |
} while (reqid != start); |
1795 |
return 0; |
1846 |
return 0; |
Lines 2638-2648
Link Here
|
2638 |
|
2689 |
|
2639 |
static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) |
2690 |
static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) |
2640 |
{ |
2691 |
{ |
2641 |
struct pfkey_dump_data *data = ptr; |
2692 |
struct pfkey_sock *pfk = ptr; |
2642 |
struct sk_buff *out_skb; |
2693 |
struct sk_buff *out_skb; |
2643 |
struct sadb_msg *out_hdr; |
2694 |
struct sadb_msg *out_hdr; |
2644 |
int err; |
2695 |
int err; |
2645 |
|
2696 |
|
|
|
2697 |
if (!pfkey_can_dump(&pfk->sk)) |
2698 |
return -ENOBUFS; |
2699 |
|
2646 |
out_skb = pfkey_xfrm_policy2msg_prep(xp); |
2700 |
out_skb = pfkey_xfrm_policy2msg_prep(xp); |
2647 |
if (IS_ERR(out_skb)) |
2701 |
if (IS_ERR(out_skb)) |
2648 |
return PTR_ERR(out_skb); |
2702 |
return PTR_ERR(out_skb); |
Lines 2652-2672
Link Here
|
2652 |
return err; |
2706 |
return err; |
2653 |
|
2707 |
|
2654 |
out_hdr = (struct sadb_msg *) out_skb->data; |
2708 |
out_hdr = (struct sadb_msg *) out_skb->data; |
2655 |
out_hdr->sadb_msg_version = data->hdr->sadb_msg_version; |
2709 |
out_hdr->sadb_msg_version = pfk->dump.msg_version; |
2656 |
out_hdr->sadb_msg_type = SADB_X_SPDDUMP; |
2710 |
out_hdr->sadb_msg_type = SADB_X_SPDDUMP; |
2657 |
out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; |
2711 |
out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; |
2658 |
out_hdr->sadb_msg_errno = 0; |
2712 |
out_hdr->sadb_msg_errno = 0; |
2659 |
out_hdr->sadb_msg_seq = count; |
2713 |
out_hdr->sadb_msg_seq = count; |
2660 |
out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid; |
2714 |
out_hdr->sadb_msg_pid = pfk->dump.msg_pid; |
2661 |
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk); |
2715 |
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); |
2662 |
return 0; |
2716 |
return 0; |
2663 |
} |
2717 |
} |
2664 |
|
2718 |
|
|
|
2719 |
static int pfkey_dump_sp(struct pfkey_sock *pfk) |
2720 |
{ |
2721 |
return xfrm_policy_walk(&pfk->dump.u.policy, dump_sp, (void *) pfk); |
2722 |
} |
2723 |
|
2724 |
static void pfkey_dump_sp_done(struct pfkey_sock *pfk) |
2725 |
{ |
2726 |
xfrm_policy_walk_done(&pfk->dump.u.policy); |
2727 |
} |
2728 |
|
2665 |
static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2729 |
static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2666 |
{ |
2730 |
{ |
2667 |
struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk }; |
2731 |
struct pfkey_sock *pfk = pfkey_sk(sk); |
|
|
2732 |
|
2733 |
if (pfk->dump.dump != NULL) |
2734 |
return -EBUSY; |
2735 |
|
2736 |
pfk->dump.msg_version = hdr->sadb_msg_version; |
2737 |
pfk->dump.msg_pid = hdr->sadb_msg_pid; |
2738 |
pfk->dump.dump = pfkey_dump_sp; |
2739 |
pfk->dump.done = pfkey_dump_sp_done; |
2740 |
xfrm_policy_walk_init(&pfk->dump.u.policy, XFRM_POLICY_TYPE_MAIN); |
2668 |
|
2741 |
|
2669 |
return xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_sp, &data); |
2742 |
return pfkey_do_dump(pfk); |
2670 |
} |
2743 |
} |
2671 |
|
2744 |
|
2672 |
static int key_notify_policy_flush(struct km_event *c) |
2745 |
static int key_notify_policy_flush(struct km_event *c) |
Lines 3672-3677
Link Here
|
3672 |
int flags) |
3745 |
int flags) |
3673 |
{ |
3746 |
{ |
3674 |
struct sock *sk = sock->sk; |
3747 |
struct sock *sk = sock->sk; |
|
|
3748 |
struct pfkey_sock *pfk = pfkey_sk(sk); |
3675 |
struct sk_buff *skb; |
3749 |
struct sk_buff *skb; |
3676 |
int copied, err; |
3750 |
int copied, err; |
3677 |
|
3751 |
|
Lines 3699-3704
Link Here
|
3699 |
|
3773 |
|
3700 |
err = (flags & MSG_TRUNC) ? skb->len : copied; |
3774 |
err = (flags & MSG_TRUNC) ? skb->len : copied; |
3701 |
|
3775 |
|
|
|
3776 |
if (pfk->dump.dump != NULL && |
3777 |
3 * atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) |
3778 |
pfkey_do_dump(pfk); |
3779 |
|
3702 |
out_free: |
3780 |
out_free: |
3703 |
skb_free_datagram(sk, skb); |
3781 |
skb_free_datagram(sk, skb); |
3704 |
out: |
3782 |
out: |