From patchwork Mon Mar 17 13:16:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helmut Schaa X-Patchwork-Id: 331037 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 043E32C00B0 for ; Tue, 18 Mar 2014 00:22:10 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id A56AA9C199; Mon, 17 Mar 2014 09:22:02 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 68FqYxfmIWBN; Mon, 17 Mar 2014 09:22:02 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 6A8869C1B5; Mon, 17 Mar 2014 09:21:36 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 60AF69C1B5 for ; Mon, 17 Mar 2014 09:21:35 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cGponB179j+G for ; Mon, 17 Mar 2014 09:21:30 -0400 (EDT) Received: from mail-qc0-f173.google.com (mail-qc0-f173.google.com [209.85.216.173]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (not verified)) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id 230D69C196 for ; Mon, 17 Mar 2014 09:21:28 -0400 (EDT) Received: by mail-qc0-f173.google.com with SMTP id r5so5883128qcx.32 for ; Mon, 17 Mar 2014 06:21:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JFqn9j5TP/iqgYc2JXNv3NZ6UqONgqvyhv2dwmC/vw8=; b=aReZ5Hi9ChA1jwwrlcg6pNfeb/I5URmKPRnvhHUCo2ZvpHx8KIzexV1eBSrnrnMguC FWBr15JjA6ES/20Wn143KHpP1dVmXza8kifUbOisVVRfidVShFH0nWeOLE5vtLvhkxy1 9H2cwzSGxXqFUtEb5bNlKObqUBWTd/2VP2vIkaS6hGCBFwd9YoLOMl4bWY0WWzSZe+s5 HKuq1JSKERWtX6KKHubMDteFDoDLDTlq3QLx/rMGmhwNkLdx/UelYDNYCniksC6tW5vl Bt8B0E4FVmDDGw32NWBW5BPObZtR+0cV20PKgBDZYXW09+mF63Vw+NTNwfPqYLoa3qMC PlEQ== X-Received: by 10.224.131.193 with SMTP id y1mr2494046qas.86.1395062487869; Mon, 17 Mar 2014 06:21:27 -0700 (PDT) Received: from hschaa-desktop.site (HSI-KBW-091-089-000-006.hsi2.kabelbw.de. [91.89.0.6]) by mx.google.com with ESMTPSA id k6sm20984744qgd.17.2014.03.17.06.21.26 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 17 Mar 2014 06:21:27 -0700 (PDT) From: Helmut Schaa To: hostap@lists.shmoo.com Subject: [RFC 2/5] hostapd: Add more flexible VLAN briging Date: Mon, 17 Mar 2014 14:16:25 +0100 Message-Id: <1395062188-13222-3-git-send-email-helmut.schaa@googlemail.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1395062188-13222-2-git-send-email-helmut.schaa@googlemail.com> References: <1395062188-13222-1-git-send-email-helmut.schaa@googlemail.com> <1395062188-13222-2-git-send-email-helmut.schaa@googlemail.com> X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com This allows a more flexible VLAN bridging configuration then using full dynamic vlan tagging (which uses a hardcoded bridge name). Instead of trying to derive the bridgenames statically allow another configuration parameter per VLAN that specifies the bridge interface this VLAN should appear in. Signed-off-by: Helmut Schaa --- hostapd/config_file.c | 46 +++++++++++++++++++++------------------------- hostapd/hostapd.vlan | 10 +++++----- src/ap/ap_config.h | 1 + src/ap/ap_drv_ops.c | 4 ++-- src/ap/ap_drv_ops.h | 3 ++- src/ap/vlan_init.c | 24 +++++++++++++++++++++--- 6 files changed, 52 insertions(+), 36 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 19d6ad3..c00bc71 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -27,7 +27,7 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, const char *fname) { FILE *f; - char buf[128], *pos, *pos2; + char buf[128], *pos, *ifname, *bridge; int line = 0, vlan_id; struct hostapd_vlan *vlan; @@ -40,26 +40,15 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, while (fgets(buf, sizeof(buf), f)) { line++; - if (buf[0] == '#') - continue; - pos = buf; - while (*pos != '\0') { - if (*pos == '\n') { - *pos = '\0'; - break; - } - pos++; - } - if (buf[0] == '\0') + if (buf[0] == '#' || buf[0] == '\0') continue; - if (buf[0] == '*') { + pos = strtok(buf, " \t\n"); + if (pos[0] == '*') { vlan_id = VLAN_ID_WILDCARD; - pos = buf + 1; } else { - vlan_id = strtol(buf, &pos, 10); - if (buf == pos || vlan_id < 1 || - vlan_id > MAX_VLAN_ID) { + vlan_id = strtol(pos, NULL, 10); + if (vlan_id < 1 || vlan_id > MAX_VLAN_ID) { wpa_printf(MSG_ERROR, "Invalid VLAN ID at " "line %d in '%s'", line, fname); fclose(f); @@ -67,18 +56,23 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, } } - while (*pos == ' ' || *pos == '\t') - pos++; - pos2 = pos; - while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0') - pos2++; - *pos2 = '\0'; - if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) { + pos = strtok(NULL, " \t\n"); + if (!pos || os_strlen(pos) > IFNAMSIZ) { wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d " "in '%s'", line, fname); fclose(f); return -1; } + ifname = pos; + + pos = strtok(NULL, " \t\n"); + if (pos && os_strlen(pos) > IFNAMSIZ) { + wpa_printf(MSG_ERROR, "Invalid VLAN bridge at line %d " + "in '%s'", line, fname); + fclose(f); + return -1; + } + bridge = pos; vlan = os_zalloc(sizeof(*vlan)); if (vlan == NULL) { @@ -89,7 +83,9 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, } vlan->vlan_id = vlan_id; - os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname)); + os_strlcpy(vlan->ifname, ifname, sizeof(vlan->ifname)); + if (bridge) + os_strlcpy(vlan->bridge, bridge, sizeof(vlan->bridge)); vlan->next = bss->vlan; bss->vlan = vlan; } diff --git a/hostapd/hostapd.vlan b/hostapd/hostapd.vlan index 98254fa..74fc201 100644 --- a/hostapd/hostapd.vlan +++ b/hostapd/hostapd.vlan @@ -1,9 +1,9 @@ # VLAN ID to network interface mapping -1 vlan1 -2 vlan2 -3 vlan3 -100 guest +1 vlan1 br1 +2 vlan2 br2 +3 vlan3 br3 +100 guest br4 # Optional wildcard entry matching all VLAN IDs. The first # in the interface # name will be replaced with the VLAN ID. The network interfaces are created # (and removed) dynamically based on the use. -* vlan# +* vlan# br# diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 4631ca9..5875529 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -85,6 +85,7 @@ struct hostapd_vlan { struct hostapd_vlan *next; int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */ char ifname[IFNAMSIZ + 1]; + char bridge[IFNAMSIZ + 1]; int dynamic_vlan; #ifdef CONFIG_FULL_DYNAMIC_VLAN diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index e998fc6..1c3f423 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -280,12 +280,12 @@ int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname, } -int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname) +int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname, const char *bridge) { char force_ifname[IFNAMSIZ]; u8 if_addr[ETH_ALEN]; return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr, - NULL, NULL, force_ifname, if_addr, NULL, 0); + NULL, NULL, force_ifname, if_addr, bridge, 0); } diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 9edaf7d..b283eca 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -30,7 +30,8 @@ int hostapd_set_authorized(struct hostapd_data *hapd, int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta); int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname, int enabled); -int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname); +int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname, + const char *bridge); int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname); int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds, const u8 *addr, int aid, int val); diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c index 7ff5b1a..4835860 100644 --- a/src/ap/vlan_init.c +++ b/src/ap/vlan_init.c @@ -933,7 +933,9 @@ static int vlan_dynamic_add(struct hostapd_data *hapd, { while (vlan) { if (vlan->vlan_id != VLAN_ID_WILDCARD) { - if (hostapd_vlan_if_add(hapd, vlan->ifname)) { + if (hostapd_vlan_if_add(hapd, vlan->ifname, + vlan->bridge[0] == '\0' ? + NULL : vlan->bridge)) { if (errno != EEXIST) { wpa_printf(MSG_ERROR, "VLAN: Could " "not add VLAN %s: %s", @@ -1026,6 +1028,7 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd, { struct hostapd_vlan *n = NULL; char *ifname, *pos; + char *brname = NULL; if (vlan == NULL || vlan_id <= 0 || vlan_id > MAX_VLAN_ID || vlan->vlan_id != VLAN_ID_WILDCARD) @@ -1041,9 +1044,21 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd, goto free_ifname; *pos++ = '\0'; + if (vlan->bridge[0] != '\0') { + brname = os_strdup(vlan->bridge); + if (brname == NULL) + goto free_ifname; + pos = os_strchr(vlan->bridge, '#'); + if (pos == NULL) + goto free_brname; + *pos++ = '\0'; + os_snprintf(n->bridge, sizeof(n->bridge), "%s%d%s", brname, + vlan_id, pos); + } + n = os_zalloc(sizeof(*n)); if (n == NULL) - goto free_ifname; + goto free_brname; n->vlan_id = vlan_id; n->dynamic_vlan = 1; @@ -1051,7 +1066,8 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd, os_snprintf(n->ifname, sizeof(n->ifname), "%s%d%s", ifname, vlan_id, pos); - if (hostapd_vlan_if_add(hapd, n->ifname)) { + if (hostapd_vlan_if_add(hapd, n->ifname, + n->bridge[0] == '\0' ? NULL : n->bridge)) { os_free(n); n = NULL; goto free_ifname; @@ -1064,6 +1080,8 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd, ifconfig_up(n->ifname); #endif /* CONFIG_FULL_DYNAMIC_VLAN */ +free_brname: + os_free(brname); free_ifname: os_free(ifname); return n;