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 ---