hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/net/core/rtnetlink.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * INET An implementation of the TCP/IP protocol suite for the LINUX
34 * operating system. INET is implemented using the BSD Socket
....@@ -6,11 +7,6 @@
67 * Routing netlink socket interface: protocol independent part.
78 *
89 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
9
- *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public License
12
- * as published by the Free Software Foundation; either version
13
- * 2 of the License, or (at your option) any later version.
1410 *
1511 * Fixes:
1612 * Vitaly E. Lavrov RTA_OK arithmetics was wrong.
....@@ -46,7 +42,6 @@
4642
4743 #include <linux/inet.h>
4844 #include <linux/netdevice.h>
49
-#include <net/switchdev.h>
5045 #include <net/ip.h>
5146 #include <net/protocol.h>
5247 #include <net/arp.h>
....@@ -59,7 +54,7 @@
5954 #include <net/rtnetlink.h>
6055 #include <net/net_namespace.h>
6156
62
-#define RTNL_MAX_TYPE 48
57
+#define RTNL_MAX_TYPE 50
6358 #define RTNL_SLAVE_MAX_TYPE 36
6459
6560 struct rtnl_link {
....@@ -635,7 +630,7 @@
635630 if (nla_put_string(skb, IFLA_INFO_SLAVE_KIND, ops->kind) < 0)
636631 return -EMSGSIZE;
637632 if (ops->fill_slave_info) {
638
- slave_data = nla_nest_start(skb, IFLA_INFO_SLAVE_DATA);
633
+ slave_data = nla_nest_start_noflag(skb, IFLA_INFO_SLAVE_DATA);
639634 if (!slave_data)
640635 return -EMSGSIZE;
641636 err = ops->fill_slave_info(skb, master_dev, dev);
....@@ -667,7 +662,7 @@
667662 return err;
668663 }
669664 if (ops->fill_info) {
670
- data = nla_nest_start(skb, IFLA_INFO_DATA);
665
+ data = nla_nest_start_noflag(skb, IFLA_INFO_DATA);
671666 if (data == NULL)
672667 return -EMSGSIZE;
673668 err = ops->fill_info(skb, dev);
....@@ -687,7 +682,7 @@
687682 struct nlattr *linkinfo;
688683 int err = -EMSGSIZE;
689684
690
- linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
685
+ linkinfo = nla_nest_start_noflag(skb, IFLA_LINKINFO);
691686 if (linkinfo == NULL)
692687 goto out;
693688
....@@ -756,7 +751,11 @@
756751 struct nlattr *mx;
757752 int i, valid = 0;
758753
759
- mx = nla_nest_start(skb, RTA_METRICS);
754
+ /* nothing is dumped for dst_default_metrics, so just skip the loop */
755
+ if (metrics == dst_default_metrics.metrics)
756
+ return 0;
757
+
758
+ mx = nla_nest_start_noflag(skb, RTA_METRICS);
760759 if (mx == NULL)
761760 return -ENOBUFS;
762761
....@@ -830,9 +829,16 @@
830829 switch (transition) {
831830 case IF_OPER_UP:
832831 if ((operstate == IF_OPER_DORMANT ||
832
+ operstate == IF_OPER_TESTING ||
833833 operstate == IF_OPER_UNKNOWN) &&
834
- !netif_dormant(dev))
834
+ !netif_dormant(dev) && !netif_testing(dev))
835835 operstate = IF_OPER_UP;
836
+ break;
837
+
838
+ case IF_OPER_TESTING:
839
+ if (operstate == IF_OPER_UP ||
840
+ operstate == IF_OPER_UNKNOWN)
841
+ operstate = IF_OPER_TESTING;
836842 break;
837843
838844 case IF_OPER_DORMANT:
....@@ -913,6 +919,7 @@
913919 size += num_vfs *
914920 (nla_total_size(0) +
915921 nla_total_size(sizeof(struct ifla_vf_mac)) +
922
+ nla_total_size(sizeof(struct ifla_vf_broadcast)) +
916923 nla_total_size(sizeof(struct ifla_vf_vlan)) +
917924 nla_total_size(0) + /* nest IFLA_VF_VLAN_LIST */
918925 nla_total_size(MAX_VLAN_LIST_LEN *
....@@ -980,6 +987,29 @@
980987 return xdp_size;
981988 }
982989
990
+static size_t rtnl_prop_list_size(const struct net_device *dev)
991
+{
992
+ struct netdev_name_node *name_node;
993
+ size_t size;
994
+
995
+ if (list_empty(&dev->name_node->list))
996
+ return 0;
997
+ size = nla_total_size(0);
998
+ list_for_each_entry(name_node, &dev->name_node->list, list)
999
+ size += nla_total_size(ALTIFNAMSIZ);
1000
+ return size;
1001
+}
1002
+
1003
+static size_t rtnl_proto_down_size(const struct net_device *dev)
1004
+{
1005
+ size_t size = nla_total_size(1);
1006
+
1007
+ if (dev->proto_down_reason)
1008
+ size += nla_total_size(0) + nla_total_size(4);
1009
+
1010
+ return size;
1011
+}
1012
+
9831013 static noinline size_t if_nlmsg_size(const struct net_device *dev,
9841014 u32 ext_filter_mask)
9851015 {
....@@ -1021,12 +1051,14 @@
10211051 + nla_total_size(4) /* IFLA_EVENT */
10221052 + nla_total_size(4) /* IFLA_NEW_NETNSID */
10231053 + nla_total_size(4) /* IFLA_NEW_IFINDEX */
1024
- + nla_total_size(1) /* IFLA_PROTO_DOWN */
1025
- + nla_total_size(4) /* IFLA_IF_NETNSID */
1054
+ + rtnl_proto_down_size(dev) /* proto down */
1055
+ + nla_total_size(4) /* IFLA_TARGET_NETNSID */
10261056 + nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */
10271057 + nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */
10281058 + nla_total_size(4) /* IFLA_MIN_MTU */
10291059 + nla_total_size(4) /* IFLA_MAX_MTU */
1060
+ + rtnl_prop_list_size(dev)
1061
+ + nla_total_size(MAX_ADDR_LEN) /* IFLA_PERM_ADDRESS */
10301062 + 0;
10311063 }
10321064
....@@ -1037,12 +1069,12 @@
10371069 int vf;
10381070 int err;
10391071
1040
- vf_ports = nla_nest_start(skb, IFLA_VF_PORTS);
1072
+ vf_ports = nla_nest_start_noflag(skb, IFLA_VF_PORTS);
10411073 if (!vf_ports)
10421074 return -EMSGSIZE;
10431075
10441076 for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) {
1045
- vf_port = nla_nest_start(skb, IFLA_VF_PORT);
1077
+ vf_port = nla_nest_start_noflag(skb, IFLA_VF_PORT);
10461078 if (!vf_port)
10471079 goto nla_put_failure;
10481080 if (nla_put_u32(skb, IFLA_PORT_VF, vf))
....@@ -1071,7 +1103,7 @@
10711103 struct nlattr *port_self;
10721104 int err;
10731105
1074
- port_self = nla_nest_start(skb, IFLA_PORT_SELF);
1106
+ port_self = nla_nest_start_noflag(skb, IFLA_PORT_SELF);
10751107 if (!port_self)
10761108 return -EMSGSIZE;
10771109
....@@ -1146,22 +1178,17 @@
11461178
11471179 static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
11481180 {
1181
+ struct netdev_phys_item_id ppid = { };
11491182 int err;
1150
- struct switchdev_attr attr = {
1151
- .orig_dev = dev,
1152
- .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
1153
- .flags = SWITCHDEV_F_NO_RECURSE,
1154
- };
11551183
1156
- err = switchdev_port_attr_get(dev, &attr);
1184
+ err = dev_get_port_parent_id(dev, &ppid, false);
11571185 if (err) {
11581186 if (err == -EOPNOTSUPP)
11591187 return 0;
11601188 return err;
11611189 }
11621190
1163
- if (nla_put(skb, IFLA_PHYS_SWITCH_ID, attr.u.ppid.id_len,
1164
- attr.u.ppid.id))
1191
+ if (nla_put(skb, IFLA_PHYS_SWITCH_ID, ppid.id_len, ppid.id))
11651192 return -EMSGSIZE;
11661193
11671194 return 0;
....@@ -1207,7 +1234,10 @@
12071234 struct ifla_vf_vlan vf_vlan;
12081235 struct ifla_vf_rate vf_rate;
12091236 struct ifla_vf_mac vf_mac;
1237
+ struct ifla_vf_broadcast vf_broadcast;
12101238 struct ifla_vf_info ivi;
1239
+ struct ifla_vf_guid node_guid;
1240
+ struct ifla_vf_guid port_guid;
12111241
12121242 memset(&ivi, 0, sizeof(ivi));
12131243
....@@ -1229,6 +1259,8 @@
12291259 return 0;
12301260
12311261 memset(&vf_vlan_info, 0, sizeof(vf_vlan_info));
1262
+ memset(&node_guid, 0, sizeof(node_guid));
1263
+ memset(&port_guid, 0, sizeof(port_guid));
12321264
12331265 vf_mac.vf =
12341266 vf_vlan.vf =
....@@ -1238,9 +1270,12 @@
12381270 vf_spoofchk.vf =
12391271 vf_linkstate.vf =
12401272 vf_rss_query_en.vf =
1241
- vf_trust.vf = ivi.vf;
1273
+ vf_trust.vf =
1274
+ node_guid.vf =
1275
+ port_guid.vf = ivi.vf;
12421276
12431277 memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
1278
+ memcpy(vf_broadcast.broadcast, dev->broadcast, dev->addr_len);
12441279 vf_vlan.vlan = ivi.vlan;
12451280 vf_vlan.qos = ivi.qos;
12461281 vf_vlan_info.vlan = ivi.vlan;
....@@ -1253,10 +1288,11 @@
12531288 vf_linkstate.link_state = ivi.linkstate;
12541289 vf_rss_query_en.setting = ivi.rss_query_en;
12551290 vf_trust.setting = ivi.trusted;
1256
- vf = nla_nest_start(skb, IFLA_VF_INFO);
1291
+ vf = nla_nest_start_noflag(skb, IFLA_VF_INFO);
12571292 if (!vf)
12581293 goto nla_put_vfinfo_failure;
12591294 if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
1295
+ nla_put(skb, IFLA_VF_BROADCAST, sizeof(vf_broadcast), &vf_broadcast) ||
12601296 nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
12611297 nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate),
12621298 &vf_rate) ||
....@@ -1272,7 +1308,17 @@
12721308 nla_put(skb, IFLA_VF_TRUST,
12731309 sizeof(vf_trust), &vf_trust))
12741310 goto nla_put_vf_failure;
1275
- vfvlanlist = nla_nest_start(skb, IFLA_VF_VLAN_LIST);
1311
+
1312
+ if (dev->netdev_ops->ndo_get_vf_guid &&
1313
+ !dev->netdev_ops->ndo_get_vf_guid(dev, vfs_num, &node_guid,
1314
+ &port_guid)) {
1315
+ if (nla_put(skb, IFLA_VF_IB_NODE_GUID, sizeof(node_guid),
1316
+ &node_guid) ||
1317
+ nla_put(skb, IFLA_VF_IB_PORT_GUID, sizeof(port_guid),
1318
+ &port_guid))
1319
+ goto nla_put_vf_failure;
1320
+ }
1321
+ vfvlanlist = nla_nest_start_noflag(skb, IFLA_VF_VLAN_LIST);
12761322 if (!vfvlanlist)
12771323 goto nla_put_vf_failure;
12781324 if (nla_put(skb, IFLA_VF_VLAN_INFO, sizeof(vf_vlan_info),
....@@ -1285,7 +1331,7 @@
12851331 if (dev->netdev_ops->ndo_get_vf_stats)
12861332 dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
12871333 &vf_stats);
1288
- vfstats = nla_nest_start(skb, IFLA_VF_STATS);
1334
+ vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
12891335 if (!vfstats)
12901336 goto nla_put_vf_failure;
12911337 if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
....@@ -1335,7 +1381,7 @@
13351381 if (!dev->netdev_ops->ndo_get_vf_config)
13361382 return 0;
13371383
1338
- vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
1384
+ vfinfo = nla_nest_start_noflag(skb, IFLA_VFINFO_LIST);
13391385 if (!vfinfo)
13401386 return -EMSGSIZE;
13411387
....@@ -1380,13 +1426,12 @@
13801426
13811427 static u32 rtnl_xdp_prog_drv(struct net_device *dev)
13821428 {
1383
- return __dev_xdp_query(dev, dev->netdev_ops->ndo_bpf, XDP_QUERY_PROG);
1429
+ return dev_xdp_prog_id(dev, XDP_MODE_DRV);
13841430 }
13851431
13861432 static u32 rtnl_xdp_prog_hw(struct net_device *dev)
13871433 {
1388
- return __dev_xdp_query(dev, dev->netdev_ops->ndo_bpf,
1389
- XDP_QUERY_PROG_HW);
1434
+ return dev_xdp_prog_id(dev, XDP_MODE_HW);
13901435 }
13911436
13921437 static int rtnl_xdp_report_one(struct sk_buff *skb, struct net_device *dev,
....@@ -1420,7 +1465,7 @@
14201465 int err;
14211466 u8 mode;
14221467
1423
- xdp = nla_nest_start(skb, IFLA_XDP);
1468
+ xdp = nla_nest_start_noflag(skb, IFLA_XDP);
14241469 if (!xdp)
14251470 return -EMSGSIZE;
14261471
....@@ -1552,7 +1597,7 @@
15521597 const struct rtnl_af_ops *af_ops;
15531598 struct nlattr *af_spec;
15541599
1555
- af_spec = nla_nest_start(skb, IFLA_AF_SPEC);
1600
+ af_spec = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
15561601 if (!af_spec)
15571602 return -EMSGSIZE;
15581603
....@@ -1563,7 +1608,7 @@
15631608 if (!af_ops->fill_link_af)
15641609 continue;
15651610
1566
- af = nla_nest_start(skb, af_ops->family);
1611
+ af = nla_nest_start_noflag(skb, af_ops->family);
15671612 if (!af)
15681613 return -EMSGSIZE;
15691614
....@@ -1586,6 +1631,71 @@
15861631 return 0;
15871632 }
15881633
1634
+static int rtnl_fill_alt_ifnames(struct sk_buff *skb,
1635
+ const struct net_device *dev)
1636
+{
1637
+ struct netdev_name_node *name_node;
1638
+ int count = 0;
1639
+
1640
+ list_for_each_entry(name_node, &dev->name_node->list, list) {
1641
+ if (nla_put_string(skb, IFLA_ALT_IFNAME, name_node->name))
1642
+ return -EMSGSIZE;
1643
+ count++;
1644
+ }
1645
+ return count;
1646
+}
1647
+
1648
+static int rtnl_fill_prop_list(struct sk_buff *skb,
1649
+ const struct net_device *dev)
1650
+{
1651
+ struct nlattr *prop_list;
1652
+ int ret;
1653
+
1654
+ prop_list = nla_nest_start(skb, IFLA_PROP_LIST);
1655
+ if (!prop_list)
1656
+ return -EMSGSIZE;
1657
+
1658
+ ret = rtnl_fill_alt_ifnames(skb, dev);
1659
+ if (ret <= 0)
1660
+ goto nest_cancel;
1661
+
1662
+ nla_nest_end(skb, prop_list);
1663
+ return 0;
1664
+
1665
+nest_cancel:
1666
+ nla_nest_cancel(skb, prop_list);
1667
+ return ret;
1668
+}
1669
+
1670
+static int rtnl_fill_proto_down(struct sk_buff *skb,
1671
+ const struct net_device *dev)
1672
+{
1673
+ struct nlattr *pr;
1674
+ u32 preason;
1675
+
1676
+ if (nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down))
1677
+ goto nla_put_failure;
1678
+
1679
+ preason = dev->proto_down_reason;
1680
+ if (!preason)
1681
+ return 0;
1682
+
1683
+ pr = nla_nest_start(skb, IFLA_PROTO_DOWN_REASON);
1684
+ if (!pr)
1685
+ return -EMSGSIZE;
1686
+
1687
+ if (nla_put_u32(skb, IFLA_PROTO_DOWN_REASON_VALUE, preason)) {
1688
+ nla_nest_cancel(skb, pr);
1689
+ goto nla_put_failure;
1690
+ }
1691
+
1692
+ nla_nest_end(skb, pr);
1693
+ return 0;
1694
+
1695
+nla_put_failure:
1696
+ return -EMSGSIZE;
1697
+}
1698
+
15891699 static int rtnl_fill_ifinfo(struct sk_buff *skb,
15901700 struct net_device *dev, struct net *src_net,
15911701 int type, u32 pid, u32 seq, u32 change,
....@@ -1595,6 +1705,7 @@
15951705 {
15961706 struct ifinfomsg *ifm;
15971707 struct nlmsghdr *nlh;
1708
+ struct Qdisc *qdisc;
15981709
15991710 ASSERT_RTNL();
16001711 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
....@@ -1609,9 +1720,10 @@
16091720 ifm->ifi_flags = dev_get_flags(dev);
16101721 ifm->ifi_change = change;
16111722
1612
- if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_IF_NETNSID, tgt_netnsid))
1723
+ if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_TARGET_NETNSID, tgt_netnsid))
16131724 goto nla_put_failure;
16141725
1726
+ qdisc = rtnl_dereference(dev->qdisc);
16151727 if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
16161728 nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) ||
16171729 nla_put_u8(skb, IFLA_OPERSTATE,
....@@ -1630,17 +1742,19 @@
16301742 #endif
16311743 put_master_ifindex(skb, dev) ||
16321744 nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
1633
- (dev->qdisc &&
1634
- nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
1745
+ (qdisc &&
1746
+ nla_put_string(skb, IFLA_QDISC, qdisc->ops->id)) ||
16351747 nla_put_ifalias(skb, dev) ||
16361748 nla_put_u32(skb, IFLA_CARRIER_CHANGES,
16371749 atomic_read(&dev->carrier_up_count) +
16381750 atomic_read(&dev->carrier_down_count)) ||
1639
- nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down) ||
16401751 nla_put_u32(skb, IFLA_CARRIER_UP_COUNT,
16411752 atomic_read(&dev->carrier_up_count)) ||
16421753 nla_put_u32(skb, IFLA_CARRIER_DOWN_COUNT,
16431754 atomic_read(&dev->carrier_down_count)))
1755
+ goto nla_put_failure;
1756
+
1757
+ if (rtnl_fill_proto_down(skb, dev))
16441758 goto nla_put_failure;
16451759
16461760 if (event != IFLA_EVENT_NONE) {
....@@ -1693,11 +1807,17 @@
16931807 nla_put_s32(skb, IFLA_NEW_IFINDEX, new_ifindex) < 0)
16941808 goto nla_put_failure;
16951809
1810
+ if (memchr_inv(dev->perm_addr, '\0', dev->addr_len) &&
1811
+ nla_put(skb, IFLA_PERM_ADDRESS, dev->addr_len, dev->perm_addr))
1812
+ goto nla_put_failure;
16961813
16971814 rcu_read_lock();
16981815 if (rtnl_fill_link_af(skb, dev, ext_filter_mask))
16991816 goto nla_put_failure_rcu;
17001817 rcu_read_unlock();
1818
+
1819
+ if (rtnl_fill_prop_list(skb, dev))
1820
+ goto nla_put_failure;
17011821
17021822 nlmsg_end(skb, nlh);
17031823 return 0;
....@@ -1747,11 +1867,16 @@
17471867 [IFLA_XDP] = { .type = NLA_NESTED },
17481868 [IFLA_EVENT] = { .type = NLA_U32 },
17491869 [IFLA_GROUP] = { .type = NLA_U32 },
1750
- [IFLA_IF_NETNSID] = { .type = NLA_S32 },
1870
+ [IFLA_TARGET_NETNSID] = { .type = NLA_S32 },
17511871 [IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 },
17521872 [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 },
17531873 [IFLA_MIN_MTU] = { .type = NLA_U32 },
17541874 [IFLA_MAX_MTU] = { .type = NLA_U32 },
1875
+ [IFLA_PROP_LIST] = { .type = NLA_NESTED },
1876
+ [IFLA_ALT_IFNAME] = { .type = NLA_STRING,
1877
+ .len = ALTIFNAMSIZ - 1 },
1878
+ [IFLA_PERM_ADDRESS] = { .type = NLA_REJECT },
1879
+ [IFLA_PROTO_DOWN_REASON] = { .type = NLA_NESTED },
17551880 };
17561881
17571882 static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
....@@ -1763,6 +1888,7 @@
17631888
17641889 static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
17651890 [IFLA_VF_MAC] = { .len = sizeof(struct ifla_vf_mac) },
1891
+ [IFLA_VF_BROADCAST] = { .type = NLA_REJECT },
17661892 [IFLA_VF_VLAN] = { .len = sizeof(struct ifla_vf_vlan) },
17671893 [IFLA_VF_VLAN_LIST] = { .type = NLA_NESTED },
17681894 [IFLA_VF_TX_RATE] = { .len = sizeof(struct ifla_vf_tx_rate) },
....@@ -1796,7 +1922,9 @@
17961922 };
17971923
17981924 static const struct nla_policy ifla_xdp_policy[IFLA_XDP_MAX + 1] = {
1925
+ [IFLA_XDP_UNSPEC] = { .strict_start_type = IFLA_XDP_EXPECTED_FD },
17991926 [IFLA_XDP_FD] = { .type = NLA_S32 },
1927
+ [IFLA_XDP_EXPECTED_FD] = { .type = NLA_S32 },
18001928 [IFLA_XDP_ATTACHED] = { .type = NLA_U8 },
18011929 [IFLA_XDP_FLAGS] = { .type = NLA_U32 },
18021930 [IFLA_XDP_PROG_ID] = { .type = NLA_U32 },
....@@ -1807,8 +1935,7 @@
18071935 const struct rtnl_link_ops *ops = NULL;
18081936 struct nlattr *linfo[IFLA_INFO_MAX + 1];
18091937
1810
- if (nla_parse_nested(linfo, IFLA_INFO_MAX, nla,
1811
- ifla_info_policy, NULL) < 0)
1938
+ if (nla_parse_nested_deprecated(linfo, IFLA_INFO_MAX, nla, ifla_info_policy, NULL) < 0)
18121939 return NULL;
18131940
18141941 if (linfo[IFLA_INFO_KIND]) {
....@@ -1855,7 +1982,15 @@
18551982 return false;
18561983 }
18571984
1858
-static struct net *get_target_net(struct sock *sk, int netnsid)
1985
+/**
1986
+ * rtnl_get_net_ns_capable - Get netns if sufficiently privileged.
1987
+ * @sk: netlink socket
1988
+ * @netnsid: network namespace identifier
1989
+ *
1990
+ * Returns the network namespace identified by netnsid on success or an error
1991
+ * pointer on failure.
1992
+ */
1993
+struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid)
18591994 {
18601995 struct net *net;
18611996
....@@ -1872,9 +2007,56 @@
18722007 }
18732008 return net;
18742009 }
2010
+EXPORT_SYMBOL_GPL(rtnl_get_net_ns_capable);
2011
+
2012
+static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh,
2013
+ bool strict_check, struct nlattr **tb,
2014
+ struct netlink_ext_ack *extack)
2015
+{
2016
+ int hdrlen;
2017
+
2018
+ if (strict_check) {
2019
+ struct ifinfomsg *ifm;
2020
+
2021
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
2022
+ NL_SET_ERR_MSG(extack, "Invalid header for link dump");
2023
+ return -EINVAL;
2024
+ }
2025
+
2026
+ ifm = nlmsg_data(nlh);
2027
+ if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
2028
+ ifm->ifi_change) {
2029
+ NL_SET_ERR_MSG(extack, "Invalid values in header for link dump request");
2030
+ return -EINVAL;
2031
+ }
2032
+ if (ifm->ifi_index) {
2033
+ NL_SET_ERR_MSG(extack, "Filter by device index not supported for link dumps");
2034
+ return -EINVAL;
2035
+ }
2036
+
2037
+ return nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb,
2038
+ IFLA_MAX, ifla_policy,
2039
+ extack);
2040
+ }
2041
+
2042
+ /* A hack to preserve kernel<->userspace interface.
2043
+ * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
2044
+ * However, before Linux v3.9 the code here assumed rtgenmsg and that's
2045
+ * what iproute2 < v3.9.0 used.
2046
+ * We can detect the old iproute2. Even including the IFLA_EXT_MASK
2047
+ * attribute, its netlink message is shorter than struct ifinfomsg.
2048
+ */
2049
+ hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ?
2050
+ sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
2051
+
2052
+ return nlmsg_parse_deprecated(nlh, hdrlen, tb, IFLA_MAX, ifla_policy,
2053
+ extack);
2054
+}
18752055
18762056 static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
18772057 {
2058
+ struct netlink_ext_ack *extack = cb->extack;
2059
+ const struct nlmsghdr *nlh = cb->nlh;
18782060 struct net *net = sock_net(skb->sk);
18792061 struct net *tgt_net = net;
18802062 int h, s_h;
....@@ -1887,44 +2069,54 @@
18872069 unsigned int flags = NLM_F_MULTI;
18882070 int master_idx = 0;
18892071 int netnsid = -1;
1890
- int err;
1891
- int hdrlen;
2072
+ int err, i;
18922073
18932074 s_h = cb->args[0];
18942075 s_idx = cb->args[1];
18952076
1896
- /* A hack to preserve kernel<->userspace interface.
1897
- * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
1898
- * However, before Linux v3.9 the code here assumed rtgenmsg and that's
1899
- * what iproute2 < v3.9.0 used.
1900
- * We can detect the old iproute2. Even including the IFLA_EXT_MASK
1901
- * attribute, its netlink message is shorter than struct ifinfomsg.
1902
- */
1903
- hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
1904
- sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
2077
+ err = rtnl_valid_dump_ifinfo_req(nlh, cb->strict_check, tb, extack);
2078
+ if (err < 0) {
2079
+ if (cb->strict_check)
2080
+ return err;
19052081
1906
- if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX,
1907
- ifla_policy, NULL) >= 0) {
1908
- if (tb[IFLA_IF_NETNSID]) {
1909
- netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]);
1910
- tgt_net = get_target_net(skb->sk, netnsid);
1911
- if (IS_ERR(tgt_net))
1912
- return PTR_ERR(tgt_net);
1913
- }
1914
-
1915
- if (tb[IFLA_EXT_MASK])
1916
- ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
1917
-
1918
- if (tb[IFLA_MASTER])
1919
- master_idx = nla_get_u32(tb[IFLA_MASTER]);
1920
-
1921
- if (tb[IFLA_LINKINFO])
1922
- kind_ops = linkinfo_to_kind_ops(tb[IFLA_LINKINFO]);
1923
-
1924
- if (master_idx || kind_ops)
1925
- flags |= NLM_F_DUMP_FILTERED;
2082
+ goto walk_entries;
19262083 }
19272084
2085
+ for (i = 0; i <= IFLA_MAX; ++i) {
2086
+ if (!tb[i])
2087
+ continue;
2088
+
2089
+ /* new attributes should only be added with strict checking */
2090
+ switch (i) {
2091
+ case IFLA_TARGET_NETNSID:
2092
+ netnsid = nla_get_s32(tb[i]);
2093
+ tgt_net = rtnl_get_net_ns_capable(skb->sk, netnsid);
2094
+ if (IS_ERR(tgt_net)) {
2095
+ NL_SET_ERR_MSG(extack, "Invalid target network namespace id");
2096
+ return PTR_ERR(tgt_net);
2097
+ }
2098
+ break;
2099
+ case IFLA_EXT_MASK:
2100
+ ext_filter_mask = nla_get_u32(tb[i]);
2101
+ break;
2102
+ case IFLA_MASTER:
2103
+ master_idx = nla_get_u32(tb[i]);
2104
+ break;
2105
+ case IFLA_LINKINFO:
2106
+ kind_ops = linkinfo_to_kind_ops(tb[i]);
2107
+ break;
2108
+ default:
2109
+ if (cb->strict_check) {
2110
+ NL_SET_ERR_MSG(extack, "Unsupported attribute in link dump request");
2111
+ return -EINVAL;
2112
+ }
2113
+ }
2114
+ }
2115
+
2116
+ if (master_idx || kind_ops)
2117
+ flags |= NLM_F_DUMP_FILTERED;
2118
+
2119
+walk_entries:
19282120 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
19292121 idx = 0;
19302122 head = &tgt_net->dev_index_head[h];
....@@ -1936,8 +2128,7 @@
19362128 err = rtnl_fill_ifinfo(skb, dev, net,
19372129 RTM_NEWLINK,
19382130 NETLINK_CB(cb->skb).portid,
1939
- cb->nlh->nlmsg_seq, 0,
1940
- flags,
2131
+ nlh->nlmsg_seq, 0, flags,
19412132 ext_filter_mask, 0, NULL, 0,
19422133 netnsid, GFP_KERNEL);
19432134
....@@ -1967,7 +2158,8 @@
19672158 int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
19682159 struct netlink_ext_ack *exterr)
19692160 {
1970
- return nla_parse(tb, IFLA_MAX, head, len, ifla_policy, exterr);
2161
+ return nla_parse_deprecated(tb, IFLA_MAX, head, len, ifla_policy,
2162
+ exterr);
19712163 }
19722164 EXPORT_SYMBOL(rtnl_nla_parse_ifla);
19732165
....@@ -1992,7 +2184,7 @@
19922184 *
19932185 * 1. IFLA_NET_NS_PID
19942186 * 2. IFLA_NET_NS_FD
1995
- * 3. IFLA_IF_NETNSID
2187
+ * 3. IFLA_TARGET_NETNSID
19962188 */
19972189 static struct net *rtnl_link_get_net_by_nlattr(struct net *src_net,
19982190 struct nlattr *tb[])
....@@ -2002,10 +2194,10 @@
20022194 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD])
20032195 return rtnl_link_get_net(src_net, tb);
20042196
2005
- if (!tb[IFLA_IF_NETNSID])
2197
+ if (!tb[IFLA_TARGET_NETNSID])
20062198 return get_net(src_net);
20072199
2008
- net = get_net_ns_by_id(src_net, nla_get_u32(tb[IFLA_IF_NETNSID]));
2200
+ net = get_net_ns_by_id(src_net, nla_get_u32(tb[IFLA_TARGET_NETNSID]));
20092201 if (!net)
20102202 return ERR_PTR(-EINVAL);
20112203
....@@ -2046,13 +2238,13 @@
20462238 return -EOPNOTSUPP;
20472239 }
20482240
2049
- if (tb[IFLA_IF_NETNSID] && (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]))
2241
+ if (tb[IFLA_TARGET_NETNSID] && (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]))
20502242 goto invalid_attr;
20512243
2052
- if (tb[IFLA_NET_NS_PID] && (tb[IFLA_IF_NETNSID] || tb[IFLA_NET_NS_FD]))
2244
+ if (tb[IFLA_NET_NS_PID] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_FD]))
20532245 goto invalid_attr;
20542246
2055
- if (tb[IFLA_NET_NS_FD] && (tb[IFLA_IF_NETNSID] || tb[IFLA_NET_NS_PID]))
2247
+ if (tb[IFLA_NET_NS_FD] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_PID]))
20562248 goto invalid_attr;
20572249
20582250 return 0;
....@@ -2334,6 +2526,67 @@
23342526 return 0;
23352527 }
23362528
2529
+static const struct nla_policy ifla_proto_down_reason_policy[IFLA_PROTO_DOWN_REASON_VALUE + 1] = {
2530
+ [IFLA_PROTO_DOWN_REASON_MASK] = { .type = NLA_U32 },
2531
+ [IFLA_PROTO_DOWN_REASON_VALUE] = { .type = NLA_U32 },
2532
+};
2533
+
2534
+static int do_set_proto_down(struct net_device *dev,
2535
+ struct nlattr *nl_proto_down,
2536
+ struct nlattr *nl_proto_down_reason,
2537
+ struct netlink_ext_ack *extack)
2538
+{
2539
+ struct nlattr *pdreason[IFLA_PROTO_DOWN_REASON_MAX + 1];
2540
+ const struct net_device_ops *ops = dev->netdev_ops;
2541
+ unsigned long mask = 0;
2542
+ u32 value;
2543
+ bool proto_down;
2544
+ int err;
2545
+
2546
+ if (!ops->ndo_change_proto_down) {
2547
+ NL_SET_ERR_MSG(extack, "Protodown not supported by device");
2548
+ return -EOPNOTSUPP;
2549
+ }
2550
+
2551
+ if (nl_proto_down_reason) {
2552
+ err = nla_parse_nested_deprecated(pdreason,
2553
+ IFLA_PROTO_DOWN_REASON_MAX,
2554
+ nl_proto_down_reason,
2555
+ ifla_proto_down_reason_policy,
2556
+ NULL);
2557
+ if (err < 0)
2558
+ return err;
2559
+
2560
+ if (!pdreason[IFLA_PROTO_DOWN_REASON_VALUE]) {
2561
+ NL_SET_ERR_MSG(extack, "Invalid protodown reason value");
2562
+ return -EINVAL;
2563
+ }
2564
+
2565
+ value = nla_get_u32(pdreason[IFLA_PROTO_DOWN_REASON_VALUE]);
2566
+
2567
+ if (pdreason[IFLA_PROTO_DOWN_REASON_MASK])
2568
+ mask = nla_get_u32(pdreason[IFLA_PROTO_DOWN_REASON_MASK]);
2569
+
2570
+ dev_change_proto_down_reason(dev, mask, value);
2571
+ }
2572
+
2573
+ if (nl_proto_down) {
2574
+ proto_down = nla_get_u8(nl_proto_down);
2575
+
2576
+ /* Dont turn off protodown if there are active reasons */
2577
+ if (!proto_down && dev->proto_down_reason) {
2578
+ NL_SET_ERR_MSG(extack, "Cannot clear protodown, active reasons");
2579
+ return -EBUSY;
2580
+ }
2581
+ err = dev_change_proto_down(dev,
2582
+ proto_down);
2583
+ if (err)
2584
+ return err;
2585
+ }
2586
+
2587
+ return 0;
2588
+}
2589
+
23372590 #define DO_SETLINK_MODIFIED 0x01
23382591 /* notify flag means notify + modified. */
23392592 #define DO_SETLINK_NOTIFY 0x03
....@@ -2349,7 +2602,8 @@
23492602 if (err < 0)
23502603 return err;
23512604
2352
- if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_IF_NETNSID]) {
2605
+ if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) {
2606
+ const char *pat = ifname && ifname[0] ? ifname : NULL;
23532607 struct net *net = rtnl_link_get_net_capable(skb, dev_net(dev),
23542608 tb, CAP_NET_ADMIN);
23552609 if (IS_ERR(net)) {
....@@ -2357,7 +2611,7 @@
23572611 goto errout;
23582612 }
23592613
2360
- err = dev_change_net_namespace(dev, net, ifname);
2614
+ err = dev_change_net_namespace(dev, net, pat);
23612615 put_net(net);
23622616 if (err)
23632617 goto errout;
....@@ -2407,7 +2661,7 @@
24072661 sa->sa_family = dev->type;
24082662 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
24092663 dev->addr_len);
2410
- err = dev_set_mac_address(dev, sa);
2664
+ err = dev_set_mac_address_user(dev, sa, extack);
24112665 kfree(sa);
24122666 if (err)
24132667 goto errout;
....@@ -2452,7 +2706,8 @@
24522706 }
24532707
24542708 if (ifm->ifi_flags || ifm->ifi_change) {
2455
- err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm));
2709
+ err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm),
2710
+ extack);
24562711 if (err < 0)
24572712 goto errout;
24582713 }
....@@ -2532,8 +2787,10 @@
25322787 err = -EINVAL;
25332788 goto errout;
25342789 }
2535
- err = nla_parse_nested(vfinfo, IFLA_VF_MAX, attr,
2536
- ifla_vf_policy, NULL);
2790
+ err = nla_parse_nested_deprecated(vfinfo, IFLA_VF_MAX,
2791
+ attr,
2792
+ ifla_vf_policy,
2793
+ NULL);
25372794 if (err < 0)
25382795 goto errout;
25392796 err = do_setvfinfo(dev, vfinfo);
....@@ -2560,8 +2817,10 @@
25602817 err = -EINVAL;
25612818 goto errout;
25622819 }
2563
- err = nla_parse_nested(port, IFLA_PORT_MAX, attr,
2564
- ifla_port_policy, NULL);
2820
+ err = nla_parse_nested_deprecated(port, IFLA_PORT_MAX,
2821
+ attr,
2822
+ ifla_port_policy,
2823
+ NULL);
25652824 if (err < 0)
25662825 goto errout;
25672826 if (!port[IFLA_PORT_VF]) {
....@@ -2580,9 +2839,9 @@
25802839 if (tb[IFLA_PORT_SELF]) {
25812840 struct nlattr *port[IFLA_PORT_MAX+1];
25822841
2583
- err = nla_parse_nested(port, IFLA_PORT_MAX,
2584
- tb[IFLA_PORT_SELF], ifla_port_policy,
2585
- NULL);
2842
+ err = nla_parse_nested_deprecated(port, IFLA_PORT_MAX,
2843
+ tb[IFLA_PORT_SELF],
2844
+ ifla_port_policy, NULL);
25862845 if (err < 0)
25872846 goto errout;
25882847
....@@ -2617,9 +2876,9 @@
26172876 }
26182877 err = 0;
26192878
2620
- if (tb[IFLA_PROTO_DOWN]) {
2621
- err = dev_change_proto_down(dev,
2622
- nla_get_u8(tb[IFLA_PROTO_DOWN]));
2879
+ if (tb[IFLA_PROTO_DOWN] || tb[IFLA_PROTO_DOWN_REASON]) {
2880
+ err = do_set_proto_down(dev, tb[IFLA_PROTO_DOWN],
2881
+ tb[IFLA_PROTO_DOWN_REASON], extack);
26232882 if (err)
26242883 goto errout;
26252884 status |= DO_SETLINK_NOTIFY;
....@@ -2629,8 +2888,9 @@
26292888 struct nlattr *xdp[IFLA_XDP_MAX + 1];
26302889 u32 xdp_flags = 0;
26312890
2632
- err = nla_parse_nested(xdp, IFLA_XDP_MAX, tb[IFLA_XDP],
2633
- ifla_xdp_policy, NULL);
2891
+ err = nla_parse_nested_deprecated(xdp, IFLA_XDP_MAX,
2892
+ tb[IFLA_XDP],
2893
+ ifla_xdp_policy, NULL);
26342894 if (err < 0)
26352895 goto errout;
26362896
....@@ -2652,8 +2912,20 @@
26522912 }
26532913
26542914 if (xdp[IFLA_XDP_FD]) {
2915
+ int expected_fd = -1;
2916
+
2917
+ if (xdp_flags & XDP_FLAGS_REPLACE) {
2918
+ if (!xdp[IFLA_XDP_EXPECTED_FD]) {
2919
+ err = -EINVAL;
2920
+ goto errout;
2921
+ }
2922
+ expected_fd =
2923
+ nla_get_s32(xdp[IFLA_XDP_EXPECTED_FD]);
2924
+ }
2925
+
26552926 err = dev_change_xdp_fd(dev, extack,
26562927 nla_get_s32(xdp[IFLA_XDP_FD]),
2928
+ expected_fd,
26572929 xdp_flags);
26582930 if (err)
26592931 goto errout;
....@@ -2674,6 +2946,26 @@
26742946 return err;
26752947 }
26762948
2949
+static struct net_device *rtnl_dev_get(struct net *net,
2950
+ struct nlattr *ifname_attr,
2951
+ struct nlattr *altifname_attr,
2952
+ char *ifname)
2953
+{
2954
+ char buffer[ALTIFNAMSIZ];
2955
+
2956
+ if (!ifname) {
2957
+ ifname = buffer;
2958
+ if (ifname_attr)
2959
+ nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
2960
+ else if (altifname_attr)
2961
+ nla_strlcpy(ifname, altifname_attr, ALTIFNAMSIZ);
2962
+ else
2963
+ return NULL;
2964
+ }
2965
+
2966
+ return __dev_get_by_name(net, ifname);
2967
+}
2968
+
26772969 static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
26782970 struct netlink_ext_ack *extack)
26792971 {
....@@ -2684,8 +2976,8 @@
26842976 struct nlattr *tb[IFLA_MAX+1];
26852977 char ifname[IFNAMSIZ];
26862978
2687
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy,
2688
- extack);
2979
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
2980
+ ifla_policy, extack);
26892981 if (err < 0)
26902982 goto errout;
26912983
....@@ -2702,8 +2994,8 @@
27022994 ifm = nlmsg_data(nlh);
27032995 if (ifm->ifi_index > 0)
27042996 dev = __dev_get_by_index(net, ifm->ifi_index);
2705
- else if (tb[IFLA_IFNAME])
2706
- dev = __dev_get_by_name(net, ifname);
2997
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
2998
+ dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
27072999 else
27083000 goto errout;
27093001
....@@ -2776,12 +3068,12 @@
27763068 struct net *tgt_net = net;
27773069 struct net_device *dev = NULL;
27783070 struct ifinfomsg *ifm;
2779
- char ifname[IFNAMSIZ];
27803071 struct nlattr *tb[IFLA_MAX+1];
27813072 int err;
27823073 int netnsid = -1;
27833074
2784
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
3075
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
3076
+ ifla_policy, extack);
27853077 if (err < 0)
27863078 return err;
27873079
....@@ -2789,12 +3081,9 @@
27893081 if (err < 0)
27903082 return err;
27913083
2792
- if (tb[IFLA_IFNAME])
2793
- nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
2794
-
2795
- if (tb[IFLA_IF_NETNSID]) {
2796
- netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]);
2797
- tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid);
3084
+ if (tb[IFLA_TARGET_NETNSID]) {
3085
+ netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]);
3086
+ tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
27983087 if (IS_ERR(tgt_net))
27993088 return PTR_ERR(tgt_net);
28003089 }
....@@ -2803,8 +3092,9 @@
28033092 ifm = nlmsg_data(nlh);
28043093 if (ifm->ifi_index > 0)
28053094 dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
2806
- else if (tb[IFLA_IFNAME])
2807
- dev = __dev_get_by_name(tgt_net, ifname);
3095
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
3096
+ dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
3097
+ tb[IFLA_ALT_IFNAME], NULL);
28083098 else if (tb[IFLA_GROUP])
28093099 err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP]));
28103100 else
....@@ -2833,7 +3123,8 @@
28333123
28343124 old_flags = dev->flags;
28353125 if (ifm && (ifm->ifi_flags || ifm->ifi_change)) {
2836
- err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm));
3126
+ err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm),
3127
+ NULL);
28373128 if (err < 0)
28383129 return err;
28393130 }
....@@ -2848,9 +3139,11 @@
28483139 }
28493140 EXPORT_SYMBOL(rtnl_configure_link);
28503141
2851
-struct net_device *rtnl_create_link(struct net *net,
2852
- const char *ifname, unsigned char name_assign_type,
2853
- const struct rtnl_link_ops *ops, struct nlattr *tb[])
3142
+struct net_device *rtnl_create_link(struct net *net, const char *ifname,
3143
+ unsigned char name_assign_type,
3144
+ const struct rtnl_link_ops *ops,
3145
+ struct nlattr *tb[],
3146
+ struct netlink_ext_ack *extack)
28543147 {
28553148 struct net_device *dev;
28563149 unsigned int num_tx_queues = 1;
....@@ -2866,11 +3159,15 @@
28663159 else if (ops->get_num_rx_queues)
28673160 num_rx_queues = ops->get_num_rx_queues();
28683161
2869
- if (num_tx_queues < 1 || num_tx_queues > 4096)
3162
+ if (num_tx_queues < 1 || num_tx_queues > 4096) {
3163
+ NL_SET_ERR_MSG(extack, "Invalid number of transmit queues");
28703164 return ERR_PTR(-EINVAL);
3165
+ }
28713166
2872
- if (num_rx_queues < 1 || num_rx_queues > 4096)
3167
+ if (num_rx_queues < 1 || num_rx_queues > 4096) {
3168
+ NL_SET_ERR_MSG(extack, "Invalid number of receive queues");
28733169 return ERR_PTR(-EINVAL);
3170
+ }
28743171
28753172 dev = alloc_netdev_mqs(ops->priv_size, ifname, name_assign_type,
28763173 ops->setup, num_tx_queues, num_rx_queues);
....@@ -2885,7 +3182,7 @@
28853182 u32 mtu = nla_get_u32(tb[IFLA_MTU]);
28863183 int err;
28873184
2888
- err = dev_validate_mtu(dev, mtu, NULL);
3185
+ err = dev_validate_mtu(dev, mtu, extack);
28893186 if (err) {
28903187 free_netdev(dev);
28913188 return ERR_PTR(err);
....@@ -2937,26 +3234,31 @@
29373234 return 0;
29383235 }
29393236
2940
-static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
2941
- struct netlink_ext_ack *extack)
3237
+static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3238
+ struct nlattr **attr, struct netlink_ext_ack *extack)
29423239 {
3240
+ struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1];
3241
+ unsigned char name_assign_type = NET_NAME_USER;
3242
+ struct nlattr *linkinfo[IFLA_INFO_MAX + 1];
3243
+ const struct rtnl_link_ops *m_ops;
3244
+ struct net_device *master_dev;
29433245 struct net *net = sock_net(skb->sk);
29443246 const struct rtnl_link_ops *ops;
2945
- const struct rtnl_link_ops *m_ops;
2946
- struct net_device *dev;
2947
- struct net_device *master_dev;
2948
- struct ifinfomsg *ifm;
3247
+ struct nlattr *tb[IFLA_MAX + 1];
3248
+ struct net *dest_net, *link_net;
3249
+ struct nlattr **slave_data;
29493250 char kind[MODULE_NAME_LEN];
3251
+ struct net_device *dev;
3252
+ struct ifinfomsg *ifm;
29503253 char ifname[IFNAMSIZ];
2951
- struct nlattr *tb[IFLA_MAX+1];
2952
- struct nlattr *linkinfo[IFLA_INFO_MAX+1];
2953
- unsigned char name_assign_type = NET_NAME_USER;
3254
+ struct nlattr **data;
29543255 int err;
29553256
29563257 #ifdef CONFIG_MODULES
29573258 replay:
29583259 #endif
2959
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
3260
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
3261
+ ifla_policy, extack);
29603262 if (err < 0)
29613263 return err;
29623264
....@@ -2972,12 +3274,10 @@
29723274 ifm = nlmsg_data(nlh);
29733275 if (ifm->ifi_index > 0)
29743276 dev = __dev_get_by_index(net, ifm->ifi_index);
2975
- else {
2976
- if (ifname[0])
2977
- dev = __dev_get_by_name(net, ifname);
2978
- else
2979
- dev = NULL;
2980
- }
3277
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
3278
+ dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
3279
+ else
3280
+ dev = NULL;
29813281
29823282 master_dev = NULL;
29833283 m_ops = NULL;
....@@ -2992,9 +3292,9 @@
29923292 return err;
29933293
29943294 if (tb[IFLA_LINKINFO]) {
2995
- err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
2996
- tb[IFLA_LINKINFO], ifla_info_policy,
2997
- NULL);
3295
+ err = nla_parse_nested_deprecated(linkinfo, IFLA_INFO_MAX,
3296
+ tb[IFLA_LINKINFO],
3297
+ ifla_info_policy, NULL);
29983298 if (err < 0)
29993299 return err;
30003300 } else
....@@ -3008,194 +3308,240 @@
30083308 ops = NULL;
30093309 }
30103310
3011
- if (1) {
3012
- struct nlattr *attr[RTNL_MAX_TYPE + 1];
3013
- struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1];
3014
- struct nlattr **data = NULL;
3015
- struct nlattr **slave_data = NULL;
3016
- struct net *dest_net, *link_net = NULL;
3311
+ data = NULL;
3312
+ if (ops) {
3313
+ if (ops->maxtype > RTNL_MAX_TYPE)
3314
+ return -EINVAL;
30173315
3018
- if (ops) {
3019
- if (ops->maxtype > RTNL_MAX_TYPE)
3020
- return -EINVAL;
3021
-
3022
- if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
3023
- err = nla_parse_nested(attr, ops->maxtype,
3024
- linkinfo[IFLA_INFO_DATA],
3025
- ops->policy, NULL);
3026
- if (err < 0)
3027
- return err;
3028
- data = attr;
3029
- }
3030
- if (ops->validate) {
3031
- err = ops->validate(tb, data, extack);
3032
- if (err < 0)
3033
- return err;
3034
- }
3316
+ if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
3317
+ err = nla_parse_nested_deprecated(attr, ops->maxtype,
3318
+ linkinfo[IFLA_INFO_DATA],
3319
+ ops->policy, extack);
3320
+ if (err < 0)
3321
+ return err;
3322
+ data = attr;
30353323 }
3036
-
3037
- if (m_ops) {
3038
- if (m_ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE)
3039
- return -EINVAL;
3040
-
3041
- if (m_ops->slave_maxtype &&
3042
- linkinfo[IFLA_INFO_SLAVE_DATA]) {
3043
- err = nla_parse_nested(slave_attr,
3044
- m_ops->slave_maxtype,
3045
- linkinfo[IFLA_INFO_SLAVE_DATA],
3046
- m_ops->slave_policy,
3047
- NULL);
3048
- if (err < 0)
3049
- return err;
3050
- slave_data = slave_attr;
3051
- }
3324
+ if (ops->validate) {
3325
+ err = ops->validate(tb, data, extack);
3326
+ if (err < 0)
3327
+ return err;
30523328 }
3329
+ }
30533330
3054
- if (dev) {
3055
- int status = 0;
3331
+ slave_data = NULL;
3332
+ if (m_ops) {
3333
+ if (m_ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE)
3334
+ return -EINVAL;
30563335
3057
- if (nlh->nlmsg_flags & NLM_F_EXCL)
3058
- return -EEXIST;
3059
- if (nlh->nlmsg_flags & NLM_F_REPLACE)
3336
+ if (m_ops->slave_maxtype &&
3337
+ linkinfo[IFLA_INFO_SLAVE_DATA]) {
3338
+ err = nla_parse_nested_deprecated(slave_attr,
3339
+ m_ops->slave_maxtype,
3340
+ linkinfo[IFLA_INFO_SLAVE_DATA],
3341
+ m_ops->slave_policy,
3342
+ extack);
3343
+ if (err < 0)
3344
+ return err;
3345
+ slave_data = slave_attr;
3346
+ }
3347
+ }
3348
+
3349
+ if (dev) {
3350
+ int status = 0;
3351
+
3352
+ if (nlh->nlmsg_flags & NLM_F_EXCL)
3353
+ return -EEXIST;
3354
+ if (nlh->nlmsg_flags & NLM_F_REPLACE)
3355
+ return -EOPNOTSUPP;
3356
+
3357
+ if (linkinfo[IFLA_INFO_DATA]) {
3358
+ if (!ops || ops != dev->rtnl_link_ops ||
3359
+ !ops->changelink)
30603360 return -EOPNOTSUPP;
30613361
3062
- if (linkinfo[IFLA_INFO_DATA]) {
3063
- if (!ops || ops != dev->rtnl_link_ops ||
3064
- !ops->changelink)
3065
- return -EOPNOTSUPP;
3066
-
3067
- err = ops->changelink(dev, tb, data, extack);
3068
- if (err < 0)
3069
- return err;
3070
- status |= DO_SETLINK_NOTIFY;
3071
- }
3072
-
3073
- if (linkinfo[IFLA_INFO_SLAVE_DATA]) {
3074
- if (!m_ops || !m_ops->slave_changelink)
3075
- return -EOPNOTSUPP;
3076
-
3077
- err = m_ops->slave_changelink(master_dev, dev,
3078
- tb, slave_data,
3079
- extack);
3080
- if (err < 0)
3081
- return err;
3082
- status |= DO_SETLINK_NOTIFY;
3083
- }
3084
-
3085
- return do_setlink(skb, dev, ifm, extack, tb, ifname,
3086
- status);
3362
+ err = ops->changelink(dev, tb, data, extack);
3363
+ if (err < 0)
3364
+ return err;
3365
+ status |= DO_SETLINK_NOTIFY;
30873366 }
30883367
3089
- if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
3090
- if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
3091
- return rtnl_group_changelink(skb, net,
3368
+ if (linkinfo[IFLA_INFO_SLAVE_DATA]) {
3369
+ if (!m_ops || !m_ops->slave_changelink)
3370
+ return -EOPNOTSUPP;
3371
+
3372
+ err = m_ops->slave_changelink(master_dev, dev, tb,
3373
+ slave_data, extack);
3374
+ if (err < 0)
3375
+ return err;
3376
+ status |= DO_SETLINK_NOTIFY;
3377
+ }
3378
+
3379
+ return do_setlink(skb, dev, ifm, extack, tb, ifname, status);
3380
+ }
3381
+
3382
+ if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
3383
+ if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
3384
+ return rtnl_group_changelink(skb, net,
30923385 nla_get_u32(tb[IFLA_GROUP]),
30933386 ifm, extack, tb);
3094
- return -ENODEV;
3095
- }
3387
+ return -ENODEV;
3388
+ }
30963389
3097
- if (tb[IFLA_MAP] || tb[IFLA_PROTINFO])
3098
- return -EOPNOTSUPP;
3390
+ if (tb[IFLA_MAP] || tb[IFLA_PROTINFO])
3391
+ return -EOPNOTSUPP;
30993392
3100
- if (!ops) {
3393
+ if (!ops) {
31013394 #ifdef CONFIG_MODULES
3102
- if (kind[0]) {
3103
- __rtnl_unlock();
3104
- request_module("rtnl-link-%s", kind);
3105
- rtnl_lock();
3106
- ops = rtnl_link_ops_get(kind);
3107
- if (ops)
3108
- goto replay;
3109
- }
3395
+ if (kind[0]) {
3396
+ __rtnl_unlock();
3397
+ request_module("rtnl-link-%s", kind);
3398
+ rtnl_lock();
3399
+ ops = rtnl_link_ops_get(kind);
3400
+ if (ops)
3401
+ goto replay;
3402
+ }
31103403 #endif
3111
- return -EOPNOTSUPP;
3112
- }
3404
+ NL_SET_ERR_MSG(extack, "Unknown device type");
3405
+ return -EOPNOTSUPP;
3406
+ }
31133407
3114
- if (!ops->setup)
3115
- return -EOPNOTSUPP;
3408
+ if (!ops->setup)
3409
+ return -EOPNOTSUPP;
31163410
3117
- if (!ifname[0]) {
3118
- snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
3119
- name_assign_type = NET_NAME_ENUM;
3120
- }
3411
+ if (!ifname[0]) {
3412
+ snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
3413
+ name_assign_type = NET_NAME_ENUM;
3414
+ }
31213415
3122
- dest_net = rtnl_link_get_net_capable(skb, net, tb, CAP_NET_ADMIN);
3123
- if (IS_ERR(dest_net))
3124
- return PTR_ERR(dest_net);
3416
+ dest_net = rtnl_link_get_net_capable(skb, net, tb, CAP_NET_ADMIN);
3417
+ if (IS_ERR(dest_net))
3418
+ return PTR_ERR(dest_net);
31253419
3126
- if (tb[IFLA_LINK_NETNSID]) {
3127
- int id = nla_get_s32(tb[IFLA_LINK_NETNSID]);
3420
+ if (tb[IFLA_LINK_NETNSID]) {
3421
+ int id = nla_get_s32(tb[IFLA_LINK_NETNSID]);
31283422
3129
- link_net = get_net_ns_by_id(dest_net, id);
3130
- if (!link_net) {
3131
- err = -EINVAL;
3132
- goto out;
3133
- }
3134
- err = -EPERM;
3135
- if (!netlink_ns_capable(skb, link_net->user_ns, CAP_NET_ADMIN))
3136
- goto out;
3137
- }
3138
-
3139
- dev = rtnl_create_link(link_net ? : dest_net, ifname,
3140
- name_assign_type, ops, tb);
3141
- if (IS_ERR(dev)) {
3142
- err = PTR_ERR(dev);
3423
+ link_net = get_net_ns_by_id(dest_net, id);
3424
+ if (!link_net) {
3425
+ NL_SET_ERR_MSG(extack, "Unknown network namespace id");
3426
+ err = -EINVAL;
31433427 goto out;
31443428 }
3429
+ err = -EPERM;
3430
+ if (!netlink_ns_capable(skb, link_net->user_ns, CAP_NET_ADMIN))
3431
+ goto out;
3432
+ } else {
3433
+ link_net = NULL;
3434
+ }
31453435
3146
- dev->ifindex = ifm->ifi_index;
3147
-
3148
- if (ops->newlink) {
3149
- err = ops->newlink(link_net ? : net, dev, tb, data,
3150
- extack);
3151
- /* Drivers should call free_netdev() in ->destructor
3152
- * and unregister it on failure after registration
3153
- * so that device could be finally freed in rtnl_unlock.
3154
- */
3155
- if (err < 0) {
3156
- /* If device is not registered at all, free it now */
3157
- if (dev->reg_state == NETREG_UNINITIALIZED ||
3158
- dev->reg_state == NETREG_UNREGISTERED)
3159
- free_netdev(dev);
3160
- goto out;
3161
- }
3162
- } else {
3163
- err = register_netdevice(dev);
3164
- if (err < 0) {
3165
- free_netdev(dev);
3166
- goto out;
3167
- }
3168
- }
3169
- err = rtnl_configure_link(dev, ifm);
3170
- if (err < 0)
3171
- goto out_unregister;
3172
- if (link_net) {
3173
- err = dev_change_net_namespace(dev, dest_net, ifname);
3174
- if (err < 0)
3175
- goto out_unregister;
3176
- }
3177
- if (tb[IFLA_MASTER]) {
3178
- err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]),
3179
- extack);
3180
- if (err)
3181
- goto out_unregister;
3182
- }
3183
-out:
3184
- if (link_net)
3185
- put_net(link_net);
3186
- put_net(dest_net);
3187
- return err;
3188
-out_unregister:
3189
- if (ops->newlink) {
3190
- LIST_HEAD(list_kill);
3191
-
3192
- ops->dellink(dev, &list_kill);
3193
- unregister_netdevice_many(&list_kill);
3194
- } else {
3195
- unregister_netdevice(dev);
3196
- }
3436
+ dev = rtnl_create_link(link_net ? : dest_net, ifname,
3437
+ name_assign_type, ops, tb, extack);
3438
+ if (IS_ERR(dev)) {
3439
+ err = PTR_ERR(dev);
31973440 goto out;
31983441 }
3442
+
3443
+ dev->ifindex = ifm->ifi_index;
3444
+
3445
+ if (ops->newlink)
3446
+ err = ops->newlink(link_net ? : net, dev, tb, data, extack);
3447
+ else
3448
+ err = register_netdevice(dev);
3449
+ if (err < 0) {
3450
+ free_netdev(dev);
3451
+ goto out;
3452
+ }
3453
+
3454
+ err = rtnl_configure_link(dev, ifm);
3455
+ if (err < 0)
3456
+ goto out_unregister;
3457
+ if (link_net) {
3458
+ err = dev_change_net_namespace(dev, dest_net, ifname);
3459
+ if (err < 0)
3460
+ goto out_unregister;
3461
+ }
3462
+ if (tb[IFLA_MASTER]) {
3463
+ err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack);
3464
+ if (err)
3465
+ goto out_unregister;
3466
+ }
3467
+out:
3468
+ if (link_net)
3469
+ put_net(link_net);
3470
+ put_net(dest_net);
3471
+ return err;
3472
+out_unregister:
3473
+ if (ops->newlink) {
3474
+ LIST_HEAD(list_kill);
3475
+
3476
+ ops->dellink(dev, &list_kill);
3477
+ unregister_netdevice_many(&list_kill);
3478
+ } else {
3479
+ unregister_netdevice(dev);
3480
+ }
3481
+ goto out;
3482
+}
3483
+
3484
+static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3485
+ struct netlink_ext_ack *extack)
3486
+{
3487
+ struct nlattr **attr;
3488
+ int ret;
3489
+
3490
+ attr = kmalloc_array(RTNL_MAX_TYPE + 1, sizeof(*attr), GFP_KERNEL);
3491
+ if (!attr)
3492
+ return -ENOMEM;
3493
+
3494
+ ret = __rtnl_newlink(skb, nlh, attr, extack);
3495
+ kfree(attr);
3496
+ return ret;
3497
+}
3498
+
3499
+static int rtnl_valid_getlink_req(struct sk_buff *skb,
3500
+ const struct nlmsghdr *nlh,
3501
+ struct nlattr **tb,
3502
+ struct netlink_ext_ack *extack)
3503
+{
3504
+ struct ifinfomsg *ifm;
3505
+ int i, err;
3506
+
3507
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
3508
+ NL_SET_ERR_MSG(extack, "Invalid header for get link");
3509
+ return -EINVAL;
3510
+ }
3511
+
3512
+ if (!netlink_strict_get_check(skb))
3513
+ return nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
3514
+ ifla_policy, extack);
3515
+
3516
+ ifm = nlmsg_data(nlh);
3517
+ if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
3518
+ ifm->ifi_change) {
3519
+ NL_SET_ERR_MSG(extack, "Invalid values in header for get link request");
3520
+ return -EINVAL;
3521
+ }
3522
+
3523
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb, IFLA_MAX,
3524
+ ifla_policy, extack);
3525
+ if (err)
3526
+ return err;
3527
+
3528
+ for (i = 0; i <= IFLA_MAX; i++) {
3529
+ if (!tb[i])
3530
+ continue;
3531
+
3532
+ switch (i) {
3533
+ case IFLA_IFNAME:
3534
+ case IFLA_ALT_IFNAME:
3535
+ case IFLA_EXT_MASK:
3536
+ case IFLA_TARGET_NETNSID:
3537
+ break;
3538
+ default:
3539
+ NL_SET_ERR_MSG(extack, "Unsupported attribute in get link request");
3540
+ return -EINVAL;
3541
+ }
3542
+ }
3543
+
3544
+ return 0;
31993545 }
32003546
32013547 static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
....@@ -3204,7 +3550,6 @@
32043550 struct net *net = sock_net(skb->sk);
32053551 struct net *tgt_net = net;
32063552 struct ifinfomsg *ifm;
3207
- char ifname[IFNAMSIZ];
32083553 struct nlattr *tb[IFLA_MAX+1];
32093554 struct net_device *dev = NULL;
32103555 struct sk_buff *nskb;
....@@ -3212,7 +3557,7 @@
32123557 int err;
32133558 u32 ext_filter_mask = 0;
32143559
3215
- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
3560
+ err = rtnl_valid_getlink_req(skb, nlh, tb, extack);
32163561 if (err < 0)
32173562 return err;
32183563
....@@ -3220,15 +3565,12 @@
32203565 if (err < 0)
32213566 return err;
32223567
3223
- if (tb[IFLA_IF_NETNSID]) {
3224
- netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]);
3225
- tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid);
3568
+ if (tb[IFLA_TARGET_NETNSID]) {
3569
+ netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]);
3570
+ tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
32263571 if (IS_ERR(tgt_net))
32273572 return PTR_ERR(tgt_net);
32283573 }
3229
-
3230
- if (tb[IFLA_IFNAME])
3231
- nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
32323574
32333575 if (tb[IFLA_EXT_MASK])
32343576 ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
....@@ -3237,8 +3579,9 @@
32373579 ifm = nlmsg_data(nlh);
32383580 if (ifm->ifi_index > 0)
32393581 dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
3240
- else if (tb[IFLA_IFNAME])
3241
- dev = __dev_get_by_name(tgt_net, ifname);
3582
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
3583
+ dev = rtnl_dev_get(tgt_net, tb[IFLA_IFNAME],
3584
+ tb[IFLA_ALT_IFNAME], NULL);
32423585 else
32433586 goto out;
32443587
....@@ -3268,20 +3611,123 @@
32683611 return err;
32693612 }
32703613
3271
-static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
3614
+static int rtnl_alt_ifname(int cmd, struct net_device *dev, struct nlattr *attr,
3615
+ bool *changed, struct netlink_ext_ack *extack)
3616
+{
3617
+ char *alt_ifname;
3618
+ size_t size;
3619
+ int err;
3620
+
3621
+ err = nla_validate(attr, attr->nla_len, IFLA_MAX, ifla_policy, extack);
3622
+ if (err)
3623
+ return err;
3624
+
3625
+ if (cmd == RTM_NEWLINKPROP) {
3626
+ size = rtnl_prop_list_size(dev);
3627
+ size += nla_total_size(ALTIFNAMSIZ);
3628
+ if (size >= U16_MAX) {
3629
+ NL_SET_ERR_MSG(extack,
3630
+ "effective property list too long");
3631
+ return -EINVAL;
3632
+ }
3633
+ }
3634
+
3635
+ alt_ifname = nla_strdup(attr, GFP_KERNEL_ACCOUNT);
3636
+ if (!alt_ifname)
3637
+ return -ENOMEM;
3638
+
3639
+ if (cmd == RTM_NEWLINKPROP) {
3640
+ err = netdev_name_node_alt_create(dev, alt_ifname);
3641
+ if (!err)
3642
+ alt_ifname = NULL;
3643
+ } else if (cmd == RTM_DELLINKPROP) {
3644
+ err = netdev_name_node_alt_destroy(dev, alt_ifname);
3645
+ } else {
3646
+ WARN_ON_ONCE(1);
3647
+ err = -EINVAL;
3648
+ }
3649
+
3650
+ kfree(alt_ifname);
3651
+ if (!err)
3652
+ *changed = true;
3653
+ return err;
3654
+}
3655
+
3656
+static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh,
3657
+ struct netlink_ext_ack *extack)
32723658 {
32733659 struct net *net = sock_net(skb->sk);
3660
+ struct nlattr *tb[IFLA_MAX + 1];
32743661 struct net_device *dev;
3662
+ struct ifinfomsg *ifm;
3663
+ bool changed = false;
3664
+ struct nlattr *attr;
3665
+ int err, rem;
3666
+
3667
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
3668
+ if (err)
3669
+ return err;
3670
+
3671
+ err = rtnl_ensure_unique_netns(tb, extack, true);
3672
+ if (err)
3673
+ return err;
3674
+
3675
+ ifm = nlmsg_data(nlh);
3676
+ if (ifm->ifi_index > 0)
3677
+ dev = __dev_get_by_index(net, ifm->ifi_index);
3678
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
3679
+ dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
3680
+ tb[IFLA_ALT_IFNAME], NULL);
3681
+ else
3682
+ return -EINVAL;
3683
+
3684
+ if (!dev)
3685
+ return -ENODEV;
3686
+
3687
+ if (!tb[IFLA_PROP_LIST])
3688
+ return 0;
3689
+
3690
+ nla_for_each_nested(attr, tb[IFLA_PROP_LIST], rem) {
3691
+ switch (nla_type(attr)) {
3692
+ case IFLA_ALT_IFNAME:
3693
+ err = rtnl_alt_ifname(cmd, dev, attr, &changed, extack);
3694
+ if (err)
3695
+ return err;
3696
+ break;
3697
+ }
3698
+ }
3699
+
3700
+ if (changed)
3701
+ netdev_state_change(dev);
3702
+ return 0;
3703
+}
3704
+
3705
+static int rtnl_newlinkprop(struct sk_buff *skb, struct nlmsghdr *nlh,
3706
+ struct netlink_ext_ack *extack)
3707
+{
3708
+ return rtnl_linkprop(RTM_NEWLINKPROP, skb, nlh, extack);
3709
+}
3710
+
3711
+static int rtnl_dellinkprop(struct sk_buff *skb, struct nlmsghdr *nlh,
3712
+ struct netlink_ext_ack *extack)
3713
+{
3714
+ return rtnl_linkprop(RTM_DELLINKPROP, skb, nlh, extack);
3715
+}
3716
+
3717
+static u32 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
3718
+{
3719
+ struct net *net = sock_net(skb->sk);
3720
+ size_t min_ifinfo_dump_size = 0;
32753721 struct nlattr *tb[IFLA_MAX+1];
32763722 u32 ext_filter_mask = 0;
3277
- u16 min_ifinfo_dump_size = 0;
3723
+ struct net_device *dev;
32783724 int hdrlen;
32793725
32803726 /* Same kernel<->userspace interface hack as in rtnl_dump_ifinfo. */
32813727 hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ?
32823728 sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
32833729
3284
- if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy, NULL) >= 0) {
3730
+ if (nlmsg_parse_deprecated(nlh, hdrlen, tb, IFLA_MAX, ifla_policy, NULL) >= 0) {
32853731 if (tb[IFLA_EXT_MASK])
32863732 ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
32873733 }
....@@ -3294,9 +3740,8 @@
32943740 */
32953741 rcu_read_lock();
32963742 for_each_netdev_rcu(net, dev) {
3297
- min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
3298
- if_nlmsg_size(dev,
3299
- ext_filter_mask));
3743
+ min_ifinfo_dump_size = max(min_ifinfo_dump_size,
3744
+ if_nlmsg_size(dev, ext_filter_mask));
33003745 }
33013746 rcu_read_unlock();
33023747
....@@ -3308,6 +3753,7 @@
33083753 int idx;
33093754 int s_idx = cb->family;
33103755 int type = cb->nlh->nlmsg_type - RTM_BASE;
3756
+ int ret = 0;
33113757
33123758 if (s_idx == 0)
33133759 s_idx = 1;
....@@ -3340,12 +3786,13 @@
33403786 cb->prev_seq = 0;
33413787 cb->seq = 0;
33423788 }
3343
- if (dumpit(skb, cb))
3789
+ ret = dumpit(skb, cb);
3790
+ if (ret)
33443791 break;
33453792 }
33463793 cb->family = idx;
33473794
3348
- return skb->len;
3795
+ return skb->len ? : ret;
33493796 }
33503797
33513798 struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
....@@ -3482,7 +3929,7 @@
34823929 rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
34833930 }
34843931
3485
-/**
3932
+/*
34863933 * ndo_dflt_fdb_add - default netdevice operation to add an FDB entry
34873934 */
34883935 int ndo_dflt_fdb_add(struct ndmsg *ndm,
....@@ -3552,116 +3999,8 @@
35523999 u16 vid;
35534000 int err;
35544001
3555
- err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, extack);
3556
- if (err < 0)
3557
- return err;
3558
-
3559
- ndm = nlmsg_data(nlh);
3560
- if (ndm->ndm_ifindex == 0) {
3561
- NL_SET_ERR_MSG(extack, "invalid ifindex");
3562
- return -EINVAL;
3563
- }
3564
-
3565
- dev = __dev_get_by_index(net, ndm->ndm_ifindex);
3566
- if (dev == NULL) {
3567
- NL_SET_ERR_MSG(extack, "unknown ifindex");
3568
- return -ENODEV;
3569
- }
3570
-
3571
- if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
3572
- NL_SET_ERR_MSG(extack, "invalid address");
3573
- return -EINVAL;
3574
- }
3575
-
3576
- if (dev->type != ARPHRD_ETHER) {
3577
- NL_SET_ERR_MSG(extack, "FDB delete only supported for Ethernet devices");
3578
- return -EINVAL;
3579
- }
3580
-
3581
- addr = nla_data(tb[NDA_LLADDR]);
3582
-
3583
- err = fdb_vid_parse(tb[NDA_VLAN], &vid, extack);
3584
- if (err)
3585
- return err;
3586
-
3587
- err = -EOPNOTSUPP;
3588
-
3589
- /* Support fdb on master device the net/bridge default case */
3590
- if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
3591
- (dev->priv_flags & IFF_BRIDGE_PORT)) {
3592
- struct net_device *br_dev = netdev_master_upper_dev_get(dev);
3593
- const struct net_device_ops *ops = br_dev->netdev_ops;
3594
-
3595
- err = ops->ndo_fdb_add(ndm, tb, dev, addr, vid,
3596
- nlh->nlmsg_flags);
3597
- if (err)
3598
- goto out;
3599
- else
3600
- ndm->ndm_flags &= ~NTF_MASTER;
3601
- }
3602
-
3603
- /* Embedded bridge, macvlan, and any other device support */
3604
- if ((ndm->ndm_flags & NTF_SELF)) {
3605
- if (dev->netdev_ops->ndo_fdb_add)
3606
- err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
3607
- vid,
3608
- nlh->nlmsg_flags);
3609
- else
3610
- err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
3611
- nlh->nlmsg_flags);
3612
-
3613
- if (!err) {
3614
- rtnl_fdb_notify(dev, addr, vid, RTM_NEWNEIGH,
3615
- ndm->ndm_state);
3616
- ndm->ndm_flags &= ~NTF_SELF;
3617
- }
3618
- }
3619
-out:
3620
- return err;
3621
-}
3622
-
3623
-/**
3624
- * ndo_dflt_fdb_del - default netdevice operation to delete an FDB entry
3625
- */
3626
-int ndo_dflt_fdb_del(struct ndmsg *ndm,
3627
- struct nlattr *tb[],
3628
- struct net_device *dev,
3629
- const unsigned char *addr, u16 vid)
3630
-{
3631
- int err = -EINVAL;
3632
-
3633
- /* If aging addresses are supported device will need to
3634
- * implement its own handler for this.
3635
- */
3636
- if (!(ndm->ndm_state & NUD_PERMANENT)) {
3637
- pr_info("%s: FDB only supports static addresses\n", dev->name);
3638
- return err;
3639
- }
3640
-
3641
- if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
3642
- err = dev_uc_del(dev, addr);
3643
- else if (is_multicast_ether_addr(addr))
3644
- err = dev_mc_del(dev, addr);
3645
-
3646
- return err;
3647
-}
3648
-EXPORT_SYMBOL(ndo_dflt_fdb_del);
3649
-
3650
-static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
3651
- struct netlink_ext_ack *extack)
3652
-{
3653
- struct net *net = sock_net(skb->sk);
3654
- struct ndmsg *ndm;
3655
- struct nlattr *tb[NDA_MAX+1];
3656
- struct net_device *dev;
3657
- int err = -EINVAL;
3658
- __u8 *addr;
3659
- u16 vid;
3660
-
3661
- if (!netlink_capable(skb, CAP_NET_ADMIN))
3662
- return -EPERM;
3663
-
3664
- err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, extack);
4002
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, NULL,
4003
+ extack);
36654004 if (err < 0)
36664005 return err;
36674006
....@@ -3697,7 +4036,118 @@
36974036
36984037 /* Support fdb on master device the net/bridge default case */
36994038 if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
3700
- (dev->priv_flags & IFF_BRIDGE_PORT)) {
4039
+ netif_is_bridge_port(dev)) {
4040
+ struct net_device *br_dev = netdev_master_upper_dev_get(dev);
4041
+ const struct net_device_ops *ops = br_dev->netdev_ops;
4042
+
4043
+ err = ops->ndo_fdb_add(ndm, tb, dev, addr, vid,
4044
+ nlh->nlmsg_flags, extack);
4045
+ if (err)
4046
+ goto out;
4047
+ else
4048
+ ndm->ndm_flags &= ~NTF_MASTER;
4049
+ }
4050
+
4051
+ /* Embedded bridge, macvlan, and any other device support */
4052
+ if ((ndm->ndm_flags & NTF_SELF)) {
4053
+ if (dev->netdev_ops->ndo_fdb_add)
4054
+ err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
4055
+ vid,
4056
+ nlh->nlmsg_flags,
4057
+ extack);
4058
+ else
4059
+ err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
4060
+ nlh->nlmsg_flags);
4061
+
4062
+ if (!err) {
4063
+ rtnl_fdb_notify(dev, addr, vid, RTM_NEWNEIGH,
4064
+ ndm->ndm_state);
4065
+ ndm->ndm_flags &= ~NTF_SELF;
4066
+ }
4067
+ }
4068
+out:
4069
+ return err;
4070
+}
4071
+
4072
+/*
4073
+ * ndo_dflt_fdb_del - default netdevice operation to delete an FDB entry
4074
+ */
4075
+int ndo_dflt_fdb_del(struct ndmsg *ndm,
4076
+ struct nlattr *tb[],
4077
+ struct net_device *dev,
4078
+ const unsigned char *addr, u16 vid)
4079
+{
4080
+ int err = -EINVAL;
4081
+
4082
+ /* If aging addresses are supported device will need to
4083
+ * implement its own handler for this.
4084
+ */
4085
+ if (!(ndm->ndm_state & NUD_PERMANENT)) {
4086
+ pr_info("%s: FDB only supports static addresses\n", dev->name);
4087
+ return err;
4088
+ }
4089
+
4090
+ if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
4091
+ err = dev_uc_del(dev, addr);
4092
+ else if (is_multicast_ether_addr(addr))
4093
+ err = dev_mc_del(dev, addr);
4094
+
4095
+ return err;
4096
+}
4097
+EXPORT_SYMBOL(ndo_dflt_fdb_del);
4098
+
4099
+static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
4100
+ struct netlink_ext_ack *extack)
4101
+{
4102
+ struct net *net = sock_net(skb->sk);
4103
+ struct ndmsg *ndm;
4104
+ struct nlattr *tb[NDA_MAX+1];
4105
+ struct net_device *dev;
4106
+ __u8 *addr;
4107
+ int err;
4108
+ u16 vid;
4109
+
4110
+ if (!netlink_capable(skb, CAP_NET_ADMIN))
4111
+ return -EPERM;
4112
+
4113
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, NULL,
4114
+ extack);
4115
+ if (err < 0)
4116
+ return err;
4117
+
4118
+ ndm = nlmsg_data(nlh);
4119
+ if (ndm->ndm_ifindex == 0) {
4120
+ NL_SET_ERR_MSG(extack, "invalid ifindex");
4121
+ return -EINVAL;
4122
+ }
4123
+
4124
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
4125
+ if (dev == NULL) {
4126
+ NL_SET_ERR_MSG(extack, "unknown ifindex");
4127
+ return -ENODEV;
4128
+ }
4129
+
4130
+ if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
4131
+ NL_SET_ERR_MSG(extack, "invalid address");
4132
+ return -EINVAL;
4133
+ }
4134
+
4135
+ if (dev->type != ARPHRD_ETHER) {
4136
+ NL_SET_ERR_MSG(extack, "FDB delete only supported for Ethernet devices");
4137
+ return -EINVAL;
4138
+ }
4139
+
4140
+ addr = nla_data(tb[NDA_LLADDR]);
4141
+
4142
+ err = fdb_vid_parse(tb[NDA_VLAN], &vid, extack);
4143
+ if (err)
4144
+ return err;
4145
+
4146
+ err = -EOPNOTSUPP;
4147
+
4148
+ /* Support fdb on master device the net/bridge default case */
4149
+ if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
4150
+ netif_is_bridge_port(dev)) {
37014151 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
37024152 const struct net_device_ops *ops = br_dev->netdev_ops;
37034153
....@@ -3759,8 +4209,11 @@
37594209
37604210 /**
37614211 * ndo_dflt_fdb_dump - default netdevice operation to dump an FDB table.
3762
- * @nlh: netlink message header
4212
+ * @skb: socket buffer to store message in
4213
+ * @cb: netlink callback
37634214 * @dev: netdevice
4215
+ * @filter_dev: ignored
4216
+ * @idx: the number of FDB table entries dumped is added to *@idx
37644217 *
37654218 * Default netdevice operation to dump the existing unicast address list.
37664219 * Returns number of addresses from list put in skb.
....@@ -3787,14 +4240,101 @@
37874240 }
37884241 EXPORT_SYMBOL(ndo_dflt_fdb_dump);
37894242
4243
+static int valid_fdb_dump_strict(const struct nlmsghdr *nlh,
4244
+ int *br_idx, int *brport_idx,
4245
+ struct netlink_ext_ack *extack)
4246
+{
4247
+ struct nlattr *tb[NDA_MAX + 1];
4248
+ struct ndmsg *ndm;
4249
+ int err, i;
4250
+
4251
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
4252
+ NL_SET_ERR_MSG(extack, "Invalid header for fdb dump request");
4253
+ return -EINVAL;
4254
+ }
4255
+
4256
+ ndm = nlmsg_data(nlh);
4257
+ if (ndm->ndm_pad1 || ndm->ndm_pad2 || ndm->ndm_state ||
4258
+ ndm->ndm_flags || ndm->ndm_type) {
4259
+ NL_SET_ERR_MSG(extack, "Invalid values in header for fdb dump request");
4260
+ return -EINVAL;
4261
+ }
4262
+
4263
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
4264
+ NDA_MAX, NULL, extack);
4265
+ if (err < 0)
4266
+ return err;
4267
+
4268
+ *brport_idx = ndm->ndm_ifindex;
4269
+ for (i = 0; i <= NDA_MAX; ++i) {
4270
+ if (!tb[i])
4271
+ continue;
4272
+
4273
+ switch (i) {
4274
+ case NDA_IFINDEX:
4275
+ if (nla_len(tb[i]) != sizeof(u32)) {
4276
+ NL_SET_ERR_MSG(extack, "Invalid IFINDEX attribute in fdb dump request");
4277
+ return -EINVAL;
4278
+ }
4279
+ *brport_idx = nla_get_u32(tb[NDA_IFINDEX]);
4280
+ break;
4281
+ case NDA_MASTER:
4282
+ if (nla_len(tb[i]) != sizeof(u32)) {
4283
+ NL_SET_ERR_MSG(extack, "Invalid MASTER attribute in fdb dump request");
4284
+ return -EINVAL;
4285
+ }
4286
+ *br_idx = nla_get_u32(tb[NDA_MASTER]);
4287
+ break;
4288
+ default:
4289
+ NL_SET_ERR_MSG(extack, "Unsupported attribute in fdb dump request");
4290
+ return -EINVAL;
4291
+ }
4292
+ }
4293
+
4294
+ return 0;
4295
+}
4296
+
4297
+static int valid_fdb_dump_legacy(const struct nlmsghdr *nlh,
4298
+ int *br_idx, int *brport_idx,
4299
+ struct netlink_ext_ack *extack)
4300
+{
4301
+ struct nlattr *tb[IFLA_MAX+1];
4302
+ int err;
4303
+
4304
+ /* A hack to preserve kernel<->userspace interface.
4305
+ * Before Linux v4.12 this code accepted ndmsg since iproute2 v3.3.0.
4306
+ * However, ndmsg is shorter than ifinfomsg thus nlmsg_parse() bails.
4307
+ * So, check for ndmsg with an optional u32 attribute (not used here).
4308
+ * Fortunately these sizes don't conflict with the size of ifinfomsg
4309
+ * with an optional attribute.
4310
+ */
4311
+ if (nlmsg_len(nlh) != sizeof(struct ndmsg) &&
4312
+ (nlmsg_len(nlh) != sizeof(struct ndmsg) +
4313
+ nla_attr_size(sizeof(u32)))) {
4314
+ struct ifinfomsg *ifm;
4315
+
4316
+ err = nlmsg_parse_deprecated(nlh, sizeof(struct ifinfomsg),
4317
+ tb, IFLA_MAX, ifla_policy,
4318
+ extack);
4319
+ if (err < 0) {
4320
+ return -EINVAL;
4321
+ } else if (err == 0) {
4322
+ if (tb[IFLA_MASTER])
4323
+ *br_idx = nla_get_u32(tb[IFLA_MASTER]);
4324
+ }
4325
+
4326
+ ifm = nlmsg_data(nlh);
4327
+ *brport_idx = ifm->ifi_index;
4328
+ }
4329
+ return 0;
4330
+}
4331
+
37904332 static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
37914333 {
37924334 struct net_device *dev;
3793
- struct nlattr *tb[IFLA_MAX+1];
37944335 struct net_device *br_dev = NULL;
37954336 const struct net_device_ops *ops = NULL;
37964337 const struct net_device_ops *cops = NULL;
3797
- struct ifinfomsg *ifm = nlmsg_data(cb->nlh);
37984338 struct net *net = sock_net(skb->sk);
37994339 struct hlist_head *head;
38004340 int brport_idx = 0;
....@@ -3804,27 +4344,14 @@
38044344 int err = 0;
38054345 int fidx = 0;
38064346
3807
- /* A hack to preserve kernel<->userspace interface.
3808
- * Before Linux v4.12 this code accepted ndmsg since iproute2 v3.3.0.
3809
- * However, ndmsg is shorter than ifinfomsg thus nlmsg_parse() bails.
3810
- * So, check for ndmsg with an optional u32 attribute (not used here).
3811
- * Fortunately these sizes don't conflict with the size of ifinfomsg
3812
- * with an optional attribute.
3813
- */
3814
- if (nlmsg_len(cb->nlh) != sizeof(struct ndmsg) &&
3815
- (nlmsg_len(cb->nlh) != sizeof(struct ndmsg) +
3816
- nla_attr_size(sizeof(u32)))) {
3817
- err = nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb,
3818
- IFLA_MAX, ifla_policy, NULL);
3819
- if (err < 0) {
3820
- return -EINVAL;
3821
- } else if (err == 0) {
3822
- if (tb[IFLA_MASTER])
3823
- br_idx = nla_get_u32(tb[IFLA_MASTER]);
3824
- }
3825
-
3826
- brport_idx = ifm->ifi_index;
3827
- }
4347
+ if (cb->strict_check)
4348
+ err = valid_fdb_dump_strict(cb->nlh, &br_idx, &brport_idx,
4349
+ cb->extack);
4350
+ else
4351
+ err = valid_fdb_dump_legacy(cb->nlh, &br_idx, &brport_idx,
4352
+ cb->extack);
4353
+ if (err < 0)
4354
+ return err;
38284355
38294356 if (br_idx) {
38304357 br_dev = __dev_get_by_index(net, br_idx);
....@@ -3846,13 +4373,13 @@
38464373 continue;
38474374
38484375 if (!br_idx) { /* user did not specify a specific bridge */
3849
- if (dev->priv_flags & IFF_BRIDGE_PORT) {
4376
+ if (netif_is_bridge_port(dev)) {
38504377 br_dev = netdev_master_upper_dev_get(dev);
38514378 cops = br_dev->netdev_ops;
38524379 }
38534380 } else {
38544381 if (dev != br_dev &&
3855
- !(dev->priv_flags & IFF_BRIDGE_PORT))
4382
+ !netif_is_bridge_port(dev))
38564383 continue;
38574384
38584385 if (br_dev != netdev_master_upper_dev_get(dev) &&
....@@ -3864,7 +4391,7 @@
38644391 if (idx < s_idx)
38654392 goto cont;
38664393
3867
- if (dev->priv_flags & IFF_BRIDGE_PORT) {
4394
+ if (netif_is_bridge_port(dev)) {
38684395 if (cops && cops->ndo_fdb_dump) {
38694396 err = cops->ndo_fdb_dump(skb, cb,
38704397 br_dev, dev,
....@@ -3900,6 +4427,165 @@
39004427 cb->args[2] = fidx;
39014428
39024429 return skb->len;
4430
+}
4431
+
4432
+static int valid_fdb_get_strict(const struct nlmsghdr *nlh,
4433
+ struct nlattr **tb, u8 *ndm_flags,
4434
+ int *br_idx, int *brport_idx, u8 **addr,
4435
+ u16 *vid, struct netlink_ext_ack *extack)
4436
+{
4437
+ struct ndmsg *ndm;
4438
+ int err, i;
4439
+
4440
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
4441
+ NL_SET_ERR_MSG(extack, "Invalid header for fdb get request");
4442
+ return -EINVAL;
4443
+ }
4444
+
4445
+ ndm = nlmsg_data(nlh);
4446
+ if (ndm->ndm_pad1 || ndm->ndm_pad2 || ndm->ndm_state ||
4447
+ ndm->ndm_type) {
4448
+ NL_SET_ERR_MSG(extack, "Invalid values in header for fdb get request");
4449
+ return -EINVAL;
4450
+ }
4451
+
4452
+ if (ndm->ndm_flags & ~(NTF_MASTER | NTF_SELF)) {
4453
+ NL_SET_ERR_MSG(extack, "Invalid flags in header for fdb get request");
4454
+ return -EINVAL;
4455
+ }
4456
+
4457
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
4458
+ NDA_MAX, nda_policy, extack);
4459
+ if (err < 0)
4460
+ return err;
4461
+
4462
+ *ndm_flags = ndm->ndm_flags;
4463
+ *brport_idx = ndm->ndm_ifindex;
4464
+ for (i = 0; i <= NDA_MAX; ++i) {
4465
+ if (!tb[i])
4466
+ continue;
4467
+
4468
+ switch (i) {
4469
+ case NDA_MASTER:
4470
+ *br_idx = nla_get_u32(tb[i]);
4471
+ break;
4472
+ case NDA_LLADDR:
4473
+ if (nla_len(tb[i]) != ETH_ALEN) {
4474
+ NL_SET_ERR_MSG(extack, "Invalid address in fdb get request");
4475
+ return -EINVAL;
4476
+ }
4477
+ *addr = nla_data(tb[i]);
4478
+ break;
4479
+ case NDA_VLAN:
4480
+ err = fdb_vid_parse(tb[i], vid, extack);
4481
+ if (err)
4482
+ return err;
4483
+ break;
4484
+ case NDA_VNI:
4485
+ break;
4486
+ default:
4487
+ NL_SET_ERR_MSG(extack, "Unsupported attribute in fdb get request");
4488
+ return -EINVAL;
4489
+ }
4490
+ }
4491
+
4492
+ return 0;
4493
+}
4494
+
4495
+static int rtnl_fdb_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
4496
+ struct netlink_ext_ack *extack)
4497
+{
4498
+ struct net_device *dev = NULL, *br_dev = NULL;
4499
+ const struct net_device_ops *ops = NULL;
4500
+ struct net *net = sock_net(in_skb->sk);
4501
+ struct nlattr *tb[NDA_MAX + 1];
4502
+ struct sk_buff *skb;
4503
+ int brport_idx = 0;
4504
+ u8 ndm_flags = 0;
4505
+ int br_idx = 0;
4506
+ u8 *addr = NULL;
4507
+ u16 vid = 0;
4508
+ int err;
4509
+
4510
+ err = valid_fdb_get_strict(nlh, tb, &ndm_flags, &br_idx,
4511
+ &brport_idx, &addr, &vid, extack);
4512
+ if (err < 0)
4513
+ return err;
4514
+
4515
+ if (!addr) {
4516
+ NL_SET_ERR_MSG(extack, "Missing lookup address for fdb get request");
4517
+ return -EINVAL;
4518
+ }
4519
+
4520
+ if (brport_idx) {
4521
+ dev = __dev_get_by_index(net, brport_idx);
4522
+ if (!dev) {
4523
+ NL_SET_ERR_MSG(extack, "Unknown device ifindex");
4524
+ return -ENODEV;
4525
+ }
4526
+ }
4527
+
4528
+ if (br_idx) {
4529
+ if (dev) {
4530
+ NL_SET_ERR_MSG(extack, "Master and device are mutually exclusive");
4531
+ return -EINVAL;
4532
+ }
4533
+
4534
+ br_dev = __dev_get_by_index(net, br_idx);
4535
+ if (!br_dev) {
4536
+ NL_SET_ERR_MSG(extack, "Invalid master ifindex");
4537
+ return -EINVAL;
4538
+ }
4539
+ ops = br_dev->netdev_ops;
4540
+ }
4541
+
4542
+ if (dev) {
4543
+ if (!ndm_flags || (ndm_flags & NTF_MASTER)) {
4544
+ if (!netif_is_bridge_port(dev)) {
4545
+ NL_SET_ERR_MSG(extack, "Device is not a bridge port");
4546
+ return -EINVAL;
4547
+ }
4548
+ br_dev = netdev_master_upper_dev_get(dev);
4549
+ if (!br_dev) {
4550
+ NL_SET_ERR_MSG(extack, "Master of device not found");
4551
+ return -EINVAL;
4552
+ }
4553
+ ops = br_dev->netdev_ops;
4554
+ } else {
4555
+ if (!(ndm_flags & NTF_SELF)) {
4556
+ NL_SET_ERR_MSG(extack, "Missing NTF_SELF");
4557
+ return -EINVAL;
4558
+ }
4559
+ ops = dev->netdev_ops;
4560
+ }
4561
+ }
4562
+
4563
+ if (!br_dev && !dev) {
4564
+ NL_SET_ERR_MSG(extack, "No device specified");
4565
+ return -ENODEV;
4566
+ }
4567
+
4568
+ if (!ops || !ops->ndo_fdb_get) {
4569
+ NL_SET_ERR_MSG(extack, "Fdb get operation not supported by device");
4570
+ return -EOPNOTSUPP;
4571
+ }
4572
+
4573
+ skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
4574
+ if (!skb)
4575
+ return -ENOBUFS;
4576
+
4577
+ if (br_dev)
4578
+ dev = br_dev;
4579
+ err = ops->ndo_fdb_get(skb, tb, dev, addr, vid,
4580
+ NETLINK_CB(in_skb).portid,
4581
+ nlh->nlmsg_seq, extack);
4582
+ if (err)
4583
+ goto out;
4584
+
4585
+ return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
4586
+out:
4587
+ kfree_skb(skb);
4588
+ return err;
39034589 }
39044590
39054591 static int brport_nla_put_flag(struct sk_buff *skb, u32 flags, u32 mask,
....@@ -3950,7 +4636,7 @@
39504636 nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))))
39514637 goto nla_put_failure;
39524638
3953
- br_afspec = nla_nest_start(skb, IFLA_AF_SPEC);
4639
+ br_afspec = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
39544640 if (!br_afspec)
39554641 goto nla_put_failure;
39564642
....@@ -3974,7 +4660,7 @@
39744660 }
39754661 nla_nest_end(skb, br_afspec);
39764662
3977
- protinfo = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);
4663
+ protinfo = nla_nest_start(skb, IFLA_PROTINFO);
39784664 if (!protinfo)
39794665 goto nla_put_failure;
39804666
....@@ -3994,7 +4680,11 @@
39944680 brport_nla_put_flag(skb, flags, mask,
39954681 IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD) ||
39964682 brport_nla_put_flag(skb, flags, mask,
3997
- IFLA_BRPORT_PROXYARP, BR_PROXYARP)) {
4683
+ IFLA_BRPORT_PROXYARP, BR_PROXYARP) ||
4684
+ brport_nla_put_flag(skb, flags, mask,
4685
+ IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) ||
4686
+ brport_nla_put_flag(skb, flags, mask,
4687
+ IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) {
39984688 nla_nest_cancel(skb, protinfo);
39994689 goto nla_put_failure;
40004690 }
....@@ -4009,28 +4699,75 @@
40094699 }
40104700 EXPORT_SYMBOL_GPL(ndo_dflt_bridge_getlink);
40114701
4702
+static int valid_bridge_getlink_req(const struct nlmsghdr *nlh,
4703
+ bool strict_check, u32 *filter_mask,
4704
+ struct netlink_ext_ack *extack)
4705
+{
4706
+ struct nlattr *tb[IFLA_MAX+1];
4707
+ int err, i;
4708
+
4709
+ if (strict_check) {
4710
+ struct ifinfomsg *ifm;
4711
+
4712
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
4713
+ NL_SET_ERR_MSG(extack, "Invalid header for bridge link dump");
4714
+ return -EINVAL;
4715
+ }
4716
+
4717
+ ifm = nlmsg_data(nlh);
4718
+ if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
4719
+ ifm->ifi_change || ifm->ifi_index) {
4720
+ NL_SET_ERR_MSG(extack, "Invalid values in header for bridge link dump request");
4721
+ return -EINVAL;
4722
+ }
4723
+
4724
+ err = nlmsg_parse_deprecated_strict(nlh,
4725
+ sizeof(struct ifinfomsg),
4726
+ tb, IFLA_MAX, ifla_policy,
4727
+ extack);
4728
+ } else {
4729
+ err = nlmsg_parse_deprecated(nlh, sizeof(struct ifinfomsg),
4730
+ tb, IFLA_MAX, ifla_policy,
4731
+ extack);
4732
+ }
4733
+ if (err < 0)
4734
+ return err;
4735
+
4736
+ /* new attributes should only be added with strict checking */
4737
+ for (i = 0; i <= IFLA_MAX; ++i) {
4738
+ if (!tb[i])
4739
+ continue;
4740
+
4741
+ switch (i) {
4742
+ case IFLA_EXT_MASK:
4743
+ *filter_mask = nla_get_u32(tb[i]);
4744
+ break;
4745
+ default:
4746
+ if (strict_check) {
4747
+ NL_SET_ERR_MSG(extack, "Unsupported attribute in bridge link dump request");
4748
+ return -EINVAL;
4749
+ }
4750
+ }
4751
+ }
4752
+
4753
+ return 0;
4754
+}
4755
+
40124756 static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
40134757 {
4758
+ const struct nlmsghdr *nlh = cb->nlh;
40144759 struct net *net = sock_net(skb->sk);
40154760 struct net_device *dev;
40164761 int idx = 0;
40174762 u32 portid = NETLINK_CB(cb->skb).portid;
4018
- u32 seq = cb->nlh->nlmsg_seq;
4763
+ u32 seq = nlh->nlmsg_seq;
40194764 u32 filter_mask = 0;
40204765 int err;
40214766
4022
- if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) {
4023
- struct nlattr *extfilt;
4024
-
4025
- extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
4026
- IFLA_EXT_MASK);
4027
- if (extfilt) {
4028
- if (nla_len(extfilt) < sizeof(filter_mask))
4029
- return -EINVAL;
4030
-
4031
- filter_mask = nla_get_u32(extfilt);
4032
- }
4033
- }
4767
+ err = valid_bridge_getlink_req(nlh, cb->strict_check, &filter_mask,
4768
+ cb->extack);
4769
+ if (err < 0 && cb->strict_check)
4770
+ return err;
40344771
40354772 rcu_read_lock();
40364773 for_each_netdev_rcu(net, dev) {
....@@ -4173,7 +4910,8 @@
41734910 goto out;
41744911 }
41754912
4176
- err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags);
4913
+ err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags,
4914
+ extack);
41774915 if (err)
41784916 goto out;
41794917
....@@ -4185,7 +4923,8 @@
41854923 err = -EOPNOTSUPP;
41864924 else
41874925 err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh,
4188
- flags);
4926
+ flags,
4927
+ extack);
41894928 if (!err) {
41904929 flags &= ~BRIDGE_FLAGS_SELF;
41914930
....@@ -4411,8 +5150,8 @@
44115150
44125151 if (ops && ops->fill_linkxstats) {
44135152 *idxattr = IFLA_STATS_LINK_XSTATS;
4414
- attr = nla_nest_start(skb,
4415
- IFLA_STATS_LINK_XSTATS);
5153
+ attr = nla_nest_start_noflag(skb,
5154
+ IFLA_STATS_LINK_XSTATS);
44165155 if (!attr)
44175156 goto nla_put_failure;
44185157
....@@ -4434,8 +5173,8 @@
44345173 ops = master->rtnl_link_ops;
44355174 if (ops && ops->fill_linkxstats) {
44365175 *idxattr = IFLA_STATS_LINK_XSTATS_SLAVE;
4437
- attr = nla_nest_start(skb,
4438
- IFLA_STATS_LINK_XSTATS_SLAVE);
5176
+ attr = nla_nest_start_noflag(skb,
5177
+ IFLA_STATS_LINK_XSTATS_SLAVE);
44395178 if (!attr)
44405179 goto nla_put_failure;
44415180
....@@ -4450,7 +5189,8 @@
44505189 if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_OFFLOAD_XSTATS,
44515190 *idxattr)) {
44525191 *idxattr = IFLA_STATS_LINK_OFFLOAD_XSTATS;
4453
- attr = nla_nest_start(skb, IFLA_STATS_LINK_OFFLOAD_XSTATS);
5192
+ attr = nla_nest_start_noflag(skb,
5193
+ IFLA_STATS_LINK_OFFLOAD_XSTATS);
44545194 if (!attr)
44555195 goto nla_put_failure;
44565196
....@@ -4469,7 +5209,7 @@
44695209 struct rtnl_af_ops *af_ops;
44705210
44715211 *idxattr = IFLA_STATS_AF_SPEC;
4472
- attr = nla_nest_start(skb, IFLA_STATS_AF_SPEC);
5212
+ attr = nla_nest_start_noflag(skb, IFLA_STATS_AF_SPEC);
44735213 if (!attr)
44745214 goto nla_put_failure;
44755215
....@@ -4479,7 +5219,8 @@
44795219 struct nlattr *af;
44805220 int err;
44815221
4482
- af = nla_nest_start(skb, af_ops->family);
5222
+ af = nla_nest_start_noflag(skb,
5223
+ af_ops->family);
44835224 if (!af) {
44845225 rcu_read_unlock();
44855226 goto nla_put_failure;
....@@ -4581,6 +5322,40 @@
45815322 return size;
45825323 }
45835324
5325
+static int rtnl_valid_stats_req(const struct nlmsghdr *nlh, bool strict_check,
5326
+ bool is_dump, struct netlink_ext_ack *extack)
5327
+{
5328
+ struct if_stats_msg *ifsm;
5329
+
5330
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifsm))) {
5331
+ NL_SET_ERR_MSG(extack, "Invalid header for stats dump");
5332
+ return -EINVAL;
5333
+ }
5334
+
5335
+ if (!strict_check)
5336
+ return 0;
5337
+
5338
+ ifsm = nlmsg_data(nlh);
5339
+
5340
+ /* only requests using strict checks can pass data to influence
5341
+ * the dump. The legacy exception is filter_mask.
5342
+ */
5343
+ if (ifsm->pad1 || ifsm->pad2 || (is_dump && ifsm->ifindex)) {
5344
+ NL_SET_ERR_MSG(extack, "Invalid values in header for stats dump request");
5345
+ return -EINVAL;
5346
+ }
5347
+ if (nlmsg_attrlen(nlh, sizeof(*ifsm))) {
5348
+ NL_SET_ERR_MSG(extack, "Invalid attributes after stats header");
5349
+ return -EINVAL;
5350
+ }
5351
+ if (ifsm->filter_mask >= IFLA_STATS_FILTER_BIT(IFLA_STATS_MAX + 1)) {
5352
+ NL_SET_ERR_MSG(extack, "Invalid stats requested through filter mask");
5353
+ return -EINVAL;
5354
+ }
5355
+
5356
+ return 0;
5357
+}
5358
+
45845359 static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
45855360 struct netlink_ext_ack *extack)
45865361 {
....@@ -4592,8 +5367,10 @@
45925367 u32 filter_mask;
45935368 int err;
45945369
4595
- if (nlmsg_len(nlh) < sizeof(*ifsm))
4596
- return -EINVAL;
5370
+ err = rtnl_valid_stats_req(nlh, netlink_strict_get_check(skb),
5371
+ false, extack);
5372
+ if (err)
5373
+ return err;
45975374
45985375 ifsm = nlmsg_data(nlh);
45995376 if (ifsm->ifindex > 0)
....@@ -4628,6 +5405,7 @@
46285405
46295406 static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
46305407 {
5408
+ struct netlink_ext_ack *extack = cb->extack;
46315409 int h, s_h, err, s_idx, s_idxattr, s_prividx;
46325410 struct net *net = sock_net(skb->sk);
46335411 unsigned int flags = NLM_F_MULTI;
....@@ -4644,13 +5422,16 @@
46445422
46455423 cb->seq = net->dev_base_seq;
46465424
4647
- if (nlmsg_len(cb->nlh) < sizeof(*ifsm))
4648
- return -EINVAL;
5425
+ err = rtnl_valid_stats_req(cb->nlh, cb->strict_check, true, extack);
5426
+ if (err)
5427
+ return err;
46495428
46505429 ifsm = nlmsg_data(cb->nlh);
46515430 filter_mask = ifsm->filter_mask;
4652
- if (!filter_mask)
5431
+ if (!filter_mask) {
5432
+ NL_SET_ERR_MSG(extack, "Filter mask must be set for stats dump");
46535433 return -EINVAL;
5434
+ }
46545435
46555436 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
46565437 idx = 0;
....@@ -4721,7 +5502,7 @@
47215502 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
47225503 struct sock *rtnl;
47235504 rtnl_dumpit_func dumpit;
4724
- u16 min_dump_alloc = 0;
5505
+ u32 min_dump_alloc = 0;
47255506
47265507 link = rtnl_get_link(family, type);
47275508 if (!link || !link->dumpit) {
....@@ -4898,9 +5679,12 @@
48985679 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0);
48995680 rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0);
49005681
5682
+ rtnl_register(PF_UNSPEC, RTM_NEWLINKPROP, rtnl_newlinkprop, NULL, 0);
5683
+ rtnl_register(PF_UNSPEC, RTM_DELLINKPROP, rtnl_dellinkprop, NULL, 0);
5684
+
49015685 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0);
49025686 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0);
4903
- rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, 0);
5687
+ rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0);
49045688
49055689 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0);
49065690 rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0);