@@ -781,7 +781,9 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
}
if (hapd->conf->ieee802_11f &&
- (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) {
+ (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface,
+ hapd->conf->bridge[0] ? hapd->conf->bridge :
+ NULL)) == NULL) {
wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
"failed.");
return -1;
@@ -214,6 +214,8 @@ static void iapp_send_layer2_update(struct iapp_data *iapp, u8 *addr)
/* Send Level 2 Update Frame to update forwarding tables in layer 2
* bridge devices */
+ if (iapp->packet_sock < 0)
+ return;
/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
* Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
@@ -382,11 +384,46 @@ static void iapp_receive_udp(int sock, void *eloop_ctx, void *sock_ctx)
}
-struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
+static int iapp_init_layer2(struct iapp_data *iapp, const char *bridge)
{
struct ifreq ifr;
struct sockaddr_ll addr;
int ifindex;
+
+ /* Layer 2 updates only make sense when the wifi interface is bridged */
+ if (!bridge)
+ return 0;
+
+ iapp->packet_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if (iapp->packet_sock < 0) {
+ perror("socket[PF_PACKET,SOCK_RAW]");
+ return -1;
+ }
+
+ os_memset(&ifr, 0, sizeof(ifr));
+ os_strlcpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name));
+ if (ioctl(iapp->packet_sock, SIOCGIFINDEX, &ifr) != 0) {
+ perror("ioctl(SIOCGIFINDEX)");
+ return -1;
+ }
+ ifindex = ifr.ifr_ifindex;
+
+ os_memset(&addr, 0, sizeof(addr));
+ addr.sll_family = AF_PACKET;
+ addr.sll_ifindex = ifindex;
+ if (bind(iapp->packet_sock, (struct sockaddr *) &addr,
+ sizeof(addr)) < 0) {
+ perror("bind[PACKET]");
+ return -1;
+ }
+
+ return 0;
+}
+
+struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface,
+ const char *bridge)
+{
+ struct ifreq ifr;
struct sockaddr_in *paddr, uaddr;
struct iapp_data *iapp;
struct ip_mreqn mreq;
@@ -415,7 +452,6 @@ struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
iapp_deinit(iapp);
return NULL;
}
- ifindex = ifr.ifr_ifindex;
if (ioctl(iapp->udp_sock, SIOCGIFADDR, &ifr) != 0) {
perror("ioctl(SIOCGIFADDR)");
@@ -466,19 +502,7 @@ struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
return NULL;
}
- iapp->packet_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (iapp->packet_sock < 0) {
- perror("socket[PF_PACKET,SOCK_RAW]");
- iapp_deinit(iapp);
- return NULL;
- }
-
- os_memset(&addr, 0, sizeof(addr));
- addr.sll_family = AF_PACKET;
- addr.sll_ifindex = ifindex;
- if (bind(iapp->packet_sock, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- perror("bind[PACKET]");
+ if (iapp_init_layer2(iapp, bridge) < 0) {
iapp_deinit(iapp);
return NULL;
}
@@ -14,7 +14,8 @@ struct iapp_data;
#ifdef CONFIG_IAPP
void iapp_new_station(struct iapp_data *iapp, struct sta_info *sta);
-struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface);
+struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface,
+ const char *bridge);
void iapp_deinit(struct iapp_data *iapp);
#else /* CONFIG_IAPP */
@@ -25,7 +26,8 @@ static inline void iapp_new_station(struct iapp_data *iapp,
}
static inline struct iapp_data * iapp_init(struct hostapd_data *hapd,
- const char *iface)
+ const char *iface,
+ const char *bridge)
{
return NULL;
}