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 memset(&ecmd, 0, sizeof(ecmd)); 2452 ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; 2453 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2454 2455 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 2456 ecmd.req.link_mode_masks_nwords >= 0 || 2457 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 2458 return; 2459 2460 ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords; 2461 2462 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 2463 ecmd.req.link_mode_masks_nwords <= 0 || 2464 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 2465 return; 2466 2467 nwords = ecmd.req.link_mode_masks_nwords; 2468 supported = &ecmd.link_mode_data[0]; 2469 advertising = &ecmd.link_mode_data[nwords]; 2470 memcpy(advertising, supported, sizeof(__u32) * nwords); 2471 2472 for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) { 2473 if (s->flags & DEV_OPT_DUPLEX) { 2474 if (s->duplex) 2475 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising); 2476 else 2477 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising); 2478 } 2479 if (!(s->flags & DEV_OPT_SPEED) || 2480 s->speed == ethtool_modes[i].speed) 2481 continue; 2482 2483 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_full, advertising); 2484 ethtool_link_mode_clear_bit(nwords, ethtool_modes[i].bit_half, advertising); 2485 } 2486 2487 if (s->flags & DEV_OPT_PAUSE) 2488 if (!s->pause) 2489 ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, advertising); 2490 2491 if (s->flags & DEV_OPT_ASYM_PAUSE) 2492 if (!s->asym_pause) 2493 ethtool_link_mode_clear_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising); 2494 2495 if (s->flags & DEV_OPT_AUTONEG) { 2496 ecmd.req.autoneg = s->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; 2497 if (!s->autoneg) { 2498 if (s->flags & DEV_OPT_SPEED) 2499 ecmd.req.speed = s->speed; 2500 2501 if (s->flags & DEV_OPT_DUPLEX) 2502 ecmd.req.duplex = s->duplex ? DUPLEX_FULL : DUPLEX_HALF; 2503 } 2504 } 2505 2506 ecmd.req.cmd = ETHTOOL_SLINKSETTINGS; 2507 ioctl(sock_ioctl, SIOCETHTOOL, &ifr); 2508 } 2509 2510 static void 2511 system_set_ethtool_settings_after_up(struct device *dev, struct device_settings *s) 2512 { 2513 if (s->flags & DEV_OPT_GRO) 2514 system_set_ethtool_gro(dev, s); 2515 } 2516 2517 void 2518 system_if_get_settings(struct device *dev, struct device_settings *s) 2519 { 2520 struct ifreq ifr; 2521 char buf[10]; 2522 int ret; 2523 2524 memset(&ifr, 0, sizeof(ifr)); 2525 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2526 2527 if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) { 2528 s->mtu = ifr.ifr_mtu; 2529 s->flags |= DEV_OPT_MTU; 2530 } 2531 2532 s->mtu6 = system_update_ipv6_mtu(dev, 0); 2533 if (s->mtu6 > 0) 2534 s->flags |= DEV_OPT_MTU6; 2535 2536 if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) { 2537 s->txqueuelen = ifr.ifr_qlen; 2538 s->flags |= DEV_OPT_TXQUEUELEN; 2539 } 2540 2541 if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) { 2542 memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr)); 2543 s->flags |= DEV_OPT_MACADDR; 2544 } 2545 2546 if (!system_get_disable_ipv6(dev, buf, sizeof(buf))) { 2547 s->ipv6 = !strtoul(buf, NULL, 0); 2548 s->flags |= DEV_OPT_IPV6; 2549 } 2550 2551 if (!system_get_ip6segmentrouting(dev, buf, sizeof(buf))) { 2552 s->ip6segmentrouting = strtoul(buf, NULL, 0); 2553 s->flags |= DEV_OPT_IP6SEGMENTROUTING; 2554 } 2555 2556 if (ioctl(sock_ioctl, SIOCGIFFLAGS, &ifr) == 0) { 2557 s->promisc = ifr.ifr_flags & IFF_PROMISC; 2558 s->flags |= DEV_OPT_PROMISC; 2559 2560 s->multicast = ifr.ifr_flags & IFF_MULTICAST; 2561 s->flags |= DEV_OPT_MULTICAST; 2562 } 2563 2564 if (!system_get_rpfilter(dev, buf, sizeof(buf))) { 2565 s->rpfilter = strtoul(buf, NULL, 0); 2566 s->flags |= DEV_OPT_RPFILTER; 2567 } 2568 2569 if (!system_get_acceptlocal(dev, buf, sizeof(buf))) { 2570 s->acceptlocal = strtoul(buf, NULL, 0); 2571 s->flags |= DEV_OPT_ACCEPTLOCAL; 2572 } 2573 2574 if (!system_get_igmpversion(dev, buf, sizeof(buf))) { 2575 s->igmpversion = strtoul(buf, NULL, 0); 2576 s->flags |= DEV_OPT_IGMPVERSION; 2577 } 2578 2579 if (!system_get_mldversion(dev, buf, sizeof(buf))) { 2580 s->mldversion = strtoul(buf, NULL, 0); 2581 s->flags |= DEV_OPT_MLDVERSION; 2582 } 2583 2584 if (!system_get_neigh4reachabletime(dev, buf, sizeof(buf))) { 2585 s->neigh4reachabletime = strtoul(buf, NULL, 0); 2586 s->flags |= DEV_OPT_NEIGHREACHABLETIME; 2587 } 2588 2589 if (!system_get_neigh6reachabletime(dev, buf, sizeof(buf))) { 2590 s->neigh6reachabletime = strtoul(buf, NULL, 0); 2591 s->flags |= DEV_OPT_NEIGHREACHABLETIME; 2592 } 2593 2594 if (!system_get_neigh4locktime(dev, buf, sizeof(buf))) { 2595 s->neigh4locktime = strtol(buf, NULL, 0); 2596 s->flags |= DEV_OPT_NEIGHLOCKTIME; 2597 } 2598 2599 if (!system_get_neigh4gcstaletime(dev, buf, sizeof(buf))) { 2600 s->neigh4gcstaletime = strtoul(buf, NULL, 0); 2601 s->flags |= DEV_OPT_NEIGHGCSTALETIME; 2602 } 2603 2604 if (!system_get_neigh6gcstaletime(dev, buf, sizeof(buf))) { 2605 s->neigh6gcstaletime = strtoul(buf, NULL, 0); 2606 s->flags |= DEV_OPT_NEIGHGCSTALETIME; 2607 } 2608 2609 if (!system_get_dadtransmits(dev, buf, sizeof(buf))) { 2610 s->dadtransmits = strtoul(buf, NULL, 0); 2611 s->flags |= DEV_OPT_DADTRANSMITS; 2612 } 2613 2614 if (!system_get_sendredirects(dev, buf, sizeof(buf))) { 2615 s->sendredirects = strtoul(buf, NULL, 0); 2616 s->flags |= DEV_OPT_SENDREDIRECTS; 2617 } 2618 2619 if (!system_get_drop_v4_unicast_in_l2_multicast(dev, buf, sizeof(buf))) { 2620 s->drop_v4_unicast_in_l2_multicast = strtoul(buf, NULL, 0); 2621 s->flags |= DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST; 2622 } 2623 2624 if (!system_get_drop_v6_unicast_in_l2_multicast(dev, buf, sizeof(buf))) { 2625 s->drop_v6_unicast_in_l2_multicast = strtoul(buf, NULL, 0); 2626 s->flags |= DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST; 2627 } 2628 2629 if (!system_get_drop_gratuitous_arp(dev, buf, sizeof(buf))) { 2630 s->drop_gratuitous_arp = strtoul(buf, NULL, 0); 2631 s->flags |= DEV_OPT_DROP_GRATUITOUS_ARP; 2632 } 2633 2634 if (!system_get_drop_unsolicited_na(dev, buf, sizeof(buf))) { 2635 s->drop_unsolicited_na = strtoul(buf, NULL, 0); 2636 s->flags |= DEV_OPT_DROP_UNSOLICITED_NA; 2637 } 2638 2639 if (!system_get_arp_accept(dev, buf, sizeof(buf))) { 2640 s->arp_accept = strtoul(buf, NULL, 0); 2641 s->flags |= DEV_OPT_ARP_ACCEPT; 2642 } 2643 2644 ret = system_get_ethtool_gro(dev); 2645 if (ret >= 0) { 2646 s->gro = ret; 2647 s->flags |= DEV_OPT_GRO; 2648 } 2649 2650 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) 2651 ret = system_if_get_master_ifindex(dev); 2652 if (ret >= 0) { 2653 s->master_ifindex = ret; 2654 s->flags |= DEV_OPT_MASTER; 2655 } 2656 #endif 2657 } 2658 2659 void 2660 system_if_apply_settings(struct device *dev, struct device_settings *s, uint64_t apply_mask) 2661 { 2662 struct ifreq ifr; 2663 char buf[12]; 2664 2665 apply_mask &= s->flags; 2666 2667 if (apply_mask & DEV_OPT_MASTER) { 2668 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) 2669 system_set_master(dev, s->master_ifindex); 2670 if (!(apply_mask & (DEV_OPT_MACADDR | DEV_OPT_DEFAULT_MACADDR)) || dev->external) 2671 system_refresh_orig_macaddr(dev, &dev->orig_settings); 2672 #else 2673 netifd_log_message(L_WARNING, "%s Your kernel is older than linux 6.1.0, changing DSA port conduit is not supported!", dev->ifname); 2674 #endif 2675 } 2676 2677 memset(&ifr, 0, sizeof(ifr)); 2678 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 2679 if (apply_mask & DEV_OPT_MTU) { 2680 ifr.ifr_mtu = s->mtu; 2681 if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0) 2682 s->flags &= ~DEV_OPT_MTU; 2683 } 2684 if (apply_mask & DEV_OPT_MTU6) { 2685 system_update_ipv6_mtu(dev, s->mtu6); 2686 } 2687 if (apply_mask & DEV_OPT_TXQUEUELEN) { 2688 ifr.ifr_qlen = s->txqueuelen; 2689 if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0) 2690 s->flags &= ~DEV_OPT_TXQUEUELEN; 2691 } 2692 if ((apply_mask & (DEV_OPT_MACADDR | DEV_OPT_DEFAULT_MACADDR)) && !dev->external) { 2693 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; 2694 memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr)); 2695 if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0) 2696 s->flags &= ~DEV_OPT_MACADDR; 2697 } 2698 if (apply_mask & DEV_OPT_IPV6) 2699 system_set_disable_ipv6(dev, s->ipv6 ? "" : "1"); 2700 if (s->flags & DEV_OPT_IP6SEGMENTROUTING & apply_mask) { 2701 struct device dummy = { 2702 .ifname = "all", 2703 }; 2704 bool ip6segmentrouting = device_check_ip6segmentrouting(); 2705 2706 system_set_ip6segmentrouting(dev, s->ip6segmentrouting ? "1" : ""); 2707 system_set_ip6segmentrouting(&dummy, ip6segmentrouting ? "1" : ""); 2708 } 2709 if (apply_mask & DEV_OPT_PROMISC) { 2710 if (system_if_flags(dev->ifname, s->promisc ? IFF_PROMISC : 0, 2711 !s->promisc ? IFF_PROMISC : 0) < 0) 2712 s->flags &= ~DEV_OPT_PROMISC; 2713 } 2714 if (apply_mask & DEV_OPT_RPFILTER) { 2715 snprintf(buf, sizeof(buf), "%u", s->rpfilter); 2716 system_set_rpfilter(dev, buf); 2717 } 2718 if (apply_mask & DEV_OPT_ACCEPTLOCAL) 2719 system_set_acceptlocal(dev, s->acceptlocal ? "1" : ""); 2720 if (apply_mask & DEV_OPT_IGMPVERSION) { 2721 snprintf(buf, sizeof(buf), "%u", s->igmpversion); 2722 system_set_igmpversion(dev, buf); 2723 } 2724 if (apply_mask & DEV_OPT_MLDVERSION) { 2725 snprintf(buf, sizeof(buf), "%u", s->mldversion); 2726 system_set_mldversion(dev, buf); 2727 } 2728 if (apply_mask & DEV_OPT_NEIGHREACHABLETIME) { 2729 snprintf(buf, sizeof(buf), "%u", s->neigh4reachabletime); 2730 system_set_neigh4reachabletime(dev, buf); 2731 snprintf(buf, sizeof(buf), "%u", s->neigh6reachabletime); 2732 system_set_neigh6reachabletime(dev, buf); 2733 } 2734 if (apply_mask & DEV_OPT_NEIGHLOCKTIME) { 2735 snprintf(buf, sizeof(buf), "%d", s->neigh4locktime); 2736 system_set_neigh4locktime(dev, buf); 2737 } 2738 if (apply_mask & DEV_OPT_NEIGHGCSTALETIME) { 2739 snprintf(buf, sizeof(buf), "%u", s->neigh4gcstaletime); 2740 system_set_neigh4gcstaletime(dev, buf); 2741 snprintf(buf, sizeof(buf), "%u", s->neigh6gcstaletime); 2742 system_set_neigh6gcstaletime(dev, buf); 2743 } 2744 if (apply_mask & DEV_OPT_DADTRANSMITS) { 2745 snprintf(buf, sizeof(buf), "%u", s->dadtransmits); 2746 system_set_dadtransmits(dev, buf); 2747 } 2748 if (apply_mask & DEV_OPT_MULTICAST) { 2749 if (system_if_flags(dev->ifname, s->multicast ? IFF_MULTICAST : 0, 2750 !s->multicast ? IFF_MULTICAST : 0) < 0) 2751 s->flags &= ~DEV_OPT_MULTICAST; 2752 } 2753 if (apply_mask & DEV_OPT_SENDREDIRECTS) 2754 system_set_sendredirects(dev, s->sendredirects ? "1" : ""); 2755 if (apply_mask & DEV_OPT_DROP_V4_UNICAST_IN_L2_MULTICAST) 2756 system_set_drop_v4_unicast_in_l2_multicast(dev, s->drop_v4_unicast_in_l2_multicast ? "1" : ""); 2757 if (apply_mask & DEV_OPT_DROP_V6_UNICAST_IN_L2_MULTICAST) 2758 system_set_drop_v6_unicast_in_l2_multicast(dev, s->drop_v6_unicast_in_l2_multicast ? "1" : ""); 2759 if (apply_mask & DEV_OPT_DROP_GRATUITOUS_ARP) 2760 system_set_drop_gratuitous_arp(dev, s->drop_gratuitous_arp ? "1" : ""); 2761 if (apply_mask & DEV_OPT_DROP_UNSOLICITED_NA) 2762 system_set_drop_unsolicited_na(dev, s->drop_unsolicited_na ? "1" : ""); 2763 if (apply_mask & DEV_OPT_ARP_ACCEPT) 2764 system_set_arp_accept(dev, s->arp_accept ? "1" : ""); 2765 system_set_ethtool_settings(dev, s); 2766 } 2767 2768 void system_if_apply_settings_after_up(struct device *dev, struct device_settings *s) 2769 { 2770 system_set_ethtool_settings_after_up(dev, s); 2771 } 2772 2773 int system_if_up(struct device *dev) 2774 { 2775 return system_if_flags(dev->ifname, IFF_UP, 0); 2776 } 2777 2778 int system_if_down(struct device *dev) 2779 { 2780 return system_if_flags(dev->ifname, 0, IFF_UP); 2781 } 2782 2783 struct if_check_data { 2784 struct device *dev; 2785 int pending; 2786 int ret; 2787 }; 2788 2789 static int cb_if_check_valid(struct nl_msg *msg, void *arg) 2790 { 2791 struct nlmsghdr *nh = nlmsg_hdr(msg); 2792 struct ifinfomsg *ifi = NLMSG_DATA(nh); 2793 struct if_check_data *chk = (struct if_check_data *)arg; 2794 2795 if (nh->nlmsg_type != RTM_NEWLINK) 2796 return NL_SKIP; 2797 2798 system_device_update_state(chk->dev, ifi->ifi_flags); 2799 return NL_OK; 2800 } 2801 2802 static int cb_if_check_ack(struct nl_msg *msg, void *arg) 2803 { 2804 struct if_check_data *chk = (struct if_check_data *)arg; 2805 chk->pending = 0; 2806 return NL_STOP; 2807 } 2808 2809 static int cb_if_check_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) 2810 { 2811 struct if_check_data *chk = (struct if_check_data *)arg; 2812 2813 if (chk->dev->type == &simple_device_type) 2814 device_set_present(chk->dev, false); 2815 device_set_link(chk->dev, false); 2816 chk->pending = err->error; 2817 2818 return NL_STOP; 2819 } 2820 2821 struct bridge_vlan_check_data { 2822 struct device *check_dev; 2823 int ifindex; 2824 int ret; 2825 bool pending; 2826 }; 2827 2828 static void bridge_vlan_check_port(struct bridge_vlan_check_data *data, 2829 struct bridge_vlan_port *port, 2830 struct bridge_vlan_info *vinfo) 2831 { 2832 uint16_t flags = 0, diff, mask; 2833 2834 if (port->flags & BRVLAN_F_PVID) 2835 flags |= BRIDGE_VLAN_INFO_PVID; 2836 if (port->flags & BRVLAN_F_UNTAGGED) 2837 flags |= BRIDGE_VLAN_INFO_UNTAGGED; 2838 2839 diff = vinfo->flags ^ flags; 2840 mask = BRVLAN_F_UNTAGGED | (flags & BRIDGE_VLAN_INFO_PVID); 2841 if (diff & mask) { 2842 data->ret = 1; 2843 data->pending = false; 2844 } 2845 2846 port->check = 1; 2847 } 2848 2849 static void bridge_vlan_check_attr(struct bridge_vlan_check_data *data, 2850 struct rtattr *attr) 2851 { 2852 struct bridge_vlan_hotplug_port *port; 2853 struct bridge_vlan_info *vinfo; 2854 struct bridge_vlan *vlan; 2855 struct rtattr *cur; 2856 int rem = RTA_PAYLOAD(attr); 2857 int i; 2858 2859 for (cur = RTA_DATA(attr); RTA_OK(cur, rem); cur = RTA_NEXT(cur, rem)) { 2860 if (cur->rta_type != IFLA_BRIDGE_VLAN_INFO) 2861 continue; 2862 2863 vinfo = RTA_DATA(cur); 2864 vlan = vlist_find(&data->check_dev->vlans, &vinfo->vid, vlan, node); 2865 if (!vlan) { 2866 data->ret = 1; 2867 data->pending = false; 2868 return; 2869 } 2870 2871 for (i = 0; i < vlan->n_ports; i++) 2872 if (!vlan->ports[i].check) 2873 bridge_vlan_check_port(data, &vlan->ports[i], vinfo); 2874 2875 list_for_each_entry(port, &vlan->hotplug_ports, list) 2876 if (!port->port.check) 2877 bridge_vlan_check_port(data, &port->port, vinfo); 2878 } 2879 } 2880 2881 static int bridge_vlan_check_cb(struct nl_msg *msg, void *arg) 2882 { 2883 struct bridge_vlan_check_data *data = arg; 2884 struct nlmsghdr *nh = nlmsg_hdr(msg); 2885 struct ifinfomsg *ifi = NLMSG_DATA(nh); 2886 struct rtattr *attr; 2887 int rem; 2888 2889 if (nh->nlmsg_type != RTM_NEWLINK) 2890 return NL_SKIP; 2891 2892 if (ifi->ifi_family != AF_BRIDGE) 2893 return NL_SKIP; 2894 2895 if (ifi->ifi_index != data->ifindex) 2896 return NL_SKIP; 2897 2898 attr = IFLA_RTA(ifi); 2899 rem = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); 2900 while (RTA_OK(attr, rem)) { 2901 if (attr->rta_type == IFLA_AF_SPEC) 2902 bridge_vlan_check_attr(data, attr); 2903 2904 attr = RTA_NEXT(attr, rem); 2905 } 2906 2907 return NL_SKIP; 2908 } 2909 2910 static int bridge_vlan_ack_cb(struct nl_msg *msg, void *arg) 2911 { 2912 struct bridge_vlan_check_data *data = arg; 2913 data->pending = false; 2914 return NL_STOP; 2915 } 2916 2917 static int bridge_vlan_error_cb(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) 2918 { 2919 struct bridge_vlan_check_data *data = arg; 2920 data->pending = false; 2921 return NL_STOP; 2922 } 2923 2924 int system_bridge_vlan_check(struct device *dev, char *ifname) 2925 { 2926 struct bridge_vlan_check_data data = { 2927 .check_dev = dev, 2928 .ifindex = if_nametoindex(ifname), 2929 .ret = -1, 2930 .pending = true, 2931 }; 2932 static struct ifinfomsg ifi = { 2933 .ifi_family = AF_BRIDGE 2934 }; 2935 static struct rtattr ext_req = { 2936 .rta_type = IFLA_EXT_MASK, 2937 .rta_len = RTA_LENGTH(sizeof(uint32_t)), 2938 }; 2939 uint32_t filter = RTEXT_FILTER_BRVLAN; 2940 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); 2941 struct bridge_vlan *vlan; 2942 struct nl_msg *msg; 2943 int i; 2944 2945 if (!data.ifindex) 2946 return 0; 2947 2948 msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP); 2949 2950 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) || 2951 nlmsg_append(msg, &ext_req, sizeof(ext_req), NLMSG_ALIGNTO) || 2952 nlmsg_append(msg, &filter, sizeof(filter), 0)) 2953 goto free; 2954 2955 vlist_for_each_element(&dev->vlans, vlan, node) { 2956 struct bridge_vlan_hotplug_port *port; 2957 2958 for (i = 0; i < vlan->n_ports; i++) { 2959 if (!strcmp(vlan->ports[i].ifname, ifname)) 2960 vlan->ports[i].check = 0; 2961 else 2962 vlan->ports[i].check = -1; 2963 } 2964 2965 list_for_each_entry(port, &vlan->hotplug_ports, list) { 2966 if (!strcmp(port->port.ifname, ifname)) 2967 port->port.check = 0; 2968 else 2969 port->port.check = -1; 2970 } 2971 } 2972 2973 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, bridge_vlan_check_cb, &data); 2974 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, bridge_vlan_ack_cb, &data); 2975 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, bridge_vlan_ack_cb, &data); 2976 nl_cb_err(cb, NL_CB_CUSTOM, bridge_vlan_error_cb, &data); 2977 2978 if (nl_send_auto_complete(sock_rtnl, msg) < 0) 2979 goto free; 2980 2981 data.ret = 0; 2982 while (data.pending) 2983 nl_recvmsgs(sock_rtnl, cb); 2984 2985 vlist_for_each_element(&dev->vlans, vlan, node) { 2986 struct bridge_vlan_hotplug_port *port; 2987 2988 for (i = 0; i < vlan->n_ports; i++) { 2989 if (!vlan->ports[i].check) { 2990 data.ret = 1; 2991 break; 2992 } 2993 } 2994 2995 list_for_each_entry(port, &vlan->hotplug_ports, list) { 2996 if (!port->port.check) { 2997 data.ret = 1; 2998 break; 2999 } 3000 } 3001 } 3002 3003 free: 3004 nlmsg_free(msg); 3005 nl_cb_put(cb); 3006 return data.ret; 3007 } 3008 3009 int system_if_check(struct device *dev) 3010 { 3011 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); 3012 struct nl_msg *msg; 3013 struct ifinfomsg ifi = { 3014 .ifi_family = AF_UNSPEC, 3015 .ifi_index = 0, 3016 }; 3017 struct if_check_data chk = { 3018 .dev = dev, 3019 .pending = 1, 3020 }; 3021 int ret = 1; 3022 3023 if (!cb) 3024 return ret; 3025 3026 msg = nlmsg_alloc_simple(RTM_GETLINK, 0); 3027 if (!msg) 3028 goto out; 3029 3030 if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) || 3031 nla_put_string(msg, IFLA_IFNAME, dev->ifname)) 3032 goto free; 3033 3034 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_check_valid, &chk); 3035 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_check_ack, &chk); 3036 nl_cb_err(cb, NL_CB_CUSTOM, cb_if_check_error, &chk); 3037 3038 ret = nl_send_auto_complete(sock_rtnl, msg); 3039 if (ret < 0) 3040 goto free; 3041 3042 while (chk.pending > 0) 3043 nl_recvmsgs(sock_rtnl, cb); 3044 3045 ret = chk.pending; 3046 3047 free: 3048 nlmsg_free(msg); 3049 out: 3050 nl_cb_put(cb); 3051 return ret; 3052 } 3053 3054 struct device * 3055 system_if_get_parent(struct device *dev) 3056 { 3057 char buf[64], *devname; 3058 int ifindex, iflink; 3059 3060 if (system_get_dev_sysfs("iflink", dev->ifname, buf, sizeof(buf)) < 0) 3061 return NULL; 3062 3063 iflink = strtoul(buf, NULL, 0); 3064 ifindex = system_if_resolve(dev); 3065 if (!iflink || iflink == ifindex) 3066 return NULL; 3067 3068 devname = if_indextoname(iflink, buf); 3069 if (!devname) 3070 return NULL; 3071 3072 return device_get(devname, true); 3073 } 3074 3075 static bool 3076 read_string_file(int dir_fd, const char *file, char *buf, int len) 3077 { 3078 bool ret = false; 3079 char *c; 3080 int fd; 3081 3082 fd = openat(dir_fd, file, O_RDONLY); 3083 if (fd < 0) 3084 return false; 3085 3086 retry: 3087 len = read(fd, buf, len - 1); 3088 if (len < 0) { 3089 if (errno == EINTR) 3090 goto retry; 3091 } else if (len > 0) { 3092 buf[len] = 0; 3093 3094 c = strchr(buf, '\n'); 3095 if (c) 3096 *c = 0; 3097 3098 ret = true; 3099 } 3100 3101 close(fd); 3102 3103 return ret; 3104 } 3105 3106 static bool 3107 read_uint64_file(int dir_fd, const char *file, uint64_t *val) 3108 { 3109 char buf[64]; 3110 bool ret = false; 3111 3112 ret = read_string_file(dir_fd, file, buf, sizeof(buf)); 3113 if (ret) 3114 *val = strtoull(buf, NULL, 0); 3115 3116 return ret; 3117 } 3118 3119 bool 3120 system_if_force_external(const char *ifname) 3121 { 3122 struct stat s; 3123 3124 return stat(dev_sysfs_path(ifname, "phy80211"), &s) == 0; 3125 } 3126 3127 static const char * 3128 system_netdevtype_name(unsigned short dev_type) 3129 { 3130 size_t i; 3131 3132 for (i = 0; i < ARRAY_SIZE(netdev_types); i++) { 3133 if (netdev_types[i].id == dev_type) 3134 return netdev_types[i].name; 3135 } 3136 3137 /* the last key is used by default */ 3138 i = ARRAY_SIZE(netdev_types) - 1; 3139 3140 return netdev_types[i].name; 3141 } 3142 3143 static void 3144 system_add_devtype(struct blob_buf *b, const char *ifname) 3145 { 3146 char buf[100]; 3147 bool found = false; 3148 3149 if (!system_get_dev_sysfs("uevent", ifname, buf, sizeof(buf))) { 3150 const char *info = "DEVTYPE="; 3151 char *context = NULL; 3152 const char *line = strtok_r(buf, "\r\n", &context); 3153 3154 while (line != NULL) { 3155 char *index = strstr(line, info); 3156 3157 if (index != NULL) { 3158 blobmsg_add_string(b, "devtype", index + strlen(info)); 3159 found = true; 3160 break; 3161 } 3162 3163 line = strtok_r(NULL, "\r\n", &context); 3164 } 3165 } 3166 3167 if (!found) { 3168 unsigned short number = 0; 3169 const char *name = NULL; 3170 3171 if (!system_get_dev_sysfs("type", ifname, buf, sizeof(buf))) { 3172 number = strtoul(buf, NULL, 0); 3173 name = system_netdevtype_name(number); 3174 blobmsg_add_string(b, "devtype", name); 3175 } 3176 } 3177 } 3178 3179 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 3180 3181 static int32_t 3182 ethtool_feature_count(const char *ifname) 3183 { 3184 struct { 3185 struct ethtool_sset_info hdr; 3186 uint32_t buf; 3187 } req = { 3188 .hdr = { 3189 .cmd = ETHTOOL_GSSET_INFO, 3190 .sset_mask = 1 << ETH_SS_FEATURES 3191 } 3192 }; 3193 3194 struct ifreq ifr = { 3195 .ifr_data = (void *)&req 3196 }; 3197 3198 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 3199 3200 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) 3201 return -1; 3202 3203 if (!req.hdr.sset_mask) 3204 return 0; 3205 3206 return req.buf; 3207 } 3208 3209 static int32_t 3210 ethtool_feature_index(const char *ifname, const char *keyname) 3211 { 3212 struct ethtool_gstrings *feature_names; 3213 struct ifreq ifr = { 0 }; 3214 int32_t n_features; 3215 uint32_t i; 3216 3217 n_features = ethtool_feature_count(ifname); 3218 3219 if (n_features <= 0) 3220 return -1; 3221 3222 feature_names = calloc(1, sizeof(*feature_names) + n_features * ETH_GSTRING_LEN); 3223 3224 if (!feature_names) 3225 return -1; 3226 3227 feature_names->cmd = ETHTOOL_GSTRINGS; 3228 feature_names->string_set = ETH_SS_FEATURES; 3229 feature_names->len = n_features; 3230 3231 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 3232 ifr.ifr_data = (void *)feature_names; 3233 3234 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) { 3235 free(feature_names); 3236 3237 return -1; 3238 } 3239 3240 for (i = 0; i < feature_names->len; i++) 3241 if (!strcmp((char *)&feature_names->data[i * ETH_GSTRING_LEN], keyname)) 3242 break; 3243 3244 if (i >= feature_names->len) 3245 i = -1; 3246 3247 free(feature_names); 3248 3249 return i; 3250 } 3251 3252 static bool 3253 ethtool_feature_value(const char *ifname, const char *keyname) 3254 { 3255 struct ethtool_get_features_block *feature_block; 3256 struct ethtool_gfeatures *feature_values; 3257 struct ifreq ifr = { 0 }; 3258 int32_t feature_idx; 3259 bool active; 3260 3261 feature_idx = ethtool_feature_index(ifname, keyname); 3262 3263 if (feature_idx < 0) 3264 return false; 3265 3266 feature_values = calloc(1, 3267 sizeof(*feature_values) + 3268 sizeof(feature_values->features[0]) * DIV_ROUND_UP(feature_idx, 32)); 3269 3270 if (!feature_values) 3271 return false; 3272 3273 feature_values->cmd = ETHTOOL_GFEATURES; 3274 feature_values->size = DIV_ROUND_UP(feature_idx, 32); 3275 3276 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 3277 ifr.ifr_data = (void *)feature_values; 3278 3279 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0) { 3280 free(feature_values); 3281 3282 return false; 3283 } 3284 3285 feature_block = &feature_values->features[feature_idx / 32]; 3286 active = feature_block->active & (1U << feature_idx % 32); 3287 3288 free(feature_values); 3289 3290 return active; 3291 } 3292 3293 static void 3294 system_add_link_mode_name(struct blob_buf *b, int i, bool half) 3295 { 3296 char *buf; 3297 3298 /* allocate string buffer large enough for the mode name and a suffix 3299 * "-F" or "-H" indicating full duplex or half duplex. 3300 */ 3301 buf = blobmsg_alloc_string_buffer(b, NULL, strlen(ethtool_modes[i].name) + 3); 3302 if (!buf) 3303 return; 3304 3305 strcpy(buf, ethtool_modes[i].name); 3306 if (half) 3307 strcat(buf, "-H"); 3308 else 3309 strcat(buf, "-F"); 3310 3311 blobmsg_add_string_buffer(b); 3312 } 3313 3314 static void 3315 system_add_link_modes(__s8 nwords, struct blob_buf *b, __u32 *mask) 3316 { 3317 size_t i; 3318 3319 for (i = 0; i < ARRAY_SIZE(ethtool_modes); i++) { 3320 if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_half, mask)) 3321 system_add_link_mode_name(b, i, true); 3322 3323 if (ethtool_link_mode_test_bit(nwords, ethtool_modes[i].bit_full, mask)) 3324 system_add_link_mode_name(b, i, false); 3325 } 3326 } 3327 3328 static void 3329 system_add_pause_modes(__s8 nwords, struct blob_buf *b, __u32 *mask) 3330 { 3331 if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Pause_BIT, mask)) 3332 blobmsg_add_string(b, NULL, "pause"); 3333 3334 if (ethtool_link_mode_test_bit(nwords, ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask)) 3335 blobmsg_add_string(b, NULL, "asym_pause"); 3336 } 3337 3338 3339 static void 3340 system_add_ethtool_pause_an(struct blob_buf *b, __s8 nwords, 3341 __u32 *advertising, __u32 *lp_advertising) 3342 { 3343 bool an_rx = false, an_tx = false; 3344 void *d; 3345 3346 d = blobmsg_open_array(b, "negotiated"); 3347 3348 /* Work out negotiated pause frame usage per 3349 * IEEE 802.3-2005 table 28B-3. 3350 */ 3351 if (ethtool_link_mode_test_bit(nwords, 3352 ETHTOOL_LINK_MODE_Pause_BIT, 3353 advertising) && 3354 ethtool_link_mode_test_bit(nwords, 3355 ETHTOOL_LINK_MODE_Pause_BIT, 3356 lp_advertising)) { 3357 an_tx = true; 3358 an_rx = true; 3359 } else if (ethtool_link_mode_test_bit(nwords, 3360 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 3361 advertising) && 3362 ethtool_link_mode_test_bit(nwords, 3363 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 3364 lp_advertising)) { 3365 if (ethtool_link_mode_test_bit(nwords, 3366 ETHTOOL_LINK_MODE_Pause_BIT, 3367 advertising)) 3368 an_rx = true; 3369 else if (ethtool_link_mode_test_bit(nwords, 3370 ETHTOOL_LINK_MODE_Pause_BIT, 3371 lp_advertising)) 3372 an_tx = true; 3373 } 3374 if (an_tx) 3375 blobmsg_add_string(b, NULL, "rx"); 3376 3377 if (an_rx) 3378 blobmsg_add_string(b, NULL, "tx"); 3379 3380 blobmsg_close_array(b, d); 3381 } 3382 3383 static void 3384 system_get_ethtool_pause(struct device *dev, bool *rx_pause, bool *tx_pause, bool *pause_autoneg) 3385 { 3386 struct ethtool_pauseparam pp; 3387 struct ifreq ifr = { 3388 .ifr_data = (caddr_t)&pp, 3389 }; 3390 3391 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 3392 memset(&pp, 0, sizeof(pp)); 3393 pp.cmd = ETHTOOL_GPAUSEPARAM; 3394 3395 /* may fail */ 3396 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) == -1) { 3397 *pause_autoneg = true; 3398 return; 3399 } 3400 3401 *rx_pause = pp.rx_pause; 3402 *tx_pause = pp.tx_pause; 3403 *pause_autoneg = pp.autoneg; 3404 } 3405 3406 int 3407 system_if_dump_info(struct device *dev, struct blob_buf *b) 3408 { 3409 __u32 *supported, *advertising, *lp_advertising; 3410 bool rx_pause = false, tx_pause = false, pause_autoneg; 3411 struct { 3412 struct ethtool_link_settings req; 3413 __u32 link_mode_data[3 * 127]; 3414 } ecmd; 3415 struct ifreq ifr = { 3416 .ifr_data = (caddr_t)&ecmd, 3417 }; 3418 __s8 nwords; 3419 void *c, *d; 3420 char *s; 3421 3422 system_get_ethtool_pause(dev, &rx_pause, &tx_pause, &pause_autoneg); 3423 3424 memset(&ecmd, 0, sizeof(ecmd)); 3425 ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; 3426 strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1); 3427 3428 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 3429 ecmd.req.link_mode_masks_nwords >= 0 || 3430 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 3431 return -EOPNOTSUPP; 3432 3433 ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords; 3434 3435 if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) < 0 || 3436 ecmd.req.link_mode_masks_nwords <= 0 || 3437 ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) 3438 return -EIO; 3439 3440 nwords = ecmd.req.link_mode_masks_nwords; 3441 supported = &ecmd.link_mode_data[0]; 3442 advertising = &ecmd.link_mode_data[nwords]; 3443 lp_advertising = &ecmd.link_mode_data[2 * nwords]; 3444 3445 c = blobmsg_open_array(b, "link-advertising"); 3446 system_add_link_modes(nwords, b, advertising); 3447 blobmsg_close_array(b, c); 3448 3449 c = blobmsg_open_array(b, "link-partner-advertising"); 3450 system_add_link_modes(nwords, b, lp_advertising); 3451 blobmsg_close_array(b, c); 3452 3453 c = blobmsg_open_array(b, "link-supported"); 3454 system_add_link_modes(nwords, b, supported); 3455 blobmsg_close_array(b, c); 3456 3457 if (ethtool_validate_speed(ecmd.req.speed) && 3458 (ecmd.req.speed != (__u32)SPEED_UNKNOWN) && 3459 (ecmd.req.speed != 0)) { 3460 s = blobmsg_alloc_string_buffer(b, "speed", 10); 3461 snprintf(s, 8, "%d%c", ecmd.req.speed, 3462 ecmd.req.duplex == DUPLEX_HALF ? 'H' : 'F'); 3463 blobmsg_add_string_buffer(b); 3464 } 3465 blobmsg_add_u8(b, "autoneg", !!ecmd.req.autoneg); 3466 3467 c = blobmsg_open_table(b, "flow-control"); 3468 blobmsg_add_u8(b, "autoneg", pause_autoneg); 3469 3470 d = blobmsg_open_array(b, "supported"); 3471 system_add_pause_modes(nwords, b, supported); 3472 blobmsg_close_array(b, d); 3473 3474 if (pause_autoneg) { 3475 d = blobmsg_open_array(b, "link-advertising"); 3476 system_add_pause_modes(nwords, b, advertising); 3477 blobmsg_close_array(b, d); 3478 } 3479 3480 d = blobmsg_open_array(b, "link-partner-advertising"); 3481 system_add_pause_modes(nwords, b, lp_advertising); 3482 blobmsg_close_array(b, d); 3483 3484 if (pause_autoneg) { 3485 system_add_ethtool_pause_an(b, nwords, advertising, 3486 lp_advertising); 3487 } else { 3488 d = blobmsg_open_array(b, "selected"); 3489 if (rx_pause) 3490 blobmsg_add_string(b, NULL, "rx"); 3491 3492 if (tx_pause) 3493 blobmsg_add_string(b, NULL, "tx"); 3494 3495 blobmsg_close_array(b, d); 3496 } 3497 3498 blobmsg_close_table(b, c); 3499 3500 blobmsg_add_u8(b, "hw-tc-offload", 3501 ethtool_feature_value(dev->ifname, "hw-tc-offload")); 3502 3503 system_add_devtype(b, dev->ifname); 3504 3505 /* Add PSE (PoE) status if available */ 3506 { 3507 struct pse_reply_data pse_data; 3508 if (system_pse_get(dev, &pse_data) == 0) { 3509 void *pse_tbl = blobmsg_open_table(b, "pse"); 3510 3511 /* C33 (Clause 33 PoE) status */ 3512 if (pse_data.c33_admin_state) { 3513 const char *state = "unknown"; 3514 switch (pse_data.c33_admin_state) { 3515 case ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED: 3516 state = "disabled"; 3517 break; 3518 case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED: 3519 state = "enabled"; 3520 break; 3521 } 3522 blobmsg_add_string(b, "c33-admin-state", state); 3523 } 3524 3525 if (pse_data.c33_pw_status) { 3526 const char *status = "unknown"; 3527 switch (pse_data.c33_pw_status) { 3528 case ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED: 3529 status = "disabled"; 3530 break; 3531 case ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING: 3532 status = "searching"; 3533 break; 3534 case ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING: 3535 status = "delivering"; 3536 break; 3537 case ETHTOOL_C33_PSE_PW_D_STATUS_TEST: 3538 status = "test"; 3539 break; 3540 case ETHTOOL_C33_PSE_PW_D_STATUS_FAULT: 3541 status = "fault"; 3542 break; 3543 case ETHTOOL_C33_PSE_PW_D_STATUS_OTHERFAULT: 3544 status = "otherfault"; 3545 break; 3546 } 3547 blobmsg_add_string(b, "c33-power-status", status); 3548 } 3549 3550 if (pse_data.c33_pw_class) 3551 blobmsg_add_u32(b, "c33-power-class", pse_data.c33_pw_class); 3552 3553 if (pse_data.c33_actual_pw) 3554 blobmsg_add_u32(b, "c33-actual-power", pse_data.c33_actual_pw); 3555 3556 if (pse_data.c33_avail_pw_limit) 3557 blobmsg_add_u32(b, "c33-available-power-limit", pse_data.c33_avail_pw_limit); 3558 3559 /* PoDL (Power over Data Line) status */ 3560 if (pse_data.podl_admin_state) { 3561 const char *state = "unknown"; 3562 switch (pse_data.podl_admin_state) { 3563 case ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED: 3564 state = "disabled"; 3565 break; 3566 case ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED: 3567 state = "enabled"; 3568 break; 3569 } 3570 blobmsg_add_string(b, "podl-admin-state", state); 3571 } 3572 3573 if (pse_data.podl_pw_status) { 3574 const char *status = "unknown"; 3575 switch (pse_data.podl_pw_status) { 3576 case ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED: 3577 status = "disabled"; 3578 break; 3579 case ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING: 3580 status = "searching"; 3581 break; 3582 case ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING: 3583 status = "delivering"; 3584 break; 3585 case ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP: 3586 status = "sleep"; 3587 break; 3588 case ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE: 3589 status = "idle"; 3590 break; 3591 case ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR: 3592 status = "error"; 3593 break; 3594 } 3595 blobmsg_add_string(b, "podl-power-status", status); 3596 } 3597 3598 /* Priority settings */ 3599 if (pse_data.pse_prio_max) 3600 blobmsg_add_u32(b, "priority-max", pse_data.pse_prio_max); 3601 3602 if (pse_data.pse_prio) 3603 blobmsg_add_u32(b, "priority", pse_data.pse_prio); 3604 3605 blobmsg_close_table(b, pse_tbl); 3606 } 3607 } 3608 3609 return 0; 3610 } 3611 3612 int 3613 system_if_dump_stats(struct device *dev, struct blob_buf *b) 3614 { 3615 const char *const counters[] = { 3616 "collisions", "rx_frame_errors", "tx_compressed", 3617 "multicast", "rx_length_errors", "tx_dropped", 3618 "rx_bytes", "rx_missed_errors", "tx_errors", 3619 "rx_compressed", "rx_over_errors", "tx_fifo_errors", 3620 "rx_crc_errors", "rx_packets", "tx_heartbeat_errors", 3621 "rx_dropped", "tx_aborted_errors", "tx_packets", 3622 "rx_errors", "tx_bytes", "tx_window_errors", 3623 "rx_fifo_errors", "tx_carrier_errors", 3624 }; 3625 int stats_dir; 3626 size_t i; 3627 uint64_t val = 0; 3628 3629 stats_dir = open(dev_sysfs_path(dev->ifname, "statistics"), O_DIRECTORY); 3630 if (stats_dir < 0) 3631 return -1; 3632 3633 for (i = 0; i < ARRAY_SIZE(counters); i++) 3634 if (read_uint64_file(stats_dir, counters[i], &val)) 3635 blobmsg_add_u64(b, counters[i], val); 3636 3637 close(stats_dir); 3638 return 0; 3639 } 3640 3641 static int system_addr(struct device *dev, struct device_addr *addr, int cmd) 3642 { 3643 bool v4 = ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4); 3644 int alen = v4 ? 4 : 16; 3645 unsigned int flags = 0; 3646 struct ifaddrmsg ifa = { 3647 .ifa_family = (alen == 4) ? AF_INET : AF_INET6, 3648 .ifa_prefixlen = addr->mask, 3649 .ifa_index = dev->ifindex, 3650 }; 3651 3652 struct nl_msg *msg; 3653 if (cmd == RTM_NEWADDR) 3654 flags |= NLM_F_CREATE | NLM_F_REPLACE; 3655 3656 msg = nlmsg_alloc_simple(cmd, flags); 3657 if (!msg) 3658 return -1; 3659 3660 nlmsg_append(msg, &ifa, sizeof(ifa), 0); 3661 nla_put(msg, IFA_LOCAL, alen, &addr->addr); 3662 if (v4) { 3663 if (addr->broadcast) 3664 nla_put_u32(msg, IFA_BROADCAST, addr->broadcast); 3665 if (addr->point_to_point) 3666 nla_put_u32(msg, IFA_ADDRESS, addr->point_to_point); 3667 } else { 3668 time_t now = system_get_rtime(); 3669 struct ifa_cacheinfo cinfo = {0xffffffffU, 0xffffffffU, 0, 0}; 3670 3671 if (addr->preferred_until) { 3672 int64_t preferred = addr->preferred_until - now; 3673 if (preferred < 0) 3674 preferred = 0; 3675 else if (preferred > UINT32_MAX) 3676 preferred = UINT32_MAX; 3677 3678 cinfo.ifa_prefered = preferred; 3679 } 3680 3681 if (addr->valid_until) { 3682 int64_t valid = addr->valid_until - now; 3683 if (valid <= 0) { 3684 nlmsg_free(msg); 3685 return -1; 3686 } 3687 else if (valid > UINT32_MAX) 3688 valid = UINT32_MAX; 3689 3690 cinfo.ifa_valid = valid; 3691 } 3692 3693 nla_put(msg, IFA_CACHEINFO, sizeof(cinfo), &cinfo); 3694 3695 if (cmd == RTM_NEWADDR && (addr->flags & DEVADDR_OFFLINK)) 3696 nla_put_u32(msg, IFA_FLAGS, IFA_F_NOPREFIXROUTE); 3697 } 3698 3699 return system_rtnl_call(msg); 3700 } 3701 3702 int system_add_address(struct device *dev, struct device_addr *addr) 3703 { 3704 return system_addr(dev, addr, RTM_NEWADDR); 3705 } 3706 3707 int system_del_address(struct device *dev, struct device_addr *addr) 3708 { 3709 return system_addr(dev, addr, RTM_DELADDR); 3710 } 3711 3712 static int system_neigh(struct device *dev, struct device_neighbor *neighbor, int cmd) 3713 { 3714 int alen = ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16; 3715 unsigned int flags = 0; 3716 struct ndmsg ndm = { 3717 .ndm_family = (alen == 4) ? AF_INET : AF_INET6, 3718 .ndm_ifindex = dev->ifindex, 3719 .ndm_state = NUD_PERMANENT, 3720 .ndm_flags = (neighbor->proxy ? NTF_PROXY : 0) | (neighbor->router ? NTF_ROUTER : 0), 3721 }; 3722 struct nl_msg *msg; 3723 3724 if (cmd == RTM_NEWNEIGH) 3725 flags |= NLM_F_CREATE | NLM_F_REPLACE; 3726 3727 msg = nlmsg_alloc_simple(cmd, flags); 3728 3729 if (!msg) 3730 return -1; 3731 3732 nlmsg_append(msg, &ndm, sizeof(ndm), 0); 3733 3734 nla_put(msg, NDA_DST, alen, &neighbor->addr); 3735 if (neighbor->flags & DEVNEIGH_MAC) 3736 nla_put(msg, NDA_LLADDR, sizeof(neighbor->macaddr), &neighbor->macaddr); 3737 3738 3739 return system_rtnl_call(msg); 3740 } 3741 3742 int system_add_neighbor(struct device *dev, struct device_neighbor *neighbor) 3743 { 3744 return system_neigh(dev, neighbor, RTM_NEWNEIGH); 3745 } 3746 3747 int system_del_neighbor(struct device *dev, struct device_neighbor *neighbor) 3748 { 3749 return system_neigh(dev, neighbor, RTM_DELNEIGH); 3750 } 3751 3752 static int system_rt(struct device *dev, struct device_route *route, int cmd) 3753 { 3754 int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16; 3755 bool have_gw; 3756 unsigned int flags = 0; 3757 3758 if (alen == 4) 3759 have_gw = !!route->nexthop.in.s_addr; 3760 else 3761 have_gw = route->nexthop.in6.s6_addr32[0] || 3762 route->nexthop.in6.s6_addr32[1] || 3763 route->nexthop.in6.s6_addr32[2] || 3764 route->nexthop.in6.s6_addr32[3]; 3765 3766 unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE)) 3767 ? route->table : RT_TABLE_MAIN; 3768 3769 struct rtmsg rtm = { 3770 .rtm_family = (alen == 4) ? AF_INET : AF_INET6, 3771 .rtm_dst_len = route->mask, 3772 .rtm_src_len = route->sourcemask, 3773 .rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC, 3774 .rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC, 3775 .rtm_scope = RT_SCOPE_NOWHERE, 3776 .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST, 3777 .rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0, 3778 }; 3779 struct nl_msg *msg; 3780 3781 if (cmd == RTM_NEWROUTE) { 3782 flags |= NLM_F_CREATE | NLM_F_REPLACE; 3783 3784 if (!dev) { /* Add null-route */ 3785 rtm.rtm_scope = RT_SCOPE_UNIVERSE; 3786 rtm.rtm_type = RTN_UNREACHABLE; 3787 } 3788 else 3789 rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK; 3790 } 3791 3792 if (route->flags & DEVROUTE_TYPE) { 3793 rtm.rtm_type = route->type; 3794 if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) { 3795 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST || 3796 rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST) 3797 rtm.rtm_table = RT_TABLE_LOCAL; 3798 } 3799 3800 if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) { 3801 rtm.rtm_scope = RT_SCOPE_HOST; 3802 } else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST || 3803 rtm.rtm_type == RTN_ANYCAST) { 3804 rtm.rtm_scope = RT_SCOPE_LINK; 3805 } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE || 3806 rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY || 3807 rtm.rtm_type == RTN_THROW) { 3808 rtm.rtm_scope = RT_SCOPE_UNIVERSE; 3809 dev = NULL; 3810 } 3811 } 3812 3813 if (route->flags & DEVROUTE_NODEV) 3814 dev = NULL; 3815 3816 msg = nlmsg_alloc_simple(cmd, flags); 3817 if (!msg) 3818 return -1; 3819 3820 nlmsg_append(msg, &rtm, sizeof(rtm), 0); 3821 3822 if (route->mask) 3823 nla_put(msg, RTA_DST, alen, &route->addr); 3824 3825 if (route->sourcemask) { 3826 if (rtm.rtm_family == AF_INET) 3827 nla_put(msg, RTA_PREFSRC, alen, &route->source); 3828 else 3829 nla_put(msg, RTA_SRC, alen, &route->source); 3830 } 3831 3832 if (route->metric > 0) 3833 nla_put_u32(msg, RTA_PRIORITY, route->metric); 3834 3835 if (have_gw) 3836 nla_put(msg, RTA_GATEWAY, alen, &route->nexthop); 3837 3838 if (dev) 3839 nla_put_u32(msg, RTA_OIF, dev->ifindex); 3840 3841 if (table >= 256) 3842 nla_put_u32(msg, RTA_TABLE, table); 3843 3844 if (route->flags & DEVROUTE_MTU) { 3845 struct nlattr *metrics; 3846 3847 if (!(metrics = nla_nest_start(msg, RTA_METRICS))) 3848 goto nla_put_failure; 3849 3850 nla_put_u32(msg, RTAX_MTU, route->mtu); 3851 3852 nla_nest_end(msg, metrics); 3853 } 3854 3855 return system_rtnl_call(msg); 3856 3857 nla_put_failure: 3858 nlmsg_free(msg); 3859 return -ENOMEM; 3860 } 3861 3862 int system_add_route(struct device *dev, struct device_route *route) 3863 { 3864 return system_rt(dev, route, RTM_NEWROUTE); 3865 } 3866 3867 int system_del_route(struct device *dev, struct device_route *route) 3868 { 3869 return system_rt(dev, route, RTM_DELROUTE); 3870 } 3871 3872 int system_flush_routes(void) 3873 { 3874 const char *names[] = { "ipv4", "ipv6" }; 3875 size_t i; 3876 int fd; 3877 3878 for (i = 0; i < ARRAY_SIZE(names); i++) { 3879 snprintf(dev_buf, sizeof(dev_buf), "%s/sys/net/%s/route/flush", proc_path, names[i]); 3880 fd = open(dev_buf, O_WRONLY); 3881 if (fd < 0) 3882 continue; 3883 3884 if (write(fd, "-1", 2)) {} 3885 close(fd); 3886 } 3887 return 0; 3888 } 3889 3890 bool system_resolve_rt_type(const char *type, unsigned int *id) 3891 { 3892 return system_rtn_aton(type, id); 3893 } 3894 3895 bool system_resolve_rt_proto(const char *type, unsigned int *id) 3896 { 3897 FILE *f; 3898 char *e, buf[128]; 3899 unsigned int n, proto = 256; 3900 n = strtoul(type, &e, 0); 3901 if (!*e && e != type) 3902 proto = n; 3903 else if (!strcmp(type, "unspec")) 3904 proto = RTPROT_UNSPEC; 3905 else if (!strcmp(type, "kernel")) 3906 proto = RTPROT_KERNEL; 3907 else if (!strcmp(type, "boot")) 3908 proto = RTPROT_BOOT; 3909 else if (!strcmp(type, "static")) 3910 proto = RTPROT_STATIC; 3911 else if ((f = fopen("/etc/iproute2/rt_protos", "r")) != NULL) { 3912 while (fgets(buf, sizeof(buf) - 1, f) != NULL) { 3913 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#') 3914 continue; 3915 3916 n = strtoul(e, NULL, 10); 3917 e = strtok(NULL, " \t\n"); 3918 3919 if (e && !strcmp(e, type)) { 3920 proto = n; 3921 break; 3922 } 3923 } 3924 fclose(f); 3925 } 3926 3927 if (proto > 255) 3928 return false; 3929 3930 *id = proto; 3931 return true; 3932 } 3933 3934 bool system_resolve_rt_table(const char *name, unsigned int *id) 3935 { 3936 FILE *f; 3937 char *e, buf[128]; 3938 unsigned int n, table = RT_TABLE_UNSPEC; 3939 3940 /* first try to parse table as number */ 3941 if ((n = strtoul(name, &e, 0)) > 0 && !*e) 3942 table = n; 3943 3944 /* handle well known aliases */ 3945 else if (!strcmp(name, "default")) 3946 table = RT_TABLE_DEFAULT; 3947 else if (!strcmp(name, "main")) 3948 table = RT_TABLE_MAIN; 3949 else if (!strcmp(name, "local")) 3950 table = RT_TABLE_LOCAL; 3951 3952 /* try to look up name in /etc/iproute2/rt_tables */ 3953 else if ((f = fopen("/etc/iproute2/rt_tables", "r")) != NULL) 3954 { 3955 while (fgets(buf, sizeof(buf) - 1, f) != NULL) 3956 { 3957 if ((e = strtok(buf, " \t\n")) == NULL || *e == '#') 3958 continue; 3959 3960 n = strtoul(e, NULL, 10); 3961 e = strtok(NULL, " \t\n"); 3962 3963 if (e && !strcmp(e, name)) 3964 { 3965 table = n; 3966 break; 3967 } 3968 } 3969 3970 fclose(f); 3971 } 3972 3973 if (table == RT_TABLE_UNSPEC) 3974 return false; 3975 3976 *id = table; 3977 return true; 3978 } 3979 3980 bool system_is_default_rt_table(unsigned int id) 3981 { 3982 return (id == RT_TABLE_MAIN); 3983 } 3984 3985 bool system_resolve_rpfilter(const char *filter, unsigned int *id) 3986 { 3987 char *e; 3988 unsigned int n; 3989 3990 if (!strcmp(filter, "strict")) 3991 n = 1; 3992 else if (!strcmp(filter, "loose")) 3993 n = 2; 3994 else { 3995 n = strtoul(filter, &e, 0); 3996 if (*e || e == filter || n > 2) 3997 return false; 3998 } 3999 4000 *id = n; 4001 return true; 4002 } 4003 4004 static int system_iprule(struct iprule *rule, int cmd) 4005 { 4006 int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16; 4007 4008 struct nl_msg *msg; 4009 struct rtmsg rtm = { 4010 .rtm_family = (alen == 4) ? AF_INET : AF_INET6, 4011 .rtm_protocol = RTPROT_STATIC, 4012 .rtm_scope = RT_SCOPE_UNIVERSE, 4013 .rtm_table = RT_TABLE_UNSPEC, 4014 .rtm_type = RTN_UNSPEC, 4015 .rtm_flags = 0, 4016 }; 4017 4018 if (cmd == RTM_NEWRULE) 4019 rtm.rtm_type = RTN_UNICAST; 4020 4021 if (rule->invert) 4022 rtm.rtm_flags |= FIB_RULE_INVERT; 4023 4024 if (rule->flags & IPRULE_SRC) 4025 rtm.rtm_src_len = rule->src_mask; 4026 4027 if (rule->flags & IPRULE_DEST) 4028 rtm.rtm_dst_len = rule->dest_mask; 4029 4030 if (rule->flags & IPRULE_TOS) 4031 rtm.rtm_tos = rule->tos; 4032 4033 if (rule->flags & IPRULE_LOOKUP) { 4034 if (rule->lookup < 256) 4035 rtm.rtm_table = rule->lookup; 4036 } 4037 4038 if (rule->flags & IPRULE_ACTION) 4039 rtm.rtm_type = rule->action; 4040 else if (rule->flags & IPRULE_GOTO) 4041 rtm.rtm_type = FR_ACT_GOTO; 4042 else if (!(rule->flags & (IPRULE_LOOKUP | IPRULE_ACTION | IPRULE_GOTO))) 4043 rtm.rtm_type = FR_ACT_NOP; 4044 4045 msg = nlmsg_alloc_simple(cmd, NLM_F_REQUEST); 4046 4047 if (!msg) 4048 return -1; 4049 4050 nlmsg_append(msg, &rtm, sizeof(rtm), 0); 4051 4052 if (rule->flags & IPRULE_IN) 4053 nla_put(msg, FRA_IFNAME, strlen(rule->in_dev) + 1, rule->in_dev); 4054 4055 if (rule->flags & IPRULE_OUT) 4056 nla_put(msg, FRA_OIFNAME, strlen(rule->out_dev) + 1, rule->out_dev); 4057 4058 if (rule->flags & IPRULE_SRC) 4059 nla_put(msg, FRA_SRC, alen, &rule->src_addr); 4060 4061 if (rule->flags & IPRULE_DEST) 4062 nla_put(msg, FRA_DST, alen, &rule->dest_addr); 4063 4064 if (rule->flags & IPRULE_PRIORITY) 4065 nla_put_u32(msg, FRA_PRIORITY, rule->priority); 4066 else if (cmd == RTM_NEWRULE) 4067 nla_put_u32(msg, FRA_PRIORITY, rule->order); 4068 4069 if (rule->flags & IPRULE_FWMARK) 4070 nla_put_u32(msg, FRA_FWMARK, rule->fwmark); 4071 4072 if (rule->flags & IPRULE_FWMASK) 4073 nla_put_u32(msg, FRA_FWMASK, rule->fwmask); 4074 4075 if (rule->flags & IPRULE_LOOKUP) { 4076 if (rule->lookup >= 256) 4077 nla_put_u32(msg, FRA_TABLE, rule->lookup); 4078 } 4079 4080 if (rule->flags & IPRULE_SUP_PREFIXLEN) 4081 nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen); 4082 4083 if (rule->flags & IPRULE_UIDRANGE) { 4084 struct fib_rule_uid_range uidrange = { 4085 .start = rule->uidrange_start, 4086 .end = rule->uidrange_end 4087 }; 4088 4089 nla_put(msg, FRA_UID_RANGE, sizeof(uidrange), &uidrange); 4090 } 4091 4092 if (rule->flags & IPRULE_GOTO) 4093 nla_put_u32(msg, FRA_GOTO, rule->gotoid); 4094 4095 if (rule->flags & IPRULE_IPPROTO) 4096 nla_put_u8(msg, FRA_IP_PROTO, rule->ipproto); 4097 4098 if (rule->flags & IPRULE_SPORT) { 4099 struct fib_rule_port_range sportrange = { 4100 .start = rule->sport_start, 4101 .end = rule->sport_end 4102 }; 4103 4104 nla_put(msg, FRA_SPORT_RANGE, sizeof(sportrange), &sportrange); 4105 } 4106 4107 if (rule->flags & IPRULE_DPORT) { 4108 struct fib_rule_port_range dportrange = { 4109 .start = rule->dport_start, 4110 .end = rule->dport_end 4111 }; 4112 4113 nla_put(msg, FRA_DPORT_RANGE, sizeof(dportrange), &dportrange); 4114 } 4115 4116 return system_rtnl_call(msg); 4117 } 4118 4119 int system_add_iprule(struct iprule *rule) 4120 { 4121 return system_iprule(rule, RTM_NEWRULE); 4122 } 4123 4124 int system_del_iprule(struct iprule *rule) 4125 { 4126 return system_iprule(rule, RTM_DELRULE); 4127 } 4128 4129 int system_flush_iprules(void) 4130 { 4131 int rv = 0; 4132 struct iprule rule; 4133 4134 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET); 4135 system_if_clear_entries(NULL, RTM_GETRULE, AF_INET6); 4136 4137 memset(&rule, 0, sizeof(rule)); 4138 4139 4140 rule.flags = IPRULE_INET4 | IPRULE_PRIORITY | IPRULE_LOOKUP; 4141 4142 rule.priority = 0; 4143 rule.lookup = RT_TABLE_LOCAL; 4144 rv |= system_iprule(&rule, RTM_NEWRULE); 4145 4146 rule.priority = 32766; 4147 rule.lookup = RT_TABLE_MAIN; 4148 rv |= system_iprule(&rule, RTM_NEWRULE); 4149 4150 rule.priority = 32767; 4151 rule.lookup = RT_TABLE_DEFAULT; 4152 rv |= system_iprule(&rule, RTM_NEWRULE); 4153 4154 4155 rule.flags = IPRULE_INET6 | IPRULE_PRIORITY | IPRULE_LOOKUP; 4156 4157 rule.priority = 0; 4158 rule.lookup = RT_TABLE_LOCAL; 4159 rv |= system_iprule(&rule, RTM_NEWRULE); 4160 4161 rule.priority = 32766; 4162 rule.lookup = RT_TABLE_MAIN; 4163 rv |= system_iprule(&rule, RTM_NEWRULE); 4164 4165 return rv; 4166 } 4167 4168 bool system_resolve_iprule_action(const char *action, unsigned int *id) 4169 { 4170 return system_rtn_aton(action, id); 4171 } 4172 4173 bool system_resolve_iprule_ipproto(const char *name, unsigned int *id) 4174 { 4175 char *e; 4176 struct protoent *ent; 4177 unsigned int n, ipproto = 0; 4178 4179 if ((n = strtoul(name, &e, 0)) > 0 && *e == '\0') 4180 ipproto = n; 4181 else { 4182 ent = getprotobyname(name); 4183 4184 if (ent) 4185 ipproto = ent->p_proto; 4186 else 4187 return false; 4188 } 4189 4190 *id = ipproto; 4191 return true; 4192 } 4193 4194 time_t system_get_rtime(void) 4195 { 4196 struct timespec ts; 4197 struct timeval tv; 4198 4199 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) 4200 return ts.tv_sec; 4201 4202 if (gettimeofday(&tv, NULL) == 0) 4203 return tv.tv_sec; 4204 4205 return 0; 4206 } 4207 4208 #ifndef IP_DF 4209 #define IP_DF 0x4000 4210 #endif 4211 4212 static int tunnel_ioctl(const char *name, int cmd, void *p) 4213 { 4214 struct ifreq ifr; 4215 4216 memset(&ifr, 0, sizeof(ifr)); 4217 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1); 4218 ifr.ifr_ifru.ifru_data = p; 4219 return ioctl(sock_ioctl, cmd, &ifr); 4220 } 4221 4222 #ifdef IFLA_IPTUN_MAX 4223 static int system_add_ip6_tunnel(const char *name, const unsigned int link, 4224 struct blob_attr **tb) 4225 { 4226 struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK, 4227 NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 4228 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC }; 4229 struct blob_attr *cur; 4230 int ret = 0, ttl = 0; 4231 4232 if (!nlm) 4233 return -1; 4234 4235 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 4236 nla_put_string(nlm, IFLA_IFNAME, name); 4237 4238 if (link) 4239 nla_put_u32(nlm, IFLA_LINK, link); 4240 4241 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 4242 if (!linkinfo) { 4243 ret = -ENOMEM; 4244 goto failure; 4245 } 4246 4247 nla_put_string(nlm, IFLA_INFO_KIND, "ip6tnl"); 4248 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 4249 if (!infodata) { 4250 ret = -ENOMEM; 4251 goto failure; 4252 } 4253 4254 if (link) 4255 nla_put_u32(nlm, IFLA_IPTUN_LINK, link); 4256 4257 if ((cur = tb[TUNNEL_ATTR_TTL])) 4258 ttl = blobmsg_get_u32(cur); 4259 4260 nla_put_u8(nlm, IFLA_IPTUN_PROTO, IPPROTO_IPIP); 4261 nla_put_u8(nlm, IFLA_IPTUN_TTL, (ttl) ? ttl : 64); 4262 4263 struct in6_addr in6buf; 4264 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4265 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4266 ret = -EINVAL; 4267 goto failure; 4268 } 4269 nla_put(nlm, IFLA_IPTUN_LOCAL, sizeof(in6buf), &in6buf); 4270 } 4271 4272 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4273 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4274 ret = -EINVAL; 4275 goto failure; 4276 } 4277 nla_put(nlm, IFLA_IPTUN_REMOTE, sizeof(in6buf), &in6buf); 4278 } 4279 4280 if ((cur = tb[TUNNEL_ATTR_DATA])) { 4281 struct blob_attr *tb_data[__IPIP6_DATA_ATTR_MAX]; 4282 uint32_t tun_flags = IP6_TNL_F_IGN_ENCAP_LIMIT; 4283 4284 blobmsg_parse_attr(ipip6_data_attr_list.params, __IPIP6_DATA_ATTR_MAX, 4285 tb_data, cur); 4286 4287 if ((cur = tb_data[IPIP6_DATA_ENCAPLIMIT])) { 4288 char *str = blobmsg_get_string(cur); 4289 4290 if (strcmp(str, "ignore")) { 4291 char *e; 4292 unsigned encap_limit = strtoul(str, &e, 0); 4293 4294 if (e == str || *e || encap_limit > 255) { 4295 ret = -EINVAL; 4296 goto failure; 4297 } 4298 4299 nla_put_u8(nlm, IFLA_IPTUN_ENCAP_LIMIT, encap_limit); 4300 tun_flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; 4301 } 4302 } 4303 4304 #ifdef IFLA_IPTUN_FMR_MAX 4305 if ((cur = tb_data[IPIP6_DATA_FMRS])) { 4306 struct blob_attr *rcur; 4307 unsigned rrem, fmrcnt = 0; 4308 struct nlattr *fmrs = nla_nest_start(nlm, IFLA_IPTUN_FMRS); 4309 4310 if (!fmrs) { 4311 ret = -ENOMEM; 4312 goto failure; 4313 } 4314 4315 blobmsg_for_each_attr(rcur, cur, rrem) { 4316 struct blob_attr *tb_fmr[__FMR_DATA_ATTR_MAX], *tb_cur; 4317 struct in6_addr ip6prefix; 4318 struct in_addr ip4prefix; 4319 unsigned ip4len, ip6len, ealen, offset; 4320 4321 blobmsg_parse_attr(fmr_data_attr_list.params, __FMR_DATA_ATTR_MAX, 4322 tb_fmr, rcur); 4323 4324 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX6]) || 4325 !parse_ip_and_netmask(AF_INET6, 4326 blobmsg_data(tb_cur), &ip6prefix, 4327 &ip6len)) { 4328 ret = -EINVAL; 4329 goto failure; 4330 } 4331 4332 if (!(tb_cur = tb_fmr[FMR_DATA_PREFIX4]) || 4333 !parse_ip_and_netmask(AF_INET, 4334 blobmsg_data(tb_cur), &ip4prefix, 4335 &ip4len)) { 4336 ret = -EINVAL; 4337 goto failure; 4338 } 4339 4340 if (!(tb_cur = tb_fmr[FMR_DATA_EALEN])) { 4341 ret = -EINVAL; 4342 goto failure; 4343 } 4344 ealen = blobmsg_get_u32(tb_cur); 4345 4346 if (!(tb_cur = tb_fmr[FMR_DATA_OFFSET])) { 4347 ret = -EINVAL; 4348 goto failure; 4349 } 4350 offset = blobmsg_get_u32(tb_cur); 4351 4352 struct nlattr *rule = nla_nest_start(nlm, ++fmrcnt); 4353 if (!rule) { 4354 ret = -ENOMEM; 4355 goto failure; 4356 } 4357 4358 nla_put(nlm, IFLA_IPTUN_FMR_IP6_PREFIX, sizeof(ip6prefix), &ip6prefix); 4359 nla_put(nlm, IFLA_IPTUN_FMR_IP4_PREFIX, sizeof(ip4prefix), &ip4prefix); 4360 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, ip6len); 4361 nla_put_u8(nlm, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, ip4len); 4362 nla_put_u8(nlm, IFLA_IPTUN_FMR_EA_LEN, ealen); 4363 nla_put_u8(nlm, IFLA_IPTUN_FMR_OFFSET, offset); 4364 4365 nla_nest_end(nlm, rule); 4366 } 4367 4368 nla_nest_end(nlm, fmrs); 4369 } 4370 #endif 4371 if (tun_flags) 4372 nla_put_u32(nlm, IFLA_IPTUN_FLAGS, tun_flags); 4373 } 4374 4375 nla_nest_end(nlm, infodata); 4376 nla_nest_end(nlm, linkinfo); 4377 4378 return system_rtnl_call(nlm); 4379 4380 failure: 4381 nlmsg_free(nlm); 4382 return ret; 4383 } 4384 #endif 4385 4386 #ifdef IFLA_IPTUN_MAX 4387 #define IP6_FLOWINFO_TCLASS htonl(0x0FF00000) 4388 static int system_add_gre_tunnel(const char *name, const char *kind, 4389 const unsigned int link, struct blob_attr **tb, bool v6) 4390 { 4391 struct nl_msg *nlm; 4392 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, }; 4393 struct blob_attr *cur; 4394 uint32_t ikey = 0, okey = 0, flowinfo = 0, flags6 = IP6_TNL_F_IGN_ENCAP_LIMIT; 4395 uint16_t iflags = 0, oflags = 0; 4396 uint8_t tos = 0; 4397 int ret = 0, ttl = 0; 4398 unsigned encap_limit = 0; 4399 4400 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 4401 if (!nlm) 4402 return -1; 4403 4404 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 4405 nla_put_string(nlm, IFLA_IFNAME, name); 4406 4407 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 4408 if (!linkinfo) { 4409 ret = -ENOMEM; 4410 goto failure; 4411 } 4412 4413 nla_put_string(nlm, IFLA_INFO_KIND, kind); 4414 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 4415 if (!infodata) { 4416 ret = -ENOMEM; 4417 goto failure; 4418 } 4419 4420 if (link) 4421 nla_put_u32(nlm, IFLA_GRE_LINK, link); 4422 4423 if ((cur = tb[TUNNEL_ATTR_TTL])) 4424 ttl = blobmsg_get_u32(cur); 4425 4426 if ((cur = tb[TUNNEL_ATTR_TOS])) { 4427 char *str = blobmsg_get_string(cur); 4428 if (strcmp(str, "inherit")) { 4429 unsigned uval; 4430 4431 if (!system_tos_aton(str, &uval)) { 4432 ret = -EINVAL; 4433 goto failure; 4434 } 4435 4436 if (v6) 4437 flowinfo |= htonl(uval << 20) & IP6_FLOWINFO_TCLASS; 4438 else 4439 tos = uval; 4440 } else { 4441 if (v6) 4442 flags6 |= IP6_TNL_F_USE_ORIG_TCLASS; 4443 else 4444 tos = 1; 4445 } 4446 } 4447 4448 if ((cur = tb[TUNNEL_ATTR_DATA])) { 4449 struct blob_attr *tb_data[__GRE_DATA_ATTR_MAX]; 4450 4451 blobmsg_parse_attr(gre_data_attr_list.params, __GRE_DATA_ATTR_MAX, 4452 tb_data, cur); 4453 4454 if ((cur = tb_data[GRE_DATA_IKEY])) { 4455 if ((ikey = blobmsg_get_u32(cur))) 4456 iflags |= GRE_KEY; 4457 } 4458 4459 if ((cur = tb_data[GRE_DATA_OKEY])) { 4460 if ((okey = blobmsg_get_u32(cur))) 4461 oflags |= GRE_KEY; 4462 } 4463 4464 if ((cur = tb_data[GRE_DATA_ICSUM])) { 4465 if (blobmsg_get_bool(cur)) 4466 iflags |= GRE_CSUM; 4467 } 4468 4469 if ((cur = tb_data[GRE_DATA_OCSUM])) { 4470 if (blobmsg_get_bool(cur)) 4471 oflags |= GRE_CSUM; 4472 } 4473 4474 if ((cur = tb_data[GRE_DATA_ISEQNO])) { 4475 if (blobmsg_get_bool(cur)) 4476 iflags |= GRE_SEQ; 4477 } 4478 4479 if ((cur = tb_data[GRE_DATA_OSEQNO])) { 4480 if (blobmsg_get_bool(cur)) 4481 oflags |= GRE_SEQ; 4482 } 4483 4484 if ((cur = tb_data[GRE_DATA_ENCAPLIMIT])) { 4485 char *str = blobmsg_get_string(cur); 4486 4487 if (strcmp(str, "ignore")) { 4488 char *e; 4489 4490 encap_limit = strtoul(str, &e, 0); 4491 4492 if (e == str || *e || encap_limit > 255) { 4493 ret = -EINVAL; 4494 goto failure; 4495 } 4496 4497 flags6 &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; 4498 } 4499 } 4500 } 4501 4502 if (v6) { 4503 struct in6_addr in6buf; 4504 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4505 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4506 ret = -EINVAL; 4507 goto failure; 4508 } 4509 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(in6buf), &in6buf); 4510 } 4511 4512 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4513 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4514 ret = -EINVAL; 4515 goto failure; 4516 } 4517 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(in6buf), &in6buf); 4518 } 4519 4520 if (!(flags6 & IP6_TNL_F_IGN_ENCAP_LIMIT)) 4521 nla_put_u8(nlm, IFLA_GRE_ENCAP_LIMIT, encap_limit); 4522 4523 if (flowinfo) 4524 nla_put_u32(nlm, IFLA_GRE_FLOWINFO, flowinfo); 4525 4526 if (flags6) 4527 nla_put_u32(nlm, IFLA_GRE_FLAGS, flags6); 4528 4529 if (!ttl) 4530 ttl = 64; 4531 } else { 4532 struct in_addr inbuf; 4533 bool set_df = true; 4534 4535 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4536 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4537 ret = -EINVAL; 4538 goto failure; 4539 } 4540 nla_put(nlm, IFLA_GRE_LOCAL, sizeof(inbuf), &inbuf); 4541 } 4542 4543 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4544 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4545 ret = -EINVAL; 4546 goto failure; 4547 } 4548 nla_put(nlm, IFLA_GRE_REMOTE, sizeof(inbuf), &inbuf); 4549 4550 if (IN_MULTICAST(ntohl(inbuf.s_addr))) { 4551 if (!okey) { 4552 okey = inbuf.s_addr; 4553 oflags |= GRE_KEY; 4554 } 4555 4556 if (!ikey) { 4557 ikey = inbuf.s_addr; 4558 iflags |= GRE_KEY; 4559 } 4560 } 4561 } 4562 4563 if ((cur = tb[TUNNEL_ATTR_DF])) 4564 set_df = blobmsg_get_bool(cur); 4565 4566 if (!set_df) { 4567 /* ttl != 0 and nopmtudisc are incompatible */ 4568 if (ttl) { 4569 ret = -EINVAL; 4570 goto failure; 4571 } 4572 } else if (!ttl) 4573 ttl = 64; 4574 4575 nla_put_u8(nlm, IFLA_GRE_PMTUDISC, set_df ? 1 : 0); 4576 4577 nla_put_u8(nlm, IFLA_GRE_TOS, tos); 4578 } 4579 4580 if (ttl) 4581 nla_put_u8(nlm, IFLA_GRE_TTL, ttl); 4582 4583 if (oflags) 4584 nla_put_u16(nlm, IFLA_GRE_OFLAGS, oflags); 4585 4586 if (iflags) 4587 nla_put_u16(nlm, IFLA_GRE_IFLAGS, iflags); 4588 4589 if (okey) 4590 nla_put_u32(nlm, IFLA_GRE_OKEY, htonl(okey)); 4591 4592 if (ikey) 4593 nla_put_u32(nlm, IFLA_GRE_IKEY, htonl(ikey)); 4594 4595 nla_nest_end(nlm, infodata); 4596 nla_nest_end(nlm, linkinfo); 4597 4598 return system_rtnl_call(nlm); 4599 4600 failure: 4601 nlmsg_free(nlm); 4602 return ret; 4603 } 4604 #endif 4605 4606 #ifdef IFLA_VTI_MAX 4607 static int system_add_vti_tunnel(const char *name, const char *kind, 4608 const unsigned int link, struct blob_attr **tb, bool v6) 4609 { 4610 struct nl_msg *nlm; 4611 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, }; 4612 struct blob_attr *cur; 4613 int ret = 0; 4614 4615 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 4616 if (!nlm) 4617 return -1; 4618 4619 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 4620 nla_put_string(nlm, IFLA_IFNAME, name); 4621 4622 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 4623 if (!linkinfo) { 4624 ret = -ENOMEM; 4625 goto failure; 4626 } 4627 4628 nla_put_string(nlm, IFLA_INFO_KIND, kind); 4629 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 4630 if (!infodata) { 4631 ret = -ENOMEM; 4632 goto failure; 4633 } 4634 4635 if (link) 4636 nla_put_u32(nlm, IFLA_VTI_LINK, link); 4637 4638 if (v6) { 4639 struct in6_addr in6buf; 4640 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4641 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4642 ret = -EINVAL; 4643 goto failure; 4644 } 4645 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(in6buf), &in6buf); 4646 } 4647 4648 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4649 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4650 ret = -EINVAL; 4651 goto failure; 4652 } 4653 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(in6buf), &in6buf); 4654 } 4655 4656 } else { 4657 struct in_addr inbuf; 4658 4659 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4660 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4661 ret = -EINVAL; 4662 goto failure; 4663 } 4664 nla_put(nlm, IFLA_VTI_LOCAL, sizeof(inbuf), &inbuf); 4665 } 4666 4667 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4668 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4669 ret = -EINVAL; 4670 goto failure; 4671 } 4672 nla_put(nlm, IFLA_VTI_REMOTE, sizeof(inbuf), &inbuf); 4673 } 4674 4675 } 4676 4677 if ((cur = tb[TUNNEL_ATTR_DATA])) { 4678 struct blob_attr *tb_data[__VTI_DATA_ATTR_MAX]; 4679 uint32_t ikey = 0, okey = 0; 4680 4681 blobmsg_parse_attr(vti_data_attr_list.params, __VTI_DATA_ATTR_MAX, 4682 tb_data, cur); 4683 4684 if ((cur = tb_data[VTI_DATA_IKEY])) { 4685 if ((ikey = blobmsg_get_u32(cur))) 4686 nla_put_u32(nlm, IFLA_VTI_IKEY, htonl(ikey)); 4687 } 4688 4689 if ((cur = tb_data[VTI_DATA_OKEY])) { 4690 if ((okey = blobmsg_get_u32(cur))) 4691 nla_put_u32(nlm, IFLA_VTI_OKEY, htonl(okey)); 4692 } 4693 } 4694 4695 nla_nest_end(nlm, infodata); 4696 nla_nest_end(nlm, linkinfo); 4697 4698 return system_rtnl_call(nlm); 4699 4700 failure: 4701 nlmsg_free(nlm); 4702 return ret; 4703 } 4704 #endif 4705 4706 #ifdef IFLA_XFRM_MAX 4707 static int system_add_xfrm_tunnel(const char *name, const char *kind, 4708 const unsigned int link, struct blob_attr **tb) 4709 { 4710 struct nl_msg *nlm; 4711 struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, }; 4712 struct blob_attr *cur; 4713 int ret = 0; 4714 4715 nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE); 4716 if (!nlm) 4717 return -1; 4718 4719 nlmsg_append(nlm, &ifi, sizeof(ifi), 0); 4720 nla_put_string(nlm, IFLA_IFNAME, name); 4721 4722 struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO); 4723 if (!linkinfo) { 4724 ret = -ENOMEM; 4725 goto failure; 4726 } 4727 4728 nla_put_string(nlm, IFLA_INFO_KIND, kind); 4729 struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA); 4730 if (!infodata) { 4731 ret = -ENOMEM; 4732 goto failure; 4733 } 4734 4735 if (link) 4736 nla_put_u32(nlm, IFLA_XFRM_LINK, link); 4737 4738 if ((cur = tb[TUNNEL_ATTR_DATA])) { 4739 struct blob_attr *tb_data[__XFRM_DATA_ATTR_MAX]; 4740 uint32_t if_id = 0; 4741 4742 blobmsg_parse_attr(xfrm_data_attr_list.params, __XFRM_DATA_ATTR_MAX, 4743 tb_data, cur); 4744 4745 if ((cur = tb_data[XFRM_DATA_IF_ID])) { 4746 if ((if_id = blobmsg_get_u32(cur))) 4747 nla_put_u32(nlm, IFLA_XFRM_IF_ID, if_id); 4748 } 4749 4750 } 4751 4752 nla_nest_end(nlm, infodata); 4753 nla_nest_end(nlm, linkinfo); 4754 4755 return system_rtnl_call(nlm); 4756 4757 failure: 4758 nlmsg_free(nlm); 4759 return ret; 4760 } 4761 #endif 4762 4763 #ifdef IFLA_VXLAN_MAX 4764 static void system_vxlan_map_bool_attr(struct nl_msg *msg, struct blob_attr **tb_data, int attrtype, int vxlandatatype, bool invert) { 4765 struct blob_attr *cur; 4766 if ((cur = tb_data[vxlandatatype])) { 4767 bool val = blobmsg_get_bool(cur); 4768 if (invert) 4769 val = !val; 4770 4771 if ((attrtype == IFLA_VXLAN_GBP) && val) 4772 nla_put_flag(msg, attrtype); 4773 else 4774 nla_put_u8(msg, attrtype, val); 4775 4776 } 4777 } 4778 4779 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6) 4780 { 4781 struct blob_attr *tb_data[__VXLAN_DATA_ATTR_MAX]; 4782 struct nl_msg *msg; 4783 struct nlattr *linkinfo, *data; 4784 struct ifinfomsg iim = { .ifi_family = AF_UNSPEC, }; 4785 struct blob_attr *cur; 4786 int ret = 0; 4787 4788 if ((cur = tb[TUNNEL_ATTR_DATA])) 4789 blobmsg_parse_attr(vxlan_data_attr_list.params, __VXLAN_DATA_ATTR_MAX, 4790 tb_data, cur); 4791 else 4792 return -EINVAL; 4793 4794 msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); 4795 4796 if (!msg) 4797 return -1; 4798 4799 nlmsg_append(msg, &iim, sizeof(iim), 0); 4800 4801 nla_put_string(msg, IFLA_IFNAME, name); 4802 4803 if ((cur = tb_data[VXLAN_DATA_ATTR_MACADDR])) { 4804 struct ether_addr *ea = ether_aton(blobmsg_get_string(cur)); 4805 if (!ea) { 4806 ret = -EINVAL; 4807 goto failure; 4808 } 4809 4810 nla_put(msg, IFLA_ADDRESS, ETH_ALEN, ea); 4811 } 4812 4813 if ((cur = tb[TUNNEL_ATTR_MTU])) { 4814 uint32_t mtu = blobmsg_get_u32(cur); 4815 nla_put_u32(msg, IFLA_MTU, mtu); 4816 } 4817 4818 if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO))) { 4819 ret = -ENOMEM; 4820 goto failure; 4821 } 4822 4823 nla_put_string(msg, IFLA_INFO_KIND, "vxlan"); 4824 4825 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) { 4826 ret = -ENOMEM; 4827 goto failure; 4828 } 4829 4830 if (link) 4831 nla_put_u32(msg, IFLA_VXLAN_LINK, link); 4832 4833 if ((cur = tb_data[VXLAN_DATA_ATTR_ID])) { 4834 uint32_t id = blobmsg_get_u32(cur); 4835 if (id >= (1u << 24) - 1) { 4836 ret = -EINVAL; 4837 goto failure; 4838 } 4839 4840 nla_put_u32(msg, IFLA_VXLAN_ID, id); 4841 } 4842 4843 if (v6) { 4844 struct in6_addr in6buf; 4845 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4846 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4847 ret = -EINVAL; 4848 goto failure; 4849 } 4850 nla_put(msg, IFLA_VXLAN_LOCAL6, sizeof(in6buf), &in6buf); 4851 } 4852 4853 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4854 if (inet_pton(AF_INET6, blobmsg_data(cur), &in6buf) < 1) { 4855 ret = -EINVAL; 4856 goto failure; 4857 } 4858 nla_put(msg, IFLA_VXLAN_GROUP6, sizeof(in6buf), &in6buf); 4859 } 4860 } else { 4861 struct in_addr inbuf; 4862 4863 if ((cur = tb[TUNNEL_ATTR_LOCAL])) { 4864 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4865 ret = -EINVAL; 4866 goto failure; 4867 } 4868 nla_put(msg, IFLA_VXLAN_LOCAL, sizeof(inbuf), &inbuf); 4869 } 4870 4871 if ((cur = tb[TUNNEL_ATTR_REMOTE])) { 4872 if (inet_pton(AF_INET, blobmsg_data(cur), &inbuf) < 1) { 4873 ret = -EINVAL; 4874 goto failure; 4875 } 4876 nla_put(msg, IFLA_VXLAN_GROUP, sizeof(inbuf), &inbuf); 4877 } 4878 } 4879 4880 uint32_t port = 4789; 4881 if ((cur = tb_data[VXLAN_DATA_ATTR_PORT])) { 4882 port = blobmsg_get_u32(cur); 4883 if (port < 1 || port > 65535) { 4884 ret = -EINVAL; 4885 goto failure; 4886 } 4887 } 4888 nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port)); 4889 4890 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMIN])) { 4891 struct ifla_vxlan_port_range srcports = {0,0}; 4892 4893 uint32_t low = blobmsg_get_u32(cur); 4894 if (low < 1 || low > 65535 - 1) { 4895 ret = -EINVAL; 4896 goto failure; 4897 } 4898 4899 srcports.low = htons((uint16_t) low); 4900 srcports.high = htons((uint16_t) (low+1)); 4901 4902 if ((cur = tb_data[VXLAN_DATA_ATTR_SRCPORTMAX])) { 4903 uint32_t high = blobmsg_get_u32(cur); 4904 if (high < 1 || high > 65535) { 4905 ret = -EINVAL; 4906 goto failure; 4907 } 4908 4909 if (high > low) 4910 srcports.high = htons((uint16_t) high); 4911 } 4912 4913 nla_put(msg, IFLA_VXLAN_PORT_RANGE, sizeof(srcports), &srcports); 4914 } 4915 4916 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_CSUM, VXLAN_DATA_ATTR_TXCSUM, false); 4917 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, VXLAN_DATA_ATTR_RXCSUM, true); 4918 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, VXLAN_DATA_ATTR_TXCSUM, true); 4919 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_LEARNING, VXLAN_DATA_ATTR_LEARNING, false); 4920 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_RSC , VXLAN_DATA_ATTR_RSC, false); 4921 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_PROXY , VXLAN_DATA_ATTR_PROXY, false); 4922 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L2MISS , VXLAN_DATA_ATTR_L2MISS, false); 4923 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_L3MISS , VXLAN_DATA_ATTR_L3MISS, false); 4924 system_vxlan_map_bool_attr(msg, tb_data, IFLA_VXLAN_GBP , VXLAN_DATA_ATTR_GBP, false); 4925 4926 if ((cur = tb_data[VXLAN_DATA_ATTR_AGEING])) { 4927 uint32_t ageing = blobmsg_get_u32(cur); 4928 nla_put_u32(msg, IFLA_VXLAN_AGEING, ageing); 4929 } 4930 4931 if ((cur = tb_data[VXLAN_DATA_ATTR_LIMIT])) { 4932 uint32_t maxaddress = blobmsg_get_u32(cur); 4933 nla_put_u32(msg, IFLA_VXLAN_LIMIT, maxaddress); 4934 } 4935 4936 if ((cur = tb[TUNNEL_ATTR_TOS])) { 4937 char *str = blobmsg_get_string(cur); 4938 unsigned tos = 1; 4939 4940 if (strcmp(str, "inherit")) { 4941 if (!system_tos_aton(str, &tos)) { 4942 ret = -EINVAL; 4943 goto failure; 4944 } 4945 } 4946 4947 nla_put_u8(msg, IFLA_VXLAN_TOS, tos); 4948 } 4949 4950 if ((cur = tb[TUNNEL_ATTR_TTL])) { 4951 uint32_t ttl = blobmsg_get_u32(cur); 4952 if (ttl < 1 || ttl > 255) { 4953 ret = -EINVAL; 4954 goto failure; 4955 } 4956 4957 nla_put_u8(msg, IFLA_VXLAN_TTL, ttl); 4958 } 4959 4960 nla_nest_end(msg, data); 4961 nla_nest_end(msg, linkinfo); 4962 4963 ret = system_rtnl_call(msg); 4964 if (ret) 4965 D(SYSTEM, "Error adding vxlan '%s': %d", name, ret); 4966 4967 return ret; 4968 4969 failure: 4970 nlmsg_free(msg); 4971 return ret; 4972 } 4973 #endif 4974 4975 static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb) 4976 { 4977 struct blob_attr *cur; 4978 int ret = 0; 4979 4980 if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0) 4981 return -1; 4982 4983 #ifdef SIOCADD6RD 4984 if ((cur = tb[TUNNEL_ATTR_DATA])) { 4985 struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX]; 4986 unsigned int mask; 4987 struct ip_tunnel_6rd p6; 4988 4989 blobmsg_parse_attr(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, 4990 tb_data, cur); 4991 4992 memset(&p6, 0, sizeof(p6)); 4993 4994 if ((cur = tb_data[SIXRD_DATA_PREFIX])) { 4995 if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur), 4996 &p6.prefix, &mask) || mask > 128) { 4997 ret = -EINVAL; 4998 goto failure; 4999 } 5000 5001 p6.prefixlen = mask; 5002 } 5003 5004 if ((cur = tb_data[SIXRD_DATA_RELAY_PREFIX])) { 5005 if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur), 5006 &p6.relay_prefix, &mask) || mask > 32) { 5007 ret = -EINVAL; 5008 goto failure; 5009 } 5010 5011 p6.relay_prefixlen = mask; 5012 } 5013 5014 if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) { 5015 ret = -1; 5016 goto failure; 5017 } 5018 } 5019 #endif 5020 5021 return ret; 5022 5023 failure: 5024 system_link_del(name); 5025 return ret; 5026 } 5027 5028 static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb) 5029 { 5030 struct blob_attr *cur; 5031 bool set_df = true; 5032 struct ip_tunnel_parm p = { 5033 .link = link, 5034 .iph = { 5035 .version = 4, 5036 .ihl = 5, 5037 .protocol = proto, 5038 } 5039 }; 5040 5041 if ((cur = tb[TUNNEL_ATTR_LOCAL]) && 5042 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1) 5043 return -EINVAL; 5044 5045 if ((cur = tb[TUNNEL_ATTR_REMOTE]) && 5046 inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1) 5047 return -EINVAL; 5048 5049 if ((cur = tb[TUNNEL_ATTR_DF])) 5050 set_df = blobmsg_get_bool(cur); 5051 5052 if ((cur = tb[TUNNEL_ATTR_TTL])) 5053 p.iph.ttl = blobmsg_get_u32(cur); 5054 5055 if ((cur = tb[TUNNEL_ATTR_TOS])) { 5056 char *str = blobmsg_get_string(cur); 5057 if (strcmp(str, "inherit")) { 5058 unsigned uval; 5059 5060 if (!system_tos_aton(str, &uval)) 5061 return -EINVAL; 5062 5063 p.iph.tos = uval; 5064 } else 5065 p.iph.tos = 1; 5066 } 5067 5068 p.iph.frag_off = set_df ? htons(IP_DF) : 0; 5069 /* ttl !=0 and nopmtudisc are incompatible */ 5070 if (p.iph.ttl && p.iph.frag_off == 0) 5071 return -EINVAL; 5072 5073 strncpy(p.name, name, sizeof(p.name) - 1); 5074 5075 switch (p.iph.protocol) { 5076 case IPPROTO_IPIP: 5077 return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p); 5078 case IPPROTO_IPV6: 5079 return tunnel_ioctl("sit0", SIOCADDTUNNEL, &p); 5080 default: 5081 break; 5082 } 5083 return -1; 5084 } 5085 5086 int system_del_ip_tunnel(const struct device *dev) 5087 { 5088 return system_link_del(dev->ifname); 5089 } 5090 5091 int system_update_ipv6_mtu(struct device *dev, int mtu) 5092 { 5093 int ret = -1; 5094 char buf[64]; 5095 int fd; 5096 5097 fd = open(dev_sysctl_path("ipv6/conf", dev->ifname, "mtu"), O_RDWR); 5098 if (fd < 0) 5099 return ret; 5100 5101 if (!mtu) { 5102 ssize_t len = read(fd, buf, sizeof(buf) - 1); 5103 if (len < 0) 5104 goto out; 5105 5106 buf[len] = 0; 5107 ret = atoi(buf); 5108 } else { 5109 if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0) 5110 ret = mtu; 5111 } 5112 5113 out: 5114 close(fd); 5115 return ret; 5116 } 5117 5118 int system_add_ip_tunnel(const struct device *dev, struct blob_attr *attr) 5119 { 5120 struct blob_attr *tb[__TUNNEL_ATTR_MAX]; 5121 struct blob_attr *cur; 5122 const char *str; 5123 5124 blobmsg_parse_attr(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb, attr); 5125 5126 system_link_del(dev->ifname); 5127 5128 if (!(cur = tb[TUNNEL_ATTR_TYPE])) 5129 return -EINVAL; 5130 str = blobmsg_data(cur); 5131 5132 unsigned int ttl = 0; 5133 if ((cur = tb[TUNNEL_ATTR_TTL])) { 5134 ttl = blobmsg_get_u32(cur); 5135 if (ttl > 255) 5136 return -EINVAL; 5137 } 5138 5139 unsigned int link = 0; 5140 if ((cur = tb[TUNNEL_ATTR_LINK])) { 5141 struct interface *iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node); 5142 if (!iface) 5143 return -EINVAL; 5144 5145 if (iface->l3_dev.dev) 5146 link = iface->l3_dev.dev->ifindex; 5147 } 5148 5149 if (!strcmp(str, "sit")) 5150 return system_add_sit_tunnel(dev->ifname, link, tb); 5151 #ifdef IFLA_IPTUN_MAX 5152 else if (!strcmp(str, "ipip6")) { 5153 return system_add_ip6_tunnel(dev->ifname, link, tb); 5154 } else if (!strcmp(str, "greip")) { 5155 return system_add_gre_tunnel(dev->ifname, "gre", link, tb, false); 5156 } else if (!strcmp(str, "gretapip")) { 5157 return system_add_gre_tunnel(dev->ifname, "gretap", link, tb, false); 5158 } else if (!strcmp(str, "greip6")) { 5159 return system_add_gre_tunnel(dev->ifname, "ip6gre", link, tb, true); 5160 } else if (!strcmp(str, "gretapip6")) { 5161 return system_add_gre_tunnel(dev->ifname, "ip6gretap", link, tb, true); 5162 #ifdef IFLA_VTI_MAX 5163 } else if (!strcmp(str, "vtiip")) { 5164 return system_add_vti_tunnel(dev->ifname, "vti", link, tb, false); 5165 } else if (!strcmp(str, "vtiip6")) { 5166 return system_add_vti_tunnel(dev->ifname, "vti6", link, tb, true); 5167 #endif 5168 #ifdef IFLA_XFRM_MAX 5169 } else if (!strcmp(str, "xfrm")) { 5170 return system_add_xfrm_tunnel(dev->ifname, "xfrm", link, tb); 5171 #endif 5172 #ifdef IFLA_VXLAN_MAX 5173 } else if(!strcmp(str, "vxlan")) { 5174 return system_add_vxlan(dev->ifname, link, tb, false); 5175 } else if(!strcmp(str, "vxlan6")) { 5176 return system_add_vxlan(dev->ifname, link, tb, true); 5177 #endif 5178 #endif 5179 } else if (!strcmp(str, "ipip")) { 5180 return system_add_proto_tunnel(dev->ifname, IPPROTO_IPIP, link, tb); 5181 } 5182 else 5183 return -EINVAL; 5184 5185 return 0; 5186 } 5187
This page was automatically generated by LXR 0.3.1. • OpenWrt