system-linux: add wrapper function for creating link config messages
[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 int
2355 system_if_dump_info(struct device *dev, struct blob_buf *b)
2356 {
2357 struct ethtool_cmd ecmd;
2358 struct ifreq ifr;
2359 char *s;
2360 void *c;
2361
2362 memset(&ecmd, 0, sizeof(ecmd));
2363 memset(&ifr, 0, sizeof(ifr));
2364 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
2365 ifr.ifr_data = (caddr_t) &ecmd;
2366 ecmd.cmd = ETHTOOL_GSET;
2367
2368 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == 0) {
2369 c = blobmsg_open_array(b, "link-advertising");
2370 system_add_link_modes(b, ecmd.advertising);
2371 blobmsg_close_array(b, c);
2372
2373 c = blobmsg_open_array(b, "link-partner-advertising");
2374 system_add_link_modes(b, ecmd.lp_advertising);
2375 blobmsg_close_array(b, c);
2376
2377 c = blobmsg_open_array(b, "link-supported");
2378 system_add_link_modes(b, ecmd.supported);
2379 blobmsg_close_array(b, c);
2380
2381 s = blobmsg_alloc_string_buffer(b, "speed", 8);
2382 snprintf(s, 8, "%d%c", ethtool_cmd_speed(&ecmd),
2383 ecmd.duplex == DUPLEX_HALF ? 'H' : 'F');
2384 blobmsg_add_string_buffer(b);
2385
2386 blobmsg_add_u8(b, "autoneg", !!ecmd.autoneg);
2387 }
2388
2389 system_add_devtype(b, dev->ifname);
2390
2391 return 0;
2392 }
2393
2394 int
2395 system_if_dump_stats(struct device *dev, struct blob_buf *b)
2396 {
2397 const char *const counters[] = {
2398 "collisions", "rx_frame_errors", "tx_compressed",
2399 "multicast", "rx_length_errors", "tx_dropped",
2400 "rx_bytes", "rx_missed_errors", "tx_errors",
2401 "rx_compressed", "rx_over_errors", "tx_fifo_errors",
2402 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors",
2403 "rx_dropped", "tx_aborted_errors", "tx_packets",
2404 "rx_errors", "tx_bytes", "tx_window_errors",
2405 "rx_fifo_errors", "tx_carrier_errors",
2406 };
2407 int stats_dir;
2408 int i;
2409 uint64_t val = 0;
2410
2411 stats_dir = open(dev_sysfs_path(dev->ifname, "statistics"), O_DIRECTORY);
2412 if (stats_dir < 0)
2413 return -1;
2414
2415 for (i = 0; i < ARRAY_SIZE(counters); i++)
2416 if (read_uint64_file(stats_dir, counters[i], &val))
2417 blobmsg_add_u64(b, counters[i], val);
2418
2419 close(stats_dir);
2420 return 0;
2421 }
2422
2423 static int system_addr(struct device *dev, struct device_addr *addr, int cmd)
2424 {
2425 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4);
2426 int alen = v4 ? 4 : 16;
2427 unsigned int flags = 0;
2428 struct ifaddrmsg ifa = {
2429 .ifa_family = (alen == 4) ? AF_INET : AF_INET6,
2430 .ifa_prefixlen = addr->mask,
2431 .ifa_index = dev->ifindex,
2432 };
2433
2434 struct nl_msg *msg;
2435 if (cmd == RTM_NEWADDR)
2436 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2437
2438 msg = nlmsg_alloc_simple(cmd, flags);
2439 if (!msg)
2440 return -1;
2441
2442 nlmsg_append(msg, &ifa, sizeof(ifa), 0);
2443 nla_put(msg, IFA_LOCAL, alen, &addr->addr);
2444 if (v4) {
2445 if (addr->broadcast)
2446 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast);
2447 if (addr->point_to_point)
2448 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point);
2449 } else {
2450 time_t now = system_get_rtime();
2451 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0};
2452
2453 if (addr->preferred_until) {
2454 int64_t preferred = addr->preferred_until - now;
2455 if (preferred < 0)
2456 preferred = 0;
2457 else if (preferred > UINT32_MAX)
2458 preferred = UINT32_MAX;
2459
2460 cinfo.ifa_prefered = preferred;
2461 }
2462
2463 if (addr->valid_until) {
2464 int64_t valid = addr->valid_until - now;
2465 if (valid <= 0) {
2466 nlmsg_free(msg);
2467 return -1;
2468 }
2469 else if (valid > UINT32_MAX)
2470 valid = UINT32_MAX;
2471
2472 cinfo.ifa_valid = valid;
2473 }
2474
2475 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo);
2476
2477 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK))
2478 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE);
2479 }
2480
2481 return system_rtnl_call(msg);
2482 }
2483
2484 int system_add_address(struct device *dev, struct device_addr *addr)
2485 {
2486 return system_addr(dev, addr, RTM_NEWADDR);
2487 }
2488
2489 int system_del_address(struct device *dev, struct device_addr *addr)
2490 {
2491 return system_addr(dev, addr, RTM_DELADDR);
2492 }
2493
2494 static int system_neigh(struct device *dev, struct device_neighbor *neighbor, int cmd)
2495 {
2496 int alen = ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
2497 unsigned int flags = 0;
2498 struct ndmsg ndm = {
2499 .ndm_family = (alen == 4) ? AF_INET : AF_INET6,
2500 .ndm_ifindex = dev->ifindex,
2501 .ndm_state = NUD_PERMANENT,
2502 .ndm_flags = (neighbor->proxy ? NTF_PROXY : 0) | (neighbor->router ? NTF_ROUTER : 0),
2503 };
2504 struct nl_msg *msg;
2505
2506 if (cmd == RTM_NEWNEIGH)
2507 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2508
2509 msg = nlmsg_alloc_simple(cmd, flags);
2510
2511 if (!msg)
2512 return -1;
2513
2514 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
2515
2516 nla_put(msg, NDA_DST, alen, &neighbor->addr);
2517 if (neighbor->flags & DEVNEIGH_MAC)
2518 nla_put(msg, NDA_LLADDR, sizeof(neighbor->macaddr), &neighbor->macaddr);
2519
2520
2521 return system_rtnl_call(msg);
2522 }
2523
2524 int system_add_neighbor(struct device *dev, struct device_neighbor *neighbor)
2525 {
2526 return system_neigh(dev, neighbor, RTM_NEWNEIGH);
2527 }
2528
2529 int system_del_neighbor(struct device *dev, struct device_neighbor *neighbor)
2530 {
2531 return system_neigh(dev, neighbor, RTM_DELNEIGH);
2532 }
2533
2534 static int system_rt(struct device *dev, struct device_route *route, int cmd)
2535 {
2536 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
2537 bool have_gw;
2538 unsigned int flags = 0;
2539
2540 if (alen == 4)
2541 have_gw = !!route->nexthop.in.s_addr;
2542 else
2543 have_gw = route->nexthop.in6.s6_addr32[0] ||
2544 route->nexthop.in6.s6_addr32[1] ||
2545 route->nexthop.in6.s6_addr32[2] ||
2546 route->nexthop.in6.s6_addr32[3];
2547
2548 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))
2549 ? route->table : RT_TABLE_MAIN;
2550
2551 struct rtmsg rtm = {
2552 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2553 .rtm_dst_len = route->mask,
2554 .rtm_src_len = route->sourcemask,
2555 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
2556 .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC,
2557 .rtm_scope = RT_SCOPE_NOWHERE,
2558 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
2559 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
2560 };
2561 struct nl_msg *msg;
2562
2563 if (cmd == RTM_NEWROUTE) {
2564 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2565
2566 if (!dev) { /* Add null-route */
2567 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
2568 rtm.rtm_type = RTN_UNREACHABLE;
2569 }
2570 else
2571 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
2572 }
2573
2574 if (route->flags & DEVROUTE_TYPE) {
2575 rtm.rtm_type = route->type;
2576 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) {
2577 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST ||
2578 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST)
2579 rtm.rtm_table = RT_TABLE_LOCAL;
2580 }
2581
2582 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) {
2583 rtm.rtm_scope = RT_SCOPE_HOST;
2584 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
2585 rtm.rtm_type == RTN_ANYCAST) {
2586 rtm.rtm_scope = RT_SCOPE_LINK;
2587 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE ||
2588 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY ||
2589 rtm.rtm_type == RTN_THROW) {
2590 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
2591 dev = NULL;
2592 }
2593 }
2594
2595 msg = nlmsg_alloc_simple(cmd, flags);
2596 if (!msg)
2597 return -1;
2598
2599 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2600
2601 if (route->mask)
2602 nla_put(msg, RTA_DST, alen, &route->addr);
2603
2604 if (route->sourcemask) {
2605 if (rtm.rtm_family == AF_INET)
2606 nla_put(msg, RTA_PREFSRC, alen, &route->source);
2607 else
2608 nla_put(msg, RTA_SRC, alen, &route->source);
2609 }
2610
2611 if (route->metric > 0)
2612 nla_put_u32(msg, RTA_PRIORITY, route->metric);
2613
2614 if (have_gw)
2615 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop);
2616
2617 if (dev)
2618 nla_put_u32(msg, RTA_OIF, dev->ifindex);
2619
2620 if (table >= 256)
2621 nla_put_u32(msg, RTA_TABLE, table);
2622
2623 if (route->flags & DEVROUTE_MTU) {
2624 struct nlattr *metrics;
2625
2626 if (!(metrics = nla_nest_start(msg, RTA_METRICS)))
2627 goto nla_put_failure;
2628
2629 nla_put_u32(msg, RTAX_MTU, route->mtu);
2630
2631 nla_nest_end(msg, metrics);
2632 }
2633
2634 return system_rtnl_call(msg);
2635
2636 nla_put_failure:
2637 nlmsg_free(msg);
2638 return -ENOMEM;
2639 }
2640
2641 int system_add_route(struct device *dev, struct device_route *route)
2642 {
2643 return system_rt(dev, route, RTM_NEWROUTE);
2644 }
2645
2646 int system_del_route(struct device *dev, struct device_route *route)
2647 {
2648 return system_rt(dev, route, RTM_DELROUTE);
2649 }
2650
2651 int system_flush_routes(void)
2652 {
2653 const char *names[] = { "ipv4", "ipv6" };
2654 int fd, i;
2655
2656 for (i = 0; i < ARRAY_SIZE(names); i++) {
2657 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/route/flush", proc_path, names[i]);
2658 fd = open(dev_buf, O_WRONLY);
2659 if (fd < 0)
2660 continue;
2661
2662 if (write(fd, "-1", 2)) {}
2663 close(fd);
2664 }
2665 return 0;
2666 }
2667
2668 bool system_resolve_rt_type(const char *type, unsigned int *id)
2669 {
2670 return system_rtn_aton(type, id);
2671 }
2672
2673 bool system_resolve_rt_proto(const char *type, unsigned int *id)
2674 {
2675 FILE *f;
2676 char *e, buf[128];
2677 unsigned int n, proto = 256;
2678 n = strtoul(type, &e, 0);
2679 if (!*e && e != type)
2680 proto = n;
2681 else if (!strcmp(type, "unspec"))
2682 proto = RTPROT_UNSPEC;
2683 else if (!strcmp(type, "kernel"))
2684 proto = RTPROT_KERNEL;
2685 else if (!strcmp(type, "boot"))
2686 proto = RTPROT_BOOT;
2687 else if (!strcmp(type, "static"))
2688 proto = RTPROT_STATIC;
2689 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) {
2690 while (fgets(buf, sizeof(buf) - 1, f) != NULL) {
2691 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2692 continue;
2693
2694 n = strtoul(e, NULL, 10);
2695 e = strtok(NULL, " \t\n");
2696
2697 if (e && !strcmp(e, type)) {
2698 proto = n;
2699 break;
2700 }
2701 }
2702 fclose(f);
2703 }
2704
2705 if (proto > 255)
2706 return false;
2707
2708 *id = proto;
2709 return true;
2710 }
2711
2712 bool system_resolve_rt_table(const char *name, unsigned int *id)
2713 {
2714 FILE *f;
2715 char *e, buf[128];
2716 unsigned int n, table = RT_TABLE_UNSPEC;
2717
2718 /* first try to parse table as number */
2719 if ((n = strtoul(name, &e, 0)) > 0 && !*e)
2720 table = n;
2721
2722 /* handle well known aliases */
2723 else if (!strcmp(name, "default"))
2724 table = RT_TABLE_DEFAULT;
2725 else if (!strcmp(name, "main"))
2726 table = RT_TABLE_MAIN;
2727 else if (!strcmp(name, "local"))
2728 table = RT_TABLE_LOCAL;
2729
2730 /* try to look up name in /etc/iproute2/rt_tables */
2731 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL)
2732 {
2733 while (fgets(buf, sizeof(buf) - 1, f) != NULL)
2734 {
2735 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2736 continue;
2737
2738 n = strtoul(e, NULL, 10);
2739 e = strtok(NULL, " \t\n");
2740
2741 if (e && !strcmp(e, name))
2742 {
2743 table = n;
2744 break;
2745 }
2746 }
2747
2748 fclose(f);
2749 }
2750
2751 if (table == RT_TABLE_UNSPEC)
2752 return false;
2753
2754 *id = table;
2755 return true;
2756 }
2757
2758 bool system_is_default_rt_table(unsigned int id)
2759 {
2760 return (id == RT_TABLE_MAIN);
2761 }
2762
2763 bool system_resolve_rpfilter(const char *filter, unsigned int *id)
2764 {
2765 char *e;
2766 unsigned int n;
2767
2768 if (!strcmp(filter, "strict"))
2769 n = 1;
2770 else if (!strcmp(filter, "loose"))
2771 n = 2;
2772 else {
2773 n = strtoul(filter, &e, 0);
2774 if (*e || e == filter || n > 2)
2775 return false;
2776 }
2777
2778 *id = n;
2779 return true;
2780 }
2781
2782 static int system_iprule(struct iprule *rule, int cmd)
2783 {
2784 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;
2785
2786 struct nl_msg *msg;
2787 struct rtmsg rtm = {
2788 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2789 .rtm_protocol = RTPROT_STATIC,
2790 .rtm_scope = RT_SCOPE_UNIVERSE,
2791 .rtm_table = RT_TABLE_UNSPEC,
2792 .rtm_type = RTN_UNSPEC,
2793 .rtm_flags = 0,
2794 };
2795
2796 if (cmd == RTM_NEWRULE)
2797 rtm.rtm_type = RTN_UNICAST;
2798
2799 if (rule->invert)
2800 rtm.rtm_flags |= FIB_RULE_INVERT;
2801
2802 if (rule->flags & IPRULE_SRC)
2803 rtm.rtm_src_len = rule->src_mask;
2804
2805 if (rule->flags & IPRULE_DEST)
2806 rtm.rtm_dst_len = rule->dest_mask;
2807
2808 if (rule->flags & IPRULE_TOS)
2809 rtm.rtm_tos = rule->tos;
2810
2811 if (rule->flags & IPRULE_LOOKUP) {
2812 if (rule->lookup < 256)
2813 rtm.rtm_table = rule->lookup;
2814 }
2815
2816 if (rule->flags & IPRULE_ACTION)
2817 rtm.rtm_type = rule->action;
2818 else if (rule->flags & IPRULE_GOTO)
2819 rtm.rtm_type = FR_ACT_GOTO;
2820 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO)))
2821 rtm.rtm_type = FR_ACT_NOP;
2822
2823 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST);
2824
2825 if (!msg)
2826 return -1;
2827
2828 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2829
2830 if (rule->flags & IPRULE_IN)
2831 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev);
2832
2833 if (rule->flags & IPRULE_OUT)
2834 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev);
2835
2836 if (rule->flags & IPRULE_SRC)
2837 nla_put(msg, FRA_SRC, alen, &rule->src_addr);
2838
2839 if (rule->flags & IPRULE_DEST)
2840 nla_put(msg, FRA_DST, alen, &rule->dest_addr);
2841
2842 if (rule->flags & IPRULE_PRIORITY)
2843 nla_put_u32(msg, FRA_PRIORITY, rule->priority);
2844 else if (cmd == RTM_NEWRULE)
2845 nla_put_u32(msg, FRA_PRIORITY, rule->order);
2846
2847 if (rule->flags & IPRULE_FWMARK)
2848 nla_put_u32(msg, FRA_FWMARK, rule->fwmark);
2849
2850 if (rule->flags & IPRULE_FWMASK)
2851 nla_put_u32(msg, FRA_FWMASK, rule->fwmask);
2852
2853 if (rule->flags & IPRULE_LOOKUP) {
2854 if (rule->lookup >= 256)
2855 nla_put_u32(msg, FRA_TABLE, rule->lookup);
2856 }
2857
2858 if (rule->flags & IPRULE_SUP_PREFIXLEN)
2859 nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen);
2860
2861 if (rule->flags & IPRULE_UIDRANGE) {
2862 struct fib_rule_uid_range uidrange = {
2863 .start = rule->uidrange_start,
2864 .end = rule->uidrange_end
2865 };
2866
2867 nla_put(msg, FRA_UID_RANGE, sizeof(uidrange), &uidrange);
2868 }
2869
2870 if (rule->flags & IPRULE_GOTO)
2871 nla_put_u32(msg, FRA_GOTO, rule->gotoid);
2872
2873 return system_rtnl_call(msg);
2874 }
2875
2876 int system_add_iprule(struct iprule *rule)
2877 {
2878 return system_iprule(rule, RTM_NEWRULE);
2879 }
2880
2881 int system_del_iprule(struct iprule *rule)
2882 {
2883 return system_iprule(rule, RTM_DELRULE);
2884 }
2885
2886 int system_flush_iprules(void)
2887 {
2888 int rv = 0;
2889 struct iprule rule;
2890
2891 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET);
2892 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6);
2893
2894 memset(&rule, 0, sizeof(rule));
2895
2896
2897 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2898
2899 rule.priority = 0;
2900 rule.lookup = RT_TABLE_LOCAL;
2901 rv |= system_iprule(&rule, RTM_NEWRULE);
2902
2903 rule.priority = 32766;
2904 rule.lookup = RT_TABLE_MAIN;
2905 rv |= system_iprule(&rule, RTM_NEWRULE);
2906
2907 rule.priority = 32767;
2908 rule.lookup = RT_TABLE_DEFAULT;
2909 rv |= system_iprule(&rule, RTM_NEWRULE);
2910
2911
2912 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2913
2914 rule.priority = 0;
2915 rule.lookup = RT_TABLE_LOCAL;
2916 rv |= system_iprule(&rule, RTM_NEWRULE);
2917
2918 rule.priority = 32766;
2919 rule.lookup = RT_TABLE_MAIN;
2920 rv |= system_iprule(&rule, RTM_NEWRULE);
2921
2922 return rv;
2923 }
2924
2925 bool system_resolve_iprule_action(const char *action, unsigned int *id)
2926 {
2927 return system_rtn_aton(action, id);
2928 }
2929
2930 time_t system_get_rtime(void)
2931 {
2932 struct timespec ts;
2933 struct timeval tv;
2934
2935 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
2936 return ts.tv_sec;
2937
2938 if (gettimeofday(&tv, NULL) == 0)
2939 return tv.tv_sec;
2940
2941 return 0;
2942 }
2943
2944 #ifndef IP_DF
2945 #define IP_DF 0x4000
2946 #endif
2947
2948 static int tunnel_ioctl(const char *name, int cmd, void *p)
2949 {
2950 struct ifreq ifr;
2951
2952 memset(&ifr, 0, sizeof(ifr));
2953 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
2954 ifr.ifr_ifru.ifru_data = p;
2955 return ioctl(sock_ioctl, cmd, &ifr);
2956 }
2957
2958 #ifdef IFLA_IPTUN_MAX
2959 static int system_add_ip6_tunnel(const char *name, const unsigned int link,
2960 struct blob_attr **tb)
2961 {
2962 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
2963 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2964 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
2965 struct blob_attr *cur;
2966 int ret = 0, ttl = 0;
2967
2968 if (!nlm)
2969 return -1;
2970
2971 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2972 nla_put_string(nlm, IFLA_IFNAME, name);
2973
2974 if (link)
2975 nla_put_u32(nlm, IFLA_LINK, link);
2976
2977 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2978 if (!linkinfo) {
2979 ret = -ENOMEM;
2980 goto failure;
2981 }
2982
2983 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl");
2984 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2985 if (!infodata) {
2986 ret = -ENOMEM;
2987 goto failure;
2988 }
2989
2990 if (link)
2991 nla_put_u32(nlm, IFLA_IPTUN_LINK, link);
2992
2993 if ((cur = tb[TUNNEL_ATTR_TTL]))
2994 ttl = blobmsg_get_u32(cur);
2995
2996 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP);
2997 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64);
2998
2999 struct in6_addr in6buf;
3000 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3001 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3002 ret = -EINVAL;
3003 goto failure;
3004 }
3005 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf);
3006 }
3007
3008 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3009 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3010 ret = -EINVAL;
3011 goto failure;
3012 }
3013 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf);
3014 }
3015
3016 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3017 struct blob_attr *tb_data[__IPIP6_DATA_ATTR_MAX];
3018 uint32_t tun_flags = IP6_TNL_F_IGN_ENCAP_LIMIT;
3019
3020 blobmsg_parse(ipip6_data_attr_list.params, __IPIP6_DATA_ATTR_MAX, tb_data,
3021 blobmsg_data(cur), blobmsg_len(cur));
3022
3023 if ((cur = tb_data[IPIP6_DATA_ENCAPLIMIT])) {
3024 char *str = blobmsg_get_string(cur);
3025
3026 if (strcmp(str, "ignore")) {
3027 char *e;
3028 unsigned encap_limit = strtoul(str, &e, 0);
3029
3030 if (e == str || *e || encap_limit > 255) {
3031 ret = -EINVAL;
3032 goto failure;
3033 }
3034
3035 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, encap_limit);
3036 tun_flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
3037 }
3038 }
3039
3040 #ifdef IFLA_IPTUN_FMR_MAX
3041 if ((cur = tb_data[IPIP6_DATA_FMRS])) {
3042 struct blob_attr *rcur;
3043 unsigned rrem, fmrcnt = 0;
3044 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS);
3045
3046 if (!fmrs) {
3047 ret = -ENOMEM;
3048 goto failure;
3049 }
3050
3051 blobmsg_for_each_attr(rcur, cur, rrem) {
3052 struct blob_attr *tb_fmr[__FMR_DATA_ATTR_MAX], *tb_cur;
3053 struct in6_addr ip6prefix;
3054 struct in_addr ip4prefix;
3055 unsigned ip4len, ip6len, ealen, offset;
3056
3057 blobmsg_parse(fmr_data_attr_list.params, __FMR_DATA_ATTR_MAX, tb_fmr,
3058 blobmsg_data(rcur), blobmsg_len(rcur));
3059
3060 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX6]) ||
3061 !parse_ip_and_netmask(AF_INET6,
3062 blobmsg_data(tb_cur), &ip6prefix,
3063 &ip6len)) {
3064 ret = -EINVAL;
3065 goto failure;
3066 }
3067
3068 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX4]) ||
3069 !parse_ip_and_netmask(AF_INET,
3070 blobmsg_data(tb_cur), &ip4prefix,
3071 &ip4len)) {
3072 ret = -EINVAL;
3073 goto failure;
3074 }
3075
3076 if (!(tb_cur = tb_fmr[FMR_DATA_EALEN])) {
3077 ret = -EINVAL;
3078 goto failure;
3079 }
3080 ealen = blobmsg_get_u32(tb_cur);
3081
3082 if (!(tb_cur = tb_fmr[FMR_DATA_OFFSET])) {
3083 ret = -EINVAL;
3084 goto failure;
3085 }
3086 offset = blobmsg_get_u32(tb_cur);
3087
3088 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt);
3089 if (!rule) {
3090 ret = -ENOMEM;
3091 goto failure;
3092 }
3093
3094 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix);
3095 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix);
3096 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len);
3097 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len);
3098 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen);
3099 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset);
3100
3101 nla_nest_end(nlm, rule);
3102 }
3103
3104 nla_nest_end(nlm, fmrs);
3105 }
3106 #endif
3107 if (tun_flags)
3108 nla_put_u32(nlm, IFLA_IPTUN_FLAGS, tun_flags);
3109 }
3110
3111 nla_nest_end(nlm, infodata);
3112 nla_nest_end(nlm, linkinfo);
3113
3114 return system_rtnl_call(nlm);
3115
3116 failure:
3117 nlmsg_free(nlm);
3118 return ret;
3119 }
3120 #endif
3121
3122 #ifdef IFLA_IPTUN_MAX
3123 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
3124 static int system_add_gre_tunnel(const char *name, const char *kind,
3125 const unsigned int link, struct blob_attr **tb, bool v6)
3126 {
3127 struct nl_msg *nlm;
3128 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
3129 struct blob_attr *cur;
3130 uint32_t ikey = 0, okey = 0, flowinfo = 0, flags6 = IP6_TNL_F_IGN_ENCAP_LIMIT;
3131 uint16_t iflags = 0, oflags = 0;
3132 uint8_t tos = 0;
3133 int ret = 0, ttl = 0;
3134 unsigned encap_limit = 0;
3135
3136 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3137 if (!nlm)
3138 return -1;
3139
3140 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3141 nla_put_string(nlm, IFLA_IFNAME, name);
3142
3143 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3144 if (!linkinfo) {
3145 ret = -ENOMEM;
3146 goto failure;
3147 }
3148
3149 nla_put_string(nlm, IFLA_INFO_KIND, kind);
3150 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3151 if (!infodata) {
3152 ret = -ENOMEM;
3153 goto failure;
3154 }
3155
3156 if (link)
3157 nla_put_u32(nlm, IFLA_GRE_LINK, link);
3158
3159 if ((cur = tb[TUNNEL_ATTR_TTL]))
3160 ttl = blobmsg_get_u32(cur);
3161
3162 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3163 char *str = blobmsg_get_string(cur);
3164 if (strcmp(str, "inherit")) {
3165 unsigned uval;
3166
3167 if (!system_tos_aton(str, &uval)) {
3168 ret = -EINVAL;
3169 goto failure;
3170 }
3171
3172 if (v6)
3173 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS;
3174 else
3175 tos = uval;
3176 } else {
3177 if (v6)
3178 flags6 |= IP6_TNL_F_USE_ORIG_TCLASS;
3179 else
3180 tos = 1;
3181 }
3182 }
3183
3184 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3185 struct blob_attr *tb_data[__GRE_DATA_ATTR_MAX];
3186
3187 blobmsg_parse(gre_data_attr_list.params, __GRE_DATA_ATTR_MAX, tb_data,
3188 blobmsg_data(cur), blobmsg_len(cur));
3189
3190 if ((cur = tb_data[GRE_DATA_IKEY])) {
3191 if ((ikey = blobmsg_get_u32(cur)))
3192 iflags |= GRE_KEY;
3193 }
3194
3195 if ((cur = tb_data[GRE_DATA_OKEY])) {
3196 if ((okey = blobmsg_get_u32(cur)))
3197 oflags |= GRE_KEY;
3198 }
3199
3200 if ((cur = tb_data[GRE_DATA_ICSUM])) {
3201 if (blobmsg_get_bool(cur))
3202 iflags |= GRE_CSUM;
3203 }
3204
3205 if ((cur = tb_data[GRE_DATA_OCSUM])) {
3206 if (blobmsg_get_bool(cur))
3207 oflags |= GRE_CSUM;
3208 }
3209
3210 if ((cur = tb_data[GRE_DATA_ISEQNO])) {
3211 if (blobmsg_get_bool(cur))
3212 iflags |= GRE_SEQ;
3213 }
3214
3215 if ((cur = tb_data[GRE_DATA_OSEQNO])) {
3216 if (blobmsg_get_bool(cur))
3217 oflags |= GRE_SEQ;
3218 }
3219
3220 if ((cur = tb_data[GRE_DATA_ENCAPLIMIT])) {
3221 char *str = blobmsg_get_string(cur);
3222
3223 if (strcmp(str, "ignore")) {
3224 char *e;
3225
3226 encap_limit = strtoul(str, &e, 0);
3227
3228 if (e == str || *e || encap_limit > 255) {
3229 ret = -EINVAL;
3230 goto failure;
3231 }
3232
3233 flags6 &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
3234 }
3235 }
3236 }
3237
3238 if (v6) {
3239 struct in6_addr in6buf;
3240 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3241 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3242 ret = -EINVAL;
3243 goto failure;
3244 }
3245 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf);
3246 }
3247
3248 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3249 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3250 ret = -EINVAL;
3251 goto failure;
3252 }
3253 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf);
3254 }
3255
3256 if (!(flags6 & IP6_TNL_F_IGN_ENCAP_LIMIT))
3257 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, encap_limit);
3258
3259 if (flowinfo)
3260 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo);
3261
3262 if (flags6)
3263 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags6);
3264
3265 if (!ttl)
3266 ttl = 64;
3267 } else {
3268 struct in_addr inbuf;
3269 bool set_df = true;
3270
3271 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3272 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3273 ret = -EINVAL;
3274 goto failure;
3275 }
3276 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf);
3277 }
3278
3279 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3280 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3281 ret = -EINVAL;
3282 goto failure;
3283 }
3284 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf);
3285
3286 if (IN_MULTICAST(ntohl(inbuf.s_addr))) {
3287 if (!okey) {
3288 okey = inbuf.s_addr;
3289 oflags |= GRE_KEY;
3290 }
3291
3292 if (!ikey) {
3293 ikey = inbuf.s_addr;
3294 iflags |= GRE_KEY;
3295 }
3296 }
3297 }
3298
3299 if ((cur = tb[TUNNEL_ATTR_DF]))
3300 set_df = blobmsg_get_bool(cur);
3301
3302 if (!set_df) {
3303 /* ttl != 0 and nopmtudisc are incompatible */
3304 if (ttl) {
3305 ret = -EINVAL;
3306 goto failure;
3307 }
3308 } else if (!ttl)
3309 ttl = 64;
3310
3311 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0);
3312
3313 nla_put_u8(nlm, IFLA_GRE_TOS, tos);
3314 }
3315
3316 if (ttl)
3317 nla_put_u8(nlm, IFLA_GRE_TTL, ttl);
3318
3319 if (oflags)
3320 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags);
3321
3322 if (iflags)
3323 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags);
3324
3325 if (okey)
3326 nla_put_u32(nlm, IFLA_GRE_OKEY, htonl(okey));
3327
3328 if (ikey)
3329 nla_put_u32(nlm, IFLA_GRE_IKEY, htonl(ikey));
3330
3331 nla_nest_end(nlm, infodata);
3332 nla_nest_end(nlm, linkinfo);
3333
3334 return system_rtnl_call(nlm);
3335
3336 failure:
3337 nlmsg_free(nlm);
3338 return ret;
3339 }
3340 #endif
3341
3342 #ifdef IFLA_VTI_MAX
3343 static int system_add_vti_tunnel(const char *name, const char *kind,
3344 const unsigned int link, struct blob_attr **tb, bool v6)
3345 {
3346 struct nl_msg *nlm;
3347 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
3348 struct blob_attr *cur;
3349 int ret = 0;
3350
3351 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3352 if (!nlm)
3353 return -1;
3354
3355 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3356 nla_put_string(nlm, IFLA_IFNAME, name);
3357
3358 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3359 if (!linkinfo) {
3360 ret = -ENOMEM;
3361 goto failure;
3362 }
3363
3364 nla_put_string(nlm, IFLA_INFO_KIND, kind);
3365 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3366 if (!infodata) {
3367 ret = -ENOMEM;
3368 goto failure;
3369 }
3370
3371 if (link)
3372 nla_put_u32(nlm, IFLA_VTI_LINK, link);
3373
3374 if (v6) {
3375 struct in6_addr in6buf;
3376 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3377 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3378 ret = -EINVAL;
3379 goto failure;
3380 }
3381 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf);
3382 }
3383
3384 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3385 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3386 ret = -EINVAL;
3387 goto failure;
3388 }
3389 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf);
3390 }
3391
3392 } else {
3393 struct in_addr inbuf;
3394
3395 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3396 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3397 ret = -EINVAL;
3398 goto failure;
3399 }
3400 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf);
3401 }
3402
3403 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3404 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3405 ret = -EINVAL;
3406 goto failure;
3407 }
3408 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf);
3409 }
3410
3411 }
3412
3413 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3414 struct blob_attr *tb_data[__VTI_DATA_ATTR_MAX];
3415 uint32_t ikey = 0, okey = 0;
3416
3417 blobmsg_parse(vti_data_attr_list.params, __VTI_DATA_ATTR_MAX, tb_data,
3418 blobmsg_data(cur), blobmsg_len(cur));
3419
3420 if ((cur = tb_data[VTI_DATA_IKEY])) {
3421 if ((ikey = blobmsg_get_u32(cur)))
3422 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey));
3423 }
3424
3425 if ((cur = tb_data[VTI_DATA_OKEY])) {
3426 if ((okey = blobmsg_get_u32(cur)))
3427 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey));
3428 }
3429 }
3430
3431 nla_nest_end(nlm, infodata);
3432 nla_nest_end(nlm, linkinfo);
3433
3434 return system_rtnl_call(nlm);
3435
3436 failure:
3437 nlmsg_free(nlm);
3438 return ret;
3439 }
3440 #endif
3441
3442 #ifdef IFLA_XFRM_MAX
3443 static int system_add_xfrm_tunnel(const char *name, const char *kind,
3444 const unsigned int link, struct blob_attr **tb)
3445 {
3446 struct nl_msg *nlm;
3447 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
3448 struct blob_attr *cur;
3449 int ret = 0;
3450
3451 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3452 if (!nlm)
3453 return -1;
3454
3455 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3456 nla_put_string(nlm, IFLA_IFNAME, name);
3457
3458 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3459 if (!linkinfo) {
3460 ret = -ENOMEM;
3461 goto failure;
3462 }
3463
3464 nla_put_string(nlm, IFLA_INFO_KIND, kind);
3465 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3466 if (!infodata) {
3467 ret = -ENOMEM;
3468 goto failure;
3469 }
3470
3471 if (link)
3472 nla_put_u32(nlm, IFLA_XFRM_LINK, link);
3473
3474 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3475 struct blob_attr *tb_data[__XFRM_DATA_ATTR_MAX];
3476 uint32_t if_id = 0;
3477
3478 blobmsg_parse(xfrm_data_attr_list.params, __XFRM_DATA_ATTR_MAX, tb_data,
3479 blobmsg_data(cur), blobmsg_len(cur));
3480
3481 if ((cur = tb_data[XFRM_DATA_IF_ID])) {
3482 if ((if_id = blobmsg_get_u32(cur)))
3483 nla_put_u32(nlm, IFLA_XFRM_IF_ID, if_id);
3484 }
3485
3486 }
3487
3488 nla_nest_end(nlm, infodata);
3489 nla_nest_end(nlm, linkinfo);
3490
3491 return system_rtnl_call(nlm);
3492
3493 failure:
3494 nlmsg_free(nlm);
3495 return ret;
3496 }
3497 #endif
3498
3499 #ifdef IFLA_VXLAN_MAX
3500 static void system_vxlan_map_bool_attr(struct nl_msg *msg, struct blob_attr **tb_data, int attrtype, int vxlandatatype, bool invert) {
3501 struct blob_attr *cur;
3502 if ((cur = tb_data[vxlandatatype])) {
3503 bool val = blobmsg_get_bool(cur);
3504 if (invert)
3505 val = !val;
3506
3507 if ((attrtype == IFLA_VXLAN_GBP) && val)
3508 nla_put_flag(msg, attrtype);
3509 else
3510 nla_put_u8(msg, attrtype, val);
3511
3512 }
3513 }
3514
3515 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6)
3516 {
3517 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX];
3518 struct nl_msg *msg;
3519 struct nlattr *linkinfo, *data;
3520 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
3521 struct blob_attr *cur;
3522 int ret = 0;
3523
3524 if ((cur = tb[TUNNEL_ATTR_DATA]))
3525 blobmsg_parse(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, tb_data,
3526 blobmsg_data(cur), blobmsg_len(cur));
3527 else
3528 return -EINVAL;
3529
3530 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
3531
3532 if (!msg)
3533 return -1;
3534
3535 nlmsg_append(msg, &iim, sizeof(iim), 0);
3536
3537 nla_put_string(msg, IFLA_IFNAME, name);
3538
3539 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) {
3540 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur));
3541 if (!ea) {
3542 ret = -EINVAL;
3543 goto failure;
3544 }
3545
3546 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea);
3547 }
3548
3549 if ((cur = tb[TUNNEL_ATTR_MTU])) {
3550 uint32_t mtu = blobmsg_get_u32(cur);
3551 nla_put_u32(msg, IFLA_MTU, mtu);
3552 }
3553
3554 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) {
3555 ret = -ENOMEM;
3556 goto failure;
3557 }
3558
3559 nla_put_string(msg, IFLA_INFO_KIND, "vxlan");
3560
3561 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) {
3562 ret = -ENOMEM;
3563 goto failure;
3564 }
3565
3566 if (link)
3567 nla_put_u32(msg, IFLA_VXLAN_LINK, link);
3568
3569 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) {
3570 uint32_t id = blobmsg_get_u32(cur);
3571 if (id >= (1u << 24) - 1) {
3572 ret = -EINVAL;
3573 goto failure;
3574 }
3575
3576 nla_put_u32(msg, IFLA_VXLAN_ID, id);
3577 }
3578
3579 if (v6) {
3580 struct in6_addr in6buf;
3581 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3582 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3583 ret = -EINVAL;
3584 goto failure;
3585 }
3586 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf);
3587 }
3588
3589 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3590 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3591 ret = -EINVAL;
3592 goto failure;
3593 }
3594 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf);
3595 }
3596 } else {
3597 struct in_addr inbuf;
3598
3599 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3600 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3601 ret = -EINVAL;
3602 goto failure;
3603 }
3604 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf);
3605 }
3606
3607 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3608 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3609 ret = -EINVAL;
3610 goto failure;
3611 }
3612 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf);
3613 }
3614 }
3615
3616 uint32_t port = 4789;
3617 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) {
3618 port = blobmsg_get_u32(cur);
3619 if (port < 1 || port > 65535) {
3620 ret = -EINVAL;
3621 goto failure;
3622 }
3623 }
3624 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port));
3625
3626 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMIN])) {
3627 struct ifla_vxlan_port_range srcports = {0,0};
3628
3629 uint32_t low = blobmsg_get_u32(cur);
3630 if (low < 1 || low > 65535 - 1) {
3631 ret = -EINVAL;
3632 goto failure;
3633 }
3634
3635 srcports.low = htons((uint16_t) low);
3636 srcports.high = htons((uint16_t) (low+1));
3637
3638 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMAX])) {
3639 uint32_t high = blobmsg_get_u32(cur);
3640 if (high < 1 || high > 65535) {
3641 ret = -EINVAL;
3642 goto failure;
3643 }
3644
3645 if (high > low)
3646 srcports.high = htons((uint16_t) high);
3647 }
3648
3649 nla_put(msg, IFLA_VXLAN_PORT_RANGE, sizeof(srcports), &srcports);
3650 }
3651
3652 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_CSUM, VXLAN_DATA_ATTR_TXCSUM, false);
3653 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, VXLAN_DATA_ATTR_RXCSUM, true);
3654 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, VXLAN_DATA_ATTR_TXCSUM, true);
3655 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_LEARNING, VXLAN_DATA_ATTR_LEARNING, false);
3656 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_RSC , VXLAN_DATA_ATTR_RSC, false);
3657 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_PROXY , VXLAN_DATA_ATTR_PROXY, false);
3658 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L2MISS , VXLAN_DATA_ATTR_L2MISS, false);
3659 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L3MISS , VXLAN_DATA_ATTR_L3MISS, false);
3660 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_GBP , VXLAN_DATA_ATTR_GBP, false);
3661
3662 if ((cur = tb_data[VXLAN_DATA_ATTR_AGEING])) {
3663 uint32_t ageing = blobmsg_get_u32(cur);
3664 nla_put_u32(msg, IFLA_VXLAN_AGEING, ageing);
3665 }
3666
3667 if ((cur = tb_data[VXLAN_DATA_ATTR_LIMIT])) {
3668 uint32_t maxaddress = blobmsg_get_u32(cur);
3669 nla_put_u32(msg, IFLA_VXLAN_LIMIT, maxaddress);
3670 }
3671
3672 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3673 char *str = blobmsg_get_string(cur);
3674 unsigned tos = 1;
3675
3676 if (strcmp(str, "inherit")) {
3677 if (!system_tos_aton(str, &tos)) {
3678 ret = -EINVAL;
3679 goto failure;
3680 }
3681 }
3682
3683 nla_put_u8(msg, IFLA_VXLAN_TOS, tos);
3684 }
3685
3686 if ((cur = tb[TUNNEL_ATTR_TTL])) {
3687 uint32_t ttl = blobmsg_get_u32(cur);
3688 if (ttl < 1 || ttl > 255) {
3689 ret = -EINVAL;
3690 goto failure;
3691 }
3692
3693 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl);
3694 }
3695
3696 nla_nest_end(msg, data);
3697 nla_nest_end(msg, linkinfo);
3698
3699 ret = system_rtnl_call(msg);
3700 if (ret)
3701 D(SYSTEM, "Error adding vxlan '%s': %d\n", name, ret);
3702
3703 return ret;
3704
3705 failure:
3706 nlmsg_free(msg);
3707 return ret;
3708 }
3709 #endif
3710
3711 static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb)
3712 {
3713 struct blob_attr *cur;
3714 int ret = 0;
3715
3716 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
3717 return -1;
3718
3719 #ifdef SIOCADD6RD
3720 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3721 struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX];
3722 unsigned int mask;
3723 struct ip_tunnel_6rd p6;
3724
3725 blobmsg_parse(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, tb_data,
3726 blobmsg_data(cur), blobmsg_len(cur));
3727
3728 memset(&p6, 0, sizeof(p6));
3729
3730 if ((cur = tb_data[SIXRD_DATA_PREFIX])) {
3731 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
3732 &p6.prefix, &mask) || mask > 128) {
3733 ret = -EINVAL;
3734 goto failure;
3735 }
3736
3737 p6.prefixlen = mask;
3738 }
3739
3740 if ((cur = tb_data[SIXRD_DATA_RELAY_PREFIX])) {
3741 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
3742 &p6.relay_prefix, &mask) || mask > 32) {
3743 ret = -EINVAL;
3744 goto failure;
3745 }
3746
3747 p6.relay_prefixlen = mask;
3748 }
3749
3750 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
3751 ret = -1;
3752 goto failure;
3753 }
3754 }
3755 #endif
3756
3757 return ret;
3758
3759 failure:
3760 system_link_del(name);
3761 return ret;
3762 }
3763
3764 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
3765 {
3766 struct blob_attr *cur;
3767 bool set_df = true;
3768 struct ip_tunnel_parm p = {
3769 .link = link,
3770 .iph = {
3771 .version = 4,
3772 .ihl = 5,
3773 .protocol = proto,
3774 }
3775 };
3776
3777 if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
3778 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
3779 return -EINVAL;
3780
3781 if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
3782 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
3783 return -EINVAL;
3784
3785 if ((cur = tb[TUNNEL_ATTR_DF]))
3786 set_df = blobmsg_get_bool(cur);
3787
3788 if ((cur = tb[TUNNEL_ATTR_TTL]))
3789 p.iph.ttl = blobmsg_get_u32(cur);
3790
3791 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3792 char *str = blobmsg_get_string(cur);
3793 if (strcmp(str, "inherit")) {
3794 unsigned uval;
3795
3796 if (!system_tos_aton(str, &uval))
3797 return -EINVAL;
3798
3799 p.iph.tos = uval;
3800 } else
3801 p.iph.tos = 1;
3802 }
3803
3804 p.iph.frag_off = set_df ? htons(IP_DF) : 0;
3805 /* ttl !=0 and nopmtudisc are incompatible */
3806 if (p.iph.ttl && p.iph.frag_off == 0)
3807 return -EINVAL;
3808
3809 strncpy(p.name, name, sizeof(p.name) - 1);
3810
3811 switch (p.iph.protocol) {
3812 case IPPROTO_IPIP:
3813 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
3814 case IPPROTO_IPV6:
3815 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p);
3816 default:
3817 break;
3818 }
3819 return -1;
3820 }
3821
3822 int system_del_ip_tunnel(const struct device *dev)
3823 {
3824 return system_link_del(dev->ifname);
3825 }
3826
3827 int system_update_ipv6_mtu(struct device *dev, int mtu)
3828 {
3829 int ret = -1;
3830 char buf[64];
3831 int fd;
3832
3833 fd = open(dev_sysctl_path("ipv6/conf", dev->ifname, "mtu"), O_RDWR);
3834 if (fd < 0)
3835 return ret;
3836
3837 if (!mtu) {
3838 ssize_t len = read(fd, buf, sizeof(buf) - 1);
3839 if (len < 0)
3840 goto out;
3841
3842 buf[len] = 0;
3843 ret = atoi(buf);
3844 } else {
3845 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0)
3846 ret = mtu;
3847 }
3848
3849 out:
3850 close(fd);
3851 return ret;
3852 }
3853
3854 int system_add_ip_tunnel(const struct device *dev, struct blob_attr *attr)
3855 {
3856 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
3857 struct blob_attr *cur;
3858 const char *str;
3859
3860 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
3861 blob_data(attr), blob_len(attr));
3862
3863 system_link_del(dev->ifname);
3864
3865 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
3866 return -EINVAL;
3867 str = blobmsg_data(cur);
3868
3869 unsigned int ttl = 0;
3870 if ((cur = tb[TUNNEL_ATTR_TTL])) {
3871 ttl = blobmsg_get_u32(cur);
3872 if (ttl > 255)
3873 return -EINVAL;
3874 }
3875
3876 unsigned int link = 0;
3877 if ((cur = tb[TUNNEL_ATTR_LINK])) {
3878 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
3879 if (!iface)
3880 return -EINVAL;
3881
3882 if (iface->l3_dev.dev)
3883 link = iface->l3_dev.dev->ifindex;
3884 }
3885
3886 if (!strcmp(str, "sit"))
3887 return system_add_sit_tunnel(dev->ifname, link, tb);
3888 #ifdef IFLA_IPTUN_MAX
3889 else if (!strcmp(str, "ipip6")) {
3890 return system_add_ip6_tunnel(dev->ifname, link, tb);
3891 } else if (!strcmp(str, "greip")) {
3892 return system_add_gre_tunnel(dev->ifname, "gre", link, tb, false);
3893 } else if (!strcmp(str, "gretapip")) {
3894 return system_add_gre_tunnel(dev->ifname, "gretap", link, tb, false);
3895 } else if (!strcmp(str, "greip6")) {
3896 return system_add_gre_tunnel(dev->ifname, "ip6gre", link, tb, true);
3897 } else if (!strcmp(str, "gretapip6")) {
3898 return system_add_gre_tunnel(dev->ifname, "ip6gretap", link, tb, true);
3899 #ifdef IFLA_VTI_MAX
3900 } else if (!strcmp(str, "vtiip")) {
3901 return system_add_vti_tunnel(dev->ifname, "vti", link, tb, false);
3902 } else if (!strcmp(str, "vtiip6")) {
3903 return system_add_vti_tunnel(dev->ifname, "vti6", link, tb, true);
3904 #endif
3905 #ifdef IFLA_XFRM_MAX
3906 } else if (!strcmp(str, "xfrm")) {
3907 return system_add_xfrm_tunnel(dev->ifname, "xfrm", link, tb);
3908 #endif
3909 #ifdef IFLA_VXLAN_MAX
3910 } else if(!strcmp(str, "vxlan")) {
3911 return system_add_vxlan(dev->ifname, link, tb, false);
3912 } else if(!strcmp(str, "vxlan6")) {
3913 return system_add_vxlan(dev->ifname, link, tb, true);
3914 #endif
3915 #endif
3916 } else if (!strcmp(str, "ipip")) {
3917 return system_add_proto_tunnel(dev->ifname, IPPROTO_IPIP, link, tb);
3918 }
3919 else
3920 return -EINVAL;
3921
3922 return 0;
3923 }