diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/neighbour.c | 317 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 20 |
2 files changed, 326 insertions, 11 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 43bdc521e20d..0841ac78c67d 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1276,9 +1276,14 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, | |||
1276 | INIT_RCU_HEAD(&p->rcu_head); | 1276 | INIT_RCU_HEAD(&p->rcu_head); |
1277 | p->reachable_time = | 1277 | p->reachable_time = |
1278 | neigh_rand_reach_time(p->base_reachable_time); | 1278 | neigh_rand_reach_time(p->base_reachable_time); |
1279 | if (dev && dev->neigh_setup && dev->neigh_setup(dev, p)) { | 1279 | if (dev) { |
1280 | kfree(p); | 1280 | if (dev->neigh_setup && dev->neigh_setup(dev, p)) { |
1281 | return NULL; | 1281 | kfree(p); |
1282 | return NULL; | ||
1283 | } | ||
1284 | |||
1285 | dev_hold(dev); | ||
1286 | p->dev = dev; | ||
1282 | } | 1287 | } |
1283 | p->sysctl_table = NULL; | 1288 | p->sysctl_table = NULL; |
1284 | write_lock_bh(&tbl->lock); | 1289 | write_lock_bh(&tbl->lock); |
@@ -1309,6 +1314,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) | |||
1309 | *p = parms->next; | 1314 | *p = parms->next; |
1310 | parms->dead = 1; | 1315 | parms->dead = 1; |
1311 | write_unlock_bh(&tbl->lock); | 1316 | write_unlock_bh(&tbl->lock); |
1317 | if (parms->dev) | ||
1318 | dev_put(parms->dev); | ||
1312 | call_rcu(&parms->rcu_head, neigh_rcu_free_parms); | 1319 | call_rcu(&parms->rcu_head, neigh_rcu_free_parms); |
1313 | return; | 1320 | return; |
1314 | } | 1321 | } |
@@ -1546,6 +1553,308 @@ out: | |||
1546 | return err; | 1553 | return err; |
1547 | } | 1554 | } |
1548 | 1555 | ||
1556 | static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms) | ||
1557 | { | ||
1558 | struct rtattr *nest = RTA_NEST(skb, NDTA_PARMS); | ||
1559 | |||
1560 | if (parms->dev) | ||
1561 | RTA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); | ||
1562 | |||
1563 | RTA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); | ||
1564 | RTA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len); | ||
1565 | RTA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); | ||
1566 | RTA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); | ||
1567 | RTA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); | ||
1568 | RTA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes); | ||
1569 | RTA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time); | ||
1570 | RTA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME, | ||
1571 | parms->base_reachable_time); | ||
1572 | RTA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime); | ||
1573 | RTA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time); | ||
1574 | RTA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time); | ||
1575 | RTA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay); | ||
1576 | RTA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay); | ||
1577 | RTA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime); | ||
1578 | |||
1579 | return RTA_NEST_END(skb, nest); | ||
1580 | |||
1581 | rtattr_failure: | ||
1582 | return RTA_NEST_CANCEL(skb, nest); | ||
1583 | } | ||
1584 | |||
1585 | static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, | ||
1586 | struct netlink_callback *cb) | ||
1587 | { | ||
1588 | struct nlmsghdr *nlh; | ||
1589 | struct ndtmsg *ndtmsg; | ||
1590 | |||
1591 | nlh = NLMSG_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg)); | ||
1592 | ndtmsg = NLMSG_DATA(nlh); | ||
1593 | |||
1594 | NLMSG_SET_MULTIPART(nlh); | ||
1595 | |||
1596 | read_lock_bh(&tbl->lock); | ||
1597 | ndtmsg->ndtm_family = tbl->family; | ||
1598 | |||
1599 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | ||
1600 | RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); | ||
1601 | RTA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1); | ||
1602 | RTA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2); | ||
1603 | RTA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3); | ||
1604 | |||
1605 | { | ||
1606 | unsigned long now = jiffies; | ||
1607 | unsigned int flush_delta = now - tbl->last_flush; | ||
1608 | unsigned int rand_delta = now - tbl->last_rand; | ||
1609 | |||
1610 | struct ndt_config ndc = { | ||
1611 | .ndtc_key_len = tbl->key_len, | ||
1612 | .ndtc_entry_size = tbl->entry_size, | ||
1613 | .ndtc_entries = atomic_read(&tbl->entries), | ||
1614 | .ndtc_last_flush = jiffies_to_msecs(flush_delta), | ||
1615 | .ndtc_last_rand = jiffies_to_msecs(rand_delta), | ||
1616 | .ndtc_hash_rnd = tbl->hash_rnd, | ||
1617 | .ndtc_hash_mask = tbl->hash_mask, | ||
1618 | .ndtc_hash_chain_gc = tbl->hash_chain_gc, | ||
1619 | .ndtc_proxy_qlen = tbl->proxy_queue.qlen, | ||
1620 | }; | ||
1621 | |||
1622 | RTA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); | ||
1623 | } | ||
1624 | |||
1625 | { | ||
1626 | int cpu; | ||
1627 | struct ndt_stats ndst; | ||
1628 | |||
1629 | memset(&ndst, 0, sizeof(ndst)); | ||
1630 | |||
1631 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | ||
1632 | struct neigh_statistics *st; | ||
1633 | |||
1634 | if (!cpu_possible(cpu)) | ||
1635 | continue; | ||
1636 | |||
1637 | st = per_cpu_ptr(tbl->stats, cpu); | ||
1638 | ndst.ndts_allocs += st->allocs; | ||
1639 | ndst.ndts_destroys += st->destroys; | ||
1640 | ndst.ndts_hash_grows += st->hash_grows; | ||
1641 | ndst.ndts_res_failed += st->res_failed; | ||
1642 | ndst.ndts_lookups += st->lookups; | ||
1643 | ndst.ndts_hits += st->hits; | ||
1644 | ndst.ndts_rcv_probes_mcast += st->rcv_probes_mcast; | ||
1645 | ndst.ndts_rcv_probes_ucast += st->rcv_probes_ucast; | ||
1646 | ndst.ndts_periodic_gc_runs += st->periodic_gc_runs; | ||
1647 | ndst.ndts_forced_gc_runs += st->forced_gc_runs; | ||
1648 | } | ||
1649 | |||
1650 | RTA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst); | ||
1651 | } | ||
1652 | |||
1653 | BUG_ON(tbl->parms.dev); | ||
1654 | if (neightbl_fill_parms(skb, &tbl->parms) < 0) | ||
1655 | goto rtattr_failure; | ||
1656 | |||
1657 | read_unlock_bh(&tbl->lock); | ||
1658 | return NLMSG_END(skb, nlh); | ||
1659 | |||
1660 | rtattr_failure: | ||
1661 | read_unlock_bh(&tbl->lock); | ||
1662 | return NLMSG_CANCEL(skb, nlh); | ||
1663 | |||
1664 | nlmsg_failure: | ||
1665 | return -1; | ||
1666 | } | ||
1667 | |||
1668 | static int neightbl_fill_param_info(struct neigh_table *tbl, | ||
1669 | struct neigh_parms *parms, | ||
1670 | struct sk_buff *skb, | ||
1671 | struct netlink_callback *cb) | ||
1672 | { | ||
1673 | struct ndtmsg *ndtmsg; | ||
1674 | struct nlmsghdr *nlh; | ||
1675 | |||
1676 | nlh = NLMSG_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg)); | ||
1677 | ndtmsg = NLMSG_DATA(nlh); | ||
1678 | |||
1679 | NLMSG_SET_MULTIPART(nlh); | ||
1680 | |||
1681 | read_lock_bh(&tbl->lock); | ||
1682 | ndtmsg->ndtm_family = tbl->family; | ||
1683 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | ||
1684 | |||
1685 | if (neightbl_fill_parms(skb, parms) < 0) | ||
1686 | goto rtattr_failure; | ||
1687 | |||
1688 | read_unlock_bh(&tbl->lock); | ||
1689 | return NLMSG_END(skb, nlh); | ||
1690 | |||
1691 | rtattr_failure: | ||
1692 | read_unlock_bh(&tbl->lock); | ||
1693 | return NLMSG_CANCEL(skb, nlh); | ||
1694 | |||
1695 | nlmsg_failure: | ||
1696 | return -1; | ||
1697 | } | ||
1698 | |||
1699 | static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | ||
1700 | int ifindex) | ||
1701 | { | ||
1702 | struct neigh_parms *p; | ||
1703 | |||
1704 | for (p = &tbl->parms; p; p = p->next) | ||
1705 | if ((p->dev && p->dev->ifindex == ifindex) || | ||
1706 | (!p->dev && !ifindex)) | ||
1707 | return p; | ||
1708 | |||
1709 | return NULL; | ||
1710 | } | ||
1711 | |||
1712 | int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | ||
1713 | { | ||
1714 | struct neigh_table *tbl; | ||
1715 | struct ndtmsg *ndtmsg = NLMSG_DATA(nlh); | ||
1716 | struct rtattr **tb = arg; | ||
1717 | int err = -EINVAL; | ||
1718 | |||
1719 | if (!tb[NDTA_NAME - 1] || !RTA_PAYLOAD(tb[NDTA_NAME - 1])) | ||
1720 | return -EINVAL; | ||
1721 | |||
1722 | read_lock(&neigh_tbl_lock); | ||
1723 | for (tbl = neigh_tables; tbl; tbl = tbl->next) { | ||
1724 | if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family) | ||
1725 | continue; | ||
1726 | |||
1727 | if (!rtattr_strcmp(tb[NDTA_NAME - 1], tbl->id)) | ||
1728 | break; | ||
1729 | } | ||
1730 | |||
1731 | if (tbl == NULL) { | ||
1732 | err = -ENOENT; | ||
1733 | goto errout; | ||
1734 | } | ||
1735 | |||
1736 | /* | ||
1737 | * We acquire tbl->lock to be nice to the periodic timers and | ||
1738 | * make sure they always see a consistent set of values. | ||
1739 | */ | ||
1740 | write_lock_bh(&tbl->lock); | ||
1741 | |||
1742 | if (tb[NDTA_THRESH1 - 1]) | ||
1743 | tbl->gc_thresh1 = RTA_GET_U32(tb[NDTA_THRESH1 - 1]); | ||
1744 | |||
1745 | if (tb[NDTA_THRESH2 - 1]) | ||
1746 | tbl->gc_thresh2 = RTA_GET_U32(tb[NDTA_THRESH2 - 1]); | ||
1747 | |||
1748 | if (tb[NDTA_THRESH3 - 1]) | ||
1749 | tbl->gc_thresh3 = RTA_GET_U32(tb[NDTA_THRESH3 - 1]); | ||
1750 | |||
1751 | if (tb[NDTA_GC_INTERVAL - 1]) | ||
1752 | tbl->gc_interval = RTA_GET_MSECS(tb[NDTA_GC_INTERVAL - 1]); | ||
1753 | |||
1754 | if (tb[NDTA_PARMS - 1]) { | ||
1755 | struct rtattr *tbp[NDTPA_MAX]; | ||
1756 | struct neigh_parms *p; | ||
1757 | u32 ifindex = 0; | ||
1758 | |||
1759 | if (rtattr_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS - 1]) < 0) | ||
1760 | goto rtattr_failure; | ||
1761 | |||
1762 | if (tbp[NDTPA_IFINDEX - 1]) | ||
1763 | ifindex = RTA_GET_U32(tbp[NDTPA_IFINDEX - 1]); | ||
1764 | |||
1765 | p = lookup_neigh_params(tbl, ifindex); | ||
1766 | if (p == NULL) { | ||
1767 | err = -ENOENT; | ||
1768 | goto rtattr_failure; | ||
1769 | } | ||
1770 | |||
1771 | if (tbp[NDTPA_QUEUE_LEN - 1]) | ||
1772 | p->queue_len = RTA_GET_U32(tbp[NDTPA_QUEUE_LEN - 1]); | ||
1773 | |||
1774 | if (tbp[NDTPA_PROXY_QLEN - 1]) | ||
1775 | p->proxy_qlen = RTA_GET_U32(tbp[NDTPA_PROXY_QLEN - 1]); | ||
1776 | |||
1777 | if (tbp[NDTPA_APP_PROBES - 1]) | ||
1778 | p->app_probes = RTA_GET_U32(tbp[NDTPA_APP_PROBES - 1]); | ||
1779 | |||
1780 | if (tbp[NDTPA_UCAST_PROBES - 1]) | ||
1781 | p->ucast_probes = | ||
1782 | RTA_GET_U32(tbp[NDTPA_UCAST_PROBES - 1]); | ||
1783 | |||
1784 | if (tbp[NDTPA_MCAST_PROBES - 1]) | ||
1785 | p->mcast_probes = | ||
1786 | RTA_GET_U32(tbp[NDTPA_MCAST_PROBES - 1]); | ||
1787 | |||
1788 | if (tbp[NDTPA_BASE_REACHABLE_TIME - 1]) | ||
1789 | p->base_reachable_time = | ||
1790 | RTA_GET_MSECS(tbp[NDTPA_BASE_REACHABLE_TIME - 1]); | ||
1791 | |||
1792 | if (tbp[NDTPA_GC_STALETIME - 1]) | ||
1793 | p->gc_staletime = | ||
1794 | RTA_GET_MSECS(tbp[NDTPA_GC_STALETIME - 1]); | ||
1795 | |||
1796 | if (tbp[NDTPA_DELAY_PROBE_TIME - 1]) | ||
1797 | p->delay_probe_time = | ||
1798 | RTA_GET_MSECS(tbp[NDTPA_DELAY_PROBE_TIME - 1]); | ||
1799 | |||
1800 | if (tbp[NDTPA_RETRANS_TIME - 1]) | ||
1801 | p->retrans_time = | ||
1802 | RTA_GET_MSECS(tbp[NDTPA_RETRANS_TIME - 1]); | ||
1803 | |||
1804 | if (tbp[NDTPA_ANYCAST_DELAY - 1]) | ||
1805 | p->anycast_delay = | ||
1806 | RTA_GET_MSECS(tbp[NDTPA_ANYCAST_DELAY - 1]); | ||
1807 | |||
1808 | if (tbp[NDTPA_PROXY_DELAY - 1]) | ||
1809 | p->proxy_delay = | ||
1810 | RTA_GET_MSECS(tbp[NDTPA_PROXY_DELAY - 1]); | ||
1811 | |||
1812 | if (tbp[NDTPA_LOCKTIME - 1]) | ||
1813 | p->locktime = RTA_GET_MSECS(tbp[NDTPA_LOCKTIME - 1]); | ||
1814 | } | ||
1815 | |||
1816 | err = 0; | ||
1817 | |||
1818 | rtattr_failure: | ||
1819 | write_unlock_bh(&tbl->lock); | ||
1820 | errout: | ||
1821 | read_unlock(&neigh_tbl_lock); | ||
1822 | return err; | ||
1823 | } | ||
1824 | |||
1825 | int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) | ||
1826 | { | ||
1827 | int idx, family; | ||
1828 | int s_idx = cb->args[0]; | ||
1829 | struct neigh_table *tbl; | ||
1830 | |||
1831 | family = ((struct rtgenmsg *)NLMSG_DATA(cb->nlh))->rtgen_family; | ||
1832 | |||
1833 | read_lock(&neigh_tbl_lock); | ||
1834 | for (tbl = neigh_tables, idx = 0; tbl; tbl = tbl->next) { | ||
1835 | struct neigh_parms *p; | ||
1836 | |||
1837 | if (idx < s_idx || (family && tbl->family != family)) | ||
1838 | continue; | ||
1839 | |||
1840 | if (neightbl_fill_info(tbl, skb, cb) <= 0) | ||
1841 | break; | ||
1842 | |||
1843 | for (++idx, p = tbl->parms.next; p; p = p->next, idx++) { | ||
1844 | if (idx < s_idx) | ||
1845 | continue; | ||
1846 | |||
1847 | if (neightbl_fill_param_info(tbl, p, skb, cb) <= 0) | ||
1848 | goto out; | ||
1849 | } | ||
1850 | |||
1851 | } | ||
1852 | out: | ||
1853 | read_unlock(&neigh_tbl_lock); | ||
1854 | cb->args[0] = idx; | ||
1855 | |||
1856 | return skb->len; | ||
1857 | } | ||
1549 | 1858 | ||
1550 | static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, | 1859 | static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, |
1551 | u32 pid, u32 seq, int event) | 1860 | u32 pid, u32 seq, int event) |
@@ -2352,6 +2661,8 @@ EXPORT_SYMBOL(neigh_update); | |||
2352 | EXPORT_SYMBOL(neigh_update_hhs); | 2661 | EXPORT_SYMBOL(neigh_update_hhs); |
2353 | EXPORT_SYMBOL(pneigh_enqueue); | 2662 | EXPORT_SYMBOL(pneigh_enqueue); |
2354 | EXPORT_SYMBOL(pneigh_lookup); | 2663 | EXPORT_SYMBOL(pneigh_lookup); |
2664 | EXPORT_SYMBOL(neightbl_dump_info); | ||
2665 | EXPORT_SYMBOL(neightbl_set); | ||
2355 | 2666 | ||
2356 | #ifdef CONFIG_ARPD | 2667 | #ifdef CONFIG_ARPD |
2357 | EXPORT_SYMBOL(neigh_app_ns); | 2668 | EXPORT_SYMBOL(neigh_app_ns); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 00caf4b318b2..56a20f014b8a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -100,6 +100,7 @@ static const int rtm_min[RTM_NR_FAMILIES] = | |||
100 | [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | 100 | [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), |
101 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | 101 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), |
102 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | 102 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), |
103 | [RTM_FAM(RTM_NEWNEIGHTBL)] = NLMSG_LENGTH(sizeof(struct ndtmsg)), | ||
103 | }; | 104 | }; |
104 | 105 | ||
105 | static const int rta_max[RTM_NR_FAMILIES] = | 106 | static const int rta_max[RTM_NR_FAMILIES] = |
@@ -113,6 +114,7 @@ static const int rta_max[RTM_NR_FAMILIES] = | |||
113 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, | 114 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, |
114 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, | 115 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, |
115 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, | 116 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, |
117 | [RTM_FAM(RTM_NEWNEIGHTBL)] = NDTA_MAX, | ||
116 | }; | 118 | }; |
117 | 119 | ||
118 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) | 120 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) |
@@ -649,14 +651,16 @@ static void rtnetlink_rcv(struct sock *sk, int len) | |||
649 | 651 | ||
650 | static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = | 652 | static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = |
651 | { | 653 | { |
652 | [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, | 654 | [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, |
653 | [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, | 655 | [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, |
654 | [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, | 656 | [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, |
655 | [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, | 657 | [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, |
656 | [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, | 658 | [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, |
657 | [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, | 659 | [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, |
658 | [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, | 660 | [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, |
659 | [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, | 661 | [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, |
662 | [RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info }, | ||
663 | [RTM_SETNEIGHTBL - RTM_BASE] = { .doit = neightbl_set }, | ||
660 | }; | 664 | }; |
661 | 665 | ||
662 | static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) | 666 | static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) |