rtnetlink.c (fc8eaa85681fa72dc6a4e46f01c92e4fba83d0ab) | rtnetlink.c (4565d7e5a300fcc3a41d40dbcf7ff9d1fe316814) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 116 unchanged lines hidden (view full) --- 125EXPORT_SYMBOL(rtnl_trylock); 126 127int rtnl_is_locked(void) 128{ 129 return mutex_is_locked(&rtnl_mutex); 130} 131EXPORT_SYMBOL(rtnl_is_locked); 132 | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 116 unchanged lines hidden (view full) --- 125EXPORT_SYMBOL(rtnl_trylock); 126 127int rtnl_is_locked(void) 128{ 129 return mutex_is_locked(&rtnl_mutex); 130} 131EXPORT_SYMBOL(rtnl_is_locked); 132 |
133bool refcount_dec_and_rtnl_lock(refcount_t *r) 134{ 135 return refcount_dec_and_mutex_lock(r, &rtnl_mutex); 136} 137EXPORT_SYMBOL(refcount_dec_and_rtnl_lock); 138 |
|
133#ifdef CONFIG_PROVE_LOCKING 134bool lockdep_rtnl_is_held(void) 135{ 136 return lockdep_is_held(&rtnl_mutex); 137} 138EXPORT_SYMBOL(lockdep_rtnl_is_held); 139#endif /* #ifdef CONFIG_PROVE_LOCKING */ 140 --- 870 unchanged lines hidden (view full) --- 1011 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ 1012 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ 1013 + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ 1014 + rtnl_xdp_size() /* IFLA_XDP */ 1015 + nla_total_size(4) /* IFLA_EVENT */ 1016 + nla_total_size(4) /* IFLA_NEW_NETNSID */ 1017 + nla_total_size(4) /* IFLA_NEW_IFINDEX */ 1018 + nla_total_size(1) /* IFLA_PROTO_DOWN */ | 139#ifdef CONFIG_PROVE_LOCKING 140bool lockdep_rtnl_is_held(void) 141{ 142 return lockdep_is_held(&rtnl_mutex); 143} 144EXPORT_SYMBOL(lockdep_rtnl_is_held); 145#endif /* #ifdef CONFIG_PROVE_LOCKING */ 146 --- 870 unchanged lines hidden (view full) --- 1017 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ 1018 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ 1019 + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ 1020 + rtnl_xdp_size() /* IFLA_XDP */ 1021 + nla_total_size(4) /* IFLA_EVENT */ 1022 + nla_total_size(4) /* IFLA_NEW_NETNSID */ 1023 + nla_total_size(4) /* IFLA_NEW_IFINDEX */ 1024 + nla_total_size(1) /* IFLA_PROTO_DOWN */ |
1019 + nla_total_size(4) /* IFLA_IF_NETNSID */ | 1025 + nla_total_size(4) /* IFLA_TARGET_NETNSID */ |
1020 + nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */ 1021 + nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */ 1022 + nla_total_size(4) /* IFLA_MIN_MTU */ 1023 + nla_total_size(4) /* IFLA_MAX_MTU */ 1024 + 0; 1025} 1026 1027static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) --- 565 unchanged lines hidden (view full) --- 1593 ifm = nlmsg_data(nlh); 1594 ifm->ifi_family = AF_UNSPEC; 1595 ifm->__ifi_pad = 0; 1596 ifm->ifi_type = dev->type; 1597 ifm->ifi_index = dev->ifindex; 1598 ifm->ifi_flags = dev_get_flags(dev); 1599 ifm->ifi_change = change; 1600 | 1026 + nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */ 1027 + nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */ 1028 + nla_total_size(4) /* IFLA_MIN_MTU */ 1029 + nla_total_size(4) /* IFLA_MAX_MTU */ 1030 + 0; 1031} 1032 1033static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) --- 565 unchanged lines hidden (view full) --- 1599 ifm = nlmsg_data(nlh); 1600 ifm->ifi_family = AF_UNSPEC; 1601 ifm->__ifi_pad = 0; 1602 ifm->ifi_type = dev->type; 1603 ifm->ifi_index = dev->ifindex; 1604 ifm->ifi_flags = dev_get_flags(dev); 1605 ifm->ifi_change = change; 1606 |
1601 if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_IF_NETNSID, tgt_netnsid)) | 1607 if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_TARGET_NETNSID, tgt_netnsid)) |
1602 goto nla_put_failure; 1603 1604 if (nla_put_string(skb, IFLA_IFNAME, dev->name) || 1605 nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) || 1606 nla_put_u8(skb, IFLA_OPERSTATE, 1607 netif_running(dev) ? dev->operstate : IF_OPER_DOWN) || 1608 nla_put_u8(skb, IFLA_LINKMODE, dev->link_mode) || 1609 nla_put_u32(skb, IFLA_MTU, dev->mtu) || --- 122 unchanged lines hidden (view full) --- 1732 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1733 [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */ 1734 [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1735 [IFLA_LINK_NETNSID] = { .type = NLA_S32 }, 1736 [IFLA_PROTO_DOWN] = { .type = NLA_U8 }, 1737 [IFLA_XDP] = { .type = NLA_NESTED }, 1738 [IFLA_EVENT] = { .type = NLA_U32 }, 1739 [IFLA_GROUP] = { .type = NLA_U32 }, | 1608 goto nla_put_failure; 1609 1610 if (nla_put_string(skb, IFLA_IFNAME, dev->name) || 1611 nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) || 1612 nla_put_u8(skb, IFLA_OPERSTATE, 1613 netif_running(dev) ? dev->operstate : IF_OPER_DOWN) || 1614 nla_put_u8(skb, IFLA_LINKMODE, dev->link_mode) || 1615 nla_put_u32(skb, IFLA_MTU, dev->mtu) || --- 122 unchanged lines hidden (view full) --- 1738 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1739 [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */ 1740 [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN }, 1741 [IFLA_LINK_NETNSID] = { .type = NLA_S32 }, 1742 [IFLA_PROTO_DOWN] = { .type = NLA_U8 }, 1743 [IFLA_XDP] = { .type = NLA_NESTED }, 1744 [IFLA_EVENT] = { .type = NLA_U32 }, 1745 [IFLA_GROUP] = { .type = NLA_U32 }, |
1740 [IFLA_IF_NETNSID] = { .type = NLA_S32 }, | 1746 [IFLA_TARGET_NETNSID] = { .type = NLA_S32 }, |
1741 [IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 }, 1742 [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 }, 1743 [IFLA_MIN_MTU] = { .type = NLA_U32 }, 1744 [IFLA_MAX_MTU] = { .type = NLA_U32 }, 1745}; 1746 1747static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 1748 [IFLA_INFO_KIND] = { .type = NLA_STRING }, --- 91 unchanged lines hidden (view full) --- 1840{ 1841 if (link_master_filtered(dev, master_idx) || 1842 link_kind_filtered(dev, kind_ops)) 1843 return true; 1844 1845 return false; 1846} 1847 | 1747 [IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 }, 1748 [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 }, 1749 [IFLA_MIN_MTU] = { .type = NLA_U32 }, 1750 [IFLA_MAX_MTU] = { .type = NLA_U32 }, 1751}; 1752 1753static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 1754 [IFLA_INFO_KIND] = { .type = NLA_STRING }, --- 91 unchanged lines hidden (view full) --- 1846{ 1847 if (link_master_filtered(dev, master_idx) || 1848 link_kind_filtered(dev, kind_ops)) 1849 return true; 1850 1851 return false; 1852} 1853 |
1848static struct net *get_target_net(struct sock *sk, int netnsid) | 1854/** 1855 * rtnl_get_net_ns_capable - Get netns if sufficiently privileged. 1856 * @sk: netlink socket 1857 * @netnsid: network namespace identifier 1858 * 1859 * Returns the network namespace identified by netnsid on success or an error 1860 * pointer on failure. 1861 */ 1862struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid) |
1849{ 1850 struct net *net; 1851 1852 net = get_net_ns_by_id(sock_net(sk), netnsid); 1853 if (!net) 1854 return ERR_PTR(-EINVAL); 1855 1856 /* For now, the caller is required to have CAP_NET_ADMIN in 1857 * the user namespace owning the target net ns. 1858 */ 1859 if (!sk_ns_capable(sk, net->user_ns, CAP_NET_ADMIN)) { 1860 put_net(net); 1861 return ERR_PTR(-EACCES); 1862 } 1863 return net; 1864} | 1863{ 1864 struct net *net; 1865 1866 net = get_net_ns_by_id(sock_net(sk), netnsid); 1867 if (!net) 1868 return ERR_PTR(-EINVAL); 1869 1870 /* For now, the caller is required to have CAP_NET_ADMIN in 1871 * the user namespace owning the target net ns. 1872 */ 1873 if (!sk_ns_capable(sk, net->user_ns, CAP_NET_ADMIN)) { 1874 put_net(net); 1875 return ERR_PTR(-EACCES); 1876 } 1877 return net; 1878} |
1879EXPORT_SYMBOL_GPL(rtnl_get_net_ns_capable); |
|
1865 | 1880 |
1881static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh, 1882 bool strict_check, struct nlattr **tb, 1883 struct netlink_ext_ack *extack) 1884{ 1885 int hdrlen; 1886 1887 if (strict_check) { 1888 struct ifinfomsg *ifm; 1889 1890 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) { 1891 NL_SET_ERR_MSG(extack, "Invalid header for link dump"); 1892 return -EINVAL; 1893 } 1894 1895 ifm = nlmsg_data(nlh); 1896 if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags || 1897 ifm->ifi_change) { 1898 NL_SET_ERR_MSG(extack, "Invalid values in header for link dump request"); 1899 return -EINVAL; 1900 } 1901 if (ifm->ifi_index) { 1902 NL_SET_ERR_MSG(extack, "Filter by device index not supported for link dumps"); 1903 return -EINVAL; 1904 } 1905 1906 return nlmsg_parse_strict(nlh, sizeof(*ifm), tb, IFLA_MAX, 1907 ifla_policy, extack); 1908 } 1909 1910 /* A hack to preserve kernel<->userspace interface. 1911 * The correct header is ifinfomsg. It is consistent with rtnl_getlink. 1912 * However, before Linux v3.9 the code here assumed rtgenmsg and that's 1913 * what iproute2 < v3.9.0 used. 1914 * We can detect the old iproute2. Even including the IFLA_EXT_MASK 1915 * attribute, its netlink message is shorter than struct ifinfomsg. 1916 */ 1917 hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ? 1918 sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); 1919 1920 return nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy, extack); 1921} 1922 |
|
1866static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 1867{ | 1923static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 1924{ |
1925 struct netlink_ext_ack *extack = cb->extack; 1926 const struct nlmsghdr *nlh = cb->nlh; |
|
1868 struct net *net = sock_net(skb->sk); 1869 struct net *tgt_net = net; 1870 int h, s_h; 1871 int idx = 0, s_idx; 1872 struct net_device *dev; 1873 struct hlist_head *head; 1874 struct nlattr *tb[IFLA_MAX+1]; 1875 u32 ext_filter_mask = 0; 1876 const struct rtnl_link_ops *kind_ops = NULL; 1877 unsigned int flags = NLM_F_MULTI; 1878 int master_idx = 0; 1879 int netnsid = -1; | 1927 struct net *net = sock_net(skb->sk); 1928 struct net *tgt_net = net; 1929 int h, s_h; 1930 int idx = 0, s_idx; 1931 struct net_device *dev; 1932 struct hlist_head *head; 1933 struct nlattr *tb[IFLA_MAX+1]; 1934 u32 ext_filter_mask = 0; 1935 const struct rtnl_link_ops *kind_ops = NULL; 1936 unsigned int flags = NLM_F_MULTI; 1937 int master_idx = 0; 1938 int netnsid = -1; |
1880 int err; 1881 int hdrlen; | 1939 int err, i; |
1882 1883 s_h = cb->args[0]; 1884 s_idx = cb->args[1]; 1885 | 1940 1941 s_h = cb->args[0]; 1942 s_idx = cb->args[1]; 1943 |
1886 /* A hack to preserve kernel<->userspace interface. 1887 * The correct header is ifinfomsg. It is consistent with rtnl_getlink. 1888 * However, before Linux v3.9 the code here assumed rtgenmsg and that's 1889 * what iproute2 < v3.9.0 used. 1890 * We can detect the old iproute2. Even including the IFLA_EXT_MASK 1891 * attribute, its netlink message is shorter than struct ifinfomsg. 1892 */ 1893 hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ? 1894 sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); | 1944 err = rtnl_valid_dump_ifinfo_req(nlh, cb->strict_check, tb, extack); 1945 if (err < 0) { 1946 if (cb->strict_check) 1947 return err; |
1895 | 1948 |
1896 if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, 1897 ifla_policy, NULL) >= 0) { 1898 if (tb[IFLA_IF_NETNSID]) { 1899 netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); 1900 tgt_net = get_target_net(skb->sk, netnsid); 1901 if (IS_ERR(tgt_net)) 1902 return PTR_ERR(tgt_net); 1903 } | 1949 goto walk_entries; 1950 } |
1904 | 1951 |
1905 if (tb[IFLA_EXT_MASK]) 1906 ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); | 1952 for (i = 0; i <= IFLA_MAX; ++i) { 1953 if (!tb[i]) 1954 continue; |
1907 | 1955 |
1908 if (tb[IFLA_MASTER]) 1909 master_idx = nla_get_u32(tb[IFLA_MASTER]); 1910 1911 if (tb[IFLA_LINKINFO]) 1912 kind_ops = linkinfo_to_kind_ops(tb[IFLA_LINKINFO]); 1913 1914 if (master_idx || kind_ops) 1915 flags |= NLM_F_DUMP_FILTERED; | 1956 /* new attributes should only be added with strict checking */ 1957 switch (i) { 1958 case IFLA_TARGET_NETNSID: 1959 netnsid = nla_get_s32(tb[i]); 1960 tgt_net = rtnl_get_net_ns_capable(skb->sk, netnsid); 1961 if (IS_ERR(tgt_net)) { 1962 NL_SET_ERR_MSG(extack, "Invalid target network namespace id"); 1963 return PTR_ERR(tgt_net); 1964 } 1965 break; 1966 case IFLA_EXT_MASK: 1967 ext_filter_mask = nla_get_u32(tb[i]); 1968 break; 1969 case IFLA_MASTER: 1970 master_idx = nla_get_u32(tb[i]); 1971 break; 1972 case IFLA_LINKINFO: 1973 kind_ops = linkinfo_to_kind_ops(tb[i]); 1974 break; 1975 default: 1976 if (cb->strict_check) { 1977 NL_SET_ERR_MSG(extack, "Unsupported attribute in link dump request"); 1978 return -EINVAL; 1979 } 1980 } |
1916 } 1917 | 1981 } 1982 |
1983 if (master_idx || kind_ops) 1984 flags |= NLM_F_DUMP_FILTERED; 1985 1986walk_entries: |
|
1918 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 1919 idx = 0; 1920 head = &tgt_net->dev_index_head[h]; 1921 hlist_for_each_entry(dev, head, index_hlist) { 1922 if (link_dump_filtered(dev, master_idx, kind_ops)) 1923 goto cont; 1924 if (idx < s_idx) 1925 goto cont; 1926 err = rtnl_fill_ifinfo(skb, dev, net, 1927 RTM_NEWLINK, 1928 NETLINK_CB(cb->skb).portid, | 1987 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 1988 idx = 0; 1989 head = &tgt_net->dev_index_head[h]; 1990 hlist_for_each_entry(dev, head, index_hlist) { 1991 if (link_dump_filtered(dev, master_idx, kind_ops)) 1992 goto cont; 1993 if (idx < s_idx) 1994 goto cont; 1995 err = rtnl_fill_ifinfo(skb, dev, net, 1996 RTM_NEWLINK, 1997 NETLINK_CB(cb->skb).portid, |
1929 cb->nlh->nlmsg_seq, 0, 1930 flags, | 1998 nlh->nlmsg_seq, 0, flags, |
1931 ext_filter_mask, 0, NULL, 0, 1932 netnsid); 1933 1934 if (err < 0) { 1935 if (likely(skb->len)) 1936 goto out; 1937 1938 goto out_err; --- 38 unchanged lines hidden (view full) --- 1977} 1978EXPORT_SYMBOL(rtnl_link_get_net); 1979 1980/* Figure out which network namespace we are talking about by 1981 * examining the link attributes in the following order: 1982 * 1983 * 1. IFLA_NET_NS_PID 1984 * 2. IFLA_NET_NS_FD | 1999 ext_filter_mask, 0, NULL, 0, 2000 netnsid); 2001 2002 if (err < 0) { 2003 if (likely(skb->len)) 2004 goto out; 2005 2006 goto out_err; --- 38 unchanged lines hidden (view full) --- 2045} 2046EXPORT_SYMBOL(rtnl_link_get_net); 2047 2048/* Figure out which network namespace we are talking about by 2049 * examining the link attributes in the following order: 2050 * 2051 * 1. IFLA_NET_NS_PID 2052 * 2. IFLA_NET_NS_FD |
1985 * 3. IFLA_IF_NETNSID | 2053 * 3. IFLA_TARGET_NETNSID |
1986 */ 1987static struct net *rtnl_link_get_net_by_nlattr(struct net *src_net, 1988 struct nlattr *tb[]) 1989{ 1990 struct net *net; 1991 1992 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) 1993 return rtnl_link_get_net(src_net, tb); 1994 | 2054 */ 2055static struct net *rtnl_link_get_net_by_nlattr(struct net *src_net, 2056 struct nlattr *tb[]) 2057{ 2058 struct net *net; 2059 2060 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) 2061 return rtnl_link_get_net(src_net, tb); 2062 |
1995 if (!tb[IFLA_IF_NETNSID]) | 2063 if (!tb[IFLA_TARGET_NETNSID]) |
1996 return get_net(src_net); 1997 | 2064 return get_net(src_net); 2065 |
1998 net = get_net_ns_by_id(src_net, nla_get_u32(tb[IFLA_IF_NETNSID])); | 2066 net = get_net_ns_by_id(src_net, nla_get_u32(tb[IFLA_TARGET_NETNSID])); |
1999 if (!net) 2000 return ERR_PTR(-EINVAL); 2001 2002 return net; 2003} 2004 2005static struct net *rtnl_link_get_net_capable(const struct sk_buff *skb, 2006 struct net *src_net, --- 24 unchanged lines hidden (view full) --- 2031 if (netns_id_only) { 2032 if (!tb[IFLA_NET_NS_PID] && !tb[IFLA_NET_NS_FD]) 2033 return 0; 2034 2035 NL_SET_ERR_MSG(extack, "specified netns attribute not supported"); 2036 return -EOPNOTSUPP; 2037 } 2038 | 2067 if (!net) 2068 return ERR_PTR(-EINVAL); 2069 2070 return net; 2071} 2072 2073static struct net *rtnl_link_get_net_capable(const struct sk_buff *skb, 2074 struct net *src_net, --- 24 unchanged lines hidden (view full) --- 2099 if (netns_id_only) { 2100 if (!tb[IFLA_NET_NS_PID] && !tb[IFLA_NET_NS_FD]) 2101 return 0; 2102 2103 NL_SET_ERR_MSG(extack, "specified netns attribute not supported"); 2104 return -EOPNOTSUPP; 2105 } 2106 |
2039 if (tb[IFLA_IF_NETNSID] && (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD])) | 2107 if (tb[IFLA_TARGET_NETNSID] && (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD])) |
2040 goto invalid_attr; 2041 | 2108 goto invalid_attr; 2109 |
2042 if (tb[IFLA_NET_NS_PID] && (tb[IFLA_IF_NETNSID] || tb[IFLA_NET_NS_FD])) | 2110 if (tb[IFLA_NET_NS_PID] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_FD])) |
2043 goto invalid_attr; 2044 | 2111 goto invalid_attr; 2112 |
2045 if (tb[IFLA_NET_NS_FD] && (tb[IFLA_IF_NETNSID] || tb[IFLA_NET_NS_PID])) | 2113 if (tb[IFLA_NET_NS_FD] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_PID])) |
2046 goto invalid_attr; 2047 2048 return 0; 2049 2050invalid_attr: 2051 NL_SET_ERR_MSG(extack, "multiple netns identifying attributes specified"); 2052 return -EINVAL; 2053} --- 259 unchanged lines hidden (view full) --- 2313{ 2314 const struct net_device_ops *ops = dev->netdev_ops; 2315 int err; 2316 2317 err = validate_linkmsg(dev, tb); 2318 if (err < 0) 2319 return err; 2320 | 2114 goto invalid_attr; 2115 2116 return 0; 2117 2118invalid_attr: 2119 NL_SET_ERR_MSG(extack, "multiple netns identifying attributes specified"); 2120 return -EINVAL; 2121} --- 259 unchanged lines hidden (view full) --- 2381{ 2382 const struct net_device_ops *ops = dev->netdev_ops; 2383 int err; 2384 2385 err = validate_linkmsg(dev, tb); 2386 if (err < 0) 2387 return err; 2388 |
2321 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_IF_NETNSID]) { | 2389 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) { |
2322 struct net *net = rtnl_link_get_net_capable(skb, dev_net(dev), 2323 tb, CAP_NET_ADMIN); 2324 if (IS_ERR(net)) { 2325 err = PTR_ERR(net); 2326 goto errout; 2327 } 2328 2329 err = dev_change_net_namespace(dev, net, ifname); --- 426 unchanged lines hidden (view full) --- 2756 2757 err = rtnl_ensure_unique_netns(tb, extack, true); 2758 if (err < 0) 2759 return err; 2760 2761 if (tb[IFLA_IFNAME]) 2762 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 2763 | 2390 struct net *net = rtnl_link_get_net_capable(skb, dev_net(dev), 2391 tb, CAP_NET_ADMIN); 2392 if (IS_ERR(net)) { 2393 err = PTR_ERR(net); 2394 goto errout; 2395 } 2396 2397 err = dev_change_net_namespace(dev, net, ifname); --- 426 unchanged lines hidden (view full) --- 2824 2825 err = rtnl_ensure_unique_netns(tb, extack, true); 2826 if (err < 0) 2827 return err; 2828 2829 if (tb[IFLA_IFNAME]) 2830 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 2831 |
2764 if (tb[IFLA_IF_NETNSID]) { 2765 netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); 2766 tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid); | 2832 if (tb[IFLA_TARGET_NETNSID]) { 2833 netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]); 2834 tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid); |
2767 if (IS_ERR(tgt_net)) 2768 return PTR_ERR(tgt_net); 2769 } 2770 2771 err = -EINVAL; 2772 ifm = nlmsg_data(nlh); 2773 if (ifm->ifi_index > 0) 2774 dev = __dev_get_by_index(tgt_net, ifm->ifi_index); --- 397 unchanged lines hidden (view full) --- 3172 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack); 3173 if (err < 0) 3174 return err; 3175 3176 err = rtnl_ensure_unique_netns(tb, extack, true); 3177 if (err < 0) 3178 return err; 3179 | 2835 if (IS_ERR(tgt_net)) 2836 return PTR_ERR(tgt_net); 2837 } 2838 2839 err = -EINVAL; 2840 ifm = nlmsg_data(nlh); 2841 if (ifm->ifi_index > 0) 2842 dev = __dev_get_by_index(tgt_net, ifm->ifi_index); --- 397 unchanged lines hidden (view full) --- 3240 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack); 3241 if (err < 0) 3242 return err; 3243 3244 err = rtnl_ensure_unique_netns(tb, extack, true); 3245 if (err < 0) 3246 return err; 3247 |
3180 if (tb[IFLA_IF_NETNSID]) { 3181 netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); 3182 tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid); | 3248 if (tb[IFLA_TARGET_NETNSID]) { 3249 netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]); 3250 tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid); |
3183 if (IS_ERR(tgt_net)) 3184 return PTR_ERR(tgt_net); 3185 } 3186 3187 if (tb[IFLA_IFNAME]) 3188 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 3189 3190 if (tb[IFLA_EXT_MASK]) --- 68 unchanged lines hidden (view full) --- 3259 3260 return nlmsg_total_size(min_ifinfo_dump_size); 3261} 3262 3263static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 3264{ 3265 int idx; 3266 int s_idx = cb->family; | 3251 if (IS_ERR(tgt_net)) 3252 return PTR_ERR(tgt_net); 3253 } 3254 3255 if (tb[IFLA_IFNAME]) 3256 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 3257 3258 if (tb[IFLA_EXT_MASK]) --- 68 unchanged lines hidden (view full) --- 3327 3328 return nlmsg_total_size(min_ifinfo_dump_size); 3329} 3330 3331static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 3332{ 3333 int idx; 3334 int s_idx = cb->family; |
3335 int type = cb->nlh->nlmsg_type - RTM_BASE; |
|
3267 3268 if (s_idx == 0) 3269 s_idx = 1; 3270 3271 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { 3272 struct rtnl_link **tab; | 3336 3337 if (s_idx == 0) 3338 s_idx = 1; 3339 3340 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { 3341 struct rtnl_link **tab; |
3273 int type = cb->nlh->nlmsg_type-RTM_BASE; | |
3274 struct rtnl_link *link; 3275 rtnl_dumpit_func dumpit; 3276 3277 if (idx < s_idx || idx == PF_PACKET) 3278 continue; 3279 3280 if (type < 0 || type >= RTM_NR_MSGTYPES) 3281 continue; --- 444 unchanged lines hidden (view full) --- 3726 goto out; 3727 err = nlmsg_populate_fdb(skb, cb, dev, idx, &dev->mc); 3728out: 3729 netif_addr_unlock_bh(dev); 3730 return err; 3731} 3732EXPORT_SYMBOL(ndo_dflt_fdb_dump); 3733 | 3342 struct rtnl_link *link; 3343 rtnl_dumpit_func dumpit; 3344 3345 if (idx < s_idx || idx == PF_PACKET) 3346 continue; 3347 3348 if (type < 0 || type >= RTM_NR_MSGTYPES) 3349 continue; --- 444 unchanged lines hidden (view full) --- 3794 goto out; 3795 err = nlmsg_populate_fdb(skb, cb, dev, idx, &dev->mc); 3796out: 3797 netif_addr_unlock_bh(dev); 3798 return err; 3799} 3800EXPORT_SYMBOL(ndo_dflt_fdb_dump); 3801 |
3734static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) | 3802static int valid_fdb_dump_strict(const struct nlmsghdr *nlh, 3803 int *br_idx, int *brport_idx, 3804 struct netlink_ext_ack *extack) |
3735{ | 3805{ |
3736 struct net_device *dev; | 3806 struct nlattr *tb[NDA_MAX + 1]; 3807 struct ndmsg *ndm; 3808 int err, i; 3809 3810 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) { 3811 NL_SET_ERR_MSG(extack, "Invalid header for fdb dump request"); 3812 return -EINVAL; 3813 } 3814 3815 ndm = nlmsg_data(nlh); 3816 if (ndm->ndm_pad1 || ndm->ndm_pad2 || ndm->ndm_state || 3817 ndm->ndm_flags || ndm->ndm_type) { 3818 NL_SET_ERR_MSG(extack, "Invalid values in header for fbd dump request"); 3819 return -EINVAL; 3820 } 3821 3822 err = nlmsg_parse_strict(nlh, sizeof(struct ndmsg), tb, NDA_MAX, 3823 NULL, extack); 3824 if (err < 0) 3825 return err; 3826 3827 *brport_idx = ndm->ndm_ifindex; 3828 for (i = 0; i <= NDA_MAX; ++i) { 3829 if (!tb[i]) 3830 continue; 3831 3832 switch (i) { 3833 case NDA_IFINDEX: 3834 if (nla_len(tb[i]) != sizeof(u32)) { 3835 NL_SET_ERR_MSG(extack, "Invalid IFINDEX attribute in fdb dump request"); 3836 return -EINVAL; 3837 } 3838 *brport_idx = nla_get_u32(tb[NDA_IFINDEX]); 3839 break; 3840 case NDA_MASTER: 3841 if (nla_len(tb[i]) != sizeof(u32)) { 3842 NL_SET_ERR_MSG(extack, "Invalid MASTER attribute in fdb dump request"); 3843 return -EINVAL; 3844 } 3845 *br_idx = nla_get_u32(tb[NDA_MASTER]); 3846 break; 3847 default: 3848 NL_SET_ERR_MSG(extack, "Unsupported attribute in fdb dump request"); 3849 return -EINVAL; 3850 } 3851 } 3852 3853 return 0; 3854} 3855 3856static int valid_fdb_dump_legacy(const struct nlmsghdr *nlh, 3857 int *br_idx, int *brport_idx, 3858 struct netlink_ext_ack *extack) 3859{ |
3737 struct nlattr *tb[IFLA_MAX+1]; | 3860 struct nlattr *tb[IFLA_MAX+1]; |
3738 struct net_device *br_dev = NULL; 3739 const struct net_device_ops *ops = NULL; 3740 const struct net_device_ops *cops = NULL; 3741 struct ifinfomsg *ifm = nlmsg_data(cb->nlh); 3742 struct net *net = sock_net(skb->sk); 3743 struct hlist_head *head; 3744 int brport_idx = 0; 3745 int br_idx = 0; 3746 int h, s_h; 3747 int idx = 0, s_idx; 3748 int err = 0; 3749 int fidx = 0; | 3861 int err; |
3750 3751 /* A hack to preserve kernel<->userspace interface. 3752 * Before Linux v4.12 this code accepted ndmsg since iproute2 v3.3.0. 3753 * However, ndmsg is shorter than ifinfomsg thus nlmsg_parse() bails. 3754 * So, check for ndmsg with an optional u32 attribute (not used here). 3755 * Fortunately these sizes don't conflict with the size of ifinfomsg 3756 * with an optional attribute. 3757 */ | 3862 3863 /* A hack to preserve kernel<->userspace interface. 3864 * Before Linux v4.12 this code accepted ndmsg since iproute2 v3.3.0. 3865 * However, ndmsg is shorter than ifinfomsg thus nlmsg_parse() bails. 3866 * So, check for ndmsg with an optional u32 attribute (not used here). 3867 * Fortunately these sizes don't conflict with the size of ifinfomsg 3868 * with an optional attribute. 3869 */ |
3758 if (nlmsg_len(cb->nlh) != sizeof(struct ndmsg) && 3759 (nlmsg_len(cb->nlh) != sizeof(struct ndmsg) + | 3870 if (nlmsg_len(nlh) != sizeof(struct ndmsg) && 3871 (nlmsg_len(nlh) != sizeof(struct ndmsg) + |
3760 nla_attr_size(sizeof(u32)))) { | 3872 nla_attr_size(sizeof(u32)))) { |
3761 err = nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, 3762 IFLA_MAX, ifla_policy, NULL); | 3873 struct ifinfomsg *ifm; 3874 3875 err = nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, 3876 ifla_policy, extack); |
3763 if (err < 0) { 3764 return -EINVAL; 3765 } else if (err == 0) { 3766 if (tb[IFLA_MASTER]) | 3877 if (err < 0) { 3878 return -EINVAL; 3879 } else if (err == 0) { 3880 if (tb[IFLA_MASTER]) |
3767 br_idx = nla_get_u32(tb[IFLA_MASTER]); | 3881 *br_idx = nla_get_u32(tb[IFLA_MASTER]); |
3768 } 3769 | 3882 } 3883 |
3770 brport_idx = ifm->ifi_index; | 3884 ifm = nlmsg_data(nlh); 3885 *brport_idx = ifm->ifi_index; |
3771 } | 3886 } |
3887 return 0; 3888} |
|
3772 | 3889 |
3890static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) 3891{ 3892 struct net_device *dev; 3893 struct net_device *br_dev = NULL; 3894 const struct net_device_ops *ops = NULL; 3895 const struct net_device_ops *cops = NULL; 3896 struct net *net = sock_net(skb->sk); 3897 struct hlist_head *head; 3898 int brport_idx = 0; 3899 int br_idx = 0; 3900 int h, s_h; 3901 int idx = 0, s_idx; 3902 int err = 0; 3903 int fidx = 0; 3904 3905 if (cb->strict_check) 3906 err = valid_fdb_dump_strict(cb->nlh, &br_idx, &brport_idx, 3907 cb->extack); 3908 else 3909 err = valid_fdb_dump_legacy(cb->nlh, &br_idx, &brport_idx, 3910 cb->extack); 3911 if (err < 0) 3912 return err; 3913 |
|
3773 if (br_idx) { 3774 br_dev = __dev_get_by_index(net, br_idx); 3775 if (!br_dev) 3776 return -ENODEV; 3777 3778 ops = br_dev->netdev_ops; 3779 } 3780 --- 167 unchanged lines hidden (view full) --- 3948 nlmsg_end(skb, nlh); 3949 return 0; 3950nla_put_failure: 3951 nlmsg_cancel(skb, nlh); 3952 return err ? err : -EMSGSIZE; 3953} 3954EXPORT_SYMBOL_GPL(ndo_dflt_bridge_getlink); 3955 | 3914 if (br_idx) { 3915 br_dev = __dev_get_by_index(net, br_idx); 3916 if (!br_dev) 3917 return -ENODEV; 3918 3919 ops = br_dev->netdev_ops; 3920 } 3921 --- 167 unchanged lines hidden (view full) --- 4089 nlmsg_end(skb, nlh); 4090 return 0; 4091nla_put_failure: 4092 nlmsg_cancel(skb, nlh); 4093 return err ? err : -EMSGSIZE; 4094} 4095EXPORT_SYMBOL_GPL(ndo_dflt_bridge_getlink); 4096 |
4097static int valid_bridge_getlink_req(const struct nlmsghdr *nlh, 4098 bool strict_check, u32 *filter_mask, 4099 struct netlink_ext_ack *extack) 4100{ 4101 struct nlattr *tb[IFLA_MAX+1]; 4102 int err, i; 4103 4104 if (strict_check) { 4105 struct ifinfomsg *ifm; 4106 4107 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) { 4108 NL_SET_ERR_MSG(extack, "Invalid header for bridge link dump"); 4109 return -EINVAL; 4110 } 4111 4112 ifm = nlmsg_data(nlh); 4113 if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags || 4114 ifm->ifi_change || ifm->ifi_index) { 4115 NL_SET_ERR_MSG(extack, "Invalid values in header for bridge link dump request"); 4116 return -EINVAL; 4117 } 4118 4119 err = nlmsg_parse_strict(nlh, sizeof(struct ifinfomsg), tb, 4120 IFLA_MAX, ifla_policy, extack); 4121 } else { 4122 err = nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, 4123 IFLA_MAX, ifla_policy, extack); 4124 } 4125 if (err < 0) 4126 return err; 4127 4128 /* new attributes should only be added with strict checking */ 4129 for (i = 0; i <= IFLA_MAX; ++i) { 4130 if (!tb[i]) 4131 continue; 4132 4133 switch (i) { 4134 case IFLA_EXT_MASK: 4135 *filter_mask = nla_get_u32(tb[i]); 4136 break; 4137 default: 4138 if (strict_check) { 4139 NL_SET_ERR_MSG(extack, "Unsupported attribute in bridge link dump request"); 4140 return -EINVAL; 4141 } 4142 } 4143 } 4144 4145 return 0; 4146} 4147 |
|
3956static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) 3957{ | 4148static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) 4149{ |
4150 const struct nlmsghdr *nlh = cb->nlh; |
|
3958 struct net *net = sock_net(skb->sk); 3959 struct net_device *dev; 3960 int idx = 0; 3961 u32 portid = NETLINK_CB(cb->skb).portid; | 4151 struct net *net = sock_net(skb->sk); 4152 struct net_device *dev; 4153 int idx = 0; 4154 u32 portid = NETLINK_CB(cb->skb).portid; |
3962 u32 seq = cb->nlh->nlmsg_seq; | 4155 u32 seq = nlh->nlmsg_seq; |
3963 u32 filter_mask = 0; 3964 int err; 3965 | 4156 u32 filter_mask = 0; 4157 int err; 4158 |
3966 if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) { 3967 struct nlattr *extfilt; | 4159 err = valid_bridge_getlink_req(nlh, cb->strict_check, &filter_mask, 4160 cb->extack); 4161 if (err < 0 && cb->strict_check) 4162 return err; |
3968 | 4163 |
3969 extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), 3970 IFLA_EXT_MASK); 3971 if (extfilt) { 3972 if (nla_len(extfilt) < sizeof(filter_mask)) 3973 return -EINVAL; 3974 3975 filter_mask = nla_get_u32(extfilt); 3976 } 3977 } 3978 | |
3979 rcu_read_lock(); 3980 for_each_netdev_rcu(net, dev) { 3981 const struct net_device_ops *ops = dev->netdev_ops; 3982 struct net_device *br_dev = netdev_master_upper_dev_get(dev); 3983 3984 if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { 3985 if (idx >= cb->args[0]) { 3986 err = br_dev->netdev_ops->ndo_bridge_getlink( --- 576 unchanged lines hidden (view full) --- 4563 err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid); 4564 } 4565 4566 return err; 4567} 4568 4569static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb) 4570{ | 4164 rcu_read_lock(); 4165 for_each_netdev_rcu(net, dev) { 4166 const struct net_device_ops *ops = dev->netdev_ops; 4167 struct net_device *br_dev = netdev_master_upper_dev_get(dev); 4168 4169 if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { 4170 if (idx >= cb->args[0]) { 4171 err = br_dev->netdev_ops->ndo_bridge_getlink( --- 576 unchanged lines hidden (view full) --- 4748 err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid); 4749 } 4750 4751 return err; 4752} 4753 4754static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb) 4755{ |
4756 struct netlink_ext_ack *extack = cb->extack; |
|
4571 int h, s_h, err, s_idx, s_idxattr, s_prividx; 4572 struct net *net = sock_net(skb->sk); 4573 unsigned int flags = NLM_F_MULTI; 4574 struct if_stats_msg *ifsm; 4575 struct hlist_head *head; 4576 struct net_device *dev; 4577 u32 filter_mask = 0; 4578 int idx = 0; 4579 4580 s_h = cb->args[0]; 4581 s_idx = cb->args[1]; 4582 s_idxattr = cb->args[2]; 4583 s_prividx = cb->args[3]; 4584 4585 cb->seq = net->dev_base_seq; 4586 | 4757 int h, s_h, err, s_idx, s_idxattr, s_prividx; 4758 struct net *net = sock_net(skb->sk); 4759 unsigned int flags = NLM_F_MULTI; 4760 struct if_stats_msg *ifsm; 4761 struct hlist_head *head; 4762 struct net_device *dev; 4763 u32 filter_mask = 0; 4764 int idx = 0; 4765 4766 s_h = cb->args[0]; 4767 s_idx = cb->args[1]; 4768 s_idxattr = cb->args[2]; 4769 s_prividx = cb->args[3]; 4770 4771 cb->seq = net->dev_base_seq; 4772 |
4587 if (nlmsg_len(cb->nlh) < sizeof(*ifsm)) | 4773 if (nlmsg_len(cb->nlh) < sizeof(*ifsm)) { 4774 NL_SET_ERR_MSG(extack, "Invalid header for stats dump"); |
4588 return -EINVAL; | 4775 return -EINVAL; |
4776 } |
|
4589 4590 ifsm = nlmsg_data(cb->nlh); | 4777 4778 ifsm = nlmsg_data(cb->nlh); |
4779 4780 /* only requests using NLM_F_DUMP_PROPER_HDR can pass data to 4781 * influence the dump. The legacy exception is filter_mask. 4782 */ 4783 if (cb->strict_check) { 4784 if (ifsm->pad1 || ifsm->pad2 || ifsm->ifindex) { 4785 NL_SET_ERR_MSG(extack, "Invalid values in header for stats dump request"); 4786 return -EINVAL; 4787 } 4788 if (nlmsg_attrlen(cb->nlh, sizeof(*ifsm))) { 4789 NL_SET_ERR_MSG(extack, "Invalid attributes after stats header"); 4790 return -EINVAL; 4791 } 4792 } 4793 |
|
4591 filter_mask = ifsm->filter_mask; | 4794 filter_mask = ifsm->filter_mask; |
4592 if (!filter_mask) | 4795 if (!filter_mask) { 4796 NL_SET_ERR_MSG(extack, "Filter mask must be set for stats dump"); |
4593 return -EINVAL; | 4797 return -EINVAL; |
4798 } |
|
4594 4595 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 4596 idx = 0; 4597 head = &net->dev_index_head[h]; 4598 hlist_for_each_entry(dev, head, index_hlist) { 4599 if (idx < s_idx) 4600 goto cont; 4601 err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS, --- 250 unchanged lines hidden --- | 4799 4800 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 4801 idx = 0; 4802 head = &net->dev_index_head[h]; 4803 hlist_for_each_entry(dev, head, index_hlist) { 4804 if (idx < s_idx) 4805 goto cont; 4806 err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS, --- 250 unchanged lines hidden --- |