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