From patchwork Sat Jul 7 08:52:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: michael-dev X-Patchwork-Id: 169568 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]) by ozlabs.org (Postfix) with ESMTP id 92AC62C020A for ; Sat, 7 Jul 2012 18:52:57 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 7FEA79C1AF; Sat, 7 Jul 2012 04:52:54 -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 Hbr+NfLv8O+V; Sat, 7 Jul 2012 04:52:54 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id A82D89C1B6; Sat, 7 Jul 2012 04:52:31 -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 8F90A9C19E for ; Sat, 7 Jul 2012 04:52:29 -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 z-VjWMsqJUvc for ; Sat, 7 Jul 2012 04:52:24 -0400 (EDT) Received: from a251.fem.tu-ilmenau.de (gast-001.fem.tu-ilmenau.de [141.24.44.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B40929C1A5 for ; Sat, 7 Jul 2012 04:52:12 -0400 (EDT) Received: from localhost6.localdomain6 (localhost.localdomain [127.0.0.1]) by konsullaptop.a-keller (Postfix) with ESMTP id 082C2221457; Sat, 7 Jul 2012 10:52:12 +0200 (CEST) Subject: [PATCH 2/4] use netlink to create vlan interface To: projekt-wlan@fem.tu-ilmenau.de, hostap@lists.shmoo.com From: Michael Braun Date: Sat, 07 Jul 2012 10:52:12 +0200 Message-ID: <20120707085212.24229.73047.stgit@localhost6.localdomain6> In-Reply-To: <20120707085201.24229.47142.stgit@localhost6.localdomain6> References: <20120707085201.24229.47142.stgit@localhost6.localdomain6> User-Agent: StGit/0.15 MIME-Version: 1.0 X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com This permits hostapd to set the name of the created interface. --- hostapd/Android.mk | 1 hostapd/Makefile | 1 src/ap/vlan_init.c | 131 ++++++--------------------------------------- src/ap/vlan_util.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++ src/ap/vlan_util.h | 21 +++++++ src/drivers/drivers.mak | 20 +++++++ src/drivers/drivers.mk | 21 +++++++ 7 files changed, 219 insertions(+), 113 deletions(-) create mode 100644 src/ap/vlan_util.c create mode 100644 src/ap/vlan_util.h diff --git a/hostapd/Android.mk b/hostapd/Android.mk index 543c152..3ba6d47 100644 --- a/hostapd/Android.mk +++ b/hostapd/Android.mk @@ -151,6 +151,7 @@ ifdef CONFIG_NO_VLAN L_CFLAGS += -DCONFIG_NO_VLAN else OBJS += src/ap/vlan_init.c +OBJS += src/ap/vlan_util.c endif ifdef CONFIG_NO_CTRL_IFACE diff --git a/hostapd/Makefile b/hostapd/Makefile index b43aa75..a734968 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -123,6 +123,7 @@ ifdef CONFIG_NO_VLAN CFLAGS += -DCONFIG_NO_VLAN else OBJS += ../src/ap/vlan_init.o +OBJS += ../src/ap/vlan_util.o endif ifdef CONFIG_NO_CTRL_IFACE diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c index f2f766f..b1e8f42 100644 --- a/src/ap/vlan_init.c +++ b/src/ap/vlan_init.c @@ -21,6 +21,7 @@ #include "ap_config.h" #include "ap_drv_ops.h" #include "vlan_init.h" +#include "vlan_util.h" #ifdef CONFIG_FULL_DYNAMIC_VLAN @@ -370,117 +371,13 @@ static int vlan_rem(const char *if_name) } -/* - 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; - - 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; -} - - -static int vlan_set_name_type(unsigned int name_type) -{ - int fd; - struct vlan_ioctl_args if_request; - - wpa_printf(MSG_DEBUG, "VLAN: vlan_set_name_type(name_type=%u)", - name_type); - 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)); - - if_request.u.name_type = name_type; - if_request.cmd = SET_VLAN_NAME_TYPE_CMD; - if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { - wpa_printf(MSG_ERROR, "VLAN: %s: SET_VLAN_NAME_TYPE_CMD " - "name_type=%u failed: %s", - __func__, name_type, strerror(errno)); - 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; + int vlan_naming = hapd->conf->ssid.vlan_naming; wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname); @@ -497,11 +394,16 @@ static void vlan_newlink(char *ifname, struct hostapd_data *hapd) if (tagged_interface) { - if (!vlan_add(tagged_interface, vlan->vlan_id)) - vlan->clean |= DVLAN_CLEAN_VLAN; + 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); - os_snprintf(vlan_ifname, sizeof(vlan_ifname), - "vlan%d", vlan->vlan_id); + ifconfig_up(tagged_interface); + if (!vlan_add(tagged_interface, vlan->vlan_id, vlan_ifname)) + vlan->clean |= DVLAN_CLEAN_VLAN; if (!br_addif(br_name, vlan_ifname)) vlan->clean |= DVLAN_CLEAN_VLAN_PORT; @@ -527,6 +429,7 @@ static void vlan_dellink(char *ifname, struct hostapd_data *hapd) char br_name[IFNAMSIZ]; struct hostapd_vlan *first, *prev, *vlan = hapd->conf->vlan; char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; + int vlan_naming = hapd->conf->ssid.vlan_naming; wpa_printf(MSG_DEBUG, "VLAN: vlan_dellink(%s)", ifname); @@ -541,8 +444,12 @@ static void vlan_dellink(char *ifname, struct hostapd_data *hapd) br_delif(br_name, vlan->ifname); if (tagged_interface) { - os_snprintf(vlan_ifname, sizeof(vlan_ifname), - "vlan%d", vlan->vlan_id); + 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); if (vlan->clean & DVLAN_CLEAN_VLAN_PORT) br_delif(br_name, vlan_ifname); ifconfig_down(vlan_ifname); @@ -682,8 +589,6 @@ full_dynamic_vlan_init(struct hostapd_data *hapd) if (priv == NULL) return NULL; - vlan_set_name_type(VLAN_NAME_TYPE_PLUS_VID_NO_PAD); - priv->s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (priv->s < 0) { wpa_printf(MSG_ERROR, "VLAN: %s: socket(PF_NETLINK,SOCK_RAW," diff --git a/src/ap/vlan_util.c b/src/ap/vlan_util.c new file mode 100644 index 0000000..ca18963 --- /dev/null +++ b/src/ap/vlan_util.c @@ -0,0 +1,137 @@ +/* + * hostapd / VLAN initialization + * Copyright 2003, Instant802 Networks, Inc. + * Copyright 2005-2006, Devicescape Software, Inc. + * Copyright (c) 2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" + +#include "utils/common.h" +#include "hostapd.h" +#include "vlan_util.h" + + +#ifdef CONFIG_FULL_DYNAMIC_VLAN + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "utils/eloop.h" + + +/* + Add a vlan interface with name 'vlan_if_name', 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 ret = -1; + struct nl_sock *handle = 0; + struct nl_cache *cache = 0; + struct rtnl_link *link = 0; + int if_idx = 0; + + wpa_printf(MSG_DEBUG, "VLAN: vlan_add(if_name=%s, vid=%d, vlan_if_name=%s)", + if_name, vid, vlan_if_name); + + if ((os_strlen(if_name) + 1) > IFNAMSIZ) { + wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'", + if_name); + return -1; + } + + if ((os_strlen(vlan_if_name) + 1) > IFNAMSIZ) { + wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'", + vlan_if_name); + return -1; + } + + handle = nl_socket_alloc(); + if (!handle) { + wpa_printf(MSG_ERROR, "VLAN: failed to open netlink socket"); + goto vlan_add_error; + } + + if (nl_connect(handle, NETLINK_ROUTE) < 0) { + wpa_printf(MSG_ERROR, "VLAN: failed to connect to netlink"); + goto vlan_add_error; + } + + if (rtnl_link_alloc_cache(handle, AF_UNSPEC, &cache) < 0) { + cache = NULL; + wpa_printf(MSG_ERROR, "VLAN: failed to alloc cache"); + goto vlan_add_error; + } + + if (!(if_idx = rtnl_link_name2i(cache, if_name))) {; + /* link does not exist */ + wpa_printf(MSG_ERROR, "VLAN: interface %s does not exist", if_name); + goto vlan_add_error; + } + + if ((link = rtnl_link_get_by_name(cache, vlan_if_name))) { + /* link does exist */ + rtnl_link_put(link); link = NULL; + wpa_printf(MSG_ERROR, "VLAN: interface %s already exists", vlan_if_name); + ret = 1; + goto vlan_add_error; + } + + link = rtnl_link_alloc(); + if (!link) { + wpa_printf(MSG_ERROR, "VLAN: failed to allocate new link"); + goto vlan_add_error; + } + + if (rtnl_link_set_type(link, "vlan") < 0) { + wpa_printf(MSG_ERROR, "VLAN: failed to set link type"); + goto vlan_add_error; + } + + rtnl_link_set_link(link, if_idx); + rtnl_link_set_name(link, vlan_if_name); + + if (rtnl_link_vlan_set_id(link, vid) < 0) { + wpa_printf(MSG_ERROR, "VLAN: failed to set link vlan id"); + goto vlan_add_error; + } + + if (rtnl_link_add(handle, link, NLM_F_CREATE) < 0) { + wpa_printf(MSG_ERROR, "VLAN: failed to create link %s for vlan %d on %s (%d)", vlan_if_name, vid, if_name, if_idx); + goto vlan_add_error; + } + + ret = 0; + +vlan_add_error: + if (link) + rtnl_link_put(link); + if (cache) + nl_cache_free(cache); + if (handle) + nl_socket_free(handle); + return ret; +} + +#endif diff --git a/src/ap/vlan_util.h b/src/ap/vlan_util.h new file mode 100644 index 0000000..1fd146a --- /dev/null +++ b/src/ap/vlan_util.h @@ -0,0 +1,21 @@ +/* + * hostapd / VLAN initialization + * Copyright 2003, Instant802 Networks, Inc. + * Copyright 2005, Devicescape Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef VLAN_UTIL_H +#define VLAN_UTIL_H + +int vlan_add(const char *if_name, int vid, const char* vlan_if_name); + +#endif diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak index 0cc81f9..c2e53ab 100644 --- a/src/drivers/drivers.mak +++ b/src/drivers/drivers.mak @@ -142,6 +142,26 @@ ifdef NEED_RFKILL DRV_OBJS += ../src/drivers/rfkill.o endif +ifdef CONFIG_FULL_DYNAMIC_VLAN +ifdef CONFIG_LIBNL32 + DRV_LIBS += -lnl-3 + DRV_LIBS += -lnl-genl-3 + DRV_LIBS += -lnl-route-3 + DRV_CFLAGS += -DCONFIG_LIBNL20 +else + ifdef CONFIG_LIBNL_TINY + DRV_LIBS += -lnl-tiny + else + DRV_LIBS += -lnl + endif + + ifdef CONFIG_LIBNL20 + DRV_LIBS += -lnl-genl + DRV_LIBS += -lnl-route + DRV_CFLAGS += -DCONFIG_LIBNL20 + endif +endif +endif ##### COMMON VARS DRV_BOTH_CFLAGS := $(DRV_CFLAGS) $(DRV_WPA_CFLAGS) $(DRV_AP_CFLAGS) diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk index 1d7129c..0ec1c55 100644 --- a/src/drivers/drivers.mk +++ b/src/drivers/drivers.mk @@ -146,6 +146,27 @@ ifdef CONFIG_DRIVER_CUSTOM DRV_CFLAGS += -DCONFIG_DRIVER_CUSTOM endif +ifdef CONFIG_FULL_DYNAMIC_VLAN +ifdef CONFIG_LIBNL32 + DRV_LIBS += -lnl-3 + DRV_LIBS += -lnl-genl-3 + DRV_LIBS += -lnl-route-3 + DRV_CFLAGS += -DCONFIG_LIBNL20 +else + ifdef CONFIG_LIBNL_TINY + DRV_LIBS += -lnl-tiny + else + DRV_LIBS += -lnl + endif + + ifdef CONFIG_LIBNL20 + DRV_LIBS += -lnl-genl + DRV_LIBS += -lnl-route + DRV_CFLAGS += -DCONFIG_LIBNL20 + endif +endif +endif + ##### COMMON VARS DRV_BOTH_CFLAGS := $(DRV_CFLAGS) $(DRV_WPA_CFLAGS) $(DRV_AP_CFLAGS) DRV_WPA_CFLAGS += $(DRV_CFLAGS)