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