vlan_init.c (281806) | vlan_init.c (289549) |
---|---|
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" | 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#ifdef CONFIG_FULL_DYNAMIC_VLAN 13#include <net/if.h> 14#include <sys/ioctl.h> 15#include <linux/sockios.h> 16#include <linux/if_vlan.h> 17#include <linux/if_bridge.h> 18#endif /* CONFIG_FULL_DYNAMIC_VLAN */ |
|
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 | 19 20#include "utils/common.h" 21#include "hostapd.h" 22#include "ap_config.h" 23#include "ap_drv_ops.h" 24#include "vlan_init.h" 25#include "vlan_util.h" 26 27 28#ifdef CONFIG_FULL_DYNAMIC_VLAN 29 |
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 33struct full_dynamic_vlan { 34 int s; /* socket on which to listen for new/removed interfaces. */ 35}; 36 | 30#include "drivers/priv_netlink.h" 31#include "utils/eloop.h" 32 33 34struct full_dynamic_vlan { 35 int s; /* socket on which to listen for new/removed interfaces. */ 36}; 37 |
38#define DVLAN_CLEAN_BR 0x1 39#define DVLAN_CLEAN_VLAN 0x2 40#define DVLAN_CLEAN_VLAN_PORT 0x4 |
|
37 | 41 |
42struct dynamic_iface { 43 char ifname[IFNAMSIZ + 1]; 44 int usage; 45 int clean; 46 struct dynamic_iface *next; 47}; 48 49 50/* Increment ref counter for ifname and add clean flag. 51 * If not in list, add it only if some flags are given. 52 */ 53static void dyn_iface_get(struct hostapd_data *hapd, const char *ifname, 54 int clean) 55{ 56 struct dynamic_iface *next, **dynamic_ifaces; 57 struct hapd_interfaces *interfaces; 58 59 interfaces = hapd->iface->interfaces; 60 dynamic_ifaces = &interfaces->vlan_priv; 61 62 for (next = *dynamic_ifaces; next; next = next->next) { 63 if (os_strcmp(ifname, next->ifname) == 0) 64 break; 65 } 66 67 if (next) { 68 next->usage++; 69 next->clean |= clean; 70 return; 71 } 72 73 if (!clean) 74 return; 75 76 next = os_zalloc(sizeof(*next)); 77 if (!next) 78 return; 79 os_strlcpy(next->ifname, ifname, sizeof(next->ifname)); 80 next->usage = 1; 81 next->clean = clean; 82 next->next = *dynamic_ifaces; 83 *dynamic_ifaces = next; 84} 85 86 87/* Decrement reference counter for given ifname. 88 * Return clean flag iff reference counter was decreased to zero, else zero 89 */ 90static int dyn_iface_put(struct hostapd_data *hapd, const char *ifname) 91{ 92 struct dynamic_iface *next, *prev = NULL, **dynamic_ifaces; 93 struct hapd_interfaces *interfaces; 94 int clean; 95 96 interfaces = hapd->iface->interfaces; 97 dynamic_ifaces = &interfaces->vlan_priv; 98 99 for (next = *dynamic_ifaces; next; next = next->next) { 100 if (os_strcmp(ifname, next->ifname) == 0) 101 break; 102 prev = next; 103 } 104 105 if (!next) 106 return 0; 107 108 next->usage--; 109 if (next->usage) 110 return 0; 111 112 if (prev) 113 prev->next = next->next; 114 else 115 *dynamic_ifaces = next->next; 116 clean = next->clean; 117 os_free(next); 118 119 return clean; 120} 121 122 |
|
38static 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)); --- 430 unchanged lines hidden (view full) --- 476 477static 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; | 123static int ifconfig_helper(const char *if_name, int up) 124{ 125 int fd; 126 struct ifreq ifr; 127 128 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 129 wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " 130 "failed: %s", __func__, strerror(errno)); --- 430 unchanged lines hidden (view full) --- 561 562static void vlan_newlink(char *ifname, struct hostapd_data *hapd) 563{ 564 char vlan_ifname[IFNAMSIZ]; 565 char br_name[IFNAMSIZ]; 566 struct hostapd_vlan *vlan = hapd->conf->vlan; 567 char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; 568 int vlan_naming = hapd->conf->ssid.vlan_naming; |
569 int clean; |
|
484 485 wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname); 486 487 while (vlan) { | 570 571 wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname); 572 573 while (vlan) { |
488 if (os_strcmp(ifname, vlan->ifname) == 0) { | 574 if (os_strcmp(ifname, vlan->ifname) == 0 && !vlan->configured) { 575 vlan->configured = 1; |
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 | 576 577 if (hapd->conf->vlan_bridge[0]) { 578 os_snprintf(br_name, sizeof(br_name), "%s%d", 579 hapd->conf->vlan_bridge, 580 vlan->vlan_id); 581 } else if (tagged_interface) { 582 os_snprintf(br_name, sizeof(br_name), 583 "br%s.%d", tagged_interface, 584 vlan->vlan_id); 585 } else { 586 os_snprintf(br_name, sizeof(br_name), 587 "brvlan%d", vlan->vlan_id); 588 } 589 |
503 if (!br_addbr(br_name)) 504 vlan->clean |= DVLAN_CLEAN_BR; | 590 dyn_iface_get(hapd, br_name, 591 br_addbr(br_name) ? 0 : 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 | 592 593 ifconfig_up(br_name); 594 595 if (tagged_interface) { 596 if (vlan_naming == 597 DYNAMIC_VLAN_NAMING_WITH_DEVICE) 598 os_snprintf(vlan_ifname, 599 sizeof(vlan_ifname), 600 "%s.%d", tagged_interface, 601 vlan->vlan_id); 602 else 603 os_snprintf(vlan_ifname, 604 sizeof(vlan_ifname), 605 "vlan%d", vlan->vlan_id); 606 |
607 clean = 0; |
|
520 ifconfig_up(tagged_interface); 521 if (!vlan_add(tagged_interface, vlan->vlan_id, 522 vlan_ifname)) | 608 ifconfig_up(tagged_interface); 609 if (!vlan_add(tagged_interface, vlan->vlan_id, 610 vlan_ifname)) |
523 vlan->clean |= DVLAN_CLEAN_VLAN; | 611 clean |= DVLAN_CLEAN_VLAN; |
524 525 if (!br_addif(br_name, vlan_ifname)) | 612 613 if (!br_addif(br_name, vlan_ifname)) |
526 vlan->clean |= DVLAN_CLEAN_VLAN_PORT; | 614 clean |= DVLAN_CLEAN_VLAN_PORT; |
527 | 615 |
616 dyn_iface_get(hapd, vlan_ifname, clean); 617 |
|
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 --- 6 unchanged lines hidden (view full) --- 542 543static 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; | 618 ifconfig_up(vlan_ifname); 619 } 620 621 if (!br_addif(br_name, ifname)) 622 vlan->clean |= DVLAN_CLEAN_WLAN_PORT; 623 624 ifconfig_up(ifname); 625 --- 6 unchanged lines hidden (view full) --- 632 633static void vlan_dellink(char *ifname, struct hostapd_data *hapd) 634{ 635 char vlan_ifname[IFNAMSIZ]; 636 char br_name[IFNAMSIZ]; 637 struct hostapd_vlan *first, *prev, *vlan = hapd->conf->vlan; 638 char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; 639 int vlan_naming = hapd->conf->ssid.vlan_naming; |
640 int clean; |
|
550 551 wpa_printf(MSG_DEBUG, "VLAN: vlan_dellink(%s)", ifname); 552 553 first = prev = vlan; 554 555 while (vlan) { | 641 642 wpa_printf(MSG_DEBUG, "VLAN: vlan_dellink(%s)", ifname); 643 644 first = prev = vlan; 645 646 while (vlan) { |
556 if (os_strcmp(ifname, vlan->ifname) == 0) { | 647 if (os_strcmp(ifname, vlan->ifname) == 0 && 648 vlan->configured) { |
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); --- 11 unchanged lines hidden (view full) --- 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); | 649 if (hapd->conf->vlan_bridge[0]) { 650 os_snprintf(br_name, sizeof(br_name), "%s%d", 651 hapd->conf->vlan_bridge, 652 vlan->vlan_id); 653 } else if (tagged_interface) { 654 os_snprintf(br_name, sizeof(br_name), 655 "br%s.%d", tagged_interface, 656 vlan->vlan_id); --- 11 unchanged lines hidden (view full) --- 668 os_snprintf(vlan_ifname, 669 sizeof(vlan_ifname), 670 "%s.%d", tagged_interface, 671 vlan->vlan_id); 672 else 673 os_snprintf(vlan_ifname, 674 sizeof(vlan_ifname), 675 "vlan%d", vlan->vlan_id); |
584 if (vlan->clean & DVLAN_CLEAN_VLAN_PORT) | 676 677 clean = dyn_iface_put(hapd, vlan_ifname); 678 679 if (clean & DVLAN_CLEAN_VLAN_PORT) |
585 br_delif(br_name, vlan_ifname); | 680 br_delif(br_name, vlan_ifname); |
586 ifconfig_down(vlan_ifname); | |
587 | 681 |
588 if (vlan->clean & DVLAN_CLEAN_VLAN) | 682 if (clean & DVLAN_CLEAN_VLAN) { 683 ifconfig_down(vlan_ifname); |
589 vlan_rem(vlan_ifname); | 684 vlan_rem(vlan_ifname); |
685 } |
|
590 } 591 | 686 } 687 |
592 if ((vlan->clean & DVLAN_CLEAN_BR) && | 688 clean = dyn_iface_put(hapd, br_name); 689 if ((clean & DVLAN_CLEAN_BR) && |
593 br_getnumports(br_name) == 0) { 594 ifconfig_down(br_name); 595 br_delbr(br_name); 596 } | 690 br_getnumports(br_name) == 0) { 691 ifconfig_down(br_name); 692 br_delbr(br_name); 693 } |
694 } |
|
597 | 695 |
696 if (os_strcmp(ifname, vlan->ifname) == 0) { |
|
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; --- 40 unchanged lines hidden (view full) --- 646 647 } 648 649 attr = RTA_NEXT(attr, attrlen); 650 } 651 652 if (!ifname[0]) 653 return; | 697 if (vlan == first) { 698 hapd->conf->vlan = vlan->next; 699 } else { 700 prev->next = vlan->next; 701 } 702 os_free(vlan); 703 704 break; --- 40 unchanged lines hidden (view full) --- 745 746 } 747 748 attr = RTA_NEXT(attr, attrlen); 749 } 750 751 if (!ifname[0]) 752 return; |
753 if (del && if_nametoindex(ifname)) { 754 /* interface still exists, race condition -> 755 * iface has just been recreated */ 756 return; 757 } |
|
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]" : "", --- 111 unchanged lines hidden (view full) --- 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 | 758 759 wpa_printf(MSG_DEBUG, 760 "VLAN: RTM_%sLINK: ifi_index=%d ifname=%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)", 761 del ? "DEL" : "NEW", 762 ifi->ifi_index, ifname, ifi->ifi_family, ifi->ifi_flags, 763 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "", 764 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", 765 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", --- 111 unchanged lines hidden (view full) --- 877 return; 878 eloop_unregister_read_sock(priv->s); 879 close(priv->s); 880 os_free(priv); 881} 882#endif /* CONFIG_FULL_DYNAMIC_VLAN */ 883 884 |
781int vlan_setup_encryption_dyn(struct hostapd_data *hapd, 782 struct hostapd_ssid *mssid, const char *dyn_vlan) | 885int vlan_setup_encryption_dyn(struct hostapd_data *hapd, 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++) { | 886{ 887 int i; 888 889 if (dyn_vlan == NULL) 890 return 0; 891 892 /* Static WEP keys are set here; IEEE 802.1X and WPA uses their own 893 * functions for setting up dynamic broadcast keys. */ 894 for (i = 0; i < 4; i++) { |
792 if (mssid->wep.key[i] && | 895 if (hapd->conf->ssid.wep.key[i] && |
793 hostapd_drv_set_key(dyn_vlan, hapd, WPA_ALG_WEP, NULL, i, | 896 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])) | 897 i == hapd->conf->ssid.wep.idx, NULL, 0, 898 hapd->conf->ssid.wep.key[i], 899 hapd->conf->ssid.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; --- 144 unchanged lines hidden (view full) --- 948 949int 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 | 900 { 901 wpa_printf(MSG_ERROR, "VLAN: Could not set WEP " 902 "encryption for dynamic VLAN"); 903 return -1; 904 } 905 } 906 907 return 0; --- 144 unchanged lines hidden (view full) --- 1052 1053int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id) 1054{ 1055 struct hostapd_vlan *vlan; 1056 1057 if (vlan_id <= 0 || vlan_id > MAX_VLAN_ID) 1058 return 1; 1059 |
956 wpa_printf(MSG_DEBUG, "VLAN: %s(vlan_id=%d)", __func__, vlan_id); | 1060 wpa_printf(MSG_DEBUG, "VLAN: %s(ifname=%s vlan_id=%d)", 1061 __func__, hapd->conf->iface, 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 | 1062 1063 vlan = hapd->conf->vlan; 1064 while (vlan) { 1065 if (vlan->vlan_id == vlan_id && vlan->dynamic_vlan > 0) { 1066 vlan->dynamic_vlan--; 1067 break; 1068 } 1069 vlan = vlan->next; 1070 } 1071 1072 if (vlan == NULL) 1073 return 1; 1074 |
970 if (vlan->dynamic_vlan == 0) | 1075 if (vlan->dynamic_vlan == 0) { |
971 hostapd_vlan_if_remove(hapd, vlan->ifname); | 1076 hostapd_vlan_if_remove(hapd, vlan->ifname); |
1077#ifdef CONFIG_FULL_DYNAMIC_VLAN 1078 vlan_dellink(vlan->ifname, hapd); 1079#endif /* CONFIG_FULL_DYNAMIC_VLAN */ 1080 } |
|
972 973 return 0; 974} | 1081 1082 return 0; 1083} |