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