nl80211: Rewrite neigh code to not depend on libnl3-route

This removes an unnecessary dependency and also makes the code smaller.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Felix Fietkau 2024-04-04 12:52:14 +02:00 committed by Jouni Malinen
parent 3ef0579013
commit a210fdb1c7
3 changed files with 52 additions and 96 deletions

View file

@ -18,9 +18,6 @@
#include <netlink/genl/genl.h> #include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h> #include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h> #include <netlink/genl/family.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/errqueue.h> #include <linux/errqueue.h>
@ -5858,26 +5855,25 @@ fail:
static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) 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 wpa_driver_nl80211_data *drv = bss->drv;
struct rtnl_neigh *rn; struct ndmsg nhdr = {
struct nl_addr *nl_addr; .ndm_state = NUD_PERMANENT,
.ndm_ifindex = bss->ifindex,
.ndm_family = AF_BRIDGE,
};
struct nl_msg *msg;
int err; int err;
rn = rtnl_neigh_alloc(); msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
if (!rn) if (!msg)
return; return;
rtnl_neigh_set_family(rn, AF_BRIDGE); if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0 ||
rtnl_neigh_set_ifindex(rn, bss->ifindex); nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *) addr) ||
nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN); nl_send_auto_complete(drv->rtnl_sk, msg) < 0)
if (!nl_addr) { goto errout;
rtnl_neigh_put(rn);
return;
}
rtnl_neigh_set_lladdr(rn, nl_addr);
err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); err = nl_wait_for_ack(drv->rtnl_sk);
if (err < 0) { if (err < 0) {
wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
MACSTR " ifindex=%d failed: %s", MAC2STR(addr), MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
@ -5887,9 +5883,8 @@ static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
MACSTR, MAC2STR(addr)); MACSTR, MAC2STR(addr));
} }
nl_addr_put(nl_addr); errout:
rtnl_neigh_put(rn); nlmsg_free(msg);
#endif /* CONFIG_LIBNL3_ROUTE */
} }
@ -8614,7 +8609,6 @@ static void *i802_init(struct hostapd_data *hapd,
(params->num_bridge == 0 || !params->bridge[0])) (params->num_bridge == 0 || !params->bridge[0]))
add_ifidx(drv, br_ifindex, drv->ifindex); add_ifidx(drv, br_ifindex, drv->ifindex);
#ifdef CONFIG_LIBNL3_ROUTE
if (bss->added_if_into_bridge || bss->already_in_bridge) { if (bss->added_if_into_bridge || bss->already_in_bridge) {
int err; int err;
@ -8631,7 +8625,6 @@ static void *i802_init(struct hostapd_data *hapd,
goto failed; goto failed;
} }
} }
#endif /* CONFIG_LIBNL3_ROUTE */
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
@ -12146,13 +12139,14 @@ static int wpa_driver_br_add_ip_neigh(void *priv, u8 version,
const u8 *ipaddr, int prefixlen, const u8 *ipaddr, int prefixlen,
const u8 *addr) const u8 *addr)
{ {
#ifdef CONFIG_LIBNL3_ROUTE
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
struct rtnl_neigh *rn; struct ndmsg nhdr = {
struct nl_addr *nl_ipaddr = NULL; .ndm_state = NUD_PERMANENT,
struct nl_addr *nl_lladdr = NULL; .ndm_ifindex = bss->br_ifindex,
int family, addrsize; };
struct nl_msg *msg;
int addrsize;
int res; int res;
if (!ipaddr || prefixlen == 0 || !addr) if (!ipaddr || prefixlen == 0 || !addr)
@ -12171,85 +12165,62 @@ static int wpa_driver_br_add_ip_neigh(void *priv, u8 version,
} }
if (version == 4) { if (version == 4) {
family = AF_INET; nhdr.ndm_family = AF_INET;
addrsize = 4; addrsize = 4;
} else if (version == 6) { } else if (version == 6) {
family = AF_INET6; nhdr.ndm_family = AF_INET6;
addrsize = 16; addrsize = 16;
} else { } else {
return -EINVAL; return -EINVAL;
} }
rn = rtnl_neigh_alloc(); msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE);
if (rn == NULL) if (!msg)
return -ENOMEM; return -ENOMEM;
/* set the destination ip address for neigh */ res = -ENOMEM;
nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0 ||
if (nl_ipaddr == NULL) { nla_put(msg, NDA_DST, addrsize, (void *) ipaddr) ||
wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *) addr))
res = -ENOMEM;
goto errout; goto errout;
}
nl_addr_set_prefixlen(nl_ipaddr, prefixlen); res = nl_send_auto_complete(drv->rtnl_sk, msg);
res = rtnl_neigh_set_dst(rn, nl_ipaddr); if (res < 0)
if (res) {
wpa_printf(MSG_DEBUG,
"nl80211: neigh set destination addr failed");
goto errout; goto errout;
}
/* set the corresponding lladdr for neigh */ res = nl_wait_for_ack(drv->rtnl_sk);
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;
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 = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE);
if (res) { if (res) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: Adding bridge ip neigh failed: %s", "nl80211: Adding bridge ip neigh failed: %s",
nl_geterror(res)); nl_geterror(res));
} }
errout: errout:
if (nl_lladdr) nlmsg_free(msg);
nl_addr_put(nl_lladdr);
if (nl_ipaddr)
nl_addr_put(nl_ipaddr);
if (rn)
rtnl_neigh_put(rn);
return res; return res;
#else /* CONFIG_LIBNL3_ROUTE */
return -1;
#endif /* CONFIG_LIBNL3_ROUTE */
} }
static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version, static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
const u8 *ipaddr) const u8 *ipaddr)
{ {
#ifdef CONFIG_LIBNL3_ROUTE
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
struct rtnl_neigh *rn; struct ndmsg nhdr = {
struct nl_addr *nl_ipaddr; .ndm_state = NUD_PERMANENT,
int family, addrsize; .ndm_ifindex = bss->br_ifindex,
};
struct nl_msg *msg;
int addrsize;
int res; int res;
if (!ipaddr) if (!ipaddr)
return -EINVAL; return -EINVAL;
if (version == 4) { if (version == 4) {
family = AF_INET; nhdr.ndm_family = AF_INET;
addrsize = 4; addrsize = 4;
} else if (version == 6) { } else if (version == 6) {
family = AF_INET6; nhdr.ndm_family = AF_INET6;
addrsize = 16; addrsize = 16;
} else { } else {
return -EINVAL; return -EINVAL;
@ -12267,41 +12238,28 @@ static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
return -1; return -1;
} }
rn = rtnl_neigh_alloc(); msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
if (rn == NULL) if (!msg)
return -ENOMEM; return -ENOMEM;
/* set the destination ip address for neigh */ res = -ENOMEM;
nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0 ||
if (nl_ipaddr == NULL) { nla_put(msg, NDA_DST, addrsize, (void *) ipaddr))
wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
res = -ENOMEM;
goto errout; goto errout;
}
res = rtnl_neigh_set_dst(rn, nl_ipaddr); res = nl_send_auto_complete(drv->rtnl_sk, msg);
if (res) { if (res < 0)
wpa_printf(MSG_DEBUG,
"nl80211: neigh set destination addr failed");
goto errout; goto errout;
}
rtnl_neigh_set_ifindex(rn, bss->br_ifindex); res = nl_wait_for_ack(drv->rtnl_sk);
res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
if (res) { if (res) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: Deleting bridge ip neigh failed: %s", "nl80211: Deleting bridge ip neigh failed: %s",
nl_geterror(res)); nl_geterror(res));
} }
errout: errout:
if (nl_ipaddr) nlmsg_free(msg);
nl_addr_put(nl_ipaddr);
if (rn)
rtnl_neigh_put(rn);
return res; return res;
#else /* CONFIG_LIBNL3_ROUTE */
return -1;
#endif /* CONFIG_LIBNL3_ROUTE */
} }

View file

@ -156,7 +156,6 @@ ifdef CONFIG_FULL_DYNAMIC_VLAN
NEED_LINUX_IOCTL=y NEED_LINUX_IOCTL=y
ifdef CONFIG_VLAN_NETLINK ifdef CONFIG_VLAN_NETLINK
NEED_LIBNL=y NEED_LIBNL=y
CONFIG_LIBNL3_ROUTE=y
endif endif
endif endif

View file

@ -151,7 +151,6 @@ ifdef CONFIG_FULL_DYNAMIC_VLAN
NEED_LINUX_IOCTL=y NEED_LINUX_IOCTL=y
ifdef CONFIG_VLAN_NETLINK ifdef CONFIG_VLAN_NETLINK
NEED_LIBNL=y NEED_LIBNL=y
CONFIG_LIBNL3_ROUTE=y
endif endif
endif endif