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