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