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