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