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