From: Felix Fietkau 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 --- --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -16,9 +16,6 @@ #include #include #include -#ifdef CONFIG_LIBNL3_ROUTE -#include -#endif /* CONFIG_LIBNL3_ROUTE */ #include #include #include @@ -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 */ }