mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-08-08 20:03:41 +08:00
hostapd: sync upstream (#7549)
* hostapd: make the snooping interface (for proxyarp) configurable Use the VLAN interface instead of the bridge, to ensure that hostapd receives untagged DHCP packets Signed-off-by: Felix Fietkau <nbd@nbd.name> * hostapd: fix a segfault on sta disconnect with proxy arp enabled Signed-off-by: Felix Fietkau <nbd@nbd.name> * hostapd: make proxyarp work with libnl-tiny Remove a dependency on libnl3-route Signed-off-by: Felix Fietkau <nbd@nbd.name> Co-authored-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
b01a5f922a
commit
3c6aadc40e
@ -756,6 +756,7 @@ hostapd_set_bss_options() {
|
||||
|
||||
append bss_conf "ssid=$ssid" "$N"
|
||||
[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
|
||||
[ -n "$network_ifname" ] && append bss_conf "snoop_iface=$network_ifname" "$N"
|
||||
[ -n "$iapp_interface" ] && {
|
||||
local ifname
|
||||
network_get_device ifname "$iapp_interface" || ifname="$iapp_interface"
|
||||
|
@ -0,0 +1,19 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 28 Jul 2021 05:43:29 +0200
|
||||
Subject: [PATCH] ndisc_snoop: call dl_list_del before freeing ipv6 addresses
|
||||
|
||||
Fixes a segmentation fault on sta disconnect
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/src/ap/ndisc_snoop.c
|
||||
+++ b/src/ap/ndisc_snoop.c
|
||||
@@ -61,6 +61,7 @@ void sta_ip6addr_del(struct hostapd_data
|
||||
dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr,
|
||||
list) {
|
||||
hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr);
|
||||
+ dl_list_del(&ip6addr->list);
|
||||
os_free(ip6addr);
|
||||
}
|
||||
}
|
@ -0,0 +1,275 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 28 Jul 2021 05:49:46 +0200
|
||||
Subject: [PATCH] driver_nl80211: rewrite neigh code to not depend on
|
||||
libnl3-route
|
||||
|
||||
Removes an unnecessary dependency and also makes the code smaller
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -16,9 +16,6 @@
|
||||
#include <net/if.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
-#include <netlink/route/neighbour.h>
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/errqueue.h>
|
||||
@@ -5284,26 +5281,29 @@ fail:
|
||||
|
||||
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;
|
||||
+ struct ndmsg nhdr = {
|
||||
+ .ndm_state = NUD_PERMANENT,
|
||||
+ .ndm_ifindex = bss->ifindex,
|
||||
+ .ndm_family = AF_BRIDGE,
|
||||
+ };
|
||||
+ struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
- rn = rtnl_neigh_alloc();
|
||||
- if (!rn)
|
||||
+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
|
||||
+ if (!msg)
|
||||
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);
|
||||
+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
|
||||
+ goto errout;
|
||||
+
|
||||
+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr))
|
||||
+ goto errout;
|
||||
+
|
||||
+ if (nl_send_auto_complete(drv->rtnl_sk, msg) < 0)
|
||||
+ goto errout;
|
||||
|
||||
- err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
|
||||
+ err = nl_wait_for_ack(drv->rtnl_sk);
|
||||
if (err < 0) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
|
||||
MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
|
||||
@@ -5313,9 +5313,8 @@ static void rtnl_neigh_delete_fdb_entry(
|
||||
MACSTR, MAC2STR(addr));
|
||||
}
|
||||
|
||||
- nl_addr_put(nl_addr);
|
||||
- rtnl_neigh_put(rn);
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
+errout:
|
||||
+ nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -7691,7 +7690,6 @@ static void *i802_init(struct hostapd_da
|
||||
(params->num_bridge == 0 || !params->bridge[0]))
|
||||
add_ifidx(drv, br_ifindex, drv->ifindex);
|
||||
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
if (bss->added_if_into_bridge || bss->already_in_bridge) {
|
||||
int err;
|
||||
|
||||
@@ -7708,7 +7706,6 @@ static void *i802_init(struct hostapd_da
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
|
||||
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
@@ -10655,13 +10652,14 @@ static int wpa_driver_br_add_ip_neigh(vo
|
||||
const u8 *ipaddr, int prefixlen,
|
||||
const u8 *addr)
|
||||
{
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
- struct rtnl_neigh *rn;
|
||||
- struct nl_addr *nl_ipaddr = NULL;
|
||||
- struct nl_addr *nl_lladdr = NULL;
|
||||
- int family, addrsize;
|
||||
+ struct ndmsg nhdr = {
|
||||
+ .ndm_state = NUD_PERMANENT,
|
||||
+ .ndm_ifindex = bss->br_ifindex,
|
||||
+ };
|
||||
+ struct nl_msg *msg;
|
||||
+ int addrsize;
|
||||
int res;
|
||||
|
||||
if (!ipaddr || prefixlen == 0 || !addr)
|
||||
@@ -10680,85 +10678,66 @@ static int wpa_driver_br_add_ip_neigh(vo
|
||||
}
|
||||
|
||||
if (version == 4) {
|
||||
- family = AF_INET;
|
||||
+ nhdr.ndm_family = AF_INET;
|
||||
addrsize = 4;
|
||||
} else if (version == 6) {
|
||||
- family = AF_INET6;
|
||||
+ nhdr.ndm_family = AF_INET6;
|
||||
addrsize = 16;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- rn = rtnl_neigh_alloc();
|
||||
- if (rn == NULL)
|
||||
+ msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE);
|
||||
+ if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
- /* set the destination ip address for neigh */
|
||||
- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
|
||||
- if (nl_ipaddr == NULL) {
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
|
||||
- res = -ENOMEM;
|
||||
+ res = -ENOMEM;
|
||||
+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
|
||||
goto errout;
|
||||
- }
|
||||
- nl_addr_set_prefixlen(nl_ipaddr, prefixlen);
|
||||
- res = rtnl_neigh_set_dst(rn, nl_ipaddr);
|
||||
- if (res) {
|
||||
- wpa_printf(MSG_DEBUG,
|
||||
- "nl80211: neigh set destination addr failed");
|
||||
+
|
||||
+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr))
|
||||
goto errout;
|
||||
- }
|
||||
|
||||
- /* set the corresponding lladdr for neigh */
|
||||
- nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN);
|
||||
- if (nl_lladdr == NULL) {
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed");
|
||||
- res = -ENOMEM;
|
||||
+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr))
|
||||
goto errout;
|
||||
- }
|
||||
- rtnl_neigh_set_lladdr(rn, nl_lladdr);
|
||||
|
||||
- rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
|
||||
- rtnl_neigh_set_state(rn, NUD_PERMANENT);
|
||||
+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
|
||||
+ if (res < 0)
|
||||
+ goto errout;
|
||||
|
||||
- res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE);
|
||||
+ res = nl_wait_for_ack(drv->rtnl_sk);
|
||||
if (res) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Adding bridge ip neigh failed: %s",
|
||||
nl_geterror(res));
|
||||
}
|
||||
errout:
|
||||
- if (nl_lladdr)
|
||||
- nl_addr_put(nl_lladdr);
|
||||
- if (nl_ipaddr)
|
||||
- nl_addr_put(nl_ipaddr);
|
||||
- if (rn)
|
||||
- rtnl_neigh_put(rn);
|
||||
+ nlmsg_free(msg);
|
||||
return res;
|
||||
-#else /* CONFIG_LIBNL3_ROUTE */
|
||||
- return -1;
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
}
|
||||
|
||||
|
||||
static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
|
||||
const u8 *ipaddr)
|
||||
{
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
- struct rtnl_neigh *rn;
|
||||
- struct nl_addr *nl_ipaddr;
|
||||
- int family, addrsize;
|
||||
+ struct ndmsg nhdr = {
|
||||
+ .ndm_state = NUD_PERMANENT,
|
||||
+ .ndm_ifindex = bss->br_ifindex,
|
||||
+ };
|
||||
+ struct nl_msg *msg;
|
||||
+ int addrsize;
|
||||
int res;
|
||||
|
||||
if (!ipaddr)
|
||||
return -EINVAL;
|
||||
|
||||
if (version == 4) {
|
||||
- family = AF_INET;
|
||||
+ nhdr.ndm_family = AF_INET;
|
||||
addrsize = 4;
|
||||
} else if (version == 6) {
|
||||
- family = AF_INET6;
|
||||
+ nhdr.ndm_family = AF_INET6;
|
||||
addrsize = 16;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
@@ -10776,41 +10755,30 @@ static int wpa_driver_br_delete_ip_neigh
|
||||
return -1;
|
||||
}
|
||||
|
||||
- rn = rtnl_neigh_alloc();
|
||||
- if (rn == NULL)
|
||||
+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
|
||||
+ if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
- /* set the destination ip address for neigh */
|
||||
- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
|
||||
- if (nl_ipaddr == NULL) {
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
|
||||
- res = -ENOMEM;
|
||||
+ res = -ENOMEM;
|
||||
+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
|
||||
goto errout;
|
||||
- }
|
||||
- res = rtnl_neigh_set_dst(rn, nl_ipaddr);
|
||||
- if (res) {
|
||||
- wpa_printf(MSG_DEBUG,
|
||||
- "nl80211: neigh set destination addr failed");
|
||||
+
|
||||
+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr))
|
||||
goto errout;
|
||||
- }
|
||||
|
||||
- rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
|
||||
+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
|
||||
+ if (res < 0)
|
||||
+ goto errout;
|
||||
|
||||
- res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
|
||||
+ res = nl_wait_for_ack(drv->rtnl_sk);
|
||||
if (res) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Deleting bridge ip neigh failed: %s",
|
||||
nl_geterror(res));
|
||||
}
|
||||
errout:
|
||||
- if (nl_ipaddr)
|
||||
- nl_addr_put(nl_ipaddr);
|
||||
- if (rn)
|
||||
- rtnl_neigh_put(rn);
|
||||
+ nlmsg_free(msg);
|
||||
return res;
|
||||
-#else /* CONFIG_LIBNL3_ROUTE */
|
||||
- return -1;
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -278,6 +278,7 @@ struct hostapd_bss_config {
|
||||
char iface[IFNAMSIZ + 1];
|
||||
char bridge[IFNAMSIZ + 1];
|
||||
char ft_iface[IFNAMSIZ + 1];
|
||||
+ char snoop_iface[IFNAMSIZ + 1];
|
||||
char vlan_bridge[IFNAMSIZ + 1];
|
||||
char wds_bridge[IFNAMSIZ + 1];
|
||||
|
||||
--- a/src/ap/x_snoop.c
|
||||
+++ b/src/ap/x_snoop.c
|
||||
@@ -71,6 +71,10 @@ x_snoop_get_l2_packet(struct hostapd_dat
|
||||
{
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
struct l2_packet_data *l2;
|
||||
+ const char *ifname = conf->bridge;
|
||||
+
|
||||
+ if (conf->snoop_iface[0])
|
||||
+ ifname = conf->snoop_iface;
|
||||
|
||||
l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1);
|
||||
if (l2 == NULL) {
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho
|
||||
sizeof(conf->bss[0]->iface));
|
||||
} else if (os_strcmp(buf, "bridge") == 0) {
|
||||
os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
|
||||
+ } else if (os_strcmp(buf, "snoop_iface") == 0) {
|
||||
+ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface));
|
||||
} else if (os_strcmp(buf, "vlan_bridge") == 0) {
|
||||
os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
|
||||
} else if (os_strcmp(buf, "wds_bridge") == 0) {
|
Loading…
x
Reference in New Issue
Block a user