hostapd: make proxyarp work with libnl-tiny
authorFelix Fietkau <nbd@nbd.name>
Wed, 28 Jul 2021 03:54:29 +0000 (05:54 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 28 Jul 2021 03:55:11 +0000 (05:55 +0200)
Remove a dependency on libnl3-route

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch [new file with mode: 0644]

diff --git a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch
new file mode 100644 (file)
index 0000000..e8a78e3
--- /dev/null
@@ -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 */
+ }