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