ef2bb408fb28d90fa55132ea2deea9f5024bbcb2
[openwrt/staging/ldir.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Wed, 28 Jul 2021 05:49:46 +0200
3 Subject: [PATCH] driver_nl80211: rewrite neigh code to not depend on
4 libnl3-route
5
6 Removes an unnecessary dependency and also makes the code smaller
7
8 Signed-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 @@ -5783,26 +5780,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 @@ -5812,9 +5812,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 @@ -8492,7 +8491,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 @@ -8509,7 +8507,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 @@ -11883,13 +11880,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 @@ -11908,85 +11906,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 @@ -12004,41 +11983,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