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