Deleted Added
full compact
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}