wireless: improve reliability of proxyarp support
[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 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb);
93
94 static char dev_buf[256];
95 static const char *proc_path = "/proc";
96 static const char *sysfs_path = "/sys";
97
98 static void
99 handler_nl_event(struct uloop_fd *u, unsigned int events)
100 {
101 struct event_socket *ev = container_of(u, struct event_socket, uloop);
102 int err;
103 socklen_t errlen = sizeof(err);
104
105 if (!u->error) {
106 nl_recvmsgs_default(ev->sock);
107 return;
108 }
109
110 if (getsockopt(u->fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen))
111 goto abort;
112
113 switch(err) {
114 case ENOBUFS:
115 /* Increase rx buffer size on netlink socket */
116 ev->bufsize *= 2;
117 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
118 goto abort;
119
120 /* Request full dump since some info got dropped */
121 struct rtgenmsg msg = { .rtgen_family = AF_UNSPEC };
122 nl_send_simple(ev->sock, RTM_GETLINK, NLM_F_DUMP, &msg, sizeof(msg));
123 break;
124
125 default:
126 goto abort;
127 }
128 u->error = false;
129 return;
130
131 abort:
132 uloop_fd_delete(&ev->uloop);
133 return;
134 }
135
136 static struct nl_sock *
137 create_socket(int protocol, int groups)
138 {
139 struct nl_sock *sock;
140
141 sock = nl_socket_alloc();
142 if (!sock)
143 return NULL;
144
145 if (groups)
146 nl_join_groups(sock, groups);
147
148 if (nl_connect(sock, protocol)) {
149 nl_socket_free(sock);
150 return NULL;
151 }
152
153 return sock;
154 }
155
156 static bool
157 create_raw_event_socket(struct event_socket *ev, int protocol, int groups,
158 uloop_fd_handler cb, int flags)
159 {
160 ev->sock = create_socket(protocol, groups);
161 if (!ev->sock)
162 return false;
163
164 ev->uloop.fd = nl_socket_get_fd(ev->sock);
165 ev->uloop.cb = cb;
166 if (uloop_fd_add(&ev->uloop, ULOOP_READ|flags))
167 return false;
168
169 return true;
170 }
171
172 static bool
173 create_event_socket(struct event_socket *ev, int protocol,
174 int (*cb)(struct nl_msg *msg, void *arg))
175 {
176 if (!create_raw_event_socket(ev, protocol, 0, handler_nl_event, ULOOP_ERROR_CB))
177 return false;
178
179 /* Install the valid custom callback handler */
180 nl_socket_modify_cb(ev->sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL);
181
182 /* Disable sequence number checking on event sockets */
183 nl_socket_disable_seq_check(ev->sock);
184
185 /* Increase rx buffer size to 65K on event sockets */
186 ev->bufsize = 65535;
187 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
188 return false;
189
190 return true;
191 }
192
193 static bool
194 create_hotplug_event_socket(struct event_socket *ev, int protocol,
195 void (*cb)(struct uloop_fd *u, unsigned int events))
196 {
197 if (!create_raw_event_socket(ev, protocol, 1, cb, ULOOP_ERROR_CB))
198 return false;
199
200 /* Increase rx buffer size to 65K on event sockets */
201 ev->bufsize = 65535;
202 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
203 return false;
204
205 return true;
206 }
207
208 static bool
209 system_rtn_aton(const char *src, unsigned int *dst)
210 {
211 char *e;
212 unsigned int n;
213
214 if (!strcmp(src, "local"))
215 n = RTN_LOCAL;
216 else if (!strcmp(src, "nat"))
217 n = RTN_NAT;
218 else if (!strcmp(src, "broadcast"))
219 n = RTN_BROADCAST;
220 else if (!strcmp(src, "anycast"))
221 n = RTN_ANYCAST;
222 else if (!strcmp(src, "multicast"))
223 n = RTN_MULTICAST;
224 else if (!strcmp(src, "prohibit"))
225 n = RTN_PROHIBIT;
226 else if (!strcmp(src, "unreachable"))
227 n = RTN_UNREACHABLE;
228 else if (!strcmp(src, "blackhole"))
229 n = RTN_BLACKHOLE;
230 else if (!strcmp(src, "xresolve"))
231 n = RTN_XRESOLVE;
232 else if (!strcmp(src, "unicast"))
233 n = RTN_UNICAST;
234 else if (!strcmp(src, "throw"))
235 n = RTN_THROW;
236 else if (!strcmp(src, "failed_policy"))
237 n = RTN_FAILED_POLICY;
238 else {
239 n = strtoul(src, &e, 0);
240 if (!e || *e || e == src || n > 255)
241 return false;
242 }
243
244 *dst = n;
245 return true;
246 }
247
248 static bool
249 system_tos_aton(const char *src, unsigned *dst)
250 {
251 char *e;
252
253 *dst = strtoul(src, &e, 16);
254 if (e == src || *e || *dst > 255)
255 return false;
256
257 return true;
258 }
259
260 int system_init(void)
261 {
262 static struct event_socket rtnl_event;
263 static struct event_socket hotplug_event;
264
265 sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0);
266 system_fd_set_cloexec(sock_ioctl);
267
268 /* Prepare socket for routing / address control */
269 sock_rtnl = create_socket(NETLINK_ROUTE, 0);
270 if (!sock_rtnl)
271 return -1;
272
273 if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event))
274 return -1;
275
276 if (!create_hotplug_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT,
277 handle_hotplug_event))
278 return -1;
279
280 /* Receive network link events form kernel */
281 nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK);
282
283 return 0;
284 }
285
286 static void write_file(const char *path, const char *val)
287 {
288 int fd;
289
290 fd = open(path, O_WRONLY);
291 if (fd < 0)
292 return;
293
294 if (write(fd, val, strlen(val))) {}
295 close(fd);
296 }
297
298 static int read_file(const char *path, char *buf, const size_t buf_sz)
299 {
300 int fd = -1, ret = -1;
301
302 fd = open(path, O_RDONLY);
303 if (fd < 0)
304 goto out;
305
306 ssize_t len = read(fd, buf, buf_sz - 1);
307 if (len < 0)
308 goto out;
309
310 ret = buf[len] = 0;
311
312 out:
313 if (fd >= 0)
314 close(fd);
315
316 return ret;
317 }
318
319
320 static const char *
321 dev_sysctl_path(const char *prefix, const char *ifname, const char *file)
322 {
323 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/%s/%s", proc_path, prefix, ifname, file);
324
325 return dev_buf;
326 }
327
328 static const char *
329 dev_sysfs_path(const char *ifname, const char *file)
330 {
331 snprintf(dev_buf, sizeof(dev_buf), "%s/class/net/%s/%s", sysfs_path, ifname, file);
332
333 return dev_buf;
334 }
335
336 static void
337 system_set_dev_sysctl(const char *prefix, const char *file, const char *ifname,
338 const char *val)
339 {
340 write_file(dev_sysctl_path(prefix, ifname, file), val);
341 }
342
343 static int
344 system_get_dev_sysctl(const char *prefix, const char *file, const char *ifname,
345 char *buf, size_t buf_sz)
346 {
347 return read_file(dev_sysctl_path(prefix, ifname, file), buf, buf_sz);
348 }
349
350 static void
351 system_set_dev_sysfs(const char *file, const char *ifname, const char *val)
352 {
353 write_file(dev_sysfs_path(ifname, file), val);
354 }
355
356 static int
357 system_get_dev_sysfs(const char *file, const char *ifname, char *buf, size_t buf_sz)
358 {
359 return read_file(dev_sysfs_path(ifname, file), buf, buf_sz);
360 }
361
362 static void system_set_disable_ipv6(struct device *dev, const char *val)
363 {
364 system_set_dev_sysctl("ipv6/conf", "disable_ipv6", dev->ifname, val);
365 }
366
367 static void system_set_ip6segmentrouting(struct device *dev, const char *val)
368 {
369 system_set_dev_sysctl("ipv6/conf", "seg6_enabled", dev->ifname, val);
370 }
371
372 static void system_set_rpfilter(struct device *dev, const char *val)
373 {
374 system_set_dev_sysctl("ipv4/conf", "rp_filter", dev->ifname, val);
375 }
376
377 static void system_set_acceptlocal(struct device *dev, const char *val)
378 {
379 system_set_dev_sysctl("ipv4/conf", "accept_local", dev->ifname, val);
380 }
381
382 static void system_set_igmpversion(struct device *dev, const char *val)
383 {
384 system_set_dev_sysctl("ipv4/conf", "force_igmp_version", dev->ifname, val);
385 }
386
387 static void system_set_mldversion(struct device *dev, const char *val)
388 {
389 system_set_dev_sysctl("ipv6/conf", "force_mld_version", dev->ifname, val);
390 }
391
392 static void system_set_neigh4reachabletime(struct device *dev, const char *val)
393 {
394 system_set_dev_sysctl("ipv4/neigh", "base_reachable_time_ms", dev->ifname, val);
395 }
396
397 static void system_set_neigh6reachabletime(struct device *dev, const char *val)
398 {
399 system_set_dev_sysctl("ipv6/neigh", "base_reachable_time_ms", dev->ifname, val);
400 }
401
402 static void system_set_neigh4gcstaletime(struct device *dev, const char *val)
403 {
404 system_set_dev_sysctl("ipv4/neigh", "gc_stale_time", dev->ifname, val);
405 }
406
407 static void system_set_neigh6gcstaletime(struct device *dev, const char *val)
408 {
409 system_set_dev_sysctl("ipv6/neigh", "gc_stale_time", dev->ifname, val);
410 }
411
412 static void system_set_neigh4locktime(struct device *dev, const char *val)
413 {
414 system_set_dev_sysctl("ipv4/neigh", "locktime", dev->ifname, val);
415 }
416
417 static void system_set_dadtransmits(struct device *dev, const char *val)
418 {
419 system_set_dev_sysctl("ipv6/conf", "dad_transmits", dev->ifname, val);
420 }
421
422 static void system_set_sendredirects(struct device *dev, const char *val)
423 {
424 system_set_dev_sysctl("ipv4/conf", "send_redirects", dev->ifname, val);
425 }
426
427 static void system_set_drop_v4_unicast_in_l2_multicast(struct device *dev, const char *val)
428 {
429 system_set_dev_sysctl("ipv4/conf", "drop_unicast_in_l2_multicast", dev->ifname, val);
430 }
431
432 static void system_set_drop_v6_unicast_in_l2_multicast(struct device *dev, const char *val)
433 {
434 system_set_dev_sysctl("ipv6/conf", "drop_unicast_in_l2_multicast", dev->ifname, val);
435 }
436
437 static void system_set_drop_gratuitous_arp(struct device *dev, const char *val)
438 {
439 system_set_dev_sysctl("ipv4/conf", "drop_gratuitous_arp", dev->ifname, val);
440 }
441
442 static void system_set_drop_unsolicited_na(struct device *dev, const char *val)
443 {
444 system_set_dev_sysctl("ipv6/conf", "drop_unsolicited_na", dev->ifname, val);
445 }
446
447 static void system_set_arp_accept(struct device *dev, const char *val)
448 {
449 system_set_dev_sysctl("ipv4/conf", "arp_accept", dev->ifname, val);
450 }
451
452 static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val)
453 {
454 system_set_dev_sysfs("brport/multicast_to_unicast", dev->ifname, val);
455 }
456
457 static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val)
458 {
459 system_set_dev_sysfs("brport/multicast_fast_leave", dev->ifname, val);
460 }
461
462 static void system_bridge_set_hairpin_mode(struct device *dev, const char *val)
463 {
464 system_set_dev_sysfs("brport/hairpin_mode", dev->ifname, val);
465 }
466
467 static void system_bridge_set_proxyarp_wifi(struct device *dev, const char *val)
468 {
469 system_set_dev_sysfs("brport/proxyarp_wifi", dev->ifname, val);
470 }
471
472 static void system_bridge_set_bpdu_filter(struct device *dev, const char *val)
473 {
474 system_set_dev_sysfs("brport/bpdu_filter", dev->ifname, val);
475 }
476
477 static void system_bridge_set_isolated(struct device *dev, const char *val)
478 {
479 system_set_dev_sysfs("brport/isolated", dev->ifname, val);
480 }
481
482 static void system_bridge_set_multicast_router(struct device *dev, const char *val, bool bridge)
483 {
484 system_set_dev_sysfs(bridge ? "bridge/multicast_router" :
485 "brport/multicast_router",
486 dev->ifname, val);
487 }
488
489 static void system_bridge_set_robustness(struct device *dev, const char *val)
490 {
491 system_set_dev_sysfs("bridge/multicast_startup_query_count",
492 dev->ifname, val);
493 system_set_dev_sysfs("bridge/multicast_last_member_count",
494 dev->ifname, val);
495 }
496
497 static void system_bridge_set_query_interval(struct device *dev, const char *val)
498 {
499 system_set_dev_sysfs("bridge/multicast_query_interval",
500 dev->ifname, val);
501 }
502
503 static void system_bridge_set_query_response_interval(struct device *dev, const char *val)
504 {
505 system_set_dev_sysfs("bridge/multicast_query_response_interval",
506 dev->ifname, val);
507 }
508
509 static void system_bridge_set_last_member_interval(struct device *dev, const char *val)
510 {
511 system_set_dev_sysfs("bridge/multicast_last_member_interval",
512 dev->ifname, val);
513 }
514
515 static void system_bridge_set_membership_interval(struct device *dev, const char *val)
516 {
517 system_set_dev_sysfs("bridge/multicast_membership_interval",
518 dev->ifname, val);
519 }
520
521 static void system_bridge_set_other_querier_timeout(struct device *dev, const char *val)
522 {
523 system_set_dev_sysfs("bridge/multicast_querier_interval",
524 dev->ifname, val);
525 }
526
527 static void system_bridge_set_startup_query_interval(struct device *dev, const char *val)
528 {
529 system_set_dev_sysfs("bridge/multicast_startup_query_interval",
530 dev->ifname, val);
531 }
532
533 void system_bridge_set_stp_state(struct device *dev, bool val)
534 {
535 const char *valstr = val ? "1" : "0";
536
537 system_set_dev_sysfs("bridge/stp_state", dev->ifname, valstr);
538 }
539
540 static void system_bridge_set_forward_delay(struct device *dev, const char *val)
541 {
542 system_set_dev_sysfs("bridge/forward_delay", dev->ifname, val);
543 }
544
545 static void system_bridge_set_priority(struct device *dev, const char *val)
546 {
547 system_set_dev_sysfs("bridge/priority", dev->ifname, val);
548 }
549
550 static void system_bridge_set_ageing_time(struct device *dev, const char *val)
551 {
552 system_set_dev_sysfs("bridge/ageing_time", dev->ifname, val);
553 }
554
555 static void system_bridge_set_hello_time(struct device *dev, const char *val)
556 {
557 system_set_dev_sysfs("bridge/hello_time", dev->ifname, val);
558 }
559
560 static void system_bridge_set_max_age(struct device *dev, const char *val)
561 {
562 system_set_dev_sysfs("bridge/max_age", dev->ifname, val);
563 }
564
565 static void system_bridge_set_learning(struct device *dev, const char *val)
566 {
567 system_set_dev_sysfs("brport/learning", dev->ifname, val);
568 }
569
570 static void system_bridge_set_unicast_flood(struct device *dev, const char *val)
571 {
572 system_set_dev_sysfs("brport/unicast_flood", dev->ifname, val);
573 }
574
575 static void system_bridge_set_vlan_filtering(struct device *dev, const char *val)
576 {
577 system_set_dev_sysfs("bridge/vlan_filtering", dev->ifname, val);
578 }
579
580 static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz)
581 {
582 return system_get_dev_sysctl("ipv6/conf", "disable_ipv6",
583 dev->ifname, buf, buf_sz);
584 }
585
586 static int system_get_ip6segmentrouting(struct device *dev, char *buf, const size_t buf_sz)
587 {
588 return system_get_dev_sysctl("ipv6/conf", "seg6_enabled",
589 dev->ifname, buf, buf_sz);
590 }
591
592 static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz)
593 {
594 return system_get_dev_sysctl("ipv4/conf", "rp_filter",
595 dev->ifname, buf, buf_sz);
596 }
597
598 static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz)
599 {
600 return system_get_dev_sysctl("ipv4/conf", "accept_local",
601 dev->ifname, buf, buf_sz);
602 }
603
604 static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz)
605 {
606 return system_get_dev_sysctl("ipv4/conf", "force_igmp_version",
607 dev->ifname, buf, buf_sz);
608 }
609
610 static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz)
611 {
612 return system_get_dev_sysctl("ipv6/conf", "force_mld_version",
613 dev->ifname, buf, buf_sz);
614 }
615
616 static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz)
617 {
618 return system_get_dev_sysctl("ipv4/neigh", "base_reachable_time_ms",
619 dev->ifname, buf, buf_sz);
620 }
621
622 static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz)
623 {
624 return system_get_dev_sysctl("ipv6/neigh", "base_reachable_time_ms",
625 dev->ifname, buf, buf_sz);
626 }
627
628 static int system_get_neigh4gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
629 {
630 return system_get_dev_sysctl("ipv4/neigh", "gc_stale_time",
631 dev->ifname, buf, buf_sz);
632 }
633
634 static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
635 {
636 return system_get_dev_sysctl("ipv6/neigh", "gc_stale_time",
637 dev->ifname, buf, buf_sz);
638 }
639
640 static int system_get_neigh4locktime(struct device *dev, char *buf, const size_t buf_sz)
641 {
642 return system_get_dev_sysctl("ipv4/neigh", "locktime",
643 dev->ifname, buf, buf_sz);
644 }
645
646 static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz)
647 {
648 return system_get_dev_sysctl("ipv6/conf", "dad_transmits",
649 dev->ifname, buf, buf_sz);
650 }
651
652 static int system_get_sendredirects(struct device *dev, char *buf, const size_t buf_sz)
653 {
654 return system_get_dev_sysctl("ipv4/conf", "send_redirects",
655 dev->ifname, buf, buf_sz);
656 }
657
658
659 static int system_get_drop_v4_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz)
660 {
661 return system_get_dev_sysctl("ipv4/conf", "drop_unicast_in_l2_multicast",
662 dev->ifname, buf, buf_sz);
663 }
664
665 static int system_get_drop_v6_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz)
666 {
667 return system_get_dev_sysctl("ipv6/conf", "drop_unicast_in_l2_multicast",
668 dev->ifname, buf, buf_sz);
669 }
670
671 static int system_get_drop_gratuitous_arp(struct device *dev, char *buf, const size_t buf_sz)
672 {
673 return system_get_dev_sysctl("ipv4/conf", "drop_gratuitous_arp",
674 dev->ifname, buf, buf_sz);
675 }
676
677 static int system_get_drop_unsolicited_na(struct device *dev, char *buf, const size_t buf_sz)
678 {
679 return system_get_dev_sysctl("ipv6/conf", "drop_unsolicited_na",
680 dev->ifname, buf, buf_sz);
681 }
682
683 static int system_get_arp_accept(struct device *dev, char *buf, const size_t buf_sz)
684 {
685 return system_get_dev_sysctl("ipv4/conf", "arp_accept",
686 dev->ifname, buf, buf_sz);
687 }
688
689 /* Evaluate netlink messages */
690 static int cb_rtnl_event(struct nl_msg *msg, void *arg)
691 {
692 struct nlmsghdr *nh = nlmsg_hdr(msg);
693 struct nlattr *nla[__IFLA_MAX];
694 int link_state = 0;
695 char buf[10];
696
697 if (nh->nlmsg_type != RTM_NEWLINK)
698 goto out;
699
700 nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL);
701 if (!nla[IFLA_IFNAME])
702 goto out;
703
704 struct device *dev = device_find(nla_data(nla[IFLA_IFNAME]));
705 if (!dev)
706 goto out;
707
708 if (!system_get_dev_sysfs("carrier", dev->ifname, buf, sizeof(buf)))
709 link_state = strtoul(buf, NULL, 0);
710
711 if (dev->type == &simple_device_type)
712 device_set_present(dev, true);
713
714 device_set_link(dev, link_state ? true : false);
715
716 out:
717 return 0;
718 }
719
720 static void
721 handle_hotplug_msg(char *data, int size)
722 {
723 const char *subsystem = NULL, *interface = NULL, *interface_old = NULL;
724 char *cur, *end, *sep;
725 int skip;
726 bool add;
727
728 if (!strncmp(data, "add@", 4) || !strncmp(data, "move@", 5))
729 add = true;
730 else if (!strncmp(data, "remove@", 7))
731 add = false;
732 else
733 return;
734
735 skip = strlen(data) + 1;
736 end = data + size;
737
738 for (cur = data + skip; cur < end; cur += skip) {
739 skip = strlen(cur) + 1;
740
741 sep = strchr(cur, '=');
742 if (!sep)
743 continue;
744
745 *sep = 0;
746 if (!strcmp(cur, "INTERFACE"))
747 interface = sep + 1;
748 else if (!strcmp(cur, "SUBSYSTEM")) {
749 subsystem = sep + 1;
750 if (strcmp(subsystem, "net") != 0)
751 return;
752 } else if (!strcmp(cur, "DEVPATH_OLD")) {
753 interface_old = strrchr(sep + 1, '/');
754 if (interface_old)
755 interface_old++;
756 }
757 }
758
759 if (!subsystem || !interface)
760 return;
761
762 if (interface_old)
763 device_hotplug_event(interface_old, false);
764
765 device_hotplug_event(interface, add);
766 }
767
768 static void
769 handle_hotplug_event(struct uloop_fd *u, unsigned int events)
770 {
771 struct event_socket *ev = container_of(u, struct event_socket, uloop);
772 struct sockaddr_nl nla;
773 unsigned char *buf = NULL;
774 int size;
775 int err;
776 socklen_t errlen = sizeof(err);
777
778 if (!u->error) {
779 while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) {
780 if (nla.nl_pid == 0)
781 handle_hotplug_msg((char *) buf, size);
782
783 free(buf);
784 }
785 return;
786 }
787
788 if (getsockopt(u->fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen))
789 goto abort;
790
791 switch(err) {
792 case ENOBUFS:
793 /* Increase rx buffer size on netlink socket */
794 ev->bufsize *= 2;
795 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0))
796 goto abort;
797 break;
798
799 default:
800 goto abort;
801 }
802 u->error = false;
803 return;
804
805 abort:
806 uloop_fd_delete(&ev->uloop);
807 return;
808 }
809
810 static int system_rtnl_call(struct nl_msg *msg)
811 {
812 int ret;
813
814 ret = nl_send_auto_complete(sock_rtnl, msg);
815 nlmsg_free(msg);
816
817 if (ret < 0)
818 return ret;
819
820 return nl_wait_for_ack(sock_rtnl);
821 }
822
823 int system_bridge_delbr(struct device *bridge)
824 {
825 return ioctl(sock_ioctl, SIOCBRDELBR, bridge->ifname);
826 }
827
828 static int system_bridge_if(const char *bridge, struct device *dev, int cmd, void *data)
829 {
830 struct ifreq ifr;
831
832 memset(&ifr, 0, sizeof(ifr));
833 if (dev)
834 ifr.ifr_ifindex = dev->ifindex;
835 else
836 ifr.ifr_data = data;
837 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
838 return ioctl(sock_ioctl, cmd, &ifr);
839 }
840
841 static bool system_is_bridge(const char *name)
842 {
843 struct stat st;
844
845 return stat(dev_sysfs_path(name, "bridge"), &st) >= 0;
846 }
847
848 static char *system_get_bridge(const char *name, char *buf, int buflen)
849 {
850 char *path;
851 ssize_t len = -1;
852 glob_t gl;
853
854 snprintf(buf, buflen, "%s/devices/virtual/net/*/brif/%s/bridge", sysfs_path, name);
855 if (glob(buf, GLOB_NOSORT, NULL, &gl) < 0)
856 return NULL;
857
858 if (gl.gl_pathc > 0)
859 len = readlink(gl.gl_pathv[0], buf, buflen);
860
861 globfree(&gl);
862
863 if (len < 0)
864 return NULL;
865
866 buf[len] = 0;
867 path = strrchr(buf, '/');
868 if (!path)
869 return NULL;
870
871 return path + 1;
872 }
873
874 static void
875 system_bridge_set_wireless(struct device *bridge, struct device *dev)
876 {
877 bool mcast_to_ucast = dev->wireless_ap;
878 bool hairpin;
879
880 if (bridge->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST &&
881 !bridge->settings.multicast_to_unicast)
882 mcast_to_ucast = false;
883
884 hairpin = mcast_to_ucast || dev->wireless_proxyarp;
885 if (dev->wireless_isolate)
886 hairpin = false;
887
888 system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : "0");
889 system_bridge_set_hairpin_mode(dev, hairpin ? "1" : "0");
890 system_bridge_set_proxyarp_wifi(dev, dev->wireless_proxyarp ? "1" : "0");
891 }
892
893 int system_bridge_addif(struct device *bridge, struct device *dev)
894 {
895 char buf[64];
896 char *oldbr;
897 int tries = 0;
898 int ret;
899
900 retry:
901 ret = 0;
902 oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
903 if (!oldbr || strcmp(oldbr, bridge->ifname) != 0) {
904 ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
905 tries++;
906 D(SYSTEM, "Failed to add device '%s' to bridge '%s' (tries=%d): %s\n",
907 dev->ifname, bridge->ifname, tries, strerror(errno));
908 if (tries <= 3)
909 goto retry;
910 }
911
912 if (dev->wireless)
913 system_bridge_set_wireless(bridge, dev);
914
915 if (dev->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
916 snprintf(buf, sizeof(buf), "%u", dev->settings.multicast_router);
917 system_bridge_set_multicast_router(dev, buf, false);
918 }
919
920 if (dev->settings.flags & DEV_OPT_MULTICAST_FAST_LEAVE &&
921 dev->settings.multicast_fast_leave)
922 system_bridge_set_multicast_fast_leave(dev, "1");
923
924 if (dev->settings.flags & DEV_OPT_LEARNING &&
925 !dev->settings.learning)
926 system_bridge_set_learning(dev, "0");
927
928 if (dev->settings.flags & DEV_OPT_UNICAST_FLOOD &&
929 !dev->settings.unicast_flood)
930 system_bridge_set_unicast_flood(dev, "0");
931
932 if (dev->settings.flags & DEV_OPT_ISOLATE &&
933 dev->settings.isolate)
934 system_bridge_set_isolated(dev, "1");
935
936 if (dev->bpdu_filter)
937 system_bridge_set_bpdu_filter(dev, dev->bpdu_filter ? "1" : "0");
938
939 return ret;
940 }
941
942 int system_bridge_delif(struct device *bridge, struct device *dev)
943 {
944 return system_bridge_if(bridge->ifname, dev, SIOCBRDELIF, NULL);
945 }
946
947 int system_bridge_vlan(const char *iface, uint16_t vid, bool add, unsigned int vflags)
948 {
949 struct ifinfomsg ifi = { .ifi_family = PF_BRIDGE, };
950 struct bridge_vlan_info vinfo = { .vid = vid, };
951 unsigned short flags = 0;
952 struct nlattr *afspec;
953 struct nl_msg *nlm;
954 int ret = 0;
955
956 ifi.ifi_index = if_nametoindex(iface);
957 if (!ifi.ifi_index)
958 return -1;
959
960 nlm = nlmsg_alloc_simple(add ? RTM_SETLINK : RTM_DELLINK, NLM_F_REQUEST);
961 if (!nlm)
962 return -1;
963
964 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
965
966 if (vflags & BRVLAN_F_SELF)
967 flags |= BRIDGE_FLAGS_SELF;
968
969 if (vflags & BRVLAN_F_PVID)
970 vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
971
972 if (vflags & BRVLAN_F_UNTAGGED)
973 vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
974
975 afspec = nla_nest_start(nlm, IFLA_AF_SPEC);
976 if (!afspec) {
977 ret = -ENOMEM;
978 goto failure;
979 }
980
981 if (flags)
982 nla_put_u16(nlm, IFLA_BRIDGE_FLAGS, flags);
983
984 nla_put(nlm, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo);
985 nla_nest_end(nlm, afspec);
986
987 return system_rtnl_call(nlm);
988
989 failure:
990 nlmsg_free(nlm);
991 return ret;
992 }
993
994 int system_if_resolve(struct device *dev)
995 {
996 struct ifreq ifr;
997
998 memset(&ifr, 0, sizeof(ifr));
999 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
1000 if (!ioctl(sock_ioctl, SIOCGIFINDEX, &ifr))
1001 return ifr.ifr_ifindex;
1002 else
1003 return 0;
1004 }
1005
1006 static int system_if_flags(const char *ifname, unsigned add, unsigned rem)
1007 {
1008 struct ifreq ifr;
1009
1010 memset(&ifr, 0, sizeof(ifr));
1011 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
1012 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) < 0)
1013 return -1;
1014
1015 ifr.ifr_flags |= add;
1016 ifr.ifr_flags &= ~rem;
1017 return ioctl(sock_ioctl, SIOCSIFFLAGS, &ifr);
1018 }
1019
1020 struct clear_data {
1021 struct nl_msg *msg;
1022 struct device *dev;
1023 int type;
1024 int size;
1025 int af;
1026 };
1027
1028
1029 static bool check_ifaddr(struct nlmsghdr *hdr, int ifindex)
1030 {
1031 struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
1032
1033 return ifa->ifa_index == ifindex;
1034 }
1035
1036 static bool check_route(struct nlmsghdr *hdr, int ifindex)
1037 {
1038 struct rtmsg *r = NLMSG_DATA(hdr);
1039 struct nlattr *tb[__RTA_MAX];
1040
1041 if (r->rtm_protocol == RTPROT_KERNEL &&
1042 r->rtm_family == AF_INET6)
1043 return false;
1044
1045 nlmsg_parse(hdr, sizeof(struct rtmsg), tb, __RTA_MAX - 1, NULL);
1046 if (!tb[RTA_OIF])
1047 return false;
1048
1049 return *(int *)RTA_DATA(tb[RTA_OIF]) == ifindex;
1050 }
1051
1052 static bool check_rule(struct nlmsghdr *hdr, int ifindex)
1053 {
1054 return true;
1055 }
1056
1057 static int cb_clear_event(struct nl_msg *msg, void *arg)
1058 {
1059 struct clear_data *clr = arg;
1060 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1061 bool (*cb)(struct nlmsghdr *, int ifindex);
1062 int type, ret;
1063
1064 switch(clr->type) {
1065 case RTM_GETADDR:
1066 type = RTM_DELADDR;
1067 if (hdr->nlmsg_type != RTM_NEWADDR)
1068 return NL_SKIP;
1069
1070 cb = check_ifaddr;
1071 break;
1072 case RTM_GETROUTE:
1073 type = RTM_DELROUTE;
1074 if (hdr->nlmsg_type != RTM_NEWROUTE)
1075 return NL_SKIP;
1076
1077 cb = check_route;
1078 break;
1079 case RTM_GETRULE:
1080 type = RTM_DELRULE;
1081 if (hdr->nlmsg_type != RTM_NEWRULE)
1082 return NL_SKIP;
1083
1084 cb = check_rule;
1085 break;
1086 default:
1087 return NL_SKIP;
1088 }
1089
1090 if (!cb(hdr, clr->dev ? clr->dev->ifindex : 0))
1091 return NL_SKIP;
1092
1093 if (type == RTM_DELRULE)
1094 D(SYSTEM, "Remove a rule\n");
1095 else
1096 D(SYSTEM, "Remove %s from device %s\n",
1097 type == RTM_DELADDR ? "an address" : "a route",
1098 clr->dev->ifname);
1099
1100 memcpy(nlmsg_hdr(clr->msg), hdr, hdr->nlmsg_len);
1101 hdr = nlmsg_hdr(clr->msg);
1102 hdr->nlmsg_type = type;
1103 hdr->nlmsg_flags = NLM_F_REQUEST;
1104
1105 nl_socket_disable_auto_ack(sock_rtnl);
1106 ret = nl_send_auto_complete(sock_rtnl, clr->msg);
1107 if (ret < 0) {
1108 if (type == RTM_DELRULE)
1109 D(SYSTEM, "Error deleting a rule: %d\n", ret);
1110 else
1111 D(SYSTEM, "Error deleting %s from device '%s': %d\n",
1112 type == RTM_DELADDR ? "an address" : "a route",
1113 clr->dev->ifname, ret);
1114 }
1115
1116 nl_socket_enable_auto_ack(sock_rtnl);
1117
1118 return NL_SKIP;
1119 }
1120
1121 static int
1122 cb_finish_event(struct nl_msg *msg, void *arg)
1123 {
1124 int *pending = arg;
1125 *pending = 0;
1126 return NL_STOP;
1127 }
1128
1129 static int
1130 error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1131 {
1132 int *pending = arg;
1133 *pending = err->error;
1134 return NL_STOP;
1135 }
1136
1137 static void
1138 system_if_clear_entries(struct device *dev, int type, int af)
1139 {
1140 struct clear_data clr;
1141 struct nl_cb *cb;
1142 struct rtmsg rtm = {
1143 .rtm_family = af,
1144 .rtm_flags = RTM_F_CLONED,
1145 };
1146 int flags = NLM_F_DUMP;
1147 int pending = 1;
1148
1149 clr.af = af;
1150 clr.dev = dev;
1151 clr.type = type;
1152 switch (type) {
1153 case RTM_GETADDR:
1154 case RTM_GETRULE:
1155 clr.size = sizeof(struct rtgenmsg);
1156 break;
1157 case RTM_GETROUTE:
1158 clr.size = sizeof(struct rtmsg);
1159 break;
1160 default:
1161 return;
1162 }
1163
1164 cb = nl_cb_alloc(NL_CB_DEFAULT);
1165 if (!cb)
1166 return;
1167
1168 clr.msg = nlmsg_alloc_simple(type, flags);
1169 if (!clr.msg)
1170 goto out;
1171
1172 nlmsg_append(clr.msg, &rtm, clr.size, 0);
1173 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_clear_event, &clr);
1174 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_finish_event, &pending);
1175 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &pending);
1176
1177 if (nl_send_auto_complete(sock_rtnl, clr.msg) < 0)
1178 goto free;
1179
1180 while (pending > 0)
1181 nl_recvmsgs(sock_rtnl, cb);
1182
1183 free:
1184 nlmsg_free(clr.msg);
1185 out:
1186 nl_cb_put(cb);
1187 }
1188
1189 /*
1190 * Clear bridge (membership) state and bring down device
1191 */
1192 void system_if_clear_state(struct device *dev)
1193 {
1194 static char buf[256];
1195 char *bridge;
1196 device_set_ifindex(dev, system_if_resolve(dev));
1197
1198 if (dev->external || !dev->ifindex)
1199 return;
1200
1201 system_if_flags(dev->ifname, 0, IFF_UP);
1202
1203 if (system_is_bridge(dev->ifname)) {
1204 D(SYSTEM, "Delete existing bridge named '%s'\n", dev->ifname);
1205 system_bridge_delbr(dev);
1206 return;
1207 }
1208
1209 bridge = system_get_bridge(dev->ifname, buf, sizeof(buf));
1210 if (bridge) {
1211 D(SYSTEM, "Remove device '%s' from bridge '%s'\n", dev->ifname, bridge);
1212 system_bridge_if(bridge, dev, SIOCBRDELIF, NULL);
1213 }
1214
1215 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET);
1216 system_if_clear_entries(dev, RTM_GETADDR, AF_INET);
1217 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6);
1218 system_if_clear_entries(dev, RTM_GETADDR, AF_INET6);
1219 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET);
1220 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET6);
1221 system_set_disable_ipv6(dev, "0");
1222 }
1223
1224 static inline unsigned long
1225 sec_to_jiffies(int val)
1226 {
1227 return (unsigned long) val * 100;
1228 }
1229
1230 static void system_bridge_conf_multicast_deps(struct device *bridge,
1231 struct bridge_config *cfg,
1232 char *buf,
1233 int buf_len)
1234 {
1235 int val;
1236
1237 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS ||
1238 cfg->flags & BRIDGE_OPT_QUERY_INTERVAL ||
1239 cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
1240 val = cfg->robustness * cfg->query_interval +
1241 cfg->query_response_interval;
1242
1243 snprintf(buf, buf_len, "%i", val);
1244 system_bridge_set_membership_interval(bridge, buf);
1245
1246 val = cfg->robustness * cfg->query_interval +
1247 cfg->query_response_interval / 2;
1248
1249 snprintf(buf, buf_len, "%i", val);
1250 system_bridge_set_other_querier_timeout(bridge, buf);
1251 }
1252
1253 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1254 val = cfg->query_interval / 4;
1255
1256 snprintf(buf, buf_len, "%i", val);
1257 system_bridge_set_startup_query_interval(bridge, buf);
1258 }
1259 }
1260
1261 static void system_bridge_conf_multicast(struct device *bridge,
1262 struct bridge_config *cfg,
1263 char *buf,
1264 int buf_len)
1265 {
1266 system_set_dev_sysfs("bridge/multicast_snooping",
1267 bridge->ifname, cfg->igmp_snoop ? "1" : "0");
1268
1269 system_set_dev_sysfs("bridge/multicast_querier",
1270 bridge->ifname, cfg->multicast_querier ? "1" : "0");
1271
1272 snprintf(buf, buf_len, "%i", cfg->hash_max);
1273 system_set_dev_sysfs("/bridge/hash_max",
1274 bridge->ifname, buf);
1275
1276 if (bridge->settings.flags & DEV_OPT_MULTICAST_ROUTER) {
1277 snprintf(buf, buf_len, "%u", bridge->settings.multicast_router);
1278 system_bridge_set_multicast_router(bridge, buf, true);
1279 }
1280
1281 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS) {
1282 snprintf(buf, buf_len, "%i", cfg->robustness);
1283 system_bridge_set_robustness(bridge, buf);
1284 }
1285
1286 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) {
1287 snprintf(buf, buf_len, "%i", cfg->query_interval);
1288 system_bridge_set_query_interval(bridge, buf);
1289 }
1290
1291 if (cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) {
1292 snprintf(buf, buf_len, "%i", cfg->query_response_interval);
1293 system_bridge_set_query_response_interval(bridge, buf);
1294 }
1295
1296 if (cfg->flags & BRIDGE_OPT_LAST_MEMBER_INTERVAL) {
1297 snprintf(buf, buf_len, "%i", cfg->last_member_interval);
1298 system_bridge_set_last_member_interval(bridge, buf);
1299 }
1300
1301 system_bridge_conf_multicast_deps(bridge, cfg, buf, buf_len);
1302 }
1303
1304 int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
1305 {
1306 char buf[64];
1307
1308 if (ioctl(sock_ioctl, SIOCBRADDBR, bridge->ifname) < 0)
1309 return -1;
1310
1311 system_bridge_set_stp_state(bridge, cfg->stp);
1312
1313 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->forward_delay));
1314 system_bridge_set_forward_delay(bridge, buf);
1315
1316 system_bridge_conf_multicast(bridge, cfg, buf, sizeof(buf));
1317 system_bridge_set_vlan_filtering(bridge, cfg->vlan_filtering ? "1" : "0");
1318
1319 snprintf(buf, sizeof(buf), "%d", cfg->priority);
1320 system_bridge_set_priority(bridge, buf);
1321
1322 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->hello_time));
1323 system_bridge_set_hello_time(bridge, buf);
1324
1325 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->max_age));
1326 system_bridge_set_max_age(bridge, buf);
1327
1328 if (cfg->flags & BRIDGE_OPT_AGEING_TIME) {
1329 snprintf(buf, sizeof(buf), "%lu", sec_to_jiffies(cfg->ageing_time));
1330 system_bridge_set_ageing_time(bridge, buf);
1331 }
1332
1333 return 0;
1334 }
1335
1336 int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg)
1337 {
1338 struct nl_msg *msg;
1339 struct nlattr *linkinfo, *data;
1340 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
1341 int i, rv;
1342 static const struct {
1343 const char *name;
1344 enum macvlan_mode val;
1345 } modes[] = {
1346 { "private", MACVLAN_MODE_PRIVATE },
1347 { "vepa", MACVLAN_MODE_VEPA },
1348 { "bridge", MACVLAN_MODE_BRIDGE },
1349 { "passthru", MACVLAN_MODE_PASSTHRU },
1350 };
1351
1352 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
1353
1354 if (!msg)
1355 return -1;
1356
1357 nlmsg_append(msg, &iim, sizeof(iim), 0);
1358
1359 if (cfg->flags & MACVLAN_OPT_MACADDR)
1360 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
1361 nla_put_string(msg, IFLA_IFNAME, macvlan->ifname);
1362 nla_put_u32(msg, IFLA_LINK, dev->ifindex);
1363
1364 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
1365 goto nla_put_failure;
1366
1367 nla_put_string(msg, IFLA_INFO_KIND, "macvlan");
1368
1369 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
1370 goto nla_put_failure;
1371
1372 if (cfg->mode) {
1373 for (i = 0; i < ARRAY_SIZE(modes); i++) {
1374 if (strcmp(cfg->mode, modes[i].name) != 0)
1375 continue;
1376
1377 nla_put_u32(msg, IFLA_MACVLAN_MODE, modes[i].val);
1378 break;
1379 }
1380 }
1381
1382 nla_nest_end(msg, data);
1383 nla_nest_end(msg, linkinfo);
1384
1385 rv = system_rtnl_call(msg);
1386 if (rv)
1387 D(SYSTEM, "Error adding macvlan '%s' over '%s': %d\n", macvlan->ifname, dev->ifname, rv);
1388
1389 return rv;
1390
1391 nla_put_failure:
1392 nlmsg_free(msg);
1393 return -ENOMEM;
1394 }
1395
1396 int system_link_netns_move(struct device *dev, int netns_fd, const char *target_ifname)
1397 {
1398 struct nl_msg *msg;
1399 struct ifinfomsg iim = {
1400 .ifi_family = AF_UNSPEC,
1401 };
1402
1403 if (!dev)
1404 return -1;
1405
1406 iim.ifi_index = system_if_resolve(dev);
1407 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST);
1408
1409 if (!msg)
1410 return -1;
1411
1412 nlmsg_append(msg, &iim, sizeof(iim), 0);
1413 if (target_ifname)
1414 nla_put_string(msg, IFLA_IFNAME, target_ifname);
1415
1416 nla_put_u32(msg, IFLA_NET_NS_FD, netns_fd);
1417 return system_rtnl_call(msg);
1418 }
1419
1420 static int system_link_del(const char *ifname)
1421 {
1422 struct nl_msg *msg;
1423 struct ifinfomsg iim = {
1424 .ifi_family = AF_UNSPEC,
1425 .ifi_index = 0,
1426 };
1427
1428 msg = nlmsg_alloc_simple(RTM_DELLINK, NLM_F_REQUEST);
1429
1430 if (!msg)
1431 return -1;
1432
1433 nlmsg_append(msg, &iim, sizeof(iim), 0);
1434 nla_put_string(msg, IFLA_IFNAME, ifname);
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 int
2303 system_if_dump_info(struct device *dev, struct blob_buf *b)
2304 {
2305 struct ethtool_cmd ecmd;
2306 struct ifreq ifr;
2307 char *s;
2308 void *c;
2309
2310 memset(&ecmd, 0, sizeof(ecmd));
2311 memset(&ifr, 0, sizeof(ifr));
2312 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
2313 ifr.ifr_data = (caddr_t) &ecmd;
2314 ecmd.cmd = ETHTOOL_GSET;
2315
2316 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == 0) {
2317 c = blobmsg_open_array(b, "link-advertising");
2318 system_add_link_modes(b, ecmd.advertising);
2319 blobmsg_close_array(b, c);
2320
2321 c = blobmsg_open_array(b, "link-partner-advertising");
2322 system_add_link_modes(b, ecmd.lp_advertising);
2323 blobmsg_close_array(b, c);
2324
2325 c = blobmsg_open_array(b, "link-supported");
2326 system_add_link_modes(b, ecmd.supported);
2327 blobmsg_close_array(b, c);
2328
2329 s = blobmsg_alloc_string_buffer(b, "speed", 8);
2330 snprintf(s, 8, "%d%c", ethtool_cmd_speed(&ecmd),
2331 ecmd.duplex == DUPLEX_HALF ? 'H' : 'F');
2332 blobmsg_add_string_buffer(b);
2333
2334 blobmsg_add_u8(b, "autoneg", !!ecmd.autoneg);
2335 }
2336
2337 return 0;
2338 }
2339
2340 int
2341 system_if_dump_stats(struct device *dev, struct blob_buf *b)
2342 {
2343 const char *const counters[] = {
2344 "collisions", "rx_frame_errors", "tx_compressed",
2345 "multicast", "rx_length_errors", "tx_dropped",
2346 "rx_bytes", "rx_missed_errors", "tx_errors",
2347 "rx_compressed", "rx_over_errors", "tx_fifo_errors",
2348 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors",
2349 "rx_dropped", "tx_aborted_errors", "tx_packets",
2350 "rx_errors", "tx_bytes", "tx_window_errors",
2351 "rx_fifo_errors", "tx_carrier_errors",
2352 };
2353 int stats_dir;
2354 int i;
2355 uint64_t val = 0;
2356
2357 stats_dir = open(dev_sysfs_path(dev->ifname, "statistics"), O_DIRECTORY);
2358 if (stats_dir < 0)
2359 return -1;
2360
2361 for (i = 0; i < ARRAY_SIZE(counters); i++)
2362 if (read_uint64_file(stats_dir, counters[i], &val))
2363 blobmsg_add_u64(b, counters[i], val);
2364
2365 close(stats_dir);
2366 return 0;
2367 }
2368
2369 static int system_addr(struct device *dev, struct device_addr *addr, int cmd)
2370 {
2371 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4);
2372 int alen = v4 ? 4 : 16;
2373 unsigned int flags = 0;
2374 struct ifaddrmsg ifa = {
2375 .ifa_family = (alen == 4) ? AF_INET : AF_INET6,
2376 .ifa_prefixlen = addr->mask,
2377 .ifa_index = dev->ifindex,
2378 };
2379
2380 struct nl_msg *msg;
2381 if (cmd == RTM_NEWADDR)
2382 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2383
2384 msg = nlmsg_alloc_simple(cmd, flags);
2385 if (!msg)
2386 return -1;
2387
2388 nlmsg_append(msg, &ifa, sizeof(ifa), 0);
2389 nla_put(msg, IFA_LOCAL, alen, &addr->addr);
2390 if (v4) {
2391 if (addr->broadcast)
2392 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast);
2393 if (addr->point_to_point)
2394 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point);
2395 } else {
2396 time_t now = system_get_rtime();
2397 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0};
2398
2399 if (addr->preferred_until) {
2400 int64_t preferred = addr->preferred_until - now;
2401 if (preferred < 0)
2402 preferred = 0;
2403 else if (preferred > UINT32_MAX)
2404 preferred = UINT32_MAX;
2405
2406 cinfo.ifa_prefered = preferred;
2407 }
2408
2409 if (addr->valid_until) {
2410 int64_t valid = addr->valid_until - now;
2411 if (valid <= 0) {
2412 nlmsg_free(msg);
2413 return -1;
2414 }
2415 else if (valid > UINT32_MAX)
2416 valid = UINT32_MAX;
2417
2418 cinfo.ifa_valid = valid;
2419 }
2420
2421 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo);
2422
2423 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK))
2424 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE);
2425 }
2426
2427 return system_rtnl_call(msg);
2428 }
2429
2430 int system_add_address(struct device *dev, struct device_addr *addr)
2431 {
2432 return system_addr(dev, addr, RTM_NEWADDR);
2433 }
2434
2435 int system_del_address(struct device *dev, struct device_addr *addr)
2436 {
2437 return system_addr(dev, addr, RTM_DELADDR);
2438 }
2439
2440 static int system_neigh(struct device *dev, struct device_neighbor *neighbor, int cmd)
2441 {
2442 int alen = ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
2443 unsigned int flags = 0;
2444 struct ndmsg ndm = {
2445 .ndm_family = (alen == 4) ? AF_INET : AF_INET6,
2446 .ndm_ifindex = dev->ifindex,
2447 .ndm_state = NUD_PERMANENT,
2448 .ndm_flags = (neighbor->proxy ? NTF_PROXY : 0) | (neighbor->router ? NTF_ROUTER : 0),
2449 };
2450 struct nl_msg *msg;
2451
2452 if (cmd == RTM_NEWNEIGH)
2453 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2454
2455 msg = nlmsg_alloc_simple(cmd, flags);
2456
2457 if (!msg)
2458 return -1;
2459
2460 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
2461
2462 nla_put(msg, NDA_DST, alen, &neighbor->addr);
2463 if (neighbor->flags & DEVNEIGH_MAC)
2464 nla_put(msg, NDA_LLADDR, sizeof(neighbor->macaddr), &neighbor->macaddr);
2465
2466
2467 return system_rtnl_call(msg);
2468 }
2469
2470 int system_add_neighbor(struct device *dev, struct device_neighbor *neighbor)
2471 {
2472 return system_neigh(dev, neighbor, RTM_NEWNEIGH);
2473 }
2474
2475 int system_del_neighbor(struct device *dev, struct device_neighbor *neighbor)
2476 {
2477 return system_neigh(dev, neighbor, RTM_DELNEIGH);
2478 }
2479
2480 static int system_rt(struct device *dev, struct device_route *route, int cmd)
2481 {
2482 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16;
2483 bool have_gw;
2484 unsigned int flags = 0;
2485
2486 if (alen == 4)
2487 have_gw = !!route->nexthop.in.s_addr;
2488 else
2489 have_gw = route->nexthop.in6.s6_addr32[0] ||
2490 route->nexthop.in6.s6_addr32[1] ||
2491 route->nexthop.in6.s6_addr32[2] ||
2492 route->nexthop.in6.s6_addr32[3];
2493
2494 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))
2495 ? route->table : RT_TABLE_MAIN;
2496
2497 struct rtmsg rtm = {
2498 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2499 .rtm_dst_len = route->mask,
2500 .rtm_src_len = route->sourcemask,
2501 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
2502 .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC,
2503 .rtm_scope = RT_SCOPE_NOWHERE,
2504 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
2505 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
2506 };
2507 struct nl_msg *msg;
2508
2509 if (cmd == RTM_NEWROUTE) {
2510 flags |= NLM_F_CREATE | NLM_F_REPLACE;
2511
2512 if (!dev) { /* Add null-route */
2513 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
2514 rtm.rtm_type = RTN_UNREACHABLE;
2515 }
2516 else
2517 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
2518 }
2519
2520 if (route->flags & DEVROUTE_TYPE) {
2521 rtm.rtm_type = route->type;
2522 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) {
2523 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST ||
2524 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST)
2525 rtm.rtm_table = RT_TABLE_LOCAL;
2526 }
2527
2528 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) {
2529 rtm.rtm_scope = RT_SCOPE_HOST;
2530 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
2531 rtm.rtm_type == RTN_ANYCAST) {
2532 rtm.rtm_scope = RT_SCOPE_LINK;
2533 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE ||
2534 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY ||
2535 rtm.rtm_type == RTN_THROW) {
2536 rtm.rtm_scope = RT_SCOPE_UNIVERSE;
2537 dev = NULL;
2538 }
2539 }
2540
2541 msg = nlmsg_alloc_simple(cmd, flags);
2542 if (!msg)
2543 return -1;
2544
2545 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2546
2547 if (route->mask)
2548 nla_put(msg, RTA_DST, alen, &route->addr);
2549
2550 if (route->sourcemask) {
2551 if (rtm.rtm_family == AF_INET)
2552 nla_put(msg, RTA_PREFSRC, alen, &route->source);
2553 else
2554 nla_put(msg, RTA_SRC, alen, &route->source);
2555 }
2556
2557 if (route->metric > 0)
2558 nla_put_u32(msg, RTA_PRIORITY, route->metric);
2559
2560 if (have_gw)
2561 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop);
2562
2563 if (dev)
2564 nla_put_u32(msg, RTA_OIF, dev->ifindex);
2565
2566 if (table >= 256)
2567 nla_put_u32(msg, RTA_TABLE, table);
2568
2569 if (route->flags & DEVROUTE_MTU) {
2570 struct nlattr *metrics;
2571
2572 if (!(metrics = nla_nest_start(msg, RTA_METRICS)))
2573 goto nla_put_failure;
2574
2575 nla_put_u32(msg, RTAX_MTU, route->mtu);
2576
2577 nla_nest_end(msg, metrics);
2578 }
2579
2580 return system_rtnl_call(msg);
2581
2582 nla_put_failure:
2583 nlmsg_free(msg);
2584 return -ENOMEM;
2585 }
2586
2587 int system_add_route(struct device *dev, struct device_route *route)
2588 {
2589 return system_rt(dev, route, RTM_NEWROUTE);
2590 }
2591
2592 int system_del_route(struct device *dev, struct device_route *route)
2593 {
2594 return system_rt(dev, route, RTM_DELROUTE);
2595 }
2596
2597 int system_flush_routes(void)
2598 {
2599 const char *names[] = { "ipv4", "ipv6" };
2600 int fd, i;
2601
2602 for (i = 0; i < ARRAY_SIZE(names); i++) {
2603 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/route/flush", proc_path, names[i]);
2604 fd = open(dev_buf, O_WRONLY);
2605 if (fd < 0)
2606 continue;
2607
2608 if (write(fd, "-1", 2)) {}
2609 close(fd);
2610 }
2611 return 0;
2612 }
2613
2614 bool system_resolve_rt_type(const char *type, unsigned int *id)
2615 {
2616 return system_rtn_aton(type, id);
2617 }
2618
2619 bool system_resolve_rt_proto(const char *type, unsigned int *id)
2620 {
2621 FILE *f;
2622 char *e, buf[128];
2623 unsigned int n, proto = 256;
2624 n = strtoul(type, &e, 0);
2625 if (!*e && e != type)
2626 proto = n;
2627 else if (!strcmp(type, "unspec"))
2628 proto = RTPROT_UNSPEC;
2629 else if (!strcmp(type, "kernel"))
2630 proto = RTPROT_KERNEL;
2631 else if (!strcmp(type, "boot"))
2632 proto = RTPROT_BOOT;
2633 else if (!strcmp(type, "static"))
2634 proto = RTPROT_STATIC;
2635 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) {
2636 while (fgets(buf, sizeof(buf) - 1, f) != NULL) {
2637 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2638 continue;
2639
2640 n = strtoul(e, NULL, 10);
2641 e = strtok(NULL, " \t\n");
2642
2643 if (e && !strcmp(e, type)) {
2644 proto = n;
2645 break;
2646 }
2647 }
2648 fclose(f);
2649 }
2650
2651 if (proto > 255)
2652 return false;
2653
2654 *id = proto;
2655 return true;
2656 }
2657
2658 bool system_resolve_rt_table(const char *name, unsigned int *id)
2659 {
2660 FILE *f;
2661 char *e, buf[128];
2662 unsigned int n, table = RT_TABLE_UNSPEC;
2663
2664 /* first try to parse table as number */
2665 if ((n = strtoul(name, &e, 0)) > 0 && !*e)
2666 table = n;
2667
2668 /* handle well known aliases */
2669 else if (!strcmp(name, "default"))
2670 table = RT_TABLE_DEFAULT;
2671 else if (!strcmp(name, "main"))
2672 table = RT_TABLE_MAIN;
2673 else if (!strcmp(name, "local"))
2674 table = RT_TABLE_LOCAL;
2675
2676 /* try to look up name in /etc/iproute2/rt_tables */
2677 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL)
2678 {
2679 while (fgets(buf, sizeof(buf) - 1, f) != NULL)
2680 {
2681 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#')
2682 continue;
2683
2684 n = strtoul(e, NULL, 10);
2685 e = strtok(NULL, " \t\n");
2686
2687 if (e && !strcmp(e, name))
2688 {
2689 table = n;
2690 break;
2691 }
2692 }
2693
2694 fclose(f);
2695 }
2696
2697 if (table == RT_TABLE_UNSPEC)
2698 return false;
2699
2700 *id = table;
2701 return true;
2702 }
2703
2704 bool system_is_default_rt_table(unsigned int id)
2705 {
2706 return (id == RT_TABLE_MAIN);
2707 }
2708
2709 bool system_resolve_rpfilter(const char *filter, unsigned int *id)
2710 {
2711 char *e;
2712 unsigned int n;
2713
2714 if (!strcmp(filter, "strict"))
2715 n = 1;
2716 else if (!strcmp(filter, "loose"))
2717 n = 2;
2718 else {
2719 n = strtoul(filter, &e, 0);
2720 if (*e || e == filter || n > 2)
2721 return false;
2722 }
2723
2724 *id = n;
2725 return true;
2726 }
2727
2728 static int system_iprule(struct iprule *rule, int cmd)
2729 {
2730 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;
2731
2732 struct nl_msg *msg;
2733 struct rtmsg rtm = {
2734 .rtm_family = (alen == 4) ? AF_INET : AF_INET6,
2735 .rtm_protocol = RTPROT_STATIC,
2736 .rtm_scope = RT_SCOPE_UNIVERSE,
2737 .rtm_table = RT_TABLE_UNSPEC,
2738 .rtm_type = RTN_UNSPEC,
2739 .rtm_flags = 0,
2740 };
2741
2742 if (cmd == RTM_NEWRULE)
2743 rtm.rtm_type = RTN_UNICAST;
2744
2745 if (rule->invert)
2746 rtm.rtm_flags |= FIB_RULE_INVERT;
2747
2748 if (rule->flags & IPRULE_SRC)
2749 rtm.rtm_src_len = rule->src_mask;
2750
2751 if (rule->flags & IPRULE_DEST)
2752 rtm.rtm_dst_len = rule->dest_mask;
2753
2754 if (rule->flags & IPRULE_TOS)
2755 rtm.rtm_tos = rule->tos;
2756
2757 if (rule->flags & IPRULE_LOOKUP) {
2758 if (rule->lookup < 256)
2759 rtm.rtm_table = rule->lookup;
2760 }
2761
2762 if (rule->flags & IPRULE_ACTION)
2763 rtm.rtm_type = rule->action;
2764 else if (rule->flags & IPRULE_GOTO)
2765 rtm.rtm_type = FR_ACT_GOTO;
2766 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO)))
2767 rtm.rtm_type = FR_ACT_NOP;
2768
2769 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST);
2770
2771 if (!msg)
2772 return -1;
2773
2774 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
2775
2776 if (rule->flags & IPRULE_IN)
2777 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev);
2778
2779 if (rule->flags & IPRULE_OUT)
2780 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev);
2781
2782 if (rule->flags & IPRULE_SRC)
2783 nla_put(msg, FRA_SRC, alen, &rule->src_addr);
2784
2785 if (rule->flags & IPRULE_DEST)
2786 nla_put(msg, FRA_DST, alen, &rule->dest_addr);
2787
2788 if (rule->flags & IPRULE_PRIORITY)
2789 nla_put_u32(msg, FRA_PRIORITY, rule->priority);
2790 else if (cmd == RTM_NEWRULE)
2791 nla_put_u32(msg, FRA_PRIORITY, rule->order);
2792
2793 if (rule->flags & IPRULE_FWMARK)
2794 nla_put_u32(msg, FRA_FWMARK, rule->fwmark);
2795
2796 if (rule->flags & IPRULE_FWMASK)
2797 nla_put_u32(msg, FRA_FWMASK, rule->fwmask);
2798
2799 if (rule->flags & IPRULE_LOOKUP) {
2800 if (rule->lookup >= 256)
2801 nla_put_u32(msg, FRA_TABLE, rule->lookup);
2802 }
2803
2804 if (rule->flags & IPRULE_SUP_PREFIXLEN)
2805 nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen);
2806
2807 if (rule->flags & IPRULE_GOTO)
2808 nla_put_u32(msg, FRA_GOTO, rule->gotoid);
2809
2810 return system_rtnl_call(msg);
2811 }
2812
2813 int system_add_iprule(struct iprule *rule)
2814 {
2815 return system_iprule(rule, RTM_NEWRULE);
2816 }
2817
2818 int system_del_iprule(struct iprule *rule)
2819 {
2820 return system_iprule(rule, RTM_DELRULE);
2821 }
2822
2823 int system_flush_iprules(void)
2824 {
2825 int rv = 0;
2826 struct iprule rule;
2827
2828 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET);
2829 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6);
2830
2831 memset(&rule, 0, sizeof(rule));
2832
2833
2834 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2835
2836 rule.priority = 0;
2837 rule.lookup = RT_TABLE_LOCAL;
2838 rv |= system_iprule(&rule, RTM_NEWRULE);
2839
2840 rule.priority = 32766;
2841 rule.lookup = RT_TABLE_MAIN;
2842 rv |= system_iprule(&rule, RTM_NEWRULE);
2843
2844 rule.priority = 32767;
2845 rule.lookup = RT_TABLE_DEFAULT;
2846 rv |= system_iprule(&rule, RTM_NEWRULE);
2847
2848
2849 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP;
2850
2851 rule.priority = 0;
2852 rule.lookup = RT_TABLE_LOCAL;
2853 rv |= system_iprule(&rule, RTM_NEWRULE);
2854
2855 rule.priority = 32766;
2856 rule.lookup = RT_TABLE_MAIN;
2857 rv |= system_iprule(&rule, RTM_NEWRULE);
2858
2859 return rv;
2860 }
2861
2862 bool system_resolve_iprule_action(const char *action, unsigned int *id)
2863 {
2864 return system_rtn_aton(action, id);
2865 }
2866
2867 time_t system_get_rtime(void)
2868 {
2869 struct timespec ts;
2870 struct timeval tv;
2871
2872 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
2873 return ts.tv_sec;
2874
2875 if (gettimeofday(&tv, NULL) == 0)
2876 return tv.tv_sec;
2877
2878 return 0;
2879 }
2880
2881 #ifndef IP_DF
2882 #define IP_DF 0x4000
2883 #endif
2884
2885 static int tunnel_ioctl(const char *name, int cmd, void *p)
2886 {
2887 struct ifreq ifr;
2888
2889 memset(&ifr, 0, sizeof(ifr));
2890 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
2891 ifr.ifr_ifru.ifru_data = p;
2892 return ioctl(sock_ioctl, cmd, &ifr);
2893 }
2894
2895 #ifdef IFLA_IPTUN_MAX
2896 static int system_add_ip6_tunnel(const char *name, const unsigned int link,
2897 struct blob_attr **tb)
2898 {
2899 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
2900 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
2901 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
2902 struct blob_attr *cur;
2903 int ret = 0, ttl = 0;
2904
2905 if (!nlm)
2906 return -1;
2907
2908 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
2909 nla_put_string(nlm, IFLA_IFNAME, name);
2910
2911 if (link)
2912 nla_put_u32(nlm, IFLA_LINK, link);
2913
2914 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
2915 if (!linkinfo) {
2916 ret = -ENOMEM;
2917 goto failure;
2918 }
2919
2920 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl");
2921 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
2922 if (!infodata) {
2923 ret = -ENOMEM;
2924 goto failure;
2925 }
2926
2927 if (link)
2928 nla_put_u32(nlm, IFLA_IPTUN_LINK, link);
2929
2930 if ((cur = tb[TUNNEL_ATTR_TTL]))
2931 ttl = blobmsg_get_u32(cur);
2932
2933 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP);
2934 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64);
2935
2936 struct in6_addr in6buf;
2937 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
2938 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2939 ret = -EINVAL;
2940 goto failure;
2941 }
2942 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf);
2943 }
2944
2945 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
2946 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
2947 ret = -EINVAL;
2948 goto failure;
2949 }
2950 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf);
2951 }
2952
2953 if ((cur = tb[TUNNEL_ATTR_DATA])) {
2954 struct blob_attr *tb_data[__IPIP6_DATA_ATTR_MAX];
2955 uint32_t tun_flags = IP6_TNL_F_IGN_ENCAP_LIMIT;
2956
2957 blobmsg_parse(ipip6_data_attr_list.params, __IPIP6_DATA_ATTR_MAX, tb_data,
2958 blobmsg_data(cur), blobmsg_len(cur));
2959
2960 if ((cur = tb_data[IPIP6_DATA_ENCAPLIMIT])) {
2961 char *str = blobmsg_get_string(cur);
2962
2963 if (strcmp(str, "ignore")) {
2964 char *e;
2965 unsigned encap_limit = strtoul(str, &e, 0);
2966
2967 if (e == str || *e || encap_limit > 255) {
2968 ret = -EINVAL;
2969 goto failure;
2970 }
2971
2972 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, encap_limit);
2973 tun_flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
2974 }
2975 }
2976
2977 #ifdef IFLA_IPTUN_FMR_MAX
2978 if ((cur = tb_data[IPIP6_DATA_FMRS])) {
2979 struct blob_attr *rcur;
2980 unsigned rrem, fmrcnt = 0;
2981 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS);
2982
2983 if (!fmrs) {
2984 ret = -ENOMEM;
2985 goto failure;
2986 }
2987
2988 blobmsg_for_each_attr(rcur, cur, rrem) {
2989 struct blob_attr *tb_fmr[__FMR_DATA_ATTR_MAX], *tb_cur;
2990 struct in6_addr ip6prefix;
2991 struct in_addr ip4prefix;
2992 unsigned ip4len, ip6len, ealen, offset;
2993
2994 blobmsg_parse(fmr_data_attr_list.params, __FMR_DATA_ATTR_MAX, tb_fmr,
2995 blobmsg_data(rcur), blobmsg_len(rcur));
2996
2997 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX6]) ||
2998 !parse_ip_and_netmask(AF_INET6,
2999 blobmsg_data(tb_cur), &ip6prefix,
3000 &ip6len)) {
3001 ret = -EINVAL;
3002 goto failure;
3003 }
3004
3005 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX4]) ||
3006 !parse_ip_and_netmask(AF_INET,
3007 blobmsg_data(tb_cur), &ip4prefix,
3008 &ip4len)) {
3009 ret = -EINVAL;
3010 goto failure;
3011 }
3012
3013 if (!(tb_cur = tb_fmr[FMR_DATA_EALEN])) {
3014 ret = -EINVAL;
3015 goto failure;
3016 }
3017 ealen = blobmsg_get_u32(tb_cur);
3018
3019 if (!(tb_cur = tb_fmr[FMR_DATA_OFFSET])) {
3020 ret = -EINVAL;
3021 goto failure;
3022 }
3023 offset = blobmsg_get_u32(tb_cur);
3024
3025 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt);
3026 if (!rule) {
3027 ret = -ENOMEM;
3028 goto failure;
3029 }
3030
3031 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix);
3032 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix);
3033 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len);
3034 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len);
3035 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen);
3036 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset);
3037
3038 nla_nest_end(nlm, rule);
3039 }
3040
3041 nla_nest_end(nlm, fmrs);
3042 }
3043 #endif
3044 if (tun_flags)
3045 nla_put_u32(nlm, IFLA_IPTUN_FLAGS, tun_flags);
3046 }
3047
3048 nla_nest_end(nlm, infodata);
3049 nla_nest_end(nlm, linkinfo);
3050
3051 return system_rtnl_call(nlm);
3052
3053 failure:
3054 nlmsg_free(nlm);
3055 return ret;
3056 }
3057 #endif
3058
3059 #ifdef IFLA_IPTUN_MAX
3060 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
3061 static int system_add_gre_tunnel(const char *name, const char *kind,
3062 const unsigned int link, struct blob_attr **tb, bool v6)
3063 {
3064 struct nl_msg *nlm;
3065 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
3066 struct blob_attr *cur;
3067 uint32_t ikey = 0, okey = 0, flowinfo = 0, flags6 = IP6_TNL_F_IGN_ENCAP_LIMIT;
3068 uint16_t iflags = 0, oflags = 0;
3069 uint8_t tos = 0;
3070 int ret = 0, ttl = 0;
3071 unsigned encap_limit = 0;
3072
3073 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3074 if (!nlm)
3075 return -1;
3076
3077 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3078 nla_put_string(nlm, IFLA_IFNAME, name);
3079
3080 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3081 if (!linkinfo) {
3082 ret = -ENOMEM;
3083 goto failure;
3084 }
3085
3086 nla_put_string(nlm, IFLA_INFO_KIND, kind);
3087 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3088 if (!infodata) {
3089 ret = -ENOMEM;
3090 goto failure;
3091 }
3092
3093 if (link)
3094 nla_put_u32(nlm, IFLA_GRE_LINK, link);
3095
3096 if ((cur = tb[TUNNEL_ATTR_TTL]))
3097 ttl = blobmsg_get_u32(cur);
3098
3099 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3100 char *str = blobmsg_get_string(cur);
3101 if (strcmp(str, "inherit")) {
3102 unsigned uval;
3103
3104 if (!system_tos_aton(str, &uval)) {
3105 ret = -EINVAL;
3106 goto failure;
3107 }
3108
3109 if (v6)
3110 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS;
3111 else
3112 tos = uval;
3113 } else {
3114 if (v6)
3115 flags6 |= IP6_TNL_F_USE_ORIG_TCLASS;
3116 else
3117 tos = 1;
3118 }
3119 }
3120
3121 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3122 struct blob_attr *tb_data[__GRE_DATA_ATTR_MAX];
3123
3124 blobmsg_parse(gre_data_attr_list.params, __GRE_DATA_ATTR_MAX, tb_data,
3125 blobmsg_data(cur), blobmsg_len(cur));
3126
3127 if ((cur = tb_data[GRE_DATA_IKEY])) {
3128 if ((ikey = blobmsg_get_u32(cur)))
3129 iflags |= GRE_KEY;
3130 }
3131
3132 if ((cur = tb_data[GRE_DATA_OKEY])) {
3133 if ((okey = blobmsg_get_u32(cur)))
3134 oflags |= GRE_KEY;
3135 }
3136
3137 if ((cur = tb_data[GRE_DATA_ICSUM])) {
3138 if (blobmsg_get_bool(cur))
3139 iflags |= GRE_CSUM;
3140 }
3141
3142 if ((cur = tb_data[GRE_DATA_OCSUM])) {
3143 if (blobmsg_get_bool(cur))
3144 oflags |= GRE_CSUM;
3145 }
3146
3147 if ((cur = tb_data[GRE_DATA_ISEQNO])) {
3148 if (blobmsg_get_bool(cur))
3149 iflags |= GRE_SEQ;
3150 }
3151
3152 if ((cur = tb_data[GRE_DATA_OSEQNO])) {
3153 if (blobmsg_get_bool(cur))
3154 oflags |= GRE_SEQ;
3155 }
3156
3157 if ((cur = tb_data[GRE_DATA_ENCAPLIMIT])) {
3158 char *str = blobmsg_get_string(cur);
3159
3160 if (strcmp(str, "ignore")) {
3161 char *e;
3162
3163 encap_limit = strtoul(str, &e, 0);
3164
3165 if (e == str || *e || encap_limit > 255) {
3166 ret = -EINVAL;
3167 goto failure;
3168 }
3169
3170 flags6 &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
3171 }
3172 }
3173 }
3174
3175 if (v6) {
3176 struct in6_addr in6buf;
3177 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3178 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3179 ret = -EINVAL;
3180 goto failure;
3181 }
3182 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf);
3183 }
3184
3185 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3186 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3187 ret = -EINVAL;
3188 goto failure;
3189 }
3190 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf);
3191 }
3192
3193 if (!(flags6 & IP6_TNL_F_IGN_ENCAP_LIMIT))
3194 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, encap_limit);
3195
3196 if (flowinfo)
3197 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo);
3198
3199 if (flags6)
3200 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags6);
3201
3202 if (!ttl)
3203 ttl = 64;
3204 } else {
3205 struct in_addr inbuf;
3206 bool set_df = true;
3207
3208 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3209 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3210 ret = -EINVAL;
3211 goto failure;
3212 }
3213 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf);
3214 }
3215
3216 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3217 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3218 ret = -EINVAL;
3219 goto failure;
3220 }
3221 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf);
3222
3223 if (IN_MULTICAST(ntohl(inbuf.s_addr))) {
3224 if (!okey) {
3225 okey = inbuf.s_addr;
3226 oflags |= GRE_KEY;
3227 }
3228
3229 if (!ikey) {
3230 ikey = inbuf.s_addr;
3231 iflags |= GRE_KEY;
3232 }
3233 }
3234 }
3235
3236 if ((cur = tb[TUNNEL_ATTR_DF]))
3237 set_df = blobmsg_get_bool(cur);
3238
3239 if (!set_df) {
3240 /* ttl != 0 and nopmtudisc are incompatible */
3241 if (ttl) {
3242 ret = -EINVAL;
3243 goto failure;
3244 }
3245 } else if (!ttl)
3246 ttl = 64;
3247
3248 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0);
3249
3250 nla_put_u8(nlm, IFLA_GRE_TOS, tos);
3251 }
3252
3253 if (ttl)
3254 nla_put_u8(nlm, IFLA_GRE_TTL, ttl);
3255
3256 if (oflags)
3257 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags);
3258
3259 if (iflags)
3260 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags);
3261
3262 if (okey)
3263 nla_put_u32(nlm, IFLA_GRE_OKEY, htonl(okey));
3264
3265 if (ikey)
3266 nla_put_u32(nlm, IFLA_GRE_IKEY, htonl(ikey));
3267
3268 nla_nest_end(nlm, infodata);
3269 nla_nest_end(nlm, linkinfo);
3270
3271 return system_rtnl_call(nlm);
3272
3273 failure:
3274 nlmsg_free(nlm);
3275 return ret;
3276 }
3277 #endif
3278
3279 #ifdef IFLA_VTI_MAX
3280 static int system_add_vti_tunnel(const char *name, const char *kind,
3281 const unsigned int link, struct blob_attr **tb, bool v6)
3282 {
3283 struct nl_msg *nlm;
3284 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
3285 struct blob_attr *cur;
3286 int ret = 0;
3287
3288 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3289 if (!nlm)
3290 return -1;
3291
3292 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3293 nla_put_string(nlm, IFLA_IFNAME, name);
3294
3295 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3296 if (!linkinfo) {
3297 ret = -ENOMEM;
3298 goto failure;
3299 }
3300
3301 nla_put_string(nlm, IFLA_INFO_KIND, kind);
3302 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3303 if (!infodata) {
3304 ret = -ENOMEM;
3305 goto failure;
3306 }
3307
3308 if (link)
3309 nla_put_u32(nlm, IFLA_VTI_LINK, link);
3310
3311 if (v6) {
3312 struct in6_addr in6buf;
3313 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3314 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3315 ret = -EINVAL;
3316 goto failure;
3317 }
3318 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf);
3319 }
3320
3321 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3322 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3323 ret = -EINVAL;
3324 goto failure;
3325 }
3326 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf);
3327 }
3328
3329 } else {
3330 struct in_addr inbuf;
3331
3332 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3333 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3334 ret = -EINVAL;
3335 goto failure;
3336 }
3337 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf);
3338 }
3339
3340 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3341 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3342 ret = -EINVAL;
3343 goto failure;
3344 }
3345 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf);
3346 }
3347
3348 }
3349
3350 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3351 struct blob_attr *tb_data[__VTI_DATA_ATTR_MAX];
3352 uint32_t ikey = 0, okey = 0;
3353
3354 blobmsg_parse(vti_data_attr_list.params, __VTI_DATA_ATTR_MAX, tb_data,
3355 blobmsg_data(cur), blobmsg_len(cur));
3356
3357 if ((cur = tb_data[VTI_DATA_IKEY])) {
3358 if ((ikey = blobmsg_get_u32(cur)))
3359 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey));
3360 }
3361
3362 if ((cur = tb_data[VTI_DATA_OKEY])) {
3363 if ((okey = blobmsg_get_u32(cur)))
3364 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey));
3365 }
3366 }
3367
3368 nla_nest_end(nlm, infodata);
3369 nla_nest_end(nlm, linkinfo);
3370
3371 return system_rtnl_call(nlm);
3372
3373 failure:
3374 nlmsg_free(nlm);
3375 return ret;
3376 }
3377 #endif
3378
3379 #ifdef IFLA_XFRM_MAX
3380 static int system_add_xfrm_tunnel(const char *name, const char *kind,
3381 const unsigned int link, struct blob_attr **tb)
3382 {
3383 struct nl_msg *nlm;
3384 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
3385 struct blob_attr *cur;
3386 int ret = 0;
3387
3388 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
3389 if (!nlm)
3390 return -1;
3391
3392 nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
3393 nla_put_string(nlm, IFLA_IFNAME, name);
3394
3395 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
3396 if (!linkinfo) {
3397 ret = -ENOMEM;
3398 goto failure;
3399 }
3400
3401 nla_put_string(nlm, IFLA_INFO_KIND, kind);
3402 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
3403 if (!infodata) {
3404 ret = -ENOMEM;
3405 goto failure;
3406 }
3407
3408 if (link)
3409 nla_put_u32(nlm, IFLA_XFRM_LINK, link);
3410
3411 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3412 struct blob_attr *tb_data[__XFRM_DATA_ATTR_MAX];
3413 uint32_t if_id = 0;
3414
3415 blobmsg_parse(xfrm_data_attr_list.params, __XFRM_DATA_ATTR_MAX, tb_data,
3416 blobmsg_data(cur), blobmsg_len(cur));
3417
3418 if ((cur = tb_data[XFRM_DATA_IF_ID])) {
3419 if ((if_id = blobmsg_get_u32(cur)))
3420 nla_put_u32(nlm, IFLA_XFRM_IF_ID, if_id);
3421 }
3422
3423 }
3424
3425 nla_nest_end(nlm, infodata);
3426 nla_nest_end(nlm, linkinfo);
3427
3428 return system_rtnl_call(nlm);
3429
3430 failure:
3431 nlmsg_free(nlm);
3432 return ret;
3433 }
3434 #endif
3435
3436 #ifdef IFLA_VXLAN_MAX
3437 static void system_vxlan_map_bool_attr(struct nl_msg *msg, struct blob_attr **tb_data, int attrtype, int vxlandatatype, bool invert) {
3438 struct blob_attr *cur;
3439 if ((cur = tb_data[vxlandatatype])) {
3440 bool val = blobmsg_get_bool(cur);
3441 if (invert)
3442 val = !val;
3443
3444 if ((attrtype == IFLA_VXLAN_GBP) && val)
3445 nla_put_flag(msg, attrtype);
3446 else
3447 nla_put_u8(msg, attrtype, val);
3448
3449 }
3450 }
3451
3452 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6)
3453 {
3454 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX];
3455 struct nl_msg *msg;
3456 struct nlattr *linkinfo, *data;
3457 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, };
3458 struct blob_attr *cur;
3459 int ret = 0;
3460
3461 if ((cur = tb[TUNNEL_ATTR_DATA]))
3462 blobmsg_parse(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, tb_data,
3463 blobmsg_data(cur), blobmsg_len(cur));
3464 else
3465 return -EINVAL;
3466
3467 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
3468
3469 if (!msg)
3470 return -1;
3471
3472 nlmsg_append(msg, &iim, sizeof(iim), 0);
3473
3474 nla_put_string(msg, IFLA_IFNAME, name);
3475
3476 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) {
3477 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur));
3478 if (!ea) {
3479 ret = -EINVAL;
3480 goto failure;
3481 }
3482
3483 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea);
3484 }
3485
3486 if ((cur = tb[TUNNEL_ATTR_MTU])) {
3487 uint32_t mtu = blobmsg_get_u32(cur);
3488 nla_put_u32(msg, IFLA_MTU, mtu);
3489 }
3490
3491 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) {
3492 ret = -ENOMEM;
3493 goto failure;
3494 }
3495
3496 nla_put_string(msg, IFLA_INFO_KIND, "vxlan");
3497
3498 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) {
3499 ret = -ENOMEM;
3500 goto failure;
3501 }
3502
3503 if (link)
3504 nla_put_u32(msg, IFLA_VXLAN_LINK, link);
3505
3506 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) {
3507 uint32_t id = blobmsg_get_u32(cur);
3508 if (id >= (1u << 24) - 1) {
3509 ret = -EINVAL;
3510 goto failure;
3511 }
3512
3513 nla_put_u32(msg, IFLA_VXLAN_ID, id);
3514 }
3515
3516 if (v6) {
3517 struct in6_addr in6buf;
3518 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3519 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3520 ret = -EINVAL;
3521 goto failure;
3522 }
3523 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf);
3524 }
3525
3526 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3527 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) {
3528 ret = -EINVAL;
3529 goto failure;
3530 }
3531 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf);
3532 }
3533 } else {
3534 struct in_addr inbuf;
3535
3536 if ((cur = tb[TUNNEL_ATTR_LOCAL])) {
3537 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3538 ret = -EINVAL;
3539 goto failure;
3540 }
3541 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf);
3542 }
3543
3544 if ((cur = tb[TUNNEL_ATTR_REMOTE])) {
3545 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) {
3546 ret = -EINVAL;
3547 goto failure;
3548 }
3549 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf);
3550 }
3551 }
3552
3553 uint32_t port = 4789;
3554 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) {
3555 port = blobmsg_get_u32(cur);
3556 if (port < 1 || port > 65535) {
3557 ret = -EINVAL;
3558 goto failure;
3559 }
3560 }
3561 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port));
3562
3563 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMIN])) {
3564 struct ifla_vxlan_port_range srcports = {0,0};
3565
3566 uint32_t low = blobmsg_get_u32(cur);
3567 if (low < 1 || low > 65535 - 1) {
3568 ret = -EINVAL;
3569 goto failure;
3570 }
3571
3572 srcports.low = htons((uint16_t) low);
3573 srcports.high = htons((uint16_t) (low+1));
3574
3575 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMAX])) {
3576 uint32_t high = blobmsg_get_u32(cur);
3577 if (high < 1 || high > 65535) {
3578 ret = -EINVAL;
3579 goto failure;
3580 }
3581
3582 if (high > low)
3583 srcports.high = htons((uint16_t) high);
3584 }
3585
3586 nla_put(msg, IFLA_VXLAN_PORT_RANGE, sizeof(srcports), &srcports);
3587 }
3588
3589 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_CSUM, VXLAN_DATA_ATTR_TXCSUM, false);
3590 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, VXLAN_DATA_ATTR_RXCSUM, true);
3591 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, VXLAN_DATA_ATTR_TXCSUM, true);
3592 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_LEARNING, VXLAN_DATA_ATTR_LEARNING, false);
3593 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_RSC , VXLAN_DATA_ATTR_RSC, false);
3594 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_PROXY , VXLAN_DATA_ATTR_PROXY, false);
3595 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L2MISS , VXLAN_DATA_ATTR_L2MISS, false);
3596 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L3MISS , VXLAN_DATA_ATTR_L3MISS, false);
3597 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_GBP , VXLAN_DATA_ATTR_GBP, false);
3598
3599 if ((cur = tb_data[VXLAN_DATA_ATTR_AGEING])) {
3600 uint32_t ageing = blobmsg_get_u32(cur);
3601 nla_put_u32(msg, IFLA_VXLAN_AGEING, ageing);
3602 }
3603
3604 if ((cur = tb_data[VXLAN_DATA_ATTR_LIMIT])) {
3605 uint32_t maxaddress = blobmsg_get_u32(cur);
3606 nla_put_u32(msg, IFLA_VXLAN_LIMIT, maxaddress);
3607 }
3608
3609 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3610 char *str = blobmsg_get_string(cur);
3611 unsigned tos = 1;
3612
3613 if (strcmp(str, "inherit")) {
3614 if (!system_tos_aton(str, &tos)) {
3615 ret = -EINVAL;
3616 goto failure;
3617 }
3618 }
3619
3620 nla_put_u8(msg, IFLA_VXLAN_TOS, tos);
3621 }
3622
3623 if ((cur = tb[TUNNEL_ATTR_TTL])) {
3624 uint32_t ttl = blobmsg_get_u32(cur);
3625 if (ttl < 1 || ttl > 255) {
3626 ret = -EINVAL;
3627 goto failure;
3628 }
3629
3630 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl);
3631 }
3632
3633 nla_nest_end(msg, data);
3634 nla_nest_end(msg, linkinfo);
3635
3636 ret = system_rtnl_call(msg);
3637 if (ret)
3638 D(SYSTEM, "Error adding vxlan '%s': %d\n", name, ret);
3639
3640 return ret;
3641
3642 failure:
3643 nlmsg_free(msg);
3644 return ret;
3645 }
3646 #endif
3647
3648 static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb)
3649 {
3650 struct blob_attr *cur;
3651 int ret = 0;
3652
3653 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
3654 return -1;
3655
3656 #ifdef SIOCADD6RD
3657 if ((cur = tb[TUNNEL_ATTR_DATA])) {
3658 struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX];
3659 unsigned int mask;
3660 struct ip_tunnel_6rd p6;
3661
3662 blobmsg_parse(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, tb_data,
3663 blobmsg_data(cur), blobmsg_len(cur));
3664
3665 memset(&p6, 0, sizeof(p6));
3666
3667 if ((cur = tb_data[SIXRD_DATA_PREFIX])) {
3668 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
3669 &p6.prefix, &mask) || mask > 128) {
3670 ret = -EINVAL;
3671 goto failure;
3672 }
3673
3674 p6.prefixlen = mask;
3675 }
3676
3677 if ((cur = tb_data[SIXRD_DATA_RELAY_PREFIX])) {
3678 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
3679 &p6.relay_prefix, &mask) || mask > 32) {
3680 ret = -EINVAL;
3681 goto failure;
3682 }
3683
3684 p6.relay_prefixlen = mask;
3685 }
3686
3687 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
3688 ret = -1;
3689 goto failure;
3690 }
3691 }
3692 #endif
3693
3694 return ret;
3695
3696 failure:
3697 __system_del_ip_tunnel(name, tb);
3698 return ret;
3699 }
3700
3701 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
3702 {
3703 struct blob_attr *cur;
3704 bool set_df = true;
3705 struct ip_tunnel_parm p = {
3706 .link = link,
3707 .iph = {
3708 .version = 4,
3709 .ihl = 5,
3710 .protocol = proto,
3711 }
3712 };
3713
3714 if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
3715 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
3716 return -EINVAL;
3717
3718 if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
3719 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
3720 return -EINVAL;
3721
3722 if ((cur = tb[TUNNEL_ATTR_DF]))
3723 set_df = blobmsg_get_bool(cur);
3724
3725 if ((cur = tb[TUNNEL_ATTR_TTL]))
3726 p.iph.ttl = blobmsg_get_u32(cur);
3727
3728 if ((cur = tb[TUNNEL_ATTR_TOS])) {
3729 char *str = blobmsg_get_string(cur);
3730 if (strcmp(str, "inherit")) {
3731 unsigned uval;
3732
3733 if (!system_tos_aton(str, &uval))
3734 return -EINVAL;
3735
3736 p.iph.tos = uval;
3737 } else
3738 p.iph.tos = 1;
3739 }
3740
3741 p.iph.frag_off = set_df ? htons(IP_DF) : 0;
3742 /* ttl !=0 and nopmtudisc are incompatible */
3743 if (p.iph.ttl && p.iph.frag_off == 0)
3744 return -EINVAL;
3745
3746 strncpy(p.name, name, sizeof(p.name) - 1);
3747
3748 switch (p.iph.protocol) {
3749 case IPPROTO_IPIP:
3750 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
3751 case IPPROTO_IPV6:
3752 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p);
3753 default:
3754 break;
3755 }
3756 return -1;
3757 }
3758
3759 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb)
3760 {
3761 struct blob_attr *cur;
3762 const char *str;
3763
3764 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
3765 return -EINVAL;
3766 str = blobmsg_data(cur);
3767
3768 if (!strcmp(str, "greip") || !strcmp(str, "gretapip") ||
3769 !strcmp(str, "greip6") || !strcmp(str, "gretapip6") ||
3770 !strcmp(str, "vtiip") || !strcmp(str, "vtiip6") ||
3771 !strcmp(str, "vxlan") || !strcmp(str, "vxlan6") ||
3772 !strcmp(str, "xfrm"))
3773 return system_link_del(name);
3774 else
3775 return tunnel_ioctl(name, SIOCDELTUNNEL, NULL);
3776 }
3777
3778 int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
3779 {
3780 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
3781
3782 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
3783 blob_data(attr), blob_len(attr));
3784
3785 return __system_del_ip_tunnel(name, tb);
3786 }
3787
3788 int system_update_ipv6_mtu(struct device *dev, int mtu)
3789 {
3790 int ret = -1;
3791 char buf[64];
3792 int fd;
3793
3794 fd = open(dev_sysctl_path("ipv6/conf", dev->ifname, "mtu"), O_RDWR);
3795 if (fd < 0)
3796 return ret;
3797
3798 if (!mtu) {
3799 ssize_t len = read(fd, buf, sizeof(buf) - 1);
3800 if (len < 0)
3801 goto out;
3802
3803 buf[len] = 0;
3804 ret = atoi(buf);
3805 } else {
3806 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0)
3807 ret = mtu;
3808 }
3809
3810 out:
3811 close(fd);
3812 return ret;
3813 }
3814
3815 int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
3816 {
3817 struct blob_attr *tb[__TUNNEL_ATTR_MAX];
3818 struct blob_attr *cur;
3819 const char *str;
3820
3821 blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
3822 blob_data(attr), blob_len(attr));
3823
3824 __system_del_ip_tunnel(name, tb);
3825
3826 if (!(cur = tb[TUNNEL_ATTR_TYPE]))
3827 return -EINVAL;
3828 str = blobmsg_data(cur);
3829
3830 unsigned int ttl = 0;
3831 if ((cur = tb[TUNNEL_ATTR_TTL])) {
3832 ttl = blobmsg_get_u32(cur);
3833 if (ttl > 255)
3834 return -EINVAL;
3835 }
3836
3837 unsigned int link = 0;
3838 if ((cur = tb[TUNNEL_ATTR_LINK])) {
3839 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
3840 if (!iface)
3841 return -EINVAL;
3842
3843 if (iface->l3_dev.dev)
3844 link = iface->l3_dev.dev->ifindex;
3845 }
3846
3847 if (!strcmp(str, "sit"))
3848 return system_add_sit_tunnel(name, link, tb);
3849 #ifdef IFLA_IPTUN_MAX
3850 else if (!strcmp(str, "ipip6")) {
3851 return system_add_ip6_tunnel(name, link, tb);
3852 } else if (!strcmp(str, "greip")) {
3853 return system_add_gre_tunnel(name, "gre", link, tb, false);
3854 } else if (!strcmp(str, "gretapip")) {
3855 return system_add_gre_tunnel(name, "gretap", link, tb, false);
3856 } else if (!strcmp(str, "greip6")) {
3857 return system_add_gre_tunnel(name, "ip6gre", link, tb, true);
3858 } else if (!strcmp(str, "gretapip6")) {
3859 return system_add_gre_tunnel(name, "ip6gretap", link, tb, true);
3860 #ifdef IFLA_VTI_MAX
3861 } else if (!strcmp(str, "vtiip")) {
3862 return system_add_vti_tunnel(name, "vti", link, tb, false);
3863 } else if (!strcmp(str, "vtiip6")) {
3864 return system_add_vti_tunnel(name, "vti6", link, tb, true);
3865 #endif
3866 #ifdef IFLA_XFRM_MAX
3867 } else if (!strcmp(str, "xfrm")) {
3868 return system_add_xfrm_tunnel(name, "xfrm", link, tb);
3869 #endif
3870 #ifdef IFLA_VXLAN_MAX
3871 } else if(!strcmp(str, "vxlan")) {
3872 return system_add_vxlan(name, link, tb, false);
3873 } else if(!strcmp(str, "vxlan6")) {
3874 return system_add_vxlan(name, link, tb, true);
3875 #endif
3876 #endif
3877 } else if (!strcmp(str, "ipip")) {
3878 return system_add_proto_tunnel(name, IPPROTO_IPIP, link, tb);
3879 }
3880 else
3881 return -EINVAL;
3882
3883 return 0;
3884 }