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