Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : #include <linux/kmod.h>
3 : #include <linux/netdevice.h>
4 : #include <linux/etherdevice.h>
5 : #include <linux/rtnetlink.h>
6 : #include <linux/net_tstamp.h>
7 : #include <linux/wireless.h>
8 : #include <net/dsa.h>
9 : #include <net/wext.h>
10 :
11 : /*
12 : * Map an interface index to its name (SIOCGIFNAME)
13 : */
14 :
15 : /*
16 : * We need this ioctl for efficient implementation of the
17 : * if_indextoname() function required by the IPv6 API. Without
18 : * it, we would have to search all the interfaces to find a
19 : * match. --pb
20 : */
21 :
22 3 : static int dev_ifname(struct net *net, struct ifreq *ifr)
23 : {
24 3 : ifr->ifr_name[IFNAMSIZ-1] = 0;
25 3 : return netdev_get_name(net, ifr->ifr_name, ifr->ifr_ifindex);
26 : }
27 :
28 : static gifconf_func_t *gifconf_list[NPROTO];
29 :
30 : /**
31 : * register_gifconf - register a SIOCGIF handler
32 : * @family: Address family
33 : * @gifconf: Function handler
34 : *
35 : * Register protocol dependent address dumping routines. The handler
36 : * that is passed must not be freed or reused until it has been replaced
37 : * by another handler.
38 : */
39 1 : int register_gifconf(unsigned int family, gifconf_func_t *gifconf)
40 : {
41 1 : if (family >= NPROTO)
42 : return -EINVAL;
43 1 : gifconf_list[family] = gifconf;
44 1 : return 0;
45 : }
46 : EXPORT_SYMBOL(register_gifconf);
47 :
48 : /*
49 : * Perform a SIOCGIFCONF call. This structure will change
50 : * size eventually, and there is nothing I can do about it.
51 : * Thus we will need a 'compatibility mode'.
52 : */
53 :
54 0 : int dev_ifconf(struct net *net, struct ifconf *ifc, int size)
55 : {
56 0 : struct net_device *dev;
57 0 : char __user *pos;
58 0 : int len;
59 0 : int total;
60 0 : int i;
61 :
62 : /*
63 : * Fetch the caller's info block.
64 : */
65 :
66 0 : pos = ifc->ifc_buf;
67 0 : len = ifc->ifc_len;
68 :
69 : /*
70 : * Loop over the interfaces, and write an info block for each.
71 : */
72 :
73 0 : total = 0;
74 0 : for_each_netdev(net, dev) {
75 0 : for (i = 0; i < NPROTO; i++) {
76 0 : if (gifconf_list[i]) {
77 0 : int done;
78 0 : if (!pos)
79 0 : done = gifconf_list[i](dev, NULL, 0, size);
80 : else
81 0 : done = gifconf_list[i](dev, pos + total,
82 : len - total, size);
83 0 : if (done < 0)
84 : return -EFAULT;
85 0 : total += done;
86 : }
87 : }
88 : }
89 :
90 : /*
91 : * All done. Write the updated control block back to the caller.
92 : */
93 0 : ifc->ifc_len = total;
94 :
95 : /*
96 : * Both BSD and Solaris return 0 here, so we do too.
97 : */
98 0 : return 0;
99 : }
100 :
101 : /*
102 : * Perform the SIOCxIFxxx calls, inside rcu_read_lock()
103 : */
104 9 : static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cmd)
105 : {
106 9 : int err;
107 9 : struct net_device *dev = dev_get_by_name_rcu(net, ifr->ifr_name);
108 :
109 9 : if (!dev)
110 : return -ENODEV;
111 :
112 8 : switch (cmd) {
113 2 : case SIOCGIFFLAGS: /* Get interface flags */
114 2 : ifr->ifr_flags = (short) dev_get_flags(dev);
115 2 : return 0;
116 :
117 0 : case SIOCGIFMETRIC: /* Get the metric on the interface
118 : (currently unused) */
119 0 : ifr->ifr_metric = 0;
120 0 : return 0;
121 :
122 0 : case SIOCGIFMTU: /* Get the MTU of a device */
123 0 : ifr->ifr_mtu = dev->mtu;
124 0 : return 0;
125 :
126 : case SIOCGIFSLAVE:
127 : err = -EINVAL;
128 : break;
129 :
130 0 : case SIOCGIFMAP:
131 0 : ifr->ifr_map.mem_start = dev->mem_start;
132 0 : ifr->ifr_map.mem_end = dev->mem_end;
133 0 : ifr->ifr_map.base_addr = dev->base_addr;
134 0 : ifr->ifr_map.irq = dev->irq;
135 0 : ifr->ifr_map.dma = dev->dma;
136 0 : ifr->ifr_map.port = dev->if_port;
137 0 : return 0;
138 :
139 6 : case SIOCGIFINDEX:
140 6 : ifr->ifr_ifindex = dev->ifindex;
141 6 : return 0;
142 :
143 0 : case SIOCGIFTXQLEN:
144 0 : ifr->ifr_qlen = dev->tx_queue_len;
145 0 : return 0;
146 :
147 : default:
148 : /* dev_ioctl() should ensure this case
149 : * is never reached
150 : */
151 0 : WARN_ON(1);
152 0 : err = -ENOTTY;
153 0 : break;
154 :
155 : }
156 : return err;
157 : }
158 :
159 0 : static int net_hwtstamp_validate(struct ifreq *ifr)
160 : {
161 0 : struct hwtstamp_config cfg;
162 0 : enum hwtstamp_tx_types tx_type;
163 0 : enum hwtstamp_rx_filters rx_filter;
164 0 : int tx_type_valid = 0;
165 0 : int rx_filter_valid = 0;
166 :
167 0 : if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
168 : return -EFAULT;
169 :
170 0 : if (cfg.flags) /* reserved for future extensions */
171 : return -EINVAL;
172 :
173 0 : tx_type = cfg.tx_type;
174 0 : rx_filter = cfg.rx_filter;
175 :
176 0 : switch (tx_type) {
177 0 : case HWTSTAMP_TX_OFF:
178 : case HWTSTAMP_TX_ON:
179 : case HWTSTAMP_TX_ONESTEP_SYNC:
180 : case HWTSTAMP_TX_ONESTEP_P2P:
181 0 : tx_type_valid = 1;
182 0 : break;
183 : case __HWTSTAMP_TX_CNT:
184 : /* not a real value */
185 : break;
186 : }
187 :
188 0 : switch (rx_filter) {
189 0 : case HWTSTAMP_FILTER_NONE:
190 : case HWTSTAMP_FILTER_ALL:
191 : case HWTSTAMP_FILTER_SOME:
192 : case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
193 : case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
194 : case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
195 : case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
196 : case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
197 : case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
198 : case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
199 : case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
200 : case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
201 : case HWTSTAMP_FILTER_PTP_V2_EVENT:
202 : case HWTSTAMP_FILTER_PTP_V2_SYNC:
203 : case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
204 : case HWTSTAMP_FILTER_NTP_ALL:
205 0 : rx_filter_valid = 1;
206 0 : break;
207 : case __HWTSTAMP_FILTER_CNT:
208 : /* not a real value */
209 : break;
210 : }
211 :
212 0 : if (!tx_type_valid || !rx_filter_valid)
213 0 : return -ERANGE;
214 :
215 : return 0;
216 : }
217 :
218 0 : static int dev_do_ioctl(struct net_device *dev,
219 : struct ifreq *ifr, unsigned int cmd)
220 : {
221 0 : const struct net_device_ops *ops = dev->netdev_ops;
222 0 : int err;
223 :
224 0 : err = dsa_ndo_do_ioctl(dev, ifr, cmd);
225 0 : if (err == 0 || err != -EOPNOTSUPP)
226 : return err;
227 :
228 0 : if (ops->ndo_do_ioctl) {
229 0 : if (netif_device_present(dev))
230 0 : err = ops->ndo_do_ioctl(dev, ifr, cmd);
231 : else
232 : err = -ENODEV;
233 : }
234 :
235 0 : return err;
236 : }
237 :
238 : /*
239 : * Perform the SIOCxIFxxx calls, inside rtnl_lock()
240 : */
241 0 : static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
242 : {
243 0 : int err;
244 0 : struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
245 0 : const struct net_device_ops *ops;
246 :
247 0 : if (!dev)
248 : return -ENODEV;
249 :
250 0 : ops = dev->netdev_ops;
251 :
252 0 : switch (cmd) {
253 0 : case SIOCSIFFLAGS: /* Set interface flags */
254 0 : return dev_change_flags(dev, ifr->ifr_flags, NULL);
255 :
256 : case SIOCSIFMETRIC: /* Set the metric on the interface
257 : (currently unused) */
258 : return -EOPNOTSUPP;
259 :
260 0 : case SIOCSIFMTU: /* Set the MTU of a device */
261 0 : return dev_set_mtu(dev, ifr->ifr_mtu);
262 :
263 0 : case SIOCSIFHWADDR:
264 0 : if (dev->addr_len > sizeof(struct sockaddr))
265 : return -EINVAL;
266 0 : return dev_set_mac_address_user(dev, &ifr->ifr_hwaddr, NULL);
267 :
268 0 : case SIOCSIFHWBROADCAST:
269 0 : if (ifr->ifr_hwaddr.sa_family != dev->type)
270 : return -EINVAL;
271 0 : memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
272 0 : min(sizeof(ifr->ifr_hwaddr.sa_data),
273 : (size_t)dev->addr_len));
274 0 : call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
275 0 : return 0;
276 :
277 0 : case SIOCSIFMAP:
278 0 : if (ops->ndo_set_config) {
279 0 : if (!netif_device_present(dev))
280 : return -ENODEV;
281 0 : return ops->ndo_set_config(dev, &ifr->ifr_map);
282 : }
283 : return -EOPNOTSUPP;
284 :
285 0 : case SIOCADDMULTI:
286 0 : if (!ops->ndo_set_rx_mode ||
287 0 : ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
288 : return -EINVAL;
289 0 : if (!netif_device_present(dev))
290 : return -ENODEV;
291 0 : return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data);
292 :
293 0 : case SIOCDELMULTI:
294 0 : if (!ops->ndo_set_rx_mode ||
295 0 : ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
296 : return -EINVAL;
297 0 : if (!netif_device_present(dev))
298 : return -ENODEV;
299 0 : return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data);
300 :
301 0 : case SIOCSIFTXQLEN:
302 0 : if (ifr->ifr_qlen < 0)
303 : return -EINVAL;
304 0 : return dev_change_tx_queue_len(dev, ifr->ifr_qlen);
305 :
306 0 : case SIOCSIFNAME:
307 0 : ifr->ifr_newname[IFNAMSIZ-1] = '\0';
308 0 : return dev_change_name(dev, ifr->ifr_newname);
309 :
310 0 : case SIOCSHWTSTAMP:
311 0 : err = net_hwtstamp_validate(ifr);
312 0 : if (err)
313 : return err;
314 0 : fallthrough;
315 :
316 : /*
317 : * Unknown or private ioctl
318 : */
319 : default:
320 0 : if ((cmd >= SIOCDEVPRIVATE &&
321 0 : cmd <= SIOCDEVPRIVATE + 15) ||
322 0 : cmd == SIOCBONDENSLAVE ||
323 0 : cmd == SIOCBONDRELEASE ||
324 : cmd == SIOCBONDSETHWADDR ||
325 0 : cmd == SIOCBONDSLAVEINFOQUERY ||
326 : cmd == SIOCBONDINFOQUERY ||
327 0 : cmd == SIOCBONDCHANGEACTIVE ||
328 0 : cmd == SIOCGMIIPHY ||
329 0 : cmd == SIOCGMIIREG ||
330 : cmd == SIOCSMIIREG ||
331 0 : cmd == SIOCBRADDIF ||
332 : cmd == SIOCBRDELIF ||
333 0 : cmd == SIOCSHWTSTAMP ||
334 0 : cmd == SIOCGHWTSTAMP ||
335 : cmd == SIOCWANDEV) {
336 0 : err = dev_do_ioctl(dev, ifr, cmd);
337 : } else
338 : err = -EINVAL;
339 :
340 : }
341 : return err;
342 : }
343 :
344 : /**
345 : * dev_load - load a network module
346 : * @net: the applicable net namespace
347 : * @name: name of interface
348 : *
349 : * If a network interface is not present and the process has suitable
350 : * privileges this function loads the module. If module loading is not
351 : * available in this kernel then it becomes a nop.
352 : */
353 :
354 18 : void dev_load(struct net *net, const char *name)
355 : {
356 18 : struct net_device *dev;
357 18 : int no_module;
358 :
359 18 : rcu_read_lock();
360 18 : dev = dev_get_by_name_rcu(net, name);
361 18 : rcu_read_unlock();
362 :
363 18 : no_module = !dev;
364 18 : if (no_module && capable(CAP_NET_ADMIN))
365 1 : no_module = request_module("netdev-%s", name);
366 18 : if (no_module && capable(CAP_SYS_MODULE))
367 18 : request_module("%s", name);
368 18 : }
369 : EXPORT_SYMBOL(dev_load);
370 :
371 : /*
372 : * This function handles all "interface"-type I/O control requests. The actual
373 : * 'doing' part of this is dev_ifsioc above.
374 : */
375 :
376 : /**
377 : * dev_ioctl - network device ioctl
378 : * @net: the applicable net namespace
379 : * @cmd: command to issue
380 : * @ifr: pointer to a struct ifreq in user space
381 : * @need_copyout: whether or not copy_to_user() should be called
382 : *
383 : * Issue ioctl functions to devices. This is normally called by the
384 : * user space syscall interfaces but can sometimes be useful for
385 : * other purposes. The return value is the return from the syscall if
386 : * positive or a negative errno code on error.
387 : */
388 :
389 66 : int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_copyout)
390 : {
391 66 : int ret;
392 66 : char *colon;
393 :
394 66 : if (need_copyout)
395 66 : *need_copyout = true;
396 66 : if (cmd == SIOCGIFNAME)
397 3 : return dev_ifname(net, ifr);
398 :
399 63 : ifr->ifr_name[IFNAMSIZ-1] = 0;
400 :
401 63 : colon = strchr(ifr->ifr_name, ':');
402 63 : if (colon)
403 0 : *colon = 0;
404 :
405 : /*
406 : * See which interface the caller is talking about.
407 : */
408 :
409 63 : switch (cmd) {
410 1 : case SIOCGIFHWADDR:
411 1 : dev_load(net, ifr->ifr_name);
412 1 : ret = dev_get_mac_address(&ifr->ifr_hwaddr, net, ifr->ifr_name);
413 1 : if (colon)
414 0 : *colon = ':';
415 : return ret;
416 : /*
417 : * These ioctl calls:
418 : * - can be done by all.
419 : * - atomic and do not require locking.
420 : * - return a value
421 : */
422 9 : case SIOCGIFFLAGS:
423 : case SIOCGIFMETRIC:
424 : case SIOCGIFMTU:
425 : case SIOCGIFSLAVE:
426 : case SIOCGIFMAP:
427 : case SIOCGIFINDEX:
428 : case SIOCGIFTXQLEN:
429 9 : dev_load(net, ifr->ifr_name);
430 9 : rcu_read_lock();
431 9 : ret = dev_ifsioc_locked(net, ifr, cmd);
432 9 : rcu_read_unlock();
433 9 : if (colon)
434 0 : *colon = ':';
435 : return ret;
436 :
437 8 : case SIOCETHTOOL:
438 8 : dev_load(net, ifr->ifr_name);
439 8 : rtnl_lock();
440 8 : ret = dev_ethtool(net, ifr);
441 8 : rtnl_unlock();
442 8 : if (colon)
443 0 : *colon = ':';
444 : return ret;
445 :
446 : /*
447 : * These ioctl calls:
448 : * - require superuser power.
449 : * - require strict serialization.
450 : * - return a value
451 : */
452 0 : case SIOCGMIIPHY:
453 : case SIOCGMIIREG:
454 : case SIOCSIFNAME:
455 0 : dev_load(net, ifr->ifr_name);
456 0 : if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
457 : return -EPERM;
458 0 : rtnl_lock();
459 0 : ret = dev_ifsioc(net, ifr, cmd);
460 0 : rtnl_unlock();
461 0 : if (colon)
462 0 : *colon = ':';
463 : return ret;
464 :
465 : /*
466 : * These ioctl calls:
467 : * - require superuser power.
468 : * - require strict serialization.
469 : * - do not return a value
470 : */
471 0 : case SIOCSIFMAP:
472 : case SIOCSIFTXQLEN:
473 0 : if (!capable(CAP_NET_ADMIN))
474 : return -EPERM;
475 0 : fallthrough;
476 : /*
477 : * These ioctl calls:
478 : * - require local superuser power.
479 : * - require strict serialization.
480 : * - do not return a value
481 : */
482 : case SIOCSIFFLAGS:
483 : case SIOCSIFMETRIC:
484 : case SIOCSIFMTU:
485 : case SIOCSIFHWADDR:
486 : case SIOCSIFSLAVE:
487 : case SIOCADDMULTI:
488 : case SIOCDELMULTI:
489 : case SIOCSIFHWBROADCAST:
490 : case SIOCSMIIREG:
491 : case SIOCBONDENSLAVE:
492 : case SIOCBONDRELEASE:
493 : case SIOCBONDSETHWADDR:
494 : case SIOCBONDCHANGEACTIVE:
495 : case SIOCBRADDIF:
496 : case SIOCBRDELIF:
497 : case SIOCSHWTSTAMP:
498 0 : if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
499 : return -EPERM;
500 0 : fallthrough;
501 : case SIOCBONDSLAVEINFOQUERY:
502 : case SIOCBONDINFOQUERY:
503 0 : dev_load(net, ifr->ifr_name);
504 0 : rtnl_lock();
505 0 : ret = dev_ifsioc(net, ifr, cmd);
506 0 : rtnl_unlock();
507 0 : if (need_copyout)
508 0 : *need_copyout = false;
509 : return ret;
510 :
511 : case SIOCGIFMEM:
512 : /* Get the per device memory space. We can add this but
513 : * currently do not support it */
514 : case SIOCSIFMEM:
515 : /* Set the per device memory buffer space.
516 : * Not applicable in our case */
517 : case SIOCSIFLINK:
518 : return -ENOTTY;
519 :
520 : /*
521 : * Unknown or private ioctl.
522 : */
523 45 : default:
524 45 : if (cmd == SIOCWANDEV ||
525 45 : cmd == SIOCGHWTSTAMP ||
526 45 : (cmd >= SIOCDEVPRIVATE &&
527 : cmd <= SIOCDEVPRIVATE + 15)) {
528 0 : dev_load(net, ifr->ifr_name);
529 0 : rtnl_lock();
530 0 : ret = dev_ifsioc(net, ifr, cmd);
531 0 : rtnl_unlock();
532 0 : return ret;
533 : }
534 : return -ENOTTY;
535 : }
536 : }
|