blob: ade0b1131105e74669a32216df7c0a19f3e7b563 [file] [log] [blame]
developer7b43f2d2022-04-29 17:53:25 +08001From: Felix Fietkau <nbd@nbd.name>
2Date: Wed, 28 Jul 2021 05:49:46 +0200
3Subject: [PATCH] driver_nl80211: rewrite neigh code to not depend on
4 libnl3-route
5
6Removes an unnecessary dependency and also makes the code smaller
7
8Signed-off-by: Felix Fietkau <nbd@nbd.name>
9---
10
11--- a/src/drivers/driver_nl80211.c
12+++ b/src/drivers/driver_nl80211.c
13@@ -16,9 +16,6 @@
14 #include <net/if.h>
15 #include <netlink/genl/genl.h>
16 #include <netlink/genl/ctrl.h>
17-#ifdef CONFIG_LIBNL3_ROUTE
18-#include <netlink/route/neighbour.h>
19-#endif /* CONFIG_LIBNL3_ROUTE */
20 #include <linux/rtnetlink.h>
21 #include <netpacket/packet.h>
22 #include <linux/errqueue.h>
23@@ -5300,26 +5297,29 @@ fail:
24
25 static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
26 {
27-#ifdef CONFIG_LIBNL3_ROUTE
28 struct wpa_driver_nl80211_data *drv = bss->drv;
29- struct rtnl_neigh *rn;
30- struct nl_addr *nl_addr;
31+ struct ndmsg nhdr = {
32+ .ndm_state = NUD_PERMANENT,
33+ .ndm_ifindex = bss->ifindex,
34+ .ndm_family = AF_BRIDGE,
35+ };
36+ struct nl_msg *msg;
37 int err;
38
39- rn = rtnl_neigh_alloc();
40- if (!rn)
41+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
42+ if (!msg)
43 return;
44
45- rtnl_neigh_set_family(rn, AF_BRIDGE);
46- rtnl_neigh_set_ifindex(rn, bss->ifindex);
47- nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN);
48- if (!nl_addr) {
49- rtnl_neigh_put(rn);
50- return;
51- }
52- rtnl_neigh_set_lladdr(rn, nl_addr);
53+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
54+ goto errout;
55+
56+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr))
57+ goto errout;
58+
59+ if (nl_send_auto_complete(drv->rtnl_sk, msg) < 0)
60+ goto errout;
61
62- err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
63+ err = nl_wait_for_ack(drv->rtnl_sk);
64 if (err < 0) {
65 wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
66 MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
67@@ -5329,9 +5329,8 @@ static void rtnl_neigh_delete_fdb_entry(
68 MACSTR, MAC2STR(addr));
69 }
70
71- nl_addr_put(nl_addr);
72- rtnl_neigh_put(rn);
73-#endif /* CONFIG_LIBNL3_ROUTE */
74+errout:
75+ nlmsg_free(msg);
76 }
77
78
79@@ -7714,7 +7713,6 @@ static void *i802_init(struct hostapd_da
80 (params->num_bridge == 0 || !params->bridge[0]))
81 add_ifidx(drv, br_ifindex, drv->ifindex);
82
83-#ifdef CONFIG_LIBNL3_ROUTE
84 if (bss->added_if_into_bridge || bss->already_in_bridge) {
85 int err;
86
87@@ -7731,7 +7729,6 @@ static void *i802_init(struct hostapd_da
88 goto failed;
89 }
90 }
91-#endif /* CONFIG_LIBNL3_ROUTE */
92
93 if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
94 wpa_printf(MSG_DEBUG,
95@@ -10678,13 +10675,14 @@ static int wpa_driver_br_add_ip_neigh(vo
96 const u8 *ipaddr, int prefixlen,
97 const u8 *addr)
98 {
99-#ifdef CONFIG_LIBNL3_ROUTE
100 struct i802_bss *bss = priv;
101 struct wpa_driver_nl80211_data *drv = bss->drv;
102- struct rtnl_neigh *rn;
103- struct nl_addr *nl_ipaddr = NULL;
104- struct nl_addr *nl_lladdr = NULL;
105- int family, addrsize;
106+ struct ndmsg nhdr = {
107+ .ndm_state = NUD_PERMANENT,
108+ .ndm_ifindex = bss->br_ifindex,
109+ };
110+ struct nl_msg *msg;
111+ int addrsize;
112 int res;
113
114 if (!ipaddr || prefixlen == 0 || !addr)
115@@ -10703,85 +10701,66 @@ static int wpa_driver_br_add_ip_neigh(vo
116 }
117
118 if (version == 4) {
119- family = AF_INET;
120+ nhdr.ndm_family = AF_INET;
121 addrsize = 4;
122 } else if (version == 6) {
123- family = AF_INET6;
124+ nhdr.ndm_family = AF_INET6;
125 addrsize = 16;
126 } else {
127 return -EINVAL;
128 }
129
130- rn = rtnl_neigh_alloc();
131- if (rn == NULL)
132+ msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE);
133+ if (!msg)
134 return -ENOMEM;
135
136- /* set the destination ip address for neigh */
137- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
138- if (nl_ipaddr == NULL) {
139- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
140- res = -ENOMEM;
141+ res = -ENOMEM;
142+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
143 goto errout;
144- }
145- nl_addr_set_prefixlen(nl_ipaddr, prefixlen);
146- res = rtnl_neigh_set_dst(rn, nl_ipaddr);
147- if (res) {
148- wpa_printf(MSG_DEBUG,
149- "nl80211: neigh set destination addr failed");
150+
151+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr))
152 goto errout;
153- }
154
155- /* set the corresponding lladdr for neigh */
156- nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN);
157- if (nl_lladdr == NULL) {
158- wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed");
159- res = -ENOMEM;
160+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr))
161 goto errout;
162- }
163- rtnl_neigh_set_lladdr(rn, nl_lladdr);
164
165- rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
166- rtnl_neigh_set_state(rn, NUD_PERMANENT);
167+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
168+ if (res < 0)
169+ goto errout;
170
171- res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE);
172+ res = nl_wait_for_ack(drv->rtnl_sk);
173 if (res) {
174 wpa_printf(MSG_DEBUG,
175 "nl80211: Adding bridge ip neigh failed: %s",
176 nl_geterror(res));
177 }
178 errout:
179- if (nl_lladdr)
180- nl_addr_put(nl_lladdr);
181- if (nl_ipaddr)
182- nl_addr_put(nl_ipaddr);
183- if (rn)
184- rtnl_neigh_put(rn);
185+ nlmsg_free(msg);
186 return res;
187-#else /* CONFIG_LIBNL3_ROUTE */
188- return -1;
189-#endif /* CONFIG_LIBNL3_ROUTE */
190 }
191
192
193 static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
194 const u8 *ipaddr)
195 {
196-#ifdef CONFIG_LIBNL3_ROUTE
197 struct i802_bss *bss = priv;
198 struct wpa_driver_nl80211_data *drv = bss->drv;
199- struct rtnl_neigh *rn;
200- struct nl_addr *nl_ipaddr;
201- int family, addrsize;
202+ struct ndmsg nhdr = {
203+ .ndm_state = NUD_PERMANENT,
204+ .ndm_ifindex = bss->br_ifindex,
205+ };
206+ struct nl_msg *msg;
207+ int addrsize;
208 int res;
209
210 if (!ipaddr)
211 return -EINVAL;
212
213 if (version == 4) {
214- family = AF_INET;
215+ nhdr.ndm_family = AF_INET;
216 addrsize = 4;
217 } else if (version == 6) {
218- family = AF_INET6;
219+ nhdr.ndm_family = AF_INET6;
220 addrsize = 16;
221 } else {
222 return -EINVAL;
223@@ -10799,41 +10778,30 @@ static int wpa_driver_br_delete_ip_neigh
224 return -1;
225 }
226
227- rn = rtnl_neigh_alloc();
228- if (rn == NULL)
229+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
230+ if (!msg)
231 return -ENOMEM;
232
233- /* set the destination ip address for neigh */
234- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
235- if (nl_ipaddr == NULL) {
236- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
237- res = -ENOMEM;
238+ res = -ENOMEM;
239+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
240 goto errout;
241- }
242- res = rtnl_neigh_set_dst(rn, nl_ipaddr);
243- if (res) {
244- wpa_printf(MSG_DEBUG,
245- "nl80211: neigh set destination addr failed");
246+
247+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr))
248 goto errout;
249- }
250
251- rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
252+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
253+ if (res < 0)
254+ goto errout;
255
256- res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
257+ res = nl_wait_for_ack(drv->rtnl_sk);
258 if (res) {
259 wpa_printf(MSG_DEBUG,
260 "nl80211: Deleting bridge ip neigh failed: %s",
261 nl_geterror(res));
262 }
263 errout:
264- if (nl_ipaddr)
265- nl_addr_put(nl_ipaddr);
266- if (rn)
267- rtnl_neigh_put(rn);
268+ nlmsg_free(msg);
269 return res;
270-#else /* CONFIG_LIBNL3_ROUTE */
271- return -1;
272-#endif /* CONFIG_LIBNL3_ROUTE */
273 }
274
275