af_netlink.c (c63d6ea3060d9e10773e869b1112e3a0efbcf820) | af_netlink.c (670dc2833d144375eac36ad74111495a825a9288) |
---|---|
1/* 2 * NETLINK Kernel-user communication protocol. 3 * 4 * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk> 5 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License --- 1645 unchanged lines hidden (view full) --- 1654 * It looks a bit ugly. 1655 * It would be better to create kernel thread. 1656 */ 1657 1658static int netlink_dump(struct sock *sk) 1659{ 1660 struct netlink_sock *nlk = nlk_sk(sk); 1661 struct netlink_callback *cb; | 1/* 2 * NETLINK Kernel-user communication protocol. 3 * 4 * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk> 5 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License --- 1645 unchanged lines hidden (view full) --- 1654 * It looks a bit ugly. 1655 * It would be better to create kernel thread. 1656 */ 1657 1658static int netlink_dump(struct sock *sk) 1659{ 1660 struct netlink_sock *nlk = nlk_sk(sk); 1661 struct netlink_callback *cb; |
1662 struct sk_buff *skb = NULL; | 1662 struct sk_buff *skb; |
1663 struct nlmsghdr *nlh; 1664 int len, err = -ENOBUFS; | 1663 struct nlmsghdr *nlh; 1664 int len, err = -ENOBUFS; |
1665 int alloc_size; | |
1666 | 1665 |
1666 skb = sock_rmalloc(sk, NLMSG_GOODSIZE, 0, GFP_KERNEL); 1667 if (!skb) 1668 goto errout; 1669 |
|
1667 mutex_lock(nlk->cb_mutex); 1668 1669 cb = nlk->cb; 1670 if (cb == NULL) { 1671 err = -EINVAL; 1672 goto errout_skb; 1673 } 1674 | 1670 mutex_lock(nlk->cb_mutex); 1671 1672 cb = nlk->cb; 1673 if (cb == NULL) { 1674 err = -EINVAL; 1675 goto errout_skb; 1676 } 1677 |
1675 alloc_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE); 1676 1677 skb = sock_rmalloc(sk, alloc_size, 0, GFP_KERNEL); 1678 if (!skb) 1679 goto errout_skb; 1680 | |
1681 len = cb->dump(skb, cb); 1682 1683 if (len > 0) { 1684 mutex_unlock(nlk->cb_mutex); 1685 1686 if (sk_filter(sk, skb)) 1687 kfree_skb(skb); 1688 else { 1689 skb_queue_tail(&sk->sk_receive_queue, skb); 1690 sk->sk_data_ready(sk, skb->len); 1691 } 1692 return 0; 1693 } 1694 1695 nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE, sizeof(len), NLM_F_MULTI); 1696 if (!nlh) 1697 goto errout_skb; 1698 | 1678 len = cb->dump(skb, cb); 1679 1680 if (len > 0) { 1681 mutex_unlock(nlk->cb_mutex); 1682 1683 if (sk_filter(sk, skb)) 1684 kfree_skb(skb); 1685 else { 1686 skb_queue_tail(&sk->sk_receive_queue, skb); 1687 sk->sk_data_ready(sk, skb->len); 1688 } 1689 return 0; 1690 } 1691 1692 nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE, sizeof(len), NLM_F_MULTI); 1693 if (!nlh) 1694 goto errout_skb; 1695 |
1696 nl_dump_check_consistent(cb, nlh); 1697 |
|
1699 memcpy(nlmsg_data(nlh), &len, sizeof(len)); 1700 1701 if (sk_filter(sk, skb)) 1702 kfree_skb(skb); 1703 else { 1704 skb_queue_tail(&sk->sk_receive_queue, skb); 1705 sk->sk_data_ready(sk, skb->len); 1706 } --- 4 unchanged lines hidden (view full) --- 1711 mutex_unlock(nlk->cb_mutex); 1712 1713 netlink_destroy_callback(cb); 1714 return 0; 1715 1716errout_skb: 1717 mutex_unlock(nlk->cb_mutex); 1718 kfree_skb(skb); | 1698 memcpy(nlmsg_data(nlh), &len, sizeof(len)); 1699 1700 if (sk_filter(sk, skb)) 1701 kfree_skb(skb); 1702 else { 1703 skb_queue_tail(&sk->sk_receive_queue, skb); 1704 sk->sk_data_ready(sk, skb->len); 1705 } --- 4 unchanged lines hidden (view full) --- 1710 mutex_unlock(nlk->cb_mutex); 1711 1712 netlink_destroy_callback(cb); 1713 return 0; 1714 1715errout_skb: 1716 mutex_unlock(nlk->cb_mutex); 1717 kfree_skb(skb); |
1718errout: |
|
1719 return err; 1720} 1721 1722int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, 1723 const struct nlmsghdr *nlh, 1724 int (*dump)(struct sk_buff *skb, 1725 struct netlink_callback *), | 1719 return err; 1720} 1721 1722int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, 1723 const struct nlmsghdr *nlh, 1724 int (*dump)(struct sk_buff *skb, 1725 struct netlink_callback *), |
1726 int (*done)(struct netlink_callback *), 1727 u16 min_dump_alloc) | 1726 int (*done)(struct netlink_callback *)) |
1728{ 1729 struct netlink_callback *cb; 1730 struct sock *sk; 1731 struct netlink_sock *nlk; 1732 int ret; 1733 1734 cb = kzalloc(sizeof(*cb), GFP_KERNEL); 1735 if (cb == NULL) 1736 return -ENOBUFS; 1737 1738 cb->dump = dump; 1739 cb->done = done; 1740 cb->nlh = nlh; | 1727{ 1728 struct netlink_callback *cb; 1729 struct sock *sk; 1730 struct netlink_sock *nlk; 1731 int ret; 1732 1733 cb = kzalloc(sizeof(*cb), GFP_KERNEL); 1734 if (cb == NULL) 1735 return -ENOBUFS; 1736 1737 cb->dump = dump; 1738 cb->done = done; 1739 cb->nlh = nlh; |
1741 cb->min_dump_alloc = min_dump_alloc; | |
1742 atomic_inc(&skb->users); 1743 cb->skb = skb; 1744 1745 sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).pid); 1746 if (sk == NULL) { 1747 netlink_destroy_callback(cb); 1748 return -ECONNREFUSED; 1749 } --- 418 unchanged lines hidden --- | 1740 atomic_inc(&skb->users); 1741 cb->skb = skb; 1742 1743 sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).pid); 1744 if (sk == NULL) { 1745 netlink_destroy_callback(cb); 1746 return -ECONNREFUSED; 1747 } --- 418 unchanged lines hidden --- |