From patchwork Mon Mar 17 13:16:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helmut Schaa X-Patchwork-Id: 331039 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 1EB2F2C00B0 for ; Tue, 18 Mar 2014 00:22:49 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id C97DB9C1FB; Mon, 17 Mar 2014 09:22:28 -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 ZFrfp+yDIjJx; Mon, 17 Mar 2014 09:22:28 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 699999C1D1; Mon, 17 Mar 2014 09:21:41 -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 3C4BD9C1CB for ; Mon, 17 Mar 2014 09:21:40 -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 EATPCP+CF+ln for ; Mon, 17 Mar 2014 09:21:35 -0400 (EDT) Received: from mail-qg0-f46.google.com (mail-qg0-f46.google.com [209.85.192.46]) (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 DB1DE9C154 for ; Mon, 17 Mar 2014 09:21:30 -0400 (EDT) Received: by mail-qg0-f46.google.com with SMTP id e89so16565848qgf.5 for ; Mon, 17 Mar 2014 06:21:30 -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=uSMPso2AHbEzWVigVpJQeV+65N68n71UKlog6c/IcRw=; b=lJXG+NEuWTsR2vKXDaY51xRhc4Zu+QXuWnHGMsAJVOHw8OMYepypwWYelymh+f9WUD CJ+CuwAekTJFCBDDrn1aGex+uPTN0t2x3oU2LUZwh47CapmNPip9OAl4NvE8bauqA5Dl WLIqr3pFP17yRm16cJJY+TvKBxW6Tg5e678fT2vgUsiw7zwWUpyrEHNYg3+HYB3OB8FK cOHw4tp3+8pZ49+pAzcCR03J7tAWJmrfkFqu+CCSMhS0zJ9GigFiPis+IKczXTj1vZM/ bZNowK/Smfw+D7lk9SMtFJyHS8vEmlgsPOdLTQbdW1lsXkLc/dQqwD8isT/qLb7VC9GU BJEQ== X-Received: by 10.229.193.136 with SMTP id du8mr28174926qcb.11.1395062490623; Mon, 17 Mar 2014 06:21:30 -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.29 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 17 Mar 2014 06:21:30 -0700 (PDT) From: Helmut Schaa To: hostap@lists.shmoo.com Subject: [RFC 4/5] driver_nl80211: Allow bridging of AP_VLAN interfaces Date: Mon, 17 Mar 2014 14:16:27 +0100 Message-Id: <1395062188-13222-5-git-send-email-helmut.schaa@googlemail.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1395062188-13222-4-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> <1395062188-13222-3-git-send-email-helmut.schaa@googlemail.com> <1395062188-13222-4-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 Signed-off-by: Helmut Schaa --- src/drivers/driver_nl80211.c | 109 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 17 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 3cfaadc..276c750 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -224,6 +224,15 @@ struct i802_bridge { unsigned int added_bridge:1; }; +struct i802_ap_vlan { + struct i802_ap_vlan *next; + + int ifindex; + char ifname[IFNAMSIZ + 1]; + struct i802_bridge bridge; + unsigned int added_if:1; +}; + struct i802_bss { struct wpa_driver_nl80211_data *drv; struct i802_bss *next; @@ -235,6 +244,7 @@ struct i802_bss { unsigned int wdev_id_set:1; unsigned int added_if:1; struct i802_bridge bridge; + struct i802_ap_vlan *vlans; u8 addr[ETH_ALEN]; @@ -9743,6 +9753,35 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type, } #endif /* CONFIG_P2P */ + if (type == WPA_IF_AP_VLAN) { + struct i802_ap_vlan *ap_vlan = os_zalloc(sizeof(*ap_vlan)); + if (bridge && + i802_check_bridge(drv, &ap_vlan->bridge, bridge, ifname) < 0) { + wpa_printf(MSG_ERROR, "nl80211: Failed to add the new " + "interface %s to a bridge %s", + ifname, bridge); + if (added) + nl80211_remove_iface(drv, ifidx); + os_free(ap_vlan); + return -1; + } + + if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1)) { + if (added) + nl80211_remove_iface(drv, ifidx); + os_free(ap_vlan); + return -1; + } + + ap_vlan->added_if = added; + ap_vlan->ifindex = ifidx; + os_strlcpy(ap_vlan->ifname, ifname, IFNAMSIZ); + + /* Remeber this AP VLAN */ + ap_vlan->next = bss->vlans; + bss->vlans = ap_vlan; + } + if (type == WPA_IF_AP_BSS) { struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss)); if (new_bss == NULL) { @@ -9799,29 +9838,65 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, { struct wpa_driver_nl80211_data *drv = bss->drv; int ifindex = if_nametoindex(ifname); - + struct i802_bridge *bridge = NULL; + struct i802_ap_vlan *ap_vlan = NULL, *ap_vlan_prev = NULL; + wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d", __func__, type, ifname, ifindex, bss->added_if); - if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex)) - nl80211_remove_iface(drv, ifindex); - - if (type != WPA_IF_AP_BSS) - return 0; - if (bss->bridge.added_if_into_bridge) { - if (linux_br_del_if(drv->global->ioctl_sock, bss->bridge.brname, - bss->ifname) < 0) - wpa_printf(MSG_INFO, "nl80211: Failed to remove " - "interface %s from bridge %s: %s", - bss->ifname, bss->bridge.brname, strerror(errno)); + switch (type) { + case WPA_IF_AP_BSS: + bridge = &bss->bridge; + break; + case WPA_IF_AP_VLAN: + ap_vlan = bss->vlans; + while (ap_vlan) { + if (ap_vlan->ifindex != ifindex) { + ap_vlan_prev = ap_vlan; + ap_vlan = ap_vlan->next; + continue; + } + bridge = &ap_vlan->bridge; + break; + } + break; + default: + if (ifindex > 0) + nl80211_remove_iface(drv, ifindex); + return 0; } - if (bss->bridge.added_bridge) { - if (linux_br_del(drv->global->ioctl_sock, bss->bridge.brname) < 0) - wpa_printf(MSG_INFO, "nl80211: Failed to remove " - "bridge %s: %s", - bss->bridge.brname, strerror(errno)); + + if (bridge) { + if (bridge->added_if_into_bridge) { + if (linux_br_del_if(drv->global->ioctl_sock, bridge->brname, + ifname) < 0) + wpa_printf(MSG_INFO, "nl80211: Failed to remove " + "interface %s from bridge %s: %s", + ifname, bridge->brname, strerror(errno)); + } + if (bridge->added_bridge) { + if (linux_br_del(drv->global->ioctl_sock, bridge->brname) < 0) + wpa_printf(MSG_INFO, "nl80211: Failed to remove " + "bridge %s: %s", + bridge->brname, strerror(errno)); + } } + if (ap_vlan) { + if (ap_vlan->added_if && ap_vlan->ifindex == ifindex) + nl80211_remove_iface(drv, ifindex); + if (ap_vlan_prev) + ap_vlan_prev->next = ap_vlan->next; + else + bss->vlans = ap_vlan->next; + + os_free(ap_vlan); + return 0; + } + + if (bss->added_if) + nl80211_remove_iface(drv, ifindex); + if (bss != drv->first_bss) { struct i802_bss *tbss;