hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/net/core/dev_ioctl.c
....@@ -1,10 +1,12 @@
11 // SPDX-License-Identifier: GPL-2.0
22 #include <linux/kmod.h>
33 #include <linux/netdevice.h>
4
+#include <linux/inetdevice.h>
45 #include <linux/etherdevice.h>
56 #include <linux/rtnetlink.h>
67 #include <linux/net_tstamp.h>
78 #include <linux/wireless.h>
9
+#include <net/dsa.h>
810 #include <net/wext.h>
911
1012 /*
....@@ -24,26 +26,6 @@
2426 return netdev_get_name(net, ifr->ifr_name, ifr->ifr_ifindex);
2527 }
2628
27
-static gifconf_func_t *gifconf_list[NPROTO];
28
-
29
-/**
30
- * register_gifconf - register a SIOCGIF handler
31
- * @family: Address family
32
- * @gifconf: Function handler
33
- *
34
- * Register protocol dependent address dumping routines. The handler
35
- * that is passed must not be freed or reused until it has been replaced
36
- * by another handler.
37
- */
38
-int register_gifconf(unsigned int family, gifconf_func_t *gifconf)
39
-{
40
- if (family >= NPROTO)
41
- return -EINVAL;
42
- gifconf_list[family] = gifconf;
43
- return 0;
44
-}
45
-EXPORT_SYMBOL(register_gifconf);
46
-
4729 /*
4830 * Perform a SIOCGIFCONF call. This structure will change
4931 * size eventually, and there is nothing I can do about it.
....@@ -56,7 +38,6 @@
5638 char __user *pos;
5739 int len;
5840 int total;
59
- int i;
6041
6142 /*
6243 * Fetch the caller's info block.
....@@ -71,19 +52,15 @@
7152
7253 total = 0;
7354 for_each_netdev(net, dev) {
74
- for (i = 0; i < NPROTO; i++) {
75
- if (gifconf_list[i]) {
76
- int done;
77
- if (!pos)
78
- done = gifconf_list[i](dev, NULL, 0, size);
79
- else
80
- done = gifconf_list[i](dev, pos + total,
81
- len - total, size);
82
- if (done < 0)
83
- return -EFAULT;
84
- total += done;
85
- }
86
- }
55
+ int done;
56
+ if (!pos)
57
+ done = inet_gifconf(dev, NULL, 0, size);
58
+ else
59
+ done = inet_gifconf(dev, pos + total,
60
+ len - total, size);
61
+ if (done < 0)
62
+ return -EFAULT;
63
+ total += done;
8764 }
8865
8966 /*
....@@ -120,17 +97,6 @@
12097
12198 case SIOCGIFMTU: /* Get the MTU of a device */
12299 ifr->ifr_mtu = dev->mtu;
123
- return 0;
124
-
125
- case SIOCGIFHWADDR:
126
- if (!dev->addr_len)
127
- memset(ifr->ifr_hwaddr.sa_data, 0,
128
- sizeof(ifr->ifr_hwaddr.sa_data));
129
- else
130
- memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
131
- min(sizeof(ifr->ifr_hwaddr.sa_data),
132
- (size_t)dev->addr_len));
133
- ifr->ifr_hwaddr.sa_family = dev->type;
134100 return 0;
135101
136102 case SIOCGIFSLAVE:
....@@ -187,7 +153,11 @@
187153 case HWTSTAMP_TX_OFF:
188154 case HWTSTAMP_TX_ON:
189155 case HWTSTAMP_TX_ONESTEP_SYNC:
156
+ case HWTSTAMP_TX_ONESTEP_P2P:
190157 tx_type_valid = 1;
158
+ break;
159
+ case __HWTSTAMP_TX_CNT:
160
+ /* not a real value */
191161 break;
192162 }
193163
....@@ -210,12 +180,35 @@
210180 case HWTSTAMP_FILTER_NTP_ALL:
211181 rx_filter_valid = 1;
212182 break;
183
+ case __HWTSTAMP_FILTER_CNT:
184
+ /* not a real value */
185
+ break;
213186 }
214187
215188 if (!tx_type_valid || !rx_filter_valid)
216189 return -ERANGE;
217190
218191 return 0;
192
+}
193
+
194
+static int dev_do_ioctl(struct net_device *dev,
195
+ struct ifreq *ifr, unsigned int cmd)
196
+{
197
+ const struct net_device_ops *ops = dev->netdev_ops;
198
+ int err = -EOPNOTSUPP;
199
+
200
+ err = dsa_ndo_do_ioctl(dev, ifr, cmd);
201
+ if (err == 0 || err != -EOPNOTSUPP)
202
+ return err;
203
+
204
+ if (ops->ndo_do_ioctl) {
205
+ if (netif_device_present(dev))
206
+ err = ops->ndo_do_ioctl(dev, ifr, cmd);
207
+ else
208
+ err = -ENODEV;
209
+ }
210
+
211
+ return err;
219212 }
220213
221214 /*
....@@ -234,7 +227,7 @@
234227
235228 switch (cmd) {
236229 case SIOCSIFFLAGS: /* Set interface flags */
237
- return dev_change_flags(dev, ifr->ifr_flags);
230
+ return dev_change_flags(dev, ifr->ifr_flags, NULL);
238231
239232 case SIOCSIFMETRIC: /* Set the metric on the interface
240233 (currently unused) */
....@@ -246,7 +239,7 @@
246239 case SIOCSIFHWADDR:
247240 if (dev->addr_len > sizeof(struct sockaddr))
248241 return -EINVAL;
249
- return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
242
+ return dev_set_mac_address_user(dev, &ifr->ifr_hwaddr, NULL);
250243
251244 case SIOCSIFHWBROADCAST:
252245 if (ifr->ifr_hwaddr.sa_family != dev->type)
....@@ -294,7 +287,7 @@
294287 err = net_hwtstamp_validate(ifr);
295288 if (err)
296289 return err;
297
- /* fall through */
290
+ fallthrough;
298291
299292 /*
300293 * Unknown or private ioctl
....@@ -316,13 +309,7 @@
316309 cmd == SIOCSHWTSTAMP ||
317310 cmd == SIOCGHWTSTAMP ||
318311 cmd == SIOCWANDEV) {
319
- err = -EOPNOTSUPP;
320
- if (ops->ndo_do_ioctl) {
321
- if (netif_device_present(dev))
322
- err = ops->ndo_do_ioctl(dev, ifr, cmd);
323
- else
324
- err = -ENODEV;
325
- }
312
+ err = dev_do_ioctl(dev, ifr, cmd);
326313 } else
327314 err = -EINVAL;
328315
....@@ -366,7 +353,8 @@
366353 * dev_ioctl - network device ioctl
367354 * @net: the applicable net namespace
368355 * @cmd: command to issue
369
- * @arg: pointer to a struct ifreq in user space
356
+ * @ifr: pointer to a struct ifreq in user space
357
+ * @need_copyout: whether or not copy_to_user() should be called
370358 *
371359 * Issue ioctl functions to devices. This is normally called by the
372360 * user space syscall interfaces but can sometimes be useful for
....@@ -395,6 +383,12 @@
395383 */
396384
397385 switch (cmd) {
386
+ case SIOCGIFHWADDR:
387
+ dev_load(net, ifr->ifr_name);
388
+ ret = dev_get_mac_address(&ifr->ifr_hwaddr, net, ifr->ifr_name);
389
+ if (colon)
390
+ *colon = ':';
391
+ return ret;
398392 /*
399393 * These ioctl calls:
400394 * - can be done by all.
....@@ -404,7 +398,6 @@
404398 case SIOCGIFFLAGS:
405399 case SIOCGIFMETRIC:
406400 case SIOCGIFMTU:
407
- case SIOCGIFHWADDR:
408401 case SIOCGIFSLAVE:
409402 case SIOCGIFMAP:
410403 case SIOCGIFINDEX:
....@@ -417,7 +410,6 @@
417410 *colon = ':';
418411 return ret;
419412
420
-#ifdef CONFIG_ETHTOOL
421413 case SIOCETHTOOL:
422414 dev_load(net, ifr->ifr_name);
423415 rtnl_lock();
....@@ -426,7 +418,6 @@
426418 if (colon)
427419 *colon = ':';
428420 return ret;
429
-#endif
430421
431422 /*
432423 * These ioctl calls:
....@@ -457,7 +448,7 @@
457448 case SIOCSIFTXQLEN:
458449 if (!capable(CAP_NET_ADMIN))
459450 return -EPERM;
460
- /* fall through */
451
+ fallthrough;
461452 /*
462453 * These ioctl calls:
463454 * - require local superuser power.
....@@ -482,7 +473,7 @@
482473 case SIOCSHWTSTAMP:
483474 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
484475 return -EPERM;
485
- /* fall through */
476
+ fallthrough;
486477 case SIOCBONDSLAVEINFOQUERY:
487478 case SIOCBONDINFOQUERY:
488479 dev_load(net, ifr->ifr_name);