4463a2a8282a1151cb99734d65dd57689a7fad52
[project/netifd.git] / system-linux.c
1 /*
2 * netifd - network interface daemon
3 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
4 * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
5 * Copyright (C) 2013 Steven Barth <steven@midlink.org>
6 * Copyright (C) 2014 Gioacchino Mazzurco <gio@eigenlab.org>
7 * Copyright (C) 2017 Matthias Schiffer <mschiffer@universe-factory.net>
8 * Copyright (C) 2018 Hans Dedecker <dedeckeh@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19 #define _GNU_SOURCE
20
21 #include <sys/socket.h>
22 #include <sys/ioctl.h>
23 #include <sys/stat.h>
24 #include <sys/syscall.h>
25
26 #include <net/if.h>
27 #include <net/if_arp.h>
28
29 #include <limits.h>
30 #include <arpa/inet.h>
31 #include <netinet/in.h>
32 #include <netinet/ether.h>
33
34 #include <linux/rtnetlink.h>
35 #include <linux/neighbour.h>
36 #include <linux/sockios.h>
37 #include <linux/ip.h>
38 #include <linux/if_addr.h>
39 #include <linux/if_link.h>
40 #include <linux/if_vlan.h>
41 #include <linux/if_bridge.h>
42 #include <linux/if_tunnel.h>
43 #include <linux/ip6_tunnel.h>
44 #include <linux/ethtool.h>
45 #include <linux/fib_rules.h>
46 #include <linux/veth.h>
47 #include <linux/version.h>
48
49 #include <sched.h>
50
51 #include "ethtool-modes.h"
52
53 #ifndef RTN_FAILED_POLICY
54 #define RTN_FAILED_POLICY 12
55 #endif
56
57 #ifndef IFA_F_NOPREFIXROUTE
58 #define IFA_F_NOPREFIXROUTE 0x200
59 #endif
60
61 #ifndef IFA_FLAGS
62 #define IFA_FLAGS (IFA_MULTICAST + 1)
63 #endif
64
65 #include <string.h>
66 #include <fcntl.h>
67 #include <glob.h>
68 #include <time.h>
69 #include <unistd.h>
70
71 #include <netlink/msg.h>
72 #include <netlink/attr.h>
73 #include <netlink/socket.h>
74 #include <libubox/uloop.h>
75
76 #include "netifd.h"
77 #include "device.h"
78 #include "system.h"
79 #include "utils.h"
80
81 struct event_socket {
82 struct uloop_fd uloop;
83 struct nl_sock *sock;
84 int bufsize;
85 };
86
87 static int sock_ioctl = -1;
88 static struct nl_sock *sock_rtnl = NULL;
89
90 static int cb_rtnl_event(struct nl_msg *msg, void *arg);
91 static void handle_hotplug_event(struct uloop_fd *u, unsigned int events);
92 static int system_add_proto_tunnel(const char *name, const uint8_t proto,
93 const unsigned int link, struct blob_attr **tb);
94
95 static char dev_buf[256];
96 static const char *proc_path = "/proc";
97 static const char *sysfs_path = "/sys";
98
99 struct netdev_type {
100 unsigned short id;
101 const char *name;
102 };
103
104 static const struct netdev_type netdev_types[] = {
105 {ARPHRD_NETROM, "netrom"},
106 {ARPHRD_ETHER, "ethernet"},
107 {ARPHRD_EETHER, "eethernet"},
108 {ARPHRD_AX25, "ax25"},
109 {ARPHRD_PRONET, "pronet"},
110 {ARPHRD_CHAOS, "chaos"},
111 {ARPHRD_IEEE802, "ieee802"},
112 {ARPHRD_ARCNET, "arcnet"},
113 {ARPHRD_APPLETLK, "appletlk"},
114 {ARPHRD_DLCI, "dlci"},
115 {ARPHRD_ATM, "atm"},
116 {ARPHRD_METRICOM, "metricom"},
117 {ARPHRD_IEEE1394, "ieee1394"},
118 {ARPHRD_EUI64, "eui64"},
119 {ARPHRD_INFINIBAND, "infiniband"},
120 {ARPHRD_SLIP, "slip"},
121 {ARPHRD_CSLIP, "cslip"},
122 {ARPHRD_SLIP6, "slip6"},
123 {ARPHRD_CSLIP6, "cslip6"},
124 {ARPHRD_RSRVD, "rsrvd"},
125 {ARPHRD_ADAPT, "adapt"},
126 {ARPHRD_ROSE, "rose"},
127 {ARPHRD_X25, "x25"},
128 {ARPHRD_HWX25, "hwx25"},
129 {ARPHRD_PPP, "ppp"},
130 {ARPHRD_CISCO, "cisco"},
131 {ARPHRD_LAPB, "lapb"},
132 {ARPHRD_DDCMP, "ddcmp"},
133 {ARPHRD_RAWHDLC, "rawhdlc"},
134 {ARPHRD_TUNNEL, "tunnel"},
135 {ARPHRD_TUNNEL6, "tunnel6"},
136 {ARPHRD_FRAD, "frad"},
137 {ARPHRD_SKIP, "skip"},
138 {ARPHRD_LOOPBACK, "loopback"},
139 {ARPHRD_LOCALTLK, "localtlk"},
140 {ARPHRD_FDDI, "fddi"},
141 {ARPHRD_BIF, "bif"},
142 {ARPHRD_SIT, "sit"},
143 {ARPHRD_IPDDP, "ipddp"},
144 {ARPHRD_IPGRE, "ipgre"},
145 {ARPHRD_PIMREG,"pimreg"},
146 {ARPHRD_HIPPI, "hippi"},
147 {ARPHRD_ASH, "ash"},
148 {ARPHRD_ECONET, "econet"},
149 {ARPHRD_IRDA, "irda"},
150 {ARPHRD_FCPP, "fcpp"},
151 {ARPHRD_FCAL, "fcal"},
152 {ARPHRD_FCPL, "fcpl"},
153 {ARPHRD_FCFABRIC, "fcfabric"},
154 {ARPHRD_IEEE80211, "ieee80211"},
155 {ARPHRD_IEEE80211_PRISM, "ie80211-prism"},
156 {ARPHRD_IEEE80211_RADIOTAP, "ieee80211-radiotap"},
157 #ifdef ARPHRD_PHONET
158 {ARPHRD_PHONET, "phonet"},
159 #endif
160 #ifdef ARPHRD_PHONET_PIPE
161 {ARPHRD_PHONET_PIPE, "phonet-pipe"},
162 #endif
163 {ARPHRD_IEEE802154, "ieee802154"},
164 {ARPHRD_VOID, "void"},
165 {ARPHRD_NONE, "none"}
166 };
167
168 static void
169 handler_nl_event(struct uloop_fd *u, unsigned int events)
170 {
171 struct event_socket *ev = container_of(u, struct event_socket, uloop);
172 int ret;
173
174 ret = nl_recvmsgs_default(ev->sock);
175 if (ret >= 0)
176 return;
177
178 switch (-ret) {
179 case NLE_NOMEM:
180 /* Increase rx buffer size on netlink socket */
181 ev->bufsize *= 2;
182 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
183 goto abort;
184
185 /* Request full dump since some info got dropped */
186 struct rtgenmsg msg = { .rtgen_family = AF_UNSPEC };
187 nl_send_simple(ev->sock, RTM_GETLINK, NLM_F_DUMP, &msg, sizeof(msg));
188 break;
189
190 default:
191 goto abort;
192 }
193 return;
194
195 abort:
196 uloop_fd_delete(&ev->uloop);
197 return;
198 }
199
200 static void
201 nl_udebug_cb(void *priv, struct nl_msg *msg)
202 {
203 struct nlmsghdr *nlh = nlmsg_hdr(msg);
204
205 udebug_netlink_msg(priv, nlmsg_get_proto(msg), nlh, nlh->nlmsg_len);
206 }
207
208 static struct nl_sock *
209 create_socket(int protocol, int groups)
210 {
211 struct nl_sock *sock;
212
213 sock = nl_socket_alloc();
214 if (!sock)
215 return NULL;
216
217 if (groups)
218 nl_join_groups(sock, groups);
219
220 if (nl_connect(sock, protocol)) {
221 nl_socket_free(sock);
222 return NULL;
223 }
224
225 nl_socket_set_tx_debug_cb(sock, nl_udebug_cb, &udb_nl);
226 nl_socket_set_rx_debug_cb(sock, nl_udebug_cb, &udb_nl);
227
228 return sock;
229 }
230
231 static bool
232 create_raw_event_socket(struct event_socket *ev, int protocol, int groups,
233 uloop_fd_handler cb, int flags)
234 {
235 ev->sock = create_socket(protocol, groups);
236 if (!ev->sock)
237 return false;
238
239 ev->uloop.fd = nl_socket_get_fd(ev->sock);
240 ev->uloop.cb = cb;
241 if (uloop_fd_add(&ev->uloop, ULOOP_READ|flags))
242 return false;
243
244 return true;
245 }
246
247 static bool
248 create_event_socket(struct event_socket *ev, int protocol,
249 int (*cb)(struct nl_msg *msg, void *arg))
250 {
251 if (!create_raw_event_socket(ev, protocol, 0, handler_nl_event, ULOOP_ERROR_CB))
252 return false;
253
254 /* Install the valid custom callback handler */
255 nl_socket_modify_cb(ev->sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL);
256
257 /* Disable sequence number checking on event sockets */
258 nl_socket_disable_seq_check(ev->sock);
259
260 /* Increase rx buffer size to 65K on event sockets */
261 ev->bufsize = 65535;
262 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
263 return false;
264
265 return true;
266 }
267
268 static bool
269 create_hotplug_event_socket(struct event_socket *ev, int protocol,
270 void (*cb)(struct uloop_fd *u, unsigned int events))
271 {
272 if (!create_raw_event_socket(ev, protocol, 1, cb, ULOOP_ERROR_CB))
273 return false;
274
275 /* Increase rx buffer size to 65K on event sockets */
276 ev->bufsize = 65535;
277 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
278 return false;
279
280 return true;
281 }
282
283 static bool
284 system_rtn_aton(const char *src, unsigned int *dst)
285 {
286 char *e;
287 unsigned int n;
288
289 if (!strcmp(src, "local"))
290 n = RTN_LOCAL;
291 else if (!strcmp(src, "nat"))
292 n = RTN_NAT;
293 else if (!strcmp(src, "broadcast"))
294 n = RTN_BROADCAST;
295 else if (!strcmp(src, "anycast"))
296 n = RTN_ANYCAST;
297 else if (!strcmp(src, "multicast"))
298 n = RTN_MULTICAST;
299 else if (!strcmp(src, "prohibit"))
300 n = RTN_PROHIBIT;
301 else if (!strcmp(src, "unreachable"))
302 n = RTN_UNREACHABLE;
303 else if (!strcmp(src, "blackhole"))
304 n = RTN_BLACKHOLE;
305 else if (!strcmp(src, "xresolve"))
306 n = RTN_XRESOLVE;
307 else if (!strcmp(src, "unicast"))
308 n = RTN_UNICAST;
309 else if (!strcmp(src, "throw"))
310 n = RTN_THROW;
311 else if (!strcmp(src, "failed_policy"))
312 n = RTN_FAILED_POLICY;
313 else {
314 n = strtoul(src, &e, 0);
315 if (!e || *e || e == src || n > 255)
316 return false;
317 }
318
319 *dst = n;
320 return true;
321 }
322
323 static bool
324 system_tos_aton(const char *src, unsigned *dst)
325 {
326 char *e;
327
328 *dst = strtoul(src, &e, 16);
329 if (e == src || *e || *dst > 255)
330 return false;
331
332 return true;
333 }
334
335 int system_init(void)
336 {
337 static struct event_socket rtnl_event;
338 static struct event_socket hotplug_event;
339
340 sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0);
341 system_fd_set_cloexec(sock_ioctl);
342
343 /* Prepare socket for routing / address control */
344 sock_rtnl = create_socket(NETLINK_ROUTE, 0);
345 if (!sock_rtnl)
346 return -1;
347
348 if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event))
349 return -1;
350
351 if (!create_hotplug_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT,
352 handle_hotplug_event))
353 return -1;
354
355 /* Receive network link events form kernel */
356 nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK);
357
358 return 0;
359 }
360
361 static void write_file(const char *path, const char *val)
362 {
363 int fd;
364
365 fd = open(path, O_WRONLY);
366 if (fd < 0)
367 return;
368
369 if (write(fd, val, strlen(val))) {}
370 close(fd);
371 }
372
373 static int read_file(const char *path, char *buf, const size_t buf_sz)
374 {
375 int fd = -1, ret = -1;
376
377 fd = open(path, O_RDONLY);
378 if (fd < 0)
379 goto out;
380
381 ssize_t len = read(fd, buf, buf_sz - 1);
382 if (len < 0)
383 goto out;
384
385 ret = buf[len] = 0;
386
387 out:
388 if (fd >= 0)
389 close(fd);
390
391 return ret;
392 }
393
394
395 static const char *
396 dev_sysctl_path(const char *prefix, const char *ifname, const char *file)
397 {
398 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/%s/%s", proc_path, prefix, ifname, file);
399
400 return dev_buf;
401 }
402
403 static const char *
404 dev_sysfs_path(const char *ifname, const char *file)
405 {
406 snprintf(dev_buf, sizeof(dev_buf), "%s/class/net/%s/%s", sysfs_path, ifname, file);
407
408 return dev_buf;
409 }
410
411 static void
412 system_set_dev_sysctl(const char *prefix, const char *file, const char *ifname,
413 const char *val)
414 {
415 write_file(dev_sysctl_path(prefix, ifname, file), val);
416 }
417
418 static int
419 system_get_dev_sysctl(const char *prefix, const char *file, const char *ifname,
420 char *buf, size_t buf_sz)
421 {
422 return read_file(dev_sysctl_path(prefix, ifname, file), buf, buf_sz);
423 }
424
425 static void
426 system_set_dev_sysfs(const char *file, const char *ifname, const char *val)
427 {
428 if (!val)
429 return;
430
431 write_file(dev_sysfs_path(ifname, file), val);
432 }
433
434 static void
435 system_set_dev_sysfs_int(const char *file, const char *ifname, int val)
436 {
437 char buf[16];
438
439 snprintf(buf, sizeof(buf), "%d", val);
440 system_set_dev_sysfs(file, ifname, buf);
441 }
442
443 static int
444 system_get_dev_sysfs(const char *file, const char *ifname, char *buf, size_t buf_sz)
445 {
446 return read_file(dev_sysfs_path(ifname, file), buf, buf_sz);
447 }
448
449 static void system_set_disable_ipv6(struct device *dev, const char *val)
450 {
451 system_set_dev_sysctl("ipv6/conf", "disable_ipv6", dev->ifname, val);
452 }
453
454 static void system_set_ip6segmentrouting(struct device *dev, const char *val)
455 {
456 system_set_dev_sysctl("ipv6/conf", "seg6_enabled", dev->ifname, val);
457 }
458
459 static void system_set_rpfilter(struct device *dev, const char *val)
460 {
461 system_set_dev_sysctl("ipv4/conf", "rp_filter", dev->ifname, val);
462 }
463
464 static void system_set_acceptlocal(struct device *dev, const char *val)
465 {
466 system_set_dev_sysctl("ipv4/conf", "accept_local", dev->ifname, val);
467 }
468
469 static void system_set_igmpversion(struct device *dev, const char *val)
470 {
471 system_set_dev_sysctl("ipv4/conf", "force_igmp_version", dev->ifname, val);
472 }
473
474 static void system_set_mldversion(struct device *dev, const char *val)
475 {
476 system_set_dev_sysctl("ipv6/conf", "force_mld_version", dev->ifname, val);
477 }
478
479 static void system_set_neigh4reachabletime(struct device *dev, const char *val)
480 {
481 system_set_dev_sysctl("ipv4/neigh", "base_reachable_time_ms", dev->ifname, val);
482 }
483
484 static void system_set_neigh6reachabletime(struct device *dev, const char *val)
485 {
486 system_set_dev_sysctl("ipv6/neigh", "base_reachable_time_ms", dev->ifname, val);
487 }
488
489 static void system_set_neigh4gcstaletime(struct device *dev, const char *val)
490 {
491 system_set_dev_sysctl("ipv4/neigh", "gc_stale_time", dev->ifname, val);
492 }
493
494 static void system_set_neigh6gcstaletime(struct device *dev, const char *val)
495 {
496 system_set_dev_sysctl("ipv6/neigh", "gc_stale_time", dev->ifname, val);
497 }
498
499 static void system_set_neigh4locktime(struct device *dev, const char *val)
500 {
501 system_set_dev_sysctl("ipv4/neigh", "locktime", dev->ifname, val);
502 }
503
504 static void system_set_dadtransmits(struct device *dev, const char *val)
505 {
506 system_set_dev_sysctl("ipv6/conf", "dad_transmits", dev->ifname, val);
507 }
508
509 static void system_set_sendredirects(struct device *dev, const char *val)
510 {
511 system_set_dev_sysctl("ipv4/conf", "send_redirects", dev->ifname, val);
512 }
513
514 static void system_set_drop_v4_unicast_in_l2_multicast(struct device *dev, const char *val)
515 {
516 system_set_dev_sysctl("ipv4/conf", "drop_unicast_in_l2_multicast", dev->ifname, val);
517 }
518
519 static void system_set_drop_v6_unicast_in_l2_multicast(struct device *dev, const char *val)
520 {
521 system_set_dev_sysctl("ipv6/conf", "drop_unicast_in_l2_multicast", dev->ifname, val);
522 }
523
524 static void system_set_drop_gratuitous_arp(struct device *dev, const char *val)
525 {
526 system_set_dev_sysctl("ipv4/conf", "drop_gratuitous_arp", dev->ifname, val);
527 }
528
529 static void system_set_drop_unsolicited_na(struct device *dev, const char *val)
530 {
531 system_set_dev_sysctl("ipv6/conf", "drop_unsolicited_na", dev->ifname, val);
532 }
533
534 static void system_set_arp_accept(struct device *dev, const char *val)
535 {
536 system_set_dev_sysctl("ipv4/conf", "arp_accept", dev->ifname, val);
537 }
538
539 static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val)
540 {
541 system_set_dev_sysfs("brport/multicast_to_unicast", dev->ifname, val);
542 }
543
544 static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val)
545 {
546 system_set_dev_sysfs("brport/multicast_fast_leave", dev->ifname, val);
547 }
548
549 static void system_bridge_set_hairpin_mode(struct device *dev, const char *val)
550 {
551 system_set_dev_sysfs("brport/hairpin_mode", dev->ifname, val);
552 }
553
554 static void system_bridge_set_proxyarp_wifi(struct device *dev, const char *val)
555 {
556 system_set_dev_sysfs("brport/proxyarp_wifi", dev->ifname, val);
557 }
558
559 static void system_bridge_set_bpdu_filter(struct device *dev, const char *val)
560 {
561 system_set_dev_sysfs("brport/bpdu_filter", dev->ifname, val);
562 }
563
564 static void system_bridge_set_isolated(struct device *dev, const char *val)
565 {
566 system_set_dev_sysfs("brport/isolated", dev->ifname, val);
567 }
568
569 static void system_bridge_set_multicast_router(struct device *dev, const char *val)
570 {
571 system_set_dev_sysfs("brport/multicast_router", dev->ifname, val);
572 }
573
574 void system_bridge_set_stp_state(struct device *dev, bool val)
575 {
576 const char *valstr = val ? "1" : "0";
577
578 system_set_dev_sysfs("bridge/stp_state", dev->ifname, valstr);
579 }
580
581 static void system_bridge_set_learning(struct device *dev, const char *val)
582 {
583 system_set_dev_sysfs("brport/learning", dev->ifname, val);
584 }
585
586 static void system_bridge_set_unicast_flood(struct device *dev, const char *val)
587 {
588 system_set_dev_sysfs("brport/unicast_flood", dev->ifname, val);
589 }
590
591 static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz)
592 {
593 return system_get_dev_sysctl("ipv6/conf", "disable_ipv6",
594 dev->ifname, buf, buf_sz);
595 }
596
597 static int system_get_ip6segmentrouting(struct device *dev, char *buf, const size_t buf_sz)
598 {
599 return system_get_dev_sysctl("ipv6/conf", "seg6_enabled",
600 dev->ifname, buf, buf_sz);
601 }
602
603 static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz)
604 {
605 return system_get_dev_sysctl("ipv4/conf", "rp_filter",
606 dev->ifname, buf, buf_sz);
607 }
608
609 static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz)
610 {
611 return system_get_dev_sysctl("ipv4/conf", "accept_local",
612 dev->ifname, buf, buf_sz);
613 }
614
615 static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz)
616 {
617 return system_get_dev_sysctl("ipv4/conf", "force_igmp_version",
618 dev->ifname, buf, buf_sz);
619 }
620
621 static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz)
622 {
623 return system_get_dev_sysctl("ipv6/conf", "force_mld_version",
624 dev->ifname, buf, buf_sz);
625 }
626
627 static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz)
628 {
629 return system_get_dev_sysctl("ipv4/neigh", "base_reachable_time_ms",
630 dev->ifname, buf, buf_sz);
631 }
632
633 static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz)
634 {
635 return system_get_dev_sysctl("ipv6/neigh", "base_reachable_time_ms",
636 dev->ifname, buf, buf_sz);
637 }
638
639 static int system_get_neigh4gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
640 {
641 return system_get_dev_sysctl("ipv4/neigh", "gc_stale_time",
642 dev->ifname, buf, buf_sz);
643 }
644
645 static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
646 {
647 return system_get_dev_sysctl("ipv6/neigh", "gc_stale_time",
648 dev->ifname, buf, buf_sz);
649 }
650
651 static int system_get_neigh4locktime(struct device *dev, char *buf, const size_t buf_sz)
652 {
653 return system_get_dev_sysctl("ipv4/neigh", "locktime",
654 dev->ifname, buf, buf_sz);
655 }
656
657 static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz)
658 {
659 return system_get_dev_sysctl("ipv6/conf", "dad_transmits",
660 dev->ifname, buf, buf_sz);
661 }
662
663 static int system_get_sendredirects(struct device *dev, char *buf, const size_t buf_sz)
664 {
665 return system_get_dev_sysctl("ipv4/conf", "send_redirects",
666 dev->ifname, buf, buf_sz);
667 }
668
669
670 static int system_get_drop_v4_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz)
671 {
672 return system_get_dev_sysctl("ipv4/conf", "drop_unicast_in_l2_multicast",
673 dev->ifname, buf, buf_sz);
674 }
675
676 static int system_get_drop_v6_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz)
677 {
678 return system_get_dev_sysctl("ipv6/conf", "drop_unicast_in_l2_multicast",
679 dev->ifname, buf, buf_sz);
680 }
681
682 static int system_get_drop_gratuitous_arp(struct device *dev, char *buf, const size_t buf_sz)
683 {
684 return system_get_dev_sysctl("ipv4/conf", "drop_gratuitous_arp",
685 dev->ifname, buf, buf_sz);
686 }
687
688 static int system_get_drop_unsolicited_na(struct device *dev, char *buf, const size_t buf_sz)
689 {
690 return system_get_dev_sysctl("ipv6/conf", "drop_unsolicited_na",
691 dev->ifname, buf, buf_sz);
692 }
693
694 static int system_get_arp_accept(struct device *dev, char *buf, const size_t buf_sz)
695 {
696 return system_get_dev_sysctl("ipv4/conf", "arp_accept",
697 dev->ifname, buf, buf_sz);
698 }
699
700 #ifndef IFF_LOWER_UP
701 #define IFF_LOWER_UP 0x10000
702 #endif
703
704 static void
705 system_device_update_state(struct device *dev, unsigned int flags, unsigned int ifindex)
706 {
707 if (dev->type == &simple_device_type) {
708 if (dev->external)
709 device_set_disabled(dev, !(flags & IFF_UP));
710
711 device_set_present(dev, ifindex > 0);
712 }
713 device_set_link(dev, flags & IFF_LOWER_UP ? true : false);
714 }
715
716 /* Evaluate netlink messages */
717 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
718 {
719 struct nlmsghdr *nh = nlmsg_hdr(msg);
720 struct ifinfomsg *ifi = NLMSG_DATA(nh);
721 struct nlattr *nla[__IFLA_MAX];
722 struct device *dev;
723
724 if (nh->nlmsg_type != RTM_NEWLINK)
725 return 0;
726
727 nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL);
728 if (!nla[IFLA_IFNAME])
729 return 0;
730
731 dev = device_find(nla_data(nla[IFLA_IFNAME]));
732 if (!dev)
733 return 0;
734
735 system_device_update_state(dev, ifi->ifi_flags, ifi->ifi_index);
736 return 0;
737 }
738
739 static void
740 handle_hotplug_msg(char *data, int size)
741 {
742 const char *subsystem = NULL, *interface = NULL, *interface_old = NULL;
743 char *cur, *end, *sep;
744 int skip;
745 bool add;
746
747 if (!strncmp(data, "add@", 4) || !strncmp(data, "move@", 5))
748 add = true;
749 else if (!strncmp(data, "remove@", 7))
750 add = false;
751 else
752 return;
753
754 skip = strlen(data) + 1;
755 end = data + size;
756
757 for (cur = data + skip; cur < end; cur += skip) {
758 skip = strlen(cur) + 1;
759
760 sep = strchr(cur, '=');
761 if (!sep)
762 continue;
763
764 *sep = 0;
765 if (!strcmp(cur, "INTERFACE"))
766 interface = sep + 1;
767 else if (!strcmp(cur, "SUBSYSTEM")) {
768 subsystem = sep + 1;
769 if (strcmp(subsystem, "net") != 0)
770 return;
771 } else if (!strcmp(cur, "DEVPATH_OLD")) {
772 interface_old = strrchr(sep + 1, '/');
773 if (interface_old)
774 interface_old++;
775 }
776 }
777
778 if (!subsystem || !interface)
779 return;
780
781 if (interface_old)
782 device_hotplug_event(interface_old, false);
783
784 device_hotplug_event(interface, add);
785 }
786
787 static void
788 handle_hotplug_event(struct uloop_fd *u, unsigned int events)
789 {
790 struct event_socket *ev = container_of(u, struct event_socket, uloop);
791 struct sockaddr_nl nla;
792 unsigned char *buf = NULL;
793 int size;
794
795 while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) {
796 if (nla.nl_pid == 0)
797 handle_hotplug_msg((char *) buf, size);
798
799 free(buf);
800 }
801
802 switch (-size) {
803 case 0:
804 return;
805
806 case NLE_NOMEM:
807 /* Increase rx buffer size on netlink socket */
808 ev->bufsize *= 2;
809 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
810 goto abort;
811 break;
812
813 default:
814 goto abort;
815 }
816 return;
817
818 abort:
819 uloop_fd_delete(&ev->uloop);
820 return;
821 }
822
823 static int system_rtnl_call(struct nl_msg *msg)
824 {
825 int ret;
826
827 ret = nl_send_auto_complete(sock_rtnl, msg);
828 nlmsg_free(msg);
829
830 if (ret < 0)
831 return ret;
832
833 return nl_wait_for_ack(sock_rtnl);
834 }
835
836 static struct nl_msg *__system_ifinfo_msg(int af, int index, const char *ifname, uint16_t type, uint16_t flags)
837 {
838 struct nl_msg *msg;
839 struct ifinfomsg iim = {
840 .ifi_family = af,
841 .ifi_index = index,
842 };
843
844 msg = nlmsg_alloc_simple(type, flags | NLM_F_REQUEST);
845 if (!msg)
846 return NULL;
847
848 nlmsg_append(msg, &iim, sizeof(iim), 0);
849 if (ifname)
850 nla_put_string(msg, IFLA_IFNAME, ifname);
851
852 return msg;
853 }
854
855 static struct nl_msg *system_ifinfo_msg(const char *ifname, uint16_t type, uint16_t flags)
856 {
857 return __system_ifinfo_msg(AF_UNSPEC, 0, ifname, type, flags);
858 }
859
860 static int system_link_del(const char *ifname)
861 {
862 struct nl_msg *msg;
863
864 msg = system_ifinfo_msg(ifname, RTM_DELLINK, 0);
865 if (!msg)
866 return -1;
867
868 return system_rtnl_call(msg);
869 }
870
871 int system_bridge_delbr(struct device *bridge)
872 {
873 return system_link_del(bridge->ifname);
874 }
875
876 static int system_bridge_if(const char *bridge, struct device *dev, int cmd, void *data)
877 {
878 struct ifreq ifr;
879
880 memset(&ifr, 0, sizeof(ifr));
881 if (dev)
882 ifr.ifr_ifindex = dev->ifindex;
883 else
884 ifr.ifr_data = data;
885 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
886 return ioctl(sock_ioctl, cmd, &ifr);
887 }
888
889 static bool system_is_bridge(const char *name)
890 {
891 struct stat st;
892
893 return stat(dev_sysfs_path(name, "bridge"), &st) >= 0;
894 }
895
896 static char *system_get_bridge(const char *name, char *buf, int buflen)
897 {
898 char *path;
899 ssize_t len = -1;
900 glob_t gl;
901
902 snprintf(buf, buflen, "%s/devices/virtual/net/*/brif/%s/bridge", sysfs_path, name);
903 if (glob(buf, GLOB_NOSORT, NULL, &gl) < 0)
904 return NULL;
905
906 if (gl.gl_pathc > 0)
907 len = readlink(gl.gl_pathv[0], buf, buflen);
908
909 globfree(&gl);
910
911 if (len < 0)
912 return NULL;
913
914 buf[len] = 0;
915 path = strrchr(buf, '/');
916 if (!path)
917 return NULL;
918
919 return path + 1;
920 }
921
922 static void
923 system_bridge_set_wireless(struct device *bridge, struct device *dev)
924 {
925 bool mcast_to_ucast = dev->wireless_ap;
926 bool hairpin;
927
928 if (dev->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST)
929 mcast_to_ucast = dev->settings.multicast_to_unicast;
930 else if (bridge->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST &&
931 !bridge->settings.multicast_to_unicast)
932 mcast_to_ucast = false;
933
934 hairpin = mcast_to_ucast || dev->wireless_proxyarp;
935 if (dev->wireless_isolate)
936 hairpin = false;
937
938 system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : "0");
939 system_bridge_set_hairpin_mode(dev, hairpin ? "1" : "0");
940 system_bridge_set_proxyarp_wifi(dev, dev->wireless_proxyarp ? "1" : "0");
941 }
942
943 int system_bridge_addif(struct device *bridge, struct device *dev)
944 {
945 char buf[64];
946 char *oldbr;
947 int tries = 0;
948 int ret;
949
950
951 for (tries = 0; tries < 3; tries++) {
952 ret = 0;
953 oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
954 if (oldbr && !strcmp(oldbr, bridge->ifname))
955 break;
956
957 ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
958 if (!ret)
959 break;
960
961 D(SYSTEM, "Failed to add device '%s' to bridge '%s' (tries=%d): %s",
962 dev->ifname, bridge->ifname, tries, strerror(errno));
963 }
964
965 if (dev->wireless)
966 system_bridge_set_wireless(bridge, dev);
967
968 if (dev->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
969 snprintf(buf, sizeof(buf), "%u", dev->settings.multicast_router);
970 system_bridge_set_multicast_router(dev, buf);
971 }
972
973 if (dev->settings.flags & DEV_OPT_MULTICAST_FAST_LEAVE &&
974 dev->settings.multicast_fast_leave)
975 system_bridge_set_multicast_fast_leave(dev, "1");
976
977 if (dev->settings.flags & DEV_OPT_LEARNING &&
978 !dev->settings.learning)
979 system_bridge_set_learning(dev, "0");
980
981 if (dev->settings.flags & DEV_OPT_UNICAST_FLOOD &&
982 !dev->settings.unicast_flood)
983 system_bridge_set_unicast_flood(dev, "0");
984
985 if (dev->settings.flags & DEV_OPT_ISOLATE &&
986 dev->settings.isolate)
987 system_bridge_set_isolated(dev, "1");
988
989 if (dev->bpdu_filter)
990 system_bridge_set_bpdu_filter(dev, dev->bpdu_filter ? "1" : "0");
991
992 return ret;
993 }
994
995 int system_bridge_delif(struct device *bridge, struct device *dev)
996 {
997 return system_bridge_if(bridge->ifname, dev, SIOCBRDELIF, NULL);
998 }
999
1000 int system_bridge_vlan(const char *iface, uint16_t vid, int16_t vid_end, bool add, unsigned int vflags)
1001 {
1002 struct bridge_vlan_info vinfo = { .vid = vid, };
1003 unsigned short flags = 0;
1004 struct nlattr *afspec;
1005 struct nl_msg *nlm;
1006 int index;
1007 int ret = 0;
1008
1009 index = if_nametoindex(iface);
1010 if (!index)
1011 return -1;
1012
1013 nlm = __system_ifinfo_msg(PF_BRIDGE, index, NULL, add ? RTM_SETLINK : RTM_DELLINK, 0);
1014 if (!nlm)
1015 return -1;
1016
1017 if (vflags & BRVLAN_F_SELF)
1018 flags |= BRIDGE_FLAGS_SELF;
1019
1020 if (vflags & BRVLAN_F_PVID)
1021 vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
1022
1023 if (vflags & BRVLAN_F_UNTAGGED)
1024 vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
1025
1026 afspec = nla_nest_start(nlm, IFLA_AF_SPEC);
1027 if (!afspec) {
1028 ret = -ENOMEM;
1029 goto failure;
1030 }
1031
1032 if (flags)
1033 nla_put_u16(nlm, IFLA_BRIDGE_FLAGS, flags);
1034
1035 if (vid_end > vid)
1036 vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN;
1037
1038 nla_put(nlm, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo);
1039
1040 if (vid_end > vid) {
1041 vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
1042 vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END;
1043 vinfo.vid = vid_end;
1044 nla_put(nlm, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo);
1045 }
1046
1047 nla_nest_end(nlm, afspec);
1048
1049 return system_rtnl_call(nlm);
1050
1051 failure:
1052 nlmsg_free(nlm);
1053 return ret;
1054 }
1055
1056 int system_bonding_set_device(struct device *dev, struct bonding_config *cfg)
1057 {
1058 const char *ifname = dev->ifname;
1059 struct blob_attr *cur;
1060 char op = cfg ? '+' : '-';
1061 char buf[64];
1062 size_t rem;
1063
1064 snprintf(dev_buf, sizeof(dev_buf), "%s/class/net/bonding_masters", sysfs_path);
1065 snprintf(buf, sizeof(buf), "%c%s", op, ifname);
1066 write_file(dev_buf, buf);
1067
1068 if (!cfg)
1069 return 0;
1070
1071 system_set_dev_sysfs("bonding/mode", ifname, bonding_policy_str[cfg->policy]);
1072
1073 system_set_dev_sysfs_int("bonding/all_ports_active", ifname, cfg->all_ports_active);
1074
1075 if (cfg->policy == BONDING_MODE_BALANCE_XOR ||
1076 cfg->policy == BONDING_MODE_BALANCE_TLB ||
1077 cfg->policy == BONDING_MODE_8023AD)
1078 system_set_dev_sysfs("bonding/xmit_hash_policy", ifname, cfg->xmit_hash_policy);
1079
1080 if (cfg->policy == BONDING_MODE_8023AD) {
1081 system_set_dev_sysfs("bonding/ad_actor_system", ifname, cfg->ad_actor_system);
1082 system_set_dev_sysfs_int("bonding/ad_actor_sys_prio", ifname, cfg->ad_actor_sys_prio);
1083 system_set_dev_sysfs("bonding/ad_select", ifname, cfg->ad_select);
1084 system_set_dev_sysfs("bonding/lacp_rate", ifname, cfg->lacp_rate);
1085 system_set_dev_sysfs_int("bonding/min_links", ifname, cfg->min_links);
1086 }
1087
1088 if (cfg->policy == BONDING_MODE_BALANCE_RR)
1089 system_set_dev_sysfs_int("bonding/packets_per_slave", ifname, cfg->packets_per_port);
1090
1091 if (cfg->policy == BONDING_MODE_BALANCE_TLB ||
1092 cfg->policy == BONDING_MODE_BALANCE_ALB)
1093 system_set_dev_sysfs_int("bonding/lp_interval", ifname, cfg->lp_interval);
1094
1095 if (cfg->policy == BONDING_MODE_BALANCE_TLB)
1096 system_set_dev_sysfs_int("bonding/tlb_dynamic_lb", ifname, cfg->dynamic_lb);
1097 system_set_dev_sysfs_int("bonding/resend_igmp", ifname, cfg->resend_igmp);
1098 system_set_dev_sysfs_int("bonding/num_grat_arp", ifname, cfg->num_peer_notif);
1099 system_set_dev_sysfs("bonding/primary_reselect", ifname, cfg->primary_reselect);
1100 system_set_dev_sysfs("bonding/fail_over_mac", ifname, cfg->failover_mac);
1101
1102 system_set_dev_sysfs_int((cfg->monitor_arp ?
1103 "bonding/arp_interval" :
1104 "bonding/miimon"), ifname, cfg->monitor_interval);
1105
1106 blobmsg_for_each_attr(cur, cfg->arp_target, rem) {
1107 snprintf(buf, sizeof(buf), "+%s", blobmsg_get_string(cur));
1108 system_set_dev_sysfs("bonding/arp_ip_target", ifname, buf);
1109 }
1110
1111 system_set_dev_sysfs_int("bonding/arp_all_targets", ifname, cfg->arp_all_targets);
1112 if (cfg->policy < BONDING_MODE_8023AD)
1113 system_set_dev_sysfs("bonding/arp_validate", ifname, cfg->arp_validate);
1114 system_set_dev_sysfs_int("bonding/use_carrier", ifname, cfg->use_carrier);
1115 if (!cfg->monitor_arp && cfg->monitor_interval) {
1116 system_set_dev_sysfs_int("bonding/updelay", ifname, cfg->updelay);
1117 system_set_dev_sysfs_int("bonding/downdelay", ifname, cfg->downdelay);
1118 }
1119
1120 return 0;
1121 }
1122
1123 int system_bonding_set_port(struct device *dev, struct device *port, bool add, bool primary)
1124 {
1125 const char *port_name = port->ifname;
1126 const char op_ch = add ? '+' : '-';
1127 char buf[IFNAMSIZ + 1];
1128
1129 snprintf(buf, sizeof(buf), "%c%s", op_ch, port_name);
1130 system_if_down(port);
1131 system_set_dev_sysfs("bonding/slaves", dev->ifname, buf);
1132 system_if_up(port);
1133
1134 if (primary)
1135 system_set_dev_sysfs("bonding/primary", dev->ifname,
1136 add ? port_name : "");
1137
1138 return 0;
1139 }
1140
1141 int system_if_resolve(struct device *dev)
1142 {
1143 struct ifreq ifr;
1144
1145 memset(&ifr, 0, sizeof(ifr));
1146 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1147 if (!ioctl(sock_ioctl, SIOCGIFINDEX, &ifr))
1148 return ifr.ifr_ifindex;
1149 else
1150 return 0;
1151 }
1152
1153 static int system_if_flags(const char *ifname, unsigned add, unsigned rem)
1154 {
1155 struct ifreq ifr;
1156
1157 memset(&ifr, 0, sizeof(ifr));
1158 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
1159 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) < 0)
1160 return -1;
1161
1162 ifr.ifr_flags |= add;
1163 ifr.ifr_flags &= ~rem;
1164 return ioctl(sock_ioctl, SIOCSIFFLAGS, &ifr);
1165 }
1166
1167 struct clear_data {
1168 struct nl_msg *msg;
1169 struct device *dev;
1170 int type;
1171 int size;
1172 int af;
1173 };
1174
1175
1176 static bool check_ifaddr(struct nlmsghdr *hdr, int ifindex)
1177 {
1178 struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
1179
1180 return (long)ifa->ifa_index == ifindex;
1181 }
1182
1183 static bool check_route(struct nlmsghdr *hdr, int ifindex)
1184 {
1185 struct rtmsg *r = NLMSG_DATA(hdr);
1186 struct nlattr *tb[__RTA_MAX];
1187
1188 if (r->rtm_protocol == RTPROT_KERNEL &&
1189 r->rtm_family == AF_INET6)
1190 return false;
1191
1192 nlmsg_parse(hdr, sizeof(struct rtmsg), tb, __RTA_MAX - 1, NULL);
1193 if (!tb[RTA_OIF])
1194 return false;
1195
1196 return *(int *)RTA_DATA(tb[RTA_OIF]) == ifindex;
1197 }
1198
1199 static bool check_rule(struct nlmsghdr *hdr, int ifindex)
1200 {
1201 return true;
1202 }
1203
1204 static int cb_clear_event(struct nl_msg *msg, void *arg)
1205 {
1206 struct clear_data *clr = arg;
1207 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1208 bool (*cb)(struct nlmsghdr *, int ifindex);
1209 int type, ret;
1210
1211 switch(clr->type) {
1212 case RTM_GETADDR:
1213 type = RTM_DELADDR;
1214 if (hdr->nlmsg_type != RTM_NEWADDR)
1215 return NL_SKIP;
1216
1217 cb = check_ifaddr;
1218 break;
1219 case RTM_GETROUTE:
1220 type = RTM_DELROUTE;
1221 if (hdr->nlmsg_type != RTM_NEWROUTE)
1222 return NL_SKIP;
1223
1224 cb = check_route;
1225 break;
1226 case RTM_GETRULE:
1227 type = RTM_DELRULE;
1228 if (hdr->nlmsg_type != RTM_NEWRULE)
1229 return NL_SKIP;
1230
1231 cb = check_rule;
1232 break;
1233 default:
1234 return NL_SKIP;
1235 }
1236
1237 if (!cb(hdr, clr->dev ? clr->dev->ifindex : 0))
1238 return NL_SKIP;
1239
1240 if (type == RTM_DELRULE)
1241 D(SYSTEM, "Remove a rule");
1242 else
1243 D(SYSTEM, "Remove %s from device %s",
1244 type == RTM_DELADDR ? "an address" : "a route",
1245 clr->dev->ifname);
1246
1247 memcpy(nlmsg_hdr(clr->msg), hdr, hdr->nlmsg_len);
1248 hdr = nlmsg_hdr(clr->msg);
1249 hdr->nlmsg_type = type;
1250 hdr->nlmsg_flags = NLM_F_REQUEST;
1251
1252 nl_socket_disable_auto_ack(sock_rtnl);
1253 ret = nl_send_auto_complete(sock_rtnl, clr->msg);
1254 if (ret < 0) {
1255 if (type == RTM_DELRULE)
1256 D(SYSTEM, "Error deleting a rule: %d", ret);
1257 else
1258 D(SYSTEM, "Error deleting %s from device '%s': %d",
1259 type == RTM_DELADDR ? "an address" : "a route",
1260 clr->dev->ifname, ret);
1261 }
1262
1263 nl_socket_enable_auto_ack(sock_rtnl);
1264
1265 return NL_SKIP;
1266 }
1267
1268 static int
1269 cb_finish_event(struct nl_msg *msg, void *arg)
1270 {
1271 int *pending = arg;
1272 *pending = 0;
1273 return NL_STOP;
1274 }
1275
1276 static int
1277 error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1278 {
1279 int *pending = arg;
1280 *pending = err->error;
1281 return NL_STOP;
1282 }
1283
1284 static void
1285 system_if_clear_entries(struct device *dev, int type, int af)
1286 {
1287 struct clear_data clr;
1288 struct nl_cb *cb;
1289 struct rtmsg rtm = {
1290 .rtm_family = af,
1291 .rtm_flags = RTM_F_CLONED,
1292 };
1293 int flags = NLM_F_DUMP;
1294 int pending = 1;
1295
1296 clr.af = af;
1297 clr.dev = dev;
1298 clr.type = type;
1299 switch (type) {
1300 case RTM_GETADDR:
1301 case RTM_GETRULE:
1302 clr.size = sizeof(struct rtgenmsg);
1303 break;
1304 case RTM_GETROUTE:
1305 clr.size = sizeof(struct rtmsg);
1306 break;
1307 default:
1308 return;
1309 }
1310
1311 cb = nl_cb_alloc(NL_CB_DEFAULT);
1312 if (!cb)
1313 return;
1314
1315 clr.msg = nlmsg_alloc_simple(type, flags);
1316 if (!clr.msg)
1317 goto out;
1318
1319 nlmsg_append(clr.msg, &rtm, clr.size, 0);
1320 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_clear_event, &clr);
1321 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_finish_event, &pending);
1322 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &pending);
1323
1324 if (nl_send_auto_complete(sock_rtnl, clr.msg) < 0)
1325 goto free;
1326
1327 while (pending > 0)
1328 nl_recvmsgs(sock_rtnl, cb);
1329
1330 free:
1331 nlmsg_free(clr.msg);
1332 out:
1333 nl_cb_put(cb);
1334 }
1335
1336 /*
1337 * Clear bridge (membership) state and bring down device
1338 */
1339 void system_if_clear_state(struct device *dev)
1340 {
1341 static char buf[256];
1342 char *bridge;
1343 device_set_ifindex(dev, system_if_resolve(dev));
1344
1345 if (dev->external || !dev->ifindex)
1346 return;
1347
1348 system_if_flags(dev->ifname, 0, IFF_UP);
1349
1350 if (system_is_bridge(dev->ifname)) {
1351 D(SYSTEM, "Delete existing bridge named '%s'", dev->ifname);
1352 system_bridge_delbr(dev);
1353 return;
1354 }
1355
1356 bridge = system_get_bridge(dev->ifname, buf, sizeof(buf));
1357 if (bridge) {
1358 D(SYSTEM, "Remove device '%s' from bridge '%s'", dev->ifname, bridge);
1359 system_bridge_if(bridge, dev, SIOCBRDELIF, NULL);
1360 }
1361
1362 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET);
1363 system_if_clear_entries(dev, RTM_GETADDR, AF_INET);
1364 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6);
1365 system_if_clear_entries(dev, RTM_GETADDR, AF_INET6);
1366 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET);
1367 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET6);
1368 system_set_disable_ipv6(dev, "0");
1369 }
1370
1371 static inline unsigned long
1372 sec_to_jiffies(int val)
1373 {
1374 return (unsigned long) val * 100;
1375 }
1376
1377 int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
1378 {
1379 struct nlattr *linkinfo, *data;
1380 struct nl_msg *msg;
1381 uint64_t val;
1382 int rv;
1383
1384 msg = system_ifinfo_msg(bridge->ifname, RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL);
1385 if (!msg)
1386 return -1;
1387
1388 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1389 goto nla_put_failure;
1390
1391 nla_put_string(msg, IFLA_INFO_KIND, "bridge");
1392
1393 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1394 goto nla_put_failure;
1395
1396 nla_put_u32(msg, IFLA_BR_STP_STATE, cfg->stp);
1397 nla_put_u32(msg, IFLA_BR_FORWARD_DELAY, sec_to_jiffies(cfg->forward_delay));
1398 nla_put_u8(msg, IFLA_BR_MCAST_SNOOPING, !!cfg->igmp_snoop);
1399 nla_put_u8(msg, IFLA_BR_MCAST_QUERIER, !!cfg->multicast_querier);
1400 nla_put_u32(msg, IFLA_BR_MCAST_HASH_MAX, cfg->hash_max);
1401
1402 if (bridge->settings.flags & DEV_OPT_MULTICAST_ROUTER)
1403 nla_put_u8(msg, IFLA_BR_MCAST_ROUTER, !!bridge->settings.multicast_router);
1404
1405 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS) {
1406 nla_put_u32(msg, IFLA_BR_MCAST_STARTUP_QUERY_CNT, cfg->robustness);
1407 nla_put_u32(msg, IFLA_BR_MCAST_LAST_MEMBER_CNT, cfg->robustness);
1408 }
1409
1410 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL)
1411 nla_put_u64(msg, IFLA_BR_MCAST_QUERY_INTVL, cfg->query_interval);
1412
1413 if (cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL)
1414 nla_put_u64(msg, IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, cfg->query_response_interval);
1415
1416 if (cfg->flags & BRIDGE_OPT_LAST_MEMBER_INTERVAL)
1417 nla_put_u64(msg, IFLA_BR_MCAST_LAST_MEMBER_INTVL, cfg->last_member_interval);
1418
1419 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS ||
1420 cfg->flags & BRIDGE_OPT_QUERY_INTERVAL ||
1421 cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
1422 val = cfg->robustness * cfg->query_interval +
1423 cfg->query_response_interval;
1424
1425 nla_put_u64(msg, IFLA_BR_MCAST_MEMBERSHIP_INTVL, val);
1426
1427 val -= cfg->query_response_interval / 2;
1428
1429 nla_put_u64(msg, IFLA_BR_MCAST_QUERIER_INTVL, val);
1430 }
1431
1432 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1433 val = cfg->query_interval / 4;
1434
1435 nla_put_u64(msg, IFLA_BR_MCAST_STARTUP_QUERY_INTVL, val);
1436 }
1437
1438 nla_put_u8(msg, IFLA_BR_VLAN_FILTERING, !!cfg->vlan_filtering);
1439 nla_put_u16(msg, IFLA_BR_PRIORITY, cfg->priority);
1440 nla_put_u32(msg, IFLA_BR_HELLO_TIME, sec_to_jiffies(cfg->hello_time));
1441 nla_put_u32(msg, IFLA_BR_MAX_AGE, sec_to_jiffies(cfg->max_age));
1442
1443 if (cfg->flags & BRIDGE_OPT_AGEING_TIME)
1444 nla_put_u32(msg, IFLA_BR_AGEING_TIME, sec_to_jiffies(cfg->ageing_time));
1445
1446 nla_nest_end(msg, data);
1447 nla_nest_end(msg, linkinfo);
1448
1449 rv = system_rtnl_call(msg);
1450 if (rv)
1451 D(SYSTEM, "Error adding bridge '%s': %d", bridge->ifname, rv);
1452
1453 return rv;
1454
1455 nla_put_failure:
1456 nlmsg_free(msg);
1457 return -ENOMEM;
1458 }
1459
1460 int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg)
1461 {
1462 struct nl_msg *msg;
1463 struct nlattr *linkinfo, *data;
1464 size_t i;
1465 int rv;
1466 static const struct {
1467 const char *name;
1468 enum macvlan_mode val;
1469 } modes[] = {
1470 { "private", MACVLAN_MODE_PRIVATE },
1471 { "vepa", MACVLAN_MODE_VEPA },
1472 { "bridge", MACVLAN_MODE_BRIDGE },
1473 { "passthru", MACVLAN_MODE_PASSTHRU },
1474 };
1475
1476 msg = system_ifinfo_msg(macvlan->ifname, RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL);
1477 if (!msg)
1478 return -1;
1479
1480 if (cfg->flags & MACVLAN_OPT_MACADDR)
1481 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1482 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1483
1484 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1485 goto nla_put_failure;
1486
1487 nla_put_string(msg, IFLA_INFO_KIND, "macvlan");
1488
1489 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1490 goto nla_put_failure;
1491
1492 if (cfg->mode) {
1493 for (i = 0; i < ARRAY_SIZE(modes); i++) {
1494 if (strcmp(cfg->mode, modes[i].name) != 0)
1495 continue;
1496
1497 nla_put_u32(msg, IFLA_MACVLAN_MODE, modes[i].val);
1498 break;
1499 }
1500 }
1501
1502 nla_nest_end(msg, data);
1503 nla_nest_end(msg, linkinfo);
1504
1505 rv = system_rtnl_call(msg);
1506 if (rv)
1507 D(SYSTEM, "Error adding macvlan '%s' over '%s': %d", macvlan->ifname, dev->ifname, rv);
1508
1509 return rv;
1510
1511 nla_put_failure:
1512 nlmsg_free(msg);
1513 return -ENOMEM;
1514 }
1515
1516 int system_link_netns_move(struct device *dev, int netns_fd, const char *target_ifname)
1517 {
1518 struct nl_msg *msg;
1519 int index;
1520
1521 if (!dev)
1522 return -1;
1523
1524 index = system_if_resolve(dev);
1525 msg = __system_ifinfo_msg(AF_UNSPEC, index, target_ifname, RTM_NEWLINK, 0);
1526 if (!msg)
1527 return -1;
1528
1529 nla_put_u32(msg, IFLA_NET_NS_FD, netns_fd);
1530 return system_rtnl_call(msg);
1531 }
1532
1533 int system_macvlan_del(struct device *macvlan)
1534 {
1535 return system_link_del(macvlan->ifname);
1536 }
1537
1538 int system_netns_open(const pid_t target_ns)
1539 {
1540 char pid_net_path[PATH_MAX];
1541
1542 snprintf(pid_net_path, sizeof(pid_net_path), "/proc/%u/ns/net", target_ns);
1543
1544 return open(pid_net_path, O_RDONLY);
1545 }
1546
1547 int system_netns_set(int netns_fd)
1548 {
1549 return setns(netns_fd, CLONE_NEWNET);
1550 }
1551
1552 int system_veth_add(struct device *veth, struct veth_config *cfg)
1553 {
1554 struct nl_msg *msg;
1555 struct ifinfomsg empty_iim = {0,};
1556 struct nlattr *linkinfo, *data, *veth_info;
1557 int rv;
1558
1559 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1560
1561 if (!msg)
1562 return -1;
1563
1564 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1565
1566 if (cfg->flags & VETH_OPT_MACADDR)
1567 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1568 nla_put_string(msg, IFLA_IFNAME, veth->ifname);
1569
1570 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1571 goto nla_put_failure;
1572
1573 nla_put_string(msg, IFLA_INFO_KIND, "veth");
1574
1575 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1576 goto nla_put_failure;
1577
1578 if (!(veth_info = nla_nest_start(msg, VETH_INFO_PEER)))
1579 goto nla_put_failure;
1580
1581 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
1582
1583 if (cfg->flags & VETH_OPT_PEER_NAME)
1584 nla_put_string(msg, IFLA_IFNAME, cfg->peer_name);
1585 if (cfg->flags & VETH_OPT_PEER_MACADDR)
1586 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->peer_macaddr), cfg->peer_macaddr);
1587
1588 nla_nest_end(msg, veth_info);
1589 nla_nest_end(msg, data);
1590 nla_nest_end(msg, linkinfo);
1591
1592 rv = system_rtnl_call(msg);
1593 if (rv) {
1594 if (cfg->flags & VETH_OPT_PEER_NAME)
1595 D(SYSTEM, "Error adding veth '%s' with peer '%s': %d", veth->ifname, cfg->peer_name, rv);
1596 else
1597 D(SYSTEM, "Error adding veth '%s': %d", veth->ifname, rv);
1598 }
1599
1600 return rv;
1601
1602 nla_put_failure:
1603 nlmsg_free(msg);
1604 return -ENOMEM;
1605 }
1606
1607 int system_veth_del(struct device *veth)
1608 {
1609 return system_link_del(veth->ifname);
1610 }
1611
1612 static int system_vlan(struct device *dev, int id)
1613 {
1614 struct vlan_ioctl_args ifr = {
1615 .cmd = SET_VLAN_NAME_TYPE_CMD,
1616 .u.name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD,
1617 };
1618
1619 if (ioctl(sock_ioctl, SIOCSIFVLAN, &ifr) < 0)
1620 return -1;
1621
1622 if (id < 0) {
1623 ifr.cmd = DEL_VLAN_CMD;
1624 ifr.u.VID = 0;
1625 } else {
1626 ifr.cmd = ADD_VLAN_CMD;
1627 ifr.u.VID = id;
1628 }
1629 strncpy(ifr.device1, dev->ifname, sizeof(ifr.device1));
1630 return ioctl(sock_ioctl, SIOCSIFVLAN, &ifr);
1631 }
1632
1633 int system_vlan_add(struct device *dev, int id)
1634 {
1635 return system_vlan(dev, id);
1636 }
1637
1638 int system_vlan_del(struct device *dev)
1639 {
1640 return system_vlan(dev, -1);
1641 }
1642
1643 int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg)
1644 {
1645 struct nl_msg *msg;
1646 struct nlattr *linkinfo, *data, *qos;
1647 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC };
1648 struct vlan_qos_mapping *elem;
1649 struct ifla_vlan_qos_mapping nl_qos_map;
1650 int rv;
1651
1652 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1653
1654 if (!msg)
1655 return -1;
1656
1657 nlmsg_append(msg, &iim, sizeof(iim), 0);
1658 nla_put_string(msg, IFLA_IFNAME, vlandev->ifname);
1659 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1660
1661 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1662 goto nla_put_failure;
1663
1664 nla_put_string(msg, IFLA_INFO_KIND, "vlan");
1665
1666 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1667 goto nla_put_failure;
1668
1669 nla_put_u16(msg, IFLA_VLAN_ID, cfg->vid);
1670
1671 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
1672 nla_put_u16(msg, IFLA_VLAN_PROTOCOL, htons(cfg->proto));
1673 #else
1674 if(cfg->proto == VLAN_PROTO_8021AD)
1675 netifd_log_message(L_WARNING, "%s Your kernel is older than linux 3.10.0, 802.1ad is not supported defaulting to 802.1q", vlandev->type->name);
1676 #endif
1677
1678 if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS)))
1679 goto nla_put_failure;
1680
1681 vlist_simple_for_each_element(&cfg->ingress_qos_mapping_list, elem, node) {
1682 nl_qos_map.from = elem->from;
1683 nl_qos_map.to = elem->to;
1684 nla_put(msg, IFLA_VLAN_QOS_MAPPING, sizeof(nl_qos_map), &nl_qos_map);
1685 }
1686 nla_nest_end(msg, qos);
1687
1688 if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS)))
1689 goto nla_put_failure;
1690
1691 vlist_simple_for_each_element(&cfg->egress_qos_mapping_list, elem, node) {
1692 nl_qos_map.from = elem->from;
1693 nl_qos_map.to = elem->to;
1694 nla_put(msg, IFLA_VLAN_QOS_MAPPING, sizeof(nl_qos_map), &nl_qos_map);
1695 }
1696 nla_nest_end(msg, qos);
1697
1698 nla_nest_end(msg, data);
1699 nla_nest_end(msg, linkinfo);
1700
1701 rv = system_rtnl_call(msg);
1702 if (rv)
1703 D(SYSTEM, "Error adding vlandev '%s' over '%s': %d", vlandev->ifname, dev->ifname, rv);
1704
1705 return rv;
1706
1707 nla_put_failure:
1708 nlmsg_free(msg);
1709 return -ENOMEM;
1710 }
1711
1712 int system_vlandev_del(struct device *vlandev)
1713 {
1714 return system_link_del(vlandev->ifname);
1715 }
1716
1717 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
1718 struct if_get_master_data {
1719 int ifindex;
1720 int master_ifindex;
1721 int pending;
1722 };
1723
1724 static void if_get_master_dsa_linkinfo_attr(struct if_get_master_data *data,
1725 struct rtattr *attr)
1726 {
1727 struct rtattr *cur;
1728 int rem = RTA_PAYLOAD(attr);
1729
1730 for (cur = RTA_DATA(attr); RTA_OK(cur, rem); cur = RTA_NEXT(cur, rem)) {
1731 if (cur->rta_type != IFLA_DSA_MASTER)
1732 continue;
1733
1734 data->master_ifindex = *(__u32 *)RTA_DATA(cur);
1735 }
1736 }
1737
1738 static void if_get_master_linkinfo_attr(struct if_get_master_data *data,
1739 struct rtattr *attr)
1740 {
1741 struct rtattr *cur;
1742 int rem = RTA_PAYLOAD(attr);
1743
1744 for (cur = RTA_DATA(attr); RTA_OK(cur, rem); cur = RTA_NEXT(cur, rem)) {
1745 if (cur->rta_type != IFLA_INFO_KIND && cur->rta_type != IFLA_INFO_DATA)
1746 continue;
1747
1748 if (cur->rta_type == IFLA_INFO_KIND && strcmp("dsa", (char *)RTA_DATA(cur)))
1749 break;
1750
1751 if (cur->rta_type == IFLA_INFO_DATA)
1752 if_get_master_dsa_linkinfo_attr(data, cur);
1753 }
1754 }
1755
1756 static int cb_if_get_master_valid(struct nl_msg *msg, void *arg)
1757 {
1758 struct nlmsghdr *nh = nlmsg_hdr(msg);
1759 struct ifinfomsg *ifi = NLMSG_DATA(nh);
1760 struct if_get_master_data *data = (struct if_get_master_data *)arg;
1761 struct rtattr *attr;
1762 int rem;
1763
1764 if (nh->nlmsg_type != RTM_NEWLINK)
1765 return NL_SKIP;
1766
1767 if (ifi->ifi_family != AF_UNSPEC)
1768 return NL_SKIP;
1769
1770 if (ifi->ifi_index != data->ifindex)
1771 return NL_SKIP;
1772
1773 attr = IFLA_RTA(ifi);
1774 rem = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
1775
1776 while (RTA_OK(attr, rem)) {
1777 if (attr->rta_type == IFLA_LINKINFO)
1778 if_get_master_linkinfo_attr(data, attr);
1779
1780 attr = RTA_NEXT(attr, rem);
1781 }
1782
1783 return NL_OK;
1784 }
1785
1786 static int cb_if_get_master_ack(struct nl_msg *msg, void *arg)
1787 {
1788 struct if_get_master_data *data = (struct if_get_master_data *)arg;
1789 data->pending = 0;
1790 return NL_STOP;
1791 }
1792
1793 static int cb_if_get_master_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1794 {
1795 struct if_get_master_data *data = (struct if_get_master_data *)arg;
1796 data->pending = 0;
1797 return NL_STOP;
1798 }
1799
1800 static int system_if_get_master_ifindex(struct device *dev)
1801 {
1802 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1803 struct nl_msg *msg;
1804 struct ifinfomsg ifi = {
1805 .ifi_family = AF_UNSPEC,
1806 .ifi_index = 0,
1807 };
1808 struct if_get_master_data data = {
1809 .ifindex = if_nametoindex(dev->ifname),
1810 .master_ifindex = -1,
1811 .pending = 1,
1812 };
1813 int ret = -1;
1814
1815 if (!cb)
1816 return ret;
1817
1818 msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1819 if (!msg)
1820 goto out;
1821
1822 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
1823 nla_put_string(msg, IFLA_IFNAME, dev->ifname))
1824 goto free;
1825
1826 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_get_master_valid, &data);
1827 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_get_master_ack, &data);
1828 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_get_master_error, &data);
1829
1830 ret = nl_send_auto_complete(sock_rtnl, msg);
1831 if (ret < 0)
1832 goto free;
1833
1834 while (data.pending > 0)
1835 nl_recvmsgs(sock_rtnl, cb);
1836
1837 if (data.master_ifindex >= 0)
1838 ret = data.master_ifindex;
1839
1840 free:
1841 nlmsg_free(msg);
1842 out:
1843 nl_cb_put(cb);
1844 return ret;
1845 }
1846
1847 static void system_refresh_orig_macaddr(struct device *dev, struct device_settings *s)
1848 {
1849 struct ifreq ifr;
1850
1851 memset(&ifr, 0, sizeof(ifr));
1852 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1853
1854 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0)
1855 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr));
1856 }
1857
1858 static void system_set_master(struct device *dev, int master_ifindex)
1859 {
1860 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
1861 struct nl_msg *nlm;
1862
1863 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST);
1864 if (!nlm)
1865 return;
1866
1867 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
1868 nla_put_string(nlm, IFLA_IFNAME, dev->ifname);
1869
1870 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
1871 if (!linkinfo)
1872 goto failure;
1873
1874 nla_put_string(nlm, IFLA_INFO_KIND, "dsa");
1875 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
1876 if (!infodata)
1877 goto failure;
1878
1879 nla_put_u32(nlm, IFLA_DSA_MASTER, master_ifindex);
1880
1881 nla_nest_end(nlm, infodata);
1882 nla_nest_end(nlm, linkinfo);
1883
1884 system_rtnl_call(nlm);
1885
1886 return;
1887
1888 failure:
1889 nlmsg_free(nlm);
1890 }
1891 #endif
1892
1893 static void ethtool_link_mode_clear_bit(__s8 nwords, int nr, __u32 *mask)
1894 {
1895 if (nr < 0)
1896 return;
1897
1898 if (nr >= (nwords * 32))
1899 return;
1900
1901 mask[nr / 32] &= ~(1U << (nr % 32));
1902 }
1903
1904 static bool ethtool_link_mode_test_bit(__s8 nwords, int nr, const __u32 *mask)
1905 {
1906 if (nr < 0)
1907 return false;
1908
1909 if (nr >= (nwords * 32))
1910 return false;
1911
1912 return !!(mask[nr / 32] & (1U << (nr % 32)));
1913 }
1914
1915 static int
1916 system_get_ethtool_gro(struct device *dev)
1917 {
1918 struct ethtool_value ecmd;
1919 struct ifreq ifr = {
1920 .ifr_data = (caddr_t)&ecmd,
1921 };
1922
1923 memset(&ecmd, 0, sizeof(ecmd));
1924 ecmd.cmd = ETHTOOL_GGRO;
1925 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1926
1927 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr))
1928 return -1;
1929
1930 return ecmd.data;
1931 }
1932
1933 static void
1934 system_set_ethtool_gro(struct device *dev, struct device_settings *s)
1935 {
1936 struct ethtool_value ecmd;
1937 struct ifreq ifr = {
1938 .ifr_data = (caddr_t)&ecmd,
1939 };
1940
1941 memset(&ecmd, 0, sizeof(ecmd));
1942 ecmd.cmd = ETHTOOL_SGRO;
1943 ecmd.data = s->gro;
1944 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1945
1946 ioctl(sock_ioctl, SIOCETHTOOL, &ifr);
1947 }
1948
1949 static void
1950 system_set_ethtool_pause(struct device *dev, struct device_settings *s)
1951 {
1952 struct ethtool_pauseparam pp;
1953 struct ifreq ifr = {
1954 .ifr_data = (caddr_t)&pp,
1955 };
1956
1957 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1958 memset(&pp, 0, sizeof(pp));
1959 pp.cmd = ETHTOOL_GPAUSEPARAM;
1960 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr))
1961 return;
1962
1963 if (s->flags & DEV_OPT_RXPAUSE || s->flags & DEV_OPT_TXPAUSE) {
1964 pp.autoneg = AUTONEG_DISABLE;
1965
1966 if (s->flags & DEV_OPT_PAUSE) {
1967 if (s->flags & DEV_OPT_RXPAUSE)
1968 pp.rx_pause = s->rxpause && s->pause;
1969 else
1970 pp.rx_pause = s->pause;
1971
1972 if (s->flags & DEV_OPT_TXPAUSE)
1973 pp.tx_pause = s->txpause && s->pause;
1974 else
1975 pp.tx_pause = s->pause;
1976 } else {
1977 if (s->flags & DEV_OPT_RXPAUSE)
1978 pp.rx_pause = s->rxpause;
1979
1980 if (s->flags & DEV_OPT_TXPAUSE)
1981 pp.tx_pause = s->txpause;
1982 }
1983
1984 if (s->flags & DEV_OPT_ASYM_PAUSE &&
1985 !s->asym_pause && (pp.rx_pause != pp.tx_pause))
1986 pp.rx_pause = pp.tx_pause = false;
1987 } else {
1988 pp.autoneg = AUTONEG_ENABLE;
1989 /* Pause and Asym_Pause advertising bits will be set via
1990 * ETHTOOL_SLINKSETTINGS in system_set_ethtool_settings()
1991 */
1992 }
1993
1994 pp.cmd = ETHTOOL_SPAUSEPARAM;
1995 ioctl(sock_ioctl, SIOCETHTOOL, &ifr);
1996 }
1997
1998 static void
1999 system_set_ethtool_eee_settings(struct device *dev, struct device_settings *s)
2000 {
2001 struct ethtool_eee eeecmd;
2002 struct ifreq ifr = {
2003 .ifr_data = (caddr_t)&eeecmd,
2004 };
2005
2006 memset(&eeecmd, 0, sizeof(eeecmd));
2007 eeecmd.cmd = ETHTOOL_SEEE;
2008 eeecmd.eee_enabled = s->eee;
2009 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
2010
2011 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0)
2012 netifd_log_message(L_WARNING, "cannot set eee %d for device %s", s->eee, dev->ifname);
2013 }
2014
2015 static void
2016 system_set_ethtool_settings(struct device *dev, struct device_settings *s)
2017 {
2018 struct {
2019 struct ethtool_link_settings req;
2020 __u32 link_mode_data[3 * 127];
2021 } ecmd;
2022 struct ifreq ifr = {
2023 .ifr_data = (caddr_t)&ecmd,
2024 };
2025 size_t i;
2026 __s8 nwords;
2027 __u32 *supported, *advertising;
2028
2029 system_set_ethtool_pause(dev, s);
2030
2031 if (s->flags & DEV_OPT_EEE)
2032 system_set_ethtool_eee_settings(dev, s);
2033
2034 memset(&ecmd, 0, sizeof(ecmd));
2035 ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
2036 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
2037
2038 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
2039 ecmd.req.link_mode_masks_nwords >= 0 ||
2040 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
2041 return;
2042
2043 ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
2044
2045 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
2046 ecmd.req.link_mode_masks_nwords <= 0 ||
2047 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
2048 return;
2049
2050 nwords = ecmd.req.link_mode_masks_nwords;
2051 supported = &ecmd.link_mode_data[0];
2052 advertising = &ecmd.link_mode_data[nwords];
2053 memcpy(advertising, supported, sizeof(__u32) * nwords);
2054
2055 for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) {
2056 if (s->flags & DEV_OPT_DUPLEX) {
2057 if (s->duplex)
2058 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising);
2059 else
2060 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising);
2061 }
2062 if (!(s->flags & DEV_OPT_SPEED) ||
2063 s->speed == ethtool_modes[i].speed)
2064 continue;
2065
2066 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising);
2067 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising);
2068 }
2069
2070 if (s->flags & DEV_OPT_PAUSE)
2071 if (!s->pause)
2072 ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, advertising);
2073
2074 if (s->flags & DEV_OPT_ASYM_PAUSE)
2075 if (!s->asym_pause)
2076 ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising);
2077
2078 if (s->flags & DEV_OPT_AUTONEG) {
2079 ecmd.req.autoneg = s->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
2080 if (!s->autoneg) {
2081 if (s->flags & DEV_OPT_SPEED)
2082 ecmd.req.speed = s->speed;
2083
2084 if (s->flags & DEV_OPT_DUPLEX)
2085 ecmd.req.duplex = s->duplex ? DUPLEX_FULL : DUPLEX_HALF;
2086 }
2087 }
2088
2089 ecmd.req.cmd = ETHTOOL_SLINKSETTINGS;
2090 ioctl(sock_ioctl, SIOCETHTOOL, &ifr);
2091 }
2092
2093 static void
2094 system_set_ethtool_settings_after_up(struct device *dev, struct device_settings *s)
2095 {
2096 if (s->flags & DEV_OPT_GRO)
2097 system_set_ethtool_gro(dev, s);
2098 }
2099
2100 void
2101 system_if_get_settings(struct device *dev, struct device_settings *s)
2102 {
2103 struct ifreq ifr;
2104 char buf[10];
2105 int ret;
2106
2107 memset(&ifr, 0, sizeof(ifr));
2108 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
2109
2110 if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) {
2111 s->mtu = ifr.ifr_mtu;
2112 s->flags |= DEV_OPT_MTU;
2113 }
2114
2115 s->mtu6 = system_update_ipv6_mtu(dev, 0);
2116 if (s->mtu6 > 0)
2117 s->flags |= DEV_OPT_MTU6;
2118
2119 if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) {
2120 s->txqueuelen = ifr.ifr_qlen;
2121 s->flags |= DEV_OPT_TXQUEUELEN;
2122 }
2123
2124 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) {
2125 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr));
2126 s->flags |= DEV_OPT_MACADDR;
2127 }
2128
2129 if (!system_get_disable_ipv6(dev, buf, sizeof(buf))) {
2130 s->ipv6 = !strtoul(buf, NULL, 0);
2131 s->flags |= DEV_OPT_IPV6;
2132 }
2133
2134 if (!system_get_ip6segmentrouting(dev, buf, sizeof(buf))) {
2135 s->ip6segmentrouting = strtoul(buf, NULL, 0);
2136 s->flags |= DEV_OPT_IP6SEGMENTROUTING;
2137 }
2138
2139 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) {
2140 s->promisc = ifr.ifr_flags & IFF_PROMISC;
2141 s->flags |= DEV_OPT_PROMISC;
2142
2143 s->multicast = ifr.ifr_flags & IFF_MULTICAST;
2144 s->flags |= DEV_OPT_MULTICAST;
2145 }
2146
2147 if (!system_get_rpfilter(dev, buf, sizeof(buf))) {
2148 s->rpfilter = strtoul(buf, NULL, 0);
2149 s->flags |= DEV_OPT_RPFILTER;
2150 }
2151
2152 if (!system_get_acceptlocal(dev, buf, sizeof(buf))) {
2153 s->acceptlocal = strtoul(buf, NULL, 0);
2154 s->flags |= DEV_OPT_ACCEPTLOCAL;
2155 }
2156
2157 if (!system_get_igmpversion(dev, buf, sizeof(buf))) {
2158 s->igmpversion = strtoul(buf, NULL, 0);
2159 s->flags |= DEV_OPT_IGMPVERSION;
2160 }
2161
2162 if (!system_get_mldversion(dev, buf, sizeof(buf))) {
2163 s->mldversion = strtoul(buf, NULL, 0);
2164 s->flags |= DEV_OPT_MLDVERSION;
2165 }
2166
2167 if (!system_get_neigh4reachabletime(dev, buf, sizeof(buf))) {
2168 s->neigh4reachabletime = strtoul(buf, NULL, 0);
2169 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
2170 }
2171
2172 if (!system_get_neigh6reachabletime(dev, buf, sizeof(buf))) {
2173 s->neigh6reachabletime = strtoul(buf, NULL, 0);
2174 s->flags |= DEV_OPT_NEIGHREACHABLETIME;
2175 }
2176
2177 if (!system_get_neigh4locktime(dev, buf, sizeof(buf))) {
2178 s->neigh4locktime = strtol(buf, NULL, 0);
2179 s->flags |= DEV_OPT_NEIGHLOCKTIME;
2180 }
2181
2182 if (!system_get_neigh4gcstaletime(dev, buf, sizeof(buf))) {
2183 s->neigh4gcstaletime = strtoul(buf, NULL, 0);
2184 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
2185 }
2186
2187 if (!system_get_neigh6gcstaletime(dev, buf, sizeof(buf))) {
2188 s->neigh6gcstaletime = strtoul(buf, NULL, 0);
2189 s->flags |= DEV_OPT_NEIGHGCSTALETIME;
2190 }
2191
2192 if (!system_get_dadtransmits(dev, buf, sizeof(buf))) {
2193 s->dadtransmits = strtoul(buf, NULL, 0);
2194 s->flags |= DEV_OPT_DADTRANSMITS;
2195 }
2196
2197 if (!system_get_sendredirects(dev, buf, sizeof(buf))) {
2198 s->sendredirects = strtoul(buf, NULL, 0);
2199 s->flags |= DEV_OPT_SENDREDIRECTS;
2200 }
2201
2202 if (!system_get_drop_v4_unicast_in_l2_multicast(dev, buf, sizeof(buf))) {
2203 s->drop_v4_unicast_in_l2_multicast = strtoul(buf, NULL, 0);
2204 s->flags |= DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST;
2205 }
2206
2207 if (!system_get_drop_v6_unicast_in_l2_multicast(dev, buf, sizeof(buf))) {
2208 s->drop_v6_unicast_in_l2_multicast = strtoul(buf, NULL, 0);
2209 s->flags |= DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST;
2210 }
2211
2212 if (!system_get_drop_gratuitous_arp(dev, buf, sizeof(buf))) {
2213 s->drop_gratuitous_arp = strtoul(buf, NULL, 0);
2214 s->flags |= DEV_OPT_DROP_GRATUITOUS_ARP;
2215 }
2216
2217 if (!system_get_drop_unsolicited_na(dev, buf, sizeof(buf))) {
2218 s->drop_unsolicited_na = strtoul(buf, NULL, 0);
2219 s->flags |= DEV_OPT_DROP_UNSOLICITED_NA;
2220 }
2221
2222 if (!system_get_arp_accept(dev, buf, sizeof(buf))) {
2223 s->arp_accept = strtoul(buf, NULL, 0);
2224 s->flags |= DEV_OPT_ARP_ACCEPT;
2225 }
2226
2227 ret = system_get_ethtool_gro(dev);
2228 if (ret >= 0) {
2229 s->gro = ret;
2230 s->flags |= DEV_OPT_GRO;
2231 }
2232
2233 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
2234 ret = system_if_get_master_ifindex(dev);
2235 if (ret >= 0) {
2236 s->master_ifindex = ret;
2237 s->flags |= DEV_OPT_MASTER;
2238 }
2239 #endif
2240 }
2241
2242 void
2243 system_if_apply_settings(struct device *dev, struct device_settings *s, uint64_t apply_mask)
2244 {
2245 struct ifreq ifr;
2246 char buf[12];
2247
2248 apply_mask &= s->flags;
2249
2250 if (apply_mask & DEV_OPT_MASTER) {
2251 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
2252 system_set_master(dev, s->master_ifindex);
2253 if (!(apply_mask & (DEV_OPT_MACADDR | DEV_OPT_DEFAULT_MACADDR)) || dev->external)
2254 system_refresh_orig_macaddr(dev, &dev->orig_settings);
2255 #else
2256 netifd_log_message(L_WARNING, "%s Your kernel is older than linux 6.1.0, changing DSA port conduit is not supported!", dev->ifname);
2257 #endif
2258 }
2259
2260 memset(&ifr, 0, sizeof(ifr));
2261 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
2262 if (apply_mask & DEV_OPT_MTU) {
2263 ifr.ifr_mtu = s->mtu;
2264 if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0)
2265 s->flags &= ~DEV_OPT_MTU;
2266 }
2267 if (apply_mask & DEV_OPT_MTU6) {
2268 system_update_ipv6_mtu(dev, s->mtu6);
2269 }
2270 if (apply_mask & DEV_OPT_TXQUEUELEN) {
2271 ifr.ifr_qlen = s->txqueuelen;
2272 if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0)
2273 s->flags &= ~DEV_OPT_TXQUEUELEN;
2274 }
2275 if ((apply_mask & (DEV_OPT_MACADDR | DEV_OPT_DEFAULT_MACADDR)) && !dev->external) {
2276 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
2277 memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr));
2278 if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0)
2279 s->flags &= ~DEV_OPT_MACADDR;
2280 }
2281 if (apply_mask & DEV_OPT_IPV6)
2282 system_set_disable_ipv6(dev, s->ipv6 ? "0" : "1");
2283 if (s->flags & DEV_OPT_IP6SEGMENTROUTING & apply_mask) {
2284 struct device dummy = {
2285 .ifname = "all",
2286 };
2287 bool ip6segmentrouting = device_check_ip6segmentrouting();
2288
2289 system_set_ip6segmentrouting(dev, s->ip6segmentrouting ? "1" : "0");
2290 system_set_ip6segmentrouting(&dummy, ip6segmentrouting ? "1" : "0");
2291 }
2292 if (apply_mask & DEV_OPT_PROMISC) {
2293 if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0,
2294 !s->promisc ? IFF_PROMISC : 0) < 0)
2295 s->flags &= ~DEV_OPT_PROMISC;
2296 }
2297 if (apply_mask & DEV_OPT_RPFILTER) {
2298 snprintf(buf, sizeof(buf), "%u", s->rpfilter);
2299 system_set_rpfilter(dev, buf);
2300 }
2301 if (apply_mask & DEV_OPT_ACCEPTLOCAL)
2302 system_set_acceptlocal(dev, s->acceptlocal ? "1" : "0");
2303 if (apply_mask & DEV_OPT_IGMPVERSION) {
2304 snprintf(buf, sizeof(buf), "%u", s->igmpversion);
2305 system_set_igmpversion(dev, buf);
2306 }
2307 if (apply_mask & DEV_OPT_MLDVERSION) {
2308 snprintf(buf, sizeof(buf), "%u", s->mldversion);
2309 system_set_mldversion(dev, buf);
2310 }
2311 if (apply_mask & DEV_OPT_NEIGHREACHABLETIME) {
2312 snprintf(buf, sizeof(buf), "%u", s->neigh4reachabletime);
2313 system_set_neigh4reachabletime(dev, buf);
2314 snprintf(buf, sizeof(buf), "%u", s->neigh6reachabletime);
2315 system_set_neigh6reachabletime(dev, buf);
2316 }
2317 if (apply_mask & DEV_OPT_NEIGHLOCKTIME) {
2318 snprintf(buf, sizeof(buf), "%d", s->neigh4locktime);
2319 system_set_neigh4locktime(dev, buf);
2320 }
2321 if (apply_mask & DEV_OPT_NEIGHGCSTALETIME) {
2322 snprintf(buf, sizeof(buf), "%u", s->neigh4gcstaletime);
2323 system_set_neigh4gcstaletime(dev, buf);
2324 snprintf(buf, sizeof(buf), "%u", s->neigh6gcstaletime);
2325 system_set_neigh6gcstaletime(dev, buf);
2326 }
2327 if (apply_mask & DEV_OPT_DADTRANSMITS) {
2328 snprintf(buf, sizeof(buf), "%u", s->dadtransmits);
2329 system_set_dadtransmits(dev, buf);
2330 }
2331 if (apply_mask & DEV_OPT_MULTICAST) {
2332 if (system_if_flags(dev->ifname, s->multicast ? IFF_MULTICAST : 0,
2333 !s->multicast ? IFF_MULTICAST : 0) < 0)
2334 s->flags &= ~DEV_OPT_MULTICAST;
2335 }
2336 if (apply_mask & DEV_OPT_SENDREDIRECTS)
2337 system_set_sendredirects(dev, s->sendredirects ? "1" : "0");
2338 if (apply_mask & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST)
2339 system_set_drop_v4_unicast_in_l2_multicast(dev, s->drop_v4_unicast_in_l2_multicast ? "1" : "0");
2340 if (apply_mask & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST)
2341 system_set_drop_v6_unicast_in_l2_multicast(dev, s->drop_v6_unicast_in_l2_multicast ? "1" : "0");
2342 if (apply_mask & DEV_OPT_DROP_GRATUITOUS_ARP)
2343 system_set_drop_gratuitous_arp(dev, s->drop_gratuitous_arp ? "1" : "0");
2344 if (apply_mask & DEV_OPT_DROP_UNSOLICITED_NA)
2345 system_set_drop_unsolicited_na(dev, s->drop_unsolicited_na ? "1" : "0");
2346 if (apply_mask & DEV_OPT_ARP_ACCEPT)
2347 system_set_arp_accept(dev, s->arp_accept ? "1" : "0");
2348 system_set_ethtool_settings(dev, s);
2349 }
2350
2351 void system_if_apply_settings_after_up(struct device *dev, struct device_settings *s)
2352 {
2353 system_set_ethtool_settings_after_up(dev, s);
2354 }
2355
2356 int system_if_up(struct device *dev)
2357 {
2358 return system_if_flags(dev->ifname, IFF_UP, 0);
2359 }
2360
2361 int system_if_down(struct device *dev)
2362 {
2363 return system_if_flags(dev->ifname, 0, IFF_UP);
2364 }
2365
2366 struct if_check_data {
2367 struct device *dev;
2368 int pending;
2369 int ret;
2370 };
2371
2372 static int cb_if_check_valid(struct nl_msg *msg, void *arg)
2373 {
2374 struct nlmsghdr *nh = nlmsg_hdr(msg);
2375 struct ifinfomsg *ifi = NLMSG_DATA(nh);
2376 struct if_check_data *chk = (struct if_check_data *)arg;
2377
2378 if (nh->nlmsg_type != RTM_NEWLINK)
2379 return NL_SKIP;
2380
2381 system_device_update_state(chk->dev, ifi->ifi_flags, ifi->ifi_index);
2382 return NL_OK;
2383 }
2384
2385 static int cb_if_check_ack(struct nl_msg *msg, void *arg)
2386 {
2387 struct if_check_data *chk = (struct if_check_data *)arg;
2388 chk->pending = 0;
2389 return NL_STOP;
2390 }
2391
2392 static int cb_if_check_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
2393 {
2394 struct if_check_data *chk = (struct if_check_data *)arg;
2395
2396 if (chk->dev->type == &simple_device_type)
2397 device_set_present(chk->dev, false);
2398 device_set_link(chk->dev, false);
2399 chk->pending = err->error;
2400
2401 return NL_STOP;
2402 }
2403
2404 struct bridge_vlan_check_data {
2405 struct device *check_dev;
2406 int ifindex;
2407 int ret;
2408 bool pending;
2409 };
2410
2411 static void bridge_vlan_check_port(struct bridge_vlan_check_data *data,
2412 struct bridge_vlan_port *port,
2413 struct bridge_vlan_info *vinfo)
2414 {
2415 uint16_t flags = 0, diff, mask;
2416
2417 if (port->flags & BRVLAN_F_PVID)
2418 flags |= BRIDGE_VLAN_INFO_PVID;
2419 if (port->flags & BRVLAN_F_UNTAGGED)
2420 flags |= BRIDGE_VLAN_INFO_UNTAGGED;
2421
2422 diff = vinfo->flags ^ flags;
2423 mask = BRVLAN_F_UNTAGGED | (flags & BRIDGE_VLAN_INFO_PVID);
2424 if (diff & mask) {
2425 data->ret = 1;
2426 data->pending = false;
2427 }
2428
2429 port->check = 1;
2430 }
2431
2432 static void bridge_vlan_check_attr(struct bridge_vlan_check_data *data,
2433 struct rtattr *attr)
2434 {
2435 struct bridge_vlan_hotplug_port *port;
2436 struct bridge_vlan_info *vinfo;
2437 struct bridge_vlan *vlan;
2438 struct rtattr *cur;
2439 int rem = RTA_PAYLOAD(attr);
2440 int i;
2441
2442 for (cur = RTA_DATA(attr); RTA_OK(cur, rem); cur = RTA_NEXT(cur, rem)) {
2443 if (cur->rta_type != IFLA_BRIDGE_VLAN_INFO)
2444 continue;
2445
2446 vinfo = RTA_DATA(cur);
2447 vlan = vlist_find(&data->check_dev->vlans, &vinfo->vid, vlan, node);
2448 if (!vlan) {
2449 data->ret = 1;
2450 data->pending = false;
2451 return;
2452 }
2453
2454 for (i = 0; i < vlan->n_ports; i++)
2455 if (!vlan->ports[i].check)
2456 bridge_vlan_check_port(data, &vlan->ports[i], vinfo);
2457
2458 list_for_each_entry(port, &vlan->hotplug_ports, list)
2459 if (!port->port.check)
2460 bridge_vlan_check_port(data, &port->port, vinfo);
2461 }
2462 }
2463
2464 static int bridge_vlan_check_cb(struct nl_msg *msg, void *arg)
2465 {
2466 struct bridge_vlan_check_data *data = arg;
2467 struct nlmsghdr *nh = nlmsg_hdr(msg);
2468 struct ifinfomsg *ifi = NLMSG_DATA(nh);
2469 struct rtattr *attr;
2470 int rem;
2471
2472 if (nh->nlmsg_type != RTM_NEWLINK)
2473 return NL_SKIP;
2474
2475 if (ifi->ifi_family != AF_BRIDGE)
2476 return NL_SKIP;
2477
2478 if (ifi->ifi_index != data->ifindex)
2479 return NL_SKIP;
2480
2481 attr = IFLA_RTA(ifi);
2482 rem = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
2483 while (RTA_OK(attr, rem)) {
2484 if (attr->rta_type == IFLA_AF_SPEC)
2485 bridge_vlan_check_attr(data, attr);
2486
2487 attr = RTA_NEXT(attr, rem);
2488 }
2489
2490 return NL_SKIP;
2491 }
2492
2493 static int bridge_vlan_ack_cb(struct nl_msg *msg, void *arg)
2494 {
2495 struct bridge_vlan_check_data *data = arg;
2496 data->pending = false;
2497 return NL_STOP;
2498 }
2499
2500 static int bridge_vlan_error_cb(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
2501 {
2502 struct bridge_vlan_check_data *data = arg;
2503 data->pending = false;
2504 return NL_STOP;
2505 }
2506
2507 int system_bridge_vlan_check(struct device *dev, char *ifname)
2508 {
2509 struct bridge_vlan_check_data data = {
2510 .check_dev = dev,
2511 .ifindex = if_nametoindex(ifname),
2512 .ret = -1,
2513 .pending = true,
2514 };
2515 static struct ifinfomsg ifi = {
2516 .ifi_family = AF_BRIDGE
2517 };
2518 static struct rtattr ext_req = {
2519 .rta_type = IFLA_EXT_MASK,
2520 .rta_len = RTA_LENGTH(sizeof(uint32_t)),
2521 };
2522 uint32_t filter = RTEXT_FILTER_BRVLAN;
2523 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
2524 struct bridge_vlan *vlan;
2525 struct nl_msg *msg;
2526 int i;
2527
2528 if (!data.ifindex)
2529 return 0;
2530
2531 msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP);
2532
2533 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
2534 nlmsg_append(msg, &ext_req, sizeof(ext_req), NLMSG_ALIGNTO) ||
2535 nlmsg_append(msg, &filter, sizeof(filter), 0))
2536 goto free;
2537
2538 vlist_for_each_element(&dev->vlans, vlan, node) {
2539 struct bridge_vlan_hotplug_port *port;
2540
2541 for (i = 0; i < vlan->n_ports; i++) {
2542 if (!strcmp(vlan->ports[i].ifname, ifname))
2543 vlan->ports[i].check = 0;
2544 else
2545 vlan->ports[i].check = -1;
2546 }
2547
2548 list_for_each_entry(port, &vlan->hotplug_ports, list) {
2549 if (!strcmp(port->port.ifname, ifname))
2550 port->port.check = 0;
2551 else
2552 port->port.check = -1;
2553 }
2554 }
2555
2556 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, bridge_vlan_check_cb, &data);
2557 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, bridge_vlan_ack_cb, &data);
2558 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, bridge_vlan_ack_cb, &data);
2559 nl_cb_err(cb, NL_CB_CUSTOM, bridge_vlan_error_cb, &data);
2560
2561 if (nl_send_auto_complete(sock_rtnl, msg) < 0)
2562 goto free;
2563
2564 data.ret = 0;
2565 while (data.pending)
2566 nl_recvmsgs(sock_rtnl, cb);
2567
2568 vlist_for_each_element(&dev->vlans, vlan, node) {
2569 struct bridge_vlan_hotplug_port *port;
2570
2571 for (i = 0; i < vlan->n_ports; i++) {
2572 if (!vlan->ports[i].check) {
2573 data.ret = 1;
2574 break;
2575 }
2576 }
2577
2578 list_for_each_entry(port, &vlan->hotplug_ports, list) {
2579 if (!port->port.check) {
2580 data.ret = 1;
2581 break;
2582 }
2583 }
2584 }
2585
2586 free:
2587 nlmsg_free(msg);
2588 nl_cb_put(cb);
2589 return data.ret;
2590 }
2591
2592 int system_if_check(struct device *dev)
2593 {
2594 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
2595 struct nl_msg *msg;
2596 struct ifinfomsg ifi = {
2597 .ifi_family = AF_UNSPEC,
2598 .ifi_index = 0,
2599 };
2600 struct if_check_data chk = {
2601 .dev = dev,
2602 .pending = 1,
2603 };
2604 int ret = 1;
2605
2606 if (!cb)
2607 return ret;
2608
2609 msg = nlmsg_alloc_simple(RTM_GETLINK, 0);
2610 if (!msg)
2611 goto out;
2612
2613 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
2614 nla_put_string(msg, IFLA_IFNAME, dev->ifname))
2615 goto free;
2616
2617 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_check_valid, &chk);
2618 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_check_ack, &chk);
2619 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_check_error, &chk);
2620
2621 ret = nl_send_auto_complete(sock_rtnl, msg);
2622 if (ret < 0)
2623 goto free;
2624
2625 while (chk.pending > 0)
2626 nl_recvmsgs(sock_rtnl, cb);
2627
2628 ret = chk.pending;
2629
2630 free:
2631 nlmsg_free(msg);
2632 out:
2633 nl_cb_put(cb);
2634 return ret;
2635 }
2636
2637 struct device *
2638 system_if_get_parent(struct device *dev)
2639 {
2640 char buf[64], *devname;
2641 int ifindex, iflink;
2642
2643 if (system_get_dev_sysfs("iflink", dev->ifname, buf, sizeof(buf)) < 0)
2644 return NULL;
2645
2646 iflink = strtoul(buf, NULL, 0);
2647 ifindex = system_if_resolve(dev);
2648 if (!iflink || iflink == ifindex)
2649 return NULL;
2650
2651 devname = if_indextoname(iflink, buf);
2652 if (!devname)
2653 return NULL;
2654
2655 return device_get(devname, true);
2656 }
2657
2658 static bool
2659 read_string_file(int dir_fd, const char *file, char *buf, int len)
2660 {
2661 bool ret = false;
2662 char *c;
2663 int fd;
2664
2665 fd = openat(dir_fd, file, O_RDONLY);
2666 if (fd < 0)
2667 return false;
2668
2669 retry:
2670 len = read(fd, buf, len - 1);
2671 if (len < 0) {
2672 if (errno == EINTR)
2673 goto retry;
2674 } else if (len > 0) {
2675 buf[len] = 0;
2676
2677 c = strchr(buf, '\n');
2678 if (c)
2679 *c = 0;
2680
2681 ret = true;
2682 }
2683
2684 close(fd);
2685
2686 return ret;
2687 }
2688
2689 static bool
2690 read_uint64_file(int dir_fd, const char *file, uint64_t *val)
2691 {
2692 char buf[64];
2693 bool ret = false;
2694
2695 ret = read_string_file(dir_fd, file, buf, sizeof(buf));
2696 if (ret)
2697 *val = strtoull(buf, NULL, 0);
2698
2699 return ret;
2700 }
2701
2702 bool
2703 system_if_force_external(const char *ifname)
2704 {
2705 struct stat s;
2706
2707 return stat(dev_sysfs_path(ifname, "phy80211"), &s) == 0;
2708 }
2709
2710 static const char *
2711 system_netdevtype_name(unsigned short dev_type)
2712 {
2713 size_t i;
2714
2715 for (i = 0; i < ARRAY_SIZE(netdev_types); i++) {
2716 if (netdev_types[i].id == dev_type)
2717 return netdev_types[i].name;
2718 }
2719
2720 /* the last key is used by default */
2721 i = ARRAY_SIZE(netdev_types) - 1;
2722
2723 return netdev_types[i].name;
2724 }
2725
2726 static void
2727 system_add_devtype(struct blob_buf *b, const char *ifname)
2728 {
2729 char buf[100];
2730 bool found = false;
2731
2732 if (!system_get_dev_sysfs("uevent", ifname, buf, sizeof(buf))) {
2733 const char *info = "DEVTYPE=";
2734 char *context = NULL;
2735 const char *line = strtok_r(buf, "\r\n", &context);
2736
2737 while (line != NULL) {
2738 char *index = strstr(line, info);
2739
2740 if (index != NULL) {
2741 blobmsg_add_string(b, "devtype", index + strlen(info));
2742 found = true;
2743 break;
2744 }
2745
2746 line = strtok_r(NULL, "\r\n", &context);
2747 }
2748 }
2749
2750 if (!found) {
2751 unsigned short number = 0;
2752 const char *name = NULL;
2753
2754 if (!system_get_dev_sysfs("type", ifname, buf, sizeof(buf))) {
2755 number = strtoul(buf, NULL, 0);
2756 name = system_netdevtype_name(number);
2757 blobmsg_add_string(b, "devtype", name);
2758 }
2759 }
2760 }
2761
2762 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
2763
2764 static int32_t
2765 ethtool_feature_count(const char *ifname)
2766 {
2767 struct {
2768 struct ethtool_sset_info hdr;
2769 uint32_t buf;
2770 } req = {
2771 .hdr = {
2772 .cmd = ETHTOOL_GSSET_INFO,
2773 .sset_mask = 1 << ETH_SS_FEATURES
2774 }
2775 };
2776
2777 struct ifreq ifr = {
2778 .ifr_data = (void *)&req
2779 };
2780
2781 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
2782
2783 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0)
2784 return -1;
2785
2786 if (!req.hdr.sset_mask)
2787 return 0;
2788
2789 return req.buf;
2790 }
2791
2792 static int32_t
2793 ethtool_feature_index(const char *ifname, const char *keyname)
2794 {
2795 struct ethtool_gstrings *feature_names;
2796 struct ifreq ifr = { 0 };
2797 int32_t n_features;
2798 uint32_t i;
2799
2800 n_features = ethtool_feature_count(ifname);
2801
2802 if (n_features <= 0)
2803 return -1;
2804
2805 feature_names = calloc(1, sizeof(*feature_names) + n_features * ETH_GSTRING_LEN);
2806
2807 if (!feature_names)
2808 return -1;
2809
2810 feature_names->cmd = ETHTOOL_GSTRINGS;
2811 feature_names->string_set = ETH_SS_FEATURES;
2812 feature_names->len = n_features;
2813
2814 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
2815 ifr.ifr_data = (void *)feature_names;
2816
2817 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) {
2818 free(feature_names);
2819
2820 return -1;
2821 }
2822
2823 for (i = 0; i < feature_names->len; i++)
2824 if (!strcmp((char *)&feature_names->data[i * ETH_GSTRING_LEN], keyname))
2825 break;
2826
2827 if (i >= feature_names->len)
2828 i = -1;
2829
2830 free(feature_names);
2831
2832 return i;
2833 }
2834
2835 static bool
2836 ethtool_feature_value(const char *ifname, const char *keyname)
2837 {
2838 struct ethtool_get_features_block *feature_block;
2839 struct ethtool_gfeatures *feature_values;
2840 struct ifreq ifr = { 0 };
2841 int32_t feature_idx;
2842 bool active;
2843
2844 feature_idx = ethtool_feature_index(ifname, keyname);
2845
2846 if (feature_idx < 0)
2847 return false;
2848
2849 feature_values = calloc(1,
2850 sizeof(*feature_values) +
2851 sizeof(feature_values->features[0]) * DIV_ROUND_UP(feature_idx, 32));
2852
2853 if (!feature_values)
2854 return false;
2855
2856 feature_values->cmd = ETHTOOL_GFEATURES;
2857 feature_values->size = DIV_ROUND_UP(feature_idx, 32);
2858
2859 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
2860 ifr.ifr_data = (void *)feature_values;
2861
2862 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) {
2863 free(feature_values);
2864
2865 return false;
2866 }
2867
2868 feature_block = &feature_values->features[feature_idx / 32];
2869 active = feature_block->active & (1U << feature_idx % 32);
2870
2871 free(feature_values);
2872
2873 return active;
2874 }
2875
2876 static void
2877 system_add_link_mode_name(struct blob_buf *b, int i, bool half)
2878 {
2879 char *buf;
2880
2881 /* allocate string buffer large enough for the mode name and a suffix
2882 * "-F" or "-H" indicating full duplex or half duplex.
2883 */
2884 buf = blobmsg_alloc_string_buffer(b, NULL, strlen(ethtool_modes[i].name) + 3);
2885 if (!buf)
2886 return;
2887
2888 strcpy(buf, ethtool_modes[i].name);
2889 if (half)
2890 strcat(buf, "-H");
2891 else
2892 strcat(buf, "-F");
2893
2894 blobmsg_add_string_buffer(b);
2895 }
2896
2897 static void
2898 system_add_link_modes(__s8 nwords, struct blob_buf *b, __u32 *mask)
2899 {
2900 size_t i;
2901
2902 for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) {
2903 if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_half, mask))
2904 system_add_link_mode_name(b, i, true);
2905
2906 if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_full, mask))
2907 system_add_link_mode_name(b, i, false);
2908 }
2909 }
2910
2911 static void
2912 system_add_pause_modes(__s8 nwords, struct blob_buf *b, __u32 *mask)
2913 {
2914 if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, mask))
2915 blobmsg_add_string(b, NULL, "pause");
2916
2917 if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask))
2918 blobmsg_add_string(b, NULL, "asym_pause");
2919 }
2920
2921
2922 static void
2923 system_add_ethtool_pause_an(struct blob_buf *b, __s8 nwords,
2924 __u32 *advertising, __u32 *lp_advertising)
2925 {
2926 bool an_rx = false, an_tx = false;
2927 void *d;
2928
2929 d = blobmsg_open_array(b, "negotiated");
2930
2931 /* Work out negotiated pause frame usage per
2932 * IEEE 802.3-2005 table 28B-3.
2933 */
2934 if (ethtool_link_mode_test_bit(nwords,
2935 ETHTOOL_LINK_MODE_Pause_BIT,
2936 advertising) &&
2937 ethtool_link_mode_test_bit(nwords,
2938 ETHTOOL_LINK_MODE_Pause_BIT,
2939 lp_advertising)) {
2940 an_tx = true;
2941 an_rx = true;
2942 } else if (ethtool_link_mode_test_bit(nwords,
2943 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
2944 advertising) &&
2945 ethtool_link_mode_test_bit(nwords,
2946 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
2947 lp_advertising)) {
2948 if (ethtool_link_mode_test_bit(nwords,
2949 ETHTOOL_LINK_MODE_Pause_BIT,
2950 advertising))
2951 an_rx = true;
2952 else if (ethtool_link_mode_test_bit(nwords,
2953 ETHTOOL_LINK_MODE_Pause_BIT,
2954 lp_advertising))
2955 an_tx = true;
2956 }
2957 if (an_tx)
2958 blobmsg_add_string(b, NULL, "rx");
2959
2960 if (an_rx)
2961 blobmsg_add_string(b, NULL, "tx");
2962
2963 blobmsg_close_array(b, d);
2964 }
2965
2966 static void
2967 system_get_ethtool_pause(struct device *dev, bool *rx_pause, bool *tx_pause, bool *pause_autoneg)
2968 {
2969 struct ethtool_pauseparam pp;
2970 struct ifreq ifr = {
2971 .ifr_data = (caddr_t)&pp,
2972 };
2973
2974 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
2975 memset(&pp, 0, sizeof(pp));
2976 pp.cmd = ETHTOOL_GPAUSEPARAM;
2977
2978 /* may fail */
2979 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == -1) {
2980 *pause_autoneg = true;
2981 return;
2982 }
2983
2984 *rx_pause = pp.rx_pause;
2985 *tx_pause = pp.tx_pause;
2986 *pause_autoneg = pp.autoneg;
2987 }
2988
2989 int
2990 system_if_dump_info(struct device *dev, struct blob_buf *b)
2991 {
2992 __u32 *supported, *advertising, *lp_advertising;
2993 bool rx_pause, tx_pause, pause_autoneg;
2994 struct {
2995 struct ethtool_link_settings req;
2996 __u32 link_mode_data[3 * 127];
2997 } ecmd;
2998 struct ifreq ifr = {
2999 .ifr_data = (caddr_t)&ecmd,
3000 };
3001 __s8 nwords;
3002 void *c, *d;
3003 char *s;
3004
3005 system_get_ethtool_pause(dev, &rx_pause, &tx_pause, &pause_autoneg);
3006
3007 memset(&ecmd, 0, sizeof(ecmd));
3008 ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
3009 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
3010
3011 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
3012 ecmd.req.link_mode_masks_nwords >= 0 ||
3013 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
3014 return -EOPNOTSUPP;
3015
3016 ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
3017
3018 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 ||
3019 ecmd.req.link_mode_masks_nwords <= 0 ||
3020 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
3021 return -EIO;
3022
3023 nwords = ecmd.req.link_mode_masks_nwords;
3024 supported = &ecmd.link_mode_data[0];
3025 advertising = &ecmd.link_mode_data[nwords];
3026 lp_advertising = &ecmd.link_mode_data[2 * nwords];
3027
3028 c = blobmsg_open_array(b, "link-advertising");
3029 system_add_link_modes(nwords, b, advertising);
3030 blobmsg_close_array(b, c);
3031
3032 c = blobmsg_open_array(b, "link-partner-advertising");
3033 system_add_link_modes(nwords, b, lp_advertising);
3034 blobmsg_close_array(b, c);
3035
3036 c = blobmsg_open_array(b, "link-supported");
3037 system_add_link_modes(nwords, b, supported);
3038 blobmsg_close_array(b, c);
3039
3040 if (ethtool_validate_speed(ecmd.req.speed) &&
3041 (ecmd.req.speed != (__u32)SPEED_UNKNOWN) &&
3042 (ecmd.req.speed != 0)) {
3043 s = blobmsg_alloc_string_buffer(b, "speed", 10);
3044 snprintf(s, 8, "%d%c", ecmd.req.speed,
3045 ecmd.req.duplex == DUPLEX_HALF ? 'H' : 'F');
3046 blobmsg_add_string_buffer(b);
3047 }
3048 blobmsg_add_u8(b, "autoneg", !!ecmd.req.autoneg);
3049
3050 c = blobmsg_open_table(b, "flow-control");
3051 blobmsg_add_u8(b, "autoneg", pause_autoneg);
3052
3053 d = blobmsg_open_array(b, "supported");
3054 system_add_pause_modes(nwords, b, supported);
3055 blobmsg_close_array(b, d);
3056
3057 if (pause_autoneg) {
3058 d = blobmsg_open_array(b, "link-advertising");
3059 system_add_pause_modes(nwords, b, advertising);
3060 blobmsg_close_array(b, d);
3061 }
3062
3063 d = blobmsg_open_array(b, "link-partner-advertising");
3064 system_add_pause_modes(nwords, b, lp_advertising);
3065 blobmsg_close_array(b, d);
3066
3067 if (pause_autoneg) {
3068 system_add_ethtool_pause_an(b, nwords, advertising,
3069 lp_advertising);
3070 } else {
3071 d = blobmsg_open_array(b, "selected");
3072 if (rx_pause)
3073 blobmsg_add_string(b, NULL, "rx");
3074
3075 if (tx_pause)
3076 blobmsg_add_string(b, NULL, "tx");
3077
3078 blobmsg_close_array(b, d);
3079 }
3080
3081 blobmsg_close_table(b, c);
3082
3083 blobmsg_add_u8(b, "hw-tc-offload",
3084 ethtool_feature_value(dev->ifname, "hw-tc-offload"));
3085
3086 system_add_devtype(b, dev->ifname);
3087
3088 return 0;
3089 }
3090
3091 int
3092 system_if_dump_stats(struct device *dev, struct blob_buf *b)
3093 {
3094 const char *const counters[] = {
3095 "collisions", "rx_frame_errors", "tx_compressed",
3096 "multicast", "rx_length_errors", "tx_dropped",
3097 "rx_bytes", "rx_missed_errors", "tx_errors",
3098 "rx_compressed", "rx_over_errors", "tx_fifo_errors",
3099 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors",
3100 "rx_dropped", "tx_aborted_errors", "tx_packets",
3101 "rx_errors", "tx_bytes", "tx_window_errors",
3102 "rx_fifo_errors", "tx_carrier_errors",
3103 };
3104 int stats_dir;
3105 size_t i;
3106 uint64_t val = 0;
3107
3108 stats_dir = open(dev_sysfs_path(dev->ifname, "statistics"), O_DIRECTORY);
3109 if (stats_dir < 0)
3110 return -1;
3111
3112 for (i = 0; i < ARRAY_SIZE(counters); i++)
3113 if (read_uint64_file(stats_dir, counters[i], &val))
3114 blobmsg_add_u64(b, counters[i], val);
3115
3116 close(stats_dir);
3117 return 0;
3118 }
3119
3120 static int system_addr(struct device *dev, struct device_addr *addr, int cmd)
3121 {
3122 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4);
3123 int alen = v4 ? 4 : 16;
3124 unsigned int flags = 0;
3125 struct ifaddrmsg ifa = {
3126 .ifa_family = (alen == 4) ? AF_INET : AF_INET6,
3127 .ifa_prefixlen = addr->mask,
3128 .ifa_index = dev->ifindex,
3129 };
3130
3131 struct nl_msg *msg;
3132 if (cmd == RTM_NEWADDR)
3133 flags |= NLM_F_CREATE | NLM_F_REPLACE;
3134
3135 msg = nlmsg_alloc_simple(cmd, flags);
3136 if (!msg)
3137 return -1;
3138
3139 nlmsg_append(msg, &ifa, sizeof(ifa), 0);
3140 nla_put(msg, IFA_LOCAL, alen, &addr->addr);
3141 if (v4) {
3142 if (addr->broadcast)
3143 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast);
3144 if (addr->point_to_point)
3145 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point);
3146 } else {
3147 time_t now = system_get_rtime();
3148 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0};
3149
3150 if (addr->preferred_until) {
3151 int64_t preferred = addr->preferred_until - now;
3152 if (preferred < 0)
3153 preferred = 0;
3154 else if (preferred > UINT32_MAX)
3155 preferred = UINT32_MAX;
3156
3157 cinfo.ifa_prefered = preferred;
3158 }
3159
3160 if (addr->valid_until) {
3161 int64_t valid = addr->valid_until - now;
3162 if (valid <= 0) {
3163 nlmsg_free(msg);
3164 return -1;
3165 }
3166 else if (valid > UINT32_MAX)
3167 valid = UINT32_MAX;
3168
3169 cinfo.ifa_valid = valid;
3170 }
3171
3172 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo);
3173
3174 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK))
3175 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE);
3176 }
3177
3178 return system_rtnl_call(msg);
3179 }
3180
3181 int system_add_address(struct device *dev, struct device_addr *addr)
3182 {
3183 return system_addr(dev, addr, RTM_NEWADDR);
3184 }
3185
3186 int system_del_address(struct device *dev, struct device_addr *addr)
3187 {
3188 return system_addr(dev, addr, RTM_DELADDR);
3189 }
3190
3191 static int system_neigh(struct device *dev, struct device_neighbor *neighbor, int cmd)
3192 {
3193 int alen = ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
3194 unsigned int flags = 0;
3195 struct ndmsg ndm = {
3196 .ndm_family = (alen == 4) ? AF_INET : AF_INET6,
3197 .ndm_ifindex = dev->ifindex,
3198 .ndm_state = NUD_PERMANENT,
3199 .ndm_flags = (neighbor->proxy ? NTF_PROXY : 0) | (neighbor->router ? NTF_ROUTER : 0),
3200 };
3201 struct nl_msg *msg;
3202
3203 if (cmd == RTM_NEWNEIGH)
3204 flags |= NLM_F_CREATE | NLM_F_REPLACE;
3205
3206 msg = nlmsg_alloc_simple(cmd, flags);
3207
3208 if (!msg)
3209 return -1;
3210
3211 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
3212
3213 nla_put(msg, NDA_DST, alen, &neighbor->addr);
3214 if (neighbor->flags & DEVNEIGH_MAC)
3215 nla_put(msg, NDA_LLADDR, sizeof(neighbor->macaddr), &neighbor->macaddr);
3216
3217
3218 return system_rtnl_call(msg);
3219 }
3220
3221 int system_add_neighbor(struct device *dev, struct device_neighbor *neighbor)
3222 {
3223 return system_neigh(dev, neighbor, RTM_NEWNEIGH);
3224 }
3225
3226 int system_del_neighbor(struct device *dev, struct device_neighbor *neighbor)
3227 {
3228 return system_neigh(dev, neighbor, RTM_DELNEIGH);
3229 }
3230
3231 static int system_rt(struct device *dev, struct device_route *route, int cmd)
3232 {
3233 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
3234 bool have_gw;
3235 unsigned int flags = 0;
3236
3237 if (alen == 4)
3238 have_gw = !!route->nexthop.in.s_addr;
3239 else
3240 have_gw = route->nexthop.in6.s6_addr32[0] ||
3241 route->nexthop.in6.s6_addr32[1] ||
3242 route->nexthop.in6.s6_addr32[2] ||
3243 route->nexthop.in6.s6_addr32[3];
3244
3245 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))
3246 ? route->table : RT_TABLE_MAIN;
3247
3248 struct rtmsg rtm = {
3249 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
3250 .rtm_dst_len = route->mask,
3251 .rtm_src_len = route->sourcemask,
3252 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
3253 .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC,
3254 .rtm_scope = RT_SCOPE_NOWHERE,
3255 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
3256 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
3257 };
3258 struct nl_msg *msg;
3259
3260 if (cmd == RTM_NEWROUTE) {
3261 flags |= NLM_F_CREATE | NLM_F_REPLACE;
3262
3263 if (!dev) { /* Add null-route */
3264 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
3265 rtm.rtm_type = RTN_UNREACHABLE;
3266 }
3267 else
3268 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
3269 }
3270
3271 if (route->flags & DEVROUTE_TYPE) {
3272 rtm.rtm_type = route->type;
3273 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) {
3274 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST ||
3275 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST)
3276 rtm.rtm_table = RT_TABLE_LOCAL;
3277 }
3278
3279 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) {
3280 rtm.rtm_scope = RT_SCOPE_HOST;
3281 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
3282 rtm.rtm_type == RTN_ANYCAST) {
3283 rtm.rtm_scope = RT_SCOPE_LINK;
3284 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE ||
3285 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY ||
3286 rtm.rtm_type == RTN_THROW) {
3287 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
3288 dev = NULL;
3289 }
3290 }
3291
3292 if (route->flags & DEVROUTE_NODEV)
3293 dev = NULL;
3294
3295 msg = nlmsg_alloc_simple(cmd, flags);
3296 if (!msg)
3297 return -1;
3298
3299 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
3300
3301 if (route->mask)
3302 nla_put(msg, RTA_DST, alen, &route->addr);
3303
3304 if (route->sourcemask) {
3305 if (rtm.rtm_family == AF_INET)
3306 nla_put(msg, RTA_PREFSRC, alen, &route->source);
3307 else
3308 nla_put(msg, RTA_SRC, alen, &route->source);
3309 }
3310
3311 if (route->metric > 0)
3312 nla_put_u32(msg, RTA_PRIORITY, route->metric);
3313
3314 if (have_gw)
3315 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop);
3316
3317 if (dev)
3318 nla_put_u32(msg, RTA_OIF, dev->ifindex);
3319
3320 if (table >= 256)
3321 nla_put_u32(msg, RTA_TABLE, table);
3322
3323 if (route->flags & DEVROUTE_MTU) {
3324 struct nlattr *metrics;
3325
3326 if (!(metrics = nla_nest_start(msg, RTA_METRICS)))
3327 goto nla_put_failure;
3328
3329 nla_put_u32(msg, RTAX_MTU, route->mtu);
3330
3331 nla_nest_end(msg, metrics);
3332 }
3333
3334 return system_rtnl_call(msg);
3335
3336 nla_put_failure:
3337 nlmsg_free(msg);
3338 return -ENOMEM;
3339 }
3340
3341 int system_add_route(struct device *dev, struct device_route *route)
3342 {
3343 return system_rt(dev, route, RTM_NEWROUTE);
3344 }
3345
3346 int system_del_route(struct device *dev, struct device_route *route)
3347 {
3348 return system_rt(dev, route, RTM_DELROUTE);
3349 }
3350
3351 int system_flush_routes(void)
3352 {
3353 const char *names[] = { "ipv4", "ipv6" };
3354 size_t i;
3355 int fd;
3356
3357 for (i = 0; i < ARRAY_SIZE(names); i++) {
3358 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/route/flush", proc_path, names[i]);
3359 fd = open(dev_buf, O_WRONLY);
3360 if (fd < 0)
3361 continue;
3362
3363 if (write(fd, "-1", 2)) {}
3364 close(fd);
3365 }
3366 return 0;
3367 }
3368
3369 bool system_resolve_rt_type(const char *type, unsigned int *id)
3370 {
3371 return system_rtn_aton(type, id);
3372 }
3373
3374 bool system_resolve_rt_proto(const char *type, unsigned int *id)
3375 {
3376 FILE *f;
3377 char *e, buf[128];
3378 unsigned int n, proto = 256;
3379 n = strtoul(type, &e, 0);
3380 if (!*e && e != type)
3381 proto = n;
3382 else if (!strcmp(type, "unspec"))
3383 proto = RTPROT_UNSPEC;
3384 else if (!strcmp(type, "kernel"))
3385 proto = RTPROT_KERNEL;
3386 else if (!strcmp(type, "boot"))
3387 proto = RTPROT_BOOT;
3388 else if (!strcmp(type, "static"))
3389 proto = RTPROT_STATIC;
3390 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) {
3391 while (fgets(buf, sizeof(buf) - 1, f) != NULL) {
3392 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
3393 continue;
3394
3395 n = strtoul(e, NULL, 10);
3396 e = strtok(NULL, " \t\n");
3397
3398 if (e && !strcmp(e, type)) {
3399 proto = n;
3400 break;
3401 }
3402 }
3403 fclose(f);
3404 }
3405
3406 if (proto > 255)
3407 return false;
3408
3409 *id = proto;
3410 return true;
3411 }
3412
3413 bool system_resolve_rt_table(const char *name, unsigned int *id)
3414 {
3415 FILE *f;
3416 char *e, buf[128];
3417 unsigned int n, table = RT_TABLE_UNSPEC;
3418
3419 /* first try to parse table as number */
3420 if ((n = strtoul(name, &e, 0)) > 0 && !*e)
3421 table = n;
3422
3423 /* handle well known aliases */
3424 else if (!strcmp(name, "default"))
3425 table = RT_TABLE_DEFAULT;
3426 else if (!strcmp(name, "main"))
3427 table = RT_TABLE_MAIN;
3428 else if (!strcmp(name, "local"))
3429 table = RT_TABLE_LOCAL;
3430
3431 /* try to look up name in /etc/iproute2/rt_tables */
3432 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL)
3433 {
3434 while (fgets(buf, sizeof(buf) - 1, f) != NULL)
3435 {
3436 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
3437 continue;
3438
3439 n = strtoul(e, NULL, 10);
3440 e = strtok(NULL, " \t\n");
3441
3442 if (e && !strcmp(e, name))
3443 {
3444 table = n;
3445 break;
3446 }
3447 }
3448
3449 fclose(f);
3450 }
3451
3452 if (table == RT_TABLE_UNSPEC)
3453 return false;
3454
3455 *id = table;
3456 return true;
3457 }
3458
3459 bool system_is_default_rt_table(unsigned int id)
3460 {
3461 return (id == RT_TABLE_MAIN);
3462 }
3463
3464 bool system_resolve_rpfilter(const char *filter, unsigned int *id)
3465 {
3466 char *e;
3467 unsigned int n;
3468
3469 if (!strcmp(filter, "strict"))
3470 n = 1;
3471 else if (!strcmp(filter, "loose"))
3472 n = 2;
3473 else {
3474 n = strtoul(filter, &e, 0);
3475 if (*e || e == filter || n > 2)
3476 return false;
3477 }
3478
3479 *id = n;
3480 return true;
3481 }
3482
3483 static int system_iprule(struct iprule *rule, int cmd)
3484 {
3485 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;
3486
3487 struct nl_msg *msg;
3488 struct rtmsg rtm = {
3489 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
3490 .rtm_protocol = RTPROT_STATIC,
3491 .rtm_scope = RT_SCOPE_UNIVERSE,
3492 .rtm_table = RT_TABLE_UNSPEC,
3493 .rtm_type = RTN_UNSPEC,
3494 .rtm_flags = 0,
3495 };
3496
3497 if (cmd == RTM_NEWRULE)
3498 rtm.rtm_type = RTN_UNICAST;
3499
3500 if (rule->invert)
3501 rtm.rtm_flags |= FIB_RULE_INVERT;
3502
3503 if (rule->flags & IPRULE_SRC)
3504 rtm.rtm_src_len = rule->src_mask;
3505
3506 if (rule->flags & IPRULE_DEST)
3507 rtm.rtm_dst_len = rule->dest_mask;
3508
3509 if (rule->flags & IPRULE_TOS)
3510 rtm.rtm_tos = rule->tos;
3511
3512 if (rule->flags & IPRULE_LOOKUP) {
3513 if (rule->lookup < 256)
3514 rtm.rtm_table = rule->lookup;
3515 }
3516
3517 if (rule->flags & IPRULE_ACTION)
3518 rtm.rtm_type = rule->action;
3519 else if (rule->flags & IPRULE_GOTO)
3520 rtm.rtm_type = FR_ACT_GOTO;
3521 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO)))
3522 rtm.rtm_type = FR_ACT_NOP;
3523
3524 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST);
3525
3526 if (!msg)
3527 return -1;
3528
3529 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
3530
3531 if (rule->flags & IPRULE_IN)
3532 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev);
3533
3534 if (rule->flags & IPRULE_OUT)
3535 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev);
3536
3537 if (rule->flags & IPRULE_SRC)
3538 nla_put(msg, FRA_SRC, alen, &rule->src_addr);
3539
3540 if (rule->flags & IPRULE_DEST)
3541 nla_put(msg, FRA_DST, alen, &rule->dest_addr);
3542
3543 if (rule->flags & IPRULE_PRIORITY)
3544 nla_put_u32(msg, FRA_PRIORITY, rule->priority);
3545 else if (cmd == RTM_NEWRULE)
3546 nla_put_u32(msg, FRA_PRIORITY, rule->order);
3547
3548 if (rule->flags & IPRULE_FWMARK)
3549 nla_put_u32(msg, FRA_FWMARK, rule->fwmark);
3550
3551 if (rule->flags & IPRULE_FWMASK)
3552 nla_put_u32(msg, FRA_FWMASK, rule->fwmask);
3553
3554 if (rule->flags & IPRULE_LOOKUP) {
3555 if (rule->lookup >= 256)
3556 nla_put_u32(msg, FRA_TABLE, rule->lookup);
3557 }
3558
3559 if (rule->flags & IPRULE_SUP_PREFIXLEN)
3560 nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen);
3561
3562 if (rule->flags & IPRULE_UIDRANGE) {
3563 struct fib_rule_uid_range uidrange = {
3564 .start = rule->uidrange_start,
3565 .end = rule->uidrange_end
3566 };
3567
3568 nla_put(msg, FRA_UID_RANGE, sizeof(uidrange), &uidrange);
3569 }
3570
3571 if (rule->flags & IPRULE_GOTO)
3572 nla_put_u32(msg, FRA_GOTO, rule->gotoid);
3573
3574 return system_rtnl_call(msg);
3575 }
3576
3577 int system_add_iprule(struct iprule *rule)
3578 {
3579 return system_iprule(rule, RTM_NEWRULE);
3580 }
3581
3582 int system_del_iprule(struct iprule *rule)
3583 {
3584 return system_iprule(rule, RTM_DELRULE);
3585 }
3586
3587 int system_flush_iprules(void)
3588 {
3589 int rv = 0;
3590 struct iprule rule;
3591
3592 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET);
3593 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6);
3594
3595 memset(&rule, 0, sizeof(rule));
3596
3597
3598 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP;
3599
3600 rule.priority = 0;
3601 rule.lookup = RT_TABLE_LOCAL;
3602 rv |= system_iprule(&rule, RTM_NEWRULE);
3603
3604 rule.priority = 32766;
3605 rule.lookup = RT_TABLE_MAIN;
3606 rv |= system_iprule(&rule, RTM_NEWRULE);
3607
3608 rule.priority = 32767;
3609 rule.lookup = RT_TABLE_DEFAULT;
3610 rv |= system_iprule(&rule, RTM_NEWRULE);
3611
3612
3613 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP;
3614
3615 rule.priority = 0;
3616 rule.lookup = RT_TABLE_LOCAL;
3617 rv |= system_iprule(&rule, RTM_NEWRULE);
3618
3619 rule.priority = 32766;
3620 rule.lookup = RT_TABLE_MAIN;
3621 rv |= system_iprule(&rule, RTM_NEWRULE);
3622
3623 return rv;
3624 }
3625
3626 bool system_resolve_iprule_action(const char *action, unsigned int *id)
3627 {
3628 return system_rtn_aton(action, id);
3629 }
3630
3631 time_t system_get_rtime(void)
3632 {
3633 struct timespec ts;
3634 struct timeval tv;
3635
3636 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
3637 return ts.tv_sec;
3638
3639 if (gettimeofday(&tv, NULL) == 0)
3640 return tv.tv_sec;
3641
3642 return 0;
3643 }
3644
3645 #ifndef IP_DF
3646 #define IP_DF 0x4000
3647 #endif
3648
3649 static int tunnel_ioctl(const char *name, int cmd, void *p)
3650 {
3651 struct ifreq ifr;
3652
3653 memset(&ifr, 0, sizeof(ifr));
3654 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
3655 ifr.ifr_ifru.ifru_data = p;
3656 return ioctl(sock_ioctl, cmd, &ifr);
3657 }
3658
3659 #ifdef IFLA_IPTUN_MAX
3660 static int system_add_ip6_tunnel(const char *name, const unsigned int link,
3661 struct blob_attr **tb)
3662 {
3663 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
3664 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3665 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
3666 struct blob_attr *cur;
3667 int ret = 0, ttl = 0;
3668
3669 if (!nlm)
3670 return -1;
3671
3672 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3673 nla_put_string(nlm, IFLA_IFNAME, name);
3674
3675 if (link)
3676 nla_put_u32(nlm, IFLA_LINK, link);
3677
3678 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3679 if (!linkinfo) {
3680 ret = -ENOMEM;
3681 goto failure;
3682 }
3683
3684 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl");
3685 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3686 if (!infodata) {
3687 ret = -ENOMEM;
3688 goto failure;
3689 }
3690
3691 if (link)
3692 nla_put_u32(nlm, IFLA_IPTUN_LINK, link);
3693
3694 if ((cur = tb[TUNNEL_ATTR_TTL]))
3695 ttl = blobmsg_get_u32(cur);
3696
3697 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP);
3698 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64);
3699
3700 struct in6_addr in6buf;
3701 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3702 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3703 ret = -EINVAL;
3704 goto failure;
3705 }
3706 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf);
3707 }
3708
3709 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3710 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3711 ret = -EINVAL;
3712 goto failure;
3713 }
3714 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf);
3715 }
3716
3717 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3718 struct blob_attr *tb_data[__IPIP6_DATA_ATTR_MAX];
3719 uint32_t tun_flags = IP6_TNL_F_IGN_ENCAP_LIMIT;
3720
3721 blobmsg_parse(ipip6_data_attr_list.params, __IPIP6_DATA_ATTR_MAX, tb_data,
3722 blobmsg_data(cur), blobmsg_len(cur));
3723
3724 if ((cur = tb_data[IPIP6_DATA_ENCAPLIMIT])) {
3725 char *str = blobmsg_get_string(cur);
3726
3727 if (strcmp(str, "ignore")) {
3728 char *e;
3729 unsigned encap_limit = strtoul(str, &e, 0);
3730
3731 if (e == str || *e || encap_limit > 255) {
3732 ret = -EINVAL;
3733 goto failure;
3734 }
3735
3736 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, encap_limit);
3737 tun_flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
3738 }
3739 }
3740
3741 #ifdef IFLA_IPTUN_FMR_MAX
3742 if ((cur = tb_data[IPIP6_DATA_FMRS])) {
3743 struct blob_attr *rcur;
3744 unsigned rrem, fmrcnt = 0;
3745 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS);
3746
3747 if (!fmrs) {
3748 ret = -ENOMEM;
3749 goto failure;
3750 }
3751
3752 blobmsg_for_each_attr(rcur, cur, rrem) {
3753 struct blob_attr *tb_fmr[__FMR_DATA_ATTR_MAX], *tb_cur;
3754 struct in6_addr ip6prefix;
3755 struct in_addr ip4prefix;
3756 unsigned ip4len, ip6len, ealen, offset;
3757
3758 blobmsg_parse(fmr_data_attr_list.params, __FMR_DATA_ATTR_MAX, tb_fmr,
3759 blobmsg_data(rcur), blobmsg_len(rcur));
3760
3761 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX6]) ||
3762 !parse_ip_and_netmask(AF_INET6,
3763 blobmsg_data(tb_cur), &ip6prefix,
3764 &ip6len)) {
3765 ret = -EINVAL;
3766 goto failure;
3767 }
3768
3769 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX4]) ||
3770 !parse_ip_and_netmask(AF_INET,
3771 blobmsg_data(tb_cur), &ip4prefix,
3772 &ip4len)) {
3773 ret = -EINVAL;
3774 goto failure;
3775 }
3776
3777 if (!(tb_cur = tb_fmr[FMR_DATA_EALEN])) {
3778 ret = -EINVAL;
3779 goto failure;
3780 }
3781 ealen = blobmsg_get_u32(tb_cur);
3782
3783 if (!(tb_cur = tb_fmr[FMR_DATA_OFFSET])) {
3784 ret = -EINVAL;
3785 goto failure;
3786 }
3787 offset = blobmsg_get_u32(tb_cur);
3788
3789 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt);
3790 if (!rule) {
3791 ret = -ENOMEM;
3792 goto failure;
3793 }
3794
3795 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix);
3796 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix);
3797 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len);
3798 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len);
3799 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen);
3800 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset);
3801
3802 nla_nest_end(nlm, rule);
3803 }
3804
3805 nla_nest_end(nlm, fmrs);
3806 }
3807 #endif
3808 if (tun_flags)
3809 nla_put_u32(nlm, IFLA_IPTUN_FLAGS, tun_flags);
3810 }
3811
3812 nla_nest_end(nlm, infodata);
3813 nla_nest_end(nlm, linkinfo);
3814
3815 return system_rtnl_call(nlm);
3816
3817 failure:
3818 nlmsg_free(nlm);
3819 return ret;
3820 }
3821 #endif
3822
3823 #ifdef IFLA_IPTUN_MAX
3824 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
3825 static int system_add_gre_tunnel(const char *name, const char *kind,
3826 const unsigned int link, struct blob_attr **tb, bool v6)
3827 {
3828 struct nl_msg *nlm;
3829 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
3830 struct blob_attr *cur;
3831 uint32_t ikey = 0, okey = 0, flowinfo = 0, flags6 = IP6_TNL_F_IGN_ENCAP_LIMIT;
3832 uint16_t iflags = 0, oflags = 0;
3833 uint8_t tos = 0;
3834 int ret = 0, ttl = 0;
3835 unsigned encap_limit = 0;
3836
3837 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3838 if (!nlm)
3839 return -1;
3840
3841 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3842 nla_put_string(nlm, IFLA_IFNAME, name);
3843
3844 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3845 if (!linkinfo) {
3846 ret = -ENOMEM;
3847 goto failure;
3848 }
3849
3850 nla_put_string(nlm, IFLA_INFO_KIND, kind);
3851 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3852 if (!infodata) {
3853 ret = -ENOMEM;
3854 goto failure;
3855 }
3856
3857 if (link)
3858 nla_put_u32(nlm, IFLA_GRE_LINK, link);
3859
3860 if ((cur = tb[TUNNEL_ATTR_TTL]))
3861 ttl = blobmsg_get_u32(cur);
3862
3863 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3864 char *str = blobmsg_get_string(cur);
3865 if (strcmp(str, "inherit")) {
3866 unsigned uval;
3867
3868 if (!system_tos_aton(str, &uval)) {
3869 ret = -EINVAL;
3870 goto failure;
3871 }
3872
3873 if (v6)
3874 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS;
3875 else
3876 tos = uval;
3877 } else {
3878 if (v6)
3879 flags6 |= IP6_TNL_F_USE_ORIG_TCLASS;
3880 else
3881 tos = 1;
3882 }
3883 }
3884
3885 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3886 struct blob_attr *tb_data[__GRE_DATA_ATTR_MAX];
3887
3888 blobmsg_parse(gre_data_attr_list.params, __GRE_DATA_ATTR_MAX, tb_data,
3889 blobmsg_data(cur), blobmsg_len(cur));
3890
3891 if ((cur = tb_data[GRE_DATA_IKEY])) {
3892 if ((ikey = blobmsg_get_u32(cur)))
3893 iflags |= GRE_KEY;
3894 }
3895
3896 if ((cur = tb_data[GRE_DATA_OKEY])) {
3897 if ((okey = blobmsg_get_u32(cur)))
3898 oflags |= GRE_KEY;
3899 }
3900
3901 if ((cur = tb_data[GRE_DATA_ICSUM])) {
3902 if (blobmsg_get_bool(cur))
3903 iflags |= GRE_CSUM;
3904 }
3905
3906 if ((cur = tb_data[GRE_DATA_OCSUM])) {
3907 if (blobmsg_get_bool(cur))
3908 oflags |= GRE_CSUM;
3909 }
3910
3911 if ((cur = tb_data[GRE_DATA_ISEQNO])) {
3912 if (blobmsg_get_bool(cur))
3913 iflags |= GRE_SEQ;
3914 }
3915
3916 if ((cur = tb_data[GRE_DATA_OSEQNO])) {
3917 if (blobmsg_get_bool(cur))
3918 oflags |= GRE_SEQ;
3919 }
3920
3921 if ((cur = tb_data[GRE_DATA_ENCAPLIMIT])) {
3922 char *str = blobmsg_get_string(cur);
3923
3924 if (strcmp(str, "ignore")) {
3925 char *e;
3926
3927 encap_limit = strtoul(str, &e, 0);
3928
3929 if (e == str || *e || encap_limit > 255) {
3930 ret = -EINVAL;
3931 goto failure;
3932 }
3933
3934 flags6 &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
3935 }
3936 }
3937 }
3938
3939 if (v6) {
3940 struct in6_addr in6buf;
3941 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3942 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3943 ret = -EINVAL;
3944 goto failure;
3945 }
3946 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf);
3947 }
3948
3949 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3950 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3951 ret = -EINVAL;
3952 goto failure;
3953 }
3954 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf);
3955 }
3956
3957 if (!(flags6 & IP6_TNL_F_IGN_ENCAP_LIMIT))
3958 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, encap_limit);
3959
3960 if (flowinfo)
3961 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo);
3962
3963 if (flags6)
3964 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags6);
3965
3966 if (!ttl)
3967 ttl = 64;
3968 } else {
3969 struct in_addr inbuf;
3970 bool set_df = true;
3971
3972 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3973 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3974 ret = -EINVAL;
3975 goto failure;
3976 }
3977 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf);
3978 }
3979
3980 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3981 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3982 ret = -EINVAL;
3983 goto failure;
3984 }
3985 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf);
3986
3987 if (IN_MULTICAST(ntohl(inbuf.s_addr))) {
3988 if (!okey) {
3989 okey = inbuf.s_addr;
3990 oflags |= GRE_KEY;
3991 }
3992
3993 if (!ikey) {
3994 ikey = inbuf.s_addr;
3995 iflags |= GRE_KEY;
3996 }
3997 }
3998 }
3999
4000 if ((cur = tb[TUNNEL_ATTR_DF]))
4001 set_df = blobmsg_get_bool(cur);
4002
4003 if (!set_df) {
4004 /* ttl != 0 and nopmtudisc are incompatible */
4005 if (ttl) {
4006 ret = -EINVAL;
4007 goto failure;
4008 }
4009 } else if (!ttl)
4010 ttl = 64;
4011
4012 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0);
4013
4014 nla_put_u8(nlm, IFLA_GRE_TOS, tos);
4015 }
4016
4017 if (ttl)
4018 nla_put_u8(nlm, IFLA_GRE_TTL, ttl);
4019
4020 if (oflags)
4021 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags);
4022
4023 if (iflags)
4024 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags);
4025
4026 if (okey)
4027 nla_put_u32(nlm, IFLA_GRE_OKEY, htonl(okey));
4028
4029 if (ikey)
4030 nla_put_u32(nlm, IFLA_GRE_IKEY, htonl(ikey));
4031
4032 nla_nest_end(nlm, infodata);
4033 nla_nest_end(nlm, linkinfo);
4034
4035 return system_rtnl_call(nlm);
4036
4037 failure:
4038 nlmsg_free(nlm);
4039 return ret;
4040 }
4041 #endif
4042
4043 #ifdef IFLA_VTI_MAX
4044 static int system_add_vti_tunnel(const char *name, const char *kind,
4045 const unsigned int link, struct blob_attr **tb, bool v6)
4046 {
4047 struct nl_msg *nlm;
4048 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
4049 struct blob_attr *cur;
4050 int ret = 0;
4051
4052 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
4053 if (!nlm)
4054 return -1;
4055
4056 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
4057 nla_put_string(nlm, IFLA_IFNAME, name);
4058
4059 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
4060 if (!linkinfo) {
4061 ret = -ENOMEM;
4062 goto failure;
4063 }
4064
4065 nla_put_string(nlm, IFLA_INFO_KIND, kind);
4066 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
4067 if (!infodata) {
4068 ret = -ENOMEM;
4069 goto failure;
4070 }
4071
4072 if (link)
4073 nla_put_u32(nlm, IFLA_VTI_LINK, link);
4074
4075 if (v6) {
4076 struct in6_addr in6buf;
4077 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
4078 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
4079 ret = -EINVAL;
4080 goto failure;
4081 }
4082 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf);
4083 }
4084
4085 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
4086 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
4087 ret = -EINVAL;
4088 goto failure;
4089 }
4090 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf);
4091 }
4092
4093 } else {
4094 struct in_addr inbuf;
4095
4096 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
4097 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
4098 ret = -EINVAL;
4099 goto failure;
4100 }
4101 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf);
4102 }
4103
4104 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
4105 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
4106 ret = -EINVAL;
4107 goto failure;
4108 }
4109 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf);
4110 }
4111
4112 }
4113
4114 if ((cur = tb[TUNNEL_ATTR_DATA])) {
4115 struct blob_attr *tb_data[__VTI_DATA_ATTR_MAX];
4116 uint32_t ikey = 0, okey = 0;
4117
4118 blobmsg_parse(vti_data_attr_list.params, __VTI_DATA_ATTR_MAX, tb_data,
4119 blobmsg_data(cur), blobmsg_len(cur));
4120
4121 if ((cur = tb_data[VTI_DATA_IKEY])) {
4122 if ((ikey = blobmsg_get_u32(cur)))
4123 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey));
4124 }
4125
4126 if ((cur = tb_data[VTI_DATA_OKEY])) {
4127 if ((okey = blobmsg_get_u32(cur)))
4128 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey));
4129 }
4130 }
4131
4132 nla_nest_end(nlm, infodata);
4133 nla_nest_end(nlm, linkinfo);
4134
4135 return system_rtnl_call(nlm);
4136
4137 failure:
4138 nlmsg_free(nlm);
4139 return ret;
4140 }
4141 #endif
4142
4143 #ifdef IFLA_XFRM_MAX
4144 static int system_add_xfrm_tunnel(const char *name, const char *kind,
4145 const unsigned int link, struct blob_attr **tb)
4146 {
4147 struct nl_msg *nlm;
4148 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
4149 struct blob_attr *cur;
4150 int ret = 0;
4151
4152 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
4153 if (!nlm)
4154 return -1;
4155
4156 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
4157 nla_put_string(nlm, IFLA_IFNAME, name);
4158
4159 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
4160 if (!linkinfo) {
4161 ret = -ENOMEM;
4162 goto failure;
4163 }
4164
4165 nla_put_string(nlm, IFLA_INFO_KIND, kind);
4166 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
4167 if (!infodata) {
4168 ret = -ENOMEM;
4169 goto failure;
4170 }
4171
4172 if (link)
4173 nla_put_u32(nlm, IFLA_XFRM_LINK, link);
4174
4175 if ((cur = tb[TUNNEL_ATTR_DATA])) {
4176 struct blob_attr *tb_data[__XFRM_DATA_ATTR_MAX];
4177 uint32_t if_id = 0;
4178
4179 blobmsg_parse(xfrm_data_attr_list.params, __XFRM_DATA_ATTR_MAX, tb_data,
4180 blobmsg_data(cur), blobmsg_len(cur));
4181
4182 if ((cur = tb_data[XFRM_DATA_IF_ID])) {
4183 if ((if_id = blobmsg_get_u32(cur)))
4184 nla_put_u32(nlm, IFLA_XFRM_IF_ID, if_id);
4185 }
4186
4187 }
4188
4189 nla_nest_end(nlm, infodata);
4190 nla_nest_end(nlm, linkinfo);
4191
4192 return system_rtnl_call(nlm);
4193
4194 failure:
4195 nlmsg_free(nlm);
4196 return ret;
4197 }
4198 #endif
4199
4200 #ifdef IFLA_VXLAN_MAX
4201 static void system_vxlan_map_bool_attr(struct nl_msg *msg, struct blob_attr **tb_data, int attrtype, int vxlandatatype, bool invert) {
4202 struct blob_attr *cur;
4203 if ((cur = tb_data[vxlandatatype])) {
4204 bool val = blobmsg_get_bool(cur);
4205 if (invert)
4206 val = !val;
4207
4208 if ((attrtype == IFLA_VXLAN_GBP) && val)
4209 nla_put_flag(msg, attrtype);
4210 else
4211 nla_put_u8(msg, attrtype, val);
4212
4213 }
4214 }
4215
4216 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6)
4217 {
4218 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX];
4219 struct nl_msg *msg;
4220 struct nlattr *linkinfo, *data;
4221 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
4222 struct blob_attr *cur;
4223 int ret = 0;
4224
4225 if ((cur = tb[TUNNEL_ATTR_DATA]))
4226 blobmsg_parse(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, tb_data,
4227 blobmsg_data(cur), blobmsg_len(cur));
4228 else
4229 return -EINVAL;
4230
4231 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
4232
4233 if (!msg)
4234 return -1;
4235
4236 nlmsg_append(msg, &iim, sizeof(iim), 0);
4237
4238 nla_put_string(msg, IFLA_IFNAME, name);
4239
4240 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) {
4241 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur));
4242 if (!ea) {
4243 ret = -EINVAL;
4244 goto failure;
4245 }
4246
4247 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea);
4248 }
4249
4250 if ((cur = tb[TUNNEL_ATTR_MTU])) {
4251 uint32_t mtu = blobmsg_get_u32(cur);
4252 nla_put_u32(msg, IFLA_MTU, mtu);
4253 }
4254
4255 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) {
4256 ret = -ENOMEM;
4257 goto failure;
4258 }
4259
4260 nla_put_string(msg, IFLA_INFO_KIND, "vxlan");
4261
4262 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) {
4263 ret = -ENOMEM;
4264 goto failure;
4265 }
4266
4267 if (link)
4268 nla_put_u32(msg, IFLA_VXLAN_LINK, link);
4269
4270 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) {
4271 uint32_t id = blobmsg_get_u32(cur);
4272 if (id >= (1u << 24) - 1) {
4273 ret = -EINVAL;
4274 goto failure;
4275 }
4276
4277 nla_put_u32(msg, IFLA_VXLAN_ID, id);
4278 }
4279
4280 if (v6) {
4281 struct in6_addr in6buf;
4282 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
4283 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
4284 ret = -EINVAL;
4285 goto failure;
4286 }
4287 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf);
4288 }
4289
4290 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
4291 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
4292 ret = -EINVAL;
4293 goto failure;
4294 }
4295 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf);
4296 }
4297 } else {
4298 struct in_addr inbuf;
4299
4300 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
4301 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
4302 ret = -EINVAL;
4303 goto failure;
4304 }
4305 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf);
4306 }
4307
4308 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
4309 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
4310 ret = -EINVAL;
4311 goto failure;
4312 }
4313 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf);
4314 }
4315 }
4316
4317 uint32_t port = 4789;
4318 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) {
4319 port = blobmsg_get_u32(cur);
4320 if (port < 1 || port > 65535) {
4321 ret = -EINVAL;
4322 goto failure;
4323 }
4324 }
4325 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port));
4326
4327 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMIN])) {
4328 struct ifla_vxlan_port_range srcports = {0,0};
4329
4330 uint32_t low = blobmsg_get_u32(cur);
4331 if (low < 1 || low > 65535 - 1) {
4332 ret = -EINVAL;
4333 goto failure;
4334 }
4335
4336 srcports.low = htons((uint16_t) low);
4337 srcports.high = htons((uint16_t) (low+1));
4338
4339 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMAX])) {
4340 uint32_t high = blobmsg_get_u32(cur);
4341 if (high < 1 || high > 65535) {
4342 ret = -EINVAL;
4343 goto failure;
4344 }
4345
4346 if (high > low)
4347 srcports.high = htons((uint16_t) high);
4348 }
4349
4350 nla_put(msg, IFLA_VXLAN_PORT_RANGE, sizeof(srcports), &srcports);
4351 }
4352
4353 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_CSUM, VXLAN_DATA_ATTR_TXCSUM, false);
4354 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, VXLAN_DATA_ATTR_RXCSUM, true);
4355 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, VXLAN_DATA_ATTR_TXCSUM, true);
4356 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_LEARNING, VXLAN_DATA_ATTR_LEARNING, false);
4357 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_RSC , VXLAN_DATA_ATTR_RSC, false);
4358 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_PROXY , VXLAN_DATA_ATTR_PROXY, false);
4359 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L2MISS , VXLAN_DATA_ATTR_L2MISS, false);
4360 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L3MISS , VXLAN_DATA_ATTR_L3MISS, false);
4361 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_GBP , VXLAN_DATA_ATTR_GBP, false);
4362
4363 if ((cur = tb_data[VXLAN_DATA_ATTR_AGEING])) {
4364 uint32_t ageing = blobmsg_get_u32(cur);
4365 nla_put_u32(msg, IFLA_VXLAN_AGEING, ageing);
4366 }
4367
4368 if ((cur = tb_data[VXLAN_DATA_ATTR_LIMIT])) {
4369 uint32_t maxaddress = blobmsg_get_u32(cur);
4370 nla_put_u32(msg, IFLA_VXLAN_LIMIT, maxaddress);
4371 }
4372
4373 if ((cur = tb[TUNNEL_ATTR_TOS])) {
4374 char *str = blobmsg_get_string(cur);
4375 unsigned tos = 1;
4376
4377 if (strcmp(str, "inherit")) {
4378 if (!system_tos_aton(str, &tos)) {
4379 ret = -EINVAL;
4380 goto failure;
4381 }
4382 }
4383
4384 nla_put_u8(msg, IFLA_VXLAN_TOS, tos);
4385 }
4386
4387 if ((cur = tb[TUNNEL_ATTR_TTL])) {
4388 uint32_t ttl = blobmsg_get_u32(cur);
4389 if (ttl < 1 || ttl > 255) {
4390 ret = -EINVAL;
4391 goto failure;
4392 }
4393
4394 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl);
4395 }
4396
4397 nla_nest_end(msg, data);
4398 nla_nest_end(msg, linkinfo);
4399
4400 ret = system_rtnl_call(msg);
4401 if (ret)
4402 D(SYSTEM, "Error adding vxlan '%s': %d", name, ret);
4403
4404 return ret;
4405
4406 failure:
4407 nlmsg_free(msg);
4408 return ret;
4409 }
4410 #endif
4411
4412 static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb)
4413 {
4414 struct blob_attr *cur;
4415 int ret = 0;
4416
4417 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
4418 return -1;
4419
4420 #ifdef SIOCADD6RD
4421 if ((cur = tb[TUNNEL_ATTR_DATA])) {
4422 struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX];
4423 unsigned int mask;
4424 struct ip_tunnel_6rd p6;
4425
4426 blobmsg_parse(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, tb_data,
4427 blobmsg_data(cur), blobmsg_len(cur));
4428
4429 memset(&p6, 0, sizeof(p6));
4430
4431 if ((cur = tb_data[SIXRD_DATA_PREFIX])) {
4432 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
4433 &p6.prefix, &mask) || mask > 128) {
4434 ret = -EINVAL;
4435 goto failure;
4436 }
4437
4438 p6.prefixlen = mask;
4439 }
4440
4441 if ((cur = tb_data[SIXRD_DATA_RELAY_PREFIX])) {
4442 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
4443 &p6.relay_prefix, &mask) || mask > 32) {
4444 ret = -EINVAL;
4445 goto failure;
4446 }
4447
4448 p6.relay_prefixlen = mask;
4449 }
4450
4451 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
4452 ret = -1;
4453 goto failure;
4454 }
4455 }
4456 #endif
4457
4458 return ret;
4459
4460 failure:
4461 system_link_del(name);
4462 return ret;
4463 }
4464
4465 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
4466 {
4467 struct blob_attr *cur;
4468 bool set_df = true;
4469 struct ip_tunnel_parm p = {
4470 .link = link,
4471 .iph = {
4472 .version = 4,
4473 .ihl = 5,
4474 .protocol = proto,
4475 }
4476 };
4477
4478 if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
4479 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
4480 return -EINVAL;
4481
4482 if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
4483 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
4484 return -EINVAL;
4485
4486 if ((cur = tb[TUNNEL_ATTR_DF]))
4487 set_df = blobmsg_get_bool(cur);
4488
4489 if ((cur = tb[TUNNEL_ATTR_TTL]))
4490 p.iph.ttl = blobmsg_get_u32(cur);
4491
4492 if ((cur = tb[TUNNEL_ATTR_TOS])) {
4493 char *str = blobmsg_get_string(cur);
4494 if (strcmp(str, "inherit")) {
4495 unsigned uval;
4496
4497 if (!system_tos_aton(str, &uval))
4498 return -EINVAL;
4499
4500 p.iph.tos = uval;
4501 } else
4502 p.iph.tos = 1;
4503 }
4504
4505 p.iph.frag_off = set_df ? htons(IP_DF) : 0;
4506 /* ttl !=0 and nopmtudisc are incompatible */
4507 if (p.iph.ttl && p.iph.frag_off == 0)
4508 return -EINVAL;
4509
4510 strncpy(p.name, name, sizeof(p.name) - 1);
4511
4512 switch (p.iph.protocol) {
4513 case IPPROTO_IPIP:
4514 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
4515 case IPPROTO_IPV6:
4516 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p);
4517 default:
4518 break;
4519 }
4520 return -1;
4521 }
4522
4523 int system_del_ip_tunnel(const struct device *dev)
4524 {
4525 return system_link_del(dev->ifname);
4526 }
4527
4528 int system_update_ipv6_mtu(struct device *dev, int mtu)
4529 {
4530 int ret = -1;
4531 char buf[64];
4532 int fd;
4533
4534 fd = open(dev_sysctl_path("ipv6/conf", dev->ifname, "mtu"), O_RDWR);
4535 if (fd < 0)
4536 return ret;
4537
4538 if (!mtu) {
4539 ssize_t len = read(fd, buf, sizeof(buf) - 1);
4540 if (len < 0)
4541 goto out;
4542
4543 buf[len] = 0;
4544 ret = atoi(buf);
4545 } else {
4546 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0)
4547 ret = mtu;
4548 }
4549
4550 out:
4551 close(fd);
4552 return ret;
4553 }
4554
4555 int system_add_ip_tunnel(const struct device *dev, struct blob_attr *attr)
4556 {
4557 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
4558 struct blob_attr *cur;
4559 const char *str;
4560
4561 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
4562 blob_data(attr), blob_len(attr));
4563
4564 system_link_del(dev->ifname);
4565
4566 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
4567 return -EINVAL;
4568 str = blobmsg_data(cur);
4569
4570 unsigned int ttl = 0;
4571 if ((cur = tb[TUNNEL_ATTR_TTL])) {
4572 ttl = blobmsg_get_u32(cur);
4573 if (ttl > 255)
4574 return -EINVAL;
4575 }
4576
4577 unsigned int link = 0;
4578 if ((cur = tb[TUNNEL_ATTR_LINK])) {
4579 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
4580 if (!iface)
4581 return -EINVAL;
4582
4583 if (iface->l3_dev.dev)
4584 link = iface->l3_dev.dev->ifindex;
4585 }
4586
4587 if (!strcmp(str, "sit"))
4588 return system_add_sit_tunnel(dev->ifname, link, tb);
4589 #ifdef IFLA_IPTUN_MAX
4590 else if (!strcmp(str, "ipip6")) {
4591 return system_add_ip6_tunnel(dev->ifname, link, tb);
4592 } else if (!strcmp(str, "greip")) {
4593 return system_add_gre_tunnel(dev->ifname, "gre", link, tb, false);
4594 } else if (!strcmp(str, "gretapip")) {
4595 return system_add_gre_tunnel(dev->ifname, "gretap", link, tb, false);
4596 } else if (!strcmp(str, "greip6")) {
4597 return system_add_gre_tunnel(dev->ifname, "ip6gre", link, tb, true);
4598 } else if (!strcmp(str, "gretapip6")) {
4599 return system_add_gre_tunnel(dev->ifname, "ip6gretap", link, tb, true);
4600 #ifdef IFLA_VTI_MAX
4601 } else if (!strcmp(str, "vtiip")) {
4602 return system_add_vti_tunnel(dev->ifname, "vti", link, tb, false);
4603 } else if (!strcmp(str, "vtiip6")) {
4604 return system_add_vti_tunnel(dev->ifname, "vti6", link, tb, true);
4605 #endif
4606 #ifdef IFLA_XFRM_MAX
4607 } else if (!strcmp(str, "xfrm")) {
4608 return system_add_xfrm_tunnel(dev->ifname, "xfrm", link, tb);
4609 #endif
4610 #ifdef IFLA_VXLAN_MAX
4611 } else if(!strcmp(str, "vxlan")) {
4612 return system_add_vxlan(dev->ifname, link, tb, false);
4613 } else if(!strcmp(str, "vxlan6")) {
4614 return system_add_vxlan(dev->ifname, link, tb, true);
4615 #endif
4616 #endif
4617 } else if (!strcmp(str, "ipip")) {
4618 return system_add_proto_tunnel(dev->ifname, IPPROTO_IPIP, link, tb);
4619 }
4620 else
4621 return -EINVAL;
4622
4623 return 0;
4624 }