nl80211: Remove bridge FDB entry upon sta_remove()
The FDB entry removal ensures that the traffic destined for a disassociated station's MAC address is no longer forwarded from the bridge to the BSS. Signed-off-by: Kyeyoon Park <kyeyoonp@qca.qualcomm.com>
This commit is contained in:
parent
39323bc16a
commit
97ed9a06df
3 changed files with 72 additions and 0 deletions
|
@ -19,6 +19,9 @@
|
||||||
#include <netlink/genl/genl.h>
|
#include <netlink/genl/genl.h>
|
||||||
#include <netlink/genl/family.h>
|
#include <netlink/genl/family.h>
|
||||||
#include <netlink/genl/ctrl.h>
|
#include <netlink/genl/ctrl.h>
|
||||||
|
#ifdef CONFIG_LIBNL3_ROUTE
|
||||||
|
#include <netlink/route/neighbour.h>
|
||||||
|
#endif /* CONFIG_LIBNL3_ROUTE */
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <netpacket/packet.h>
|
#include <netpacket/packet.h>
|
||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
|
@ -328,6 +331,8 @@ struct wpa_driver_nl80211_data {
|
||||||
|
|
||||||
int eapol_sock; /* socket for EAPOL frames */
|
int eapol_sock; /* socket for EAPOL frames */
|
||||||
|
|
||||||
|
struct nl_sock *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
|
||||||
|
|
||||||
int default_if_indices[16];
|
int default_if_indices[16];
|
||||||
int *if_indices;
|
int *if_indices;
|
||||||
int num_if_indices;
|
int num_if_indices;
|
||||||
|
@ -4932,6 +4937,8 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
|
||||||
wpa_printf(MSG_INFO, "nl80211: Failed to remove "
|
wpa_printf(MSG_INFO, "nl80211: Failed to remove "
|
||||||
"interface %s from bridge %s: %s",
|
"interface %s from bridge %s: %s",
|
||||||
bss->ifname, bss->brname, strerror(errno));
|
bss->ifname, bss->brname, strerror(errno));
|
||||||
|
if (drv->rtnl_sk)
|
||||||
|
nl_socket_free(drv->rtnl_sk);
|
||||||
}
|
}
|
||||||
if (bss->added_bridge) {
|
if (bss->added_bridge) {
|
||||||
if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
|
if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
|
||||||
|
@ -7751,6 +7758,43 @@ static int wpa_driver_nl80211_sta_add(void *priv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_LIBNL3_ROUTE
|
||||||
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
struct rtnl_neigh *rn;
|
||||||
|
struct nl_addr *nl_addr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
rn = rtnl_neigh_alloc();
|
||||||
|
if (!rn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rtnl_neigh_set_family(rn, AF_BRIDGE);
|
||||||
|
rtnl_neigh_set_ifindex(rn, bss->ifindex);
|
||||||
|
nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN);
|
||||||
|
if (!nl_addr) {
|
||||||
|
rtnl_neigh_put(rn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rtnl_neigh_set_lladdr(rn, nl_addr);
|
||||||
|
|
||||||
|
err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
|
||||||
|
if (err < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
|
||||||
|
MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
|
||||||
|
bss->ifindex, nl_geterror(err));
|
||||||
|
} else {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: deleted bridge FDB entry for "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
nl_addr_put(nl_addr);
|
||||||
|
rtnl_neigh_put(rn);
|
||||||
|
#endif /* CONFIG_LIBNL3_ROUTE */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr)
|
static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr)
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
@ -7771,6 +7815,10 @@ static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr)
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
|
wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
|
||||||
" --> %d (%s)",
|
" --> %d (%s)",
|
||||||
bss->ifname, MAC2STR(addr), ret, strerror(-ret));
|
bss->ifname, MAC2STR(addr), ret, strerror(-ret));
|
||||||
|
|
||||||
|
if (drv->rtnl_sk)
|
||||||
|
rtnl_neigh_delete_fdb_entry(bss, addr);
|
||||||
|
|
||||||
if (ret == -ENOENT)
|
if (ret == -ENOENT)
|
||||||
return 0;
|
return 0;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -10054,6 +10102,22 @@ static void *i802_init(struct hostapd_data *hapd,
|
||||||
i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
|
i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBNL3_ROUTE
|
||||||
|
if (bss->added_if_into_bridge) {
|
||||||
|
drv->rtnl_sk = nl_socket_alloc();
|
||||||
|
if (drv->rtnl_sk == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nl_connect(drv->rtnl_sk, NETLINK_ROUTE)) {
|
||||||
|
wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
|
||||||
|
strerror(errno));
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_LIBNL3_ROUTE */
|
||||||
|
|
||||||
drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
|
drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
|
||||||
if (drv->eapol_sock < 0) {
|
if (drv->eapol_sock < 0) {
|
||||||
wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
|
wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
|
||||||
|
|
|
@ -36,6 +36,10 @@ ifdef CONFIG_LIBNL32
|
||||||
DRV_LIBS += -lnl-3
|
DRV_LIBS += -lnl-3
|
||||||
DRV_LIBS += -lnl-genl-3
|
DRV_LIBS += -lnl-genl-3
|
||||||
DRV_CFLAGS += -DCONFIG_LIBNL20 -I/usr/include/libnl3
|
DRV_CFLAGS += -DCONFIG_LIBNL20 -I/usr/include/libnl3
|
||||||
|
ifdef CONFIG_LIBNL3_ROUTE
|
||||||
|
DRV_LIBS += -lnl-route-3
|
||||||
|
DRV_CFLAGS += -DCONFIG_LIBNL3_ROUTE
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
ifdef CONFIG_LIBNL_TINY
|
ifdef CONFIG_LIBNL_TINY
|
||||||
DRV_LIBS += -lnl-tiny
|
DRV_LIBS += -lnl-tiny
|
||||||
|
|
|
@ -31,6 +31,10 @@ ifdef CONFIG_LIBNL32
|
||||||
DRV_LIBS += -lnl-3
|
DRV_LIBS += -lnl-3
|
||||||
DRV_LIBS += -lnl-genl-3
|
DRV_LIBS += -lnl-genl-3
|
||||||
DRV_CFLAGS += -DCONFIG_LIBNL20 -I/usr/include/libnl3
|
DRV_CFLAGS += -DCONFIG_LIBNL20 -I/usr/include/libnl3
|
||||||
|
ifdef CONFIG_LIBNL3_ROUTE
|
||||||
|
DRV_LIBS += -lnl-route-3
|
||||||
|
DRV_CFLAGS += -DCONFIG_LIBNL3_ROUTE
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
ifdef CONFIG_LIBNL_TINY
|
ifdef CONFIG_LIBNL_TINY
|
||||||
DRV_LIBS += -lnl-tiny
|
DRV_LIBS += -lnl-tiny
|
||||||
|
|
Loading…
Reference in a new issue