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 #define SYSTEM_IMPL 21 22 #include <sys/socket.h> 23 #include <sys/ioctl.h> 24 #include <sys/stat.h> 25 #include <sys/syscall.h> 26 27 #include <net/if.h> 28 #include <net/if_arp.h> 29 30 #include <limits.h> 31 #include <netdb.h> 32 #include <arpa/inet.h> 33 #include <netinet/in.h> 34 #include <netinet/ether.h> 35 36 #include <linux/rtnetlink.h> 37 #include <linux/neighbour.h> 38 #include <linux/sockios.h> 39 #include <linux/ip.h> 40 #include <linux/if_addr.h> 41 #include <linux/if_link.h> 42 #include <linux/if_vlan.h> 43 #include <linux/if_bridge.h> 44 #include <linux/if_tunnel.h> 45 #include <linux/ip6_tunnel.h> 46 #include <linux/ethtool.h> 47 #include <linux/fib_rules.h> 48 #include <linux/veth.h> 49 #include <linux/version.h> 50 51 #include <sched.h> 52 53 #include "ethtool-modes.h" 54 55 #ifndef RTN_FAILED_POLICY 56 #define RTN_FAILED_POLICY 12 57 #endif 58 59 #ifndef IFA_F_NOPREFIXROUTE 60 #define IFA_F_NOPREFIXROUTE 0x200 61 #endif 62 63 #ifndef IFA_FLAGS 64 #define IFA_FLAGS (IFA_MULTICAST + 1) 65 #endif 66 67 #include <string.h> 68 #include <fcntl.h> 69 #include <glob.h> 70 #include <time.h> 71 #include <unistd.h> 72 73 #include <netlink/msg.h> 74 #include <netlink/attr.h> 75 #include <netlink/socket.h> 76 #include <netlink/genl/genl.h> 77 #include <netlink/genl/ctrl.h> 78 #include <libubox/uloop.h> 79 80 #include <linux/ethtool_netlink.h> 81 82 #include "netifd.h" 83 #include "device.h" 84 #include "system.h" 85 #include "utils.h" 86 87 struct event_socket { 88 struct uloop_fd uloop; 89 struct nl_sock *sock; 90 int bufsize; 91 }; 92 93 static int sock_ioctl = -1; 94 static struct nl_sock *sock_rtnl = NULL; 95 static struct nl_sock *sock_genl = NULL; 96 static int ethtool_family = -1; 97 98 static int cb_rtnl_event(struct nl_msg *msg, void *arg); 99 static void handle_hotplug_event(struct uloop_fd *u, unsigned int events); 100 static int system_add_proto_tunnel(const char *name, const uint8_t proto, 101 const unsigned int link, struct blob_attr **tb); 102 103 static char dev_buf[256]; 104 static const char *proc_path = "/proc"; 105 static const char *sysfs_path = "/sys"; 106 107 struct netdev_type { 108 unsigned short id; 109 const char *name; 110 }; 111 112 static const struct netdev_type netdev_types[] = { 113 {ARPHRD_NETROM, "netrom"}, 114 {ARPHRD_ETHER, "ethernet"}, 115 {ARPHRD_EETHER, "eethernet"}, 116 {ARPHRD_AX25, "ax25"}, 117 {ARPHRD_PRONET, "pronet"}, 118 {ARPHRD_CHAOS, "chaos"}, 119 {ARPHRD_IEEE802, "ieee802"}, 120 {ARPHRD_ARCNET, "arcnet"}, 121 {ARPHRD_APPLETLK, "appletlk"}, 122 {ARPHRD_DLCI, "dlci"}, 123 {ARPHRD_ATM, "atm"}, 124 {ARPHRD_METRICOM, "metricom"}, 125 {ARPHRD_IEEE1394, "ieee1394"}, 126 {ARPHRD_EUI64, "eui64"}, 127 {ARPHRD_INFINIBAND, "infiniband"}, 128 {ARPHRD_SLIP, "slip"}, 129 {ARPHRD_CSLIP, "cslip"}, 130 {ARPHRD_SLIP6, "slip6"}, 131 {ARPHRD_CSLIP6, "cslip6"}, 132 {ARPHRD_RSRVD, "rsrvd"}, 133 {ARPHRD_ADAPT, "adapt"}, 134 {ARPHRD_ROSE, "rose"}, 135 {ARPHRD_X25, "x25"}, 136 {ARPHRD_HWX25, "hwx25"}, 137 {ARPHRD_PPP, "ppp"}, 138 {ARPHRD_CISCO, "cisco"}, 139 {ARPHRD_LAPB, "lapb"}, 140 {ARPHRD_DDCMP, "ddcmp"}, 141 {ARPHRD_RAWHDLC, "rawhdlc"}, 142 {ARPHRD_TUNNEL, "tunnel"}, 143 {ARPHRD_TUNNEL6, "tunnel6"}, 144 {ARPHRD_FRAD, "frad"}, 145 {ARPHRD_SKIP, "skip"}, 146 {ARPHRD_LOOPBACK, "loopback"}, 147 {ARPHRD_LOCALTLK, "localtlk"}, 148 {ARPHRD_FDDI, "fddi"}, 149 {ARPHRD_BIF, "bif"}, 150 {ARPHRD_SIT, "sit"}, 151 {ARPHRD_IPDDP, "ipddp"}, 152 {ARPHRD_IPGRE, "ipgre"}, 153 {ARPHRD_PIMREG,"pimreg"}, 154 {ARPHRD_HIPPI, "hippi"}, 155 {ARPHRD_ASH, "ash"}, 156 {ARPHRD_ECONET, "econet"}, 157 {ARPHRD_IRDA, "irda"}, 158 {ARPHRD_FCPP, "fcpp"}, 159 {ARPHRD_FCAL, "fcal"}, 160 {ARPHRD_FCPL, "fcpl"}, 161 {ARPHRD_FCFABRIC, "fcfabric"}, 162 {ARPHRD_IEEE80211, "ieee80211"}, 163 {ARPHRD_IEEE80211_PRISM, "ie80211-prism"}, 164 {ARPHRD_IEEE80211_RADIOTAP, "ieee80211-radiotap"}, 165 #ifdef ARPHRD_PHONET 166 {ARPHRD_PHONET, "phonet"}, 167 #endif 168 #ifdef ARPHRD_PHONET_PIPE 169 {ARPHRD_PHONET_PIPE, "phonet-pipe"}, 170 #endif 171 {ARPHRD_IEEE802154, "ieee802154"}, 172 {ARPHRD_VOID, "void"}, 173 {ARPHRD_NONE, "none"} 174 }; 175 176 static void 177 event_socket_drain(struct event_socket *ev) 178 { 179 char c; 180 int ret; 181 182 for (;;) { 183 /* the peek can return a new overrun, the queue is then full */ 184 if (recv(ev->uloop.fd, &c, sizeof(c), MSG_PEEK | MSG_DONTWAIT) < 0 && 185 errno != ENOBUFS) 186 return; 187 188 ret = nl_recvmsgs_default(ev->sock); 189 if (ret < 0 && ret != -NLE_NOMEM) 190 return; 191 } 192 } 193 194 static void 195 handler_nl_event(struct uloop_fd *u, unsigned int events) 196 { 197 struct event_socket *ev = container_of(u, struct event_socket, uloop); 198 int ret; 199 200 ret = nl_recvmsgs_default(ev->sock); 201 if (ret >= 0) 202 return; 203 204 switch (-ret) { 205 case NLE_NOMEM: 206 /* Increase rx buffer size on netlink socket */ 207 ev->bufsize *= 2; 208 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0)) 209 goto abort; 210 211 /* until the queue is empty, the kernel drops messages without 212 * reporting another overrun */ 213 event_socket_drain(ev); 214 215 /* Request full dump since some info got dropped */ 216 struct rtgenmsg msg = { .rtgen_family = AF_UNSPEC }; 217 nl_send_simple(ev->sock, RTM_GETLINK, NLM_F_DUMP, &msg, sizeof(msg)); 218 break; 219 220 default: 221 goto abort; 222 } 223 return; 224 225 abort: 226 uloop_fd_delete(&ev->uloop); 227 return; 228 } 229 230 static void 231 nl_udebug_cb(void *priv, struct nl_msg *msg) 232 { 233 struct nlmsghdr *nlh = nlmsg_hdr(msg); 234 235 udebug_netlink_msg(priv, nlmsg_get_proto(msg), nlh, nlh->nlmsg_len); 236 } 237 238 static struct nl_sock * 239 create_socket(int protocol, int groups) 240 { 241 struct nl_sock *sock; 242 243 sock = nl_socket_alloc(); 244 if (!sock) 245 return NULL; 246 247 if (groups) 248 nl_join_groups(sock, groups); 249 250 if (nl_connect(sock, protocol)) { 251 nl_socket_free(sock); 252 return NULL; 253 } 254 255 nl_socket_set_tx_debug_cb(sock, nl_udebug_cb, &udb_nl); 256 nl_socket_set_rx_debug_cb(sock, nl_udebug_cb, &udb_nl); 257 258 return sock; 259 } 260 261 static bool 262 create_raw_event_socket(struct event_socket *ev, int protocol, int groups, 263 uloop_fd_handler cb, int flags) 264 { 265 ev->sock = create_socket(protocol, groups); 266 if (!ev->sock) 267 return false; 268 269 ev->uloop.fd = nl_socket_get_fd(ev->sock); 270 ev->uloop.cb = cb; 271 if (uloop_fd_add(&ev->uloop, ULOOP_READ|flags)) 272 return false; 273 274 return true; 275 } 276 277 static bool 278 create_event_socket(struct event_socket *ev, int protocol, 279 int (*cb)(struct nl_msg *msg, void *arg)) 280 { 281 if (!create_raw_event_socket(ev, protocol, 0, handler_nl_event, ULOOP_ERROR_CB)) 282 return false; 283 284 /* Install the valid custom callback handler */ 285 nl_socket_modify_cb(ev->sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL); 286 287 /* Disable sequence number checking on event sockets */ 288 nl_socket_disable_seq_check(ev->sock); 289 290 /* Increase rx buffer size to 65K on event sockets */ 291 ev->bufsize = 65535; 292 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0)) 293 return false; 294 295 return true; 296 } 297 298 static bool 299 create_hotplug_event_socket(struct event_socket *ev, int protocol, 300 void (*cb)(struct uloop_fd *u, unsigned int events)) 301 { 302 if (!create_raw_event_socket(ev, protocol, 1, cb, ULOOP_ERROR_CB)) 303 return false; 304 305 /* Increase rx buffer size to 65K on event sockets */ 306 ev->bufsize = 65535; 307 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0)) 308 return false; 309 310 return true; 311 } 312 313 static bool 314 system_rtn_aton(const char *src, unsigned int *dst) 315 { 316 char *e; 317 unsigned int n; 318 319 if (!strcmp(src, "local")) 320 n = RTN_LOCAL; 321 else if (!strcmp(src, "nat")) 322 n = RTN_NAT; 323 else if (!strcmp(src, "broadcast")) 324 n = RTN_BROADCAST; 325 else if (!strcmp(src, "anycast")) 326 n = RTN_ANYCAST; 327 else if (!strcmp(src, "multicast")) 328 n = RTN_MULTICAST; 329 else if (!strcmp(src, "prohibit")) 330 n = RTN_PROHIBIT; 331 else if (!strcmp(src, "unreachable")) 332 n = RTN_UNREACHABLE; 333 else if (!strcmp(src, "blackhole")) 334 n = RTN_BLACKHOLE; 335 else if (!strcmp(src, "xresolve")) 336 n = RTN_XRESOLVE; 337 else if (!strcmp(src, "unicast")) 338 n = RTN_UNICAST; 339 else if (!strcmp(src, "throw")) 340 n = RTN_THROW; 341 else if (!strcmp(src, "failed_policy")) 342 n = RTN_FAILED_POLICY; 343 else { 344 n = strtoul(src, &e, 0); 345 if (!e || *e || e == src || n > 255) 346 return false; 347 } 348 349 *dst = n; 350 return true; 351 } 352 353 static bool 354 system_tos_aton(const char *src, unsigned *dst) 355 { 356 char *e; 357 358 *dst = strtoul(src, &e, 16); 359 if (e == src || *e || *dst > 255) 360 return false; 361 362 return true; 363 } 364 365 int system_init(void) 366 { 367 static struct event_socket rtnl_event; 368 static struct event_socket hotplug_event; 369 370 sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0); 371 system_fd_set_cloexec(sock_ioctl); 372 373 /* Prepare socket for routing / address control */ 374 sock_rtnl = create_socket(NETLINK_ROUTE, 0); 375 if (!sock_rtnl) 376 return -1; 377 378 /* Prepare genetlink socket for ethtool PSE control (optional) */ 379 sock_genl = nl_socket_alloc(); 380 if (sock_genl) { 381 if (genl_connect(sock_genl) == 0) { 382 ethtool_family = genl_ctrl_resolve(sock_genl, "ethtool"); 383 if (ethtool_family < 0) { 384 nl_socket_free(sock_genl); 385 sock_genl = NULL; 386 } 387 } else { 388 nl_socket_free(sock_genl); 389 sock_genl = NULL; 390 } 391 } 392 393 if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event)) 394 return -1; 395 396 if (!create_hotplug_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT, 397 handle_hotplug_event)) 398 return -1; 399 400 /* Receive network link events form kernel */ 401 nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK); 402 403 return 0; 404 } 405 406 static void write_file(const char *path, const char *val) 407 { 408 int fd; 409 410 fd = open(path, O_WRONLY); 411 if (fd < 0) 412 return; 413 414 if (write(fd, val, strlen(val))) {} 415 close(fd); 416 } 417 418 static int read_file(const char *path, char *buf, const size_t buf_sz) 419 { 420 int fd = -1, ret = -1; 421 422 fd = open(path, O_RDONLY); 423 if (fd < 0) 424 goto out; 425 426 ssize_t len = read(fd, buf, buf_sz - 1); 427 if (len < 0) 428 goto out; 429 430 ret = buf[len] = 0; 431 432 out: 433 if (fd >= 0) 434 close(fd); 435 436 return ret; 437 } 438 439 440 static const char * 441 dev_sysctl_path(const char *prefix, const char *ifname, const char *file) 442 { 443 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/%s/%s", proc_path, prefix, ifname, file); 444 445 return dev_buf; 446 } 447 448 static const char * 449 dev_sysfs_path(const char *ifname, const char *file) 450 { 451 snprintf(dev_buf, sizeof(dev_buf), "%s/class/net/%s/%s", sysfs_path, ifname, file); 452 453 return dev_buf; 454 } 455 456 static void 457 system_set_dev_sysctl(const char *prefix, const char *file, const char *ifname, 458 const char *val) 459 { 460 write_file(dev_sysctl_path(prefix, ifname, file), val); 461 } 462 463 static int 464 system_get_dev_sysctl(const char *prefix, const char *file, const char *ifname, 465 char *buf, size_t buf_sz) 466 { 467 return read_file(dev_sysctl_path(prefix, ifname, file), buf, buf_sz); 468 } 469 470 static void 471 system_set_dev_sysfs(const char *file, const char *ifname, const char *val) 472 { 473 if (!val) 474 return; 475 476 write_file(dev_sysfs_path(ifname, file), val); 477 } 478 479 static void 480 system_set_dev_sysfs_int(const char *file, const char *ifname, int val) 481 { 482 char buf[16]; 483 484 snprintf(buf, sizeof(buf), "%d", val); 485 system_set_dev_sysfs(file, ifname, buf); 486 } 487 488 static int 489 system_get_dev_sysfs(const char *file, const char *ifname, char *buf, size_t buf_sz) 490 { 491 return read_file(dev_sysfs_path(ifname, file), buf, buf_sz); 492 } 493 494 static void system_set_disable_ipv6(struct device *dev, const char *val) 495 { 496 system_set_dev_sysctl("ipv6/conf", "disable_ipv6", dev->ifname, val); 497 } 498 499 static void system_set_ip6segmentrouting(struct device *dev, const char *val) 500 { 501 system_set_dev_sysctl("ipv6/conf", "seg6_enabled", dev->ifname, val); 502 } 503 504 static void system_set_rpfilter(struct device *dev, const char *val) 505 { 506 system_set_dev_sysctl("ipv4/conf", "rp_filter", dev->ifname, val); 507 } 508 509 static void system_set_acceptlocal(struct device *dev, const char *val) 510 { 511 system_set_dev_sysctl("ipv4/conf", "accept_local", dev->ifname, val); 512 } 513 514 static void system_set_igmpversion(struct device *dev, const char *val) 515 { 516 system_set_dev_sysctl("ipv4/conf", "force_igmp_version", dev->ifname, val); 517 } 518 519 static void system_set_mldversion(struct device *dev, const char *val) 520 { 521 system_set_dev_sysctl("ipv6/conf", "force_mld_version", dev->ifname, val); 522 } 523 524 static void system_set_neigh4reachabletime(struct device *dev, const char *val) 525 { 526 system_set_dev_sysctl("ipv4/neigh", "base_reachable_time_ms", dev->ifname, val); 527 } 528 529 static void system_set_neigh6reachabletime(struct device *dev, const char *val) 530 { 531 system_set_dev_sysctl("ipv6/neigh", "base_reachable_time_ms", dev->ifname, val); 532 } 533 534 static void system_set_neigh4gcstaletime(struct device *dev, const char *val) 535 { 536 system_set_dev_sysctl("ipv4/neigh", "gc_stale_time", dev->ifname, val); 537 } 538 539 static void system_set_neigh6gcstaletime(struct device *dev, const char *val) 540 { 541 system_set_dev_sysctl("ipv6/neigh", "gc_stale_time", dev->ifname, val); 542 } 543 544 static void system_set_neigh4locktime(struct device *dev, const char *val) 545 { 546 system_set_dev_sysctl("ipv4/neigh", "locktime", dev->ifname, val); 547 } 548 549 static void system_set_dadtransmits(struct device *dev, const char *val) 550 { 551 system_set_dev_sysctl("ipv6/conf", "dad_transmits", dev->ifname, val); 552 } 553 554 static void system_set_rtrsolicits(struct device *dev, const char *val) 555 { 556 system_set_dev_sysctl("ipv6/conf", "router_solicitations", dev->ifname, val); 557 } 558 559 static void system_set_rtrsolicitinterval(struct device *dev, const char *val) 560 { 561 system_set_dev_sysctl("ipv6/conf", "router_solicitation_interval", dev->ifname, val); 562 } 563 564 static void system_set_neigh6retranstime(struct device *dev, const char *val) 565 { 566 system_set_dev_sysctl("ipv6/neigh", "retrans_time_ms", dev->ifname, val); 567 } 568 569 static void system_set_neigh4retranstime(struct device *dev, const char *val) 570 { 571 system_set_dev_sysctl("ipv4/neigh", "retrans_time_ms", dev->ifname, val); 572 } 573 574 static void system_set_neigh4mcastsolicit(struct device *dev, const char *val) 575 { 576 system_set_dev_sysctl("ipv4/neigh", "mcast_solicit", dev->ifname, val); 577 } 578 579 static void system_set_proxy_arp(struct device *dev, const char *val) 580 { 581 system_set_dev_sysctl("ipv4/conf", "proxy_arp", dev->ifname, val); 582 } 583 584 static void system_set_sendredirects(struct device *dev, const char *val) 585 { 586 system_set_dev_sysctl("ipv4/conf", "send_redirects", dev->ifname, val); 587 } 588 589 static void system_set_drop_v4_unicast_in_l2_multicast(struct device *dev, const char *val) 590 { 591 system_set_dev_sysctl("ipv4/conf", "drop_unicast_in_l2_multicast", dev->ifname, val); 592 } 593 594 static void system_set_drop_v6_unicast_in_l2_multicast(struct device *dev, const char *val) 595 { 596 system_set_dev_sysctl("ipv6/conf", "drop_unicast_in_l2_multicast", dev->ifname, val); 597 } 598 599 static void system_set_drop_gratuitous_arp(struct device *dev, const char *val) 600 { 601 system_set_dev_sysctl("ipv4/conf", "drop_gratuitous_arp", dev->ifname, val); 602 } 603 604 static void system_set_drop_unsolicited_na(struct device *dev, const char *val) 605 { 606 system_set_dev_sysctl("ipv6/conf", "drop_unsolicited_na", dev->ifname, val); 607 } 608 609 static void system_set_arp_accept(struct device *dev, const char *val) 610 { 611 system_set_dev_sysctl("ipv4/conf", "arp_accept", dev->ifname, val); 612 } 613 614 static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val) 615 { 616 system_set_dev_sysfs("brport/multicast_to_unicast", dev->ifname, val); 617 } 618 619 static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val) 620 { 621 system_set_dev_sysfs("brport/multicast_fast_leave", dev->ifname, val); 622 } 623 624 static void system_bridge_set_hairpin_mode(struct device *dev, const char *val) 625 { 626 system_set_dev_sysfs("brport/hairpin_mode", dev->ifname, val); 627 } 628 629 static void system_bridge_set_proxyarp_wifi(struct device *dev, const char *val) 630 { 631 system_set_dev_sysfs("brport/proxyarp_wifi", dev->ifname, val); 632 } 633 634 static void system_bridge_set_bpdu_filter(struct device *dev, const char *val) 635 { 636 system_set_dev_sysfs("brport/bpdu_filter", dev->ifname, val); 637 } 638 639 static void system_bridge_set_isolated(struct device *dev, const char *val) 640 { 641 system_set_dev_sysfs("brport/isolated", dev->ifname, val); 642 } 643 644 static void system_bridge_set_multicast_router(struct device *dev, const char *val) 645 { 646 system_set_dev_sysfs("brport/multicast_router", dev->ifname, val); 647 } 648 649 void system_bridge_set_stp_state(struct device *dev, bool val) 650 { 651 const char *valstr = val ? "1" : ""; 652 653 system_set_dev_sysfs("bridge/stp_state", dev->ifname, valstr); 654 } 655 656 static void system_bridge_set_learning(struct device *dev, const char *val) 657 { 658 system_set_dev_sysfs("brport/learning", dev->ifname, val); 659 } 660 661 static void system_bridge_set_unicast_flood(struct device *dev, const char *val) 662 { 663 system_set_dev_sysfs("brport/unicast_flood", dev->ifname, val); 664 } 665 666 static void system_bridge_set_broadcast_flood(struct device *dev, const char *val) 667 { 668 system_set_dev_sysfs("brport/broadcast_flood", dev->ifname, val); 669 } 670 671 static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz) 672 { 673 return system_get_dev_sysctl("ipv6/conf", "disable_ipv6", 674 dev->ifname, buf, buf_sz); 675 } 676 677 static int system_get_ip6segmentrouting(struct device *dev, char *buf, const size_t buf_sz) 678 { 679 return system_get_dev_sysctl("ipv6/conf", "seg6_enabled", 680 dev->ifname, buf, buf_sz); 681 } 682 683 static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz) 684 { 685 return system_get_dev_sysctl("ipv4/conf", "rp_filter", 686 dev->ifname, buf, buf_sz); 687 } 688 689 static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz) 690 { 691 return system_get_dev_sysctl("ipv4/conf", "accept_local", 692 dev->ifname, buf, buf_sz); 693 } 694 695 static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz) 696 { 697 return system_get_dev_sysctl("ipv4/conf", "force_igmp_version", 698 dev->ifname, buf, buf_sz); 699 } 700 701 static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz) 702 { 703 return system_get_dev_sysctl("ipv6/conf", "force_mld_version", 704 dev->ifname, buf, buf_sz); 705 } 706 707 static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz) 708 { 709 return system_get_dev_sysctl("ipv4/neigh", "base_reachable_time_ms", 710 dev->ifname, buf, buf_sz); 711 } 712 713 static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz) 714 { 715 return system_get_dev_sysctl("ipv6/neigh", "base_reachable_time_ms", 716 dev->ifname, buf, buf_sz); 717 } 718 719 static int system_get_neigh4gcstaletime(struct device *dev, char *buf, const size_t buf_sz) 720 { 721 return system_get_dev_sysctl("ipv4/neigh", "gc_stale_time", 722 dev->ifname, buf, buf_sz); 723 } 724 725 static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const size_t buf_sz) 726 { 727 return system_get_dev_sysctl("ipv6/neigh", "gc_stale_time", 728 dev->ifname, buf, buf_sz); 729 } 730 731 static int system_get_neigh4locktime(struct device *dev, char *buf, const size_t buf_sz) 732 { 733 return system_get_dev_sysctl("ipv4/neigh", "locktime", 734 dev->ifname, buf, buf_sz); 735 } 736 737 static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz) 738 { 739 return system_get_dev_sysctl("ipv6/conf", "dad_transmits", 740 dev->ifname, buf, buf_sz); 741 } 742 743 static int system_get_rtrsolicits(struct device *dev, char *buf, const size_t buf_sz) 744 { 745 return system_get_dev_sysctl("ipv6/conf", "router_solicitations", 746 dev->ifname, buf, buf_sz); 747 } 748 749 static int system_get_rtrsolicitinterval(struct device *dev, char *buf, const size_t buf_sz) 750 { 751 return system_get_dev_sysctl("ipv6/conf", "router_solicitation_interval", 752 dev->ifname, buf, buf_sz); 753 } 754 755 static int system_get_neigh6retranstime(struct device *dev, char *buf, const size_t buf_sz) 756 { 757 return system_get_dev_sysctl("ipv6/neigh", "retrans_time_ms", 758 dev->ifname, buf, buf_sz); 759 } 760 761 static int system_get_neigh4retranstime(struct device *dev, char *buf, const size_t buf_sz) 762 { 763 return system_get_dev_sysctl("ipv4/neigh", "retrans_time_ms", 764 dev->ifname, buf, buf_sz); 765 } 766 767 static int system_get_neigh4mcastsolicit(struct device *dev, char *buf, const size_t buf_sz) 768 { 769 return system_get_dev_sysctl("ipv4/neigh", "mcast_solicit", 770 dev->ifname, buf, buf_sz); 771 } 772 773 static int system_get_proxy_arp(struct device *dev, char *buf, const size_t buf_sz) 774 { 775 return system_get_dev_sysctl("ipv4/conf", "proxy_arp", 776 dev->ifname, buf, buf_sz); 777 } 778 779 static int system_get_sendredirects(struct device *dev, char *buf, const size_t buf_sz) 780 { 781 return system_get_dev_sysctl("ipv4/conf", "send_redirects", 782 dev->ifname, buf, buf_sz); 783 } 784 785 786 static int system_get_drop_v4_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz) 787 { 788 return system_get_dev_sysctl("ipv4/conf", "drop_unicast_in_l2_multicast", 789 dev->ifname, buf, buf_sz); 790 } 791 792 static int system_get_drop_v6_unicast_in_l2_multicast(struct device *dev, char *buf, const size_t buf_sz) 793 { 794 return system_get_dev_sysctl("ipv6/conf", "drop_unicast_in_l2_multicast", 795 dev->ifname, buf, buf_sz); 796 } 797 798 static int system_get_drop_gratuitous_arp(struct device *dev, char *buf, const size_t buf_sz) 799 { 800 return system_get_dev_sysctl("ipv4/conf", "drop_gratuitous_arp", 801 dev->ifname, buf, buf_sz); 802 } 803 804 static int system_get_drop_unsolicited_na(struct device *dev, char *buf, const size_t buf_sz) 805 { 806 return system_get_dev_sysctl("ipv6/conf", "drop_unsolicited_na", 807 dev->ifname, buf, buf_sz); 808 } 809 810 static int system_get_arp_accept(struct device *dev, char *buf, const size_t buf_sz) 811 { 812 return system_get_dev_sysctl("ipv4/conf", "arp_accept", 813 dev->ifname, buf, buf_sz); 814 } 815 816 static int 817 system_device_ifreq(struct ifreq *ifr, const char *ifname, int cmd) 818 { 819 memset(ifr, 0, sizeof(*ifr)); 820 strncpy(ifr->ifr_name, ifname, sizeof(ifr->ifr_name) - 1); 821 return ioctl(sock_ioctl, cmd, ifr); 822 } 823 824 #ifndef IFF_LOWER_UP 825 #define IFF_LOWER_UP 0x10000 826 #endif 827 828 static void 829 system_device_update_state(struct device *dev, unsigned int flags) 830 { 831 unsigned int ifindex = system_if_resolve(dev); 832 833 if (dev->type == &simple_device_type) { 834 if (dev->external) 835 device_set_disabled(dev, !(flags & IFF_UP)); 836 837 device_set_present(dev, ifindex > 0); 838 } 839 device_set_link(dev, flags & IFF_LOWER_UP ? true : false); 840 } 841 842 /* Evaluate netlink messages */ 843 static int cb_rtnl_event(struct nl_msg *msg, void *arg) 844 { 845 struct nlmsghdr *nh = nlmsg_hdr(msg); 846 struct ifinfomsg *ifi = NLMSG_DATA(nh); 847 struct nlattr *nla[__IFLA_MAX]; 848 struct device *dev; 849 unsigned int flags; 850 851 if (nh->nlmsg_type != RTM_NEWLINK && nh->nlmsg_type != RTM_DELLINK) 852 return 0; 853 854 if (ifi->ifi_family != AF_UNSPEC) 855 return 0; 856 857 if (nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL)) 858 return 0; 859 860 if (!nla[IFLA_IFNAME]) 861 return 0; 862 863 dev = device_find(nla_data(nla[IFLA_IFNAME])); 864 if (!dev) 865 return 0; 866 867 flags = (nh->nlmsg_type == RTM_DELLINK) ? 0 : ifi->ifi_flags; 868 869 /* 870 * A queued event can be earlier than netifd's last read of the state, 871 * so read the state again and use the event only as a trigger. The 872 * event flags apply only to a link that is gone, which has no flags 873 * to read, and when the read applies no state. 874 */ 875 if ((nh->nlmsg_type == RTM_DELLINK && !system_if_resolve(dev)) || 876 system_if_check(dev) > 0) 877 system_device_update_state(dev, flags); 878 879 return 0; 880 } 881 882 static void 883 handle_hotplug_msg(char *data, int size) 884 { 885 const char *subsystem = NULL, *interface = NULL, *interface_old = NULL; 886 char *cur, *end, *sep; 887 int skip; 888 bool add; 889 890 if (!strncmp(data, "add@", 4) || !strncmp(data, "move@", 5)) 891 add = true; 892 else if (!strncmp(data, "remove@", 7)) 893 add = false; 894 else 895 return; 896 897 skip = strlen(data) + 1; 898 end = data + size; 899 900 for (cur = data + skip; cur < end; cur += skip) { 901 skip = strlen(cur) + 1; 902 903 sep = strchr(cur, '='); 904 if (!sep) 905 continue; 906 907 *sep = 0; 908 if (!strcmp(cur, "INTERFACE")) 909 interface = sep + 1; 910 else if (!strcmp(cur, "SUBSYSTEM")) { 911 subsystem = sep + 1; 912 if (strcmp(subsystem, "net") != 0) 913 return; 914 } else if (!strcmp(cur, "DEVPATH_OLD")) { 915 interface_old = strrchr(sep + 1, '/'); 916 if (interface_old) 917 interface_old++; 918 } 919 } 920 921 if (!subsystem || !interface) 922 return; 923 924 if (interface_old) 925 device_hotplug_event(interface_old, false); 926 927 device_hotplug_event(interface, add); 928 } 929 930 static void 931 handle_hotplug_event(struct uloop_fd *u, unsigned int events) 932 { 933 struct event_socket *ev = container_of(u, struct event_socket, uloop); 934 struct sockaddr_nl nla; 935 unsigned char *buf = NULL; 936 int size; 937 938 while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) { 939 if (nla.nl_pid == 0) 940 handle_hotplug_msg((char *) buf, size); 941 942 free(buf); 943 } 944 945 switch (-size) { 946 case 0: 947 return; 948 949 case NLE_NOMEM: 950 /* Increase rx buffer size on netlink socket */ 951 ev->bufsize *= 2; 952 if (nl_socket_set_buffer_size(ev->sock, ev->bufsize, 0)) 953 goto abort; 954 break; 955 956 default: 957 goto abort; 958 } 959 return; 960 961 abort: 962 uloop_fd_delete(&ev->uloop); 963 return; 964 } 965 966 static int system_rtnl_call(struct nl_msg *msg) 967 { 968 int ret; 969 970 ret = nl_send_auto_complete(sock_rtnl, msg); 971 nlmsg_free(msg); 972 973 if (ret < 0) 974 return ret; 975 976 return nl_wait_for_ack(sock_rtnl); 977 } 978 979 static struct nl_msg *__system_ifinfo_msg(int af, int index, const char *ifname, uint16_t type, uint16_t flags) 980 { 981 struct nl_msg *msg; 982 struct ifinfomsg iim = { 983 .ifi_family = af, 984 .ifi_index = index, 985 }; 986 987 msg = nlmsg_alloc_simple(type, flags | NLM_F_REQUEST); 988 if (!msg) 989 return NULL; 990 991 nlmsg_append(msg, &iim, sizeof(iim), 0); 992 if (ifname) 993 nla_put_string(msg, IFLA_IFNAME, ifname); 994 995 return msg; 996 } 997 998 static struct nl_msg *system_ifinfo_msg(const char *ifname, uint16_t type, uint16_t flags) 999 { 1000 return __system_ifinfo_msg(AF_UNSPEC, 0, ifname, type, flags); 1001 } 1002 1003 static int system_link_del(const char *ifname) 1004 { 1005 struct nl_msg *msg; 1006 1007 msg = system_ifinfo_msg(ifname, RTM_DELLINK, 0); 1008 if (!msg) 1009 return -1; 1010 1011 return system_rtnl_call(msg); 1012 } 1013 1014 int system_bridge_delbr(struct device *bridge) 1015 { 1016 return system_link_del(bridge->ifname); 1017 } 1018 1019 static int system_bridge_if(const char *bridge, struct device *dev, int cmd, void *data) 1020 { 1021 struct ifreq ifr; 1022 1023 memset(&ifr, 0, sizeof(ifr)); 1024 if (dev) 1025 ifr.ifr_ifindex = dev->ifindex; 1026 else 1027 ifr.ifr_data = data; 1028 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1); 1029 return ioctl(sock_ioctl, cmd, &ifr); 1030 } 1031 1032 static bool system_is_bridge(const char *name) 1033 { 1034 struct stat st; 1035 1036 return stat(dev_sysfs_path(name, "bridge"), &st) >= 0; 1037 } 1038 1039 static char *system_get_bridge(const char *name, char *buf, int buflen) 1040 { 1041 char *path; 1042 ssize_t len = -1; 1043 glob_t gl; 1044 1045 snprintf(buf, buflen, "%s/devices/virtual/net/*/brif/%s/bridge", sysfs_path, name); 1046 if (glob(buf, GLOB_NOSORT, NULL, &gl) < 0) 1047 return NULL; 1048 1049 if (gl.gl_pathc > 0) 1050 len = readlink(gl.gl_pathv[0], buf, buflen); 1051 1052 globfree(&gl); 1053 1054 if (len < 0) 1055 return NULL; 1056 1057 buf[len] = 0; 1058 path = strrchr(buf, '/'); 1059 if (!path) 1060 return NULL; 1061 1062 return path + 1; 1063 } 1064 1065 static void 1066 system_bridge_set_wireless(struct device *bridge, struct device *dev) 1067 { 1068 bool mcast_to_ucast = dev->wireless_ap; 1069 bool hairpin; 1070 1071 if (dev->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST) 1072 mcast_to_ucast = dev->settings.multicast_to_unicast; 1073 else if (bridge->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST && 1074 !bridge->settings.multicast_to_unicast) 1075 mcast_to_ucast = false; 1076 1077 hairpin = mcast_to_ucast || dev->wireless_proxyarp; 1078 if (dev->wireless_isolate) 1079 hairpin = false; 1080 1081 system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : ""); 1082 system_bridge_set_hairpin_mode(dev, hairpin ? "1" : ""); 1083 system_bridge_set_proxyarp_wifi(dev, dev->wireless_proxyarp ? "1" : ""); 1084 } 1085 1086 int system_bridge_addif(struct device *bridge, struct device *dev) 1087 { 1088 char buf[64]; 1089 char *oldbr; 1090 int tries = 0; 1091 int ret; 1092 1093 1094 for (tries = 0; tries < 3; tries++) { 1095 ret = 0; 1096 oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf)); 1097 if (oldbr) { 1098 if (!strcmp(oldbr, bridge->ifname)) 1099 break; 1100 1101 /* still enslaved in a stale bridge; detach first to avoid EBUSY */ 1102 system_bridge_if(oldbr, dev, SIOCBRDELIF, NULL); 1103 } 1104 1105 ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL); 1106 if (!ret) 1107 break; 1108 1109 D(SYSTEM, "Failed to add device '%s' to bridge '%s' (tries=%d): %s", 1110 dev->ifname, bridge->ifname, tries, strerror(errno)); 1111 } 1112 1113 if (dev->wireless) 1114 system_bridge_set_wireless(bridge, dev); 1115 1116 if (dev->settings.flags & DEV_OPT_MULTICAST_ROUTER) { 1117 snprintf(buf, sizeof(buf), "%u", dev->settings.multicast_router); 1118 system_bridge_set_multicast_router(dev, buf); 1119 } 1120 1121 if (dev->settings.flags & DEV_OPT_MULTICAST_FAST_LEAVE && 1122 dev->settings.multicast_fast_leave) 1123 system_bridge_set_multicast_fast_leave(dev, "1"); 1124 1125 if (dev->settings.flags & DEV_OPT_LEARNING && 1126 !dev->settings.learning) 1127 system_bridge_set_learning(dev, ""); 1128 1129 if (dev->settings.flags & DEV_OPT_UNICAST_FLOOD && 1130 !dev->settings.unicast_flood) 1131 system_bridge_set_unicast_flood(dev, ""); 1132 1133 if (dev->settings.flags & DEV_OPT_BROADCAST_FLOOD && 1134 !dev->settings.broadcast_flood) 1135 system_bridge_set_broadcast_flood(dev, ""); 1136 1137 if (dev->settings.flags & DEV_OPT_ISOLATE && 1138 dev->settings.isolate) 1139 system_bridge_set_isolated(dev, "1"); 1140 1141 if (dev->bpdu_filter) 1142 system_bridge_set_bpdu_filter(dev, dev->bpdu_filter ? "1" : ""); 1143 1144 return ret; 1145 } 1146 1147 int system_bridge_delif(struct device *bridge, struct device *dev) 1148 { 1149 return system_bridge_if(bridge->ifname, dev, SIOCBRDELIF, NULL); 1150 } 1151 1152 int system_bridge_vlan(const char *iface, uint16_t vid, int16_t vid_end, bool add, unsigned int vflags) 1153 { 1154 struct bridge_vlan_info vinfo = { .vid = vid, }; 1155 unsigned short flags = 0; 1156 struct nlattr *afspec; 1157 struct nl_msg *nlm; 1158 int index; 1159 int ret = 0; 1160 1161 index = if_nametoindex(iface); 1162 if (!index) 1163 return -1; 1164 1165 nlm = __system_ifinfo_msg(PF_BRIDGE, index, NULL, add ? RTM_SETLINK : RTM_DELLINK, 0); 1166 if (!nlm) 1167 return -1; 1168 1169 if (vflags & BRVLAN_F_SELF) 1170 flags |= BRIDGE_FLAGS_SELF; 1171 1172 if (vflags & BRVLAN_F_PVID) 1173 vinfo.flags |= BRIDGE_VLAN_INFO_PVID; 1174 1175 if (vflags & BRVLAN_F_UNTAGGED) 1176 vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; 1177 1178 afspec = nla_nest_start(nlm, IFLA_AF_SPEC); 1179 if (!afspec) { 1180 ret = -ENOMEM; 1181 goto failure; 1182 } 1183 1184 if (flags) 1185 nla_put_u16(nlm, IFLA_BRIDGE_FLAGS, flags); 1186 1187 if (vid_end > vid) 1188 vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN; 1189 1190 nla_put(nlm, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo); 1191 1192 if (vid_end > vid) { 1193 vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN; 1194 vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END; 1195 vinfo.vid = vid_end; 1196 nla_put(nlm, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo); 1197 } 1198 1199 nla_nest_end(nlm, afspec); 1200 1201 return system_rtnl_call(nlm); 1202 1203 failure: 1204 nlmsg_free(nlm); 1205 return ret; 1206 } 1207 1208 /* The bridge and each VLAN context take the same multicast settings, under 1209 * different netlink attributes. */ 1210 struct bridge_mcast_attrs { 1211 int startup_query_cnt; 1212 int last_member_cnt; 1213 int query_intvl; 1214 int query_response_intvl; 1215 int last_member_intvl; 1216 int membership_intvl; 1217 int querier_intvl; 1218 int startup_query_intvl; 1219 int igmp_version; 1220 int mld_version; 1221 }; 1222 1223 static const struct bridge_mcast_attrs bridge_mcast_link_attrs = { 1224 .startup_query_cnt = IFLA_BR_MCAST_STARTUP_QUERY_CNT, 1225 .last_member_cnt = IFLA_BR_MCAST_LAST_MEMBER_CNT, 1226 .query_intvl = IFLA_BR_MCAST_QUERY_INTVL, 1227 .query_response_intvl = IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, 1228 .last_member_intvl = IFLA_BR_MCAST_LAST_MEMBER_INTVL, 1229 .membership_intvl = IFLA_BR_MCAST_MEMBERSHIP_INTVL, 1230 .querier_intvl = IFLA_BR_MCAST_QUERIER_INTVL, 1231 .startup_query_intvl = IFLA_BR_MCAST_STARTUP_QUERY_INTVL, 1232 .igmp_version = IFLA_BR_MCAST_IGMP_VERSION, 1233 .mld_version = IFLA_BR_MCAST_MLD_VERSION, 1234 }; 1235 1236 static const struct bridge_mcast_attrs bridge_mcast_vlan_attrs = { 1237 .startup_query_cnt = BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT, 1238 .last_member_cnt = BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT, 1239 .query_intvl = BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL, 1240 .query_response_intvl = BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL, 1241 .last_member_intvl = BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL, 1242 .membership_intvl = BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL, 1243 .querier_intvl = BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL, 1244 .startup_query_intvl = BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL, 1245 .igmp_version = BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION, 1246 .mld_version = BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION, 1247 }; 1248 1249 static void system_bridge_mcast_put(struct nl_msg *msg, const struct bridge_config *cfg, 1250 const struct bridge_mcast_attrs *attrs) 1251 { 1252 uint64_t val; 1253 1254 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS) { 1255 nla_put_u32(msg, attrs->startup_query_cnt, cfg->robustness); 1256 nla_put_u32(msg, attrs->last_member_cnt, cfg->robustness); 1257 } 1258 1259 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) 1260 nla_put_u64(msg, attrs->query_intvl, cfg->query_interval); 1261 1262 if (cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) 1263 nla_put_u64(msg, attrs->query_response_intvl, cfg->query_response_interval); 1264 1265 if (cfg->flags & BRIDGE_OPT_LAST_MEMBER_INTERVAL) 1266 nla_put_u64(msg, attrs->last_member_intvl, cfg->last_member_interval); 1267 1268 if (cfg->flags & BRIDGE_OPT_ROBUSTNESS || 1269 cfg->flags & BRIDGE_OPT_QUERY_INTERVAL || 1270 cfg->flags & BRIDGE_OPT_QUERY_RESPONSE_INTERVAL) { 1271 val = cfg->robustness * cfg->query_interval + 1272 cfg->query_response_interval; 1273 1274 nla_put_u64(msg, attrs->membership_intvl, val); 1275 1276 val -= cfg->query_response_interval / 2; 1277 1278 nla_put_u64(msg, attrs->querier_intvl, val); 1279 } 1280 1281 if (cfg->flags & BRIDGE_OPT_QUERY_INTERVAL) { 1282 val = cfg->query_interval / 4; 1283 1284 nla_put_u64(msg, attrs->startup_query_intvl, val); 1285 } 1286 1287 if (cfg->flags & BRIDGE_OPT_SNOOP_IGMP_VERSION) 1288 nla_put_u8(msg, attrs->igmp_version, cfg->snoop_igmp_version); 1289 1290 if (cfg->flags & BRIDGE_OPT_SNOOP_MLD_VERSION) 1291 nla_put_u8(msg, attrs->mld_version, cfg->snoop_mld_version); 1292 } 1293 1294 int system_bridge_vlan_mcast(const char *iface, uint16_t vid, const struct bridge_config *cfg, 1295 bool snooping, bool querier) 1296 { 1297 struct br_vlan_msg bvm = { .family = AF_BRIDGE, }; 1298 struct nlattr *opts; 1299 struct nl_msg *nlm; 1300 int ret; 1301 1302 bvm.ifindex = if_nametoindex(iface); 1303 if (!bvm.ifindex) 1304 return -1; 1305 1306 nlm = nlmsg_alloc_simple(RTM_NEWVLAN, NLM_F_REQUEST); 1307 if (!nlm) 1308 return -1; 1309 1310 nlmsg_append(nlm, &bvm, sizeof(bvm), 0); 1311 1312 opts = nla_nest_start(nlm, BRIDGE_VLANDB_GLOBAL_OPTIONS); 1313 if (!opts) { 1314 nlmsg_free(nlm); 1315 return -ENOMEM; 1316 } 1317 1318 nla_put_u16(nlm, BRIDGE_VLANDB_GOPTS_ID, vid); 1319 nla_put_u8(nlm, BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, snooping); 1320 nla_put_u8(nlm, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, querier); 1321 system_bridge_mcast_put(nlm, cfg, &bridge_mcast_vlan_attrs); 1322 1323 nla_nest_end(nlm, opts); 1324 1325 ret = system_rtnl_call(nlm); 1326 if (ret) 1327 D(SYSTEM, "Error setting multicast options of VLAN %d on '%s': %d", 1328 vid, iface, ret); 1329 1330 return ret; 1331 } 1332 1333 int system_vrf_addvrf(struct device *vrf, unsigned int table) 1334 { 1335 struct nlattr *linkinfo, *data; 1336 struct nl_msg *msg; 1337 int rv; 1338 1339 msg = system_ifinfo_msg(vrf->ifname, RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL); 1340 if (!msg) 1341 return -1; 1342 1343 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) 1344 goto nla_put_failure; 1345 1346 nla_put_string(msg, IFLA_INFO_KIND, "vrf"); 1347 1348 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) 1349 goto nla_put_failure; 1350 1351 nla_put_u32(msg, IFLA_VRF_TABLE, table); 1352 1353 nla_nest_end(msg, data); 1354 nla_nest_end(msg, linkinfo); 1355 1356 rv = system_rtnl_call(msg); 1357 if (rv) 1358 D(SYSTEM, "Error adding vrf '%s': %d\n", vrf->ifname, rv); 1359 1360 return rv; 1361 1362 nla_put_failure: 1363 nlmsg_free(msg); 1364 return -ENOMEM; 1365 } 1366 1367 int system_vrf_delvrf(struct device *vrf) 1368 { 1369 return system_link_del(vrf->ifname); 1370 } 1371 1372 static char *system_get_vrf(const char *name, char *buf, int buflen) 1373 { 1374 char master[PATH_MAX]; 1375 char *path; 1376 ssize_t len = -1; 1377 1378 if (snprintf(master, sizeof(master), "%s/devices/virtual/net/%s/master", sysfs_path, name) <= 0) 1379 return NULL; 1380 1381 len = readlink(master, buf, buflen); 1382 if (len < 0) 1383 return NULL; 1384 1385 buf[len] = 0; 1386 path = strrchr(buf, '/'); 1387 if (!path) 1388 return NULL; 1389 1390 return path + 1; 1391 } 1392 1393 static int 1394 system_vrf_if(int vrf_index, struct device *dev) 1395 { 1396 struct nl_msg *msg; 1397 1398 msg = __system_ifinfo_msg(AF_UNSPEC, dev->ifindex, NULL, RTM_SETLINK, NLM_F_REQUEST); 1399 if (!msg) 1400 return -1; 1401 1402 nla_put_u32(msg, IFLA_MASTER, vrf_index); 1403 return system_rtnl_call(msg); 1404 } 1405 1406 int system_vrf_addif(struct device *vrf, struct device *dev) 1407 { 1408 char *oldvrf; 1409 int tries; 1410 int ret; 1411 1412 for (tries = 0; tries < 3; tries++) { 1413 ret = 0; 1414 oldvrf = system_get_vrf(dev->ifname, dev_buf, sizeof(dev_buf)); 1415 if (oldvrf && !strcmp(oldvrf, vrf->ifname)) 1416 break; 1417 1418 ret = system_vrf_if(vrf->ifindex, dev); 1419 if (!ret) 1420 break; 1421 1422 D(SYSTEM, "Failed to add device '%s' to vrf '%s' (tries=%d): %s\n", 1423 dev->ifname, vrf->ifname, tries, strerror(errno)); 1424 } 1425 1426 return ret; 1427 } 1428 1429 int system_vrf_delif(struct device *vrf, struct device *dev) 1430 { 1431 return system_vrf_if(0, dev); 1432 } 1433 1434 void system_tcp_l3mdev(bool enable) 1435 { 1436 system_set_dev_sysctl("ipv4", "tcp_l3mdev_accept", ".", enable ? "1" : ""); 1437 } 1438 1439 void system_udp_l3mdev(bool enable) 1440 { 1441 system_set_dev_sysctl("ipv4", "udp_l3mdev_accept", ".", enable ? "1" : ""); 1442 } 1443 1444 int system_bonding_set_device(struct device *dev, struct bonding_config *cfg) 1445 { 1446 const char *ifname = dev->ifname; 1447 struct blob_attr *cur; 1448 char op = cfg ? '+' : '-'; 1449 char buf[64]; 1450 size_t rem; 1451 1452 snprintf(dev_buf, sizeof(dev_buf), "%s/class/net/bonding_masters", sysfs_path); 1453 snprintf(buf, sizeof(buf), "%c%s", op, ifname); 1454 write_file(dev_buf, buf); 1455 1456 if (!cfg) 1457 return 0; 1458 1459 system_set_dev_sysfs("bonding/mode", ifname, bonding_policy_str[cfg->policy]); 1460 1461 system_set_dev_sysfs_int("bonding/all_slaves_active", ifname, cfg->all_ports_active); 1462 1463 if (cfg->policy == BONDING_MODE_BALANCE_XOR || 1464 cfg->policy == BONDING_MODE_BALANCE_TLB || 1465 cfg->policy == BONDING_MODE_8023AD) 1466 system_set_dev_sysfs("bonding/xmit_hash_policy", ifname, cfg->xmit_hash_policy); 1467 1468 if (cfg->policy == BONDING_MODE_8023AD) { 1469 system_set_dev_sysfs("bonding/ad_actor_system", ifname, cfg->ad_actor_system); 1470 system_set_dev_sysfs_int("bonding/ad_actor_sys_prio", ifname, cfg->ad_actor_sys_prio); 1471 system_set_dev_sysfs("bonding/ad_select", ifname, cfg->ad_select); 1472 system_set_dev_sysfs("bonding/lacp_rate", ifname, cfg->lacp_rate); 1473 system_set_dev_sysfs_int("bonding/min_links", ifname, cfg->min_links); 1474 } 1475 1476 if (cfg->policy == BONDING_MODE_BALANCE_RR) 1477 system_set_dev_sysfs_int("bonding/packets_per_slave", ifname, cfg->packets_per_port); 1478 1479 if (cfg->policy == BONDING_MODE_BALANCE_TLB || 1480 cfg->policy == BONDING_MODE_BALANCE_ALB) 1481 system_set_dev_sysfs_int("bonding/lp_interval", ifname, cfg->lp_interval); 1482 1483 if (cfg->policy == BONDING_MODE_BALANCE_TLB) 1484 system_set_dev_sysfs_int("bonding/tlb_dynamic_lb", ifname, cfg->dynamic_lb); 1485 system_set_dev_sysfs_int("bonding/resend_igmp", ifname, cfg->resend_igmp); 1486 system_set_dev_sysfs_int("bonding/num_grat_arp", ifname, cfg->num_peer_notif); 1487 system_set_dev_sysfs("bonding/primary_reselect", ifname, cfg->primary_reselect); 1488 system_set_dev_sysfs("bonding/fail_over_mac", ifname, cfg->failover_mac); 1489 1490 system_set_dev_sysfs_int((cfg->monitor_arp ? 1491 "bonding/arp_interval" : 1492 "bonding/miimon"), ifname, cfg->monitor_interval); 1493 1494 blobmsg_for_each_attr(cur, cfg->arp_target, rem) { 1495 snprintf(buf, sizeof(buf), "+%s", blobmsg_get_string(cur)); 1496 system_set_dev_sysfs("bonding/arp_ip_target", ifname, buf); 1497 } 1498 1499 system_set_dev_sysfs_int("bonding/arp_all_targets", ifname, cfg->arp_all_targets); 1500 if (cfg->policy < BONDING_MODE_8023AD) 1501 system_set_dev_sysfs("bonding/arp_validate", ifname, cfg->arp_validate); 1502 system_set_dev_sysfs_int("bonding/use_carrier", ifname, cfg->use_carrier); 1503 if (!cfg->monitor_arp && cfg->monitor_interval) { 1504 system_set_dev_sysfs_int("bonding/updelay", ifname, cfg->updelay); 1505 system_set_dev_sysfs_int("bonding/downdelay", ifname, cfg->downdelay); 1506 } 1507 1508 return 0; 1509 } 1510 1511 int system_bonding_set_port(struct device *dev, struct device *port, bool add, bool primary) 1512 { 1513 const char *port_name = port->ifname; 1514 const char op_ch = add ? '+' : '-'; 1515 char buf[IFNAMSIZ + 1]; 1516 1517 snprintf(buf, sizeof(buf), "%c%s", op_ch, port_name); 1518 system_if_down(port); 1519 system_set_dev_sysfs("bonding/slaves", dev->ifname, buf); 1520 system_if_up(port); 1521 1522 if (primary) 1523 system_set_dev_sysfs("bonding/primary", dev->ifname, 1524 add ? port_name : ""); 1525 1526 return 0; 1527 } 1528 1529 int system_if_resolve(struct device *dev) 1530 { 1531 struct ifreq ifr; 1532 1533 if (system_device_ifreq(&ifr, dev->ifname, SIOCGIFINDEX)) 1534 return 0; 1535 1536 return ifr.ifr_ifindex; 1537 } 1538 1539 static int system_if_flags(const char *ifname, unsigned add, unsigned rem) 1540 { 1541 struct ifreq ifr; 1542 1543 if (system_device_ifreq(&ifr, ifname, SIOCGIFFLAGS)) 1544 return -1; 1545 1546 ifr.ifr_flags |= add; 1547 ifr.ifr_flags &= ~rem; 1548 return ioctl(sock_ioctl, SIOCSIFFLAGS, &ifr); 1549 } 1550 1551 struct clear_data { 1552 struct nl_msg *msg; 1553 struct device *dev; 1554 int type; 1555 int size; 1556 int af; 1557 struct nl_msg **del; 1558 int n_del; 1559 }; 1560 1561 1562 static bool check_ifaddr(struct nlmsghdr *hdr, int ifindex) 1563 { 1564 struct ifaddrmsg *ifa = NLMSG_DATA(hdr); 1565 1566 return (long)ifa->ifa_index == ifindex; 1567 } 1568 1569 static bool check_route(struct nlmsghdr *hdr, int ifindex) 1570 { 1571 struct rtmsg *r = NLMSG_DATA(hdr); 1572 struct nlattr *tb[__RTA_MAX]; 1573 1574 if (r->rtm_protocol == RTPROT_KERNEL && 1575 r->rtm_family == AF_INET6) 1576 return false; 1577 1578 nlmsg_parse(hdr, sizeof(struct rtmsg), tb, __RTA_MAX - 1, NULL); 1579 if (!tb[RTA_OIF]) 1580 return false; 1581 1582 return *(int *)RTA_DATA(tb[RTA_OIF]) == ifindex; 1583 } 1584 1585 static bool check_rule(struct nlmsghdr *hdr, int ifindex) 1586 { 1587 return true; 1588 } 1589 1590 static bool check_neigh(struct nlmsghdr *hdr, int ifindex) 1591 { 1592 struct ndmsg *ndm = NLMSG_DATA(hdr); 1593 1594 if (ndm->ndm_ifindex != ifindex) 1595 return false; 1596 1597 /* only clear entries netifd could have installed itself */ 1598 return (ndm->ndm_state & NUD_PERMANENT) || (ndm->ndm_flags & NTF_PROXY); 1599 } 1600 1601 static int cb_clear_event(struct nl_msg *msg, void *arg) 1602 { 1603 struct clear_data *clr = arg; 1604 struct nlmsghdr *hdr = nlmsg_hdr(msg); 1605 bool (*cb)(struct nlmsghdr *, int ifindex); 1606 struct nl_msg **tmp, *del; 1607 const char *obj_name; 1608 int type; 1609 1610 switch(clr->type) { 1611 case RTM_GETADDR: 1612 type = RTM_DELADDR; 1613 if (hdr->nlmsg_type != RTM_NEWADDR) 1614 return NL_SKIP; 1615 1616 cb = check_ifaddr; 1617 break; 1618 case RTM_GETROUTE: 1619 type = RTM_DELROUTE; 1620 if (hdr->nlmsg_type != RTM_NEWROUTE) 1621 return NL_SKIP; 1622 1623 cb = check_route; 1624 break; 1625 case RTM_GETRULE: 1626 type = RTM_DELRULE; 1627 if (hdr->nlmsg_type != RTM_NEWRULE) 1628 return NL_SKIP; 1629 1630 cb = check_rule; 1631 break; 1632 case RTM_GETNEIGH: 1633 type = RTM_DELNEIGH; 1634 if (hdr->nlmsg_type != RTM_NEWNEIGH) 1635 return NL_SKIP; 1636 1637 cb = check_neigh; 1638 break; 1639 default: 1640 return NL_SKIP; 1641 } 1642 1643 if (!cb(hdr, clr->dev ? clr->dev->ifindex : 0)) 1644 return NL_SKIP; 1645 1646 obj_name = type == RTM_DELADDR ? "an address" : 1647 type == RTM_DELNEIGH ? "a neighbor" : "a route"; 1648 if (type == RTM_DELRULE) 1649 D(SYSTEM, "Remove a rule"); 1650 else 1651 D(SYSTEM, "Remove %s from device %s", 1652 obj_name, clr->dev->ifname); 1653 1654 /* 1655 * Queue the deletion instead of sending it while the dump is still 1656 * being received: a kernel error reply to a request sent with the 1657 * dump's sequence number aborts the dump processing and desyncs the 1658 * socket's sequence accounting 1659 */ 1660 del = nlmsg_convert(hdr); 1661 if (!del) 1662 return NL_SKIP; 1663 1664 hdr = nlmsg_hdr(del); 1665 hdr->nlmsg_type = type; 1666 hdr->nlmsg_flags = NLM_F_REQUEST; 1667 hdr->nlmsg_seq = NL_AUTO_SEQ; 1668 1669 tmp = realloc(clr->del, (clr->n_del + 1) * sizeof(*clr->del)); 1670 if (!tmp) { 1671 nlmsg_free(del); 1672 return NL_SKIP; 1673 } 1674 1675 clr->del = tmp; 1676 clr->del[clr->n_del++] = del; 1677 1678 return NL_SKIP; 1679 } 1680 1681 static int 1682 cb_finish_event(struct nl_msg *msg, void *arg) 1683 { 1684 int *pending = arg; 1685 *pending = 0; 1686 return NL_STOP; 1687 } 1688 1689 static int 1690 error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) 1691 { 1692 int *pending = arg; 1693 *pending = err->error; 1694 return NL_STOP; 1695 } 1696 1697 static void 1698 system_if_clear_entries(struct device *dev, int type, int af) 1699 { 1700 struct clear_data clr; 1701 struct nl_cb *cb; 1702 struct rtmsg rtm = { 1703 .rtm_family = af, 1704 .rtm_flags = RTM_F_CLONED, 1705 }; 1706 struct ndmsg ndm = { 1707 .ndm_family = af, 1708 }; 1709 void *req = &rtm; 1710 int flags = NLM_F_DUMP; 1711 int n_dumps = 1; 1712 int pending; 1713 1714 clr.af = af; 1715 clr.dev = dev; 1716 clr.type = type; 1717 clr.del = NULL; 1718 clr.n_del = 0; 1719 switch (type) { 1720 case RTM_GETADDR: 1721 case RTM_GETRULE: 1722 clr.size = sizeof(struct rtgenmsg); 1723 break; 1724 case RTM_GETROUTE: 1725 clr.size = sizeof(struct rtmsg); 1726 break; 1727 case RTM_GETNEIGH: 1728 req = &ndm; 1729 clr.size = sizeof(struct ndmsg); 1730 /* the kernel dumps proxy entries only when asked for them */ 1731 n_dumps = 2; 1732 break; 1733 default: 1734 return; 1735 } 1736 1737 cb = nl_cb_alloc(NL_CB_DEFAULT); 1738 if (!cb) 1739 return; 1740 1741 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_clear_event, &clr); 1742 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_finish_event, &pending); 1743 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &pending); 1744 1745 for (int i = 0; i < n_dumps; i++) { 1746 ndm.ndm_flags = i ? NTF_PROXY : 0; 1747 1748 clr.msg = nlmsg_alloc_simple(type, flags); 1749 if (!clr.msg) 1750 break; 1751 1752 nlmsg_append(clr.msg, req, clr.size, 0); 1753 1754 if (nl_send_auto_complete(sock_rtnl, clr.msg) < 0) { 1755 nlmsg_free(clr.msg); 1756 break; 1757 } 1758 1759 pending = 1; 1760 while (pending > 0) 1761 if (nl_recvmsgs(sock_rtnl, cb) < 0) 1762 break; 1763 1764 nlmsg_free(clr.msg); 1765 } 1766 1767 for (int i = 0; i < clr.n_del; i++) { 1768 int err = system_rtnl_call(clr.del[i]); 1769 1770 if (err) 1771 D(SYSTEM, "Error deleting kernel entry: %d", err); 1772 } 1773 free(clr.del); 1774 1775 nl_cb_put(cb); 1776 } 1777 1778 /* 1779 * Clear bridge (membership) state and bring down device 1780 */ 1781 void system_if_clear_state(struct device *dev) 1782 { 1783 static char buf[256]; 1784 char *bridge; 1785 device_set_ifindex(dev, system_if_resolve(dev)); 1786 1787 if (dev->external || !dev->ifindex) 1788 return; 1789 1790 system_if_flags(dev->ifname, 0, IFF_UP); 1791 1792 if (system_is_bridge(dev->ifname)) { 1793 D(SYSTEM, "Delete existing bridge named '%s'", dev->ifname); 1794 system_bridge_delbr(dev); 1795 return; 1796 } 1797 1798 bridge = system_get_bridge(dev->ifname, buf, sizeof(buf)); 1799 if (bridge) { 1800 D(SYSTEM, "Remove device '%s' from bridge '%s'", dev->ifname, bridge); 1801 system_bridge_if(bridge, dev, SIOCBRDELIF, NULL); 1802 } 1803 1804 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET); 1805 system_if_clear_entries(dev, RTM_GETADDR, AF_INET); 1806 system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6); 1807 system_if_clear_entries(dev, RTM_GETADDR, AF_INET6); 1808 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET); 1809 system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET6); 1810 system_set_disable_ipv6(dev, ""); 1811 } 1812 1813 static inline unsigned long 1814 sec_to_jiffies(int val) 1815 { 1816 return (unsigned long) val * 100; 1817 } 1818 1819 static void system_bridge_vlan_snooping_put(struct nl_msg *msg, const struct bridge_config *cfg) 1820 { 1821 struct br_boolopt_multi bm = { 1822 .optmask = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING, 1823 .optval = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING, 1824 }; 1825 1826 /* the kernel refuses per-VLAN snooping without VLAN filtering */ 1827 if (!cfg->vlan_filtering || !cfg->multicast_vlan_snooping) 1828 return; 1829 1830 nla_put(msg, IFLA_BR_MULTI_BOOLOPT, sizeof(bm), &bm); 1831 } 1832 1833 int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg) 1834 { 1835 struct nlattr *linkinfo, *data; 1836 struct nl_msg *msg; 1837 int rv; 1838 1839 msg = system_ifinfo_msg(bridge->ifname, RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL); 1840 if (!msg) 1841 return -1; 1842 1843 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) 1844 goto nla_put_failure; 1845 1846 nla_put_string(msg, IFLA_INFO_KIND, "bridge"); 1847 1848 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) 1849 goto nla_put_failure; 1850 1851 nla_put_u32(msg, IFLA_BR_STP_STATE, cfg->stp); 1852 nla_put_u32(msg, IFLA_BR_FORWARD_DELAY, sec_to_jiffies(cfg->forward_delay)); 1853 nla_put_u8(msg, IFLA_BR_MCAST_SNOOPING, !!cfg->igmp_snoop); 1854 nla_put_u8(msg, IFLA_BR_MCAST_QUERIER, !!cfg->multicast_querier); 1855 nla_put_u32(msg, IFLA_BR_MCAST_HASH_MAX, cfg->hash_max); 1856 1857 if (bridge->settings.flags & DEV_OPT_MULTICAST_ROUTER) 1858 nla_put_u8(msg, IFLA_BR_MCAST_ROUTER, !!bridge->settings.multicast_router); 1859 1860 system_bridge_mcast_put(msg, cfg, &bridge_mcast_link_attrs); 1861 1862 nla_put_u8(msg, IFLA_BR_VLAN_FILTERING, !!cfg->vlan_filtering); 1863 system_bridge_vlan_snooping_put(msg, cfg); 1864 nla_put_u16(msg, IFLA_BR_PRIORITY, cfg->priority); 1865 nla_put_u32(msg, IFLA_BR_HELLO_TIME, sec_to_jiffies(cfg->hello_time)); 1866 nla_put_u32(msg, IFLA_BR_MAX_AGE, sec_to_jiffies(cfg->max_age)); 1867 1868 if (cfg->flags & BRIDGE_OPT_AGEING_TIME) 1869 nla_put_u32(msg, IFLA_BR_AGEING_TIME, sec_to_jiffies(cfg->ageing_time)); 1870 1871 nla_nest_end(msg, data); 1872 nla_nest_end(msg, linkinfo); 1873 1874 rv = system_rtnl_call(msg); 1875 if (rv) 1876 D(SYSTEM, "Error adding bridge '%s': %d", bridge->ifname, rv); 1877 1878 return rv; 1879 1880 nla_put_failure: 1881 nlmsg_free(msg); 1882 return -ENOMEM; 1883 } 1884 1885 int system_bridge_set_vlan_filtering(struct device *bridge, const struct bridge_config *cfg) 1886 { 1887 struct nlattr *linkinfo, *data; 1888 struct nl_msg *msg; 1889 int rv; 1890 1891 msg = system_ifinfo_msg(bridge->ifname, RTM_NEWLINK, 0); 1892 if (!msg) 1893 return -1; 1894 1895 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) 1896 goto nla_put_failure; 1897 1898 nla_put_string(msg, IFLA_INFO_KIND, "bridge"); 1899 1900 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) 1901 goto nla_put_failure; 1902 1903 nla_put_u8(msg, IFLA_BR_VLAN_FILTERING, !!cfg->vlan_filtering); 1904 system_bridge_vlan_snooping_put(msg, cfg); 1905 1906 nla_nest_end(msg, data); 1907 nla_nest_end(msg, linkinfo); 1908 1909 rv = system_rtnl_call(msg); 1910 if (rv) 1911 D(SYSTEM, "Error setting vlan_filtering of bridge '%s': %d", 1912 bridge->ifname, rv); 1913 1914 return rv; 1915 1916 nla_put_failure: 1917 nlmsg_free(msg); 1918 return -ENOMEM; 1919 } 1920 1921 int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg) 1922 { 1923 struct nl_msg *msg; 1924 struct nlattr *linkinfo, *data; 1925 size_t i; 1926 int rv; 1927 static const struct { 1928 const char *name; 1929 enum macvlan_mode val; 1930 } modes[] = { 1931 { "private", MACVLAN_MODE_PRIVATE }, 1932 { "vepa", MACVLAN_MODE_VEPA }, 1933 { "bridge", MACVLAN_MODE_BRIDGE }, 1934 { "passthru", MACVLAN_MODE_PASSTHRU }, 1935 }; 1936 1937 msg = system_ifinfo_msg(macvlan->ifname, RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL); 1938 if (!msg) 1939 return -1; 1940 1941 if (cfg->flags & MACVLAN_OPT_MACADDR) 1942 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr); 1943 nla_put_u32(msg, IFLA_LINK, dev->ifindex); 1944 1945 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) 1946 goto nla_put_failure; 1947 1948 nla_put_string(msg, IFLA_INFO_KIND, "macvlan"); 1949 1950 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) 1951 goto nla_put_failure; 1952 1953 if (cfg->mode) { 1954 for (i = 0; i < ARRAY_SIZE(modes); i++) { 1955 if (strcmp(cfg->mode, modes[i].name) != 0) 1956 continue; 1957 1958 nla_put_u32(msg, IFLA_MACVLAN_MODE, modes[i].val); 1959 break; 1960 } 1961 } 1962 1963 nla_nest_end(msg, data); 1964 nla_nest_end(msg, linkinfo); 1965 1966 rv = system_rtnl_call(msg); 1967 if (rv) 1968 D(SYSTEM, "Error adding macvlan '%s' over '%s': %d", macvlan->ifname, dev->ifname, rv); 1969 1970 return rv; 1971 1972 nla_put_failure: 1973 nlmsg_free(msg); 1974 return -ENOMEM; 1975 } 1976 1977 int system_link_netns_move(struct device *dev, int netns_fd, const char *target_ifname) 1978 { 1979 struct nl_msg *msg; 1980 int index; 1981 1982 if (!dev) 1983 return -1; 1984 1985 index = system_if_resolve(dev); 1986 if (index <= 0) 1987 return -1; 1988 1989 msg = __system_ifinfo_msg(AF_UNSPEC, index, target_ifname, RTM_NEWLINK, 0); 1990 if (!msg) 1991 return -1; 1992 1993 nla_put_u32(msg, IFLA_NET_NS_FD, netns_fd); 1994 return system_rtnl_call(msg); 1995 } 1996 1997 int system_macvlan_del(struct device *macvlan) 1998 { 1999 return system_link_del(macvlan->ifname); 2000 } 2001 2002 int system_netns_open(const pid_t target_ns) 2003 { 2004 char pid_net_path[PATH_MAX]; 2005 2006 snprintf(pid_net_path, sizeof(pid_net_path), "/proc/%u/ns/net", target_ns); 2007 2008 return open(pid_net_path, O_RDONLY); 2009 } 2010 2011 int system_netns_set(int netns_fd) 2012 { 2013 return setns(netns_fd, CLONE_NEWNET); 2014 } 2015 2016 int system_veth_add(struct device *veth, struct veth_config *cfg) 2017 { 2018 struct nl_msg *msg; 2019 struct ifinfomsg empty_iim = {0,}; 2020 struct nlattr *linkinfo, *data, *veth_info; 2021 int rv; 2022 2023 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); 2024 2025 if (!msg) 2026 return -1; 2027 2028 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0); 2029 2030 if (cfg->flags & VETH_OPT_MACADDR) 2031 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr); 2032 nla_put_string(msg, IFLA_IFNAME, veth->ifname); 2033 2034 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) 2035 goto nla_put_failure; 2036 2037 nla_put_string(msg, IFLA_INFO_KIND, "veth"); 2038 2039 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) 2040 goto nla_put_failure; 2041 2042 if (!(veth_info = nla_nest_start(msg, VETH_INFO_PEER))) 2043 goto nla_put_failure; 2044 2045 nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0); 2046 2047 if (cfg->flags & VETH_OPT_PEER_NAME) 2048 nla_put_string(msg, IFLA_IFNAME, cfg->peer_name); 2049 if (cfg->flags & VETH_OPT_PEER_MACADDR) 2050 nla_put(msg, IFLA_ADDRESS, sizeof(cfg->peer_macaddr), cfg->peer_macaddr); 2051 2052 nla_nest_end(msg, veth_info); 2053 nla_nest_end(msg, data); 2054 nla_nest_end(msg, linkinfo); 2055 2056 rv = system_rtnl_call(msg); 2057 if (rv) { 2058 if (cfg->flags & VETH_OPT_PEER_NAME) 2059 D(SYSTEM, "Error adding veth '%s' with peer '%s': %d", veth->ifname, cfg->peer_name, rv); 2060 else 2061 D(SYSTEM, "Error adding veth '%s': %d", veth->ifname, rv); 2062 } 2063 2064 return rv; 2065 2066 nla_put_failure: 2067 nlmsg_free(msg); 2068 return -ENOMEM; 2069 } 2070 2071 int system_veth_del(struct device *veth) 2072 { 2073 return system_link_del(veth->ifname); 2074 } 2075 2076 static int system_vlan(struct device *dev, int id) 2077 { 2078 struct vlan_ioctl_args ifr = { 2079 .cmd = SET_VLAN_NAME_TYPE_CMD, 2080 .u.name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, 2081 }; 2082 2083 if (ioctl(sock_ioctl, SIOCSIFVLAN, &ifr) < 0) 2084 return -1; 2085 2086 if (id < 0) { 2087 ifr.cmd = DEL_VLAN_CMD; 2088 ifr.u.VID = 0; 2089 } else { 2090 ifr.cmd = ADD_VLAN_CMD; 2091 ifr.u.VID = id; 2092 } 2093 strncpy(ifr.device1, dev->ifname, sizeof(ifr.device1)); 2094 return ioctl(sock_ioctl, SIOCSIFVLAN, &ifr); 2095 } 2096 2097 int system_vlan_add(struct device *dev, int id) 2098 { 2099 return system_vlan(dev, id); 2100 } 2101 2102 int system_vlan_del(struct device *dev) 2103 { 2104 return system_vlan(dev, -1); 2105 } 2106 2107 int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg) 2108 { 2109 struct nl_msg *msg; 2110 struct nlattr *linkinfo, *data, *qos; 2111 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC }; 2112 struct vlan_qos_mapping *elem; 2113 struct ifla_vlan_qos_mapping nl_qos_map; 2114 int rv; 2115 2116 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); 2117 2118 if (!msg) 2119 return -1; 2120 2121 nlmsg_append(msg, &iim, sizeof(iim), 0); 2122 nla_put_string(msg, IFLA_IFNAME, vlandev->ifname); 2123 nla_put_u32(msg, IFLA_LINK, dev->ifindex); 2124 2125 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) 2126 goto nla_put_failure; 2127 2128 nla_put_string(msg, IFLA_INFO_KIND, "vlan"); 2129 2130 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) 2131 goto nla_put_failure; 2132 2133 nla_put_u16(msg, IFLA_VLAN_ID, cfg->vid); 2134 2135 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) 2136 nla_put_u16(msg, IFLA_VLAN_PROTOCOL, htons(cfg->proto)); 2137 #else 2138 if(cfg->proto == VLAN_PROTO_8021AD) 2139 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); 2140 #endif 2141 2142 if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS))) 2143 goto nla_put_failure; 2144 2145 vlist_simple_for_each_element(&cfg->ingress_qos_mapping_list, elem, node) { 2146 nl_qos_map.from = elem->from; 2147 nl_qos_map.to = elem->to; 2148 nla_put(msg, IFLA_VLAN_QOS_MAPPING, sizeof(nl_qos_map), &nl_qos_map); 2149 } 2150 nla_nest_end(msg, qos); 2151 2152 if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS))) 2153 goto nla_put_failure; 2154 2155 vlist_simple_for_each_element(&cfg->egress_qos_mapping_list, elem, node) { 2156 nl_qos_map.from = elem->from; 2157 nl_qos_map.to = elem->to; 2158 nla_put(msg, IFLA_VLAN_QOS_MAPPING, sizeof(nl_qos_map), &nl_qos_map); 2159 } 2160 nla_nest_end(msg, qos); 2161 2162 nla_nest_end(msg, data); 2163 nla_nest_end(msg, linkinfo); 2164 2165 rv = system_rtnl_call(msg); 2166 if (rv) 2167 D(SYSTEM, "Error adding vlandev '%s' over '%s': %d", vlandev->ifname, dev->ifname, rv); 2168 2169 return rv; 2170 2171 nla_put_failure: 2172 nlmsg_free(msg); 2173 return -ENOMEM; 2174 } 2175 2176 int system_vlandev_del(struct device *vlandev) 2177 { 2178 return system_link_del(vlandev->ifname); 2179 } 2180 2181 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) 2182 struct if_get_master_data { 2183 int ifindex; 2184 int master_ifindex; 2185 int pending; 2186 }; 2187 2188 static void if_get_master_dsa_linkinfo_attr(struct if_get_master_data *data, 2189 struct rtattr *attr) 2190 { 2191 struct rtattr *cur; 2192 int rem = RTA_PAYLOAD(attr); 2193 2194 for (cur = RTA_DATA(attr); RTA_OK(cur, rem); cur = RTA_NEXT(cur, rem)) { 2195 if (cur->rta_type != IFLA_DSA_MASTER) 2196 continue; 2197 2198 data->master_ifindex = *(__u32 *)RTA_DATA(cur); 2199 } 2200 } 2201 2202 static void if_get_master_linkinfo_attr(struct if_get_master_data *data, 2203 struct rtattr *attr) 2204 { 2205 struct rtattr *cur; 2206 int rem = RTA_PAYLOAD(attr); 2207 2208 for (cur = RTA_DATA(attr); RTA_OK(cur, rem); cur = RTA_NEXT(cur, rem)) { 2209 if (cur->rta_type != IFLA_INFO_KIND && cur->rta_type != IFLA_INFO_DATA) 2210 continue; 2211 2212 if (cur->rta_type == IFLA_INFO_KIND && strcmp("dsa", (char *)RTA_DATA(cur))) 2213 break; 2214 2215 if (cur->rta_type == IFLA_INFO_DATA) 2216 if_get_master_dsa_linkinfo_attr(data, cur); 2217 } 2218 } 2219 2220 static int cb_if_get_master_valid(struct nl_msg *msg, void *arg) 2221 { 2222 struct nlmsghdr *nh = nlmsg_hdr(msg); 2223 struct ifinfomsg *ifi = NLMSG_DATA(nh); 2224 struct if_get_master_data *data = (struct if_get_master_data *)arg; 2225 struct rtattr *attr; 2226 int rem; 2227 2228 if (nh->nlmsg_type != RTM_NEWLINK) 2229 return NL_SKIP; 2230 2231 if (ifi->ifi_family != AF_UNSPEC) 2232 return NL_SKIP; 2233 2234 if (ifi->ifi_index != data->ifindex) 2235 return NL_SKIP; 2236 2237 attr = IFLA_RTA(ifi); 2238 rem = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); 2239 2240 while (RTA_OK(attr, rem)) { 2241 if (attr->rta_type == IFLA_LINKINFO) 2242 if_get_master_linkinfo_attr(data, attr); 2243 2244 attr = RTA_NEXT(attr, rem); 2245 } 2246 2247 return NL_OK; 2248 } 2249 2250 static int cb_if_get_master_ack(struct nl_msg *msg, void *arg) 2251 { 2252 struct if_get_master_data *data = (struct if_get_master_data *)arg; 2253 data->pending = 0; 2254 return NL_STOP; 2255 } 2256 2257 static int cb_if_get_master_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) 2258 { 2259 struct if_get_master_data *data = (struct if_get_master_data *)arg; 2260 data->pending = 0; 2261 return NL_STOP; 2262 } 2263 2264 static int system_if_get_master_ifindex(struct device *dev) 2265 { 2266 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); 2267 struct nl_msg *msg; 2268 struct ifinfomsg ifi = { 2269 .ifi_family = AF_UNSPEC, 2270 .ifi_index = 0, 2271 }; 2272 struct if_get_master_data data = { 2273 .ifindex = if_nametoindex(dev->ifname), 2274 .master_ifindex = -1, 2275 .pending = 1, 2276 }; 2277 int ret = -1; 2278 2279 if (!cb) 2280 return ret; 2281 2282 msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST); 2283 if (!msg) 2284 goto out; 2285 2286 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) || 2287 nla_put_string(msg, IFLA_IFNAME, dev->ifname)) 2288 goto free; 2289 2290 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_get_master_valid, &data); 2291 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_get_master_ack, &data); 2292 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_get_master_error, &data); 2293 2294 ret = nl_send_auto_complete(sock_rtnl, msg); 2295 if (ret < 0) 2296 goto free; 2297 2298 while (data.pending > 0) 2299 if (nl_recvmsgs(sock_rtnl, cb) < 0) 2300 break; 2301 2302 ret = data.master_ifindex; 2303 2304 free: 2305 nlmsg_free(msg); 2306 out: 2307 nl_cb_put(cb); 2308 return ret; 2309 } 2310 2311 static void system_refresh_orig_macaddr(struct device *dev, struct device_settings *s) 2312 { 2313 struct ifreq ifr; 2314 2315 memset(&ifr, 0, sizeof(ifr)); 2316 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2317 2318 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) 2319 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr)); 2320 } 2321 2322 static void system_set_master(struct device *dev, int master_ifindex) 2323 { 2324 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, }; 2325 struct nl_msg *nlm; 2326 2327 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST); 2328 if (!nlm) 2329 return; 2330 2331 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 2332 nla_put_string(nlm, IFLA_IFNAME, dev->ifname); 2333 2334 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 2335 if (!linkinfo) 2336 goto failure; 2337 2338 nla_put_string(nlm, IFLA_INFO_KIND, "dsa"); 2339 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 2340 if (!infodata) 2341 goto failure; 2342 2343 nla_put_u32(nlm, IFLA_DSA_MASTER, master_ifindex); 2344 2345 nla_nest_end(nlm, infodata); 2346 nla_nest_end(nlm, linkinfo); 2347 2348 system_rtnl_call(nlm); 2349 2350 return; 2351 2352 failure: 2353 nlmsg_free(nlm); 2354 } 2355 #endif 2356 2357 static void ethtool_link_mode_clear_bit(__s8 nwords, int nr, __u32 *mask) 2358 { 2359 if (nr < 0) 2360 return; 2361 2362 if (nr >= (nwords * 32)) 2363 return; 2364 2365 mask[nr / 32] &= ~(1U << (nr % 32)); 2366 } 2367 2368 static bool ethtool_link_mode_test_bit(__s8 nwords, int nr, const __u32 *mask) 2369 { 2370 if (nr < 0) 2371 return false; 2372 2373 if (nr >= (nwords * 32)) 2374 return false; 2375 2376 return !!(mask[nr / 32] & (1U << (nr % 32))); 2377 } 2378 2379 static int 2380 system_get_ethtool_gro(struct device *dev) 2381 { 2382 struct ethtool_value ecmd; 2383 struct ifreq ifr = { 2384 .ifr_data = (caddr_t)&ecmd, 2385 }; 2386 2387 memset(&ecmd, 0, sizeof(ecmd)); 2388 ecmd.cmd = ETHTOOL_GGRO; 2389 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2390 2391 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr)) 2392 return -1; 2393 2394 return ecmd.data; 2395 } 2396 2397 static void 2398 system_set_ethtool_gro(struct device *dev, struct device_settings *s) 2399 { 2400 struct ethtool_value ecmd; 2401 struct ifreq ifr = { 2402 .ifr_data = (caddr_t)&ecmd, 2403 }; 2404 2405 memset(&ecmd, 0, sizeof(ecmd)); 2406 ecmd.cmd = ETHTOOL_SGRO; 2407 ecmd.data = s->gro; 2408 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2409 2410 ioctl(sock_ioctl, SIOCETHTOOL, &ifr); 2411 } 2412 2413 static void 2414 system_set_ethtool_pause(struct device *dev, struct device_settings *s) 2415 { 2416 struct ethtool_pauseparam pp; 2417 struct ifreq ifr = { 2418 .ifr_data = (caddr_t)&pp, 2419 }; 2420 2421 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2422 memset(&pp, 0, sizeof(pp)); 2423 pp.cmd = ETHTOOL_GPAUSEPARAM; 2424 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr)) 2425 return; 2426 2427 if (s->flags & DEV_OPT_RXPAUSE || s->flags & DEV_OPT_TXPAUSE) { 2428 pp.autoneg = AUTONEG_DISABLE; 2429 2430 if (s->flags & DEV_OPT_PAUSE) { 2431 if (s->flags & DEV_OPT_RXPAUSE) 2432 pp.rx_pause = s->rxpause && s->pause; 2433 else 2434 pp.rx_pause = s->pause; 2435 2436 if (s->flags & DEV_OPT_TXPAUSE) 2437 pp.tx_pause = s->txpause && s->pause; 2438 else 2439 pp.tx_pause = s->pause; 2440 } else { 2441 if (s->flags & DEV_OPT_RXPAUSE) 2442 pp.rx_pause = s->rxpause; 2443 2444 if (s->flags & DEV_OPT_TXPAUSE) 2445 pp.tx_pause = s->txpause; 2446 } 2447 2448 if (s->flags & DEV_OPT_ASYM_PAUSE && 2449 !s->asym_pause && (pp.rx_pause != pp.tx_pause)) 2450 pp.rx_pause = pp.tx_pause = false; 2451 } else { 2452 pp.autoneg = AUTONEG_ENABLE; 2453 /* Pause and Asym_Pause advertising bits will be set via 2454 * ETHTOOL_SLINKSETTINGS in system_set_ethtool_settings() 2455 */ 2456 } 2457 2458 pp.cmd = ETHTOOL_SPAUSEPARAM; 2459 ioctl(sock_ioctl, SIOCETHTOOL, &ifr); 2460 } 2461 2462 static void 2463 system_set_ethtool_eee_settings(struct device *dev, struct device_settings *s) 2464 { 2465 struct ethtool_eee eeecmd; 2466 struct ifreq ifr = { 2467 .ifr_data = (caddr_t)&eeecmd, 2468 }; 2469 2470 memset(&eeecmd, 0, sizeof(eeecmd)); 2471 eeecmd.cmd = ETHTOOL_SEEE; 2472 eeecmd.eee_enabled = s->eee; 2473 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2474 2475 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) 2476 netifd_log_message(L_WARNING, "cannot set eee %d for device %s", s->eee, dev->ifname); 2477 } 2478 2479 /* 2480 * PSE (Power Sourcing Equipment) genetlink functions 2481 * Uses ethtool netlink interface to get/set PoE port configuration 2482 */ 2483 struct pse_reply_data { 2484 bool valid; 2485 /* IEEE 802.3 Clause 33 (standard PoE) */ 2486 uint32_t c33_admin_state; 2487 uint32_t c33_pw_status; 2488 uint32_t c33_pw_class; 2489 uint32_t c33_actual_pw; 2490 uint32_t c33_avail_pw_limit; 2491 /* IEEE 802.3 PoDL (Power over Data Line, e.g. single-pair Ethernet) */ 2492 uint32_t podl_admin_state; 2493 uint32_t podl_pw_status; 2494 /* Port priority for power budget management */ 2495 uint32_t pse_prio_max; 2496 uint32_t pse_prio; 2497 }; 2498 2499 static int cb_pse_get_reply(struct nl_msg *msg, void *arg) 2500 { 2501 struct pse_reply_data *data = arg; 2502 struct nlmsghdr *nlh = nlmsg_hdr(msg); 2503 struct nlattr *tb[ETHTOOL_A_PSE_MAX + 1]; 2504 struct genlmsghdr *ghdr; 2505 2506 if (nlh->nlmsg_type != ethtool_family) 2507 return NL_SKIP; 2508 2509 ghdr = nlmsg_data(nlh); 2510 if (nla_parse(tb, ETHTOOL_A_PSE_MAX, genlmsg_attrdata(ghdr, 0), 2511 genlmsg_attrlen(ghdr, 0), NULL) < 0) 2512 return NL_SKIP; 2513 2514 data->valid = true; 2515 2516 if (tb[ETHTOOL_A_C33_PSE_ADMIN_STATE]) 2517 data->c33_admin_state = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_STATE]); 2518 if (tb[ETHTOOL_A_C33_PSE_PW_D_STATUS]) 2519 data->c33_pw_status = nla_get_u32(tb[ETHTOOL_A_C33_PSE_PW_D_STATUS]); 2520 if (tb[ETHTOOL_A_C33_PSE_PW_CLASS]) 2521 data->c33_pw_class = nla_get_u32(tb[ETHTOOL_A_C33_PSE_PW_CLASS]); 2522 if (tb[ETHTOOL_A_C33_PSE_ACTUAL_PW]) 2523 data->c33_actual_pw = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ACTUAL_PW]); 2524 if (tb[ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT]) 2525 data->c33_avail_pw_limit = nla_get_u32(tb[ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT]); 2526 if (tb[ETHTOOL_A_PODL_PSE_ADMIN_STATE]) 2527 data->podl_admin_state = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_STATE]); 2528 if (tb[ETHTOOL_A_PODL_PSE_PW_D_STATUS]) 2529 data->podl_pw_status = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_PW_D_STATUS]); 2530 #ifdef HAVE_ETHTOOL_A_PSE_PRIO 2531 if (tb[ETHTOOL_A_PSE_PRIO_MAX]) 2532 data->pse_prio_max = nla_get_u32(tb[ETHTOOL_A_PSE_PRIO_MAX]); 2533 if (tb[ETHTOOL_A_PSE_PRIO]) 2534 data->pse_prio = nla_get_u32(tb[ETHTOOL_A_PSE_PRIO]); 2535 #endif 2536 2537 return NL_OK; 2538 } 2539 2540 struct pse_get_cb_data { 2541 struct pse_reply_data *data; 2542 int pending; 2543 int err; 2544 }; 2545 2546 static int cb_pse_get_ack(struct nl_msg *msg, void *arg) 2547 { 2548 struct pse_get_cb_data *cb_data = arg; 2549 cb_data->pending = 0; 2550 return NL_STOP; 2551 } 2552 2553 static int cb_pse_get_error(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg) 2554 { 2555 struct pse_get_cb_data *cb_data = arg; 2556 cb_data->pending = 0; 2557 cb_data->err = nlerr->error; 2558 return NL_STOP; 2559 } 2560 2561 static int cb_pse_get_valid_wrapper(struct nl_msg *msg, void *arg) 2562 { 2563 struct pse_get_cb_data *cb_data = arg; 2564 return cb_pse_get_reply(msg, cb_data->data); 2565 } 2566 2567 static int system_pse_get(struct device *dev, struct pse_reply_data *data) 2568 { 2569 struct nl_msg *msg; 2570 struct nlattr *hdr; 2571 struct nl_cb *cb; 2572 struct pse_get_cb_data cb_data; 2573 int ret; 2574 2575 memset(data, 0, sizeof(*data)); 2576 2577 if (!sock_genl || ethtool_family < 0) { 2578 return -EOPNOTSUPP; 2579 } 2580 2581 cb = nl_cb_alloc(NL_CB_DEFAULT); 2582 if (!cb) 2583 return -ENOMEM; 2584 2585 msg = nlmsg_alloc(); 2586 if (!msg) { 2587 nl_cb_put(cb); 2588 return -ENOMEM; 2589 } 2590 2591 if (!genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, ethtool_family, 2592 0, 0, ETHTOOL_MSG_PSE_GET, 1)) { 2593 nlmsg_free(msg); 2594 nl_cb_put(cb); 2595 return -ENOMEM; 2596 } 2597 2598 hdr = nla_nest_start(msg, ETHTOOL_A_PSE_HEADER); 2599 if (!hdr) { 2600 nlmsg_free(msg); 2601 nl_cb_put(cb); 2602 return -ENOMEM; 2603 } 2604 nla_put_string(msg, ETHTOOL_A_HEADER_DEV_NAME, dev->ifname); 2605 nla_nest_end(msg, hdr); 2606 2607 cb_data.data = data; 2608 cb_data.pending = 1; 2609 cb_data.err = 0; 2610 2611 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_pse_get_valid_wrapper, &cb_data); 2612 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_pse_get_ack, &cb_data); 2613 nl_cb_err(cb, NL_CB_CUSTOM, cb_pse_get_error, &cb_data); 2614 2615 ret = nl_send_auto_complete(sock_genl, msg); 2616 nlmsg_free(msg); 2617 if (ret < 0) { 2618 nl_cb_put(cb); 2619 return ret; 2620 } 2621 2622 while (cb_data.pending > 0) { 2623 ret = nl_recvmsgs(sock_genl, cb); 2624 if (ret < 0) { 2625 cb_data.pending = 0; 2626 cb_data.err = ret; 2627 } 2628 } 2629 2630 nl_cb_put(cb); 2631 2632 if (cb_data.err) { 2633 return cb_data.err; 2634 } 2635 2636 return data->valid ? 0 : -EOPNOTSUPP; 2637 } 2638 2639 struct pse_set_cb_data { 2640 int pending; 2641 int err; 2642 }; 2643 2644 static int cb_pse_set_ack(struct nl_msg *msg, void *arg) 2645 { 2646 struct pse_set_cb_data *cb_data = arg; 2647 cb_data->pending = 0; 2648 return NL_STOP; 2649 } 2650 2651 static int cb_pse_set_error(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg) 2652 { 2653 struct pse_set_cb_data *cb_data = arg; 2654 cb_data->pending = 0; 2655 cb_data->err = nlerr->error; 2656 return NL_STOP; 2657 } 2658 2659 static int system_pse_set(struct device *dev, struct device_settings *s) 2660 { 2661 struct nl_msg *msg; 2662 struct nlattr *hdr; 2663 struct nl_cb *cb; 2664 struct pse_set_cb_data cb_data; 2665 int ret; 2666 2667 /* Early return if no PSE settings requested */ 2668 if (!(s->flags & (DEV_OPT_PSE | DEV_OPT_PSE_PODL | 2669 DEV_OPT_PSE_POWER_LIMIT | DEV_OPT_PSE_PRIORITY))) 2670 return 0; 2671 2672 if (!sock_genl || ethtool_family < 0) { 2673 netifd_log_message(L_WARNING, "PSE: genetlink not available for %s", dev->ifname); 2674 return -EOPNOTSUPP; 2675 } 2676 2677 cb = nl_cb_alloc(NL_CB_DEFAULT); 2678 if (!cb) 2679 return -ENOMEM; 2680 2681 msg = nlmsg_alloc(); 2682 if (!msg) { 2683 nl_cb_put(cb); 2684 return -ENOMEM; 2685 } 2686 2687 if (!genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, ethtool_family, 2688 0, 0, ETHTOOL_MSG_PSE_SET, 1)) { 2689 nlmsg_free(msg); 2690 nl_cb_put(cb); 2691 return -ENOMEM; 2692 } 2693 2694 hdr = nla_nest_start(msg, ETHTOOL_A_PSE_HEADER); 2695 if (!hdr) { 2696 nlmsg_free(msg); 2697 nl_cb_put(cb); 2698 return -ENOMEM; 2699 } 2700 nla_put_string(msg, ETHTOOL_A_HEADER_DEV_NAME, dev->ifname); 2701 nla_nest_end(msg, hdr); 2702 2703 if (s->flags & DEV_OPT_PSE) 2704 nla_put_u32(msg, ETHTOOL_A_C33_PSE_ADMIN_CONTROL, 2705 s->pse ? ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED : 2706 ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED); 2707 2708 if (s->flags & DEV_OPT_PSE_PODL) 2709 nla_put_u32(msg, ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, 2710 s->pse_podl ? ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED : 2711 ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED); 2712 2713 if (s->flags & DEV_OPT_PSE_POWER_LIMIT) 2714 nla_put_u32(msg, ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT, s->pse_power_limit); 2715 2716 #ifdef HAVE_ETHTOOL_A_PSE_PRIO 2717 if (s->flags & DEV_OPT_PSE_PRIORITY) 2718 nla_put_u32(msg, ETHTOOL_A_PSE_PRIO, s->pse_priority); 2719 #endif 2720 2721 cb_data.pending = 1; 2722 cb_data.err = 0; 2723 2724 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_pse_set_ack, &cb_data); 2725 nl_cb_err(cb, NL_CB_CUSTOM, cb_pse_set_error, &cb_data); 2726 2727 ret = nl_send_auto_complete(sock_genl, msg); 2728 nlmsg_free(msg); 2729 if (ret < 0) { 2730 netifd_log_message(L_WARNING, "PSE: send failed for %s: %d", dev->ifname, ret); 2731 nl_cb_put(cb); 2732 return ret; 2733 } 2734 2735 while (cb_data.pending > 0) { 2736 ret = nl_recvmsgs(sock_genl, cb); 2737 if (ret < 0) { 2738 cb_data.pending = 0; 2739 cb_data.err = ret; 2740 } 2741 } 2742 2743 nl_cb_put(cb); 2744 2745 if (cb_data.err) { 2746 netifd_log_message(L_WARNING, "PSE: set failed for %s: %d", dev->ifname, cb_data.err); 2747 return cb_data.err; 2748 } 2749 2750 return 0; 2751 } 2752 2753 static void 2754 system_set_ethtool_settings(struct device *dev, struct device_settings *s) 2755 { 2756 struct { 2757 struct ethtool_link_settings req; 2758 __u32 link_mode_data[3 * 127]; 2759 } ecmd; 2760 struct ifreq ifr = { 2761 .ifr_data = (caddr_t)&ecmd, 2762 }; 2763 size_t i; 2764 __s8 nwords; 2765 __u32 *supported, *advertising; 2766 2767 system_set_ethtool_pause(dev, s); 2768 2769 if (s->flags & DEV_OPT_EEE) 2770 system_set_ethtool_eee_settings(dev, s); 2771 2772 /* Apply PSE (PoE) settings if configured */ 2773 if (s->flags & (DEV_OPT_PSE | DEV_OPT_PSE_PODL | DEV_OPT_PSE_POWER_LIMIT | DEV_OPT_PSE_PRIORITY)) 2774 system_pse_set(dev, s); 2775 2776 /* Avoid a rmw ioctl call if nothing needs to be changed. */ 2777 if (!(s->flags & (DEV_OPT_AUTONEG | DEV_OPT_SPEED | DEV_OPT_DUPLEX | DEV_OPT_PAUSE | DEV_OPT_ASYM_PAUSE))) 2778 return; 2779 2780 memset(&ecmd, 0, sizeof(ecmd)); 2781 ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; 2782 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2783 2784 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 2785 ecmd.req.link_mode_masks_nwords >= 0 || 2786 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 2787 return; 2788 2789 ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords; 2790 2791 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 2792 ecmd.req.link_mode_masks_nwords <= 0 || 2793 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 2794 return; 2795 2796 nwords = ecmd.req.link_mode_masks_nwords; 2797 supported = &ecmd.link_mode_data[0]; 2798 advertising = &ecmd.link_mode_data[nwords]; 2799 memcpy(advertising, supported, sizeof(__u32) * nwords); 2800 2801 for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) { 2802 if (s->flags & DEV_OPT_DUPLEX) { 2803 if (s->duplex) 2804 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising); 2805 else 2806 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising); 2807 } 2808 if (!(s->flags & DEV_OPT_SPEED) || 2809 s->speed == ethtool_modes[i].speed) 2810 continue; 2811 2812 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising); 2813 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising); 2814 } 2815 2816 if (s->flags & DEV_OPT_PAUSE) 2817 if (!s->pause) 2818 ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, advertising); 2819 2820 if (s->flags & DEV_OPT_ASYM_PAUSE) 2821 if (!s->asym_pause) 2822 ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising); 2823 2824 if (s->flags & DEV_OPT_AUTONEG) { 2825 ecmd.req.autoneg = s->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; 2826 if (!s->autoneg) { 2827 if (s->flags & DEV_OPT_SPEED) 2828 ecmd.req.speed = s->speed; 2829 2830 if (s->flags & DEV_OPT_DUPLEX) 2831 ecmd.req.duplex = s->duplex ? DUPLEX_FULL : DUPLEX_HALF; 2832 } 2833 } 2834 2835 ecmd.req.cmd = ETHTOOL_SLINKSETTINGS; 2836 ioctl(sock_ioctl, SIOCETHTOOL, &ifr); 2837 } 2838 2839 static void 2840 system_set_ethtool_settings_after_up(struct device *dev, struct device_settings *s) 2841 { 2842 if (s->flags & DEV_OPT_GRO) 2843 system_set_ethtool_gro(dev, s); 2844 } 2845 2846 void 2847 system_if_get_settings(struct device *dev, struct device_settings *s) 2848 { 2849 struct ifreq ifr; 2850 char buf[10]; 2851 int ret; 2852 2853 memset(&ifr, 0, sizeof(ifr)); 2854 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2855 2856 if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) { 2857 s->mtu = ifr.ifr_mtu; 2858 s->flags |= DEV_OPT_MTU; 2859 } 2860 2861 s->mtu6 = system_update_ipv6_mtu(dev, 0); 2862 if (s->mtu6 > 0) 2863 s->flags |= DEV_OPT_MTU6; 2864 2865 if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) { 2866 s->txqueuelen = ifr.ifr_qlen; 2867 s->flags |= DEV_OPT_TXQUEUELEN; 2868 } 2869 2870 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) { 2871 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr)); 2872 s->flags |= DEV_OPT_MACADDR; 2873 } 2874 2875 if (!system_get_disable_ipv6(dev, buf, sizeof(buf))) { 2876 s->ipv6 = !strtoul(buf, NULL, 0); 2877 s->flags |= DEV_OPT_IPV6; 2878 } 2879 2880 if (!system_get_ip6segmentrouting(dev, buf, sizeof(buf))) { 2881 s->ip6segmentrouting = strtoul(buf, NULL, 0); 2882 s->flags |= DEV_OPT_IP6SEGMENTROUTING; 2883 } 2884 2885 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) { 2886 s->promisc = ifr.ifr_flags & IFF_PROMISC; 2887 s->flags |= DEV_OPT_PROMISC; 2888 2889 s->multicast = ifr.ifr_flags & IFF_MULTICAST; 2890 s->flags |= DEV_OPT_MULTICAST; 2891 2892 s->arp = !(ifr.ifr_flags & IFF_NOARP); 2893 s->flags |= DEV_OPT_ARP; 2894 } 2895 2896 if (!system_get_rpfilter(dev, buf, sizeof(buf))) { 2897 s->rpfilter = strtoul(buf, NULL, 0); 2898 s->flags |= DEV_OPT_RPFILTER; 2899 } 2900 2901 if (!system_get_acceptlocal(dev, buf, sizeof(buf))) { 2902 s->acceptlocal = strtoul(buf, NULL, 0); 2903 s->flags |= DEV_OPT_ACCEPTLOCAL; 2904 } 2905 2906 if (!system_get_igmpversion(dev, buf, sizeof(buf))) { 2907 s->igmpversion = strtoul(buf, NULL, 0); 2908 s->flags |= DEV_OPT_IGMPVERSION; 2909 } 2910 2911 if (!system_get_mldversion(dev, buf, sizeof(buf))) { 2912 s->mldversion = strtoul(buf, NULL, 0); 2913 s->flags |= DEV_OPT_MLDVERSION; 2914 } 2915 2916 if (!system_get_neigh4reachabletime(dev, buf, sizeof(buf))) { 2917 s->neigh4reachabletime = strtoul(buf, NULL, 0); 2918 s->flags |= DEV_OPT_NEIGH4REACHABLETIME; 2919 } 2920 2921 if (!system_get_neigh6reachabletime(dev, buf, sizeof(buf))) { 2922 s->neigh6reachabletime = strtoul(buf, NULL, 0); 2923 s->flags |= DEV_OPT_NEIGH6REACHABLETIME; 2924 } 2925 2926 if (!system_get_neigh4locktime(dev, buf, sizeof(buf))) { 2927 s->neigh4locktime = strtol(buf, NULL, 0); 2928 s->flags |= DEV_OPT_NEIGHLOCKTIME; 2929 } 2930 2931 if (!system_get_neigh4gcstaletime(dev, buf, sizeof(buf))) { 2932 s->neigh4gcstaletime = strtoul(buf, NULL, 0); 2933 s->flags |= DEV_OPT_NEIGHGCSTALETIME; 2934 } 2935 2936 if (!system_get_neigh6gcstaletime(dev, buf, sizeof(buf))) { 2937 s->neigh6gcstaletime = strtoul(buf, NULL, 0); 2938 s->flags |= DEV_OPT_NEIGHGCSTALETIME; 2939 } 2940 2941 if (!system_get_dadtransmits(dev, buf, sizeof(buf))) { 2942 s->dadtransmits = strtoul(buf, NULL, 0); 2943 s->flags |= DEV_OPT_DADTRANSMITS; 2944 } 2945 2946 if (!system_get_rtrsolicits(dev, buf, sizeof(buf))) { 2947 s->rtrsolicits = strtol(buf, NULL, 0); 2948 s->flags |= DEV_OPT_RTRSOLICITS; 2949 } 2950 2951 if (!system_get_rtrsolicitinterval(dev, buf, sizeof(buf))) { 2952 s->rtrsolicitinterval = strtoul(buf, NULL, 0); 2953 s->flags |= DEV_OPT_RTRSOLICITINTERVAL; 2954 } 2955 2956 if (!system_get_neigh6retranstime(dev, buf, sizeof(buf))) { 2957 s->neigh6retranstime = strtoul(buf, NULL, 0); 2958 s->flags |= DEV_OPT_NEIGH6RETRANSTIME; 2959 } 2960 2961 if (!system_get_neigh4retranstime(dev, buf, sizeof(buf))) { 2962 s->neigh4retranstime = strtoul(buf, NULL, 0); 2963 s->flags |= DEV_OPT_NEIGH4RETRANSTIME; 2964 } 2965 2966 if (!system_get_neigh4mcastsolicit(dev, buf, sizeof(buf))) { 2967 s->neigh4mcastsolicit = strtoul(buf, NULL, 0); 2968 s->flags |= DEV_OPT_NEIGH4MCASTSOLICIT; 2969 } 2970 2971 if (!system_get_proxy_arp(dev, buf, sizeof(buf))) { 2972 s->proxy_arp = strtoul(buf, NULL, 0); 2973 s->flags |= DEV_OPT_PROXY_ARP; 2974 } 2975 2976 if (!system_get_sendredirects(dev, buf, sizeof(buf))) { 2977 s->sendredirects = strtoul(buf, NULL, 0); 2978 s->flags |= DEV_OPT_SENDREDIRECTS; 2979 } 2980 2981 if (!system_get_drop_v4_unicast_in_l2_multicast(dev, buf, sizeof(buf))) { 2982 s->drop_v4_unicast_in_l2_multicast = strtoul(buf, NULL, 0); 2983 s->flags |= DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST; 2984 } 2985 2986 if (!system_get_drop_v6_unicast_in_l2_multicast(dev, buf, sizeof(buf))) { 2987 s->drop_v6_unicast_in_l2_multicast = strtoul(buf, NULL, 0); 2988 s->flags |= DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST; 2989 } 2990 2991 if (!system_get_drop_gratuitous_arp(dev, buf, sizeof(buf))) { 2992 s->drop_gratuitous_arp = strtoul(buf, NULL, 0); 2993 s->flags |= DEV_OPT_DROP_GRATUITOUS_ARP; 2994 } 2995 2996 if (!system_get_drop_unsolicited_na(dev, buf, sizeof(buf))) { 2997 s->drop_unsolicited_na = strtoul(buf, NULL, 0); 2998 s->flags |= DEV_OPT_DROP_UNSOLICITED_NA; 2999 } 3000 3001 if (!system_get_arp_accept(dev, buf, sizeof(buf))) { 3002 s->arp_accept = strtoul(buf, NULL, 0); 3003 s->flags |= DEV_OPT_ARP_ACCEPT; 3004 } 3005 3006 ret = system_get_ethtool_gro(dev); 3007 if (ret >= 0) { 3008 s->gro = ret; 3009 s->flags |= DEV_OPT_GRO; 3010 } 3011 3012 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) 3013 ret = system_if_get_master_ifindex(dev); 3014 if (ret >= 0) { 3015 s->master_ifindex = ret; 3016 s->flags |= DEV_OPT_MASTER; 3017 } 3018 #endif 3019 } 3020 3021 void 3022 system_if_apply_settings(struct device *dev, struct device_settings *s, uint64_t apply_mask) 3023 { 3024 struct ifreq ifr; 3025 char buf[12]; 3026 3027 apply_mask &= s->flags; 3028 3029 if (apply_mask & DEV_OPT_MASTER) { 3030 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) 3031 system_set_master(dev, s->master_ifindex); 3032 if (!(apply_mask & (DEV_OPT_MACADDR | DEV_OPT_DEFAULT_MACADDR)) || dev->external) 3033 system_refresh_orig_macaddr(dev, &dev->orig_settings); 3034 #else 3035 netifd_log_message(L_WARNING, "%s Your kernel is older than linux 6.1.0, changing DSA port conduit is not supported!", dev->ifname); 3036 #endif 3037 } 3038 3039 memset(&ifr, 0, sizeof(ifr)); 3040 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 3041 if (apply_mask & DEV_OPT_MTU) { 3042 ifr.ifr_mtu = s->mtu; 3043 if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0) 3044 s->flags &= ~DEV_OPT_MTU; 3045 } 3046 if (apply_mask & DEV_OPT_MTU6) { 3047 system_update_ipv6_mtu(dev, s->mtu6); 3048 } 3049 if (apply_mask & DEV_OPT_TXQUEUELEN) { 3050 ifr.ifr_qlen = s->txqueuelen; 3051 if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0) 3052 s->flags &= ~DEV_OPT_TXQUEUELEN; 3053 } 3054 if ((apply_mask & (DEV_OPT_MACADDR | DEV_OPT_DEFAULT_MACADDR)) && !dev->external) { 3055 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; 3056 memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr)); 3057 if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0) 3058 s->flags &= ~DEV_OPT_MACADDR; 3059 } 3060 if (apply_mask & DEV_OPT_IPV6) 3061 system_set_disable_ipv6(dev, s->ipv6 ? "" : "1"); 3062 if (s->flags & DEV_OPT_IP6SEGMENTROUTING & apply_mask) { 3063 struct device dummy = { 3064 .ifname = "all", 3065 }; 3066 bool ip6segmentrouting = device_check_ip6segmentrouting(); 3067 3068 system_set_ip6segmentrouting(dev, s->ip6segmentrouting ? "1" : ""); 3069 system_set_ip6segmentrouting(&dummy, ip6segmentrouting ? "1" : ""); 3070 } 3071 if (apply_mask & DEV_OPT_PROMISC) { 3072 if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0, 3073 !s->promisc ? IFF_PROMISC : 0) < 0) 3074 s->flags &= ~DEV_OPT_PROMISC; 3075 } 3076 if (apply_mask & DEV_OPT_RPFILTER) { 3077 snprintf(buf, sizeof(buf), "%u", s->rpfilter); 3078 system_set_rpfilter(dev, buf); 3079 } 3080 if (apply_mask & DEV_OPT_ACCEPTLOCAL) 3081 system_set_acceptlocal(dev, s->acceptlocal ? "1" : ""); 3082 if (apply_mask & DEV_OPT_IGMPVERSION) { 3083 snprintf(buf, sizeof(buf), "%u", s->igmpversion); 3084 system_set_igmpversion(dev, buf); 3085 } 3086 if (apply_mask & DEV_OPT_MLDVERSION) { 3087 snprintf(buf, sizeof(buf), "%u", s->mldversion); 3088 system_set_mldversion(dev, buf); 3089 } 3090 if (apply_mask & DEV_OPT_NEIGH4REACHABLETIME) { 3091 snprintf(buf, sizeof(buf), "%u", s->neigh4reachabletime); 3092 system_set_neigh4reachabletime(dev, buf); 3093 } 3094 if (apply_mask & DEV_OPT_NEIGH6REACHABLETIME) { 3095 snprintf(buf, sizeof(buf), "%u", s->neigh6reachabletime); 3096 system_set_neigh6reachabletime(dev, buf); 3097 } 3098 if (apply_mask & DEV_OPT_NEIGHLOCKTIME) { 3099 snprintf(buf, sizeof(buf), "%d", s->neigh4locktime); 3100 system_set_neigh4locktime(dev, buf); 3101 } 3102 if (apply_mask & DEV_OPT_NEIGHGCSTALETIME) { 3103 snprintf(buf, sizeof(buf), "%u", s->neigh4gcstaletime); 3104 system_set_neigh4gcstaletime(dev, buf); 3105 snprintf(buf, sizeof(buf), "%u", s->neigh6gcstaletime); 3106 system_set_neigh6gcstaletime(dev, buf); 3107 } 3108 if (apply_mask & DEV_OPT_DADTRANSMITS) { 3109 snprintf(buf, sizeof(buf), "%u", s->dadtransmits); 3110 system_set_dadtransmits(dev, buf); 3111 } 3112 if (apply_mask & DEV_OPT_RTRSOLICITS) { 3113 snprintf(buf, sizeof(buf), "%d", s->rtrsolicits); 3114 system_set_rtrsolicits(dev, buf); 3115 } 3116 if (apply_mask & DEV_OPT_RTRSOLICITINTERVAL) { 3117 snprintf(buf, sizeof(buf), "%u", s->rtrsolicitinterval); 3118 system_set_rtrsolicitinterval(dev, buf); 3119 } 3120 if (apply_mask & DEV_OPT_NEIGH6RETRANSTIME) { 3121 snprintf(buf, sizeof(buf), "%u", s->neigh6retranstime); 3122 system_set_neigh6retranstime(dev, buf); 3123 } 3124 if (apply_mask & DEV_OPT_NEIGH4RETRANSTIME) { 3125 snprintf(buf, sizeof(buf), "%u", s->neigh4retranstime); 3126 system_set_neigh4retranstime(dev, buf); 3127 } 3128 if (apply_mask & DEV_OPT_NEIGH4MCASTSOLICIT) { 3129 snprintf(buf, sizeof(buf), "%u", s->neigh4mcastsolicit); 3130 system_set_neigh4mcastsolicit(dev, buf); 3131 } 3132 if (apply_mask & DEV_OPT_PROXY_ARP) 3133 system_set_proxy_arp(dev, s->proxy_arp ? "1" : ""); 3134 /* IFF_NOARP also turns off IPv6 neighbour discovery on the device. */ 3135 if (apply_mask & DEV_OPT_ARP) { 3136 if (system_if_flags(dev->ifname, !s->arp ? IFF_NOARP : 0, 3137 s->arp ? IFF_NOARP : 0) < 0) 3138 s->flags &= ~DEV_OPT_ARP; 3139 } 3140 if (apply_mask & DEV_OPT_MULTICAST) { 3141 if (system_if_flags(dev->ifname, s->multicast ? IFF_MULTICAST : 0, 3142 !s->multicast ? IFF_MULTICAST : 0) < 0) 3143 s->flags &= ~DEV_OPT_MULTICAST; 3144 } 3145 if (apply_mask & DEV_OPT_SENDREDIRECTS) 3146 system_set_sendredirects(dev, s->sendredirects ? "1" : ""); 3147 if (apply_mask & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST) 3148 system_set_drop_v4_unicast_in_l2_multicast(dev, s->drop_v4_unicast_in_l2_multicast ? "1" : ""); 3149 if (apply_mask & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST) 3150 system_set_drop_v6_unicast_in_l2_multicast(dev, s->drop_v6_unicast_in_l2_multicast ? "1" : ""); 3151 if (apply_mask & DEV_OPT_DROP_GRATUITOUS_ARP) 3152 system_set_drop_gratuitous_arp(dev, s->drop_gratuitous_arp ? "1" : ""); 3153 if (apply_mask & DEV_OPT_DROP_UNSOLICITED_NA) 3154 system_set_drop_unsolicited_na(dev, s->drop_unsolicited_na ? "1" : ""); 3155 if (apply_mask & DEV_OPT_ARP_ACCEPT) 3156 system_set_arp_accept(dev, s->arp_accept ? "1" : ""); 3157 if (apply_mask & (DEV_OPT_SPEED | DEV_OPT_DUPLEX | 3158 DEV_OPT_PAUSE | DEV_OPT_ASYM_PAUSE | 3159 DEV_OPT_RXPAUSE | DEV_OPT_TXPAUSE | 3160 DEV_OPT_AUTONEG | DEV_OPT_EEE | 3161 DEV_OPT_PSE | DEV_OPT_PSE_PODL | 3162 DEV_OPT_PSE_POWER_LIMIT | DEV_OPT_PSE_PRIORITY)) 3163 system_set_ethtool_settings(dev, s); 3164 } 3165 3166 void system_if_apply_settings_after_up(struct device *dev, struct device_settings *s) 3167 { 3168 system_set_ethtool_settings_after_up(dev, s); 3169 } 3170 3171 int system_if_up(struct device *dev) 3172 { 3173 return system_if_flags(dev->ifname, IFF_UP, 0); 3174 } 3175 3176 int system_if_down(struct device *dev) 3177 { 3178 return system_if_flags(dev->ifname, 0, IFF_UP); 3179 } 3180 3181 bool system_if_is_point_to_point(struct device *dev) 3182 { 3183 struct ifreq ifr = {}; 3184 3185 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 3186 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) < 0) 3187 return false; 3188 3189 return ifr.ifr_flags & IFF_POINTOPOINT; 3190 } 3191 3192 struct if_check_data { 3193 struct device *dev; 3194 int pending; 3195 int ret; 3196 unsigned int flags; 3197 bool valid; 3198 }; 3199 3200 static int cb_if_check_valid(struct nl_msg *msg, void *arg) 3201 { 3202 struct nlmsghdr *nh = nlmsg_hdr(msg); 3203 struct ifinfomsg *ifi = NLMSG_DATA(nh); 3204 struct if_check_data *chk = (struct if_check_data *)arg; 3205 3206 if (nh->nlmsg_type != RTM_NEWLINK) 3207 return NL_SKIP; 3208 3209 chk->flags = ifi->ifi_flags; 3210 chk->valid = true; 3211 return NL_OK; 3212 } 3213 3214 static int cb_if_check_ack(struct nl_msg *msg, void *arg) 3215 { 3216 struct if_check_data *chk = (struct if_check_data *)arg; 3217 chk->pending = 0; 3218 return NL_STOP; 3219 } 3220 3221 static int cb_if_check_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) 3222 { 3223 struct if_check_data *chk = (struct if_check_data *)arg; 3224 3225 chk->pending = err->error; 3226 3227 return NL_STOP; 3228 } 3229 3230 struct bridge_vlan_check_data { 3231 struct device *check_dev; 3232 const struct bridge_port_vlan *vlans; 3233 const struct device_vlan_range *ranges; 3234 bool *seen; 3235 int n_vlans; 3236 int n_ranges; 3237 int ifindex; 3238 int ret; 3239 bool pending; 3240 }; 3241 3242 static void bridge_vlan_check_mismatch(struct bridge_vlan_check_data *data) 3243 { 3244 data->ret = 1; 3245 data->pending = false; 3246 } 3247 3248 static void bridge_vlan_check_port(struct bridge_vlan_check_data *data, 3249 const struct bridge_port_vlan *vlan, 3250 struct bridge_vlan_info *vinfo) 3251 { 3252 uint16_t flags = 0, mask; 3253 3254 if (vlan->flags & BRVLAN_F_PVID) 3255 flags |= BRIDGE_VLAN_INFO_PVID; 3256 if (vlan->flags & BRVLAN_F_UNTAGGED) 3257 flags |= BRIDGE_VLAN_INFO_UNTAGGED; 3258 3259 data->seen[vlan - data->vlans] = true; 3260 3261 mask = BRIDGE_VLAN_INFO_UNTAGGED | (flags & BRIDGE_VLAN_INFO_PVID); 3262 if ((vinfo->flags ^ flags) & mask) 3263 bridge_vlan_check_mismatch(data); 3264 } 3265 3266 static bool bridge_vlan_check_in_range(struct bridge_vlan_check_data *data, 3267 uint16_t vid) 3268 { 3269 int i; 3270 3271 for (i = 0; i < data->n_ranges; i++) 3272 if (vid >= data->ranges[i].start && vid <= data->ranges[i].end) 3273 return true; 3274 3275 return false; 3276 } 3277 3278 static void bridge_vlan_check_attr(struct bridge_vlan_check_data *data, 3279 struct rtattr *attr) 3280 { 3281 const struct bridge_port_vlan *vlan; 3282 struct bridge_vlan_info *vinfo; 3283 struct bridge_vlan *bvlan; 3284 struct rtattr *cur; 3285 int rem = RTA_PAYLOAD(attr); 3286 3287 for (cur = RTA_DATA(attr); RTA_OK(cur, rem); cur = RTA_NEXT(cur, rem)) { 3288 if (cur->rta_type != IFLA_BRIDGE_VLAN_INFO) 3289 continue; 3290 3291 vinfo = RTA_DATA(cur); 3292 bvlan = vlist_find(&data->check_dev->vlans, &vinfo->vid, bvlan, node); 3293 if (!bvlan) { 3294 if (bridge_vlan_check_in_range(data, vinfo->vid)) 3295 continue; 3296 3297 bridge_vlan_check_mismatch(data); 3298 return; 3299 } 3300 3301 vlan = bridge_port_vlan_find(data->vlans, data->n_vlans, vinfo->vid); 3302 if (vlan) 3303 bridge_vlan_check_port(data, vlan, vinfo); 3304 } 3305 } 3306 3307 static int bridge_vlan_check_cb(struct nl_msg *msg, void *arg) 3308 { 3309 struct bridge_vlan_check_data *data = arg; 3310 struct nlmsghdr *nh = nlmsg_hdr(msg); 3311 struct ifinfomsg *ifi = NLMSG_DATA(nh); 3312 struct rtattr *attr; 3313 int rem; 3314 3315 if (nh->nlmsg_type != RTM_NEWLINK) 3316 return NL_SKIP; 3317 3318 if (ifi->ifi_family != AF_BRIDGE) 3319 return NL_SKIP; 3320 3321 if (ifi->ifi_index != data->ifindex) 3322 return NL_SKIP; 3323 3324 attr = IFLA_RTA(ifi); 3325 rem = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); 3326 while (RTA_OK(attr, rem)) { 3327 if (attr->rta_type == IFLA_AF_SPEC) 3328 bridge_vlan_check_attr(data, attr); 3329 3330 attr = RTA_NEXT(attr, rem); 3331 } 3332 3333 return NL_SKIP; 3334 } 3335 3336 static int bridge_vlan_ack_cb(struct nl_msg *msg, void *arg) 3337 { 3338 struct bridge_vlan_check_data *data = arg; 3339 data->pending = false; 3340 return NL_STOP; 3341 } 3342 3343 static int bridge_vlan_error_cb(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) 3344 { 3345 struct bridge_vlan_check_data *data = arg; 3346 data->pending = false; 3347 return NL_STOP; 3348 } 3349 3350 int system_bridge_vlan_check(struct device *dev, const char *ifname, 3351 const struct bridge_port_vlan *vlans, int n_vlans, 3352 const struct device_vlan_range *ranges, int n_ranges) 3353 { 3354 struct bridge_vlan_check_data data = { 3355 .check_dev = dev, 3356 .vlans = vlans, 3357 .n_vlans = n_vlans, 3358 .ranges = ranges, 3359 .n_ranges = n_ranges, 3360 .ifindex = if_nametoindex(ifname), 3361 .ret = -1, 3362 .pending = true, 3363 }; 3364 static struct ifinfomsg ifi = { 3365 .ifi_family = AF_BRIDGE 3366 }; 3367 static struct rtattr ext_req = { 3368 .rta_type = IFLA_EXT_MASK, 3369 .rta_len = RTA_LENGTH(sizeof(uint32_t)), 3370 }; 3371 uint32_t filter = RTEXT_FILTER_BRVLAN; 3372 struct nl_cb *cb; 3373 struct nl_msg *msg; 3374 int i; 3375 3376 if (!data.ifindex) 3377 return 0; 3378 3379 cb = nl_cb_alloc(NL_CB_DEFAULT); 3380 msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP); 3381 if (!cb || !msg) 3382 goto free; 3383 3384 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) || 3385 nlmsg_append(msg, &ext_req, sizeof(ext_req), NLMSG_ALIGNTO) || 3386 nlmsg_append(msg, &filter, sizeof(filter), 0)) 3387 goto free; 3388 3389 data.seen = calloc(n_vlans + 1, sizeof(*data.seen)); 3390 if (!data.seen) 3391 goto free; 3392 3393 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, bridge_vlan_check_cb, &data); 3394 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, bridge_vlan_ack_cb, &data); 3395 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, bridge_vlan_ack_cb, &data); 3396 nl_cb_err(cb, NL_CB_CUSTOM, bridge_vlan_error_cb, &data); 3397 3398 if (nl_send_auto_complete(sock_rtnl, msg) < 0) 3399 goto free; 3400 3401 data.ret = 0; 3402 while (data.pending) 3403 if (nl_recvmsgs(sock_rtnl, cb) < 0) 3404 break; 3405 3406 for (i = 0; i < n_vlans; i++) 3407 if (!data.seen[i]) 3408 data.ret = 1; 3409 3410 free: 3411 free(data.seen); 3412 nlmsg_free(msg); 3413 nl_cb_put(cb); 3414 return data.ret; 3415 } 3416 3417 int system_if_check(struct device *dev) 3418 { 3419 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); 3420 struct nl_msg *msg; 3421 struct ifinfomsg ifi = { 3422 .ifi_family = AF_UNSPEC, 3423 .ifi_index = 0, 3424 }; 3425 struct if_check_data chk = { 3426 .dev = dev, 3427 .pending = 1, 3428 }; 3429 int ret = 1; 3430 3431 if (!cb) 3432 return ret; 3433 3434 msg = nlmsg_alloc_simple(RTM_GETLINK, 0); 3435 if (!msg) 3436 goto out; 3437 3438 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) || 3439 nla_put_string(msg, IFLA_IFNAME, dev->ifname)) 3440 goto free; 3441 3442 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_check_valid, &chk); 3443 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_check_ack, &chk); 3444 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_check_error, &chk); 3445 3446 if (nl_send_auto_complete(sock_rtnl, msg) < 0) 3447 goto free; 3448 3449 while (chk.pending > 0) 3450 if (nl_recvmsgs(sock_rtnl, cb) < 0) 3451 break; 3452 3453 /* a positive result tells the caller that no state was applied */ 3454 ret = chk.valid ? 0 : chk.pending; 3455 3456 /* 3457 * The state change notifies the device users, which can send their 3458 * own requests on sock_rtnl, so it must wait until this exchange 3459 * has been read completely. 3460 */ 3461 if (chk.valid) { 3462 system_device_update_state(dev, chk.flags); 3463 } else if (ret < 0) { 3464 if (dev->type == &simple_device_type) 3465 device_set_present(dev, false); 3466 device_set_link(dev, false); 3467 } 3468 3469 free: 3470 nlmsg_free(msg); 3471 out: 3472 nl_cb_put(cb); 3473 return ret; 3474 } 3475 3476 struct device * 3477 system_if_get_parent(struct device *dev) 3478 { 3479 char buf[64], *devname; 3480 int ifindex, iflink; 3481 3482 if (system_get_dev_sysfs("iflink", dev->ifname, buf, sizeof(buf)) < 0) 3483 return NULL; 3484 3485 iflink = strtoul(buf, NULL, 0); 3486 ifindex = system_if_resolve(dev); 3487 if (!iflink || iflink == ifindex) 3488 return NULL; 3489 3490 devname = if_indextoname(iflink, buf); 3491 if (!devname) 3492 return NULL; 3493 3494 return device_get(devname, true); 3495 } 3496 3497 static bool 3498 read_string_file(int dir_fd, const char *file, char *buf, int size) 3499 { 3500 bool ret = false; 3501 char *c; 3502 int fd, len; 3503 3504 fd = openat(dir_fd, file, O_RDONLY); 3505 if (fd < 0) 3506 return false; 3507 3508 retry: 3509 len = read(fd, buf, size - 1); 3510 if (len < 0) { 3511 if (errno == EINTR) 3512 goto retry; 3513 } else if (len > 0) { 3514 buf[len] = 0; 3515 3516 c = strchr(buf, '\n'); 3517 if (c) 3518 *c = 0; 3519 3520 ret = true; 3521 } 3522 3523 close(fd); 3524 3525 return ret; 3526 } 3527 3528 static bool 3529 read_uint64_file(int dir_fd, const char *file, uint64_t *val) 3530 { 3531 char buf[64]; 3532 bool ret = false; 3533 3534 ret = read_string_file(dir_fd, file, buf, sizeof(buf)); 3535 if (ret) 3536 *val = strtoull(buf, NULL, 0); 3537 3538 return ret; 3539 } 3540 3541 bool 3542 system_if_force_external(const char *ifname) 3543 { 3544 struct stat s; 3545 3546 return stat(dev_sysfs_path(ifname, "phy80211"), &s) == 0; 3547 } 3548 3549 static const char * 3550 system_netdevtype_name(unsigned short dev_type) 3551 { 3552 size_t i; 3553 3554 for (i = 0; i < ARRAY_SIZE(netdev_types); i++) { 3555 if (netdev_types[i].id == dev_type) 3556 return netdev_types[i].name; 3557 } 3558 3559 /* the last key is used by default */ 3560 i = ARRAY_SIZE(netdev_types) - 1; 3561 3562 return netdev_types[i].name; 3563 } 3564 3565 static void 3566 system_add_devtype(struct blob_buf *b, const char *ifname) 3567 { 3568 char buf[100]; 3569 bool found = false; 3570 3571 if (!system_get_dev_sysfs("uevent", ifname, buf, sizeof(buf))) { 3572 const char *info = "DEVTYPE="; 3573 char *context = NULL; 3574 const char *line = strtok_r(buf, "\r\n", &context); 3575 3576 while (line != NULL) { 3577 const char *index = strstr(line, info); 3578 3579 if (index != NULL) { 3580 blobmsg_add_string(b, "devtype", index + strlen(info)); 3581 found = true; 3582 break; 3583 } 3584 3585 line = strtok_r(NULL, "\r\n", &context); 3586 } 3587 } 3588 3589 if (!found) { 3590 unsigned short number = 0; 3591 const char *name = NULL; 3592 3593 if (!system_get_dev_sysfs("type", ifname, buf, sizeof(buf))) { 3594 number = strtoul(buf, NULL, 0); 3595 name = system_netdevtype_name(number); 3596 blobmsg_add_string(b, "devtype", name); 3597 } 3598 } 3599 } 3600 3601 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 3602 3603 static int32_t 3604 ethtool_feature_count(const char *ifname) 3605 { 3606 struct { 3607 struct ethtool_sset_info hdr; 3608 uint32_t buf; 3609 } req = { 3610 .hdr = { 3611 .cmd = ETHTOOL_GSSET_INFO, 3612 .sset_mask = 1 << ETH_SS_FEATURES 3613 } 3614 }; 3615 3616 struct ifreq ifr = { 3617 .ifr_data = (void *)&req 3618 }; 3619 3620 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 3621 3622 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) 3623 return -1; 3624 3625 if (!req.hdr.sset_mask) 3626 return 0; 3627 3628 return req.buf; 3629 } 3630 3631 static int32_t 3632 ethtool_feature_index(const char *ifname, const char *keyname) 3633 { 3634 struct ethtool_gstrings *feature_names; 3635 struct ifreq ifr = { 0 }; 3636 int32_t n_features; 3637 uint32_t i; 3638 3639 n_features = ethtool_feature_count(ifname); 3640 3641 if (n_features <= 0) 3642 return -1; 3643 3644 feature_names = calloc(1, sizeof(*feature_names) + n_features * ETH_GSTRING_LEN); 3645 3646 if (!feature_names) 3647 return -1; 3648 3649 feature_names->cmd = ETHTOOL_GSTRINGS; 3650 feature_names->string_set = ETH_SS_FEATURES; 3651 feature_names->len = n_features; 3652 3653 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 3654 ifr.ifr_data = (void *)feature_names; 3655 3656 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) { 3657 free(feature_names); 3658 3659 return -1; 3660 } 3661 3662 for (i = 0; i < feature_names->len; i++) 3663 if (!strcmp((char *)&feature_names->data[i * ETH_GSTRING_LEN], keyname)) 3664 break; 3665 3666 if (i >= feature_names->len) 3667 i = -1; 3668 3669 free(feature_names); 3670 3671 return i; 3672 } 3673 3674 static bool 3675 ethtool_feature_value(const char *ifname, const char *keyname) 3676 { 3677 struct ethtool_get_features_block *feature_block; 3678 struct ethtool_gfeatures *feature_values; 3679 struct ifreq ifr = { 0 }; 3680 int32_t feature_idx; 3681 bool active; 3682 3683 feature_idx = ethtool_feature_index(ifname, keyname); 3684 3685 if (feature_idx < 0) 3686 return false; 3687 3688 feature_values = calloc(1, 3689 sizeof(*feature_values) + 3690 sizeof(feature_values->features[0]) * (feature_idx / 32 + 1)); 3691 3692 if (!feature_values) 3693 return false; 3694 3695 feature_values->cmd = ETHTOOL_GFEATURES; 3696 feature_values->size = feature_idx / 32 + 1; 3697 3698 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 3699 ifr.ifr_data = (void *)feature_values; 3700 3701 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) { 3702 free(feature_values); 3703 3704 return false; 3705 } 3706 3707 feature_block = &feature_values->features[feature_idx / 32]; 3708 active = feature_block->active & (1U << feature_idx % 32); 3709 3710 free(feature_values); 3711 3712 return active; 3713 } 3714 3715 static void 3716 system_add_link_mode_name(struct blob_buf *b, int i, bool half) 3717 { 3718 char *buf; 3719 3720 /* allocate string buffer large enough for the mode name and a suffix 3721 * "-F" or "-H" indicating full duplex or half duplex. 3722 */ 3723 buf = blobmsg_alloc_string_buffer(b, NULL, strlen(ethtool_modes[i].name) + 3); 3724 if (!buf) 3725 return; 3726 3727 strcpy(buf, ethtool_modes[i].name); 3728 if (half) 3729 strcat(buf, "-H"); 3730 else 3731 strcat(buf, "-F"); 3732 3733 blobmsg_add_string_buffer(b); 3734 } 3735 3736 static void 3737 system_add_link_modes(__s8 nwords, struct blob_buf *b, __u32 *mask) 3738 { 3739 size_t i; 3740 3741 for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) { 3742 if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_half, mask)) 3743 system_add_link_mode_name(b, i, true); 3744 3745 if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_full, mask)) 3746 system_add_link_mode_name(b, i, false); 3747 } 3748 } 3749 3750 static void 3751 system_add_pause_modes(__s8 nwords, struct blob_buf *b, __u32 *mask) 3752 { 3753 if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, mask)) 3754 blobmsg_add_string(b, NULL, "pause"); 3755 3756 if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask)) 3757 blobmsg_add_string(b, NULL, "asym_pause"); 3758 } 3759 3760 3761 static void 3762 system_add_ethtool_pause_an(struct blob_buf *b, __s8 nwords, 3763 __u32 *advertising, __u32 *lp_advertising) 3764 { 3765 bool an_rx = false, an_tx = false; 3766 void *d; 3767 3768 d = blobmsg_open_array(b, "negotiated"); 3769 3770 /* Work out negotiated pause frame usage per 3771 * IEEE 802.3-2005 table 28B-3. 3772 */ 3773 if (ethtool_link_mode_test_bit(nwords, 3774 ETHTOOL_LINK_MODE_Pause_BIT, 3775 advertising) && 3776 ethtool_link_mode_test_bit(nwords, 3777 ETHTOOL_LINK_MODE_Pause_BIT, 3778 lp_advertising)) { 3779 an_tx = true; 3780 an_rx = true; 3781 } else if (ethtool_link_mode_test_bit(nwords, 3782 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 3783 advertising) && 3784 ethtool_link_mode_test_bit(nwords, 3785 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 3786 lp_advertising)) { 3787 if (ethtool_link_mode_test_bit(nwords, 3788 ETHTOOL_LINK_MODE_Pause_BIT, 3789 advertising)) 3790 an_rx = true; 3791 else if (ethtool_link_mode_test_bit(nwords, 3792 ETHTOOL_LINK_MODE_Pause_BIT, 3793 lp_advertising)) 3794 an_tx = true; 3795 } 3796 if (an_rx) 3797 blobmsg_add_string(b, NULL, "rx"); 3798 3799 if (an_tx) 3800 blobmsg_add_string(b, NULL, "tx"); 3801 3802 blobmsg_close_array(b, d); 3803 } 3804 3805 static void 3806 system_get_ethtool_pause(struct device *dev, bool *rx_pause, bool *tx_pause, bool *pause_autoneg) 3807 { 3808 struct ethtool_pauseparam pp; 3809 struct ifreq ifr = { 3810 .ifr_data = (caddr_t)&pp, 3811 }; 3812 3813 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 3814 memset(&pp, 0, sizeof(pp)); 3815 pp.cmd = ETHTOOL_GPAUSEPARAM; 3816 3817 /* may fail */ 3818 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == -1) { 3819 *pause_autoneg = true; 3820 return; 3821 } 3822 3823 *rx_pause = pp.rx_pause; 3824 *tx_pause = pp.tx_pause; 3825 *pause_autoneg = pp.autoneg; 3826 } 3827 3828 int 3829 system_if_dump_info(struct device *dev, struct blob_buf *b) 3830 { 3831 __u32 *supported, *advertising, *lp_advertising; 3832 bool rx_pause = false, tx_pause = false, pause_autoneg; 3833 struct { 3834 struct ethtool_link_settings req; 3835 __u32 link_mode_data[3 * 127]; 3836 } ecmd; 3837 struct ifreq ifr = { 3838 .ifr_data = (caddr_t)&ecmd, 3839 }; 3840 __s8 nwords; 3841 void *c, *d; 3842 char *s; 3843 3844 system_get_ethtool_pause(dev, &rx_pause, &tx_pause, &pause_autoneg); 3845 3846 memset(&ecmd, 0, sizeof(ecmd)); 3847 ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; 3848 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 3849 3850 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 3851 ecmd.req.link_mode_masks_nwords >= 0 || 3852 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 3853 return -EOPNOTSUPP; 3854 3855 ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords; 3856 3857 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 3858 ecmd.req.link_mode_masks_nwords <= 0 || 3859 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 3860 return -EIO; 3861 3862 nwords = ecmd.req.link_mode_masks_nwords; 3863 supported = &ecmd.link_mode_data[0]; 3864 advertising = &ecmd.link_mode_data[nwords]; 3865 lp_advertising = &ecmd.link_mode_data[2 * nwords]; 3866 3867 c = blobmsg_open_array(b, "link-advertising"); 3868 system_add_link_modes(nwords, b, advertising); 3869 blobmsg_close_array(b, c); 3870 3871 c = blobmsg_open_array(b, "link-partner-advertising"); 3872 system_add_link_modes(nwords, b, lp_advertising); 3873 blobmsg_close_array(b, c); 3874 3875 c = blobmsg_open_array(b, "link-supported"); 3876 system_add_link_modes(nwords, b, supported); 3877 blobmsg_close_array(b, c); 3878 3879 if (ethtool_validate_speed(ecmd.req.speed) && 3880 (ecmd.req.speed != (__u32)SPEED_UNKNOWN) && 3881 (ecmd.req.speed != 0)) { 3882 s = blobmsg_alloc_string_buffer(b, "speed", 10); 3883 snprintf(s, 8, "%d%c", ecmd.req.speed, 3884 ecmd.req.duplex == DUPLEX_HALF ? 'H' : 'F'); 3885 blobmsg_add_string_buffer(b); 3886 } 3887 blobmsg_add_u8(b, "autoneg", !!ecmd.req.autoneg); 3888 3889 c = blobmsg_open_table(b, "flow-control"); 3890 blobmsg_add_u8(b, "autoneg", pause_autoneg); 3891 3892 d = blobmsg_open_array(b, "supported"); 3893 system_add_pause_modes(nwords, b, supported); 3894 blobmsg_close_array(b, d); 3895 3896 if (pause_autoneg) { 3897 d = blobmsg_open_array(b, "link-advertising"); 3898 system_add_pause_modes(nwords, b, advertising); 3899 blobmsg_close_array(b, d); 3900 } 3901 3902 d = blobmsg_open_array(b, "link-partner-advertising"); 3903 system_add_pause_modes(nwords, b, lp_advertising); 3904 blobmsg_close_array(b, d); 3905 3906 if (pause_autoneg) { 3907 system_add_ethtool_pause_an(b, nwords, advertising, 3908 lp_advertising); 3909 } else { 3910 d = blobmsg_open_array(b, "selected"); 3911 if (rx_pause) 3912 blobmsg_add_string(b, NULL, "rx"); 3913 3914 if (tx_pause) 3915 blobmsg_add_string(b, NULL, "tx"); 3916 3917 blobmsg_close_array(b, d); 3918 } 3919 3920 blobmsg_close_table(b, c); 3921 3922 blobmsg_add_u8(b, "hw-tc-offload", 3923 ethtool_feature_value(dev->ifname, "hw-tc-offload")); 3924 3925 system_add_devtype(b, dev->ifname); 3926 3927 /* Add PSE (PoE) status if available */ 3928 { 3929 struct pse_reply_data pse_data; 3930 if (system_pse_get(dev, &pse_data) == 0) { 3931 void *pse_tbl = blobmsg_open_table(b, "pse"); 3932 3933 /* C33 (Clause 33 PoE) status */ 3934 if (pse_data.c33_admin_state) { 3935 const char *state = "unknown"; 3936 switch (pse_data.c33_admin_state) { 3937 case ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED: 3938 state = "disabled"; 3939 break; 3940 case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED: 3941 state = "enabled"; 3942 break; 3943 } 3944 blobmsg_add_string(b, "c33-admin-state", state); 3945 } 3946 3947 if (pse_data.c33_pw_status) { 3948 const char *status = "unknown"; 3949 switch (pse_data.c33_pw_status) { 3950 case ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED: 3951 status = "disabled"; 3952 break; 3953 case ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING: 3954 status = "searching"; 3955 break; 3956 case ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING: 3957 status = "delivering"; 3958 break; 3959 case ETHTOOL_C33_PSE_PW_D_STATUS_TEST: 3960 status = "test"; 3961 break; 3962 case ETHTOOL_C33_PSE_PW_D_STATUS_FAULT: 3963 status = "fault"; 3964 break; 3965 case ETHTOOL_C33_PSE_PW_D_STATUS_OTHERFAULT: 3966 status = "otherfault"; 3967 break; 3968 } 3969 blobmsg_add_string(b, "c33-power-status", status); 3970 } 3971 3972 if (pse_data.c33_pw_class) 3973 blobmsg_add_u32(b, "c33-power-class", pse_data.c33_pw_class); 3974 3975 if (pse_data.c33_actual_pw) 3976 blobmsg_add_u32(b, "c33-actual-power", pse_data.c33_actual_pw); 3977 3978 if (pse_data.c33_avail_pw_limit) 3979 blobmsg_add_u32(b, "c33-available-power-limit", pse_data.c33_avail_pw_limit); 3980 3981 /* PoDL (Power over Data Line) status */ 3982 if (pse_data.podl_admin_state) { 3983 const char *state = "unknown"; 3984 switch (pse_data.podl_admin_state) { 3985 case ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED: 3986 state = "disabled"; 3987 break; 3988 case ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED: 3989 state = "enabled"; 3990 break; 3991 } 3992 blobmsg_add_string(b, "podl-admin-state", state); 3993 } 3994 3995 if (pse_data.podl_pw_status) { 3996 const char *status = "unknown"; 3997 switch (pse_data.podl_pw_status) { 3998 case ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED: 3999 status = "disabled"; 4000 break; 4001 case ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING: 4002 status = "searching"; 4003 break; 4004 case ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING: 4005 status = "delivering"; 4006 break; 4007 case ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP: 4008 status = "sleep"; 4009 break; 4010 case ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE: 4011 status = "idle"; 4012 break; 4013 case ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR: 4014 status = "error"; 4015 break; 4016 } 4017 blobmsg_add_string(b, "podl-power-status", status); 4018 } 4019 4020 /* Priority settings */ 4021 if (pse_data.pse_prio_max) 4022 blobmsg_add_u32(b, "priority-max", pse_data.pse_prio_max); 4023 4024 if (pse_data.pse_prio) 4025 blobmsg_add_u32(b, "priority", pse_data.pse_prio); 4026 4027 blobmsg_close_table(b, pse_tbl); 4028 } 4029 } 4030 4031 return 0; 4032 } 4033 4034 int 4035 system_if_dump_stats(struct device *dev, struct blob_buf *b) 4036 { 4037 const char *const counters[] = { 4038 "collisions", "rx_frame_errors", "tx_compressed", 4039 "multicast", "rx_length_errors", "tx_dropped", 4040 "rx_bytes", "rx_missed_errors", "tx_errors", 4041 "rx_compressed", "rx_over_errors", "tx_fifo_errors", 4042 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors", 4043 "rx_dropped", "tx_aborted_errors", "tx_packets", 4044 "rx_errors", "tx_bytes", "tx_window_errors", 4045 "rx_fifo_errors", "tx_carrier_errors", 4046 }; 4047 int stats_dir; 4048 size_t i; 4049 uint64_t val = 0; 4050 4051 stats_dir = open(dev_sysfs_path(dev->ifname, "statistics"), O_DIRECTORY); 4052 if (stats_dir < 0) 4053 return -1; 4054 4055 for (i = 0; i < ARRAY_SIZE(counters); i++) 4056 if (read_uint64_file(stats_dir, counters[i], &val)) 4057 blobmsg_add_u64(b, counters[i], val); 4058 4059 close(stats_dir); 4060 return 0; 4061 } 4062 4063 static int system_addr(struct device *dev, struct device_addr *addr, int cmd) 4064 { 4065 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4); 4066 int alen = v4 ? 4 : 16; 4067 unsigned int flags = 0; 4068 struct ifaddrmsg ifa = { 4069 .ifa_family = (alen == 4) ? AF_INET : AF_INET6, 4070 .ifa_prefixlen = addr->mask, 4071 .ifa_index = dev->ifindex, 4072 }; 4073 4074 struct nl_msg *msg; 4075 if (cmd == RTM_NEWADDR) 4076 flags |= NLM_F_CREATE | NLM_F_REPLACE; 4077 4078 msg = nlmsg_alloc_simple(cmd, flags); 4079 if (!msg) 4080 return -1; 4081 4082 nlmsg_append(msg, &ifa, sizeof(ifa), 0); 4083 nla_put(msg, IFA_LOCAL, alen, &addr->addr); 4084 if (v4) { 4085 if (addr->broadcast) 4086 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast); 4087 if (addr->point_to_point) 4088 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point); 4089 } else { 4090 time_t now = system_get_rtime(); 4091 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0}; 4092 4093 if (addr->preferred_until) { 4094 int64_t preferred = addr->preferred_until - now; 4095 if (preferred < 0) 4096 preferred = 0; 4097 else if (preferred > UINT32_MAX) 4098 preferred = UINT32_MAX; 4099 4100 cinfo.ifa_prefered = preferred; 4101 } 4102 4103 if (addr->valid_until) { 4104 int64_t valid = addr->valid_until - now; 4105 if (valid <= 0) { 4106 nlmsg_free(msg); 4107 return -1; 4108 } 4109 else if (valid > UINT32_MAX) 4110 valid = UINT32_MAX; 4111 4112 cinfo.ifa_valid = valid; 4113 } 4114 4115 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo); 4116 4117 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK) && 4118 !system_if_is_point_to_point(dev)) 4119 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE); 4120 } 4121 4122 return system_rtnl_call(msg); 4123 } 4124 4125 int system_add_address(struct device *dev, struct device_addr *addr) 4126 { 4127 return system_addr(dev, addr, RTM_NEWADDR); 4128 } 4129 4130 int system_del_address(struct device *dev, struct device_addr *addr) 4131 { 4132 return system_addr(dev, addr, RTM_DELADDR); 4133 } 4134 4135 static int system_neigh(struct device *dev, struct device_neighbor *neighbor, int cmd) 4136 { 4137 int alen = ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16; 4138 unsigned int flags = 0; 4139 struct ndmsg ndm = { 4140 .ndm_family = (alen == 4) ? AF_INET : AF_INET6, 4141 .ndm_ifindex = dev->ifindex, 4142 .ndm_state = NUD_PERMANENT, 4143 .ndm_flags = (neighbor->proxy ? NTF_PROXY : 0) | (neighbor->router ? NTF_ROUTER : 0), 4144 }; 4145 struct nl_msg *msg; 4146 4147 if (cmd == RTM_NEWNEIGH) 4148 flags |= NLM_F_CREATE | NLM_F_REPLACE; 4149 4150 msg = nlmsg_alloc_simple(cmd, flags); 4151 4152 if (!msg) 4153 return -1; 4154 4155 nlmsg_append(msg, &ndm, sizeof(ndm), 0); 4156 4157 nla_put(msg, NDA_DST, alen, &neighbor->addr); 4158 if (neighbor->flags & DEVNEIGH_MAC) 4159 nla_put(msg, NDA_LLADDR, sizeof(neighbor->macaddr), &neighbor->macaddr); 4160 4161 4162 return system_rtnl_call(msg); 4163 } 4164 4165 int system_add_neighbor(struct device *dev, struct device_neighbor *neighbor) 4166 { 4167 return system_neigh(dev, neighbor, RTM_NEWNEIGH); 4168 } 4169 4170 int system_del_neighbor(struct device *dev, struct device_neighbor *neighbor) 4171 { 4172 return system_neigh(dev, neighbor, RTM_DELNEIGH); 4173 } 4174 4175 static int system_rt(struct device *dev, struct device_route *route, int cmd) 4176 { 4177 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16; 4178 bool have_gw; 4179 unsigned int flags = 0; 4180 4181 if (alen == 4) 4182 have_gw = !!route->nexthop.in.s_addr; 4183 else 4184 have_gw = route->nexthop.in6.s6_addr32[0] || 4185 route->nexthop.in6.s6_addr32[1] || 4186 route->nexthop.in6.s6_addr32[2] || 4187 route->nexthop.in6.s6_addr32[3]; 4188 4189 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE)) 4190 ? route->table : RT_TABLE_MAIN; 4191 4192 struct rtmsg rtm = { 4193 .rtm_family = (alen == 4) ? AF_INET : AF_INET6, 4194 .rtm_dst_len = route->mask, 4195 .rtm_src_len = route->sourcemask, 4196 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC, 4197 .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC, 4198 .rtm_scope = RT_SCOPE_NOWHERE, 4199 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST, 4200 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0, 4201 }; 4202 struct nl_msg *msg; 4203 4204 if (cmd == RTM_NEWROUTE) { 4205 flags |= NLM_F_CREATE | NLM_F_REPLACE; 4206 4207 if (!dev) { /* Add null-route */ 4208 rtm.rtm_scope = RT_SCOPE_UNIVERSE; 4209 rtm.rtm_type = RTN_UNREACHABLE; 4210 } 4211 else 4212 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK; 4213 } 4214 4215 if (route->flags & DEVROUTE_TYPE) { 4216 rtm.rtm_type = route->type; 4217 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) { 4218 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST || 4219 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST) 4220 rtm.rtm_table = RT_TABLE_LOCAL; 4221 } 4222 4223 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) { 4224 rtm.rtm_scope = RT_SCOPE_HOST; 4225 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST || 4226 rtm.rtm_type == RTN_ANYCAST) { 4227 rtm.rtm_scope = RT_SCOPE_LINK; 4228 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE || 4229 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY || 4230 rtm.rtm_type == RTN_THROW) { 4231 rtm.rtm_scope = RT_SCOPE_UNIVERSE; 4232 dev = NULL; 4233 } 4234 } 4235 4236 if (route->flags & DEVROUTE_NODEV) 4237 dev = NULL; 4238 4239 msg = nlmsg_alloc_simple(cmd, flags); 4240 if (!msg) 4241 return -1; 4242 4243 nlmsg_append(msg, &rtm, sizeof(rtm), 0); 4244 4245 if (route->mask) 4246 nla_put(msg, RTA_DST, alen, &route->addr); 4247 4248 if (route->sourcemask) { 4249 if (rtm.rtm_family == AF_INET) 4250 nla_put(msg, RTA_PREFSRC, alen, &route->source); 4251 else 4252 nla_put(msg, RTA_SRC, alen, &route->source); 4253 } 4254 4255 if (route->metric > 0) 4256 nla_put_u32(msg, RTA_PRIORITY, route->metric); 4257 4258 if (have_gw) 4259 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop); 4260 4261 if (dev) 4262 nla_put_u32(msg, RTA_OIF, dev->ifindex); 4263 4264 if (table >= 256) 4265 nla_put_u32(msg, RTA_TABLE, table); 4266 4267 if (route->flags & DEVROUTE_MTU) { 4268 struct nlattr *metrics; 4269 4270 if (!(metrics = nla_nest_start(msg, RTA_METRICS))) 4271 goto nla_put_failure; 4272 4273 nla_put_u32(msg, RTAX_MTU, route->mtu); 4274 4275 nla_nest_end(msg, metrics); 4276 } 4277 4278 return system_rtnl_call(msg); 4279 4280 nla_put_failure: 4281 nlmsg_free(msg); 4282 return -ENOMEM; 4283 } 4284 4285 int system_add_route(struct device *dev, struct device_route *route) 4286 { 4287 return system_rt(dev, route, RTM_NEWROUTE); 4288 } 4289 4290 int system_del_route(struct device *dev, struct device_route *route) 4291 { 4292 return system_rt(dev, route, RTM_DELROUTE); 4293 } 4294 4295 int system_flush_routes(void) 4296 { 4297 const char *names[] = { "ipv4", "ipv6" }; 4298 size_t i; 4299 int fd; 4300 4301 for (i = 0; i < ARRAY_SIZE(names); i++) { 4302 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/route/flush", proc_path, names[i]); 4303 fd = open(dev_buf, O_WRONLY); 4304 if (fd < 0) 4305 continue; 4306 4307 if (write(fd, "-1", 2)) {} 4308 close(fd); 4309 } 4310 return 0; 4311 } 4312 4313 bool system_resolve_rt_type(const char *type, unsigned int *id) 4314 { 4315 return system_rtn_aton(type, id); 4316 } 4317 4318 bool system_resolve_rt_proto(const char *type, unsigned int *id) 4319 { 4320 FILE *f; 4321 char *e, buf[128]; 4322 unsigned int n, proto = 256; 4323 n = strtoul(type, &e, 0); 4324 if (!*e && e != type) 4325 proto = n; 4326 else if (!strcmp(type, "unspec")) 4327 proto = RTPROT_UNSPEC; 4328 else if (!strcmp(type, "kernel")) 4329 proto = RTPROT_KERNEL; 4330 else if (!strcmp(type, "boot")) 4331 proto = RTPROT_BOOT; 4332 else if (!strcmp(type, "static")) 4333 proto = RTPROT_STATIC; 4334 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) { 4335 while (fgets(buf, sizeof(buf) - 1, f) != NULL) { 4336 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#') 4337 continue; 4338 4339 n = strtoul(e, NULL, 10); 4340 e = strtok(NULL, " \t\n"); 4341 4342 if (e && !strcmp(e, type)) { 4343 proto = n; 4344 break; 4345 } 4346 } 4347 fclose(f); 4348 } 4349 4350 if (proto > 255) 4351 return false; 4352 4353 *id = proto; 4354 return true; 4355 } 4356 4357 bool system_resolve_rt_table(const char *name, unsigned int *id) 4358 { 4359 FILE *f; 4360 char *e, buf[128]; 4361 unsigned int n, table = RT_TABLE_UNSPEC; 4362 4363 /* first try to parse table as number */ 4364 if ((n = strtoul(name, &e, 0)) > 0 && !*e) 4365 table = n; 4366 4367 /* handle well known aliases */ 4368 else if (!strcmp(name, "default")) 4369 table = RT_TABLE_DEFAULT; 4370 else if (!strcmp(name, "main")) 4371 table = RT_TABLE_MAIN; 4372 else if (!strcmp(name, "local")) 4373 table = RT_TABLE_LOCAL; 4374 4375 /* try to look up name in /etc/iproute2/rt_tables */ 4376 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL) 4377 { 4378 while (fgets(buf, sizeof(buf) - 1, f) != NULL) 4379 { 4380 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#') 4381 continue; 4382 4383 n = strtoul(e, NULL, 10); 4384 e = strtok(NULL, " \t\n"); 4385 4386 if (e && !strcmp(e, name)) 4387 { 4388 table = n; 4389 break; 4390 } 4391 } 4392 4393 fclose(f); 4394 } 4395 4396 if (table == RT_TABLE_UNSPEC) 4397 return false; 4398 4399 *id = table; 4400 return true; 4401 } 4402 4403 bool system_is_default_rt_table(unsigned int id) 4404 { 4405 return (id == RT_TABLE_MAIN); 4406 } 4407 4408 bool system_resolve_rpfilter(const char *filter, unsigned int *id) 4409 { 4410 char *e; 4411 unsigned int n; 4412 4413 if (!strcmp(filter, "strict")) 4414 n = 1; 4415 else if (!strcmp(filter, "loose")) 4416 n = 2; 4417 else { 4418 n = strtoul(filter, &e, 0); 4419 if (*e || e == filter || n > 2) 4420 return false; 4421 } 4422 4423 *id = n; 4424 return true; 4425 } 4426 4427 static int system_iprule(struct iprule *rule, int cmd) 4428 { 4429 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16; 4430 4431 struct nl_msg *msg; 4432 struct rtmsg rtm = { 4433 .rtm_family = (alen == 4) ? AF_INET : AF_INET6, 4434 .rtm_protocol = RTPROT_STATIC, 4435 .rtm_scope = RT_SCOPE_UNIVERSE, 4436 .rtm_table = RT_TABLE_UNSPEC, 4437 .rtm_type = RTN_UNSPEC, 4438 .rtm_flags = 0, 4439 }; 4440 4441 if (cmd == RTM_NEWRULE) 4442 rtm.rtm_type = RTN_UNICAST; 4443 4444 if (rule->invert) 4445 rtm.rtm_flags |= FIB_RULE_INVERT; 4446 4447 if (rule->flags & IPRULE_SRC) 4448 rtm.rtm_src_len = rule->src_mask; 4449 4450 if (rule->flags & IPRULE_DEST) 4451 rtm.rtm_dst_len = rule->dest_mask; 4452 4453 if (rule->flags & IPRULE_TOS) 4454 rtm.rtm_tos = rule->tos; 4455 4456 if (rule->flags & IPRULE_LOOKUP) { 4457 if (rule->lookup < 256) 4458 rtm.rtm_table = rule->lookup; 4459 } 4460 4461 if (rule->flags & IPRULE_ACTION) 4462 rtm.rtm_type = rule->action; 4463 else if (rule->flags & IPRULE_GOTO) 4464 rtm.rtm_type = FR_ACT_GOTO; 4465 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO))) 4466 rtm.rtm_type = FR_ACT_NOP; 4467 4468 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST); 4469 4470 if (!msg) 4471 return -1; 4472 4473 nlmsg_append(msg, &rtm, sizeof(rtm), 0); 4474 4475 if (rule->flags & IPRULE_IN) 4476 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev); 4477 4478 if (rule->flags & IPRULE_OUT) 4479 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev); 4480 4481 if (rule->flags & IPRULE_SRC) 4482 nla_put(msg, FRA_SRC, alen, &rule->src_addr); 4483 4484 if (rule->flags & IPRULE_DEST) 4485 nla_put(msg, FRA_DST, alen, &rule->dest_addr); 4486 4487 if (rule->flags & IPRULE_PRIORITY) 4488 nla_put_u32(msg, FRA_PRIORITY, rule->priority); 4489 else 4490 nla_put_u32(msg, FRA_PRIORITY, rule->order); 4491 4492 if (rule->flags & IPRULE_FWMARK) 4493 nla_put_u32(msg, FRA_FWMARK, rule->fwmark); 4494 4495 if (rule->flags & IPRULE_FWMASK) 4496 nla_put_u32(msg, FRA_FWMASK, rule->fwmask); 4497 4498 if (rule->flags & IPRULE_LOOKUP) { 4499 if (rule->lookup >= 256) 4500 nla_put_u32(msg, FRA_TABLE, rule->lookup); 4501 } 4502 4503 if (rule->flags & IPRULE_SUP_PREFIXLEN) 4504 nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen); 4505 4506 if (rule->flags & IPRULE_UIDRANGE) { 4507 struct fib_rule_uid_range uidrange = { 4508 .start = rule->uidrange_start, 4509 .end = rule->uidrange_end 4510 }; 4511 4512 nla_put(msg, FRA_UID_RANGE, sizeof(uidrange), &uidrange); 4513 } 4514 4515 if (rule->flags & IPRULE_GOTO) 4516 nla_put_u32(msg, FRA_GOTO, rule->gotoid); 4517 4518 if (rule->flags & IPRULE_IPPROTO) 4519 nla_put_u8(msg, FRA_IP_PROTO, rule->ipproto); 4520 4521 if (rule->flags & IPRULE_SPORT) { 4522 struct fib_rule_port_range sportrange = { 4523 .start = rule->sport_start, 4524 .end = rule->sport_end 4525 }; 4526 4527 nla_put(msg, FRA_SPORT_RANGE, sizeof(sportrange), &sportrange); 4528 } 4529 4530 if (rule->flags & IPRULE_DPORT) { 4531 struct fib_rule_port_range dportrange = { 4532 .start = rule->dport_start, 4533 .end = rule->dport_end 4534 }; 4535 4536 nla_put(msg, FRA_DPORT_RANGE, sizeof(dportrange), &dportrange); 4537 } 4538 4539 return system_rtnl_call(msg); 4540 } 4541 4542 int system_add_iprule(struct iprule *rule) 4543 { 4544 return system_iprule(rule, RTM_NEWRULE); 4545 } 4546 4547 int system_del_iprule(struct iprule *rule) 4548 { 4549 return system_iprule(rule, RTM_DELRULE); 4550 } 4551 4552 int system_flush_iprules(void) 4553 { 4554 int rv = 0; 4555 struct iprule rule; 4556 4557 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET); 4558 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6); 4559 4560 memset(&rule, 0, sizeof(rule)); 4561 4562 4563 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP; 4564 4565 rule.priority = 0; 4566 rule.lookup = RT_TABLE_LOCAL; 4567 rv |= system_iprule(&rule, RTM_NEWRULE); 4568 4569 rule.priority = 32766; 4570 rule.lookup = RT_TABLE_MAIN; 4571 rv |= system_iprule(&rule, RTM_NEWRULE); 4572 4573 rule.priority = 32767; 4574 rule.lookup = RT_TABLE_DEFAULT; 4575 rv |= system_iprule(&rule, RTM_NEWRULE); 4576 4577 4578 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP; 4579 4580 rule.priority = 0; 4581 rule.lookup = RT_TABLE_LOCAL; 4582 rv |= system_iprule(&rule, RTM_NEWRULE); 4583 4584 rule.priority = 32766; 4585 rule.lookup = RT_TABLE_MAIN; 4586 rv |= system_iprule(&rule, RTM_NEWRULE); 4587 4588 return rv; 4589 } 4590 4591 bool system_resolve_iprule_action(const char *action, unsigned int *id) 4592 { 4593 return system_rtn_aton(action, id); 4594 } 4595 4596 bool system_resolve_iprule_ipproto(const char *name, unsigned int *id) 4597 { 4598 char *e; 4599 struct protoent *ent; 4600 unsigned int n, ipproto = 0; 4601 4602 if ((n = strtoul(name, &e, 0)) > 0 && *e == '\0') 4603 ipproto = n; 4604 else { 4605 ent = getprotobyname(name); 4606 4607 if (ent) 4608 ipproto = ent->p_proto; 4609 else 4610 return false; 4611 } 4612 4613 *id = ipproto; 4614 return true; 4615 } 4616 4617 time_t system_get_rtime(void) 4618 { 4619 struct timespec ts; 4620 struct timeval tv; 4621 4622 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) 4623 return ts.tv_sec; 4624 4625 if (gettimeofday(&tv, NULL) == 0) 4626 return tv.tv_sec; 4627 4628 return 0; 4629 } 4630 4631 #ifndef IP_DF 4632 #define IP_DF 0x4000 4633 #endif 4634 4635 static int tunnel_ioctl(const char *name, int cmd, void *p) 4636 { 4637 struct ifreq ifr; 4638 4639 memset(&ifr, 0, sizeof(ifr)); 4640 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1); 4641 ifr.ifr_ifru.ifru_data = p; 4642 return ioctl(sock_ioctl, cmd, &ifr); 4643 } 4644 4645 #ifdef IFLA_IPTUN_MAX 4646 static int system_add_ip6_tunnel(const char *name, const unsigned int link, 4647 struct blob_attr **tb) 4648 { 4649 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK, 4650 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 4651 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC }; 4652 struct blob_attr *cur; 4653 int ret = 0, ttl = 0; 4654 4655 if (!nlm) 4656 return -1; 4657 4658 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 4659 nla_put_string(nlm, IFLA_IFNAME, name); 4660 4661 if (link) 4662 nla_put_u32(nlm, IFLA_LINK, link); 4663 4664 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 4665 if (!linkinfo) { 4666 ret = -ENOMEM; 4667 goto failure; 4668 } 4669 4670 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl"); 4671 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 4672 if (!infodata) { 4673 ret = -ENOMEM; 4674 goto failure; 4675 } 4676 4677 if (link) 4678 nla_put_u32(nlm, IFLA_IPTUN_LINK, link); 4679 4680 if ((cur = tb[TUNNEL_ATTR_TTL])) 4681 ttl = blobmsg_get_u32(cur); 4682 4683 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP); 4684 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64); 4685 4686 struct in6_addr in6buf; 4687 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4688 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4689 ret = -EINVAL; 4690 goto failure; 4691 } 4692 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf); 4693 } 4694 4695 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4696 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4697 ret = -EINVAL; 4698 goto failure; 4699 } 4700 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf); 4701 } 4702 4703 if ((cur = tb[TUNNEL_ATTR_DATA])) { 4704 struct blob_attr *tb_data[__IPIP6_DATA_ATTR_MAX]; 4705 uint32_t tun_flags = IP6_TNL_F_IGN_ENCAP_LIMIT; 4706 4707 blobmsg_parse_attr(ipip6_data_attr_list.params, __IPIP6_DATA_ATTR_MAX, 4708 tb_data, cur); 4709 4710 if ((cur = tb_data[IPIP6_DATA_ENCAPLIMIT])) { 4711 char *str = blobmsg_get_string(cur); 4712 4713 if (strcmp(str, "ignore")) { 4714 char *e; 4715 unsigned encap_limit = strtoul(str, &e, 0); 4716 4717 if (e == str || *e || encap_limit > 255) { 4718 ret = -EINVAL; 4719 goto failure; 4720 } 4721 4722 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, encap_limit); 4723 tun_flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; 4724 } 4725 } 4726 4727 #ifdef IFLA_IPTUN_FMR_MAX 4728 if ((cur = tb_data[IPIP6_DATA_FMRS])) { 4729 struct blob_attr *rcur; 4730 unsigned rrem, fmrcnt = 0; 4731 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS); 4732 4733 if (!fmrs) { 4734 ret = -ENOMEM; 4735 goto failure; 4736 } 4737 4738 blobmsg_for_each_attr(rcur, cur, rrem) { 4739 struct blob_attr *tb_fmr[__FMR_DATA_ATTR_MAX], *tb_cur; 4740 struct in6_addr ip6prefix; 4741 struct in_addr ip4prefix; 4742 unsigned ip4len = 32, ip6len = 128, ealen, offset; 4743 4744 blobmsg_parse_attr(fmr_data_attr_list.params, __FMR_DATA_ATTR_MAX, 4745 tb_fmr, rcur); 4746 4747 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX6]) || 4748 !parse_ip_and_netmask(AF_INET6, 4749 blobmsg_data(tb_cur), &ip6prefix, 4750 &ip6len)) { 4751 ret = -EINVAL; 4752 goto failure; 4753 } 4754 4755 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX4]) || 4756 !parse_ip_and_netmask(AF_INET, 4757 blobmsg_data(tb_cur), &ip4prefix, 4758 &ip4len)) { 4759 ret = -EINVAL; 4760 goto failure; 4761 } 4762 4763 if (!(tb_cur = tb_fmr[FMR_DATA_EALEN])) { 4764 ret = -EINVAL; 4765 goto failure; 4766 } 4767 ealen = blobmsg_get_u32(tb_cur); 4768 if (ealen > 255) { 4769 ret = -EINVAL; 4770 goto failure; 4771 } 4772 4773 if (!(tb_cur = tb_fmr[FMR_DATA_OFFSET])) { 4774 ret = -EINVAL; 4775 goto failure; 4776 } 4777 offset = blobmsg_get_u32(tb_cur); 4778 if (offset > 255) { 4779 ret = -EINVAL; 4780 goto failure; 4781 } 4782 4783 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt); 4784 if (!rule) { 4785 ret = -ENOMEM; 4786 goto failure; 4787 } 4788 4789 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix); 4790 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix); 4791 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len); 4792 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len); 4793 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen); 4794 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset); 4795 4796 nla_nest_end(nlm, rule); 4797 } 4798 4799 nla_nest_end(nlm, fmrs); 4800 } 4801 #endif 4802 if (tun_flags) 4803 nla_put_u32(nlm, IFLA_IPTUN_FLAGS, tun_flags); 4804 } 4805 4806 nla_nest_end(nlm, infodata); 4807 nla_nest_end(nlm, linkinfo); 4808 4809 return system_rtnl_call(nlm); 4810 4811 failure: 4812 nlmsg_free(nlm); 4813 return ret; 4814 } 4815 #endif 4816 4817 #ifdef IFLA_IPTUN_MAX 4818 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000) 4819 static int system_add_gre_tunnel(const char *name, const char *kind, 4820 const unsigned int link, struct blob_attr **tb, bool v6) 4821 { 4822 struct nl_msg *nlm; 4823 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, }; 4824 struct blob_attr *cur; 4825 uint32_t ikey = 0, okey = 0, flowinfo = 0, flags6 = IP6_TNL_F_IGN_ENCAP_LIMIT; 4826 uint16_t iflags = 0, oflags = 0; 4827 uint8_t tos = 0; 4828 int ret = 0, ttl = 0; 4829 unsigned encap_limit = 0; 4830 4831 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 4832 if (!nlm) 4833 return -1; 4834 4835 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 4836 nla_put_string(nlm, IFLA_IFNAME, name); 4837 4838 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 4839 if (!linkinfo) { 4840 ret = -ENOMEM; 4841 goto failure; 4842 } 4843 4844 nla_put_string(nlm, IFLA_INFO_KIND, kind); 4845 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 4846 if (!infodata) { 4847 ret = -ENOMEM; 4848 goto failure; 4849 } 4850 4851 if (link) 4852 nla_put_u32(nlm, IFLA_GRE_LINK, link); 4853 4854 if ((cur = tb[TUNNEL_ATTR_TTL])) 4855 ttl = blobmsg_get_u32(cur); 4856 4857 if ((cur = tb[TUNNEL_ATTR_TOS])) { 4858 char *str = blobmsg_get_string(cur); 4859 if (strcmp(str, "inherit")) { 4860 unsigned uval; 4861 4862 if (!system_tos_aton(str, &uval)) { 4863 ret = -EINVAL; 4864 goto failure; 4865 } 4866 4867 if (v6) 4868 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS; 4869 else 4870 tos = uval; 4871 } else { 4872 if (v6) 4873 flags6 |= IP6_TNL_F_USE_ORIG_TCLASS; 4874 else 4875 tos = 1; 4876 } 4877 } 4878 4879 if ((cur = tb[TUNNEL_ATTR_DATA])) { 4880 struct blob_attr *tb_data[__GRE_DATA_ATTR_MAX]; 4881 4882 blobmsg_parse_attr(gre_data_attr_list.params, __GRE_DATA_ATTR_MAX, 4883 tb_data, cur); 4884 4885 if ((cur = tb_data[GRE_DATA_IKEY])) { 4886 if ((ikey = blobmsg_get_u32(cur))) 4887 iflags |= GRE_KEY; 4888 } 4889 4890 if ((cur = tb_data[GRE_DATA_OKEY])) { 4891 if ((okey = blobmsg_get_u32(cur))) 4892 oflags |= GRE_KEY; 4893 } 4894 4895 if ((cur = tb_data[GRE_DATA_ICSUM])) { 4896 if (blobmsg_get_bool(cur)) 4897 iflags |= GRE_CSUM; 4898 } 4899 4900 if ((cur = tb_data[GRE_DATA_OCSUM])) { 4901 if (blobmsg_get_bool(cur)) 4902 oflags |= GRE_CSUM; 4903 } 4904 4905 if ((cur = tb_data[GRE_DATA_ISEQNO])) { 4906 if (blobmsg_get_bool(cur)) 4907 iflags |= GRE_SEQ; 4908 } 4909 4910 if ((cur = tb_data[GRE_DATA_OSEQNO])) { 4911 if (blobmsg_get_bool(cur)) 4912 oflags |= GRE_SEQ; 4913 } 4914 4915 if ((cur = tb_data[GRE_DATA_ENCAPLIMIT])) { 4916 char *str = blobmsg_get_string(cur); 4917 4918 if (strcmp(str, "ignore")) { 4919 char *e; 4920 4921 encap_limit = strtoul(str, &e, 0); 4922 4923 if (e == str || *e || encap_limit > 255) { 4924 ret = -EINVAL; 4925 goto failure; 4926 } 4927 4928 flags6 &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; 4929 } 4930 } 4931 } 4932 4933 if (v6) { 4934 struct in6_addr in6buf; 4935 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4936 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4937 ret = -EINVAL; 4938 goto failure; 4939 } 4940 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf); 4941 } 4942 4943 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4944 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4945 ret = -EINVAL; 4946 goto failure; 4947 } 4948 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf); 4949 } 4950 4951 if (!(flags6 & IP6_TNL_F_IGN_ENCAP_LIMIT)) 4952 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, encap_limit); 4953 4954 if (flowinfo) 4955 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo); 4956 4957 if (flags6) 4958 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags6); 4959 4960 if (!ttl) 4961 ttl = 64; 4962 } else { 4963 struct in_addr inbuf; 4964 bool set_df = true; 4965 4966 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4967 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4968 ret = -EINVAL; 4969 goto failure; 4970 } 4971 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf); 4972 } 4973 4974 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4975 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4976 ret = -EINVAL; 4977 goto failure; 4978 } 4979 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf); 4980 4981 if (IN_MULTICAST(ntohl(inbuf.s_addr))) { 4982 /* okey/ikey are kept in host order and converted 4983 * via htonl() when added to the message */ 4984 if (!okey) { 4985 okey = ntohl(inbuf.s_addr); 4986 oflags |= GRE_KEY; 4987 } 4988 4989 if (!ikey) { 4990 ikey = ntohl(inbuf.s_addr); 4991 iflags |= GRE_KEY; 4992 } 4993 } 4994 } 4995 4996 if ((cur = tb[TUNNEL_ATTR_DF])) 4997 set_df = blobmsg_get_bool(cur); 4998 4999 if (!set_df) { 5000 /* ttl != 0 and nopmtudisc are incompatible */ 5001 if (ttl) { 5002 ret = -EINVAL; 5003 goto failure; 5004 } 5005 } else if (!ttl) 5006 ttl = 64; 5007 5008 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0); 5009 5010 nla_put_u8(nlm, IFLA_GRE_TOS, tos); 5011 } 5012 5013 if (ttl) 5014 nla_put_u8(nlm, IFLA_GRE_TTL, ttl); 5015 5016 if (oflags) 5017 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags); 5018 5019 if (iflags) 5020 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags); 5021 5022 if (okey) 5023 nla_put_u32(nlm, IFLA_GRE_OKEY, htonl(okey)); 5024 5025 if (ikey) 5026 nla_put_u32(nlm, IFLA_GRE_IKEY, htonl(ikey)); 5027 5028 nla_nest_end(nlm, infodata); 5029 nla_nest_end(nlm, linkinfo); 5030 5031 return system_rtnl_call(nlm); 5032 5033 failure: 5034 nlmsg_free(nlm); 5035 return ret; 5036 } 5037 #endif 5038 5039 #ifdef IFLA_VTI_MAX 5040 static int system_add_vti_tunnel(const char *name, const char *kind, 5041 const unsigned int link, struct blob_attr **tb, bool v6) 5042 { 5043 struct nl_msg *nlm; 5044 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, }; 5045 struct blob_attr *cur; 5046 int ret = 0; 5047 5048 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 5049 if (!nlm) 5050 return -1; 5051 5052 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 5053 nla_put_string(nlm, IFLA_IFNAME, name); 5054 5055 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 5056 if (!linkinfo) { 5057 ret = -ENOMEM; 5058 goto failure; 5059 } 5060 5061 nla_put_string(nlm, IFLA_INFO_KIND, kind); 5062 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 5063 if (!infodata) { 5064 ret = -ENOMEM; 5065 goto failure; 5066 } 5067 5068 if (link) 5069 nla_put_u32(nlm, IFLA_VTI_LINK, link); 5070 5071 if (v6) { 5072 struct in6_addr in6buf; 5073 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 5074 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 5075 ret = -EINVAL; 5076 goto failure; 5077 } 5078 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf); 5079 } 5080 5081 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 5082 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 5083 ret = -EINVAL; 5084 goto failure; 5085 } 5086 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf); 5087 } 5088 5089 } else { 5090 struct in_addr inbuf; 5091 5092 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 5093 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 5094 ret = -EINVAL; 5095 goto failure; 5096 } 5097 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf); 5098 } 5099 5100 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 5101 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 5102 ret = -EINVAL; 5103 goto failure; 5104 } 5105 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf); 5106 } 5107 5108 } 5109 5110 if ((cur = tb[TUNNEL_ATTR_DATA])) { 5111 struct blob_attr *tb_data[__VTI_DATA_ATTR_MAX]; 5112 uint32_t ikey = 0, okey = 0; 5113 5114 blobmsg_parse_attr(vti_data_attr_list.params, __VTI_DATA_ATTR_MAX, 5115 tb_data, cur); 5116 5117 if ((cur = tb_data[VTI_DATA_IKEY])) { 5118 if ((ikey = blobmsg_get_u32(cur))) 5119 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey)); 5120 } 5121 5122 if ((cur = tb_data[VTI_DATA_OKEY])) { 5123 if ((okey = blobmsg_get_u32(cur))) 5124 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey)); 5125 } 5126 } 5127 5128 nla_nest_end(nlm, infodata); 5129 nla_nest_end(nlm, linkinfo); 5130 5131 return system_rtnl_call(nlm); 5132 5133 failure: 5134 nlmsg_free(nlm); 5135 return ret; 5136 } 5137 #endif 5138 5139 #ifdef IFLA_XFRM_MAX 5140 static int system_add_xfrm_tunnel(const char *name, const char *kind, 5141 const unsigned int link, struct blob_attr **tb) 5142 { 5143 struct nl_msg *nlm; 5144 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, }; 5145 struct blob_attr *cur; 5146 int ret = 0; 5147 5148 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 5149 if (!nlm) 5150 return -1; 5151 5152 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 5153 nla_put_string(nlm, IFLA_IFNAME, name); 5154 5155 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 5156 if (!linkinfo) { 5157 ret = -ENOMEM; 5158 goto failure; 5159 } 5160 5161 nla_put_string(nlm, IFLA_INFO_KIND, kind); 5162 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 5163 if (!infodata) { 5164 ret = -ENOMEM; 5165 goto failure; 5166 } 5167 5168 if (link) 5169 nla_put_u32(nlm, IFLA_XFRM_LINK, link); 5170 5171 if ((cur = tb[TUNNEL_ATTR_DATA])) { 5172 struct blob_attr *tb_data[__XFRM_DATA_ATTR_MAX]; 5173 uint32_t if_id = 0; 5174 5175 blobmsg_parse_attr(xfrm_data_attr_list.params, __XFRM_DATA_ATTR_MAX, 5176 tb_data, cur); 5177 5178 if ((cur = tb_data[XFRM_DATA_IF_ID])) { 5179 if ((if_id = blobmsg_get_u32(cur))) 5180 nla_put_u32(nlm, IFLA_XFRM_IF_ID, if_id); 5181 } 5182 5183 } 5184 5185 nla_nest_end(nlm, infodata); 5186 nla_nest_end(nlm, linkinfo); 5187 5188 return system_rtnl_call(nlm); 5189 5190 failure: 5191 nlmsg_free(nlm); 5192 return ret; 5193 } 5194 #endif 5195 5196 #ifdef IFLA_VXLAN_MAX 5197 static void system_vxlan_map_bool_attr(struct nl_msg *msg, struct blob_attr **tb_data, int attrtype, int vxlandatatype, bool invert) { 5198 struct blob_attr *cur; 5199 if ((cur = tb_data[vxlandatatype])) { 5200 bool val = blobmsg_get_bool(cur); 5201 if (invert) 5202 val = !val; 5203 5204 if (attrtype == IFLA_VXLAN_GBP) { 5205 if (val) 5206 nla_put_flag(msg, attrtype); 5207 return; 5208 } 5209 5210 nla_put_u8(msg, attrtype, val); 5211 } 5212 } 5213 5214 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6) 5215 { 5216 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX]; 5217 struct nl_msg *msg; 5218 struct nlattr *linkinfo, *data; 5219 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, }; 5220 struct blob_attr *cur; 5221 int ret = 0; 5222 5223 if ((cur = tb[TUNNEL_ATTR_DATA])) 5224 blobmsg_parse_attr(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, 5225 tb_data, cur); 5226 else 5227 return -EINVAL; 5228 5229 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); 5230 5231 if (!msg) 5232 return -1; 5233 5234 nlmsg_append(msg, &iim, sizeof(iim), 0); 5235 5236 nla_put_string(msg, IFLA_IFNAME, name); 5237 5238 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) { 5239 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur)); 5240 if (!ea) { 5241 ret = -EINVAL; 5242 goto failure; 5243 } 5244 5245 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea); 5246 } 5247 5248 if ((cur = tb[TUNNEL_ATTR_MTU])) { 5249 uint32_t mtu = blobmsg_get_u32(cur); 5250 nla_put_u32(msg, IFLA_MTU, mtu); 5251 } 5252 5253 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) { 5254 ret = -ENOMEM; 5255 goto failure; 5256 } 5257 5258 nla_put_string(msg, IFLA_INFO_KIND, "vxlan"); 5259 5260 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) { 5261 ret = -ENOMEM; 5262 goto failure; 5263 } 5264 5265 if (link) 5266 nla_put_u32(msg, IFLA_VXLAN_LINK, link); 5267 5268 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) { 5269 uint32_t id = blobmsg_get_u32(cur); 5270 if (id >= (1u << 24)) { 5271 ret = -EINVAL; 5272 goto failure; 5273 } 5274 5275 nla_put_u32(msg, IFLA_VXLAN_ID, id); 5276 } 5277 5278 if (v6) { 5279 struct in6_addr in6buf; 5280 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 5281 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 5282 ret = -EINVAL; 5283 goto failure; 5284 } 5285 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf); 5286 } 5287 5288 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 5289 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 5290 ret = -EINVAL; 5291 goto failure; 5292 } 5293 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf); 5294 } 5295 } else { 5296 struct in_addr inbuf; 5297 5298 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 5299 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 5300 ret = -EINVAL; 5301 goto failure; 5302 } 5303 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf); 5304 } 5305 5306 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 5307 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 5308 ret = -EINVAL; 5309 goto failure; 5310 } 5311 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf); 5312 } 5313 } 5314 5315 uint32_t port = 4789; 5316 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) { 5317 port = blobmsg_get_u32(cur); 5318 if (port < 1 || port > 65535) { 5319 ret = -EINVAL; 5320 goto failure; 5321 } 5322 } 5323 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port)); 5324 5325 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMIN])) { 5326 struct ifla_vxlan_port_range srcports = {0,0}; 5327 5328 uint32_t low = blobmsg_get_u32(cur); 5329 if (low < 1 || low > 65535 - 1) { 5330 ret = -EINVAL; 5331 goto failure; 5332 } 5333 5334 srcports.low = htons((uint16_t) low); 5335 srcports.high = htons((uint16_t) (low+1)); 5336 5337 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMAX])) { 5338 uint32_t high = blobmsg_get_u32(cur); 5339 if (high < 1 || high > 65535) { 5340 ret = -EINVAL; 5341 goto failure; 5342 } 5343 5344 if (high > low) 5345 srcports.high = htons((uint16_t) high); 5346 } 5347 5348 nla_put(msg, IFLA_VXLAN_PORT_RANGE, sizeof(srcports), &srcports); 5349 } 5350 5351 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_CSUM, VXLAN_DATA_ATTR_TXCSUM, false); 5352 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, VXLAN_DATA_ATTR_RXCSUM, true); 5353 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, VXLAN_DATA_ATTR_TXCSUM, true); 5354 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_LEARNING, VXLAN_DATA_ATTR_LEARNING, false); 5355 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_RSC , VXLAN_DATA_ATTR_RSC, false); 5356 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_PROXY , VXLAN_DATA_ATTR_PROXY, false); 5357 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L2MISS , VXLAN_DATA_ATTR_L2MISS, false); 5358 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L3MISS , VXLAN_DATA_ATTR_L3MISS, false); 5359 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_GBP , VXLAN_DATA_ATTR_GBP, false); 5360 5361 if ((cur = tb_data[VXLAN_DATA_ATTR_AGEING])) { 5362 uint32_t ageing = blobmsg_get_u32(cur); 5363 nla_put_u32(msg, IFLA_VXLAN_AGEING, ageing); 5364 } 5365 5366 if ((cur = tb_data[VXLAN_DATA_ATTR_LIMIT])) { 5367 uint32_t maxaddress = blobmsg_get_u32(cur); 5368 nla_put_u32(msg, IFLA_VXLAN_LIMIT, maxaddress); 5369 } 5370 5371 if ((cur = tb[TUNNEL_ATTR_TOS])) { 5372 char *str = blobmsg_get_string(cur); 5373 unsigned tos = 1; 5374 5375 if (strcmp(str, "inherit")) { 5376 if (!system_tos_aton(str, &tos)) { 5377 ret = -EINVAL; 5378 goto failure; 5379 } 5380 } 5381 5382 nla_put_u8(msg, IFLA_VXLAN_TOS, tos); 5383 } 5384 5385 if ((cur = tb[TUNNEL_ATTR_TTL])) { 5386 uint32_t ttl = blobmsg_get_u32(cur); 5387 if (ttl < 1 || ttl > 255) { 5388 ret = -EINVAL; 5389 goto failure; 5390 } 5391 5392 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl); 5393 } 5394 5395 nla_nest_end(msg, data); 5396 nla_nest_end(msg, linkinfo); 5397 5398 ret = system_rtnl_call(msg); 5399 if (ret) 5400 D(SYSTEM, "Error adding vxlan '%s': %d", name, ret); 5401 5402 return ret; 5403 5404 failure: 5405 nlmsg_free(msg); 5406 return ret; 5407 } 5408 #endif 5409 5410 static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb) 5411 { 5412 struct blob_attr *cur; 5413 int ret = 0; 5414 5415 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0) 5416 return -1; 5417 5418 #ifdef SIOCADD6RD 5419 if ((cur = tb[TUNNEL_ATTR_DATA])) { 5420 struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX]; 5421 unsigned int mask; 5422 struct ip_tunnel_6rd p6; 5423 5424 blobmsg_parse_attr(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, 5425 tb_data, cur); 5426 5427 memset(&p6, 0, sizeof(p6)); 5428 5429 if ((cur = tb_data[SIXRD_DATA_PREFIX])) { 5430 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur), 5431 &p6.prefix, &mask) || mask > 128) { 5432 ret = -EINVAL; 5433 goto failure; 5434 } 5435 5436 p6.prefixlen = mask; 5437 } 5438 5439 if ((cur = tb_data[SIXRD_DATA_RELAY_PREFIX])) { 5440 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur), 5441 &p6.relay_prefix, &mask) || mask > 32) { 5442 ret = -EINVAL; 5443 goto failure; 5444 } 5445 5446 p6.relay_prefixlen = mask; 5447 } 5448 5449 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) { 5450 ret = -1; 5451 goto failure; 5452 } 5453 } 5454 #endif 5455 5456 return ret; 5457 5458 failure: 5459 system_link_del(name); 5460 return ret; 5461 } 5462 5463 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb) 5464 { 5465 struct blob_attr *cur; 5466 bool set_df = true; 5467 struct ip_tunnel_parm p = { 5468 .link = link, 5469 .iph = { 5470 .version = 4, 5471 .ihl = 5, 5472 .protocol = proto, 5473 } 5474 }; 5475 5476 if ((cur = tb[TUNNEL_ATTR_LOCAL]) && 5477 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1) 5478 return -EINVAL; 5479 5480 if ((cur = tb[TUNNEL_ATTR_REMOTE]) && 5481 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1) 5482 return -EINVAL; 5483 5484 if ((cur = tb[TUNNEL_ATTR_DF])) 5485 set_df = blobmsg_get_bool(cur); 5486 5487 if ((cur = tb[TUNNEL_ATTR_TTL])) 5488 p.iph.ttl = blobmsg_get_u32(cur); 5489 5490 if ((cur = tb[TUNNEL_ATTR_TOS])) { 5491 char *str = blobmsg_get_string(cur); 5492 if (strcmp(str, "inherit")) { 5493 unsigned uval; 5494 5495 if (!system_tos_aton(str, &uval)) 5496 return -EINVAL; 5497 5498 p.iph.tos = uval; 5499 } else 5500 p.iph.tos = 1; 5501 } 5502 5503 p.iph.frag_off = set_df ? htons(IP_DF) : 0; 5504 /* ttl !=0 and nopmtudisc are incompatible */ 5505 if (p.iph.ttl && p.iph.frag_off == 0) 5506 return -EINVAL; 5507 5508 strncpy(p.name, name, sizeof(p.name) - 1); 5509 5510 switch (p.iph.protocol) { 5511 case IPPROTO_IPIP: 5512 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p); 5513 case IPPROTO_IPV6: 5514 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p); 5515 default: 5516 break; 5517 } 5518 return -1; 5519 } 5520 5521 int system_del_ip_tunnel(const struct device *dev) 5522 { 5523 return system_link_del(dev->ifname); 5524 } 5525 5526 int system_update_ipv6_mtu(struct device *dev, int mtu) 5527 { 5528 int ret = -1; 5529 char buf[64]; 5530 int fd; 5531 5532 fd = open(dev_sysctl_path("ipv6/conf", dev->ifname, "mtu"), O_RDWR); 5533 if (fd < 0) 5534 return ret; 5535 5536 if (!mtu) { 5537 ssize_t len = read(fd, buf, sizeof(buf) - 1); 5538 if (len < 0) 5539 goto out; 5540 5541 buf[len] = 0; 5542 ret = atoi(buf); 5543 } else { 5544 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0) 5545 ret = mtu; 5546 } 5547 5548 out: 5549 close(fd); 5550 return ret; 5551 } 5552 5553 int system_add_ip_tunnel(const struct device *dev, struct blob_attr *attr) 5554 { 5555 struct blob_attr *tb[__TUNNEL_ATTR_MAX]; 5556 struct blob_attr *cur; 5557 const char *str; 5558 5559 blobmsg_parse_attr(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb, attr); 5560 5561 system_link_del(dev->ifname); 5562 5563 if (!(cur = tb[TUNNEL_ATTR_TYPE])) 5564 return -EINVAL; 5565 str = blobmsg_data(cur); 5566 5567 unsigned int ttl = 0; 5568 if ((cur = tb[TUNNEL_ATTR_TTL])) { 5569 ttl = blobmsg_get_u32(cur); 5570 if (ttl > 255) 5571 return -EINVAL; 5572 } 5573 5574 unsigned int link = 0; 5575 if ((cur = tb[TUNNEL_ATTR_LINK])) { 5576 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node); 5577 if (!iface) 5578 return -EINVAL; 5579 5580 if (iface->l3_dev.dev) 5581 link = iface->l3_dev.dev->ifindex; 5582 } 5583 5584 if (!strcmp(str, "sit")) 5585 return system_add_sit_tunnel(dev->ifname, link, tb); 5586 #ifdef IFLA_IPTUN_MAX 5587 else if (!strcmp(str, "ipip6")) { 5588 return system_add_ip6_tunnel(dev->ifname, link, tb); 5589 } else if (!strcmp(str, "greip")) { 5590 return system_add_gre_tunnel(dev->ifname, "gre", link, tb, false); 5591 } else if (!strcmp(str, "gretapip")) { 5592 return system_add_gre_tunnel(dev->ifname, "gretap", link, tb, false); 5593 } else if (!strcmp(str, "greip6")) { 5594 return system_add_gre_tunnel(dev->ifname, "ip6gre", link, tb, true); 5595 } else if (!strcmp(str, "gretapip6")) { 5596 return system_add_gre_tunnel(dev->ifname, "ip6gretap", link, tb, true); 5597 #ifdef IFLA_VTI_MAX 5598 } else if (!strcmp(str, "vtiip")) { 5599 return system_add_vti_tunnel(dev->ifname, "vti", link, tb, false); 5600 } else if (!strcmp(str, "vtiip6")) { 5601 return system_add_vti_tunnel(dev->ifname, "vti6", link, tb, true); 5602 #endif 5603 #ifdef IFLA_XFRM_MAX 5604 } else if (!strcmp(str, "xfrm")) { 5605 return system_add_xfrm_tunnel(dev->ifname, "xfrm", link, tb); 5606 #endif 5607 #ifdef IFLA_VXLAN_MAX 5608 } else if(!strcmp(str, "vxlan")) { 5609 return system_add_vxlan(dev->ifname, link, tb, false); 5610 } else if(!strcmp(str, "vxlan6")) { 5611 return system_add_vxlan(dev->ifname, link, tb, true); 5612 #endif 5613 #endif 5614 } else if (!strcmp(str, "ipip")) { 5615 return system_add_proto_tunnel(dev->ifname, IPPROTO_IPIP, link, tb); 5616 } 5617 else 5618 return -EINVAL; 5619 5620 return 0; 5621 } 5622
This page was automatically generated by LXR 0.3.1. • OpenWrt