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