Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[NEIGH]: Convert neighbour table dumping to new netlink api

Also fixes skipping of already dumped neighbours.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Thomas Graf and committed by
David S. Miller
ca860fb3 6b3f8674

+73 -66
+73 -66
net/core/neighbour.c
··· 1597 1597 1598 1598 static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms) 1599 1599 { 1600 - struct rtattr *nest = NULL; 1601 - 1602 - nest = RTA_NEST(skb, NDTA_PARMS); 1600 + struct nlattr *nest; 1601 + 1602 + nest = nla_nest_start(skb, NDTA_PARMS); 1603 + if (nest == NULL) 1604 + return -ENOBUFS; 1603 1605 1604 1606 if (parms->dev) 1605 - RTA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); 1607 + NLA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); 1606 1608 1607 - RTA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); 1608 - RTA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len); 1609 - RTA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); 1610 - RTA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); 1611 - RTA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); 1612 - RTA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes); 1613 - RTA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time); 1614 - RTA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME, 1609 + NLA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); 1610 + NLA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len); 1611 + NLA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); 1612 + NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); 1613 + NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); 1614 + NLA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes); 1615 + NLA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time); 1616 + NLA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME, 1615 1617 parms->base_reachable_time); 1616 - RTA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime); 1617 - RTA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time); 1618 - RTA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time); 1619 - RTA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay); 1620 - RTA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay); 1621 - RTA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime); 1618 + NLA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime); 1619 + NLA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time); 1620 + NLA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time); 1621 + NLA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay); 1622 + NLA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay); 1623 + NLA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime); 1622 1624 1623 - return RTA_NEST_END(skb, nest); 1625 + return nla_nest_end(skb, nest); 1624 1626 1625 - rtattr_failure: 1626 - return RTA_NEST_CANCEL(skb, nest); 1627 + nla_put_failure: 1628 + return nla_nest_cancel(skb, nest); 1627 1629 } 1628 1630 1629 - static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, 1630 - struct netlink_callback *cb) 1631 + static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, 1632 + u32 pid, u32 seq, int type, int flags) 1631 1633 { 1632 1634 struct nlmsghdr *nlh; 1633 1635 struct ndtmsg *ndtmsg; 1634 1636 1635 - nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg), 1636 - NLM_F_MULTI); 1637 + nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); 1638 + if (nlh == NULL) 1639 + return -ENOBUFS; 1637 1640 1638 - ndtmsg = NLMSG_DATA(nlh); 1641 + ndtmsg = nlmsg_data(nlh); 1639 1642 1640 1643 read_lock_bh(&tbl->lock); 1641 1644 ndtmsg->ndtm_family = tbl->family; 1642 1645 ndtmsg->ndtm_pad1 = 0; 1643 1646 ndtmsg->ndtm_pad2 = 0; 1644 1647 1645 - RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); 1646 - RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); 1647 - RTA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1); 1648 - RTA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2); 1649 - RTA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3); 1648 + NLA_PUT_STRING(skb, NDTA_NAME, tbl->id); 1649 + NLA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); 1650 + NLA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1); 1651 + NLA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2); 1652 + NLA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3); 1650 1653 1651 1654 { 1652 1655 unsigned long now = jiffies; ··· 1668 1665 .ndtc_proxy_qlen = tbl->proxy_queue.qlen, 1669 1666 }; 1670 1667 1671 - RTA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); 1668 + NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); 1672 1669 } 1673 1670 1674 1671 { ··· 1693 1690 ndst.ndts_forced_gc_runs += st->forced_gc_runs; 1694 1691 } 1695 1692 1696 - RTA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst); 1693 + NLA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst); 1697 1694 } 1698 1695 1699 1696 BUG_ON(tbl->parms.dev); 1700 1697 if (neightbl_fill_parms(skb, &tbl->parms) < 0) 1701 - goto rtattr_failure; 1698 + goto nla_put_failure; 1702 1699 1703 1700 read_unlock_bh(&tbl->lock); 1704 - return NLMSG_END(skb, nlh); 1701 + return nlmsg_end(skb, nlh); 1705 1702 1706 - rtattr_failure: 1703 + nla_put_failure: 1707 1704 read_unlock_bh(&tbl->lock); 1708 - return NLMSG_CANCEL(skb, nlh); 1709 - 1710 - nlmsg_failure: 1711 - return -1; 1705 + return nlmsg_cancel(skb, nlh); 1712 1706 } 1713 1707 1714 - static int neightbl_fill_param_info(struct neigh_table *tbl, 1708 + static int neightbl_fill_param_info(struct sk_buff *skb, 1709 + struct neigh_table *tbl, 1715 1710 struct neigh_parms *parms, 1716 - struct sk_buff *skb, 1717 - struct netlink_callback *cb) 1711 + u32 pid, u32 seq, int type, 1712 + unsigned int flags) 1718 1713 { 1719 1714 struct ndtmsg *ndtmsg; 1720 1715 struct nlmsghdr *nlh; 1721 1716 1722 - nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg), 1723 - NLM_F_MULTI); 1717 + nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); 1718 + if (nlh == NULL) 1719 + return -ENOBUFS; 1724 1720 1725 - ndtmsg = NLMSG_DATA(nlh); 1721 + ndtmsg = nlmsg_data(nlh); 1726 1722 1727 1723 read_lock_bh(&tbl->lock); 1728 1724 ndtmsg->ndtm_family = tbl->family; 1729 1725 ndtmsg->ndtm_pad1 = 0; 1730 1726 ndtmsg->ndtm_pad2 = 0; 1731 - RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); 1732 1727 1733 - if (neightbl_fill_parms(skb, parms) < 0) 1734 - goto rtattr_failure; 1728 + if (nla_put_string(skb, NDTA_NAME, tbl->id) < 0 || 1729 + neightbl_fill_parms(skb, parms) < 0) 1730 + goto errout; 1735 1731 1736 1732 read_unlock_bh(&tbl->lock); 1737 - return NLMSG_END(skb, nlh); 1738 - 1739 - rtattr_failure: 1733 + return nlmsg_end(skb, nlh); 1734 + errout: 1740 1735 read_unlock_bh(&tbl->lock); 1741 - return NLMSG_CANCEL(skb, nlh); 1742 - 1743 - nlmsg_failure: 1744 - return -1; 1736 + return nlmsg_cancel(skb, nlh); 1745 1737 } 1746 1738 1747 1739 static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, ··· 1903 1905 1904 1906 int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) 1905 1907 { 1906 - int idx, family; 1907 - int s_idx = cb->args[0]; 1908 + int family, tidx, nidx = 0; 1909 + int tbl_skip = cb->args[0]; 1910 + int neigh_skip = cb->args[1]; 1908 1911 struct neigh_table *tbl; 1909 1912 1910 - family = ((struct rtgenmsg *)NLMSG_DATA(cb->nlh))->rtgen_family; 1913 + family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; 1911 1914 1912 1915 read_lock(&neigh_tbl_lock); 1913 - for (tbl = neigh_tables, idx = 0; tbl; tbl = tbl->next) { 1916 + for (tbl = neigh_tables, tidx = 0; tbl; tbl = tbl->next, tidx++) { 1914 1917 struct neigh_parms *p; 1915 1918 1916 - if (idx < s_idx || (family && tbl->family != family)) 1919 + if (tidx < tbl_skip || (family && tbl->family != family)) 1917 1920 continue; 1918 1921 1919 - if (neightbl_fill_info(tbl, skb, cb) <= 0) 1922 + if (neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).pid, 1923 + cb->nlh->nlmsg_seq, RTM_NEWNEIGHTBL, 1924 + NLM_F_MULTI) <= 0) 1920 1925 break; 1921 1926 1922 - for (++idx, p = tbl->parms.next; p; p = p->next, idx++) { 1923 - if (idx < s_idx) 1927 + for (nidx = 0, p = tbl->parms.next; p; p = p->next, nidx++) { 1928 + if (nidx < neigh_skip) 1924 1929 continue; 1925 1930 1926 - if (neightbl_fill_param_info(tbl, p, skb, cb) <= 0) 1931 + if (neightbl_fill_param_info(skb, tbl, p, 1932 + NETLINK_CB(cb->skb).pid, 1933 + cb->nlh->nlmsg_seq, 1934 + RTM_NEWNEIGHTBL, 1935 + NLM_F_MULTI) <= 0) 1927 1936 goto out; 1928 1937 } 1929 1938 1939 + neigh_skip = 0; 1930 1940 } 1931 1941 out: 1932 1942 read_unlock(&neigh_tbl_lock); 1933 - cb->args[0] = idx; 1943 + cb->args[0] = tidx; 1944 + cb->args[1] = nidx; 1934 1945 1935 1946 return skb->len; 1936 1947 }