/* Add a vlan interface with VLAN ID 'vid' and tagged interface 'if_name'. returns -1 on error returns 1 if the interface already exists returns 0 otherwise */ static int vlan_add(const char *if_name, int vid) { int fd; struct vlan_ioctl_args if_request; ifconfig_up(if_name); if ((strlen(if_name) + 1) > sizeof(if_request.device1)) { fprintf(stderr, "Interface name to long.\n"); return -1; } if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket[AF_INET,SOCK_STREAM]"); return -1; } memset(&if_request, 0, sizeof(if_request)); /* Determine if a suitable vlan device already exists. */ snprintf(if_request.device1, sizeof(if_request.device1), "vlan%d", vid); if_request.cmd = _GET_VLAN_VID_CMD; if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0) { if (if_request.u.VID == vid) { if_request.cmd = _GET_VLAN_REALDEV_NAME_CMD; if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0 && strncmp(if_request.u.device2, if_name, sizeof(if_request.u.device2)) == 0) { close(fd); return 1; } } } /* A suitable vlan device does not already exist, add one. */ memset(&if_request, 0, sizeof(if_request)); strcpy(if_request.device1, if_name); if_request.u.VID = vid; if_request.cmd = ADD_VLAN_CMD; if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { perror("ioctl[SIOCSIFVLAN,ADD_VLAN_CMD]"); close(fd); return -1; } close(fd); return 0; }
static void vlan_newlink(char *ifname, struct hostapd_data *hapd) { char vlan_ifname[IFNAMSIZ]; char br_name[IFNAMSIZ]; struct hostapd_vlan *vlan = hapd->conf->vlan; char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; while (vlan) { if (strcmp(ifname, vlan->ifname) == 0) { snprintf(br_name, sizeof(br_name), "brvlan%d", vlan->vlan_id); if (!br_addbr(br_name)) vlan->clean |= DVLAN_CLEAN_BR; ifconfig_up(br_name); if (tagged_interface) { if (!vlan_add(tagged_interface, vlan->vlan_id)) vlan->clean |= DVLAN_CLEAN_VLAN; snprintf(vlan_ifname, sizeof(vlan_ifname), "vlan%d", vlan->vlan_id); if (!br_addif(br_name, vlan_ifname)) vlan->clean |= DVLAN_CLEAN_VLAN_PORT; ifconfig_up(vlan_ifname); } if (!br_addif(br_name, ifname)) vlan->clean |= DVLAN_CLEAN_WLAN_PORT; ifconfig_up(ifname); break; } vlan = vlan->next; } }
struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd, struct hostapd_vlan *vlan, int vlan_id) { struct hostapd_vlan *n; char *ifname, *pos; if (vlan == NULL || vlan_id <= 0 || vlan_id > MAX_VLAN_ID || vlan->vlan_id != VLAN_ID_WILDCARD) return NULL; wpa_printf(MSG_DEBUG, "VLAN: %s(vlan_id=%d ifname=%s)", __func__, vlan_id, vlan->ifname); ifname = os_strdup(vlan->ifname); if (ifname == NULL) return NULL; pos = os_strchr(ifname, '#'); if (pos == NULL) { os_free(ifname); return NULL; } *pos++ = '\0'; n = os_zalloc(sizeof(*n)); if (n == NULL) { os_free(ifname); return NULL; } n->vlan_id = vlan_id; n->dynamic_vlan = 1; os_snprintf(n->ifname, sizeof(n->ifname), "%s%d%s", ifname, vlan_id, pos); os_free(ifname); if (hostapd_vlan_if_add(hapd, n->ifname)) { os_free(n); return NULL; } n->next = hapd->conf->vlan; hapd->conf->vlan = n; #ifdef CONFIG_FULL_DYNAMIC_VLAN ifconfig_up(n->ifname); #endif /* CONFIG_FULL_DYNAMIC_VLAN */ return n; }
static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, int existsok) { int ret, i; for (i = 0; i < NUM_WEP_KEYS; i++) { if (!hapd->conf->ssid.wep.key[i]) continue; wpa_printf(MSG_ERROR, "VLAN: Refusing to set up VLAN iface %s with WEP", vlan->ifname); return -1; } if (!if_nametoindex(vlan->ifname)) ret = hostapd_vlan_if_add(hapd, vlan->ifname); else if (!existsok) return -1; else ret = 0; if (ret) return ret; ifconfig_up(vlan->ifname); /* else wpa group will fail fatal */ if (hapd->wpa_auth) ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); if (ret == 0) return ret; wpa_printf(MSG_ERROR, "WPA initialization for VLAN %d failed (%d)", vlan->vlan_id, ret); if (wpa_auth_release_group(hapd->wpa_auth, vlan->vlan_id)) wpa_printf(MSG_ERROR, "WPA deinit of %s failed", vlan->ifname); /* group state machine setup failed */ if (hostapd_vlan_if_remove(hapd, vlan->ifname)) wpa_printf(MSG_ERROR, "Removal of %s failed", vlan->ifname); return ret; }
static int vlan_dynamic_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan) { while (vlan) { if (vlan->vlan_id != VLAN_ID_WILDCARD) { if (hostapd_vlan_if_add(hapd, vlan->ifname)) { if (errno != EEXIST) { wpa_printf(MSG_ERROR, "VLAN: Could " "not add VLAN %s: %s", vlan->ifname, strerror(errno)); return -1; } } #ifdef CONFIG_FULL_DYNAMIC_VLAN ifconfig_up(vlan->ifname); #endif /* CONFIG_FULL_DYNAMIC_VLAN */ } vlan = vlan->next; } return 0; }
static void vlan_newlink(char *ifname, struct hostapd_data *hapd) { char vlan_ifname[IFNAMSIZ]; char br_name[IFNAMSIZ]; struct hostapd_vlan *vlan = hapd->conf->vlan; char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; int vlan_naming = hapd->conf->ssid.vlan_naming; int clean; wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname); while (vlan) { if (os_strcmp(ifname, vlan->ifname) == 0 && !vlan->configured) { vlan->configured = 1; if (hapd->conf->vlan_bridge[0]) { os_snprintf(br_name, sizeof(br_name), "%s%d", hapd->conf->vlan_bridge, vlan->vlan_id); } else if (tagged_interface) { os_snprintf(br_name, sizeof(br_name), "br%s.%d", tagged_interface, vlan->vlan_id); } else { os_snprintf(br_name, sizeof(br_name), "brvlan%d", vlan->vlan_id); } dyn_iface_get(hapd, br_name, br_addbr(br_name) ? 0 : DVLAN_CLEAN_BR); ifconfig_up(br_name); if (tagged_interface) { if (vlan_naming == DYNAMIC_VLAN_NAMING_WITH_DEVICE) os_snprintf(vlan_ifname, sizeof(vlan_ifname), "%s.%d", tagged_interface, vlan->vlan_id); else os_snprintf(vlan_ifname, sizeof(vlan_ifname), "vlan%d", vlan->vlan_id); clean = 0; ifconfig_up(tagged_interface); if (!vlan_add(tagged_interface, vlan->vlan_id, vlan_ifname)) clean |= DVLAN_CLEAN_VLAN; if (!br_addif(br_name, vlan_ifname)) clean |= DVLAN_CLEAN_VLAN_PORT; dyn_iface_get(hapd, vlan_ifname, clean); ifconfig_up(vlan_ifname); } if (!br_addif(br_name, ifname)) vlan->clean |= DVLAN_CLEAN_WLAN_PORT; ifconfig_up(ifname); break; } vlan = vlan->next; } }
/* Add a vlan interface with VLAN ID 'vid' and tagged interface 'if_name'. returns -1 on error returns 1 if the interface already exists returns 0 otherwise */ int vlan_add(const char *if_name, int vid, const char *vlan_if_name) { int fd; struct vlan_ioctl_args if_request; wpa_printf(MSG_DEBUG, "VLAN: vlan_add(if_name=%s, vid=%d)", if_name, vid); ifconfig_up(if_name); if ((os_strlen(if_name) + 1) > sizeof(if_request.device1)) { wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'", if_name); return -1; } if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " "failed: %s", __func__, strerror(errno)); return -1; } os_memset(&if_request, 0, sizeof(if_request)); /* Determine if a suitable vlan device already exists. */ os_snprintf(if_request.device1, sizeof(if_request.device1), "vlan%d", vid); if_request.cmd = _GET_VLAN_VID_CMD; if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0) { if (if_request.u.VID == vid) { if_request.cmd = _GET_VLAN_REALDEV_NAME_CMD; if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0 && os_strncmp(if_request.u.device2, if_name, sizeof(if_request.u.device2)) == 0) { close(fd); wpa_printf(MSG_DEBUG, "VLAN: vlan_add: " "if_name %s exists already", if_request.device1); return 1; } } } /* A suitable vlan device does not already exist, add one. */ os_memset(&if_request, 0, sizeof(if_request)); os_strlcpy(if_request.device1, if_name, sizeof(if_request.device1)); if_request.u.VID = vid; if_request.cmd = ADD_VLAN_CMD; if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { wpa_printf(MSG_ERROR, "VLAN: %s: ADD_VLAN_CMD failed for %s: " "%s", __func__, if_request.device1, strerror(errno)); close(fd); return -1; } close(fd); return 0; }