1 /* 2 * hostapd / VLAN initialization 3 * Copyright 2003, Instant802 Networks, Inc. 4 * Copyright 2005-2006, Devicescape Software, Inc. 5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 6 * 7 * This software may be distributed under the terms of the BSD license. 8 * See README for more details. 9 */ 10 11 #include "utils/includes.h" 12 13 #include "utils/common.h" 14 #include "hostapd.h" 15 #include "ap_config.h" 16 #include "ap_drv_ops.h" 17 #include "vlan_init.h" 18 #include "vlan_util.h" 19 20 21 #ifdef CONFIG_FULL_DYNAMIC_VLAN 22 23 #include <net/if.h> 24 #include <sys/ioctl.h> 25 #include <linux/sockios.h> 26 #include <linux/if_vlan.h> 27 #include <linux/if_bridge.h> 28 29 #include "drivers/priv_netlink.h" 30 #include "utils/eloop.h" 31 32 33 struct full_dynamic_vlan { 34 int s; /* socket on which to listen for new/removed interfaces. */ 35 }; 36 37 38 static int ifconfig_helper(const char *if_name, int up) 39 { 40 int fd; 41 struct ifreq ifr; 42 43 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 44 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 45 "failed: %s", __func__, strerror(errno)); 46 return -1; 47 } 48 49 os_memset(&ifr, 0, sizeof(ifr)); 50 os_strlcpy(ifr.ifr_name, if_name, IFNAMSIZ); 51 52 if (ioctl(fd, SIOCGIFFLAGS, &ifr) != 0) { 53 wpa_printf(MSG_ERROR, "VLAN: %s: ioctl(SIOCGIFFLAGS) failed " 54 "for interface %s: %s", 55 __func__, if_name, strerror(errno)); 56 close(fd); 57 return -1; 58 } 59 60 if (up) 61 ifr.ifr_flags |= IFF_UP; 62 else 63 ifr.ifr_flags &= ~IFF_UP; 64 65 if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) { 66 wpa_printf(MSG_ERROR, "VLAN: %s: ioctl(SIOCSIFFLAGS) failed " 67 "for interface %s (up=%d): %s", 68 __func__, if_name, up, strerror(errno)); 69 close(fd); 70 return -1; 71 } 72 73 close(fd); 74 return 0; 75 } 76 77 78 static int ifconfig_up(const char *if_name) 79 { 80 wpa_printf(MSG_DEBUG, "VLAN: Set interface %s up", if_name); 81 return ifconfig_helper(if_name, 1); 82 } 83 84 85 static int ifconfig_down(const char *if_name) 86 { 87 wpa_printf(MSG_DEBUG, "VLAN: Set interface %s down", if_name); 88 return ifconfig_helper(if_name, 0); 89 } 90 91 92 /* 93 * These are only available in recent linux headers (without the leading 94 * underscore). 95 */ 96 #define _GET_VLAN_REALDEV_NAME_CMD 8 97 #define _GET_VLAN_VID_CMD 9 98 99 /* This value should be 256 ONLY. If it is something else, then hostapd 100 * might crash!, as this value has been hard-coded in 2.4.x kernel 101 * bridging code. 102 */ 103 #define MAX_BR_PORTS 256 104 105 static int br_delif(const char *br_name, const char *if_name) 106 { 107 int fd; 108 struct ifreq ifr; 109 unsigned long args[2]; 110 int if_index; 111 112 wpa_printf(MSG_DEBUG, "VLAN: br_delif(%s, %s)", br_name, if_name); 113 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 114 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 115 "failed: %s", __func__, strerror(errno)); 116 return -1; 117 } 118 119 if_index = if_nametoindex(if_name); 120 121 if (if_index == 0) { 122 wpa_printf(MSG_ERROR, "VLAN: %s: Failure determining " 123 "interface index for '%s'", 124 __func__, if_name); 125 close(fd); 126 return -1; 127 } 128 129 args[0] = BRCTL_DEL_IF; 130 args[1] = if_index; 131 132 os_strlcpy(ifr.ifr_name, br_name, sizeof(ifr.ifr_name)); 133 ifr.ifr_data = (__caddr_t) args; 134 135 if (ioctl(fd, SIOCDEVPRIVATE, &ifr) < 0 && errno != EINVAL) { 136 /* No error if interface already removed. */ 137 wpa_printf(MSG_ERROR, "VLAN: %s: ioctl[SIOCDEVPRIVATE," 138 "BRCTL_DEL_IF] failed for br_name=%s if_name=%s: " 139 "%s", __func__, br_name, if_name, strerror(errno)); 140 close(fd); 141 return -1; 142 } 143 144 close(fd); 145 return 0; 146 } 147 148 149 /* 150 Add interface 'if_name' to the bridge 'br_name' 151 152 returns -1 on error 153 returns 1 if the interface is already part of the bridge 154 returns 0 otherwise 155 */ 156 static int br_addif(const char *br_name, const char *if_name) 157 { 158 int fd; 159 struct ifreq ifr; 160 unsigned long args[2]; 161 int if_index; 162 163 wpa_printf(MSG_DEBUG, "VLAN: br_addif(%s, %s)", br_name, if_name); 164 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 165 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 166 "failed: %s", __func__, strerror(errno)); 167 return -1; 168 } 169 170 if_index = if_nametoindex(if_name); 171 172 if (if_index == 0) { 173 wpa_printf(MSG_ERROR, "VLAN: %s: Failure determining " 174 "interface index for '%s'", 175 __func__, if_name); 176 close(fd); 177 return -1; 178 } 179 180 args[0] = BRCTL_ADD_IF; 181 args[1] = if_index; 182 183 os_strlcpy(ifr.ifr_name, br_name, sizeof(ifr.ifr_name)); 184 ifr.ifr_data = (__caddr_t) args; 185 186 if (ioctl(fd, SIOCDEVPRIVATE, &ifr) < 0) { 187 if (errno == EBUSY) { 188 /* The interface is already added. */ 189 close(fd); 190 return 1; 191 } 192 193 wpa_printf(MSG_ERROR, "VLAN: %s: ioctl[SIOCDEVPRIVATE," 194 "BRCTL_ADD_IF] failed for br_name=%s if_name=%s: " 195 "%s", __func__, br_name, if_name, strerror(errno)); 196 close(fd); 197 return -1; 198 } 199 200 close(fd); 201 return 0; 202 } 203 204 205 static int br_delbr(const char *br_name) 206 { 207 int fd; 208 unsigned long arg[2]; 209 210 wpa_printf(MSG_DEBUG, "VLAN: br_delbr(%s)", br_name); 211 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 212 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 213 "failed: %s", __func__, strerror(errno)); 214 return -1; 215 } 216 217 arg[0] = BRCTL_DEL_BRIDGE; 218 arg[1] = (unsigned long) br_name; 219 220 if (ioctl(fd, SIOCGIFBR, arg) < 0 && errno != ENXIO) { 221 /* No error if bridge already removed. */ 222 wpa_printf(MSG_ERROR, "VLAN: %s: BRCTL_DEL_BRIDGE failed for " 223 "%s: %s", __func__, br_name, strerror(errno)); 224 close(fd); 225 return -1; 226 } 227 228 close(fd); 229 return 0; 230 } 231 232 233 /* 234 Add a bridge with the name 'br_name'. 235 236 returns -1 on error 237 returns 1 if the bridge already exists 238 returns 0 otherwise 239 */ 240 static int br_addbr(const char *br_name) 241 { 242 int fd; 243 unsigned long arg[4]; 244 struct ifreq ifr; 245 246 wpa_printf(MSG_DEBUG, "VLAN: br_addbr(%s)", br_name); 247 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 248 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 249 "failed: %s", __func__, strerror(errno)); 250 return -1; 251 } 252 253 arg[0] = BRCTL_ADD_BRIDGE; 254 arg[1] = (unsigned long) br_name; 255 256 if (ioctl(fd, SIOCGIFBR, arg) < 0) { 257 if (errno == EEXIST) { 258 /* The bridge is already added. */ 259 close(fd); 260 return 1; 261 } else { 262 wpa_printf(MSG_ERROR, "VLAN: %s: BRCTL_ADD_BRIDGE " 263 "failed for %s: %s", 264 __func__, br_name, strerror(errno)); 265 close(fd); 266 return -1; 267 } 268 } 269 270 /* Decrease forwarding delay to avoid EAPOL timeouts. */ 271 os_memset(&ifr, 0, sizeof(ifr)); 272 os_strlcpy(ifr.ifr_name, br_name, IFNAMSIZ); 273 arg[0] = BRCTL_SET_BRIDGE_FORWARD_DELAY; 274 arg[1] = 1; 275 arg[2] = 0; 276 arg[3] = 0; 277 ifr.ifr_data = (char *) &arg; 278 if (ioctl(fd, SIOCDEVPRIVATE, &ifr) < 0) { 279 wpa_printf(MSG_ERROR, "VLAN: %s: " 280 "BRCTL_SET_BRIDGE_FORWARD_DELAY (1 sec) failed for " 281 "%s: %s", __func__, br_name, strerror(errno)); 282 /* Continue anyway */ 283 } 284 285 close(fd); 286 return 0; 287 } 288 289 290 static int br_getnumports(const char *br_name) 291 { 292 int fd; 293 int i; 294 int port_cnt = 0; 295 unsigned long arg[4]; 296 int ifindices[MAX_BR_PORTS]; 297 struct ifreq ifr; 298 299 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 300 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 301 "failed: %s", __func__, strerror(errno)); 302 return -1; 303 } 304 305 arg[0] = BRCTL_GET_PORT_LIST; 306 arg[1] = (unsigned long) ifindices; 307 arg[2] = MAX_BR_PORTS; 308 arg[3] = 0; 309 310 os_memset(ifindices, 0, sizeof(ifindices)); 311 os_strlcpy(ifr.ifr_name, br_name, sizeof(ifr.ifr_name)); 312 ifr.ifr_data = (__caddr_t) arg; 313 314 if (ioctl(fd, SIOCDEVPRIVATE, &ifr) < 0) { 315 wpa_printf(MSG_ERROR, "VLAN: %s: BRCTL_GET_PORT_LIST " 316 "failed for %s: %s", 317 __func__, br_name, strerror(errno)); 318 close(fd); 319 return -1; 320 } 321 322 for (i = 1; i < MAX_BR_PORTS; i++) { 323 if (ifindices[i] > 0) { 324 port_cnt++; 325 } 326 } 327 328 close(fd); 329 return port_cnt; 330 } 331 332 333 #ifndef CONFIG_VLAN_NETLINK 334 335 int vlan_rem(const char *if_name) 336 { 337 int fd; 338 struct vlan_ioctl_args if_request; 339 340 wpa_printf(MSG_DEBUG, "VLAN: vlan_rem(%s)", if_name); 341 if ((os_strlen(if_name) + 1) > sizeof(if_request.device1)) { 342 wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'", 343 if_name); 344 return -1; 345 } 346 347 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 348 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 349 "failed: %s", __func__, strerror(errno)); 350 return -1; 351 } 352 353 os_memset(&if_request, 0, sizeof(if_request)); 354 355 os_strlcpy(if_request.device1, if_name, sizeof(if_request.device1)); 356 if_request.cmd = DEL_VLAN_CMD; 357 358 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { 359 wpa_printf(MSG_ERROR, "VLAN: %s: DEL_VLAN_CMD failed for %s: " 360 "%s", __func__, if_name, strerror(errno)); 361 close(fd); 362 return -1; 363 } 364 365 close(fd); 366 return 0; 367 } 368 369 370 /* 371 Add a vlan interface with VLAN ID 'vid' and tagged interface 372 'if_name'. 373 374 returns -1 on error 375 returns 1 if the interface already exists 376 returns 0 otherwise 377 */ 378 int vlan_add(const char *if_name, int vid, const char *vlan_if_name) 379 { 380 int fd; 381 struct vlan_ioctl_args if_request; 382 383 wpa_printf(MSG_DEBUG, "VLAN: vlan_add(if_name=%s, vid=%d)", 384 if_name, vid); 385 ifconfig_up(if_name); 386 387 if ((os_strlen(if_name) + 1) > sizeof(if_request.device1)) { 388 wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'", 389 if_name); 390 return -1; 391 } 392 393 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 394 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 395 "failed: %s", __func__, strerror(errno)); 396 return -1; 397 } 398 399 os_memset(&if_request, 0, sizeof(if_request)); 400 401 /* Determine if a suitable vlan device already exists. */ 402 403 os_snprintf(if_request.device1, sizeof(if_request.device1), "vlan%d", 404 vid); 405 406 if_request.cmd = _GET_VLAN_VID_CMD; 407 408 if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0) { 409 410 if (if_request.u.VID == vid) { 411 if_request.cmd = _GET_VLAN_REALDEV_NAME_CMD; 412 413 if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0 && 414 os_strncmp(if_request.u.device2, if_name, 415 sizeof(if_request.u.device2)) == 0) { 416 close(fd); 417 wpa_printf(MSG_DEBUG, "VLAN: vlan_add: " 418 "if_name %s exists already", 419 if_request.device1); 420 return 1; 421 } 422 } 423 } 424 425 /* A suitable vlan device does not already exist, add one. */ 426 427 os_memset(&if_request, 0, sizeof(if_request)); 428 os_strlcpy(if_request.device1, if_name, sizeof(if_request.device1)); 429 if_request.u.VID = vid; 430 if_request.cmd = ADD_VLAN_CMD; 431 432 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { 433 wpa_printf(MSG_ERROR, "VLAN: %s: ADD_VLAN_CMD failed for %s: " 434 "%s", 435 __func__, if_request.device1, strerror(errno)); 436 close(fd); 437 return -1; 438 } 439 440 close(fd); 441 return 0; 442 } 443 444 445 static int vlan_set_name_type(unsigned int name_type) 446 { 447 int fd; 448 struct vlan_ioctl_args if_request; 449 450 wpa_printf(MSG_DEBUG, "VLAN: vlan_set_name_type(name_type=%u)", 451 name_type); 452 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 453 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 454 "failed: %s", __func__, strerror(errno)); 455 return -1; 456 } 457 458 os_memset(&if_request, 0, sizeof(if_request)); 459 460 if_request.u.name_type = name_type; 461 if_request.cmd = SET_VLAN_NAME_TYPE_CMD; 462 if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { 463 wpa_printf(MSG_ERROR, "VLAN: %s: SET_VLAN_NAME_TYPE_CMD " 464 "name_type=%u failed: %s", 465 __func__, name_type, strerror(errno)); 466 close(fd); 467 return -1; 468 } 469 470 close(fd); 471 return 0; 472 } 473 474 #endif /* CONFIG_VLAN_NETLINK */ 475 476 477 static void vlan_newlink(char *ifname, struct hostapd_data *hapd) 478 { 479 char vlan_ifname[IFNAMSIZ]; 480 char br_name[IFNAMSIZ]; 481 struct hostapd_vlan *vlan = hapd->conf->vlan; 482 char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; 483 int vlan_naming = hapd->conf->ssid.vlan_naming; 484 485 wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname); 486 487 while (vlan) { 488 if (os_strcmp(ifname, vlan->ifname) == 0) { 489 490 if (hapd->conf->vlan_bridge[0]) { 491 os_snprintf(br_name, sizeof(br_name), "%s%d", 492 hapd->conf->vlan_bridge, 493 vlan->vlan_id); 494 } else if (tagged_interface) { 495 os_snprintf(br_name, sizeof(br_name), 496 "br%s.%d", tagged_interface, 497 vlan->vlan_id); 498 } else { 499 os_snprintf(br_name, sizeof(br_name), 500 "brvlan%d", vlan->vlan_id); 501 } 502 503 if (!br_addbr(br_name)) 504 vlan->clean |= DVLAN_CLEAN_BR; 505 506 ifconfig_up(br_name); 507 508 if (tagged_interface) { 509 if (vlan_naming == 510 DYNAMIC_VLAN_NAMING_WITH_DEVICE) 511 os_snprintf(vlan_ifname, 512 sizeof(vlan_ifname), 513 "%s.%d", tagged_interface, 514 vlan->vlan_id); 515 else 516 os_snprintf(vlan_ifname, 517 sizeof(vlan_ifname), 518 "vlan%d", vlan->vlan_id); 519 520 ifconfig_up(tagged_interface); 521 if (!vlan_add(tagged_interface, vlan->vlan_id, 522 vlan_ifname)) 523 vlan->clean |= DVLAN_CLEAN_VLAN; 524 525 if (!br_addif(br_name, vlan_ifname)) 526 vlan->clean |= DVLAN_CLEAN_VLAN_PORT; 527 528 ifconfig_up(vlan_ifname); 529 } 530 531 if (!br_addif(br_name, ifname)) 532 vlan->clean |= DVLAN_CLEAN_WLAN_PORT; 533 534 ifconfig_up(ifname); 535 536 break; 537 } 538 vlan = vlan->next; 539 } 540 } 541 542 543 static void vlan_dellink(char *ifname, struct hostapd_data *hapd) 544 { 545 char vlan_ifname[IFNAMSIZ]; 546 char br_name[IFNAMSIZ]; 547 struct hostapd_vlan *first, *prev, *vlan = hapd->conf->vlan; 548 char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; 549 int vlan_naming = hapd->conf->ssid.vlan_naming; 550 551 wpa_printf(MSG_DEBUG, "VLAN: vlan_dellink(%s)", ifname); 552 553 first = prev = vlan; 554 555 while (vlan) { 556 if (os_strcmp(ifname, vlan->ifname) == 0) { 557 if (hapd->conf->vlan_bridge[0]) { 558 os_snprintf(br_name, sizeof(br_name), "%s%d", 559 hapd->conf->vlan_bridge, 560 vlan->vlan_id); 561 } else if (tagged_interface) { 562 os_snprintf(br_name, sizeof(br_name), 563 "br%s.%d", tagged_interface, 564 vlan->vlan_id); 565 } else { 566 os_snprintf(br_name, sizeof(br_name), 567 "brvlan%d", vlan->vlan_id); 568 } 569 570 if (vlan->clean & DVLAN_CLEAN_WLAN_PORT) 571 br_delif(br_name, vlan->ifname); 572 573 if (tagged_interface) { 574 if (vlan_naming == 575 DYNAMIC_VLAN_NAMING_WITH_DEVICE) 576 os_snprintf(vlan_ifname, 577 sizeof(vlan_ifname), 578 "%s.%d", tagged_interface, 579 vlan->vlan_id); 580 else 581 os_snprintf(vlan_ifname, 582 sizeof(vlan_ifname), 583 "vlan%d", vlan->vlan_id); 584 if (vlan->clean & DVLAN_CLEAN_VLAN_PORT) 585 br_delif(br_name, vlan_ifname); 586 ifconfig_down(vlan_ifname); 587 588 if (vlan->clean & DVLAN_CLEAN_VLAN) 589 vlan_rem(vlan_ifname); 590 } 591 592 if ((vlan->clean & DVLAN_CLEAN_BR) && 593 br_getnumports(br_name) == 0) { 594 ifconfig_down(br_name); 595 br_delbr(br_name); 596 } 597 598 if (vlan == first) { 599 hapd->conf->vlan = vlan->next; 600 } else { 601 prev->next = vlan->next; 602 } 603 os_free(vlan); 604 605 break; 606 } 607 prev = vlan; 608 vlan = vlan->next; 609 } 610 } 611 612 613 static void 614 vlan_read_ifnames(struct nlmsghdr *h, size_t len, int del, 615 struct hostapd_data *hapd) 616 { 617 struct ifinfomsg *ifi; 618 int attrlen, nlmsg_len, rta_len; 619 struct rtattr *attr; 620 char ifname[IFNAMSIZ + 1]; 621 622 if (len < sizeof(*ifi)) 623 return; 624 625 ifi = NLMSG_DATA(h); 626 627 nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); 628 629 attrlen = h->nlmsg_len - nlmsg_len; 630 if (attrlen < 0) 631 return; 632 633 attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); 634 635 os_memset(ifname, 0, sizeof(ifname)); 636 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 637 while (RTA_OK(attr, attrlen)) { 638 if (attr->rta_type == IFLA_IFNAME) { 639 int n = attr->rta_len - rta_len; 640 if (n < 0) 641 break; 642 643 if ((size_t) n >= sizeof(ifname)) 644 n = sizeof(ifname) - 1; 645 os_memcpy(ifname, ((char *) attr) + rta_len, n); 646 647 } 648 649 attr = RTA_NEXT(attr, attrlen); 650 } 651 652 if (!ifname[0]) 653 return; 654 655 wpa_printf(MSG_DEBUG, 656 "VLAN: RTM_%sLINK: ifi_index=%d ifname=%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)", 657 del ? "DEL" : "NEW", 658 ifi->ifi_index, ifname, ifi->ifi_family, ifi->ifi_flags, 659 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "", 660 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", 661 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", 662 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); 663 664 if (del) 665 vlan_dellink(ifname, hapd); 666 else 667 vlan_newlink(ifname, hapd); 668 } 669 670 671 static void vlan_event_receive(int sock, void *eloop_ctx, void *sock_ctx) 672 { 673 char buf[8192]; 674 int left; 675 struct sockaddr_nl from; 676 socklen_t fromlen; 677 struct nlmsghdr *h; 678 struct hostapd_data *hapd = eloop_ctx; 679 680 fromlen = sizeof(from); 681 left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, 682 (struct sockaddr *) &from, &fromlen); 683 if (left < 0) { 684 if (errno != EINTR && errno != EAGAIN) 685 wpa_printf(MSG_ERROR, "VLAN: %s: recvfrom failed: %s", 686 __func__, strerror(errno)); 687 return; 688 } 689 690 h = (struct nlmsghdr *) buf; 691 while (NLMSG_OK(h, left)) { 692 int len, plen; 693 694 len = h->nlmsg_len; 695 plen = len - sizeof(*h); 696 if (len > left || plen < 0) { 697 wpa_printf(MSG_DEBUG, "VLAN: Malformed netlink " 698 "message: len=%d left=%d plen=%d", 699 len, left, plen); 700 break; 701 } 702 703 switch (h->nlmsg_type) { 704 case RTM_NEWLINK: 705 vlan_read_ifnames(h, plen, 0, hapd); 706 break; 707 case RTM_DELLINK: 708 vlan_read_ifnames(h, plen, 1, hapd); 709 break; 710 } 711 712 h = NLMSG_NEXT(h, left); 713 } 714 715 if (left > 0) { 716 wpa_printf(MSG_DEBUG, "VLAN: %s: %d extra bytes in the end of " 717 "netlink message", __func__, left); 718 } 719 } 720 721 722 static struct full_dynamic_vlan * 723 full_dynamic_vlan_init(struct hostapd_data *hapd) 724 { 725 struct sockaddr_nl local; 726 struct full_dynamic_vlan *priv; 727 728 priv = os_zalloc(sizeof(*priv)); 729 if (priv == NULL) 730 return NULL; 731 732 #ifndef CONFIG_VLAN_NETLINK 733 vlan_set_name_type(hapd->conf->ssid.vlan_naming == 734 DYNAMIC_VLAN_NAMING_WITH_DEVICE ? 735 VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD : 736 VLAN_NAME_TYPE_PLUS_VID_NO_PAD); 737 #endif /* CONFIG_VLAN_NETLINK */ 738 739 priv->s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 740 if (priv->s < 0) { 741 wpa_printf(MSG_ERROR, "VLAN: %s: socket(PF_NETLINK,SOCK_RAW," 742 "NETLINK_ROUTE) failed: %s", 743 __func__, strerror(errno)); 744 os_free(priv); 745 return NULL; 746 } 747 748 os_memset(&local, 0, sizeof(local)); 749 local.nl_family = AF_NETLINK; 750 local.nl_groups = RTMGRP_LINK; 751 if (bind(priv->s, (struct sockaddr *) &local, sizeof(local)) < 0) { 752 wpa_printf(MSG_ERROR, "VLAN: %s: bind(netlink) failed: %s", 753 __func__, strerror(errno)); 754 close(priv->s); 755 os_free(priv); 756 return NULL; 757 } 758 759 if (eloop_register_read_sock(priv->s, vlan_event_receive, hapd, NULL)) 760 { 761 close(priv->s); 762 os_free(priv); 763 return NULL; 764 } 765 766 return priv; 767 } 768 769 770 static void full_dynamic_vlan_deinit(struct full_dynamic_vlan *priv) 771 { 772 if (priv == NULL) 773 return; 774 eloop_unregister_read_sock(priv->s); 775 close(priv->s); 776 os_free(priv); 777 } 778 #endif /* CONFIG_FULL_DYNAMIC_VLAN */ 779 780 781 int vlan_setup_encryption_dyn(struct hostapd_data *hapd, 782 struct hostapd_ssid *mssid, const char *dyn_vlan) 783 { 784 int i; 785 786 if (dyn_vlan == NULL) 787 return 0; 788 789 /* Static WEP keys are set here; IEEE 802.1X and WPA uses their own 790 * functions for setting up dynamic broadcast keys. */ 791 for (i = 0; i < 4; i++) { 792 if (mssid->wep.key[i] && 793 hostapd_drv_set_key(dyn_vlan, hapd, WPA_ALG_WEP, NULL, i, 794 i == mssid->wep.idx, NULL, 0, 795 mssid->wep.key[i], mssid->wep.len[i])) 796 { 797 wpa_printf(MSG_ERROR, "VLAN: Could not set WEP " 798 "encryption for dynamic VLAN"); 799 return -1; 800 } 801 } 802 803 return 0; 804 } 805 806 807 static int vlan_dynamic_add(struct hostapd_data *hapd, 808 struct hostapd_vlan *vlan) 809 { 810 while (vlan) { 811 if (vlan->vlan_id != VLAN_ID_WILDCARD) { 812 if (hostapd_vlan_if_add(hapd, vlan->ifname)) { 813 if (errno != EEXIST) { 814 wpa_printf(MSG_ERROR, "VLAN: Could " 815 "not add VLAN %s: %s", 816 vlan->ifname, 817 strerror(errno)); 818 return -1; 819 } 820 } 821 #ifdef CONFIG_FULL_DYNAMIC_VLAN 822 ifconfig_up(vlan->ifname); 823 #endif /* CONFIG_FULL_DYNAMIC_VLAN */ 824 } 825 826 vlan = vlan->next; 827 } 828 829 return 0; 830 } 831 832 833 static void vlan_dynamic_remove(struct hostapd_data *hapd, 834 struct hostapd_vlan *vlan) 835 { 836 struct hostapd_vlan *next; 837 838 while (vlan) { 839 next = vlan->next; 840 841 if (vlan->vlan_id != VLAN_ID_WILDCARD && 842 hostapd_vlan_if_remove(hapd, vlan->ifname)) { 843 wpa_printf(MSG_ERROR, "VLAN: Could not remove VLAN " 844 "iface: %s: %s", 845 vlan->ifname, strerror(errno)); 846 } 847 #ifdef CONFIG_FULL_DYNAMIC_VLAN 848 if (vlan->clean) 849 vlan_dellink(vlan->ifname, hapd); 850 #endif /* CONFIG_FULL_DYNAMIC_VLAN */ 851 852 vlan = next; 853 } 854 } 855 856 857 int vlan_init(struct hostapd_data *hapd) 858 { 859 #ifdef CONFIG_FULL_DYNAMIC_VLAN 860 hapd->full_dynamic_vlan = full_dynamic_vlan_init(hapd); 861 #endif /* CONFIG_FULL_DYNAMIC_VLAN */ 862 863 if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED && 864 !hapd->conf->vlan) { 865 /* dynamic vlans enabled but no (or empty) vlan_file given */ 866 struct hostapd_vlan *vlan; 867 vlan = os_zalloc(sizeof(*vlan)); 868 if (vlan == NULL) { 869 wpa_printf(MSG_ERROR, "Out of memory while assigning " 870 "VLAN interfaces"); 871 return -1; 872 } 873 874 vlan->vlan_id = VLAN_ID_WILDCARD; 875 os_snprintf(vlan->ifname, sizeof(vlan->ifname), "%s.#", 876 hapd->conf->iface); 877 vlan->next = hapd->conf->vlan; 878 hapd->conf->vlan = vlan; 879 } 880 881 if (vlan_dynamic_add(hapd, hapd->conf->vlan)) 882 return -1; 883 884 return 0; 885 } 886 887 888 void vlan_deinit(struct hostapd_data *hapd) 889 { 890 vlan_dynamic_remove(hapd, hapd->conf->vlan); 891 892 #ifdef CONFIG_FULL_DYNAMIC_VLAN 893 full_dynamic_vlan_deinit(hapd->full_dynamic_vlan); 894 hapd->full_dynamic_vlan = NULL; 895 #endif /* CONFIG_FULL_DYNAMIC_VLAN */ 896 } 897 898 899 struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd, 900 struct hostapd_vlan *vlan, 901 int vlan_id) 902 { 903 struct hostapd_vlan *n = NULL; 904 char *ifname, *pos; 905 906 if (vlan == NULL || vlan_id <= 0 || vlan_id > MAX_VLAN_ID || 907 vlan->vlan_id != VLAN_ID_WILDCARD) 908 return NULL; 909 910 wpa_printf(MSG_DEBUG, "VLAN: %s(vlan_id=%d ifname=%s)", 911 __func__, vlan_id, vlan->ifname); 912 ifname = os_strdup(vlan->ifname); 913 if (ifname == NULL) 914 return NULL; 915 pos = os_strchr(ifname, '#'); 916 if (pos == NULL) 917 goto free_ifname; 918 *pos++ = '\0'; 919 920 n = os_zalloc(sizeof(*n)); 921 if (n == NULL) 922 goto free_ifname; 923 924 n->vlan_id = vlan_id; 925 n->dynamic_vlan = 1; 926 927 os_snprintf(n->ifname, sizeof(n->ifname), "%s%d%s", ifname, vlan_id, 928 pos); 929 930 if (hostapd_vlan_if_add(hapd, n->ifname)) { 931 os_free(n); 932 n = NULL; 933 goto free_ifname; 934 } 935 936 n->next = hapd->conf->vlan; 937 hapd->conf->vlan = n; 938 939 #ifdef CONFIG_FULL_DYNAMIC_VLAN 940 ifconfig_up(n->ifname); 941 #endif /* CONFIG_FULL_DYNAMIC_VLAN */ 942 943 free_ifname: 944 os_free(ifname); 945 return n; 946 } 947 948 949 int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id) 950 { 951 struct hostapd_vlan *vlan; 952 953 if (vlan_id <= 0 || vlan_id > MAX_VLAN_ID) 954 return 1; 955 956 wpa_printf(MSG_DEBUG, "VLAN: %s(vlan_id=%d)", __func__, vlan_id); 957 958 vlan = hapd->conf->vlan; 959 while (vlan) { 960 if (vlan->vlan_id == vlan_id && vlan->dynamic_vlan > 0) { 961 vlan->dynamic_vlan--; 962 break; 963 } 964 vlan = vlan->next; 965 } 966 967 if (vlan == NULL) 968 return 1; 969 970 if (vlan->dynamic_vlan == 0) 971 hostapd_vlan_if_remove(hapd, vlan->ifname); 972 973 return 0; 974 } 975