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