Commit e2d0d35b5b0ce420505e88255fd5922ed035bb8d

Authored by Sven Eckelmann
Committed by Simon Wunderlich
1 parent 3e15b06eb7

batman-adv: Add gateway mesh genl configuration

The mesh/soft-interface can optimize the handling of DHCP packets. Instead
of flooding them through the whole mesh, it can be forwarded as unicast to
a specific gateway server. The originator which injects the packets in the
mesh has to select (based on sel_class thresholds) a responsible gateway
server. This is done by switching this originator to the gw_mode client.
The servers announce their forwarding bandwidth (download/upload) when the
gw_mode server was selected.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the attributes:

* u8 BATADV_ATTR_GW_MODE (0 == off, 1 == client, 2 == server)
* u32 BATADV_ATTR_GW_BANDWIDTH_DOWN (in 100 kbit/s steps)
* u32 BATADV_ATTR_GW_BANDWIDTH_UP (in 100 kbit/s steps)
* u32 BATADV_ATTR_GW_SEL_CLASS

Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>

Showing 7 changed files with 135 additions and 8 deletions Inline Diff

include/uapi/linux/batman_adv.h
1 /* SPDX-License-Identifier: MIT */ 1 /* SPDX-License-Identifier: MIT */
2 /* Copyright (C) 2016-2019 B.A.T.M.A.N. contributors: 2 /* Copyright (C) 2016-2019 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Matthias Schiffer 4 * Matthias Schiffer
5 * 5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a 6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"), 7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation 8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the 10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions: 11 * Software is furnished to do so, subject to the following conditions:
12 * 12 *
13 * The above copyright notice and this permission notice shall be included in 13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software. 14 * all copies or substantial portions of the Software.
15 * 15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE. 22 * DEALINGS IN THE SOFTWARE.
23 */ 23 */
24 24
25 #ifndef _UAPI_LINUX_BATMAN_ADV_H_ 25 #ifndef _UAPI_LINUX_BATMAN_ADV_H_
26 #define _UAPI_LINUX_BATMAN_ADV_H_ 26 #define _UAPI_LINUX_BATMAN_ADV_H_
27 27
28 #define BATADV_NL_NAME "batadv" 28 #define BATADV_NL_NAME "batadv"
29 29
30 #define BATADV_NL_MCAST_GROUP_CONFIG "config" 30 #define BATADV_NL_MCAST_GROUP_CONFIG "config"
31 #define BATADV_NL_MCAST_GROUP_TPMETER "tpmeter" 31 #define BATADV_NL_MCAST_GROUP_TPMETER "tpmeter"
32 32
33 /** 33 /**
34 * enum batadv_tt_client_flags - TT client specific flags 34 * enum batadv_tt_client_flags - TT client specific flags
35 * 35 *
36 * Bits from 0 to 7 are called _remote flags_ because they are sent on the wire. 36 * Bits from 0 to 7 are called _remote flags_ because they are sent on the wire.
37 * Bits from 8 to 15 are called _local flags_ because they are used for local 37 * Bits from 8 to 15 are called _local flags_ because they are used for local
38 * computations only. 38 * computations only.
39 * 39 *
40 * Bits from 4 to 7 - a subset of remote flags - are ensured to be in sync with 40 * Bits from 4 to 7 - a subset of remote flags - are ensured to be in sync with
41 * the other nodes in the network. To achieve this goal these flags are included 41 * the other nodes in the network. To achieve this goal these flags are included
42 * in the TT CRC computation. 42 * in the TT CRC computation.
43 */ 43 */
44 enum batadv_tt_client_flags { 44 enum batadv_tt_client_flags {
45 /** 45 /**
46 * @BATADV_TT_CLIENT_DEL: the client has to be deleted from the table 46 * @BATADV_TT_CLIENT_DEL: the client has to be deleted from the table
47 */ 47 */
48 BATADV_TT_CLIENT_DEL = (1 << 0), 48 BATADV_TT_CLIENT_DEL = (1 << 0),
49 49
50 /** 50 /**
51 * @BATADV_TT_CLIENT_ROAM: the client roamed to/from another node and 51 * @BATADV_TT_CLIENT_ROAM: the client roamed to/from another node and
52 * the new update telling its new real location has not been 52 * the new update telling its new real location has not been
53 * received/sent yet 53 * received/sent yet
54 */ 54 */
55 BATADV_TT_CLIENT_ROAM = (1 << 1), 55 BATADV_TT_CLIENT_ROAM = (1 << 1),
56 56
57 /** 57 /**
58 * @BATADV_TT_CLIENT_WIFI: this client is connected through a wifi 58 * @BATADV_TT_CLIENT_WIFI: this client is connected through a wifi
59 * interface. This information is used by the "AP Isolation" feature 59 * interface. This information is used by the "AP Isolation" feature
60 */ 60 */
61 BATADV_TT_CLIENT_WIFI = (1 << 4), 61 BATADV_TT_CLIENT_WIFI = (1 << 4),
62 62
63 /** 63 /**
64 * @BATADV_TT_CLIENT_ISOLA: this client is considered "isolated". This 64 * @BATADV_TT_CLIENT_ISOLA: this client is considered "isolated". This
65 * information is used by the Extended Isolation feature 65 * information is used by the Extended Isolation feature
66 */ 66 */
67 BATADV_TT_CLIENT_ISOLA = (1 << 5), 67 BATADV_TT_CLIENT_ISOLA = (1 << 5),
68 68
69 /** 69 /**
70 * @BATADV_TT_CLIENT_NOPURGE: this client should never be removed from 70 * @BATADV_TT_CLIENT_NOPURGE: this client should never be removed from
71 * the table 71 * the table
72 */ 72 */
73 BATADV_TT_CLIENT_NOPURGE = (1 << 8), 73 BATADV_TT_CLIENT_NOPURGE = (1 << 8),
74 74
75 /** 75 /**
76 * @BATADV_TT_CLIENT_NEW: this client has been added to the local table 76 * @BATADV_TT_CLIENT_NEW: this client has been added to the local table
77 * but has not been announced yet 77 * but has not been announced yet
78 */ 78 */
79 BATADV_TT_CLIENT_NEW = (1 << 9), 79 BATADV_TT_CLIENT_NEW = (1 << 9),
80 80
81 /** 81 /**
82 * @BATADV_TT_CLIENT_PENDING: this client is marked for removal but it 82 * @BATADV_TT_CLIENT_PENDING: this client is marked for removal but it
83 * is kept in the table for one more originator interval for consistency 83 * is kept in the table for one more originator interval for consistency
84 * purposes 84 * purposes
85 */ 85 */
86 BATADV_TT_CLIENT_PENDING = (1 << 10), 86 BATADV_TT_CLIENT_PENDING = (1 << 10),
87 87
88 /** 88 /**
89 * @BATADV_TT_CLIENT_TEMP: this global client has been detected to be 89 * @BATADV_TT_CLIENT_TEMP: this global client has been detected to be
90 * part of the network but no nnode has already announced it 90 * part of the network but no nnode has already announced it
91 */ 91 */
92 BATADV_TT_CLIENT_TEMP = (1 << 11), 92 BATADV_TT_CLIENT_TEMP = (1 << 11),
93 }; 93 };
94 94
95 /** 95 /**
96 * enum batadv_mcast_flags_priv - Private, own multicast flags 96 * enum batadv_mcast_flags_priv - Private, own multicast flags
97 * 97 *
98 * These are internal, multicast related flags. Currently they describe certain 98 * These are internal, multicast related flags. Currently they describe certain
99 * multicast related attributes of the segment this originator bridges into the 99 * multicast related attributes of the segment this originator bridges into the
100 * mesh. 100 * mesh.
101 * 101 *
102 * Those attributes are used to determine the public multicast flags this 102 * Those attributes are used to determine the public multicast flags this
103 * originator is going to announce via TT. 103 * originator is going to announce via TT.
104 * 104 *
105 * For netlink, if BATADV_MCAST_FLAGS_BRIDGED is unset then all querier 105 * For netlink, if BATADV_MCAST_FLAGS_BRIDGED is unset then all querier
106 * related flags are undefined. 106 * related flags are undefined.
107 */ 107 */
108 enum batadv_mcast_flags_priv { 108 enum batadv_mcast_flags_priv {
109 /** 109 /**
110 * @BATADV_MCAST_FLAGS_BRIDGED: There is a bridge on top of the mesh 110 * @BATADV_MCAST_FLAGS_BRIDGED: There is a bridge on top of the mesh
111 * interface. 111 * interface.
112 */ 112 */
113 BATADV_MCAST_FLAGS_BRIDGED = (1 << 0), 113 BATADV_MCAST_FLAGS_BRIDGED = (1 << 0),
114 114
115 /** 115 /**
116 * @BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS: Whether an IGMP querier 116 * @BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS: Whether an IGMP querier
117 * exists in the mesh 117 * exists in the mesh
118 */ 118 */
119 BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS = (1 << 1), 119 BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS = (1 << 1),
120 120
121 /** 121 /**
122 * @BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS: Whether an MLD querier 122 * @BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS: Whether an MLD querier
123 * exists in the mesh 123 * exists in the mesh
124 */ 124 */
125 BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS = (1 << 2), 125 BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS = (1 << 2),
126 126
127 /** 127 /**
128 * @BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING: If an IGMP querier 128 * @BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING: If an IGMP querier
129 * exists, whether it is potentially shadowing multicast listeners 129 * exists, whether it is potentially shadowing multicast listeners
130 * (i.e. querier is behind our own bridge segment) 130 * (i.e. querier is behind our own bridge segment)
131 */ 131 */
132 BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING = (1 << 3), 132 BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING = (1 << 3),
133 133
134 /** 134 /**
135 * @BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING: If an MLD querier 135 * @BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING: If an MLD querier
136 * exists, whether it is potentially shadowing multicast listeners 136 * exists, whether it is potentially shadowing multicast listeners
137 * (i.e. querier is behind our own bridge segment) 137 * (i.e. querier is behind our own bridge segment)
138 */ 138 */
139 BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING = (1 << 4), 139 BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING = (1 << 4),
140 }; 140 };
141 141
142 /** 142 /**
143 * enum batadv_gw_modes - gateway mode of node
144 */
145 enum batadv_gw_modes {
146 /** @BATADV_GW_MODE_OFF: gw mode disabled */
147 BATADV_GW_MODE_OFF,
148
149 /** @BATADV_GW_MODE_CLIENT: send DHCP requests to gw servers */
150 BATADV_GW_MODE_CLIENT,
151
152 /** @BATADV_GW_MODE_SERVER: announce itself as gatway server */
153 BATADV_GW_MODE_SERVER,
154 };
155
156 /**
143 * enum batadv_nl_attrs - batman-adv netlink attributes 157 * enum batadv_nl_attrs - batman-adv netlink attributes
144 */ 158 */
145 enum batadv_nl_attrs { 159 enum batadv_nl_attrs {
146 /** 160 /**
147 * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors 161 * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors
148 */ 162 */
149 BATADV_ATTR_UNSPEC, 163 BATADV_ATTR_UNSPEC,
150 164
151 /** 165 /**
152 * @BATADV_ATTR_VERSION: batman-adv version string 166 * @BATADV_ATTR_VERSION: batman-adv version string
153 */ 167 */
154 BATADV_ATTR_VERSION, 168 BATADV_ATTR_VERSION,
155 169
156 /** 170 /**
157 * @BATADV_ATTR_ALGO_NAME: name of routing algorithm 171 * @BATADV_ATTR_ALGO_NAME: name of routing algorithm
158 */ 172 */
159 BATADV_ATTR_ALGO_NAME, 173 BATADV_ATTR_ALGO_NAME,
160 174
161 /** 175 /**
162 * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface 176 * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface
163 */ 177 */
164 BATADV_ATTR_MESH_IFINDEX, 178 BATADV_ATTR_MESH_IFINDEX,
165 179
166 /** 180 /**
167 * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface 181 * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface
168 */ 182 */
169 BATADV_ATTR_MESH_IFNAME, 183 BATADV_ATTR_MESH_IFNAME,
170 184
171 /** 185 /**
172 * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface 186 * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface
173 */ 187 */
174 BATADV_ATTR_MESH_ADDRESS, 188 BATADV_ATTR_MESH_ADDRESS,
175 189
176 /** 190 /**
177 * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface 191 * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface
178 */ 192 */
179 BATADV_ATTR_HARD_IFINDEX, 193 BATADV_ATTR_HARD_IFINDEX,
180 194
181 /** 195 /**
182 * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface 196 * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface
183 */ 197 */
184 BATADV_ATTR_HARD_IFNAME, 198 BATADV_ATTR_HARD_IFNAME,
185 199
186 /** 200 /**
187 * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv 201 * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv
188 * interface 202 * interface
189 */ 203 */
190 BATADV_ATTR_HARD_ADDRESS, 204 BATADV_ATTR_HARD_ADDRESS,
191 205
192 /** 206 /**
193 * @BATADV_ATTR_ORIG_ADDRESS: originator mac address 207 * @BATADV_ATTR_ORIG_ADDRESS: originator mac address
194 */ 208 */
195 BATADV_ATTR_ORIG_ADDRESS, 209 BATADV_ATTR_ORIG_ADDRESS,
196 210
197 /** 211 /**
198 * @BATADV_ATTR_TPMETER_RESULT: result of run (see 212 * @BATADV_ATTR_TPMETER_RESULT: result of run (see
199 * batadv_tp_meter_status) 213 * batadv_tp_meter_status)
200 */ 214 */
201 BATADV_ATTR_TPMETER_RESULT, 215 BATADV_ATTR_TPMETER_RESULT,
202 216
203 /** 217 /**
204 * @BATADV_ATTR_TPMETER_TEST_TIME: time (msec) the run took 218 * @BATADV_ATTR_TPMETER_TEST_TIME: time (msec) the run took
205 */ 219 */
206 BATADV_ATTR_TPMETER_TEST_TIME, 220 BATADV_ATTR_TPMETER_TEST_TIME,
207 221
208 /** 222 /**
209 * @BATADV_ATTR_TPMETER_BYTES: amount of acked bytes during run 223 * @BATADV_ATTR_TPMETER_BYTES: amount of acked bytes during run
210 */ 224 */
211 BATADV_ATTR_TPMETER_BYTES, 225 BATADV_ATTR_TPMETER_BYTES,
212 226
213 /** 227 /**
214 * @BATADV_ATTR_TPMETER_COOKIE: session cookie to match tp_meter session 228 * @BATADV_ATTR_TPMETER_COOKIE: session cookie to match tp_meter session
215 */ 229 */
216 BATADV_ATTR_TPMETER_COOKIE, 230 BATADV_ATTR_TPMETER_COOKIE,
217 231
218 /** 232 /**
219 * @BATADV_ATTR_PAD: attribute used for padding for 64-bit alignment 233 * @BATADV_ATTR_PAD: attribute used for padding for 64-bit alignment
220 */ 234 */
221 BATADV_ATTR_PAD, 235 BATADV_ATTR_PAD,
222 236
223 /** 237 /**
224 * @BATADV_ATTR_ACTIVE: Flag indicating if the hard interface is active 238 * @BATADV_ATTR_ACTIVE: Flag indicating if the hard interface is active
225 */ 239 */
226 BATADV_ATTR_ACTIVE, 240 BATADV_ATTR_ACTIVE,
227 241
228 /** 242 /**
229 * @BATADV_ATTR_TT_ADDRESS: Client MAC address 243 * @BATADV_ATTR_TT_ADDRESS: Client MAC address
230 */ 244 */
231 BATADV_ATTR_TT_ADDRESS, 245 BATADV_ATTR_TT_ADDRESS,
232 246
233 /** 247 /**
234 * @BATADV_ATTR_TT_TTVN: Translation table version 248 * @BATADV_ATTR_TT_TTVN: Translation table version
235 */ 249 */
236 BATADV_ATTR_TT_TTVN, 250 BATADV_ATTR_TT_TTVN,
237 251
238 /** 252 /**
239 * @BATADV_ATTR_TT_LAST_TTVN: Previous translation table version 253 * @BATADV_ATTR_TT_LAST_TTVN: Previous translation table version
240 */ 254 */
241 BATADV_ATTR_TT_LAST_TTVN, 255 BATADV_ATTR_TT_LAST_TTVN,
242 256
243 /** 257 /**
244 * @BATADV_ATTR_TT_CRC32: CRC32 over translation table 258 * @BATADV_ATTR_TT_CRC32: CRC32 over translation table
245 */ 259 */
246 BATADV_ATTR_TT_CRC32, 260 BATADV_ATTR_TT_CRC32,
247 261
248 /** 262 /**
249 * @BATADV_ATTR_TT_VID: VLAN ID 263 * @BATADV_ATTR_TT_VID: VLAN ID
250 */ 264 */
251 BATADV_ATTR_TT_VID, 265 BATADV_ATTR_TT_VID,
252 266
253 /** 267 /**
254 * @BATADV_ATTR_TT_FLAGS: Translation table client flags 268 * @BATADV_ATTR_TT_FLAGS: Translation table client flags
255 */ 269 */
256 BATADV_ATTR_TT_FLAGS, 270 BATADV_ATTR_TT_FLAGS,
257 271
258 /** 272 /**
259 * @BATADV_ATTR_FLAG_BEST: Flags indicating entry is the best 273 * @BATADV_ATTR_FLAG_BEST: Flags indicating entry is the best
260 */ 274 */
261 BATADV_ATTR_FLAG_BEST, 275 BATADV_ATTR_FLAG_BEST,
262 276
263 /** 277 /**
264 * @BATADV_ATTR_LAST_SEEN_MSECS: Time in milliseconds since last seen 278 * @BATADV_ATTR_LAST_SEEN_MSECS: Time in milliseconds since last seen
265 */ 279 */
266 BATADV_ATTR_LAST_SEEN_MSECS, 280 BATADV_ATTR_LAST_SEEN_MSECS,
267 281
268 /** 282 /**
269 * @BATADV_ATTR_NEIGH_ADDRESS: Neighbour MAC address 283 * @BATADV_ATTR_NEIGH_ADDRESS: Neighbour MAC address
270 */ 284 */
271 BATADV_ATTR_NEIGH_ADDRESS, 285 BATADV_ATTR_NEIGH_ADDRESS,
272 286
273 /** 287 /**
274 * @BATADV_ATTR_TQ: TQ to neighbour 288 * @BATADV_ATTR_TQ: TQ to neighbour
275 */ 289 */
276 BATADV_ATTR_TQ, 290 BATADV_ATTR_TQ,
277 291
278 /** 292 /**
279 * @BATADV_ATTR_THROUGHPUT: Estimated throughput to Neighbour 293 * @BATADV_ATTR_THROUGHPUT: Estimated throughput to Neighbour
280 */ 294 */
281 BATADV_ATTR_THROUGHPUT, 295 BATADV_ATTR_THROUGHPUT,
282 296
283 /** 297 /**
284 * @BATADV_ATTR_BANDWIDTH_UP: Reported uplink bandwidth 298 * @BATADV_ATTR_BANDWIDTH_UP: Reported uplink bandwidth
285 */ 299 */
286 BATADV_ATTR_BANDWIDTH_UP, 300 BATADV_ATTR_BANDWIDTH_UP,
287 301
288 /** 302 /**
289 * @BATADV_ATTR_BANDWIDTH_DOWN: Reported downlink bandwidth 303 * @BATADV_ATTR_BANDWIDTH_DOWN: Reported downlink bandwidth
290 */ 304 */
291 BATADV_ATTR_BANDWIDTH_DOWN, 305 BATADV_ATTR_BANDWIDTH_DOWN,
292 306
293 /** 307 /**
294 * @BATADV_ATTR_ROUTER: Gateway router MAC address 308 * @BATADV_ATTR_ROUTER: Gateway router MAC address
295 */ 309 */
296 BATADV_ATTR_ROUTER, 310 BATADV_ATTR_ROUTER,
297 311
298 /** 312 /**
299 * @BATADV_ATTR_BLA_OWN: Flag indicating own originator 313 * @BATADV_ATTR_BLA_OWN: Flag indicating own originator
300 */ 314 */
301 BATADV_ATTR_BLA_OWN, 315 BATADV_ATTR_BLA_OWN,
302 316
303 /** 317 /**
304 * @BATADV_ATTR_BLA_ADDRESS: Bridge loop avoidance claim MAC address 318 * @BATADV_ATTR_BLA_ADDRESS: Bridge loop avoidance claim MAC address
305 */ 319 */
306 BATADV_ATTR_BLA_ADDRESS, 320 BATADV_ATTR_BLA_ADDRESS,
307 321
308 /** 322 /**
309 * @BATADV_ATTR_BLA_VID: BLA VLAN ID 323 * @BATADV_ATTR_BLA_VID: BLA VLAN ID
310 */ 324 */
311 BATADV_ATTR_BLA_VID, 325 BATADV_ATTR_BLA_VID,
312 326
313 /** 327 /**
314 * @BATADV_ATTR_BLA_BACKBONE: BLA gateway originator MAC address 328 * @BATADV_ATTR_BLA_BACKBONE: BLA gateway originator MAC address
315 */ 329 */
316 BATADV_ATTR_BLA_BACKBONE, 330 BATADV_ATTR_BLA_BACKBONE,
317 331
318 /** 332 /**
319 * @BATADV_ATTR_BLA_CRC: BLA CRC 333 * @BATADV_ATTR_BLA_CRC: BLA CRC
320 */ 334 */
321 BATADV_ATTR_BLA_CRC, 335 BATADV_ATTR_BLA_CRC,
322 336
323 /** 337 /**
324 * @BATADV_ATTR_DAT_CACHE_IP4ADDRESS: Client IPv4 address 338 * @BATADV_ATTR_DAT_CACHE_IP4ADDRESS: Client IPv4 address
325 */ 339 */
326 BATADV_ATTR_DAT_CACHE_IP4ADDRESS, 340 BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
327 341
328 /** 342 /**
329 * @BATADV_ATTR_DAT_CACHE_HWADDRESS: Client MAC address 343 * @BATADV_ATTR_DAT_CACHE_HWADDRESS: Client MAC address
330 */ 344 */
331 BATADV_ATTR_DAT_CACHE_HWADDRESS, 345 BATADV_ATTR_DAT_CACHE_HWADDRESS,
332 346
333 /** 347 /**
334 * @BATADV_ATTR_DAT_CACHE_VID: VLAN ID 348 * @BATADV_ATTR_DAT_CACHE_VID: VLAN ID
335 */ 349 */
336 BATADV_ATTR_DAT_CACHE_VID, 350 BATADV_ATTR_DAT_CACHE_VID,
337 351
338 /** 352 /**
339 * @BATADV_ATTR_MCAST_FLAGS: Per originator multicast flags 353 * @BATADV_ATTR_MCAST_FLAGS: Per originator multicast flags
340 */ 354 */
341 BATADV_ATTR_MCAST_FLAGS, 355 BATADV_ATTR_MCAST_FLAGS,
342 356
343 /** 357 /**
344 * @BATADV_ATTR_MCAST_FLAGS_PRIV: Private, own multicast flags 358 * @BATADV_ATTR_MCAST_FLAGS_PRIV: Private, own multicast flags
345 */ 359 */
346 BATADV_ATTR_MCAST_FLAGS_PRIV, 360 BATADV_ATTR_MCAST_FLAGS_PRIV,
347 361
348 /** 362 /**
349 * @BATADV_ATTR_VLANID: VLAN id on top of soft interface 363 * @BATADV_ATTR_VLANID: VLAN id on top of soft interface
350 */ 364 */
351 BATADV_ATTR_VLANID, 365 BATADV_ATTR_VLANID,
352 366
353 /** 367 /**
354 * @BATADV_ATTR_AGGREGATED_OGMS_ENABLED: whether the batman protocol 368 * @BATADV_ATTR_AGGREGATED_OGMS_ENABLED: whether the batman protocol
355 * messages of the mesh interface shall be aggregated or not. 369 * messages of the mesh interface shall be aggregated or not.
356 */ 370 */
357 BATADV_ATTR_AGGREGATED_OGMS_ENABLED, 371 BATADV_ATTR_AGGREGATED_OGMS_ENABLED,
358 372
359 /** 373 /**
360 * @BATADV_ATTR_AP_ISOLATION_ENABLED: whether the data traffic going 374 * @BATADV_ATTR_AP_ISOLATION_ENABLED: whether the data traffic going
361 * from a wireless client to another wireless client will be silently 375 * from a wireless client to another wireless client will be silently
362 * dropped. 376 * dropped.
363 */ 377 */
364 BATADV_ATTR_AP_ISOLATION_ENABLED, 378 BATADV_ATTR_AP_ISOLATION_ENABLED,
365 379
366 /** 380 /**
367 * @BATADV_ATTR_ISOLATION_MARK: the isolation mark which is used to 381 * @BATADV_ATTR_ISOLATION_MARK: the isolation mark which is used to
368 * classify clients as "isolated" by the Extended Isolation feature. 382 * classify clients as "isolated" by the Extended Isolation feature.
369 */ 383 */
370 BATADV_ATTR_ISOLATION_MARK, 384 BATADV_ATTR_ISOLATION_MARK,
371 385
372 /** 386 /**
373 * @BATADV_ATTR_ISOLATION_MASK: the isolation (bit)mask which is used to 387 * @BATADV_ATTR_ISOLATION_MASK: the isolation (bit)mask which is used to
374 * classify clients as "isolated" by the Extended Isolation feature. 388 * classify clients as "isolated" by the Extended Isolation feature.
375 */ 389 */
376 BATADV_ATTR_ISOLATION_MASK, 390 BATADV_ATTR_ISOLATION_MASK,
377 391
378 /** 392 /**
379 * @BATADV_ATTR_BONDING_ENABLED: whether the data traffic going through 393 * @BATADV_ATTR_BONDING_ENABLED: whether the data traffic going through
380 * the mesh will be sent using multiple interfaces at the same time. 394 * the mesh will be sent using multiple interfaces at the same time.
381 */ 395 */
382 BATADV_ATTR_BONDING_ENABLED, 396 BATADV_ATTR_BONDING_ENABLED,
383 397
384 /** 398 /**
385 * @BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED: whether the bridge loop 399 * @BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED: whether the bridge loop
386 * avoidance feature is enabled. This feature detects and avoids loops 400 * avoidance feature is enabled. This feature detects and avoids loops
387 * between the mesh and devices bridged with the soft interface 401 * between the mesh and devices bridged with the soft interface
388 */ 402 */
389 BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED, 403 BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED,
390 404
391 /** 405 /**
392 * @BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED: whether the distributed 406 * @BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED: whether the distributed
393 * arp table feature is enabled. This feature uses a distributed hash 407 * arp table feature is enabled. This feature uses a distributed hash
394 * table to answer ARP requests without flooding the request through 408 * table to answer ARP requests without flooding the request through
395 * the whole mesh. 409 * the whole mesh.
396 */ 410 */
397 BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED, 411 BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED,
398 412
399 /** 413 /**
400 * @BATADV_ATTR_FRAGMENTATION_ENABLED: whether the data traffic going 414 * @BATADV_ATTR_FRAGMENTATION_ENABLED: whether the data traffic going
401 * through the mesh will be fragmented or silently discarded if the 415 * through the mesh will be fragmented or silently discarded if the
402 * packet size exceeds the outgoing interface MTU. 416 * packet size exceeds the outgoing interface MTU.
403 */ 417 */
404 BATADV_ATTR_FRAGMENTATION_ENABLED, 418 BATADV_ATTR_FRAGMENTATION_ENABLED,
419
420 /**
421 * @BATADV_ATTR_GW_BANDWIDTH_DOWN: defines the download bandwidth which
422 * is propagated by this node if %BATADV_ATTR_GW_BANDWIDTH_MODE was set
423 * to 'server'.
424 */
425 BATADV_ATTR_GW_BANDWIDTH_DOWN,
426
427 /**
428 * @BATADV_ATTR_GW_BANDWIDTH_UP: defines the upload bandwidth which
429 * is propagated by this node if %BATADV_ATTR_GW_BANDWIDTH_MODE was set
430 * to 'server'.
431 */
432 BATADV_ATTR_GW_BANDWIDTH_UP,
433
434 /**
435 * @BATADV_ATTR_GW_MODE: defines the state of the gateway features.
436 * Possible values are specified in enum batadv_gw_modes
437 */
438 BATADV_ATTR_GW_MODE,
439
440 /**
441 * @BATADV_ATTR_GW_SEL_CLASS: defines the selection criteria this node
442 * will use to choose a gateway if gw_mode was set to 'client'.
443 */
444 BATADV_ATTR_GW_SEL_CLASS,
405 445
406 /* add attributes above here, update the policy in netlink.c */ 446 /* add attributes above here, update the policy in netlink.c */
407 447
408 /** 448 /**
409 * @__BATADV_ATTR_AFTER_LAST: internal use 449 * @__BATADV_ATTR_AFTER_LAST: internal use
410 */ 450 */
411 __BATADV_ATTR_AFTER_LAST, 451 __BATADV_ATTR_AFTER_LAST,
412 452
413 /** 453 /**
414 * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available 454 * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available
415 */ 455 */
416 NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST, 456 NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
417 457
418 /** 458 /**
419 * @BATADV_ATTR_MAX: highest attribute number currently defined 459 * @BATADV_ATTR_MAX: highest attribute number currently defined
420 */ 460 */
421 BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1 461 BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1
422 }; 462 };
423 463
424 /** 464 /**
425 * enum batadv_nl_commands - supported batman-adv netlink commands 465 * enum batadv_nl_commands - supported batman-adv netlink commands
426 */ 466 */
427 enum batadv_nl_commands { 467 enum batadv_nl_commands {
428 /** 468 /**
429 * @BATADV_CMD_UNSPEC: unspecified command to catch errors 469 * @BATADV_CMD_UNSPEC: unspecified command to catch errors
430 */ 470 */
431 BATADV_CMD_UNSPEC, 471 BATADV_CMD_UNSPEC,
432 472
433 /** 473 /**
434 * @BATADV_CMD_GET_MESH: Get attributes from softif/mesh 474 * @BATADV_CMD_GET_MESH: Get attributes from softif/mesh
435 */ 475 */
436 BATADV_CMD_GET_MESH, 476 BATADV_CMD_GET_MESH,
437 477
438 /** 478 /**
439 * @BATADV_CMD_GET_MESH_INFO: Alias for @BATADV_CMD_GET_MESH 479 * @BATADV_CMD_GET_MESH_INFO: Alias for @BATADV_CMD_GET_MESH
440 */ 480 */
441 BATADV_CMD_GET_MESH_INFO = BATADV_CMD_GET_MESH, 481 BATADV_CMD_GET_MESH_INFO = BATADV_CMD_GET_MESH,
442 482
443 /** 483 /**
444 * @BATADV_CMD_TP_METER: Start a tp meter session 484 * @BATADV_CMD_TP_METER: Start a tp meter session
445 */ 485 */
446 BATADV_CMD_TP_METER, 486 BATADV_CMD_TP_METER,
447 487
448 /** 488 /**
449 * @BATADV_CMD_TP_METER_CANCEL: Cancel a tp meter session 489 * @BATADV_CMD_TP_METER_CANCEL: Cancel a tp meter session
450 */ 490 */
451 BATADV_CMD_TP_METER_CANCEL, 491 BATADV_CMD_TP_METER_CANCEL,
452 492
453 /** 493 /**
454 * @BATADV_CMD_GET_ROUTING_ALGOS: Query the list of routing algorithms. 494 * @BATADV_CMD_GET_ROUTING_ALGOS: Query the list of routing algorithms.
455 */ 495 */
456 BATADV_CMD_GET_ROUTING_ALGOS, 496 BATADV_CMD_GET_ROUTING_ALGOS,
457 497
458 /** 498 /**
459 * @BATADV_CMD_GET_HARDIF: Get attributes from a hardif of the 499 * @BATADV_CMD_GET_HARDIF: Get attributes from a hardif of the
460 * current softif 500 * current softif
461 */ 501 */
462 BATADV_CMD_GET_HARDIF, 502 BATADV_CMD_GET_HARDIF,
463 503
464 /** 504 /**
465 * @BATADV_CMD_GET_HARDIFS: Alias for @BATADV_CMD_GET_HARDIF 505 * @BATADV_CMD_GET_HARDIFS: Alias for @BATADV_CMD_GET_HARDIF
466 */ 506 */
467 BATADV_CMD_GET_HARDIFS = BATADV_CMD_GET_HARDIF, 507 BATADV_CMD_GET_HARDIFS = BATADV_CMD_GET_HARDIF,
468 508
469 /** 509 /**
470 * @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations 510 * @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations
471 */ 511 */
472 BATADV_CMD_GET_TRANSTABLE_LOCAL, 512 BATADV_CMD_GET_TRANSTABLE_LOCAL,
473 513
474 /** 514 /**
475 * @BATADV_CMD_GET_TRANSTABLE_GLOBAL: Query list of global translations 515 * @BATADV_CMD_GET_TRANSTABLE_GLOBAL: Query list of global translations
476 */ 516 */
477 BATADV_CMD_GET_TRANSTABLE_GLOBAL, 517 BATADV_CMD_GET_TRANSTABLE_GLOBAL,
478 518
479 /** 519 /**
480 * @BATADV_CMD_GET_ORIGINATORS: Query list of originators 520 * @BATADV_CMD_GET_ORIGINATORS: Query list of originators
481 */ 521 */
482 BATADV_CMD_GET_ORIGINATORS, 522 BATADV_CMD_GET_ORIGINATORS,
483 523
484 /** 524 /**
485 * @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours 525 * @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours
486 */ 526 */
487 BATADV_CMD_GET_NEIGHBORS, 527 BATADV_CMD_GET_NEIGHBORS,
488 528
489 /** 529 /**
490 * @BATADV_CMD_GET_GATEWAYS: Query list of gateways 530 * @BATADV_CMD_GET_GATEWAYS: Query list of gateways
491 */ 531 */
492 BATADV_CMD_GET_GATEWAYS, 532 BATADV_CMD_GET_GATEWAYS,
493 533
494 /** 534 /**
495 * @BATADV_CMD_GET_BLA_CLAIM: Query list of bridge loop avoidance claims 535 * @BATADV_CMD_GET_BLA_CLAIM: Query list of bridge loop avoidance claims
496 */ 536 */
497 BATADV_CMD_GET_BLA_CLAIM, 537 BATADV_CMD_GET_BLA_CLAIM,
498 538
499 /** 539 /**
500 * @BATADV_CMD_GET_BLA_BACKBONE: Query list of bridge loop avoidance 540 * @BATADV_CMD_GET_BLA_BACKBONE: Query list of bridge loop avoidance
501 * backbones 541 * backbones
502 */ 542 */
503 BATADV_CMD_GET_BLA_BACKBONE, 543 BATADV_CMD_GET_BLA_BACKBONE,
504 544
505 /** 545 /**
506 * @BATADV_CMD_GET_DAT_CACHE: Query list of DAT cache entries 546 * @BATADV_CMD_GET_DAT_CACHE: Query list of DAT cache entries
507 */ 547 */
508 BATADV_CMD_GET_DAT_CACHE, 548 BATADV_CMD_GET_DAT_CACHE,
509 549
510 /** 550 /**
511 * @BATADV_CMD_GET_MCAST_FLAGS: Query list of multicast flags 551 * @BATADV_CMD_GET_MCAST_FLAGS: Query list of multicast flags
512 */ 552 */
513 BATADV_CMD_GET_MCAST_FLAGS, 553 BATADV_CMD_GET_MCAST_FLAGS,
514 554
515 /** 555 /**
516 * @BATADV_CMD_SET_MESH: Set attributes for softif/mesh 556 * @BATADV_CMD_SET_MESH: Set attributes for softif/mesh
517 */ 557 */
518 BATADV_CMD_SET_MESH, 558 BATADV_CMD_SET_MESH,
519 559
520 /** 560 /**
521 * @BATADV_CMD_SET_HARDIF: Set attributes for hardif of the 561 * @BATADV_CMD_SET_HARDIF: Set attributes for hardif of the
522 * current softif 562 * current softif
523 */ 563 */
524 BATADV_CMD_SET_HARDIF, 564 BATADV_CMD_SET_HARDIF,
525 565
526 /** 566 /**
527 * @BATADV_CMD_GET_VLAN: Get attributes from a VLAN of the 567 * @BATADV_CMD_GET_VLAN: Get attributes from a VLAN of the
528 * current softif 568 * current softif
529 */ 569 */
530 BATADV_CMD_GET_VLAN, 570 BATADV_CMD_GET_VLAN,
531 571
532 /** 572 /**
533 * @BATADV_CMD_SET_VLAN: Set attributes for VLAN of the 573 * @BATADV_CMD_SET_VLAN: Set attributes for VLAN of the
534 * current softif 574 * current softif
535 */ 575 */
536 BATADV_CMD_SET_VLAN, 576 BATADV_CMD_SET_VLAN,
537 577
538 /* add new commands above here */ 578 /* add new commands above here */
539 579
540 /** 580 /**
541 * @__BATADV_CMD_AFTER_LAST: internal use 581 * @__BATADV_CMD_AFTER_LAST: internal use
542 */ 582 */
543 __BATADV_CMD_AFTER_LAST, 583 __BATADV_CMD_AFTER_LAST,
544 584
545 /** 585 /**
546 * @BATADV_CMD_MAX: highest used command number 586 * @BATADV_CMD_MAX: highest used command number
547 */ 587 */
548 BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1 588 BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1
549 }; 589 };
550 590
551 /** 591 /**
552 * enum batadv_tp_meter_reason - reason of a tp meter test run stop 592 * enum batadv_tp_meter_reason - reason of a tp meter test run stop
553 */ 593 */
554 enum batadv_tp_meter_reason { 594 enum batadv_tp_meter_reason {
555 /** 595 /**
556 * @BATADV_TP_REASON_COMPLETE: sender finished tp run 596 * @BATADV_TP_REASON_COMPLETE: sender finished tp run
557 */ 597 */
558 BATADV_TP_REASON_COMPLETE = 3, 598 BATADV_TP_REASON_COMPLETE = 3,
559 599
560 /** 600 /**
561 * @BATADV_TP_REASON_CANCEL: sender was stopped during run 601 * @BATADV_TP_REASON_CANCEL: sender was stopped during run
562 */ 602 */
563 BATADV_TP_REASON_CANCEL = 4, 603 BATADV_TP_REASON_CANCEL = 4,
564 604
565 /* error status >= 128 */ 605 /* error status >= 128 */
566 606
567 /** 607 /**
568 * @BATADV_TP_REASON_DST_UNREACHABLE: receiver could not be reached or 608 * @BATADV_TP_REASON_DST_UNREACHABLE: receiver could not be reached or
569 * didn't answer 609 * didn't answer
570 */ 610 */
571 BATADV_TP_REASON_DST_UNREACHABLE = 128, 611 BATADV_TP_REASON_DST_UNREACHABLE = 128,
572 612
573 /** 613 /**
574 * @BATADV_TP_REASON_RESEND_LIMIT: (unused) sender retry reached limit 614 * @BATADV_TP_REASON_RESEND_LIMIT: (unused) sender retry reached limit
575 */ 615 */
576 BATADV_TP_REASON_RESEND_LIMIT = 129, 616 BATADV_TP_REASON_RESEND_LIMIT = 129,
577 617
578 /** 618 /**
579 * @BATADV_TP_REASON_ALREADY_ONGOING: test to or from the same node 619 * @BATADV_TP_REASON_ALREADY_ONGOING: test to or from the same node
580 * already ongoing 620 * already ongoing
581 */ 621 */
582 BATADV_TP_REASON_ALREADY_ONGOING = 130, 622 BATADV_TP_REASON_ALREADY_ONGOING = 130,
583 623
584 /** 624 /**
585 * @BATADV_TP_REASON_MEMORY_ERROR: test was stopped due to low memory 625 * @BATADV_TP_REASON_MEMORY_ERROR: test was stopped due to low memory
586 */ 626 */
587 BATADV_TP_REASON_MEMORY_ERROR = 131, 627 BATADV_TP_REASON_MEMORY_ERROR = 131,
588 628
589 /** 629 /**
590 * @BATADV_TP_REASON_CANT_SEND: failed to send via outgoing interface 630 * @BATADV_TP_REASON_CANT_SEND: failed to send via outgoing interface
591 */ 631 */
592 BATADV_TP_REASON_CANT_SEND = 132, 632 BATADV_TP_REASON_CANT_SEND = 132,
593 633
594 /** 634 /**
595 * @BATADV_TP_REASON_TOO_MANY: too many ongoing sessions 635 * @BATADV_TP_REASON_TOO_MANY: too many ongoing sessions
596 */ 636 */
597 BATADV_TP_REASON_TOO_MANY = 133, 637 BATADV_TP_REASON_TOO_MANY = 133,
598 }; 638 };
599 639
600 #endif /* _UAPI_LINUX_BATMAN_ADV_H_ */ 640 #endif /* _UAPI_LINUX_BATMAN_ADV_H_ */
601 641
net/batman-adv/gateway_client.c
1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors: 2 /* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation. 8 * License as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details. 13 * General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include "gateway_client.h" 19 #include "gateway_client.h"
20 #include "main.h" 20 #include "main.h"
21 21
22 #include <linux/atomic.h> 22 #include <linux/atomic.h>
23 #include <linux/byteorder/generic.h> 23 #include <linux/byteorder/generic.h>
24 #include <linux/errno.h> 24 #include <linux/errno.h>
25 #include <linux/etherdevice.h> 25 #include <linux/etherdevice.h>
26 #include <linux/gfp.h> 26 #include <linux/gfp.h>
27 #include <linux/if_ether.h> 27 #include <linux/if_ether.h>
28 #include <linux/if_vlan.h> 28 #include <linux/if_vlan.h>
29 #include <linux/in.h> 29 #include <linux/in.h>
30 #include <linux/ip.h> 30 #include <linux/ip.h>
31 #include <linux/ipv6.h> 31 #include <linux/ipv6.h>
32 #include <linux/kernel.h> 32 #include <linux/kernel.h>
33 #include <linux/kref.h> 33 #include <linux/kref.h>
34 #include <linux/list.h> 34 #include <linux/list.h>
35 #include <linux/lockdep.h> 35 #include <linux/lockdep.h>
36 #include <linux/netdevice.h> 36 #include <linux/netdevice.h>
37 #include <linux/netlink.h> 37 #include <linux/netlink.h>
38 #include <linux/rculist.h> 38 #include <linux/rculist.h>
39 #include <linux/rcupdate.h> 39 #include <linux/rcupdate.h>
40 #include <linux/seq_file.h> 40 #include <linux/seq_file.h>
41 #include <linux/skbuff.h> 41 #include <linux/skbuff.h>
42 #include <linux/slab.h> 42 #include <linux/slab.h>
43 #include <linux/spinlock.h> 43 #include <linux/spinlock.h>
44 #include <linux/stddef.h> 44 #include <linux/stddef.h>
45 #include <linux/udp.h> 45 #include <linux/udp.h>
46 #include <net/sock.h> 46 #include <net/sock.h>
47 #include <uapi/linux/batadv_packet.h> 47 #include <uapi/linux/batadv_packet.h>
48 #include <uapi/linux/batman_adv.h> 48 #include <uapi/linux/batman_adv.h>
49 49
50 #include "gateway_common.h"
51 #include "hard-interface.h" 50 #include "hard-interface.h"
52 #include "log.h" 51 #include "log.h"
53 #include "netlink.h" 52 #include "netlink.h"
54 #include "originator.h" 53 #include "originator.h"
55 #include "routing.h" 54 #include "routing.h"
56 #include "soft-interface.h" 55 #include "soft-interface.h"
57 #include "sysfs.h" 56 #include "sysfs.h"
58 #include "translation-table.h" 57 #include "translation-table.h"
59 58
60 /* These are the offsets of the "hw type" and "hw address length" in the dhcp 59 /* These are the offsets of the "hw type" and "hw address length" in the dhcp
61 * packet starting at the beginning of the dhcp header 60 * packet starting at the beginning of the dhcp header
62 */ 61 */
63 #define BATADV_DHCP_HTYPE_OFFSET 1 62 #define BATADV_DHCP_HTYPE_OFFSET 1
64 #define BATADV_DHCP_HLEN_OFFSET 2 63 #define BATADV_DHCP_HLEN_OFFSET 2
65 /* Value of htype representing Ethernet */ 64 /* Value of htype representing Ethernet */
66 #define BATADV_DHCP_HTYPE_ETHERNET 0x01 65 #define BATADV_DHCP_HTYPE_ETHERNET 0x01
67 /* This is the offset of the "chaddr" field in the dhcp packet starting at the 66 /* This is the offset of the "chaddr" field in the dhcp packet starting at the
68 * beginning of the dhcp header 67 * beginning of the dhcp header
69 */ 68 */
70 #define BATADV_DHCP_CHADDR_OFFSET 28 69 #define BATADV_DHCP_CHADDR_OFFSET 28
71 70
72 /** 71 /**
73 * batadv_gw_node_release() - release gw_node from lists and queue for free 72 * batadv_gw_node_release() - release gw_node from lists and queue for free
74 * after rcu grace period 73 * after rcu grace period
75 * @ref: kref pointer of the gw_node 74 * @ref: kref pointer of the gw_node
76 */ 75 */
77 static void batadv_gw_node_release(struct kref *ref) 76 static void batadv_gw_node_release(struct kref *ref)
78 { 77 {
79 struct batadv_gw_node *gw_node; 78 struct batadv_gw_node *gw_node;
80 79
81 gw_node = container_of(ref, struct batadv_gw_node, refcount); 80 gw_node = container_of(ref, struct batadv_gw_node, refcount);
82 81
83 batadv_orig_node_put(gw_node->orig_node); 82 batadv_orig_node_put(gw_node->orig_node);
84 kfree_rcu(gw_node, rcu); 83 kfree_rcu(gw_node, rcu);
85 } 84 }
86 85
87 /** 86 /**
88 * batadv_gw_node_put() - decrement the gw_node refcounter and possibly release 87 * batadv_gw_node_put() - decrement the gw_node refcounter and possibly release
89 * it 88 * it
90 * @gw_node: gateway node to free 89 * @gw_node: gateway node to free
91 */ 90 */
92 void batadv_gw_node_put(struct batadv_gw_node *gw_node) 91 void batadv_gw_node_put(struct batadv_gw_node *gw_node)
93 { 92 {
94 kref_put(&gw_node->refcount, batadv_gw_node_release); 93 kref_put(&gw_node->refcount, batadv_gw_node_release);
95 } 94 }
96 95
97 /** 96 /**
98 * batadv_gw_get_selected_gw_node() - Get currently selected gateway 97 * batadv_gw_get_selected_gw_node() - Get currently selected gateway
99 * @bat_priv: the bat priv with all the soft interface information 98 * @bat_priv: the bat priv with all the soft interface information
100 * 99 *
101 * Return: selected gateway (with increased refcnt), NULL on errors 100 * Return: selected gateway (with increased refcnt), NULL on errors
102 */ 101 */
103 struct batadv_gw_node * 102 struct batadv_gw_node *
104 batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv) 103 batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv)
105 { 104 {
106 struct batadv_gw_node *gw_node; 105 struct batadv_gw_node *gw_node;
107 106
108 rcu_read_lock(); 107 rcu_read_lock();
109 gw_node = rcu_dereference(bat_priv->gw.curr_gw); 108 gw_node = rcu_dereference(bat_priv->gw.curr_gw);
110 if (!gw_node) 109 if (!gw_node)
111 goto out; 110 goto out;
112 111
113 if (!kref_get_unless_zero(&gw_node->refcount)) 112 if (!kref_get_unless_zero(&gw_node->refcount))
114 gw_node = NULL; 113 gw_node = NULL;
115 114
116 out: 115 out:
117 rcu_read_unlock(); 116 rcu_read_unlock();
118 return gw_node; 117 return gw_node;
119 } 118 }
120 119
121 /** 120 /**
122 * batadv_gw_get_selected_orig() - Get originator of currently selected gateway 121 * batadv_gw_get_selected_orig() - Get originator of currently selected gateway
123 * @bat_priv: the bat priv with all the soft interface information 122 * @bat_priv: the bat priv with all the soft interface information
124 * 123 *
125 * Return: orig_node of selected gateway (with increased refcnt), NULL on errors 124 * Return: orig_node of selected gateway (with increased refcnt), NULL on errors
126 */ 125 */
127 struct batadv_orig_node * 126 struct batadv_orig_node *
128 batadv_gw_get_selected_orig(struct batadv_priv *bat_priv) 127 batadv_gw_get_selected_orig(struct batadv_priv *bat_priv)
129 { 128 {
130 struct batadv_gw_node *gw_node; 129 struct batadv_gw_node *gw_node;
131 struct batadv_orig_node *orig_node = NULL; 130 struct batadv_orig_node *orig_node = NULL;
132 131
133 gw_node = batadv_gw_get_selected_gw_node(bat_priv); 132 gw_node = batadv_gw_get_selected_gw_node(bat_priv);
134 if (!gw_node) 133 if (!gw_node)
135 goto out; 134 goto out;
136 135
137 rcu_read_lock(); 136 rcu_read_lock();
138 orig_node = gw_node->orig_node; 137 orig_node = gw_node->orig_node;
139 if (!orig_node) 138 if (!orig_node)
140 goto unlock; 139 goto unlock;
141 140
142 if (!kref_get_unless_zero(&orig_node->refcount)) 141 if (!kref_get_unless_zero(&orig_node->refcount))
143 orig_node = NULL; 142 orig_node = NULL;
144 143
145 unlock: 144 unlock:
146 rcu_read_unlock(); 145 rcu_read_unlock();
147 out: 146 out:
148 if (gw_node) 147 if (gw_node)
149 batadv_gw_node_put(gw_node); 148 batadv_gw_node_put(gw_node);
150 return orig_node; 149 return orig_node;
151 } 150 }
152 151
153 static void batadv_gw_select(struct batadv_priv *bat_priv, 152 static void batadv_gw_select(struct batadv_priv *bat_priv,
154 struct batadv_gw_node *new_gw_node) 153 struct batadv_gw_node *new_gw_node)
155 { 154 {
156 struct batadv_gw_node *curr_gw_node; 155 struct batadv_gw_node *curr_gw_node;
157 156
158 spin_lock_bh(&bat_priv->gw.list_lock); 157 spin_lock_bh(&bat_priv->gw.list_lock);
159 158
160 if (new_gw_node) 159 if (new_gw_node)
161 kref_get(&new_gw_node->refcount); 160 kref_get(&new_gw_node->refcount);
162 161
163 curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1); 162 curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1);
164 rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node); 163 rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node);
165 164
166 if (curr_gw_node) 165 if (curr_gw_node)
167 batadv_gw_node_put(curr_gw_node); 166 batadv_gw_node_put(curr_gw_node);
168 167
169 spin_unlock_bh(&bat_priv->gw.list_lock); 168 spin_unlock_bh(&bat_priv->gw.list_lock);
170 } 169 }
171 170
172 /** 171 /**
173 * batadv_gw_reselect() - force a gateway reselection 172 * batadv_gw_reselect() - force a gateway reselection
174 * @bat_priv: the bat priv with all the soft interface information 173 * @bat_priv: the bat priv with all the soft interface information
175 * 174 *
176 * Set a flag to remind the GW component to perform a new gateway reselection. 175 * Set a flag to remind the GW component to perform a new gateway reselection.
177 * However this function does not ensure that the current gateway is going to be 176 * However this function does not ensure that the current gateway is going to be
178 * deselected. The reselection mechanism may elect the same gateway once again. 177 * deselected. The reselection mechanism may elect the same gateway once again.
179 * 178 *
180 * This means that invoking batadv_gw_reselect() does not guarantee a gateway 179 * This means that invoking batadv_gw_reselect() does not guarantee a gateway
181 * change and therefore a uevent is not necessarily expected. 180 * change and therefore a uevent is not necessarily expected.
182 */ 181 */
183 void batadv_gw_reselect(struct batadv_priv *bat_priv) 182 void batadv_gw_reselect(struct batadv_priv *bat_priv)
184 { 183 {
185 atomic_set(&bat_priv->gw.reselect, 1); 184 atomic_set(&bat_priv->gw.reselect, 1);
186 } 185 }
187 186
188 /** 187 /**
189 * batadv_gw_check_client_stop() - check if client mode has been switched off 188 * batadv_gw_check_client_stop() - check if client mode has been switched off
190 * @bat_priv: the bat priv with all the soft interface information 189 * @bat_priv: the bat priv with all the soft interface information
191 * 190 *
192 * This function assumes the caller has checked that the gw state *is actually 191 * This function assumes the caller has checked that the gw state *is actually
193 * changing*. This function is not supposed to be called when there is no state 192 * changing*. This function is not supposed to be called when there is no state
194 * change. 193 * change.
195 */ 194 */
196 void batadv_gw_check_client_stop(struct batadv_priv *bat_priv) 195 void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
197 { 196 {
198 struct batadv_gw_node *curr_gw; 197 struct batadv_gw_node *curr_gw;
199 198
200 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT) 199 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
201 return; 200 return;
202 201
203 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 202 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
204 if (!curr_gw) 203 if (!curr_gw)
205 return; 204 return;
206 205
207 /* deselect the current gateway so that next time that client mode is 206 /* deselect the current gateway so that next time that client mode is
208 * enabled a proper GW_ADD event can be sent 207 * enabled a proper GW_ADD event can be sent
209 */ 208 */
210 batadv_gw_select(bat_priv, NULL); 209 batadv_gw_select(bat_priv, NULL);
211 210
212 /* if batman-adv is switching the gw client mode off and a gateway was 211 /* if batman-adv is switching the gw client mode off and a gateway was
213 * already selected, send a DEL uevent 212 * already selected, send a DEL uevent
214 */ 213 */
215 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, NULL); 214 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, NULL);
216 215
217 batadv_gw_node_put(curr_gw); 216 batadv_gw_node_put(curr_gw);
218 } 217 }
219 218
220 /** 219 /**
221 * batadv_gw_election() - Elect the best gateway 220 * batadv_gw_election() - Elect the best gateway
222 * @bat_priv: the bat priv with all the soft interface information 221 * @bat_priv: the bat priv with all the soft interface information
223 */ 222 */
224 void batadv_gw_election(struct batadv_priv *bat_priv) 223 void batadv_gw_election(struct batadv_priv *bat_priv)
225 { 224 {
226 struct batadv_gw_node *curr_gw = NULL; 225 struct batadv_gw_node *curr_gw = NULL;
227 struct batadv_gw_node *next_gw = NULL; 226 struct batadv_gw_node *next_gw = NULL;
228 struct batadv_neigh_node *router = NULL; 227 struct batadv_neigh_node *router = NULL;
229 struct batadv_neigh_ifinfo *router_ifinfo = NULL; 228 struct batadv_neigh_ifinfo *router_ifinfo = NULL;
230 char gw_addr[18] = { '\0' }; 229 char gw_addr[18] = { '\0' };
231 230
232 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT) 231 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
233 goto out; 232 goto out;
234 233
235 if (!bat_priv->algo_ops->gw.get_best_gw_node) 234 if (!bat_priv->algo_ops->gw.get_best_gw_node)
236 goto out; 235 goto out;
237 236
238 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 237 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
239 238
240 if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw) 239 if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw)
241 goto out; 240 goto out;
242 241
243 /* if gw.reselect is set to 1 it means that a previous call to 242 /* if gw.reselect is set to 1 it means that a previous call to
244 * gw.is_eligible() said that we have a new best GW, therefore it can 243 * gw.is_eligible() said that we have a new best GW, therefore it can
245 * now be picked from the list and selected 244 * now be picked from the list and selected
246 */ 245 */
247 next_gw = bat_priv->algo_ops->gw.get_best_gw_node(bat_priv); 246 next_gw = bat_priv->algo_ops->gw.get_best_gw_node(bat_priv);
248 247
249 if (curr_gw == next_gw) 248 if (curr_gw == next_gw)
250 goto out; 249 goto out;
251 250
252 if (next_gw) { 251 if (next_gw) {
253 sprintf(gw_addr, "%pM", next_gw->orig_node->orig); 252 sprintf(gw_addr, "%pM", next_gw->orig_node->orig);
254 253
255 router = batadv_orig_router_get(next_gw->orig_node, 254 router = batadv_orig_router_get(next_gw->orig_node,
256 BATADV_IF_DEFAULT); 255 BATADV_IF_DEFAULT);
257 if (!router) { 256 if (!router) {
258 batadv_gw_reselect(bat_priv); 257 batadv_gw_reselect(bat_priv);
259 goto out; 258 goto out;
260 } 259 }
261 260
262 router_ifinfo = batadv_neigh_ifinfo_get(router, 261 router_ifinfo = batadv_neigh_ifinfo_get(router,
263 BATADV_IF_DEFAULT); 262 BATADV_IF_DEFAULT);
264 if (!router_ifinfo) { 263 if (!router_ifinfo) {
265 batadv_gw_reselect(bat_priv); 264 batadv_gw_reselect(bat_priv);
266 goto out; 265 goto out;
267 } 266 }
268 } 267 }
269 268
270 if (curr_gw && !next_gw) { 269 if (curr_gw && !next_gw) {
271 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 270 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
272 "Removing selected gateway - no gateway in range\n"); 271 "Removing selected gateway - no gateway in range\n");
273 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, 272 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL,
274 NULL); 273 NULL);
275 } else if (!curr_gw && next_gw) { 274 } else if (!curr_gw && next_gw) {
276 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 275 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
277 "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n", 276 "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
278 next_gw->orig_node->orig, 277 next_gw->orig_node->orig,
279 next_gw->bandwidth_down / 10, 278 next_gw->bandwidth_down / 10,
280 next_gw->bandwidth_down % 10, 279 next_gw->bandwidth_down % 10,
281 next_gw->bandwidth_up / 10, 280 next_gw->bandwidth_up / 10,
282 next_gw->bandwidth_up % 10, 281 next_gw->bandwidth_up % 10,
283 router_ifinfo->bat_iv.tq_avg); 282 router_ifinfo->bat_iv.tq_avg);
284 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD, 283 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
285 gw_addr); 284 gw_addr);
286 } else { 285 } else {
287 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 286 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
288 "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n", 287 "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
289 next_gw->orig_node->orig, 288 next_gw->orig_node->orig,
290 next_gw->bandwidth_down / 10, 289 next_gw->bandwidth_down / 10,
291 next_gw->bandwidth_down % 10, 290 next_gw->bandwidth_down % 10,
292 next_gw->bandwidth_up / 10, 291 next_gw->bandwidth_up / 10,
293 next_gw->bandwidth_up % 10, 292 next_gw->bandwidth_up % 10,
294 router_ifinfo->bat_iv.tq_avg); 293 router_ifinfo->bat_iv.tq_avg);
295 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE, 294 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
296 gw_addr); 295 gw_addr);
297 } 296 }
298 297
299 batadv_gw_select(bat_priv, next_gw); 298 batadv_gw_select(bat_priv, next_gw);
300 299
301 out: 300 out:
302 if (curr_gw) 301 if (curr_gw)
303 batadv_gw_node_put(curr_gw); 302 batadv_gw_node_put(curr_gw);
304 if (next_gw) 303 if (next_gw)
305 batadv_gw_node_put(next_gw); 304 batadv_gw_node_put(next_gw);
306 if (router) 305 if (router)
307 batadv_neigh_node_put(router); 306 batadv_neigh_node_put(router);
308 if (router_ifinfo) 307 if (router_ifinfo)
309 batadv_neigh_ifinfo_put(router_ifinfo); 308 batadv_neigh_ifinfo_put(router_ifinfo);
310 } 309 }
311 310
312 /** 311 /**
313 * batadv_gw_check_election() - Elect orig node as best gateway when eligible 312 * batadv_gw_check_election() - Elect orig node as best gateway when eligible
314 * @bat_priv: the bat priv with all the soft interface information 313 * @bat_priv: the bat priv with all the soft interface information
315 * @orig_node: orig node which is to be checked 314 * @orig_node: orig node which is to be checked
316 */ 315 */
317 void batadv_gw_check_election(struct batadv_priv *bat_priv, 316 void batadv_gw_check_election(struct batadv_priv *bat_priv,
318 struct batadv_orig_node *orig_node) 317 struct batadv_orig_node *orig_node)
319 { 318 {
320 struct batadv_orig_node *curr_gw_orig; 319 struct batadv_orig_node *curr_gw_orig;
321 320
322 /* abort immediately if the routing algorithm does not support gateway 321 /* abort immediately if the routing algorithm does not support gateway
323 * election 322 * election
324 */ 323 */
325 if (!bat_priv->algo_ops->gw.is_eligible) 324 if (!bat_priv->algo_ops->gw.is_eligible)
326 return; 325 return;
327 326
328 curr_gw_orig = batadv_gw_get_selected_orig(bat_priv); 327 curr_gw_orig = batadv_gw_get_selected_orig(bat_priv);
329 if (!curr_gw_orig) 328 if (!curr_gw_orig)
330 goto reselect; 329 goto reselect;
331 330
332 /* this node already is the gateway */ 331 /* this node already is the gateway */
333 if (curr_gw_orig == orig_node) 332 if (curr_gw_orig == orig_node)
334 goto out; 333 goto out;
335 334
336 if (!bat_priv->algo_ops->gw.is_eligible(bat_priv, curr_gw_orig, 335 if (!bat_priv->algo_ops->gw.is_eligible(bat_priv, curr_gw_orig,
337 orig_node)) 336 orig_node))
338 goto out; 337 goto out;
339 338
340 reselect: 339 reselect:
341 batadv_gw_reselect(bat_priv); 340 batadv_gw_reselect(bat_priv);
342 out: 341 out:
343 if (curr_gw_orig) 342 if (curr_gw_orig)
344 batadv_orig_node_put(curr_gw_orig); 343 batadv_orig_node_put(curr_gw_orig);
345 } 344 }
346 345
347 /** 346 /**
348 * batadv_gw_node_add() - add gateway node to list of available gateways 347 * batadv_gw_node_add() - add gateway node to list of available gateways
349 * @bat_priv: the bat priv with all the soft interface information 348 * @bat_priv: the bat priv with all the soft interface information
350 * @orig_node: originator announcing gateway capabilities 349 * @orig_node: originator announcing gateway capabilities
351 * @gateway: announced bandwidth information 350 * @gateway: announced bandwidth information
352 * 351 *
353 * Has to be called with the appropriate locks being acquired 352 * Has to be called with the appropriate locks being acquired
354 * (gw.list_lock). 353 * (gw.list_lock).
355 */ 354 */
356 static void batadv_gw_node_add(struct batadv_priv *bat_priv, 355 static void batadv_gw_node_add(struct batadv_priv *bat_priv,
357 struct batadv_orig_node *orig_node, 356 struct batadv_orig_node *orig_node,
358 struct batadv_tvlv_gateway_data *gateway) 357 struct batadv_tvlv_gateway_data *gateway)
359 { 358 {
360 struct batadv_gw_node *gw_node; 359 struct batadv_gw_node *gw_node;
361 360
362 lockdep_assert_held(&bat_priv->gw.list_lock); 361 lockdep_assert_held(&bat_priv->gw.list_lock);
363 362
364 if (gateway->bandwidth_down == 0) 363 if (gateway->bandwidth_down == 0)
365 return; 364 return;
366 365
367 gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); 366 gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
368 if (!gw_node) 367 if (!gw_node)
369 return; 368 return;
370 369
371 kref_init(&gw_node->refcount); 370 kref_init(&gw_node->refcount);
372 INIT_HLIST_NODE(&gw_node->list); 371 INIT_HLIST_NODE(&gw_node->list);
373 kref_get(&orig_node->refcount); 372 kref_get(&orig_node->refcount);
374 gw_node->orig_node = orig_node; 373 gw_node->orig_node = orig_node;
375 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); 374 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
376 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up); 375 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
377 376
378 kref_get(&gw_node->refcount); 377 kref_get(&gw_node->refcount);
379 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list); 378 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list);
380 bat_priv->gw.generation++; 379 bat_priv->gw.generation++;
381 380
382 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 381 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
383 "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n", 382 "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
384 orig_node->orig, 383 orig_node->orig,
385 ntohl(gateway->bandwidth_down) / 10, 384 ntohl(gateway->bandwidth_down) / 10,
386 ntohl(gateway->bandwidth_down) % 10, 385 ntohl(gateway->bandwidth_down) % 10,
387 ntohl(gateway->bandwidth_up) / 10, 386 ntohl(gateway->bandwidth_up) / 10,
388 ntohl(gateway->bandwidth_up) % 10); 387 ntohl(gateway->bandwidth_up) % 10);
389 388
390 /* don't return reference to new gw_node */ 389 /* don't return reference to new gw_node */
391 batadv_gw_node_put(gw_node); 390 batadv_gw_node_put(gw_node);
392 } 391 }
393 392
394 /** 393 /**
395 * batadv_gw_node_get() - retrieve gateway node from list of available gateways 394 * batadv_gw_node_get() - retrieve gateway node from list of available gateways
396 * @bat_priv: the bat priv with all the soft interface information 395 * @bat_priv: the bat priv with all the soft interface information
397 * @orig_node: originator announcing gateway capabilities 396 * @orig_node: originator announcing gateway capabilities
398 * 397 *
399 * Return: gateway node if found or NULL otherwise. 398 * Return: gateway node if found or NULL otherwise.
400 */ 399 */
401 struct batadv_gw_node *batadv_gw_node_get(struct batadv_priv *bat_priv, 400 struct batadv_gw_node *batadv_gw_node_get(struct batadv_priv *bat_priv,
402 struct batadv_orig_node *orig_node) 401 struct batadv_orig_node *orig_node)
403 { 402 {
404 struct batadv_gw_node *gw_node_tmp, *gw_node = NULL; 403 struct batadv_gw_node *gw_node_tmp, *gw_node = NULL;
405 404
406 rcu_read_lock(); 405 rcu_read_lock();
407 hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.gateway_list, 406 hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.gateway_list,
408 list) { 407 list) {
409 if (gw_node_tmp->orig_node != orig_node) 408 if (gw_node_tmp->orig_node != orig_node)
410 continue; 409 continue;
411 410
412 if (!kref_get_unless_zero(&gw_node_tmp->refcount)) 411 if (!kref_get_unless_zero(&gw_node_tmp->refcount))
413 continue; 412 continue;
414 413
415 gw_node = gw_node_tmp; 414 gw_node = gw_node_tmp;
416 break; 415 break;
417 } 416 }
418 rcu_read_unlock(); 417 rcu_read_unlock();
419 418
420 return gw_node; 419 return gw_node;
421 } 420 }
422 421
423 /** 422 /**
424 * batadv_gw_node_update() - update list of available gateways with changed 423 * batadv_gw_node_update() - update list of available gateways with changed
425 * bandwidth information 424 * bandwidth information
426 * @bat_priv: the bat priv with all the soft interface information 425 * @bat_priv: the bat priv with all the soft interface information
427 * @orig_node: originator announcing gateway capabilities 426 * @orig_node: originator announcing gateway capabilities
428 * @gateway: announced bandwidth information 427 * @gateway: announced bandwidth information
429 */ 428 */
430 void batadv_gw_node_update(struct batadv_priv *bat_priv, 429 void batadv_gw_node_update(struct batadv_priv *bat_priv,
431 struct batadv_orig_node *orig_node, 430 struct batadv_orig_node *orig_node,
432 struct batadv_tvlv_gateway_data *gateway) 431 struct batadv_tvlv_gateway_data *gateway)
433 { 432 {
434 struct batadv_gw_node *gw_node, *curr_gw = NULL; 433 struct batadv_gw_node *gw_node, *curr_gw = NULL;
435 434
436 spin_lock_bh(&bat_priv->gw.list_lock); 435 spin_lock_bh(&bat_priv->gw.list_lock);
437 gw_node = batadv_gw_node_get(bat_priv, orig_node); 436 gw_node = batadv_gw_node_get(bat_priv, orig_node);
438 if (!gw_node) { 437 if (!gw_node) {
439 batadv_gw_node_add(bat_priv, orig_node, gateway); 438 batadv_gw_node_add(bat_priv, orig_node, gateway);
440 spin_unlock_bh(&bat_priv->gw.list_lock); 439 spin_unlock_bh(&bat_priv->gw.list_lock);
441 goto out; 440 goto out;
442 } 441 }
443 spin_unlock_bh(&bat_priv->gw.list_lock); 442 spin_unlock_bh(&bat_priv->gw.list_lock);
444 443
445 if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) && 444 if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) &&
446 gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)) 445 gw_node->bandwidth_up == ntohl(gateway->bandwidth_up))
447 goto out; 446 goto out;
448 447
449 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 448 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
450 "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n", 449 "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n",
451 orig_node->orig, 450 orig_node->orig,
452 gw_node->bandwidth_down / 10, 451 gw_node->bandwidth_down / 10,
453 gw_node->bandwidth_down % 10, 452 gw_node->bandwidth_down % 10,
454 gw_node->bandwidth_up / 10, 453 gw_node->bandwidth_up / 10,
455 gw_node->bandwidth_up % 10, 454 gw_node->bandwidth_up % 10,
456 ntohl(gateway->bandwidth_down) / 10, 455 ntohl(gateway->bandwidth_down) / 10,
457 ntohl(gateway->bandwidth_down) % 10, 456 ntohl(gateway->bandwidth_down) % 10,
458 ntohl(gateway->bandwidth_up) / 10, 457 ntohl(gateway->bandwidth_up) / 10,
459 ntohl(gateway->bandwidth_up) % 10); 458 ntohl(gateway->bandwidth_up) % 10);
460 459
461 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); 460 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
462 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up); 461 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
463 462
464 if (ntohl(gateway->bandwidth_down) == 0) { 463 if (ntohl(gateway->bandwidth_down) == 0) {
465 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 464 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
466 "Gateway %pM removed from gateway list\n", 465 "Gateway %pM removed from gateway list\n",
467 orig_node->orig); 466 orig_node->orig);
468 467
469 /* Note: We don't need a NULL check here, since curr_gw never 468 /* Note: We don't need a NULL check here, since curr_gw never
470 * gets dereferenced. 469 * gets dereferenced.
471 */ 470 */
472 spin_lock_bh(&bat_priv->gw.list_lock); 471 spin_lock_bh(&bat_priv->gw.list_lock);
473 if (!hlist_unhashed(&gw_node->list)) { 472 if (!hlist_unhashed(&gw_node->list)) {
474 hlist_del_init_rcu(&gw_node->list); 473 hlist_del_init_rcu(&gw_node->list);
475 batadv_gw_node_put(gw_node); 474 batadv_gw_node_put(gw_node);
476 bat_priv->gw.generation++; 475 bat_priv->gw.generation++;
477 } 476 }
478 spin_unlock_bh(&bat_priv->gw.list_lock); 477 spin_unlock_bh(&bat_priv->gw.list_lock);
479 478
480 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 479 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
481 if (gw_node == curr_gw) 480 if (gw_node == curr_gw)
482 batadv_gw_reselect(bat_priv); 481 batadv_gw_reselect(bat_priv);
483 482
484 if (curr_gw) 483 if (curr_gw)
485 batadv_gw_node_put(curr_gw); 484 batadv_gw_node_put(curr_gw);
486 } 485 }
487 486
488 out: 487 out:
489 if (gw_node) 488 if (gw_node)
490 batadv_gw_node_put(gw_node); 489 batadv_gw_node_put(gw_node);
491 } 490 }
492 491
493 /** 492 /**
494 * batadv_gw_node_delete() - Remove orig_node from gateway list 493 * batadv_gw_node_delete() - Remove orig_node from gateway list
495 * @bat_priv: the bat priv with all the soft interface information 494 * @bat_priv: the bat priv with all the soft interface information
496 * @orig_node: orig node which is currently in process of being removed 495 * @orig_node: orig node which is currently in process of being removed
497 */ 496 */
498 void batadv_gw_node_delete(struct batadv_priv *bat_priv, 497 void batadv_gw_node_delete(struct batadv_priv *bat_priv,
499 struct batadv_orig_node *orig_node) 498 struct batadv_orig_node *orig_node)
500 { 499 {
501 struct batadv_tvlv_gateway_data gateway; 500 struct batadv_tvlv_gateway_data gateway;
502 501
503 gateway.bandwidth_down = 0; 502 gateway.bandwidth_down = 0;
504 gateway.bandwidth_up = 0; 503 gateway.bandwidth_up = 0;
505 504
506 batadv_gw_node_update(bat_priv, orig_node, &gateway); 505 batadv_gw_node_update(bat_priv, orig_node, &gateway);
507 } 506 }
508 507
509 /** 508 /**
510 * batadv_gw_node_free() - Free gateway information from soft interface 509 * batadv_gw_node_free() - Free gateway information from soft interface
511 * @bat_priv: the bat priv with all the soft interface information 510 * @bat_priv: the bat priv with all the soft interface information
512 */ 511 */
513 void batadv_gw_node_free(struct batadv_priv *bat_priv) 512 void batadv_gw_node_free(struct batadv_priv *bat_priv)
514 { 513 {
515 struct batadv_gw_node *gw_node; 514 struct batadv_gw_node *gw_node;
516 struct hlist_node *node_tmp; 515 struct hlist_node *node_tmp;
517 516
518 spin_lock_bh(&bat_priv->gw.list_lock); 517 spin_lock_bh(&bat_priv->gw.list_lock);
519 hlist_for_each_entry_safe(gw_node, node_tmp, 518 hlist_for_each_entry_safe(gw_node, node_tmp,
520 &bat_priv->gw.gateway_list, list) { 519 &bat_priv->gw.gateway_list, list) {
521 hlist_del_init_rcu(&gw_node->list); 520 hlist_del_init_rcu(&gw_node->list);
522 batadv_gw_node_put(gw_node); 521 batadv_gw_node_put(gw_node);
523 bat_priv->gw.generation++; 522 bat_priv->gw.generation++;
524 } 523 }
525 spin_unlock_bh(&bat_priv->gw.list_lock); 524 spin_unlock_bh(&bat_priv->gw.list_lock);
526 } 525 }
527 526
528 #ifdef CONFIG_BATMAN_ADV_DEBUGFS 527 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
529 528
530 /** 529 /**
531 * batadv_gw_client_seq_print_text() - Print the gateway table in a seq file 530 * batadv_gw_client_seq_print_text() - Print the gateway table in a seq file
532 * @seq: seq file to print on 531 * @seq: seq file to print on
533 * @offset: not used 532 * @offset: not used
534 * 533 *
535 * Return: always 0 534 * Return: always 0
536 */ 535 */
537 int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) 536 int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
538 { 537 {
539 struct net_device *net_dev = (struct net_device *)seq->private; 538 struct net_device *net_dev = (struct net_device *)seq->private;
540 struct batadv_priv *bat_priv = netdev_priv(net_dev); 539 struct batadv_priv *bat_priv = netdev_priv(net_dev);
541 struct batadv_hard_iface *primary_if; 540 struct batadv_hard_iface *primary_if;
542 541
543 primary_if = batadv_seq_print_text_primary_if_get(seq); 542 primary_if = batadv_seq_print_text_primary_if_get(seq);
544 if (!primary_if) 543 if (!primary_if)
545 return 0; 544 return 0;
546 545
547 seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s %s)]\n", 546 seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s %s)]\n",
548 BATADV_SOURCE_VERSION, primary_if->net_dev->name, 547 BATADV_SOURCE_VERSION, primary_if->net_dev->name,
549 primary_if->net_dev->dev_addr, net_dev->name, 548 primary_if->net_dev->dev_addr, net_dev->name,
550 bat_priv->algo_ops->name); 549 bat_priv->algo_ops->name);
551 550
552 batadv_hardif_put(primary_if); 551 batadv_hardif_put(primary_if);
553 552
554 if (!bat_priv->algo_ops->gw.print) { 553 if (!bat_priv->algo_ops->gw.print) {
555 seq_puts(seq, 554 seq_puts(seq,
556 "No printing function for this routing protocol\n"); 555 "No printing function for this routing protocol\n");
557 return 0; 556 return 0;
558 } 557 }
559 558
560 bat_priv->algo_ops->gw.print(bat_priv, seq); 559 bat_priv->algo_ops->gw.print(bat_priv, seq);
561 560
562 return 0; 561 return 0;
563 } 562 }
564 #endif 563 #endif
565 564
566 /** 565 /**
567 * batadv_gw_dump() - Dump gateways into a message 566 * batadv_gw_dump() - Dump gateways into a message
568 * @msg: Netlink message to dump into 567 * @msg: Netlink message to dump into
569 * @cb: Control block containing additional options 568 * @cb: Control block containing additional options
570 * 569 *
571 * Return: Error code, or length of message 570 * Return: Error code, or length of message
572 */ 571 */
573 int batadv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb) 572 int batadv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb)
574 { 573 {
575 struct batadv_hard_iface *primary_if = NULL; 574 struct batadv_hard_iface *primary_if = NULL;
576 struct net *net = sock_net(cb->skb->sk); 575 struct net *net = sock_net(cb->skb->sk);
577 struct net_device *soft_iface; 576 struct net_device *soft_iface;
578 struct batadv_priv *bat_priv; 577 struct batadv_priv *bat_priv;
579 int ifindex; 578 int ifindex;
580 int ret; 579 int ret;
581 580
582 ifindex = batadv_netlink_get_ifindex(cb->nlh, 581 ifindex = batadv_netlink_get_ifindex(cb->nlh,
583 BATADV_ATTR_MESH_IFINDEX); 582 BATADV_ATTR_MESH_IFINDEX);
584 if (!ifindex) 583 if (!ifindex)
585 return -EINVAL; 584 return -EINVAL;
586 585
587 soft_iface = dev_get_by_index(net, ifindex); 586 soft_iface = dev_get_by_index(net, ifindex);
588 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { 587 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
589 ret = -ENODEV; 588 ret = -ENODEV;
590 goto out; 589 goto out;
591 } 590 }
592 591
593 bat_priv = netdev_priv(soft_iface); 592 bat_priv = netdev_priv(soft_iface);
594 593
595 primary_if = batadv_primary_if_get_selected(bat_priv); 594 primary_if = batadv_primary_if_get_selected(bat_priv);
596 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { 595 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
597 ret = -ENOENT; 596 ret = -ENOENT;
598 goto out; 597 goto out;
599 } 598 }
600 599
601 if (!bat_priv->algo_ops->gw.dump) { 600 if (!bat_priv->algo_ops->gw.dump) {
602 ret = -EOPNOTSUPP; 601 ret = -EOPNOTSUPP;
603 goto out; 602 goto out;
604 } 603 }
605 604
606 bat_priv->algo_ops->gw.dump(msg, cb, bat_priv); 605 bat_priv->algo_ops->gw.dump(msg, cb, bat_priv);
607 606
608 ret = msg->len; 607 ret = msg->len;
609 608
610 out: 609 out:
611 if (primary_if) 610 if (primary_if)
612 batadv_hardif_put(primary_if); 611 batadv_hardif_put(primary_if);
613 if (soft_iface) 612 if (soft_iface)
614 dev_put(soft_iface); 613 dev_put(soft_iface);
615 614
616 return ret; 615 return ret;
617 } 616 }
618 617
619 /** 618 /**
620 * batadv_gw_dhcp_recipient_get() - check if a packet is a DHCP message 619 * batadv_gw_dhcp_recipient_get() - check if a packet is a DHCP message
621 * @skb: the packet to check 620 * @skb: the packet to check
622 * @header_len: a pointer to the batman-adv header size 621 * @header_len: a pointer to the batman-adv header size
623 * @chaddr: buffer where the client address will be stored. Valid 622 * @chaddr: buffer where the client address will be stored. Valid
624 * only if the function returns BATADV_DHCP_TO_CLIENT 623 * only if the function returns BATADV_DHCP_TO_CLIENT
625 * 624 *
626 * This function may re-allocate the data buffer of the skb passed as argument. 625 * This function may re-allocate the data buffer of the skb passed as argument.
627 * 626 *
628 * Return: 627 * Return:
629 * - BATADV_DHCP_NO if the packet is not a dhcp message or if there was an error 628 * - BATADV_DHCP_NO if the packet is not a dhcp message or if there was an error
630 * while parsing it 629 * while parsing it
631 * - BATADV_DHCP_TO_SERVER if this is a message going to the DHCP server 630 * - BATADV_DHCP_TO_SERVER if this is a message going to the DHCP server
632 * - BATADV_DHCP_TO_CLIENT if this is a message going to a DHCP client 631 * - BATADV_DHCP_TO_CLIENT if this is a message going to a DHCP client
633 */ 632 */
634 enum batadv_dhcp_recipient 633 enum batadv_dhcp_recipient
635 batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len, 634 batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
636 u8 *chaddr) 635 u8 *chaddr)
637 { 636 {
638 enum batadv_dhcp_recipient ret = BATADV_DHCP_NO; 637 enum batadv_dhcp_recipient ret = BATADV_DHCP_NO;
639 struct ethhdr *ethhdr; 638 struct ethhdr *ethhdr;
640 struct iphdr *iphdr; 639 struct iphdr *iphdr;
641 struct ipv6hdr *ipv6hdr; 640 struct ipv6hdr *ipv6hdr;
642 struct udphdr *udphdr; 641 struct udphdr *udphdr;
643 struct vlan_ethhdr *vhdr; 642 struct vlan_ethhdr *vhdr;
644 int chaddr_offset; 643 int chaddr_offset;
645 __be16 proto; 644 __be16 proto;
646 u8 *p; 645 u8 *p;
647 646
648 /* check for ethernet header */ 647 /* check for ethernet header */
649 if (!pskb_may_pull(skb, *header_len + ETH_HLEN)) 648 if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
650 return BATADV_DHCP_NO; 649 return BATADV_DHCP_NO;
651 650
652 ethhdr = eth_hdr(skb); 651 ethhdr = eth_hdr(skb);
653 proto = ethhdr->h_proto; 652 proto = ethhdr->h_proto;
654 *header_len += ETH_HLEN; 653 *header_len += ETH_HLEN;
655 654
656 /* check for initial vlan header */ 655 /* check for initial vlan header */
657 if (proto == htons(ETH_P_8021Q)) { 656 if (proto == htons(ETH_P_8021Q)) {
658 if (!pskb_may_pull(skb, *header_len + VLAN_HLEN)) 657 if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
659 return BATADV_DHCP_NO; 658 return BATADV_DHCP_NO;
660 659
661 vhdr = vlan_eth_hdr(skb); 660 vhdr = vlan_eth_hdr(skb);
662 proto = vhdr->h_vlan_encapsulated_proto; 661 proto = vhdr->h_vlan_encapsulated_proto;
663 *header_len += VLAN_HLEN; 662 *header_len += VLAN_HLEN;
664 } 663 }
665 664
666 /* check for ip header */ 665 /* check for ip header */
667 switch (proto) { 666 switch (proto) {
668 case htons(ETH_P_IP): 667 case htons(ETH_P_IP):
669 if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr))) 668 if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
670 return BATADV_DHCP_NO; 669 return BATADV_DHCP_NO;
671 670
672 iphdr = (struct iphdr *)(skb->data + *header_len); 671 iphdr = (struct iphdr *)(skb->data + *header_len);
673 *header_len += iphdr->ihl * 4; 672 *header_len += iphdr->ihl * 4;
674 673
675 /* check for udp header */ 674 /* check for udp header */
676 if (iphdr->protocol != IPPROTO_UDP) 675 if (iphdr->protocol != IPPROTO_UDP)
677 return BATADV_DHCP_NO; 676 return BATADV_DHCP_NO;
678 677
679 break; 678 break;
680 case htons(ETH_P_IPV6): 679 case htons(ETH_P_IPV6):
681 if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr))) 680 if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
682 return BATADV_DHCP_NO; 681 return BATADV_DHCP_NO;
683 682
684 ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len); 683 ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
685 *header_len += sizeof(*ipv6hdr); 684 *header_len += sizeof(*ipv6hdr);
686 685
687 /* check for udp header */ 686 /* check for udp header */
688 if (ipv6hdr->nexthdr != IPPROTO_UDP) 687 if (ipv6hdr->nexthdr != IPPROTO_UDP)
689 return BATADV_DHCP_NO; 688 return BATADV_DHCP_NO;
690 689
691 break; 690 break;
692 default: 691 default:
693 return BATADV_DHCP_NO; 692 return BATADV_DHCP_NO;
694 } 693 }
695 694
696 if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr))) 695 if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr)))
697 return BATADV_DHCP_NO; 696 return BATADV_DHCP_NO;
698 697
699 udphdr = (struct udphdr *)(skb->data + *header_len); 698 udphdr = (struct udphdr *)(skb->data + *header_len);
700 *header_len += sizeof(*udphdr); 699 *header_len += sizeof(*udphdr);
701 700
702 /* check for bootp port */ 701 /* check for bootp port */
703 switch (proto) { 702 switch (proto) {
704 case htons(ETH_P_IP): 703 case htons(ETH_P_IP):
705 if (udphdr->dest == htons(67)) 704 if (udphdr->dest == htons(67))
706 ret = BATADV_DHCP_TO_SERVER; 705 ret = BATADV_DHCP_TO_SERVER;
707 else if (udphdr->source == htons(67)) 706 else if (udphdr->source == htons(67))
708 ret = BATADV_DHCP_TO_CLIENT; 707 ret = BATADV_DHCP_TO_CLIENT;
709 break; 708 break;
710 case htons(ETH_P_IPV6): 709 case htons(ETH_P_IPV6):
711 if (udphdr->dest == htons(547)) 710 if (udphdr->dest == htons(547))
712 ret = BATADV_DHCP_TO_SERVER; 711 ret = BATADV_DHCP_TO_SERVER;
713 else if (udphdr->source == htons(547)) 712 else if (udphdr->source == htons(547))
714 ret = BATADV_DHCP_TO_CLIENT; 713 ret = BATADV_DHCP_TO_CLIENT;
715 break; 714 break;
716 } 715 }
717 716
718 chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET; 717 chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET;
719 /* store the client address if the message is going to a client */ 718 /* store the client address if the message is going to a client */
720 if (ret == BATADV_DHCP_TO_CLIENT && 719 if (ret == BATADV_DHCP_TO_CLIENT &&
721 pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) { 720 pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) {
722 /* check if the DHCP packet carries an Ethernet DHCP */ 721 /* check if the DHCP packet carries an Ethernet DHCP */
723 p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET; 722 p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET;
724 if (*p != BATADV_DHCP_HTYPE_ETHERNET) 723 if (*p != BATADV_DHCP_HTYPE_ETHERNET)
725 return BATADV_DHCP_NO; 724 return BATADV_DHCP_NO;
726 725
727 /* check if the DHCP packet carries a valid Ethernet address */ 726 /* check if the DHCP packet carries a valid Ethernet address */
728 p = skb->data + *header_len + BATADV_DHCP_HLEN_OFFSET; 727 p = skb->data + *header_len + BATADV_DHCP_HLEN_OFFSET;
729 if (*p != ETH_ALEN) 728 if (*p != ETH_ALEN)
730 return BATADV_DHCP_NO; 729 return BATADV_DHCP_NO;
731 730
732 ether_addr_copy(chaddr, skb->data + chaddr_offset); 731 ether_addr_copy(chaddr, skb->data + chaddr_offset);
733 } 732 }
734 733
735 return ret; 734 return ret;
736 } 735 }
737 736
738 /** 737 /**
739 * batadv_gw_out_of_range() - check if the dhcp request destination is the best 738 * batadv_gw_out_of_range() - check if the dhcp request destination is the best
740 * gateway 739 * gateway
741 * @bat_priv: the bat priv with all the soft interface information 740 * @bat_priv: the bat priv with all the soft interface information
742 * @skb: the outgoing packet 741 * @skb: the outgoing packet
743 * 742 *
744 * Check if the skb is a DHCP request and if it is sent to the current best GW 743 * Check if the skb is a DHCP request and if it is sent to the current best GW
745 * server. Due to topology changes it may be the case that the GW server 744 * server. Due to topology changes it may be the case that the GW server
746 * previously selected is not the best one anymore. 745 * previously selected is not the best one anymore.
747 * 746 *
748 * This call might reallocate skb data. 747 * This call might reallocate skb data.
749 * Must be invoked only when the DHCP packet is going TO a DHCP SERVER. 748 * Must be invoked only when the DHCP packet is going TO a DHCP SERVER.
750 * 749 *
751 * Return: true if the packet destination is unicast and it is not the best gw, 750 * Return: true if the packet destination is unicast and it is not the best gw,
752 * false otherwise. 751 * false otherwise.
753 */ 752 */
754 bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, 753 bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
755 struct sk_buff *skb) 754 struct sk_buff *skb)
756 { 755 {
757 struct batadv_neigh_node *neigh_curr = NULL; 756 struct batadv_neigh_node *neigh_curr = NULL;
758 struct batadv_neigh_node *neigh_old = NULL; 757 struct batadv_neigh_node *neigh_old = NULL;
759 struct batadv_orig_node *orig_dst_node = NULL; 758 struct batadv_orig_node *orig_dst_node = NULL;
760 struct batadv_gw_node *gw_node = NULL; 759 struct batadv_gw_node *gw_node = NULL;
761 struct batadv_gw_node *curr_gw = NULL; 760 struct batadv_gw_node *curr_gw = NULL;
762 struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo; 761 struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
763 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 762 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
764 bool out_of_range = false; 763 bool out_of_range = false;
765 u8 curr_tq_avg; 764 u8 curr_tq_avg;
766 unsigned short vid; 765 unsigned short vid;
767 766
768 vid = batadv_get_vid(skb, 0); 767 vid = batadv_get_vid(skb, 0);
769 768
770 if (is_multicast_ether_addr(ethhdr->h_dest)) 769 if (is_multicast_ether_addr(ethhdr->h_dest))
771 goto out; 770 goto out;
772 771
773 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 772 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
774 ethhdr->h_dest, vid); 773 ethhdr->h_dest, vid);
775 if (!orig_dst_node) 774 if (!orig_dst_node)
776 goto out; 775 goto out;
777 776
778 gw_node = batadv_gw_node_get(bat_priv, orig_dst_node); 777 gw_node = batadv_gw_node_get(bat_priv, orig_dst_node);
779 if (!gw_node) 778 if (!gw_node)
780 goto out; 779 goto out;
781 780
782 switch (atomic_read(&bat_priv->gw.mode)) { 781 switch (atomic_read(&bat_priv->gw.mode)) {
783 case BATADV_GW_MODE_SERVER: 782 case BATADV_GW_MODE_SERVER:
784 /* If we are a GW then we are our best GW. We can artificially 783 /* If we are a GW then we are our best GW. We can artificially
785 * set the tq towards ourself as the maximum value 784 * set the tq towards ourself as the maximum value
786 */ 785 */
787 curr_tq_avg = BATADV_TQ_MAX_VALUE; 786 curr_tq_avg = BATADV_TQ_MAX_VALUE;
788 break; 787 break;
789 case BATADV_GW_MODE_CLIENT: 788 case BATADV_GW_MODE_CLIENT:
790 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 789 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
791 if (!curr_gw) 790 if (!curr_gw)
792 goto out; 791 goto out;
793 792
794 /* packet is going to our gateway */ 793 /* packet is going to our gateway */
795 if (curr_gw->orig_node == orig_dst_node) 794 if (curr_gw->orig_node == orig_dst_node)
796 goto out; 795 goto out;
797 796
798 /* If the dhcp packet has been sent to a different gw, 797 /* If the dhcp packet has been sent to a different gw,
799 * we have to evaluate whether the old gw is still 798 * we have to evaluate whether the old gw is still
800 * reliable enough 799 * reliable enough
801 */ 800 */
802 neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node, 801 neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node,
803 NULL); 802 NULL);
804 if (!neigh_curr) 803 if (!neigh_curr)
805 goto out; 804 goto out;
806 805
807 curr_ifinfo = batadv_neigh_ifinfo_get(neigh_curr, 806 curr_ifinfo = batadv_neigh_ifinfo_get(neigh_curr,
808 BATADV_IF_DEFAULT); 807 BATADV_IF_DEFAULT);
809 if (!curr_ifinfo) 808 if (!curr_ifinfo)
810 goto out; 809 goto out;
811 810
812 curr_tq_avg = curr_ifinfo->bat_iv.tq_avg; 811 curr_tq_avg = curr_ifinfo->bat_iv.tq_avg;
813 batadv_neigh_ifinfo_put(curr_ifinfo); 812 batadv_neigh_ifinfo_put(curr_ifinfo);
814 813
815 break; 814 break;
816 case BATADV_GW_MODE_OFF: 815 case BATADV_GW_MODE_OFF:
817 default: 816 default:
818 goto out; 817 goto out;
819 } 818 }
820 819
821 neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL); 820 neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL);
822 if (!neigh_old) 821 if (!neigh_old)
823 goto out; 822 goto out;
824 823
825 old_ifinfo = batadv_neigh_ifinfo_get(neigh_old, BATADV_IF_DEFAULT); 824 old_ifinfo = batadv_neigh_ifinfo_get(neigh_old, BATADV_IF_DEFAULT);
826 if (!old_ifinfo) 825 if (!old_ifinfo)
827 goto out; 826 goto out;
828 827
829 if ((curr_tq_avg - old_ifinfo->bat_iv.tq_avg) > BATADV_GW_THRESHOLD) 828 if ((curr_tq_avg - old_ifinfo->bat_iv.tq_avg) > BATADV_GW_THRESHOLD)
830 out_of_range = true; 829 out_of_range = true;
831 batadv_neigh_ifinfo_put(old_ifinfo); 830 batadv_neigh_ifinfo_put(old_ifinfo);
832 831
833 out: 832 out:
834 if (orig_dst_node) 833 if (orig_dst_node)
835 batadv_orig_node_put(orig_dst_node); 834 batadv_orig_node_put(orig_dst_node);
836 if (curr_gw) 835 if (curr_gw)
837 batadv_gw_node_put(curr_gw); 836 batadv_gw_node_put(curr_gw);
838 if (gw_node) 837 if (gw_node)
839 batadv_gw_node_put(gw_node); 838 batadv_gw_node_put(gw_node);
840 if (neigh_old) 839 if (neigh_old)
841 batadv_neigh_node_put(neigh_old); 840 batadv_neigh_node_put(neigh_old);
842 if (neigh_curr) 841 if (neigh_curr)
843 batadv_neigh_node_put(neigh_curr); 842 batadv_neigh_node_put(neigh_curr);
844 return out_of_range; 843 return out_of_range;
845 } 844 }
846 845
net/batman-adv/gateway_common.c
1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors: 2 /* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation. 8 * License as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details. 13 * General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include "gateway_common.h" 19 #include "gateway_common.h"
20 #include "main.h" 20 #include "main.h"
21 21
22 #include <linux/atomic.h> 22 #include <linux/atomic.h>
23 #include <linux/byteorder/generic.h> 23 #include <linux/byteorder/generic.h>
24 #include <linux/errno.h> 24 #include <linux/errno.h>
25 #include <linux/kernel.h> 25 #include <linux/kernel.h>
26 #include <linux/math64.h> 26 #include <linux/math64.h>
27 #include <linux/netdevice.h> 27 #include <linux/netdevice.h>
28 #include <linux/stddef.h> 28 #include <linux/stddef.h>
29 #include <linux/string.h> 29 #include <linux/string.h>
30 #include <uapi/linux/batadv_packet.h> 30 #include <uapi/linux/batadv_packet.h>
31 #include <uapi/linux/batman_adv.h>
31 32
32 #include "gateway_client.h" 33 #include "gateway_client.h"
33 #include "log.h" 34 #include "log.h"
34 #include "tvlv.h" 35 #include "tvlv.h"
35 36
36 /** 37 /**
37 * batadv_parse_throughput() - parse supplied string buffer to extract 38 * batadv_parse_throughput() - parse supplied string buffer to extract
38 * throughput information 39 * throughput information
39 * @net_dev: the soft interface net device 40 * @net_dev: the soft interface net device
40 * @buff: string buffer to parse 41 * @buff: string buffer to parse
41 * @description: text shown when throughput string cannot be parsed 42 * @description: text shown when throughput string cannot be parsed
42 * @throughput: pointer holding the returned throughput information 43 * @throughput: pointer holding the returned throughput information
43 * 44 *
44 * Return: false on parse error and true otherwise. 45 * Return: false on parse error and true otherwise.
45 */ 46 */
46 bool batadv_parse_throughput(struct net_device *net_dev, char *buff, 47 bool batadv_parse_throughput(struct net_device *net_dev, char *buff,
47 const char *description, u32 *throughput) 48 const char *description, u32 *throughput)
48 { 49 {
49 enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT; 50 enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT;
50 u64 lthroughput; 51 u64 lthroughput;
51 char *tmp_ptr; 52 char *tmp_ptr;
52 int ret; 53 int ret;
53 54
54 if (strlen(buff) > 4) { 55 if (strlen(buff) > 4) {
55 tmp_ptr = buff + strlen(buff) - 4; 56 tmp_ptr = buff + strlen(buff) - 4;
56 57
57 if (strncasecmp(tmp_ptr, "mbit", 4) == 0) 58 if (strncasecmp(tmp_ptr, "mbit", 4) == 0)
58 bw_unit_type = BATADV_BW_UNIT_MBIT; 59 bw_unit_type = BATADV_BW_UNIT_MBIT;
59 60
60 if (strncasecmp(tmp_ptr, "kbit", 4) == 0 || 61 if (strncasecmp(tmp_ptr, "kbit", 4) == 0 ||
61 bw_unit_type == BATADV_BW_UNIT_MBIT) 62 bw_unit_type == BATADV_BW_UNIT_MBIT)
62 *tmp_ptr = '\0'; 63 *tmp_ptr = '\0';
63 } 64 }
64 65
65 ret = kstrtou64(buff, 10, &lthroughput); 66 ret = kstrtou64(buff, 10, &lthroughput);
66 if (ret) { 67 if (ret) {
67 batadv_err(net_dev, 68 batadv_err(net_dev,
68 "Invalid throughput speed for %s: %s\n", 69 "Invalid throughput speed for %s: %s\n",
69 description, buff); 70 description, buff);
70 return false; 71 return false;
71 } 72 }
72 73
73 switch (bw_unit_type) { 74 switch (bw_unit_type) {
74 case BATADV_BW_UNIT_MBIT: 75 case BATADV_BW_UNIT_MBIT:
75 /* prevent overflow */ 76 /* prevent overflow */
76 if (U64_MAX / 10 < lthroughput) { 77 if (U64_MAX / 10 < lthroughput) {
77 batadv_err(net_dev, 78 batadv_err(net_dev,
78 "Throughput speed for %s too large: %s\n", 79 "Throughput speed for %s too large: %s\n",
79 description, buff); 80 description, buff);
80 return false; 81 return false;
81 } 82 }
82 83
83 lthroughput *= 10; 84 lthroughput *= 10;
84 break; 85 break;
85 case BATADV_BW_UNIT_KBIT: 86 case BATADV_BW_UNIT_KBIT:
86 default: 87 default:
87 lthroughput = div_u64(lthroughput, 100); 88 lthroughput = div_u64(lthroughput, 100);
88 break; 89 break;
89 } 90 }
90 91
91 if (lthroughput > U32_MAX) { 92 if (lthroughput > U32_MAX) {
92 batadv_err(net_dev, 93 batadv_err(net_dev,
93 "Throughput speed for %s too large: %s\n", 94 "Throughput speed for %s too large: %s\n",
94 description, buff); 95 description, buff);
95 return false; 96 return false;
96 } 97 }
97 98
98 *throughput = lthroughput; 99 *throughput = lthroughput;
99 100
100 return true; 101 return true;
101 } 102 }
102 103
103 /** 104 /**
104 * batadv_parse_gw_bandwidth() - parse supplied string buffer to extract 105 * batadv_parse_gw_bandwidth() - parse supplied string buffer to extract
105 * download and upload bandwidth information 106 * download and upload bandwidth information
106 * @net_dev: the soft interface net device 107 * @net_dev: the soft interface net device
107 * @buff: string buffer to parse 108 * @buff: string buffer to parse
108 * @down: pointer holding the returned download bandwidth information 109 * @down: pointer holding the returned download bandwidth information
109 * @up: pointer holding the returned upload bandwidth information 110 * @up: pointer holding the returned upload bandwidth information
110 * 111 *
111 * Return: false on parse error and true otherwise. 112 * Return: false on parse error and true otherwise.
112 */ 113 */
113 static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, 114 static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
114 u32 *down, u32 *up) 115 u32 *down, u32 *up)
115 { 116 {
116 char *slash_ptr; 117 char *slash_ptr;
117 bool ret; 118 bool ret;
118 119
119 slash_ptr = strchr(buff, '/'); 120 slash_ptr = strchr(buff, '/');
120 if (slash_ptr) 121 if (slash_ptr)
121 *slash_ptr = 0; 122 *slash_ptr = 0;
122 123
123 ret = batadv_parse_throughput(net_dev, buff, "download gateway speed", 124 ret = batadv_parse_throughput(net_dev, buff, "download gateway speed",
124 down); 125 down);
125 if (!ret) 126 if (!ret)
126 return false; 127 return false;
127 128
128 /* we also got some upload info */ 129 /* we also got some upload info */
129 if (slash_ptr) { 130 if (slash_ptr) {
130 ret = batadv_parse_throughput(net_dev, slash_ptr + 1, 131 ret = batadv_parse_throughput(net_dev, slash_ptr + 1,
131 "upload gateway speed", up); 132 "upload gateway speed", up);
132 if (!ret) 133 if (!ret)
133 return false; 134 return false;
134 } 135 }
135 136
136 return true; 137 return true;
137 } 138 }
138 139
139 /** 140 /**
140 * batadv_gw_tvlv_container_update() - update the gw tvlv container after 141 * batadv_gw_tvlv_container_update() - update the gw tvlv container after
141 * gateway setting change 142 * gateway setting change
142 * @bat_priv: the bat priv with all the soft interface information 143 * @bat_priv: the bat priv with all the soft interface information
143 */ 144 */
144 void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv) 145 void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
145 { 146 {
146 struct batadv_tvlv_gateway_data gw; 147 struct batadv_tvlv_gateway_data gw;
147 u32 down, up; 148 u32 down, up;
148 char gw_mode; 149 char gw_mode;
149 150
150 gw_mode = atomic_read(&bat_priv->gw.mode); 151 gw_mode = atomic_read(&bat_priv->gw.mode);
151 152
152 switch (gw_mode) { 153 switch (gw_mode) {
153 case BATADV_GW_MODE_OFF: 154 case BATADV_GW_MODE_OFF:
154 case BATADV_GW_MODE_CLIENT: 155 case BATADV_GW_MODE_CLIENT:
155 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1); 156 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
156 break; 157 break;
157 case BATADV_GW_MODE_SERVER: 158 case BATADV_GW_MODE_SERVER:
158 down = atomic_read(&bat_priv->gw.bandwidth_down); 159 down = atomic_read(&bat_priv->gw.bandwidth_down);
159 up = atomic_read(&bat_priv->gw.bandwidth_up); 160 up = atomic_read(&bat_priv->gw.bandwidth_up);
160 gw.bandwidth_down = htonl(down); 161 gw.bandwidth_down = htonl(down);
161 gw.bandwidth_up = htonl(up); 162 gw.bandwidth_up = htonl(up);
162 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1, 163 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
163 &gw, sizeof(gw)); 164 &gw, sizeof(gw));
164 break; 165 break;
165 } 166 }
166 } 167 }
167 168
168 /** 169 /**
169 * batadv_gw_bandwidth_set() - Parse and set download/upload gateway bandwidth 170 * batadv_gw_bandwidth_set() - Parse and set download/upload gateway bandwidth
170 * from supplied string buffer 171 * from supplied string buffer
171 * @net_dev: netdev struct of the soft interface 172 * @net_dev: netdev struct of the soft interface
172 * @buff: the buffer containing the user data 173 * @buff: the buffer containing the user data
173 * @count: number of bytes in the buffer 174 * @count: number of bytes in the buffer
174 * 175 *
175 * Return: 'count' on success or a negative error code in case of failure 176 * Return: 'count' on success or a negative error code in case of failure
176 */ 177 */
177 ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, 178 ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
178 size_t count) 179 size_t count)
179 { 180 {
180 struct batadv_priv *bat_priv = netdev_priv(net_dev); 181 struct batadv_priv *bat_priv = netdev_priv(net_dev);
181 u32 down_curr; 182 u32 down_curr;
182 u32 up_curr; 183 u32 up_curr;
183 u32 down_new = 0; 184 u32 down_new = 0;
184 u32 up_new = 0; 185 u32 up_new = 0;
185 bool ret; 186 bool ret;
186 187
187 down_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_down); 188 down_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_down);
188 up_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_up); 189 up_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_up);
189 190
190 ret = batadv_parse_gw_bandwidth(net_dev, buff, &down_new, &up_new); 191 ret = batadv_parse_gw_bandwidth(net_dev, buff, &down_new, &up_new);
191 if (!ret) 192 if (!ret)
192 return -EINVAL; 193 return -EINVAL;
193 194
194 if (!down_new) 195 if (!down_new)
195 down_new = 1; 196 down_new = 1;
196 197
197 if (!up_new) 198 if (!up_new)
198 up_new = down_new / 5; 199 up_new = down_new / 5;
199 200
200 if (!up_new) 201 if (!up_new)
201 up_new = 1; 202 up_new = 1;
202 203
203 if (down_curr == down_new && up_curr == up_new) 204 if (down_curr == down_new && up_curr == up_new)
204 return count; 205 return count;
205 206
206 batadv_gw_reselect(bat_priv); 207 batadv_gw_reselect(bat_priv);
207 batadv_info(net_dev, 208 batadv_info(net_dev,
208 "Changing gateway bandwidth from: '%u.%u/%u.%u MBit' to: '%u.%u/%u.%u MBit'\n", 209 "Changing gateway bandwidth from: '%u.%u/%u.%u MBit' to: '%u.%u/%u.%u MBit'\n",
209 down_curr / 10, down_curr % 10, up_curr / 10, up_curr % 10, 210 down_curr / 10, down_curr % 10, up_curr / 10, up_curr % 10,
210 down_new / 10, down_new % 10, up_new / 10, up_new % 10); 211 down_new / 10, down_new % 10, up_new / 10, up_new % 10);
211 212
212 atomic_set(&bat_priv->gw.bandwidth_down, down_new); 213 atomic_set(&bat_priv->gw.bandwidth_down, down_new);
213 atomic_set(&bat_priv->gw.bandwidth_up, up_new); 214 atomic_set(&bat_priv->gw.bandwidth_up, up_new);
214 batadv_gw_tvlv_container_update(bat_priv); 215 batadv_gw_tvlv_container_update(bat_priv);
215 216
216 return count; 217 return count;
217 } 218 }
218 219
219 /** 220 /**
220 * batadv_gw_tvlv_ogm_handler_v1() - process incoming gateway tvlv container 221 * batadv_gw_tvlv_ogm_handler_v1() - process incoming gateway tvlv container
221 * @bat_priv: the bat priv with all the soft interface information 222 * @bat_priv: the bat priv with all the soft interface information
222 * @orig: the orig_node of the ogm 223 * @orig: the orig_node of the ogm
223 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) 224 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
224 * @tvlv_value: tvlv buffer containing the gateway data 225 * @tvlv_value: tvlv buffer containing the gateway data
225 * @tvlv_value_len: tvlv buffer length 226 * @tvlv_value_len: tvlv buffer length
226 */ 227 */
227 static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, 228 static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
228 struct batadv_orig_node *orig, 229 struct batadv_orig_node *orig,
229 u8 flags, 230 u8 flags,
230 void *tvlv_value, u16 tvlv_value_len) 231 void *tvlv_value, u16 tvlv_value_len)
231 { 232 {
232 struct batadv_tvlv_gateway_data gateway, *gateway_ptr; 233 struct batadv_tvlv_gateway_data gateway, *gateway_ptr;
233 234
234 /* only fetch the tvlv value if the handler wasn't called via the 235 /* only fetch the tvlv value if the handler wasn't called via the
235 * CIFNOTFND flag and if there is data to fetch 236 * CIFNOTFND flag and if there is data to fetch
236 */ 237 */
237 if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND || 238 if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND ||
238 tvlv_value_len < sizeof(gateway)) { 239 tvlv_value_len < sizeof(gateway)) {
239 gateway.bandwidth_down = 0; 240 gateway.bandwidth_down = 0;
240 gateway.bandwidth_up = 0; 241 gateway.bandwidth_up = 0;
241 } else { 242 } else {
242 gateway_ptr = tvlv_value; 243 gateway_ptr = tvlv_value;
243 gateway.bandwidth_down = gateway_ptr->bandwidth_down; 244 gateway.bandwidth_down = gateway_ptr->bandwidth_down;
244 gateway.bandwidth_up = gateway_ptr->bandwidth_up; 245 gateway.bandwidth_up = gateway_ptr->bandwidth_up;
245 if (gateway.bandwidth_down == 0 || 246 if (gateway.bandwidth_down == 0 ||
246 gateway.bandwidth_up == 0) { 247 gateway.bandwidth_up == 0) {
247 gateway.bandwidth_down = 0; 248 gateway.bandwidth_down = 0;
248 gateway.bandwidth_up = 0; 249 gateway.bandwidth_up = 0;
249 } 250 }
250 } 251 }
251 252
252 batadv_gw_node_update(bat_priv, orig, &gateway); 253 batadv_gw_node_update(bat_priv, orig, &gateway);
253 254
254 /* restart gateway selection */ 255 /* restart gateway selection */
255 if (gateway.bandwidth_down != 0 && 256 if (gateway.bandwidth_down != 0 &&
256 atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT) 257 atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT)
257 batadv_gw_check_election(bat_priv, orig); 258 batadv_gw_check_election(bat_priv, orig);
258 } 259 }
259 260
260 /** 261 /**
261 * batadv_gw_init() - initialise the gateway handling internals 262 * batadv_gw_init() - initialise the gateway handling internals
262 * @bat_priv: the bat priv with all the soft interface information 263 * @bat_priv: the bat priv with all the soft interface information
263 */ 264 */
264 void batadv_gw_init(struct batadv_priv *bat_priv) 265 void batadv_gw_init(struct batadv_priv *bat_priv)
265 { 266 {
266 if (bat_priv->algo_ops->gw.init_sel_class) 267 if (bat_priv->algo_ops->gw.init_sel_class)
267 bat_priv->algo_ops->gw.init_sel_class(bat_priv); 268 bat_priv->algo_ops->gw.init_sel_class(bat_priv);
268 else 269 else
269 atomic_set(&bat_priv->gw.sel_class, 1); 270 atomic_set(&bat_priv->gw.sel_class, 1);
270 271
271 batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1, 272 batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
272 NULL, BATADV_TVLV_GW, 1, 273 NULL, BATADV_TVLV_GW, 1,
273 BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 274 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
274 } 275 }
275 276
276 /** 277 /**
277 * batadv_gw_free() - free the gateway handling internals 278 * batadv_gw_free() - free the gateway handling internals
278 * @bat_priv: the bat priv with all the soft interface information 279 * @bat_priv: the bat priv with all the soft interface information
279 */ 280 */
280 void batadv_gw_free(struct batadv_priv *bat_priv) 281 void batadv_gw_free(struct batadv_priv *bat_priv)
281 { 282 {
282 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1); 283 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
283 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1); 284 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1);
284 } 285 }
285 286
net/batman-adv/gateway_common.h
1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors: 2 /* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation. 8 * License as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details. 13 * General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_ 19 #ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_
20 #define _NET_BATMAN_ADV_GATEWAY_COMMON_H_ 20 #define _NET_BATMAN_ADV_GATEWAY_COMMON_H_
21 21
22 #include "main.h" 22 #include "main.h"
23 23
24 #include <linux/types.h> 24 #include <linux/types.h>
25 25
26 struct net_device; 26 struct net_device;
27 27
28 enum batadv_gw_modes {
29 BATADV_GW_MODE_OFF,
30 BATADV_GW_MODE_CLIENT,
31 BATADV_GW_MODE_SERVER,
32 };
33
34 /** 28 /**
35 * enum batadv_bandwidth_units - bandwidth unit types 29 * enum batadv_bandwidth_units - bandwidth unit types
36 */ 30 */
37 enum batadv_bandwidth_units { 31 enum batadv_bandwidth_units {
38 /** @BATADV_BW_UNIT_KBIT: unit type kbit */ 32 /** @BATADV_BW_UNIT_KBIT: unit type kbit */
39 BATADV_BW_UNIT_KBIT, 33 BATADV_BW_UNIT_KBIT,
40 34
41 /** @BATADV_BW_UNIT_MBIT: unit type mbit */ 35 /** @BATADV_BW_UNIT_MBIT: unit type mbit */
42 BATADV_BW_UNIT_MBIT, 36 BATADV_BW_UNIT_MBIT,
43 }; 37 };
44 38
45 #define BATADV_GW_MODE_OFF_NAME "off" 39 #define BATADV_GW_MODE_OFF_NAME "off"
46 #define BATADV_GW_MODE_CLIENT_NAME "client" 40 #define BATADV_GW_MODE_CLIENT_NAME "client"
47 #define BATADV_GW_MODE_SERVER_NAME "server" 41 #define BATADV_GW_MODE_SERVER_NAME "server"
48 42
49 ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, 43 ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
50 size_t count); 44 size_t count);
51 void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv); 45 void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv);
52 void batadv_gw_init(struct batadv_priv *bat_priv); 46 void batadv_gw_init(struct batadv_priv *bat_priv);
53 void batadv_gw_free(struct batadv_priv *bat_priv); 47 void batadv_gw_free(struct batadv_priv *bat_priv);
54 bool batadv_parse_throughput(struct net_device *net_dev, char *buff, 48 bool batadv_parse_throughput(struct net_device *net_dev, char *buff,
55 const char *description, u32 *throughput); 49 const char *description, u32 *throughput);
56 50
57 #endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ 51 #endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
58 52
net/batman-adv/netlink.c
1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2016-2019 B.A.T.M.A.N. contributors: 2 /* Copyright (C) 2016-2019 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Matthias Schiffer 4 * Matthias Schiffer
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation. 8 * License as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details. 13 * General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include "netlink.h" 19 #include "netlink.h"
20 #include "main.h" 20 #include "main.h"
21 21
22 #include <linux/atomic.h> 22 #include <linux/atomic.h>
23 #include <linux/bitops.h> 23 #include <linux/bitops.h>
24 #include <linux/bug.h> 24 #include <linux/bug.h>
25 #include <linux/byteorder/generic.h> 25 #include <linux/byteorder/generic.h>
26 #include <linux/cache.h> 26 #include <linux/cache.h>
27 #include <linux/err.h> 27 #include <linux/err.h>
28 #include <linux/errno.h> 28 #include <linux/errno.h>
29 #include <linux/export.h> 29 #include <linux/export.h>
30 #include <linux/genetlink.h> 30 #include <linux/genetlink.h>
31 #include <linux/gfp.h> 31 #include <linux/gfp.h>
32 #include <linux/if_ether.h> 32 #include <linux/if_ether.h>
33 #include <linux/if_vlan.h> 33 #include <linux/if_vlan.h>
34 #include <linux/init.h> 34 #include <linux/init.h>
35 #include <linux/kernel.h> 35 #include <linux/kernel.h>
36 #include <linux/list.h> 36 #include <linux/list.h>
37 #include <linux/netdevice.h> 37 #include <linux/netdevice.h>
38 #include <linux/netlink.h> 38 #include <linux/netlink.h>
39 #include <linux/printk.h> 39 #include <linux/printk.h>
40 #include <linux/rtnetlink.h> 40 #include <linux/rtnetlink.h>
41 #include <linux/skbuff.h> 41 #include <linux/skbuff.h>
42 #include <linux/stddef.h> 42 #include <linux/stddef.h>
43 #include <linux/types.h> 43 #include <linux/types.h>
44 #include <net/genetlink.h> 44 #include <net/genetlink.h>
45 #include <net/netlink.h> 45 #include <net/netlink.h>
46 #include <net/sock.h> 46 #include <net/sock.h>
47 #include <uapi/linux/batadv_packet.h> 47 #include <uapi/linux/batadv_packet.h>
48 #include <uapi/linux/batman_adv.h> 48 #include <uapi/linux/batman_adv.h>
49 49
50 #include "bat_algo.h" 50 #include "bat_algo.h"
51 #include "bridge_loop_avoidance.h" 51 #include "bridge_loop_avoidance.h"
52 #include "distributed-arp-table.h" 52 #include "distributed-arp-table.h"
53 #include "gateway_client.h" 53 #include "gateway_client.h"
54 #include "gateway_common.h"
54 #include "hard-interface.h" 55 #include "hard-interface.h"
55 #include "multicast.h" 56 #include "multicast.h"
56 #include "originator.h" 57 #include "originator.h"
57 #include "soft-interface.h" 58 #include "soft-interface.h"
58 #include "tp_meter.h" 59 #include "tp_meter.h"
59 #include "translation-table.h" 60 #include "translation-table.h"
60 61
61 struct net; 62 struct net;
62 63
63 struct genl_family batadv_netlink_family; 64 struct genl_family batadv_netlink_family;
64 65
65 /* multicast groups */ 66 /* multicast groups */
66 enum batadv_netlink_multicast_groups { 67 enum batadv_netlink_multicast_groups {
67 BATADV_NL_MCGRP_CONFIG, 68 BATADV_NL_MCGRP_CONFIG,
68 BATADV_NL_MCGRP_TPMETER, 69 BATADV_NL_MCGRP_TPMETER,
69 }; 70 };
70 71
71 /** 72 /**
72 * enum batadv_genl_ops_flags - flags for genl_ops's internal_flags 73 * enum batadv_genl_ops_flags - flags for genl_ops's internal_flags
73 */ 74 */
74 enum batadv_genl_ops_flags { 75 enum batadv_genl_ops_flags {
75 /** 76 /**
76 * @BATADV_FLAG_NEED_MESH: request requires valid soft interface in 77 * @BATADV_FLAG_NEED_MESH: request requires valid soft interface in
77 * attribute BATADV_ATTR_MESH_IFINDEX and expects a pointer to it to be 78 * attribute BATADV_ATTR_MESH_IFINDEX and expects a pointer to it to be
78 * saved in info->user_ptr[0] 79 * saved in info->user_ptr[0]
79 */ 80 */
80 BATADV_FLAG_NEED_MESH = BIT(0), 81 BATADV_FLAG_NEED_MESH = BIT(0),
81 82
82 /** 83 /**
83 * @BATADV_FLAG_NEED_HARDIF: request requires valid hard interface in 84 * @BATADV_FLAG_NEED_HARDIF: request requires valid hard interface in
84 * attribute BATADV_ATTR_HARD_IFINDEX and expects a pointer to it to be 85 * attribute BATADV_ATTR_HARD_IFINDEX and expects a pointer to it to be
85 * saved in info->user_ptr[1] 86 * saved in info->user_ptr[1]
86 */ 87 */
87 BATADV_FLAG_NEED_HARDIF = BIT(1), 88 BATADV_FLAG_NEED_HARDIF = BIT(1),
88 89
89 /** 90 /**
90 * @BATADV_FLAG_NEED_VLAN: request requires valid vlan in 91 * @BATADV_FLAG_NEED_VLAN: request requires valid vlan in
91 * attribute BATADV_ATTR_VLANID and expects a pointer to it to be 92 * attribute BATADV_ATTR_VLANID and expects a pointer to it to be
92 * saved in info->user_ptr[1] 93 * saved in info->user_ptr[1]
93 */ 94 */
94 BATADV_FLAG_NEED_VLAN = BIT(2), 95 BATADV_FLAG_NEED_VLAN = BIT(2),
95 }; 96 };
96 97
97 static const struct genl_multicast_group batadv_netlink_mcgrps[] = { 98 static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
98 [BATADV_NL_MCGRP_CONFIG] = { .name = BATADV_NL_MCAST_GROUP_CONFIG }, 99 [BATADV_NL_MCGRP_CONFIG] = { .name = BATADV_NL_MCAST_GROUP_CONFIG },
99 [BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER }, 100 [BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER },
100 }; 101 };
101 102
102 static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { 103 static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
103 [BATADV_ATTR_VERSION] = { .type = NLA_STRING }, 104 [BATADV_ATTR_VERSION] = { .type = NLA_STRING },
104 [BATADV_ATTR_ALGO_NAME] = { .type = NLA_STRING }, 105 [BATADV_ATTR_ALGO_NAME] = { .type = NLA_STRING },
105 [BATADV_ATTR_MESH_IFINDEX] = { .type = NLA_U32 }, 106 [BATADV_ATTR_MESH_IFINDEX] = { .type = NLA_U32 },
106 [BATADV_ATTR_MESH_IFNAME] = { .type = NLA_STRING }, 107 [BATADV_ATTR_MESH_IFNAME] = { .type = NLA_STRING },
107 [BATADV_ATTR_MESH_ADDRESS] = { .len = ETH_ALEN }, 108 [BATADV_ATTR_MESH_ADDRESS] = { .len = ETH_ALEN },
108 [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, 109 [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 },
109 [BATADV_ATTR_HARD_IFNAME] = { .type = NLA_STRING }, 110 [BATADV_ATTR_HARD_IFNAME] = { .type = NLA_STRING },
110 [BATADV_ATTR_HARD_ADDRESS] = { .len = ETH_ALEN }, 111 [BATADV_ATTR_HARD_ADDRESS] = { .len = ETH_ALEN },
111 [BATADV_ATTR_ORIG_ADDRESS] = { .len = ETH_ALEN }, 112 [BATADV_ATTR_ORIG_ADDRESS] = { .len = ETH_ALEN },
112 [BATADV_ATTR_TPMETER_RESULT] = { .type = NLA_U8 }, 113 [BATADV_ATTR_TPMETER_RESULT] = { .type = NLA_U8 },
113 [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NLA_U32 }, 114 [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NLA_U32 },
114 [BATADV_ATTR_TPMETER_BYTES] = { .type = NLA_U64 }, 115 [BATADV_ATTR_TPMETER_BYTES] = { .type = NLA_U64 },
115 [BATADV_ATTR_TPMETER_COOKIE] = { .type = NLA_U32 }, 116 [BATADV_ATTR_TPMETER_COOKIE] = { .type = NLA_U32 },
116 [BATADV_ATTR_ACTIVE] = { .type = NLA_FLAG }, 117 [BATADV_ATTR_ACTIVE] = { .type = NLA_FLAG },
117 [BATADV_ATTR_TT_ADDRESS] = { .len = ETH_ALEN }, 118 [BATADV_ATTR_TT_ADDRESS] = { .len = ETH_ALEN },
118 [BATADV_ATTR_TT_TTVN] = { .type = NLA_U8 }, 119 [BATADV_ATTR_TT_TTVN] = { .type = NLA_U8 },
119 [BATADV_ATTR_TT_LAST_TTVN] = { .type = NLA_U8 }, 120 [BATADV_ATTR_TT_LAST_TTVN] = { .type = NLA_U8 },
120 [BATADV_ATTR_TT_CRC32] = { .type = NLA_U32 }, 121 [BATADV_ATTR_TT_CRC32] = { .type = NLA_U32 },
121 [BATADV_ATTR_TT_VID] = { .type = NLA_U16 }, 122 [BATADV_ATTR_TT_VID] = { .type = NLA_U16 },
122 [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 }, 123 [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 },
123 [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG }, 124 [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG },
124 [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 }, 125 [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 },
125 [BATADV_ATTR_NEIGH_ADDRESS] = { .len = ETH_ALEN }, 126 [BATADV_ATTR_NEIGH_ADDRESS] = { .len = ETH_ALEN },
126 [BATADV_ATTR_TQ] = { .type = NLA_U8 }, 127 [BATADV_ATTR_TQ] = { .type = NLA_U8 },
127 [BATADV_ATTR_THROUGHPUT] = { .type = NLA_U32 }, 128 [BATADV_ATTR_THROUGHPUT] = { .type = NLA_U32 },
128 [BATADV_ATTR_BANDWIDTH_UP] = { .type = NLA_U32 }, 129 [BATADV_ATTR_BANDWIDTH_UP] = { .type = NLA_U32 },
129 [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NLA_U32 }, 130 [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NLA_U32 },
130 [BATADV_ATTR_ROUTER] = { .len = ETH_ALEN }, 131 [BATADV_ATTR_ROUTER] = { .len = ETH_ALEN },
131 [BATADV_ATTR_BLA_OWN] = { .type = NLA_FLAG }, 132 [BATADV_ATTR_BLA_OWN] = { .type = NLA_FLAG },
132 [BATADV_ATTR_BLA_ADDRESS] = { .len = ETH_ALEN }, 133 [BATADV_ATTR_BLA_ADDRESS] = { .len = ETH_ALEN },
133 [BATADV_ATTR_BLA_VID] = { .type = NLA_U16 }, 134 [BATADV_ATTR_BLA_VID] = { .type = NLA_U16 },
134 [BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN }, 135 [BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN },
135 [BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 }, 136 [BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 },
136 [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NLA_U32 }, 137 [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NLA_U32 },
137 [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .len = ETH_ALEN }, 138 [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .len = ETH_ALEN },
138 [BATADV_ATTR_DAT_CACHE_VID] = { .type = NLA_U16 }, 139 [BATADV_ATTR_DAT_CACHE_VID] = { .type = NLA_U16 },
139 [BATADV_ATTR_MCAST_FLAGS] = { .type = NLA_U32 }, 140 [BATADV_ATTR_MCAST_FLAGS] = { .type = NLA_U32 },
140 [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 }, 141 [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 },
141 [BATADV_ATTR_VLANID] = { .type = NLA_U16 }, 142 [BATADV_ATTR_VLANID] = { .type = NLA_U16 },
142 [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NLA_U8 }, 143 [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NLA_U8 },
143 [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NLA_U8 }, 144 [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NLA_U8 },
144 [BATADV_ATTR_ISOLATION_MARK] = { .type = NLA_U32 }, 145 [BATADV_ATTR_ISOLATION_MARK] = { .type = NLA_U32 },
145 [BATADV_ATTR_ISOLATION_MASK] = { .type = NLA_U32 }, 146 [BATADV_ATTR_ISOLATION_MASK] = { .type = NLA_U32 },
146 [BATADV_ATTR_BONDING_ENABLED] = { .type = NLA_U8 }, 147 [BATADV_ATTR_BONDING_ENABLED] = { .type = NLA_U8 },
147 [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NLA_U8 }, 148 [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NLA_U8 },
148 [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NLA_U8 }, 149 [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NLA_U8 },
149 [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NLA_U8 }, 150 [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NLA_U8 },
151 [BATADV_ATTR_GW_BANDWIDTH_DOWN] = { .type = NLA_U32 },
152 [BATADV_ATTR_GW_BANDWIDTH_UP] = { .type = NLA_U32 },
153 [BATADV_ATTR_GW_MODE] = { .type = NLA_U8 },
154 [BATADV_ATTR_GW_SEL_CLASS] = { .type = NLA_U32 },
150 }; 155 };
151 156
152 /** 157 /**
153 * batadv_netlink_get_ifindex() - Extract an interface index from a message 158 * batadv_netlink_get_ifindex() - Extract an interface index from a message
154 * @nlh: Message header 159 * @nlh: Message header
155 * @attrtype: Attribute which holds an interface index 160 * @attrtype: Attribute which holds an interface index
156 * 161 *
157 * Return: interface index, or 0. 162 * Return: interface index, or 0.
158 */ 163 */
159 int 164 int
160 batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype) 165 batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
161 { 166 {
162 struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype); 167 struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype);
163 168
164 return attr ? nla_get_u32(attr) : 0; 169 return attr ? nla_get_u32(attr) : 0;
165 } 170 }
166 171
167 /** 172 /**
168 * batadv_netlink_mesh_fill_ap_isolation() - Add ap_isolation softif attribute 173 * batadv_netlink_mesh_fill_ap_isolation() - Add ap_isolation softif attribute
169 * @msg: Netlink message to dump into 174 * @msg: Netlink message to dump into
170 * @bat_priv: the bat priv with all the soft interface information 175 * @bat_priv: the bat priv with all the soft interface information
171 * 176 *
172 * Return: 0 on success or negative error number in case of failure 177 * Return: 0 on success or negative error number in case of failure
173 */ 178 */
174 static int batadv_netlink_mesh_fill_ap_isolation(struct sk_buff *msg, 179 static int batadv_netlink_mesh_fill_ap_isolation(struct sk_buff *msg,
175 struct batadv_priv *bat_priv) 180 struct batadv_priv *bat_priv)
176 { 181 {
177 struct batadv_softif_vlan *vlan; 182 struct batadv_softif_vlan *vlan;
178 u8 ap_isolation; 183 u8 ap_isolation;
179 184
180 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); 185 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
181 if (!vlan) 186 if (!vlan)
182 return 0; 187 return 0;
183 188
184 ap_isolation = atomic_read(&vlan->ap_isolation); 189 ap_isolation = atomic_read(&vlan->ap_isolation);
185 batadv_softif_vlan_put(vlan); 190 batadv_softif_vlan_put(vlan);
186 191
187 return nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, 192 return nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED,
188 !!ap_isolation); 193 !!ap_isolation);
189 } 194 }
190 195
191 /** 196 /**
192 * batadv_option_set_ap_isolation() - Set ap_isolation from genl msg 197 * batadv_option_set_ap_isolation() - Set ap_isolation from genl msg
193 * @attr: parsed BATADV_ATTR_AP_ISOLATION_ENABLED attribute 198 * @attr: parsed BATADV_ATTR_AP_ISOLATION_ENABLED attribute
194 * @bat_priv: the bat priv with all the soft interface information 199 * @bat_priv: the bat priv with all the soft interface information
195 * 200 *
196 * Return: 0 on success or negative error number in case of failure 201 * Return: 0 on success or negative error number in case of failure
197 */ 202 */
198 static int batadv_netlink_set_mesh_ap_isolation(struct nlattr *attr, 203 static int batadv_netlink_set_mesh_ap_isolation(struct nlattr *attr,
199 struct batadv_priv *bat_priv) 204 struct batadv_priv *bat_priv)
200 { 205 {
201 struct batadv_softif_vlan *vlan; 206 struct batadv_softif_vlan *vlan;
202 207
203 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); 208 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
204 if (!vlan) 209 if (!vlan)
205 return -ENOENT; 210 return -ENOENT;
206 211
207 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr)); 212 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
208 batadv_softif_vlan_put(vlan); 213 batadv_softif_vlan_put(vlan);
209 214
210 return 0; 215 return 0;
211 } 216 }
212 217
213 /** 218 /**
214 * batadv_netlink_mesh_fill() - Fill message with mesh attributes 219 * batadv_netlink_mesh_fill() - Fill message with mesh attributes
215 * @msg: Netlink message to dump into 220 * @msg: Netlink message to dump into
216 * @bat_priv: the bat priv with all the soft interface information 221 * @bat_priv: the bat priv with all the soft interface information
217 * @cmd: type of message to generate 222 * @cmd: type of message to generate
218 * @portid: Port making netlink request 223 * @portid: Port making netlink request
219 * @seq: sequence number for message 224 * @seq: sequence number for message
220 * @flags: Additional flags for message 225 * @flags: Additional flags for message
221 * 226 *
222 * Return: 0 on success or negative error number in case of failure 227 * Return: 0 on success or negative error number in case of failure
223 */ 228 */
224 static int batadv_netlink_mesh_fill(struct sk_buff *msg, 229 static int batadv_netlink_mesh_fill(struct sk_buff *msg,
225 struct batadv_priv *bat_priv, 230 struct batadv_priv *bat_priv,
226 enum batadv_nl_commands cmd, 231 enum batadv_nl_commands cmd,
227 u32 portid, u32 seq, int flags) 232 u32 portid, u32 seq, int flags)
228 { 233 {
229 struct net_device *soft_iface = bat_priv->soft_iface; 234 struct net_device *soft_iface = bat_priv->soft_iface;
230 struct batadv_hard_iface *primary_if = NULL; 235 struct batadv_hard_iface *primary_if = NULL;
231 struct net_device *hard_iface; 236 struct net_device *hard_iface;
232 void *hdr; 237 void *hdr;
233 238
234 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 239 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
235 if (!hdr) 240 if (!hdr)
236 return -ENOBUFS; 241 return -ENOBUFS;
237 242
238 if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) || 243 if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) ||
239 nla_put_string(msg, BATADV_ATTR_ALGO_NAME, 244 nla_put_string(msg, BATADV_ATTR_ALGO_NAME,
240 bat_priv->algo_ops->name) || 245 bat_priv->algo_ops->name) ||
241 nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, soft_iface->ifindex) || 246 nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, soft_iface->ifindex) ||
242 nla_put_string(msg, BATADV_ATTR_MESH_IFNAME, soft_iface->name) || 247 nla_put_string(msg, BATADV_ATTR_MESH_IFNAME, soft_iface->name) ||
243 nla_put(msg, BATADV_ATTR_MESH_ADDRESS, ETH_ALEN, 248 nla_put(msg, BATADV_ATTR_MESH_ADDRESS, ETH_ALEN,
244 soft_iface->dev_addr) || 249 soft_iface->dev_addr) ||
245 nla_put_u8(msg, BATADV_ATTR_TT_TTVN, 250 nla_put_u8(msg, BATADV_ATTR_TT_TTVN,
246 (u8)atomic_read(&bat_priv->tt.vn))) 251 (u8)atomic_read(&bat_priv->tt.vn)))
247 goto nla_put_failure; 252 goto nla_put_failure;
248 253
249 #ifdef CONFIG_BATMAN_ADV_BLA 254 #ifdef CONFIG_BATMAN_ADV_BLA
250 if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC, 255 if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
251 ntohs(bat_priv->bla.claim_dest.group))) 256 ntohs(bat_priv->bla.claim_dest.group)))
252 goto nla_put_failure; 257 goto nla_put_failure;
253 #endif 258 #endif
254 259
255 if (batadv_mcast_mesh_info_put(msg, bat_priv)) 260 if (batadv_mcast_mesh_info_put(msg, bat_priv))
256 goto nla_put_failure; 261 goto nla_put_failure;
257 262
258 primary_if = batadv_primary_if_get_selected(bat_priv); 263 primary_if = batadv_primary_if_get_selected(bat_priv);
259 if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) { 264 if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) {
260 hard_iface = primary_if->net_dev; 265 hard_iface = primary_if->net_dev;
261 266
262 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, 267 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
263 hard_iface->ifindex) || 268 hard_iface->ifindex) ||
264 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, 269 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
265 hard_iface->name) || 270 hard_iface->name) ||
266 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN, 271 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN,
267 hard_iface->dev_addr)) 272 hard_iface->dev_addr))
268 goto nla_put_failure; 273 goto nla_put_failure;
269 } 274 }
270 275
271 if (nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS_ENABLED, 276 if (nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS_ENABLED,
272 !!atomic_read(&bat_priv->aggregated_ogms))) 277 !!atomic_read(&bat_priv->aggregated_ogms)))
273 goto nla_put_failure; 278 goto nla_put_failure;
274 279
275 if (batadv_netlink_mesh_fill_ap_isolation(msg, bat_priv)) 280 if (batadv_netlink_mesh_fill_ap_isolation(msg, bat_priv))
276 goto nla_put_failure; 281 goto nla_put_failure;
277 282
278 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MARK, 283 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MARK,
279 bat_priv->isolation_mark)) 284 bat_priv->isolation_mark))
280 goto nla_put_failure; 285 goto nla_put_failure;
281 286
282 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MASK, 287 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MASK,
283 bat_priv->isolation_mark_mask)) 288 bat_priv->isolation_mark_mask))
284 goto nla_put_failure; 289 goto nla_put_failure;
285 290
286 if (nla_put_u8(msg, BATADV_ATTR_BONDING_ENABLED, 291 if (nla_put_u8(msg, BATADV_ATTR_BONDING_ENABLED,
287 !!atomic_read(&bat_priv->bonding))) 292 !!atomic_read(&bat_priv->bonding)))
288 goto nla_put_failure; 293 goto nla_put_failure;
289 294
290 #ifdef CONFIG_BATMAN_ADV_BLA 295 #ifdef CONFIG_BATMAN_ADV_BLA
291 if (nla_put_u8(msg, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED, 296 if (nla_put_u8(msg, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED,
292 !!atomic_read(&bat_priv->bridge_loop_avoidance))) 297 !!atomic_read(&bat_priv->bridge_loop_avoidance)))
293 goto nla_put_failure; 298 goto nla_put_failure;
294 #endif /* CONFIG_BATMAN_ADV_BLA */ 299 #endif /* CONFIG_BATMAN_ADV_BLA */
295 300
296 #ifdef CONFIG_BATMAN_ADV_DAT 301 #ifdef CONFIG_BATMAN_ADV_DAT
297 if (nla_put_u8(msg, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED, 302 if (nla_put_u8(msg, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED,
298 !!atomic_read(&bat_priv->distributed_arp_table))) 303 !!atomic_read(&bat_priv->distributed_arp_table)))
299 goto nla_put_failure; 304 goto nla_put_failure;
300 #endif /* CONFIG_BATMAN_ADV_DAT */ 305 #endif /* CONFIG_BATMAN_ADV_DAT */
301 306
302 if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION_ENABLED, 307 if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION_ENABLED,
303 !!atomic_read(&bat_priv->fragmentation))) 308 !!atomic_read(&bat_priv->fragmentation)))
304 goto nla_put_failure; 309 goto nla_put_failure;
305 310
311 if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_DOWN,
312 atomic_read(&bat_priv->gw.bandwidth_down)))
313 goto nla_put_failure;
314
315 if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_UP,
316 atomic_read(&bat_priv->gw.bandwidth_up)))
317 goto nla_put_failure;
318
319 if (nla_put_u8(msg, BATADV_ATTR_GW_MODE,
320 atomic_read(&bat_priv->gw.mode)))
321 goto nla_put_failure;
322
323 if (bat_priv->algo_ops->gw.get_best_gw_node &&
324 bat_priv->algo_ops->gw.is_eligible) {
325 /* GW selection class is not available if the routing algorithm
326 * in use does not implement the GW API
327 */
328 if (nla_put_u32(msg, BATADV_ATTR_GW_SEL_CLASS,
329 atomic_read(&bat_priv->gw.sel_class)))
330 goto nla_put_failure;
331 }
332
306 if (primary_if) 333 if (primary_if)
307 batadv_hardif_put(primary_if); 334 batadv_hardif_put(primary_if);
308 335
309 genlmsg_end(msg, hdr); 336 genlmsg_end(msg, hdr);
310 return 0; 337 return 0;
311 338
312 nla_put_failure: 339 nla_put_failure:
313 if (primary_if) 340 if (primary_if)
314 batadv_hardif_put(primary_if); 341 batadv_hardif_put(primary_if);
315 342
316 genlmsg_cancel(msg, hdr); 343 genlmsg_cancel(msg, hdr);
317 return -EMSGSIZE; 344 return -EMSGSIZE;
318 } 345 }
319 346
320 /** 347 /**
321 * batadv_netlink_notify_mesh() - send softif attributes to listener 348 * batadv_netlink_notify_mesh() - send softif attributes to listener
322 * @bat_priv: the bat priv with all the soft interface information 349 * @bat_priv: the bat priv with all the soft interface information
323 * 350 *
324 * Return: 0 on success, < 0 on error 351 * Return: 0 on success, < 0 on error
325 */ 352 */
326 static int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv) 353 static int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv)
327 { 354 {
328 struct sk_buff *msg; 355 struct sk_buff *msg;
329 int ret; 356 int ret;
330 357
331 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 358 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
332 if (!msg) 359 if (!msg)
333 return -ENOMEM; 360 return -ENOMEM;
334 361
335 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_SET_MESH, 362 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_SET_MESH,
336 0, 0, 0); 363 0, 0, 0);
337 if (ret < 0) { 364 if (ret < 0) {
338 nlmsg_free(msg); 365 nlmsg_free(msg);
339 return ret; 366 return ret;
340 } 367 }
341 368
342 genlmsg_multicast_netns(&batadv_netlink_family, 369 genlmsg_multicast_netns(&batadv_netlink_family,
343 dev_net(bat_priv->soft_iface), msg, 0, 370 dev_net(bat_priv->soft_iface), msg, 0,
344 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 371 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
345 372
346 return 0; 373 return 0;
347 } 374 }
348 375
349 /** 376 /**
350 * batadv_netlink_get_mesh() - Get softif attributes 377 * batadv_netlink_get_mesh() - Get softif attributes
351 * @skb: Netlink message with request data 378 * @skb: Netlink message with request data
352 * @info: receiver information 379 * @info: receiver information
353 * 380 *
354 * Return: 0 on success or negative error number in case of failure 381 * Return: 0 on success or negative error number in case of failure
355 */ 382 */
356 static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info) 383 static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info)
357 { 384 {
358 struct batadv_priv *bat_priv = info->user_ptr[0]; 385 struct batadv_priv *bat_priv = info->user_ptr[0];
359 struct sk_buff *msg; 386 struct sk_buff *msg;
360 int ret; 387 int ret;
361 388
362 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 389 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
363 if (!msg) 390 if (!msg)
364 return -ENOMEM; 391 return -ENOMEM;
365 392
366 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_GET_MESH, 393 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_GET_MESH,
367 info->snd_portid, info->snd_seq, 0); 394 info->snd_portid, info->snd_seq, 0);
368 if (ret < 0) { 395 if (ret < 0) {
369 nlmsg_free(msg); 396 nlmsg_free(msg);
370 return ret; 397 return ret;
371 } 398 }
372 399
373 ret = genlmsg_reply(msg, info); 400 ret = genlmsg_reply(msg, info);
374 401
375 return ret; 402 return ret;
376 } 403 }
377 404
378 /** 405 /**
379 * batadv_netlink_set_mesh() - Set softif attributes 406 * batadv_netlink_set_mesh() - Set softif attributes
380 * @skb: Netlink message with request data 407 * @skb: Netlink message with request data
381 * @info: receiver information 408 * @info: receiver information
382 * 409 *
383 * Return: 0 on success or negative error number in case of failure 410 * Return: 0 on success or negative error number in case of failure
384 */ 411 */
385 static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info) 412 static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
386 { 413 {
387 struct batadv_priv *bat_priv = info->user_ptr[0]; 414 struct batadv_priv *bat_priv = info->user_ptr[0];
388 struct nlattr *attr; 415 struct nlattr *attr;
389 416
390 if (info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]) { 417 if (info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]) {
391 attr = info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]; 418 attr = info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED];
392 419
393 atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr)); 420 atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr));
394 } 421 }
395 422
396 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) { 423 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) {
397 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]; 424 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED];
398 425
399 batadv_netlink_set_mesh_ap_isolation(attr, bat_priv); 426 batadv_netlink_set_mesh_ap_isolation(attr, bat_priv);
400 } 427 }
401 428
402 if (info->attrs[BATADV_ATTR_ISOLATION_MARK]) { 429 if (info->attrs[BATADV_ATTR_ISOLATION_MARK]) {
403 attr = info->attrs[BATADV_ATTR_ISOLATION_MARK]; 430 attr = info->attrs[BATADV_ATTR_ISOLATION_MARK];
404 431
405 bat_priv->isolation_mark = nla_get_u32(attr); 432 bat_priv->isolation_mark = nla_get_u32(attr);
406 } 433 }
407 434
408 if (info->attrs[BATADV_ATTR_ISOLATION_MASK]) { 435 if (info->attrs[BATADV_ATTR_ISOLATION_MASK]) {
409 attr = info->attrs[BATADV_ATTR_ISOLATION_MASK]; 436 attr = info->attrs[BATADV_ATTR_ISOLATION_MASK];
410 437
411 bat_priv->isolation_mark_mask = nla_get_u32(attr); 438 bat_priv->isolation_mark_mask = nla_get_u32(attr);
412 } 439 }
413 440
414 if (info->attrs[BATADV_ATTR_BONDING_ENABLED]) { 441 if (info->attrs[BATADV_ATTR_BONDING_ENABLED]) {
415 attr = info->attrs[BATADV_ATTR_BONDING_ENABLED]; 442 attr = info->attrs[BATADV_ATTR_BONDING_ENABLED];
416 443
417 atomic_set(&bat_priv->bonding, !!nla_get_u8(attr)); 444 atomic_set(&bat_priv->bonding, !!nla_get_u8(attr));
418 } 445 }
419 446
420 #ifdef CONFIG_BATMAN_ADV_BLA 447 #ifdef CONFIG_BATMAN_ADV_BLA
421 if (info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED]) { 448 if (info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED]) {
422 attr = info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED]; 449 attr = info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED];
423 450
424 atomic_set(&bat_priv->bridge_loop_avoidance, 451 atomic_set(&bat_priv->bridge_loop_avoidance,
425 !!nla_get_u8(attr)); 452 !!nla_get_u8(attr));
426 batadv_bla_status_update(bat_priv->soft_iface); 453 batadv_bla_status_update(bat_priv->soft_iface);
427 } 454 }
428 #endif /* CONFIG_BATMAN_ADV_BLA */ 455 #endif /* CONFIG_BATMAN_ADV_BLA */
429 456
430 #ifdef CONFIG_BATMAN_ADV_DAT 457 #ifdef CONFIG_BATMAN_ADV_DAT
431 if (info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED]) { 458 if (info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED]) {
432 attr = info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED]; 459 attr = info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED];
433 460
434 atomic_set(&bat_priv->distributed_arp_table, 461 atomic_set(&bat_priv->distributed_arp_table,
435 !!nla_get_u8(attr)); 462 !!nla_get_u8(attr));
436 batadv_dat_status_update(bat_priv->soft_iface); 463 batadv_dat_status_update(bat_priv->soft_iface);
437 } 464 }
438 #endif /* CONFIG_BATMAN_ADV_DAT */ 465 #endif /* CONFIG_BATMAN_ADV_DAT */
439 466
440 if (info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]) { 467 if (info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]) {
441 attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]; 468 attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED];
442 469
443 atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr)); 470 atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr));
444 batadv_update_min_mtu(bat_priv->soft_iface); 471 batadv_update_min_mtu(bat_priv->soft_iface);
472 }
473
474 if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) {
475 attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN];
476
477 atomic_set(&bat_priv->gw.bandwidth_down, nla_get_u32(attr));
478 batadv_gw_tvlv_container_update(bat_priv);
479 }
480
481 if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]) {
482 attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP];
483
484 atomic_set(&bat_priv->gw.bandwidth_up, nla_get_u32(attr));
485 batadv_gw_tvlv_container_update(bat_priv);
486 }
487
488 if (info->attrs[BATADV_ATTR_GW_MODE]) {
489 u8 gw_mode;
490
491 attr = info->attrs[BATADV_ATTR_GW_MODE];
492 gw_mode = nla_get_u8(attr);
493
494 if (gw_mode <= BATADV_GW_MODE_SERVER) {
495 /* Invoking batadv_gw_reselect() is not enough to really
496 * de-select the current GW. It will only instruct the
497 * gateway client code to perform a re-election the next
498 * time that this is needed.
499 *
500 * When gw client mode is being switched off the current
501 * GW must be de-selected explicitly otherwise no GW_ADD
502 * uevent is thrown on client mode re-activation. This
503 * is operation is performed in
504 * batadv_gw_check_client_stop().
505 */
506 batadv_gw_reselect(bat_priv);
507
508 /* always call batadv_gw_check_client_stop() before
509 * changing the gateway state
510 */
511 batadv_gw_check_client_stop(bat_priv);
512 atomic_set(&bat_priv->gw.mode, gw_mode);
513 batadv_gw_tvlv_container_update(bat_priv);
514 }
515 }
516
517 if (info->attrs[BATADV_ATTR_GW_SEL_CLASS] &&
518 bat_priv->algo_ops->gw.get_best_gw_node &&
519 bat_priv->algo_ops->gw.is_eligible) {
520 /* setting the GW selection class is allowed only if the routing
521 * algorithm in use implements the GW API
522 */
523
524 u32 sel_class_max = 0xffffffffu;
525 u32 sel_class;
526
527 attr = info->attrs[BATADV_ATTR_GW_SEL_CLASS];
528 sel_class = nla_get_u32(attr);
529
530 if (!bat_priv->algo_ops->gw.store_sel_class)
531 sel_class_max = BATADV_TQ_MAX_VALUE;
532
533 if (sel_class >= 1 && sel_class <= sel_class_max) {
534 atomic_set(&bat_priv->gw.sel_class, sel_class);
535 batadv_gw_reselect(bat_priv);
536 }
445 } 537 }
446 538
447 batadv_netlink_notify_mesh(bat_priv); 539 batadv_netlink_notify_mesh(bat_priv);
448 540
449 return 0; 541 return 0;
450 } 542 }
451 543
452 /** 544 /**
453 * batadv_netlink_tp_meter_put() - Fill information of started tp_meter session 545 * batadv_netlink_tp_meter_put() - Fill information of started tp_meter session
454 * @msg: netlink message to be sent back 546 * @msg: netlink message to be sent back
455 * @cookie: tp meter session cookie 547 * @cookie: tp meter session cookie
456 * 548 *
457 * Return: 0 on success, < 0 on error 549 * Return: 0 on success, < 0 on error
458 */ 550 */
459 static int 551 static int
460 batadv_netlink_tp_meter_put(struct sk_buff *msg, u32 cookie) 552 batadv_netlink_tp_meter_put(struct sk_buff *msg, u32 cookie)
461 { 553 {
462 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie)) 554 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie))
463 return -ENOBUFS; 555 return -ENOBUFS;
464 556
465 return 0; 557 return 0;
466 } 558 }
467 559
468 /** 560 /**
469 * batadv_netlink_tpmeter_notify() - send tp_meter result via netlink to client 561 * batadv_netlink_tpmeter_notify() - send tp_meter result via netlink to client
470 * @bat_priv: the bat priv with all the soft interface information 562 * @bat_priv: the bat priv with all the soft interface information
471 * @dst: destination of tp_meter session 563 * @dst: destination of tp_meter session
472 * @result: reason for tp meter session stop 564 * @result: reason for tp meter session stop
473 * @test_time: total time ot the tp_meter session 565 * @test_time: total time ot the tp_meter session
474 * @total_bytes: bytes acked to the receiver 566 * @total_bytes: bytes acked to the receiver
475 * @cookie: cookie of tp_meter session 567 * @cookie: cookie of tp_meter session
476 * 568 *
477 * Return: 0 on success, < 0 on error 569 * Return: 0 on success, < 0 on error
478 */ 570 */
479 int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst, 571 int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst,
480 u8 result, u32 test_time, u64 total_bytes, 572 u8 result, u32 test_time, u64 total_bytes,
481 u32 cookie) 573 u32 cookie)
482 { 574 {
483 struct sk_buff *msg; 575 struct sk_buff *msg;
484 void *hdr; 576 void *hdr;
485 int ret; 577 int ret;
486 578
487 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 579 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
488 if (!msg) 580 if (!msg)
489 return -ENOMEM; 581 return -ENOMEM;
490 582
491 hdr = genlmsg_put(msg, 0, 0, &batadv_netlink_family, 0, 583 hdr = genlmsg_put(msg, 0, 0, &batadv_netlink_family, 0,
492 BATADV_CMD_TP_METER); 584 BATADV_CMD_TP_METER);
493 if (!hdr) { 585 if (!hdr) {
494 ret = -ENOBUFS; 586 ret = -ENOBUFS;
495 goto err_genlmsg; 587 goto err_genlmsg;
496 } 588 }
497 589
498 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie)) 590 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie))
499 goto nla_put_failure; 591 goto nla_put_failure;
500 592
501 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_TEST_TIME, test_time)) 593 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_TEST_TIME, test_time))
502 goto nla_put_failure; 594 goto nla_put_failure;
503 595
504 if (nla_put_u64_64bit(msg, BATADV_ATTR_TPMETER_BYTES, total_bytes, 596 if (nla_put_u64_64bit(msg, BATADV_ATTR_TPMETER_BYTES, total_bytes,
505 BATADV_ATTR_PAD)) 597 BATADV_ATTR_PAD))
506 goto nla_put_failure; 598 goto nla_put_failure;
507 599
508 if (nla_put_u8(msg, BATADV_ATTR_TPMETER_RESULT, result)) 600 if (nla_put_u8(msg, BATADV_ATTR_TPMETER_RESULT, result))
509 goto nla_put_failure; 601 goto nla_put_failure;
510 602
511 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, dst)) 603 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, dst))
512 goto nla_put_failure; 604 goto nla_put_failure;
513 605
514 genlmsg_end(msg, hdr); 606 genlmsg_end(msg, hdr);
515 607
516 genlmsg_multicast_netns(&batadv_netlink_family, 608 genlmsg_multicast_netns(&batadv_netlink_family,
517 dev_net(bat_priv->soft_iface), msg, 0, 609 dev_net(bat_priv->soft_iface), msg, 0,
518 BATADV_NL_MCGRP_TPMETER, GFP_KERNEL); 610 BATADV_NL_MCGRP_TPMETER, GFP_KERNEL);
519 611
520 return 0; 612 return 0;
521 613
522 nla_put_failure: 614 nla_put_failure:
523 genlmsg_cancel(msg, hdr); 615 genlmsg_cancel(msg, hdr);
524 ret = -EMSGSIZE; 616 ret = -EMSGSIZE;
525 617
526 err_genlmsg: 618 err_genlmsg:
527 nlmsg_free(msg); 619 nlmsg_free(msg);
528 return ret; 620 return ret;
529 } 621 }
530 622
531 /** 623 /**
532 * batadv_netlink_tp_meter_start() - Start a new tp_meter session 624 * batadv_netlink_tp_meter_start() - Start a new tp_meter session
533 * @skb: received netlink message 625 * @skb: received netlink message
534 * @info: receiver information 626 * @info: receiver information
535 * 627 *
536 * Return: 0 on success, < 0 on error 628 * Return: 0 on success, < 0 on error
537 */ 629 */
538 static int 630 static int
539 batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info) 631 batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
540 { 632 {
541 struct batadv_priv *bat_priv = info->user_ptr[0]; 633 struct batadv_priv *bat_priv = info->user_ptr[0];
542 struct sk_buff *msg = NULL; 634 struct sk_buff *msg = NULL;
543 u32 test_length; 635 u32 test_length;
544 void *msg_head; 636 void *msg_head;
545 u32 cookie; 637 u32 cookie;
546 u8 *dst; 638 u8 *dst;
547 int ret; 639 int ret;
548 640
549 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS]) 641 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
550 return -EINVAL; 642 return -EINVAL;
551 643
552 if (!info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]) 644 if (!info->attrs[BATADV_ATTR_TPMETER_TEST_TIME])
553 return -EINVAL; 645 return -EINVAL;
554 646
555 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]); 647 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
556 648
557 test_length = nla_get_u32(info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]); 649 test_length = nla_get_u32(info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]);
558 650
559 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 651 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
560 if (!msg) { 652 if (!msg) {
561 ret = -ENOMEM; 653 ret = -ENOMEM;
562 goto out; 654 goto out;
563 } 655 }
564 656
565 msg_head = genlmsg_put(msg, info->snd_portid, info->snd_seq, 657 msg_head = genlmsg_put(msg, info->snd_portid, info->snd_seq,
566 &batadv_netlink_family, 0, 658 &batadv_netlink_family, 0,
567 BATADV_CMD_TP_METER); 659 BATADV_CMD_TP_METER);
568 if (!msg_head) { 660 if (!msg_head) {
569 ret = -ENOBUFS; 661 ret = -ENOBUFS;
570 goto out; 662 goto out;
571 } 663 }
572 664
573 batadv_tp_start(bat_priv, dst, test_length, &cookie); 665 batadv_tp_start(bat_priv, dst, test_length, &cookie);
574 666
575 ret = batadv_netlink_tp_meter_put(msg, cookie); 667 ret = batadv_netlink_tp_meter_put(msg, cookie);
576 668
577 out: 669 out:
578 if (ret) { 670 if (ret) {
579 if (msg) 671 if (msg)
580 nlmsg_free(msg); 672 nlmsg_free(msg);
581 return ret; 673 return ret;
582 } 674 }
583 675
584 genlmsg_end(msg, msg_head); 676 genlmsg_end(msg, msg_head);
585 return genlmsg_reply(msg, info); 677 return genlmsg_reply(msg, info);
586 } 678 }
587 679
588 /** 680 /**
589 * batadv_netlink_tp_meter_start() - Cancel a running tp_meter session 681 * batadv_netlink_tp_meter_start() - Cancel a running tp_meter session
590 * @skb: received netlink message 682 * @skb: received netlink message
591 * @info: receiver information 683 * @info: receiver information
592 * 684 *
593 * Return: 0 on success, < 0 on error 685 * Return: 0 on success, < 0 on error
594 */ 686 */
595 static int 687 static int
596 batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info) 688 batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info)
597 { 689 {
598 struct batadv_priv *bat_priv = info->user_ptr[0]; 690 struct batadv_priv *bat_priv = info->user_ptr[0];
599 u8 *dst; 691 u8 *dst;
600 int ret = 0; 692 int ret = 0;
601 693
602 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS]) 694 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
603 return -EINVAL; 695 return -EINVAL;
604 696
605 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]); 697 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
606 698
607 batadv_tp_stop(bat_priv, dst, BATADV_TP_REASON_CANCEL); 699 batadv_tp_stop(bat_priv, dst, BATADV_TP_REASON_CANCEL);
608 700
609 return ret; 701 return ret;
610 } 702 }
611 703
612 /** 704 /**
613 * batadv_netlink_hardif_fill() - Fill message with hardif attributes 705 * batadv_netlink_hardif_fill() - Fill message with hardif attributes
614 * @msg: Netlink message to dump into 706 * @msg: Netlink message to dump into
615 * @bat_priv: the bat priv with all the soft interface information 707 * @bat_priv: the bat priv with all the soft interface information
616 * @hard_iface: hard interface which was modified 708 * @hard_iface: hard interface which was modified
617 * @cmd: type of message to generate 709 * @cmd: type of message to generate
618 * @portid: Port making netlink request 710 * @portid: Port making netlink request
619 * @seq: sequence number for message 711 * @seq: sequence number for message
620 * @flags: Additional flags for message 712 * @flags: Additional flags for message
621 * @cb: Control block containing additional options 713 * @cb: Control block containing additional options
622 * 714 *
623 * Return: 0 on success or negative error number in case of failure 715 * Return: 0 on success or negative error number in case of failure
624 */ 716 */
625 static int batadv_netlink_hardif_fill(struct sk_buff *msg, 717 static int batadv_netlink_hardif_fill(struct sk_buff *msg,
626 struct batadv_priv *bat_priv, 718 struct batadv_priv *bat_priv,
627 struct batadv_hard_iface *hard_iface, 719 struct batadv_hard_iface *hard_iface,
628 enum batadv_nl_commands cmd, 720 enum batadv_nl_commands cmd,
629 u32 portid, u32 seq, int flags, 721 u32 portid, u32 seq, int flags,
630 struct netlink_callback *cb) 722 struct netlink_callback *cb)
631 { 723 {
632 struct net_device *net_dev = hard_iface->net_dev; 724 struct net_device *net_dev = hard_iface->net_dev;
633 void *hdr; 725 void *hdr;
634 726
635 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 727 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
636 if (!hdr) 728 if (!hdr)
637 return -ENOBUFS; 729 return -ENOBUFS;
638 730
639 if (cb) 731 if (cb)
640 genl_dump_check_consistent(cb, hdr); 732 genl_dump_check_consistent(cb, hdr);
641 733
642 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, 734 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX,
643 bat_priv->soft_iface->ifindex)) 735 bat_priv->soft_iface->ifindex))
644 goto nla_put_failure; 736 goto nla_put_failure;
645 737
646 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, 738 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
647 net_dev->ifindex) || 739 net_dev->ifindex) ||
648 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, 740 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
649 net_dev->name) || 741 net_dev->name) ||
650 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN, 742 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN,
651 net_dev->dev_addr)) 743 net_dev->dev_addr))
652 goto nla_put_failure; 744 goto nla_put_failure;
653 745
654 if (hard_iface->if_status == BATADV_IF_ACTIVE) { 746 if (hard_iface->if_status == BATADV_IF_ACTIVE) {
655 if (nla_put_flag(msg, BATADV_ATTR_ACTIVE)) 747 if (nla_put_flag(msg, BATADV_ATTR_ACTIVE))
656 goto nla_put_failure; 748 goto nla_put_failure;
657 } 749 }
658 750
659 genlmsg_end(msg, hdr); 751 genlmsg_end(msg, hdr);
660 return 0; 752 return 0;
661 753
662 nla_put_failure: 754 nla_put_failure:
663 genlmsg_cancel(msg, hdr); 755 genlmsg_cancel(msg, hdr);
664 return -EMSGSIZE; 756 return -EMSGSIZE;
665 } 757 }
666 758
667 /** 759 /**
668 * batadv_netlink_notify_hardif() - send hardif attributes to listener 760 * batadv_netlink_notify_hardif() - send hardif attributes to listener
669 * @bat_priv: the bat priv with all the soft interface information 761 * @bat_priv: the bat priv with all the soft interface information
670 * @hard_iface: hard interface which was modified 762 * @hard_iface: hard interface which was modified
671 * 763 *
672 * Return: 0 on success, < 0 on error 764 * Return: 0 on success, < 0 on error
673 */ 765 */
674 static int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv, 766 static int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv,
675 struct batadv_hard_iface *hard_iface) 767 struct batadv_hard_iface *hard_iface)
676 { 768 {
677 struct sk_buff *msg; 769 struct sk_buff *msg;
678 int ret; 770 int ret;
679 771
680 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 772 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
681 if (!msg) 773 if (!msg)
682 return -ENOMEM; 774 return -ENOMEM;
683 775
684 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 776 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface,
685 BATADV_CMD_SET_HARDIF, 0, 0, 0, NULL); 777 BATADV_CMD_SET_HARDIF, 0, 0, 0, NULL);
686 if (ret < 0) { 778 if (ret < 0) {
687 nlmsg_free(msg); 779 nlmsg_free(msg);
688 return ret; 780 return ret;
689 } 781 }
690 782
691 genlmsg_multicast_netns(&batadv_netlink_family, 783 genlmsg_multicast_netns(&batadv_netlink_family,
692 dev_net(bat_priv->soft_iface), msg, 0, 784 dev_net(bat_priv->soft_iface), msg, 0,
693 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 785 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
694 786
695 return 0; 787 return 0;
696 } 788 }
697 789
698 /** 790 /**
699 * batadv_netlink_get_hardif() - Get hardif attributes 791 * batadv_netlink_get_hardif() - Get hardif attributes
700 * @skb: Netlink message with request data 792 * @skb: Netlink message with request data
701 * @info: receiver information 793 * @info: receiver information
702 * 794 *
703 * Return: 0 on success or negative error number in case of failure 795 * Return: 0 on success or negative error number in case of failure
704 */ 796 */
705 static int batadv_netlink_get_hardif(struct sk_buff *skb, 797 static int batadv_netlink_get_hardif(struct sk_buff *skb,
706 struct genl_info *info) 798 struct genl_info *info)
707 { 799 {
708 struct batadv_hard_iface *hard_iface = info->user_ptr[1]; 800 struct batadv_hard_iface *hard_iface = info->user_ptr[1];
709 struct batadv_priv *bat_priv = info->user_ptr[0]; 801 struct batadv_priv *bat_priv = info->user_ptr[0];
710 struct sk_buff *msg; 802 struct sk_buff *msg;
711 int ret; 803 int ret;
712 804
713 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 805 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
714 if (!msg) 806 if (!msg)
715 return -ENOMEM; 807 return -ENOMEM;
716 808
717 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 809 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface,
718 BATADV_CMD_GET_HARDIF, 810 BATADV_CMD_GET_HARDIF,
719 info->snd_portid, info->snd_seq, 0, 811 info->snd_portid, info->snd_seq, 0,
720 NULL); 812 NULL);
721 if (ret < 0) { 813 if (ret < 0) {
722 nlmsg_free(msg); 814 nlmsg_free(msg);
723 return ret; 815 return ret;
724 } 816 }
725 817
726 ret = genlmsg_reply(msg, info); 818 ret = genlmsg_reply(msg, info);
727 819
728 return ret; 820 return ret;
729 } 821 }
730 822
731 /** 823 /**
732 * batadv_netlink_set_hardif() - Set hardif attributes 824 * batadv_netlink_set_hardif() - Set hardif attributes
733 * @skb: Netlink message with request data 825 * @skb: Netlink message with request data
734 * @info: receiver information 826 * @info: receiver information
735 * 827 *
736 * Return: 0 on success or negative error number in case of failure 828 * Return: 0 on success or negative error number in case of failure
737 */ 829 */
738 static int batadv_netlink_set_hardif(struct sk_buff *skb, 830 static int batadv_netlink_set_hardif(struct sk_buff *skb,
739 struct genl_info *info) 831 struct genl_info *info)
740 { 832 {
741 struct batadv_hard_iface *hard_iface = info->user_ptr[1]; 833 struct batadv_hard_iface *hard_iface = info->user_ptr[1];
742 struct batadv_priv *bat_priv = info->user_ptr[0]; 834 struct batadv_priv *bat_priv = info->user_ptr[0];
743 835
744 batadv_netlink_notify_hardif(bat_priv, hard_iface); 836 batadv_netlink_notify_hardif(bat_priv, hard_iface);
745 837
746 return 0; 838 return 0;
747 } 839 }
748 840
749 /** 841 /**
750 * batadv_netlink_dump_hardif() - Dump all hard interface into a messages 842 * batadv_netlink_dump_hardif() - Dump all hard interface into a messages
751 * @msg: Netlink message to dump into 843 * @msg: Netlink message to dump into
752 * @cb: Parameters from query 844 * @cb: Parameters from query
753 * 845 *
754 * Return: error code, or length of reply message on success 846 * Return: error code, or length of reply message on success
755 */ 847 */
756 static int 848 static int
757 batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb) 849 batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb)
758 { 850 {
759 struct net *net = sock_net(cb->skb->sk); 851 struct net *net = sock_net(cb->skb->sk);
760 struct net_device *soft_iface; 852 struct net_device *soft_iface;
761 struct batadv_hard_iface *hard_iface; 853 struct batadv_hard_iface *hard_iface;
762 struct batadv_priv *bat_priv; 854 struct batadv_priv *bat_priv;
763 int ifindex; 855 int ifindex;
764 int portid = NETLINK_CB(cb->skb).portid; 856 int portid = NETLINK_CB(cb->skb).portid;
765 int skip = cb->args[0]; 857 int skip = cb->args[0];
766 int i = 0; 858 int i = 0;
767 859
768 ifindex = batadv_netlink_get_ifindex(cb->nlh, 860 ifindex = batadv_netlink_get_ifindex(cb->nlh,
769 BATADV_ATTR_MESH_IFINDEX); 861 BATADV_ATTR_MESH_IFINDEX);
770 if (!ifindex) 862 if (!ifindex)
771 return -EINVAL; 863 return -EINVAL;
772 864
773 soft_iface = dev_get_by_index(net, ifindex); 865 soft_iface = dev_get_by_index(net, ifindex);
774 if (!soft_iface) 866 if (!soft_iface)
775 return -ENODEV; 867 return -ENODEV;
776 868
777 if (!batadv_softif_is_valid(soft_iface)) { 869 if (!batadv_softif_is_valid(soft_iface)) {
778 dev_put(soft_iface); 870 dev_put(soft_iface);
779 return -ENODEV; 871 return -ENODEV;
780 } 872 }
781 873
782 bat_priv = netdev_priv(soft_iface); 874 bat_priv = netdev_priv(soft_iface);
783 875
784 rtnl_lock(); 876 rtnl_lock();
785 cb->seq = batadv_hardif_generation << 1 | 1; 877 cb->seq = batadv_hardif_generation << 1 | 1;
786 878
787 list_for_each_entry(hard_iface, &batadv_hardif_list, list) { 879 list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
788 if (hard_iface->soft_iface != soft_iface) 880 if (hard_iface->soft_iface != soft_iface)
789 continue; 881 continue;
790 882
791 if (i++ < skip) 883 if (i++ < skip)
792 continue; 884 continue;
793 885
794 if (batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 886 if (batadv_netlink_hardif_fill(msg, bat_priv, hard_iface,
795 BATADV_CMD_GET_HARDIF, 887 BATADV_CMD_GET_HARDIF,
796 portid, cb->nlh->nlmsg_seq, 888 portid, cb->nlh->nlmsg_seq,
797 NLM_F_MULTI, cb)) { 889 NLM_F_MULTI, cb)) {
798 i--; 890 i--;
799 break; 891 break;
800 } 892 }
801 } 893 }
802 894
803 rtnl_unlock(); 895 rtnl_unlock();
804 896
805 dev_put(soft_iface); 897 dev_put(soft_iface);
806 898
807 cb->args[0] = i; 899 cb->args[0] = i;
808 900
809 return msg->len; 901 return msg->len;
810 } 902 }
811 903
812 /** 904 /**
813 * batadv_netlink_vlan_fill() - Fill message with vlan attributes 905 * batadv_netlink_vlan_fill() - Fill message with vlan attributes
814 * @msg: Netlink message to dump into 906 * @msg: Netlink message to dump into
815 * @bat_priv: the bat priv with all the soft interface information 907 * @bat_priv: the bat priv with all the soft interface information
816 * @vlan: vlan which was modified 908 * @vlan: vlan which was modified
817 * @cmd: type of message to generate 909 * @cmd: type of message to generate
818 * @portid: Port making netlink request 910 * @portid: Port making netlink request
819 * @seq: sequence number for message 911 * @seq: sequence number for message
820 * @flags: Additional flags for message 912 * @flags: Additional flags for message
821 * 913 *
822 * Return: 0 on success or negative error number in case of failure 914 * Return: 0 on success or negative error number in case of failure
823 */ 915 */
824 static int batadv_netlink_vlan_fill(struct sk_buff *msg, 916 static int batadv_netlink_vlan_fill(struct sk_buff *msg,
825 struct batadv_priv *bat_priv, 917 struct batadv_priv *bat_priv,
826 struct batadv_softif_vlan *vlan, 918 struct batadv_softif_vlan *vlan,
827 enum batadv_nl_commands cmd, 919 enum batadv_nl_commands cmd,
828 u32 portid, u32 seq, int flags) 920 u32 portid, u32 seq, int flags)
829 { 921 {
830 void *hdr; 922 void *hdr;
831 923
832 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 924 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
833 if (!hdr) 925 if (!hdr)
834 return -ENOBUFS; 926 return -ENOBUFS;
835 927
836 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, 928 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX,
837 bat_priv->soft_iface->ifindex)) 929 bat_priv->soft_iface->ifindex))
838 goto nla_put_failure; 930 goto nla_put_failure;
839 931
840 if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK)) 932 if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK))
841 goto nla_put_failure; 933 goto nla_put_failure;
842 934
843 if (nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, 935 if (nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED,
844 !!atomic_read(&vlan->ap_isolation))) 936 !!atomic_read(&vlan->ap_isolation)))
845 goto nla_put_failure; 937 goto nla_put_failure;
846 938
847 genlmsg_end(msg, hdr); 939 genlmsg_end(msg, hdr);
848 return 0; 940 return 0;
849 941
850 nla_put_failure: 942 nla_put_failure:
851 genlmsg_cancel(msg, hdr); 943 genlmsg_cancel(msg, hdr);
852 return -EMSGSIZE; 944 return -EMSGSIZE;
853 } 945 }
854 946
855 /** 947 /**
856 * batadv_netlink_notify_vlan() - send vlan attributes to listener 948 * batadv_netlink_notify_vlan() - send vlan attributes to listener
857 * @bat_priv: the bat priv with all the soft interface information 949 * @bat_priv: the bat priv with all the soft interface information
858 * @vlan: vlan which was modified 950 * @vlan: vlan which was modified
859 * 951 *
860 * Return: 0 on success, < 0 on error 952 * Return: 0 on success, < 0 on error
861 */ 953 */
862 static int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv, 954 static int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv,
863 struct batadv_softif_vlan *vlan) 955 struct batadv_softif_vlan *vlan)
864 { 956 {
865 struct sk_buff *msg; 957 struct sk_buff *msg;
866 int ret; 958 int ret;
867 959
868 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 960 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
869 if (!msg) 961 if (!msg)
870 return -ENOMEM; 962 return -ENOMEM;
871 963
872 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, 964 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan,
873 BATADV_CMD_SET_VLAN, 0, 0, 0); 965 BATADV_CMD_SET_VLAN, 0, 0, 0);
874 if (ret < 0) { 966 if (ret < 0) {
875 nlmsg_free(msg); 967 nlmsg_free(msg);
876 return ret; 968 return ret;
877 } 969 }
878 970
879 genlmsg_multicast_netns(&batadv_netlink_family, 971 genlmsg_multicast_netns(&batadv_netlink_family,
880 dev_net(bat_priv->soft_iface), msg, 0, 972 dev_net(bat_priv->soft_iface), msg, 0,
881 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 973 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
882 974
883 return 0; 975 return 0;
884 } 976 }
885 977
886 /** 978 /**
887 * batadv_netlink_get_vlan() - Get vlan attributes 979 * batadv_netlink_get_vlan() - Get vlan attributes
888 * @skb: Netlink message with request data 980 * @skb: Netlink message with request data
889 * @info: receiver information 981 * @info: receiver information
890 * 982 *
891 * Return: 0 on success or negative error number in case of failure 983 * Return: 0 on success or negative error number in case of failure
892 */ 984 */
893 static int batadv_netlink_get_vlan(struct sk_buff *skb, struct genl_info *info) 985 static int batadv_netlink_get_vlan(struct sk_buff *skb, struct genl_info *info)
894 { 986 {
895 struct batadv_softif_vlan *vlan = info->user_ptr[1]; 987 struct batadv_softif_vlan *vlan = info->user_ptr[1];
896 struct batadv_priv *bat_priv = info->user_ptr[0]; 988 struct batadv_priv *bat_priv = info->user_ptr[0];
897 struct sk_buff *msg; 989 struct sk_buff *msg;
898 int ret; 990 int ret;
899 991
900 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 992 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
901 if (!msg) 993 if (!msg)
902 return -ENOMEM; 994 return -ENOMEM;
903 995
904 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, BATADV_CMD_GET_VLAN, 996 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, BATADV_CMD_GET_VLAN,
905 info->snd_portid, info->snd_seq, 0); 997 info->snd_portid, info->snd_seq, 0);
906 if (ret < 0) { 998 if (ret < 0) {
907 nlmsg_free(msg); 999 nlmsg_free(msg);
908 return ret; 1000 return ret;
909 } 1001 }
910 1002
911 ret = genlmsg_reply(msg, info); 1003 ret = genlmsg_reply(msg, info);
912 1004
913 return ret; 1005 return ret;
914 } 1006 }
915 1007
916 /** 1008 /**
917 * batadv_netlink_set_vlan() - Get vlan attributes 1009 * batadv_netlink_set_vlan() - Get vlan attributes
918 * @skb: Netlink message with request data 1010 * @skb: Netlink message with request data
919 * @info: receiver information 1011 * @info: receiver information
920 * 1012 *
921 * Return: 0 on success or negative error number in case of failure 1013 * Return: 0 on success or negative error number in case of failure
922 */ 1014 */
923 static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info) 1015 static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info)
924 { 1016 {
925 struct batadv_softif_vlan *vlan = info->user_ptr[1]; 1017 struct batadv_softif_vlan *vlan = info->user_ptr[1];
926 struct batadv_priv *bat_priv = info->user_ptr[0]; 1018 struct batadv_priv *bat_priv = info->user_ptr[0];
927 struct nlattr *attr; 1019 struct nlattr *attr;
928 1020
929 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) { 1021 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) {
930 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]; 1022 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED];
931 1023
932 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr)); 1024 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
933 } 1025 }
934 1026
935 batadv_netlink_notify_vlan(bat_priv, vlan); 1027 batadv_netlink_notify_vlan(bat_priv, vlan);
936 1028
937 return 0; 1029 return 0;
938 } 1030 }
939 1031
940 /** 1032 /**
941 * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes 1033 * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes
942 * @net: the applicable net namespace 1034 * @net: the applicable net namespace
943 * @info: receiver information 1035 * @info: receiver information
944 * 1036 *
945 * Return: Pointer to soft interface (with increased refcnt) on success, error 1037 * Return: Pointer to soft interface (with increased refcnt) on success, error
946 * pointer on error 1038 * pointer on error
947 */ 1039 */
948 static struct net_device * 1040 static struct net_device *
949 batadv_get_softif_from_info(struct net *net, struct genl_info *info) 1041 batadv_get_softif_from_info(struct net *net, struct genl_info *info)
950 { 1042 {
951 struct net_device *soft_iface; 1043 struct net_device *soft_iface;
952 int ifindex; 1044 int ifindex;
953 1045
954 if (!info->attrs[BATADV_ATTR_MESH_IFINDEX]) 1046 if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
955 return ERR_PTR(-EINVAL); 1047 return ERR_PTR(-EINVAL);
956 1048
957 ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]); 1049 ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
958 1050
959 soft_iface = dev_get_by_index(net, ifindex); 1051 soft_iface = dev_get_by_index(net, ifindex);
960 if (!soft_iface) 1052 if (!soft_iface)
961 return ERR_PTR(-ENODEV); 1053 return ERR_PTR(-ENODEV);
962 1054
963 if (!batadv_softif_is_valid(soft_iface)) 1055 if (!batadv_softif_is_valid(soft_iface))
964 goto err_put_softif; 1056 goto err_put_softif;
965 1057
966 return soft_iface; 1058 return soft_iface;
967 1059
968 err_put_softif: 1060 err_put_softif:
969 dev_put(soft_iface); 1061 dev_put(soft_iface);
970 1062
971 return ERR_PTR(-EINVAL); 1063 return ERR_PTR(-EINVAL);
972 } 1064 }
973 1065
974 /** 1066 /**
975 * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes 1067 * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes
976 * @bat_priv: the bat priv with all the soft interface information 1068 * @bat_priv: the bat priv with all the soft interface information
977 * @net: the applicable net namespace 1069 * @net: the applicable net namespace
978 * @info: receiver information 1070 * @info: receiver information
979 * 1071 *
980 * Return: Pointer to hard interface (with increased refcnt) on success, error 1072 * Return: Pointer to hard interface (with increased refcnt) on success, error
981 * pointer on error 1073 * pointer on error
982 */ 1074 */
983 static struct batadv_hard_iface * 1075 static struct batadv_hard_iface *
984 batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net *net, 1076 batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net *net,
985 struct genl_info *info) 1077 struct genl_info *info)
986 { 1078 {
987 struct batadv_hard_iface *hard_iface; 1079 struct batadv_hard_iface *hard_iface;
988 struct net_device *hard_dev; 1080 struct net_device *hard_dev;
989 unsigned int hardif_index; 1081 unsigned int hardif_index;
990 1082
991 if (!info->attrs[BATADV_ATTR_HARD_IFINDEX]) 1083 if (!info->attrs[BATADV_ATTR_HARD_IFINDEX])
992 return ERR_PTR(-EINVAL); 1084 return ERR_PTR(-EINVAL);
993 1085
994 hardif_index = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]); 1086 hardif_index = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]);
995 1087
996 hard_dev = dev_get_by_index(net, hardif_index); 1088 hard_dev = dev_get_by_index(net, hardif_index);
997 if (!hard_dev) 1089 if (!hard_dev)
998 return ERR_PTR(-ENODEV); 1090 return ERR_PTR(-ENODEV);
999 1091
1000 hard_iface = batadv_hardif_get_by_netdev(hard_dev); 1092 hard_iface = batadv_hardif_get_by_netdev(hard_dev);
1001 if (!hard_iface) 1093 if (!hard_iface)
1002 goto err_put_harddev; 1094 goto err_put_harddev;
1003 1095
1004 if (hard_iface->soft_iface != bat_priv->soft_iface) 1096 if (hard_iface->soft_iface != bat_priv->soft_iface)
1005 goto err_put_hardif; 1097 goto err_put_hardif;
1006 1098
1007 /* hard_dev is referenced by hard_iface and not needed here */ 1099 /* hard_dev is referenced by hard_iface and not needed here */
1008 dev_put(hard_dev); 1100 dev_put(hard_dev);
1009 1101
1010 return hard_iface; 1102 return hard_iface;
1011 1103
1012 err_put_hardif: 1104 err_put_hardif:
1013 batadv_hardif_put(hard_iface); 1105 batadv_hardif_put(hard_iface);
1014 err_put_harddev: 1106 err_put_harddev:
1015 dev_put(hard_dev); 1107 dev_put(hard_dev);
1016 1108
1017 return ERR_PTR(-EINVAL); 1109 return ERR_PTR(-EINVAL);
1018 } 1110 }
1019 1111
1020 /** 1112 /**
1021 * batadv_get_vlan_from_info() - Retrieve vlan from genl attributes 1113 * batadv_get_vlan_from_info() - Retrieve vlan from genl attributes
1022 * @bat_priv: the bat priv with all the soft interface information 1114 * @bat_priv: the bat priv with all the soft interface information
1023 * @net: the applicable net namespace 1115 * @net: the applicable net namespace
1024 * @info: receiver information 1116 * @info: receiver information
1025 * 1117 *
1026 * Return: Pointer to vlan on success (with increased refcnt), error pointer 1118 * Return: Pointer to vlan on success (with increased refcnt), error pointer
1027 * on error 1119 * on error
1028 */ 1120 */
1029 static struct batadv_softif_vlan * 1121 static struct batadv_softif_vlan *
1030 batadv_get_vlan_from_info(struct batadv_priv *bat_priv, struct net *net, 1122 batadv_get_vlan_from_info(struct batadv_priv *bat_priv, struct net *net,
1031 struct genl_info *info) 1123 struct genl_info *info)
1032 { 1124 {
1033 struct batadv_softif_vlan *vlan; 1125 struct batadv_softif_vlan *vlan;
1034 u16 vid; 1126 u16 vid;
1035 1127
1036 if (!info->attrs[BATADV_ATTR_VLANID]) 1128 if (!info->attrs[BATADV_ATTR_VLANID])
1037 return ERR_PTR(-EINVAL); 1129 return ERR_PTR(-EINVAL);
1038 1130
1039 vid = nla_get_u16(info->attrs[BATADV_ATTR_VLANID]); 1131 vid = nla_get_u16(info->attrs[BATADV_ATTR_VLANID]);
1040 1132
1041 vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); 1133 vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG);
1042 if (!vlan) 1134 if (!vlan)
1043 return ERR_PTR(-ENOENT); 1135 return ERR_PTR(-ENOENT);
1044 1136
1045 return vlan; 1137 return vlan;
1046 } 1138 }
1047 1139
1048 /** 1140 /**
1049 * batadv_pre_doit() - Prepare batman-adv genl doit request 1141 * batadv_pre_doit() - Prepare batman-adv genl doit request
1050 * @ops: requested netlink operation 1142 * @ops: requested netlink operation
1051 * @skb: Netlink message with request data 1143 * @skb: Netlink message with request data
1052 * @info: receiver information 1144 * @info: receiver information
1053 * 1145 *
1054 * Return: 0 on success or negative error number in case of failure 1146 * Return: 0 on success or negative error number in case of failure
1055 */ 1147 */
1056 static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, 1148 static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
1057 struct genl_info *info) 1149 struct genl_info *info)
1058 { 1150 {
1059 struct net *net = genl_info_net(info); 1151 struct net *net = genl_info_net(info);
1060 struct batadv_hard_iface *hard_iface; 1152 struct batadv_hard_iface *hard_iface;
1061 struct batadv_priv *bat_priv = NULL; 1153 struct batadv_priv *bat_priv = NULL;
1062 struct batadv_softif_vlan *vlan; 1154 struct batadv_softif_vlan *vlan;
1063 struct net_device *soft_iface; 1155 struct net_device *soft_iface;
1064 u8 user_ptr1_flags; 1156 u8 user_ptr1_flags;
1065 u8 mesh_dep_flags; 1157 u8 mesh_dep_flags;
1066 int ret; 1158 int ret;
1067 1159
1068 user_ptr1_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN; 1160 user_ptr1_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN;
1069 if (WARN_ON(hweight8(ops->internal_flags & user_ptr1_flags) > 1)) 1161 if (WARN_ON(hweight8(ops->internal_flags & user_ptr1_flags) > 1))
1070 return -EINVAL; 1162 return -EINVAL;
1071 1163
1072 mesh_dep_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN; 1164 mesh_dep_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN;
1073 if (WARN_ON((ops->internal_flags & mesh_dep_flags) && 1165 if (WARN_ON((ops->internal_flags & mesh_dep_flags) &&
1074 (~ops->internal_flags & BATADV_FLAG_NEED_MESH))) 1166 (~ops->internal_flags & BATADV_FLAG_NEED_MESH)))
1075 return -EINVAL; 1167 return -EINVAL;
1076 1168
1077 if (ops->internal_flags & BATADV_FLAG_NEED_MESH) { 1169 if (ops->internal_flags & BATADV_FLAG_NEED_MESH) {
1078 soft_iface = batadv_get_softif_from_info(net, info); 1170 soft_iface = batadv_get_softif_from_info(net, info);
1079 if (IS_ERR(soft_iface)) 1171 if (IS_ERR(soft_iface))
1080 return PTR_ERR(soft_iface); 1172 return PTR_ERR(soft_iface);
1081 1173
1082 bat_priv = netdev_priv(soft_iface); 1174 bat_priv = netdev_priv(soft_iface);
1083 info->user_ptr[0] = bat_priv; 1175 info->user_ptr[0] = bat_priv;
1084 } 1176 }
1085 1177
1086 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF) { 1178 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF) {
1087 hard_iface = batadv_get_hardif_from_info(bat_priv, net, info); 1179 hard_iface = batadv_get_hardif_from_info(bat_priv, net, info);
1088 if (IS_ERR(hard_iface)) { 1180 if (IS_ERR(hard_iface)) {
1089 ret = PTR_ERR(hard_iface); 1181 ret = PTR_ERR(hard_iface);
1090 goto err_put_softif; 1182 goto err_put_softif;
1091 } 1183 }
1092 1184
1093 info->user_ptr[1] = hard_iface; 1185 info->user_ptr[1] = hard_iface;
1094 } 1186 }
1095 1187
1096 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN) { 1188 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN) {
1097 vlan = batadv_get_vlan_from_info(bat_priv, net, info); 1189 vlan = batadv_get_vlan_from_info(bat_priv, net, info);
1098 if (IS_ERR(vlan)) { 1190 if (IS_ERR(vlan)) {
1099 ret = PTR_ERR(vlan); 1191 ret = PTR_ERR(vlan);
1100 goto err_put_softif; 1192 goto err_put_softif;
1101 } 1193 }
1102 1194
1103 info->user_ptr[1] = vlan; 1195 info->user_ptr[1] = vlan;
1104 } 1196 }
1105 1197
1106 return 0; 1198 return 0;
1107 1199
1108 err_put_softif: 1200 err_put_softif:
1109 if (bat_priv) 1201 if (bat_priv)
1110 dev_put(bat_priv->soft_iface); 1202 dev_put(bat_priv->soft_iface);
1111 1203
1112 return ret; 1204 return ret;
1113 } 1205 }
1114 1206
1115 /** 1207 /**
1116 * batadv_post_doit() - End batman-adv genl doit request 1208 * batadv_post_doit() - End batman-adv genl doit request
1117 * @ops: requested netlink operation 1209 * @ops: requested netlink operation
1118 * @skb: Netlink message with request data 1210 * @skb: Netlink message with request data
1119 * @info: receiver information 1211 * @info: receiver information
1120 */ 1212 */
1121 static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb, 1213 static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
1122 struct genl_info *info) 1214 struct genl_info *info)
1123 { 1215 {
1124 struct batadv_hard_iface *hard_iface; 1216 struct batadv_hard_iface *hard_iface;
1125 struct batadv_softif_vlan *vlan; 1217 struct batadv_softif_vlan *vlan;
1126 struct batadv_priv *bat_priv; 1218 struct batadv_priv *bat_priv;
1127 1219
1128 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF && 1220 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF &&
1129 info->user_ptr[1]) { 1221 info->user_ptr[1]) {
1130 hard_iface = info->user_ptr[1]; 1222 hard_iface = info->user_ptr[1];
1131 1223
1132 batadv_hardif_put(hard_iface); 1224 batadv_hardif_put(hard_iface);
1133 } 1225 }
1134 1226
1135 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN && info->user_ptr[1]) { 1227 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN && info->user_ptr[1]) {
1136 vlan = info->user_ptr[1]; 1228 vlan = info->user_ptr[1];
1137 batadv_softif_vlan_put(vlan); 1229 batadv_softif_vlan_put(vlan);
1138 } 1230 }
1139 1231
1140 if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) { 1232 if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) {
1141 bat_priv = info->user_ptr[0]; 1233 bat_priv = info->user_ptr[0];
1142 dev_put(bat_priv->soft_iface); 1234 dev_put(bat_priv->soft_iface);
1143 } 1235 }
1144 } 1236 }
1145 1237
1146 static const struct genl_ops batadv_netlink_ops[] = { 1238 static const struct genl_ops batadv_netlink_ops[] = {
1147 { 1239 {
1148 .cmd = BATADV_CMD_GET_MESH, 1240 .cmd = BATADV_CMD_GET_MESH,
1149 /* can be retrieved by unprivileged users */ 1241 /* can be retrieved by unprivileged users */
1150 .policy = batadv_netlink_policy, 1242 .policy = batadv_netlink_policy,
1151 .doit = batadv_netlink_get_mesh, 1243 .doit = batadv_netlink_get_mesh,
1152 .internal_flags = BATADV_FLAG_NEED_MESH, 1244 .internal_flags = BATADV_FLAG_NEED_MESH,
1153 }, 1245 },
1154 { 1246 {
1155 .cmd = BATADV_CMD_TP_METER, 1247 .cmd = BATADV_CMD_TP_METER,
1156 .flags = GENL_ADMIN_PERM, 1248 .flags = GENL_ADMIN_PERM,
1157 .policy = batadv_netlink_policy, 1249 .policy = batadv_netlink_policy,
1158 .doit = batadv_netlink_tp_meter_start, 1250 .doit = batadv_netlink_tp_meter_start,
1159 .internal_flags = BATADV_FLAG_NEED_MESH, 1251 .internal_flags = BATADV_FLAG_NEED_MESH,
1160 }, 1252 },
1161 { 1253 {
1162 .cmd = BATADV_CMD_TP_METER_CANCEL, 1254 .cmd = BATADV_CMD_TP_METER_CANCEL,
1163 .flags = GENL_ADMIN_PERM, 1255 .flags = GENL_ADMIN_PERM,
1164 .policy = batadv_netlink_policy, 1256 .policy = batadv_netlink_policy,
1165 .doit = batadv_netlink_tp_meter_cancel, 1257 .doit = batadv_netlink_tp_meter_cancel,
1166 .internal_flags = BATADV_FLAG_NEED_MESH, 1258 .internal_flags = BATADV_FLAG_NEED_MESH,
1167 }, 1259 },
1168 { 1260 {
1169 .cmd = BATADV_CMD_GET_ROUTING_ALGOS, 1261 .cmd = BATADV_CMD_GET_ROUTING_ALGOS,
1170 .flags = GENL_ADMIN_PERM, 1262 .flags = GENL_ADMIN_PERM,
1171 .policy = batadv_netlink_policy, 1263 .policy = batadv_netlink_policy,
1172 .dumpit = batadv_algo_dump, 1264 .dumpit = batadv_algo_dump,
1173 }, 1265 },
1174 { 1266 {
1175 .cmd = BATADV_CMD_GET_HARDIF, 1267 .cmd = BATADV_CMD_GET_HARDIF,
1176 /* can be retrieved by unprivileged users */ 1268 /* can be retrieved by unprivileged users */
1177 .policy = batadv_netlink_policy, 1269 .policy = batadv_netlink_policy,
1178 .dumpit = batadv_netlink_dump_hardif, 1270 .dumpit = batadv_netlink_dump_hardif,
1179 .doit = batadv_netlink_get_hardif, 1271 .doit = batadv_netlink_get_hardif,
1180 .internal_flags = BATADV_FLAG_NEED_MESH | 1272 .internal_flags = BATADV_FLAG_NEED_MESH |
1181 BATADV_FLAG_NEED_HARDIF, 1273 BATADV_FLAG_NEED_HARDIF,
1182 }, 1274 },
1183 { 1275 {
1184 .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL, 1276 .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
1185 .flags = GENL_ADMIN_PERM, 1277 .flags = GENL_ADMIN_PERM,
1186 .policy = batadv_netlink_policy, 1278 .policy = batadv_netlink_policy,
1187 .dumpit = batadv_tt_local_dump, 1279 .dumpit = batadv_tt_local_dump,
1188 }, 1280 },
1189 { 1281 {
1190 .cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL, 1282 .cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
1191 .flags = GENL_ADMIN_PERM, 1283 .flags = GENL_ADMIN_PERM,
1192 .policy = batadv_netlink_policy, 1284 .policy = batadv_netlink_policy,
1193 .dumpit = batadv_tt_global_dump, 1285 .dumpit = batadv_tt_global_dump,
1194 }, 1286 },
1195 { 1287 {
1196 .cmd = BATADV_CMD_GET_ORIGINATORS, 1288 .cmd = BATADV_CMD_GET_ORIGINATORS,
1197 .flags = GENL_ADMIN_PERM, 1289 .flags = GENL_ADMIN_PERM,
1198 .policy = batadv_netlink_policy, 1290 .policy = batadv_netlink_policy,
1199 .dumpit = batadv_orig_dump, 1291 .dumpit = batadv_orig_dump,
1200 }, 1292 },
1201 { 1293 {
1202 .cmd = BATADV_CMD_GET_NEIGHBORS, 1294 .cmd = BATADV_CMD_GET_NEIGHBORS,
1203 .flags = GENL_ADMIN_PERM, 1295 .flags = GENL_ADMIN_PERM,
1204 .policy = batadv_netlink_policy, 1296 .policy = batadv_netlink_policy,
1205 .dumpit = batadv_hardif_neigh_dump, 1297 .dumpit = batadv_hardif_neigh_dump,
1206 }, 1298 },
1207 { 1299 {
1208 .cmd = BATADV_CMD_GET_GATEWAYS, 1300 .cmd = BATADV_CMD_GET_GATEWAYS,
1209 .flags = GENL_ADMIN_PERM, 1301 .flags = GENL_ADMIN_PERM,
1210 .policy = batadv_netlink_policy, 1302 .policy = batadv_netlink_policy,
1211 .dumpit = batadv_gw_dump, 1303 .dumpit = batadv_gw_dump,
1212 }, 1304 },
1213 { 1305 {
1214 .cmd = BATADV_CMD_GET_BLA_CLAIM, 1306 .cmd = BATADV_CMD_GET_BLA_CLAIM,
1215 .flags = GENL_ADMIN_PERM, 1307 .flags = GENL_ADMIN_PERM,
1216 .policy = batadv_netlink_policy, 1308 .policy = batadv_netlink_policy,
1217 .dumpit = batadv_bla_claim_dump, 1309 .dumpit = batadv_bla_claim_dump,
1218 }, 1310 },
1219 { 1311 {
1220 .cmd = BATADV_CMD_GET_BLA_BACKBONE, 1312 .cmd = BATADV_CMD_GET_BLA_BACKBONE,
1221 .flags = GENL_ADMIN_PERM, 1313 .flags = GENL_ADMIN_PERM,
1222 .policy = batadv_netlink_policy, 1314 .policy = batadv_netlink_policy,
1223 .dumpit = batadv_bla_backbone_dump, 1315 .dumpit = batadv_bla_backbone_dump,
1224 }, 1316 },
1225 { 1317 {
1226 .cmd = BATADV_CMD_GET_DAT_CACHE, 1318 .cmd = BATADV_CMD_GET_DAT_CACHE,
1227 .flags = GENL_ADMIN_PERM, 1319 .flags = GENL_ADMIN_PERM,
1228 .policy = batadv_netlink_policy, 1320 .policy = batadv_netlink_policy,
1229 .dumpit = batadv_dat_cache_dump, 1321 .dumpit = batadv_dat_cache_dump,
1230 }, 1322 },
1231 { 1323 {
1232 .cmd = BATADV_CMD_GET_MCAST_FLAGS, 1324 .cmd = BATADV_CMD_GET_MCAST_FLAGS,
1233 .flags = GENL_ADMIN_PERM, 1325 .flags = GENL_ADMIN_PERM,
1234 .policy = batadv_netlink_policy, 1326 .policy = batadv_netlink_policy,
1235 .dumpit = batadv_mcast_flags_dump, 1327 .dumpit = batadv_mcast_flags_dump,
1236 }, 1328 },
1237 { 1329 {
1238 .cmd = BATADV_CMD_SET_MESH, 1330 .cmd = BATADV_CMD_SET_MESH,
1239 .flags = GENL_ADMIN_PERM, 1331 .flags = GENL_ADMIN_PERM,
1240 .policy = batadv_netlink_policy, 1332 .policy = batadv_netlink_policy,
1241 .doit = batadv_netlink_set_mesh, 1333 .doit = batadv_netlink_set_mesh,
1242 .internal_flags = BATADV_FLAG_NEED_MESH, 1334 .internal_flags = BATADV_FLAG_NEED_MESH,
1243 }, 1335 },
1244 { 1336 {
1245 .cmd = BATADV_CMD_SET_HARDIF, 1337 .cmd = BATADV_CMD_SET_HARDIF,
1246 .flags = GENL_ADMIN_PERM, 1338 .flags = GENL_ADMIN_PERM,
1247 .policy = batadv_netlink_policy, 1339 .policy = batadv_netlink_policy,
1248 .doit = batadv_netlink_set_hardif, 1340 .doit = batadv_netlink_set_hardif,
1249 .internal_flags = BATADV_FLAG_NEED_MESH | 1341 .internal_flags = BATADV_FLAG_NEED_MESH |
1250 BATADV_FLAG_NEED_HARDIF, 1342 BATADV_FLAG_NEED_HARDIF,
1251 }, 1343 },
1252 { 1344 {
1253 .cmd = BATADV_CMD_GET_VLAN, 1345 .cmd = BATADV_CMD_GET_VLAN,
1254 /* can be retrieved by unprivileged users */ 1346 /* can be retrieved by unprivileged users */
1255 .policy = batadv_netlink_policy, 1347 .policy = batadv_netlink_policy,
1256 .doit = batadv_netlink_get_vlan, 1348 .doit = batadv_netlink_get_vlan,
1257 .internal_flags = BATADV_FLAG_NEED_MESH | 1349 .internal_flags = BATADV_FLAG_NEED_MESH |
1258 BATADV_FLAG_NEED_VLAN, 1350 BATADV_FLAG_NEED_VLAN,
1259 }, 1351 },
1260 { 1352 {
1261 .cmd = BATADV_CMD_SET_VLAN, 1353 .cmd = BATADV_CMD_SET_VLAN,
1262 .flags = GENL_ADMIN_PERM, 1354 .flags = GENL_ADMIN_PERM,
1263 .policy = batadv_netlink_policy, 1355 .policy = batadv_netlink_policy,
1264 .doit = batadv_netlink_set_vlan, 1356 .doit = batadv_netlink_set_vlan,
1265 .internal_flags = BATADV_FLAG_NEED_MESH | 1357 .internal_flags = BATADV_FLAG_NEED_MESH |
1266 BATADV_FLAG_NEED_VLAN, 1358 BATADV_FLAG_NEED_VLAN,
1267 }, 1359 },
1268 }; 1360 };
1269 1361
1270 struct genl_family batadv_netlink_family __ro_after_init = { 1362 struct genl_family batadv_netlink_family __ro_after_init = {
1271 .hdrsize = 0, 1363 .hdrsize = 0,
1272 .name = BATADV_NL_NAME, 1364 .name = BATADV_NL_NAME,
1273 .version = 1, 1365 .version = 1,
1274 .maxattr = BATADV_ATTR_MAX, 1366 .maxattr = BATADV_ATTR_MAX,
1275 .netnsok = true, 1367 .netnsok = true,
1276 .pre_doit = batadv_pre_doit, 1368 .pre_doit = batadv_pre_doit,
1277 .post_doit = batadv_post_doit, 1369 .post_doit = batadv_post_doit,
1278 .module = THIS_MODULE, 1370 .module = THIS_MODULE,
1279 .ops = batadv_netlink_ops, 1371 .ops = batadv_netlink_ops,
1280 .n_ops = ARRAY_SIZE(batadv_netlink_ops), 1372 .n_ops = ARRAY_SIZE(batadv_netlink_ops),
1281 .mcgrps = batadv_netlink_mcgrps, 1373 .mcgrps = batadv_netlink_mcgrps,
1282 .n_mcgrps = ARRAY_SIZE(batadv_netlink_mcgrps), 1374 .n_mcgrps = ARRAY_SIZE(batadv_netlink_mcgrps),
1283 }; 1375 };
1284 1376
1285 /** 1377 /**
1286 * batadv_netlink_register() - register batadv genl netlink family 1378 * batadv_netlink_register() - register batadv genl netlink family
1287 */ 1379 */
1288 void __init batadv_netlink_register(void) 1380 void __init batadv_netlink_register(void)
1289 { 1381 {
1290 int ret; 1382 int ret;
1291 1383
1292 ret = genl_register_family(&batadv_netlink_family); 1384 ret = genl_register_family(&batadv_netlink_family);
1293 if (ret) 1385 if (ret)
1294 pr_warn("unable to register netlink family"); 1386 pr_warn("unable to register netlink family");
1295 } 1387 }
1296 1388
1297 /** 1389 /**
1298 * batadv_netlink_unregister() - unregister batadv genl netlink family 1390 * batadv_netlink_unregister() - unregister batadv genl netlink family
1299 */ 1391 */
1300 void batadv_netlink_unregister(void) 1392 void batadv_netlink_unregister(void)
1301 { 1393 {
1302 genl_unregister_family(&batadv_netlink_family); 1394 genl_unregister_family(&batadv_netlink_family);
1303 } 1395 }
1304 1396
net/batman-adv/soft-interface.c
1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2007-2019 B.A.T.M.A.N. contributors: 2 /* Copyright (C) 2007-2019 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation. 8 * License as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details. 13 * General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include "soft-interface.h" 19 #include "soft-interface.h"
20 #include "main.h" 20 #include "main.h"
21 21
22 #include <linux/atomic.h> 22 #include <linux/atomic.h>
23 #include <linux/byteorder/generic.h> 23 #include <linux/byteorder/generic.h>
24 #include <linux/cache.h> 24 #include <linux/cache.h>
25 #include <linux/compiler.h> 25 #include <linux/compiler.h>
26 #include <linux/cpumask.h> 26 #include <linux/cpumask.h>
27 #include <linux/errno.h> 27 #include <linux/errno.h>
28 #include <linux/etherdevice.h> 28 #include <linux/etherdevice.h>
29 #include <linux/ethtool.h> 29 #include <linux/ethtool.h>
30 #include <linux/gfp.h> 30 #include <linux/gfp.h>
31 #include <linux/if_ether.h> 31 #include <linux/if_ether.h>
32 #include <linux/if_vlan.h> 32 #include <linux/if_vlan.h>
33 #include <linux/jiffies.h> 33 #include <linux/jiffies.h>
34 #include <linux/kernel.h> 34 #include <linux/kernel.h>
35 #include <linux/kref.h> 35 #include <linux/kref.h>
36 #include <linux/list.h> 36 #include <linux/list.h>
37 #include <linux/lockdep.h> 37 #include <linux/lockdep.h>
38 #include <linux/netdevice.h> 38 #include <linux/netdevice.h>
39 #include <linux/percpu.h> 39 #include <linux/percpu.h>
40 #include <linux/printk.h> 40 #include <linux/printk.h>
41 #include <linux/random.h> 41 #include <linux/random.h>
42 #include <linux/rculist.h> 42 #include <linux/rculist.h>
43 #include <linux/rcupdate.h> 43 #include <linux/rcupdate.h>
44 #include <linux/rtnetlink.h> 44 #include <linux/rtnetlink.h>
45 #include <linux/skbuff.h> 45 #include <linux/skbuff.h>
46 #include <linux/slab.h> 46 #include <linux/slab.h>
47 #include <linux/socket.h> 47 #include <linux/socket.h>
48 #include <linux/spinlock.h> 48 #include <linux/spinlock.h>
49 #include <linux/stddef.h> 49 #include <linux/stddef.h>
50 #include <linux/string.h> 50 #include <linux/string.h>
51 #include <linux/types.h> 51 #include <linux/types.h>
52 #include <uapi/linux/batadv_packet.h> 52 #include <uapi/linux/batadv_packet.h>
53 #include <uapi/linux/batman_adv.h>
53 54
54 #include "bat_algo.h" 55 #include "bat_algo.h"
55 #include "bridge_loop_avoidance.h" 56 #include "bridge_loop_avoidance.h"
56 #include "debugfs.h" 57 #include "debugfs.h"
57 #include "distributed-arp-table.h" 58 #include "distributed-arp-table.h"
58 #include "gateway_client.h" 59 #include "gateway_client.h"
59 #include "gateway_common.h"
60 #include "hard-interface.h" 60 #include "hard-interface.h"
61 #include "multicast.h" 61 #include "multicast.h"
62 #include "network-coding.h" 62 #include "network-coding.h"
63 #include "originator.h" 63 #include "originator.h"
64 #include "send.h" 64 #include "send.h"
65 #include "sysfs.h" 65 #include "sysfs.h"
66 #include "translation-table.h" 66 #include "translation-table.h"
67 67
68 /** 68 /**
69 * batadv_skb_head_push() - Increase header size and move (push) head pointer 69 * batadv_skb_head_push() - Increase header size and move (push) head pointer
70 * @skb: packet buffer which should be modified 70 * @skb: packet buffer which should be modified
71 * @len: number of bytes to add 71 * @len: number of bytes to add
72 * 72 *
73 * Return: 0 on success or negative error number in case of failure 73 * Return: 0 on success or negative error number in case of failure
74 */ 74 */
75 int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) 75 int batadv_skb_head_push(struct sk_buff *skb, unsigned int len)
76 { 76 {
77 int result; 77 int result;
78 78
79 /* TODO: We must check if we can release all references to non-payload 79 /* TODO: We must check if we can release all references to non-payload
80 * data using __skb_header_release in our skbs to allow skb_cow_header 80 * data using __skb_header_release in our skbs to allow skb_cow_header
81 * to work optimally. This means that those skbs are not allowed to read 81 * to work optimally. This means that those skbs are not allowed to read
82 * or write any data which is before the current position of skb->data 82 * or write any data which is before the current position of skb->data
83 * after that call and thus allow other skbs with the same data buffer 83 * after that call and thus allow other skbs with the same data buffer
84 * to write freely in that area. 84 * to write freely in that area.
85 */ 85 */
86 result = skb_cow_head(skb, len); 86 result = skb_cow_head(skb, len);
87 if (result < 0) 87 if (result < 0)
88 return result; 88 return result;
89 89
90 skb_push(skb, len); 90 skb_push(skb, len);
91 return 0; 91 return 0;
92 } 92 }
93 93
94 static int batadv_interface_open(struct net_device *dev) 94 static int batadv_interface_open(struct net_device *dev)
95 { 95 {
96 netif_start_queue(dev); 96 netif_start_queue(dev);
97 return 0; 97 return 0;
98 } 98 }
99 99
100 static int batadv_interface_release(struct net_device *dev) 100 static int batadv_interface_release(struct net_device *dev)
101 { 101 {
102 netif_stop_queue(dev); 102 netif_stop_queue(dev);
103 return 0; 103 return 0;
104 } 104 }
105 105
106 /** 106 /**
107 * batadv_sum_counter() - Sum the cpu-local counters for index 'idx' 107 * batadv_sum_counter() - Sum the cpu-local counters for index 'idx'
108 * @bat_priv: the bat priv with all the soft interface information 108 * @bat_priv: the bat priv with all the soft interface information
109 * @idx: index of counter to sum up 109 * @idx: index of counter to sum up
110 * 110 *
111 * Return: sum of all cpu-local counters 111 * Return: sum of all cpu-local counters
112 */ 112 */
113 static u64 batadv_sum_counter(struct batadv_priv *bat_priv, size_t idx) 113 static u64 batadv_sum_counter(struct batadv_priv *bat_priv, size_t idx)
114 { 114 {
115 u64 *counters, sum = 0; 115 u64 *counters, sum = 0;
116 int cpu; 116 int cpu;
117 117
118 for_each_possible_cpu(cpu) { 118 for_each_possible_cpu(cpu) {
119 counters = per_cpu_ptr(bat_priv->bat_counters, cpu); 119 counters = per_cpu_ptr(bat_priv->bat_counters, cpu);
120 sum += counters[idx]; 120 sum += counters[idx];
121 } 121 }
122 122
123 return sum; 123 return sum;
124 } 124 }
125 125
126 static struct net_device_stats *batadv_interface_stats(struct net_device *dev) 126 static struct net_device_stats *batadv_interface_stats(struct net_device *dev)
127 { 127 {
128 struct batadv_priv *bat_priv = netdev_priv(dev); 128 struct batadv_priv *bat_priv = netdev_priv(dev);
129 struct net_device_stats *stats = &dev->stats; 129 struct net_device_stats *stats = &dev->stats;
130 130
131 stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); 131 stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX);
132 stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); 132 stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES);
133 stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); 133 stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED);
134 stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); 134 stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX);
135 stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); 135 stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES);
136 return stats; 136 return stats;
137 } 137 }
138 138
139 static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) 139 static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
140 { 140 {
141 struct batadv_priv *bat_priv = netdev_priv(dev); 141 struct batadv_priv *bat_priv = netdev_priv(dev);
142 struct batadv_softif_vlan *vlan; 142 struct batadv_softif_vlan *vlan;
143 struct sockaddr *addr = p; 143 struct sockaddr *addr = p;
144 u8 old_addr[ETH_ALEN]; 144 u8 old_addr[ETH_ALEN];
145 145
146 if (!is_valid_ether_addr(addr->sa_data)) 146 if (!is_valid_ether_addr(addr->sa_data))
147 return -EADDRNOTAVAIL; 147 return -EADDRNOTAVAIL;
148 148
149 ether_addr_copy(old_addr, dev->dev_addr); 149 ether_addr_copy(old_addr, dev->dev_addr);
150 ether_addr_copy(dev->dev_addr, addr->sa_data); 150 ether_addr_copy(dev->dev_addr, addr->sa_data);
151 151
152 /* only modify transtable if it has been initialized before */ 152 /* only modify transtable if it has been initialized before */
153 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 153 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
154 return 0; 154 return 0;
155 155
156 rcu_read_lock(); 156 rcu_read_lock();
157 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { 157 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
158 batadv_tt_local_remove(bat_priv, old_addr, vlan->vid, 158 batadv_tt_local_remove(bat_priv, old_addr, vlan->vid,
159 "mac address changed", false); 159 "mac address changed", false);
160 batadv_tt_local_add(dev, addr->sa_data, vlan->vid, 160 batadv_tt_local_add(dev, addr->sa_data, vlan->vid,
161 BATADV_NULL_IFINDEX, BATADV_NO_MARK); 161 BATADV_NULL_IFINDEX, BATADV_NO_MARK);
162 } 162 }
163 rcu_read_unlock(); 163 rcu_read_unlock();
164 164
165 return 0; 165 return 0;
166 } 166 }
167 167
168 static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) 168 static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
169 { 169 {
170 /* check ranges */ 170 /* check ranges */
171 if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev)) 171 if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev))
172 return -EINVAL; 172 return -EINVAL;
173 173
174 dev->mtu = new_mtu; 174 dev->mtu = new_mtu;
175 175
176 return 0; 176 return 0;
177 } 177 }
178 178
179 /** 179 /**
180 * batadv_interface_set_rx_mode() - set the rx mode of a device 180 * batadv_interface_set_rx_mode() - set the rx mode of a device
181 * @dev: registered network device to modify 181 * @dev: registered network device to modify
182 * 182 *
183 * We do not actually need to set any rx filters for the virtual batman 183 * We do not actually need to set any rx filters for the virtual batman
184 * soft interface. However a dummy handler enables a user to set static 184 * soft interface. However a dummy handler enables a user to set static
185 * multicast listeners for instance. 185 * multicast listeners for instance.
186 */ 186 */
187 static void batadv_interface_set_rx_mode(struct net_device *dev) 187 static void batadv_interface_set_rx_mode(struct net_device *dev)
188 { 188 {
189 } 189 }
190 190
191 static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, 191 static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
192 struct net_device *soft_iface) 192 struct net_device *soft_iface)
193 { 193 {
194 struct ethhdr *ethhdr; 194 struct ethhdr *ethhdr;
195 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 195 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
196 struct batadv_hard_iface *primary_if = NULL; 196 struct batadv_hard_iface *primary_if = NULL;
197 struct batadv_bcast_packet *bcast_packet; 197 struct batadv_bcast_packet *bcast_packet;
198 static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 198 static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
199 0x00, 0x00}; 199 0x00, 0x00};
200 static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, 200 static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
201 0x00, 0x00}; 201 0x00, 0x00};
202 enum batadv_dhcp_recipient dhcp_rcp = BATADV_DHCP_NO; 202 enum batadv_dhcp_recipient dhcp_rcp = BATADV_DHCP_NO;
203 u8 *dst_hint = NULL, chaddr[ETH_ALEN]; 203 u8 *dst_hint = NULL, chaddr[ETH_ALEN];
204 struct vlan_ethhdr *vhdr; 204 struct vlan_ethhdr *vhdr;
205 unsigned int header_len = 0; 205 unsigned int header_len = 0;
206 int data_len = skb->len, ret; 206 int data_len = skb->len, ret;
207 unsigned long brd_delay = 1; 207 unsigned long brd_delay = 1;
208 bool do_bcast = false, client_added; 208 bool do_bcast = false, client_added;
209 unsigned short vid; 209 unsigned short vid;
210 u32 seqno; 210 u32 seqno;
211 int gw_mode; 211 int gw_mode;
212 enum batadv_forw_mode forw_mode; 212 enum batadv_forw_mode forw_mode;
213 struct batadv_orig_node *mcast_single_orig = NULL; 213 struct batadv_orig_node *mcast_single_orig = NULL;
214 int network_offset = ETH_HLEN; 214 int network_offset = ETH_HLEN;
215 __be16 proto; 215 __be16 proto;
216 216
217 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 217 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
218 goto dropped; 218 goto dropped;
219 219
220 /* reset control block to avoid left overs from previous users */ 220 /* reset control block to avoid left overs from previous users */
221 memset(skb->cb, 0, sizeof(struct batadv_skb_cb)); 221 memset(skb->cb, 0, sizeof(struct batadv_skb_cb));
222 222
223 netif_trans_update(soft_iface); 223 netif_trans_update(soft_iface);
224 vid = batadv_get_vid(skb, 0); 224 vid = batadv_get_vid(skb, 0);
225 ethhdr = eth_hdr(skb); 225 ethhdr = eth_hdr(skb);
226 226
227 proto = ethhdr->h_proto; 227 proto = ethhdr->h_proto;
228 228
229 switch (ntohs(proto)) { 229 switch (ntohs(proto)) {
230 case ETH_P_8021Q: 230 case ETH_P_8021Q:
231 vhdr = vlan_eth_hdr(skb); 231 vhdr = vlan_eth_hdr(skb);
232 proto = vhdr->h_vlan_encapsulated_proto; 232 proto = vhdr->h_vlan_encapsulated_proto;
233 233
234 /* drop batman-in-batman packets to prevent loops */ 234 /* drop batman-in-batman packets to prevent loops */
235 if (proto != htons(ETH_P_BATMAN)) { 235 if (proto != htons(ETH_P_BATMAN)) {
236 network_offset += VLAN_HLEN; 236 network_offset += VLAN_HLEN;
237 break; 237 break;
238 } 238 }
239 239
240 /* fall through */ 240 /* fall through */
241 case ETH_P_BATMAN: 241 case ETH_P_BATMAN:
242 goto dropped; 242 goto dropped;
243 } 243 }
244 244
245 skb_set_network_header(skb, network_offset); 245 skb_set_network_header(skb, network_offset);
246 246
247 if (batadv_bla_tx(bat_priv, skb, vid)) 247 if (batadv_bla_tx(bat_priv, skb, vid))
248 goto dropped; 248 goto dropped;
249 249
250 /* skb->data might have been reallocated by batadv_bla_tx() */ 250 /* skb->data might have been reallocated by batadv_bla_tx() */
251 ethhdr = eth_hdr(skb); 251 ethhdr = eth_hdr(skb);
252 252
253 /* Register the client MAC in the transtable */ 253 /* Register the client MAC in the transtable */
254 if (!is_multicast_ether_addr(ethhdr->h_source) && 254 if (!is_multicast_ether_addr(ethhdr->h_source) &&
255 !batadv_bla_is_loopdetect_mac(ethhdr->h_source)) { 255 !batadv_bla_is_loopdetect_mac(ethhdr->h_source)) {
256 client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source, 256 client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source,
257 vid, skb->skb_iif, 257 vid, skb->skb_iif,
258 skb->mark); 258 skb->mark);
259 if (!client_added) 259 if (!client_added)
260 goto dropped; 260 goto dropped;
261 } 261 }
262 262
263 /* Snoop address candidates from DHCPACKs for early DAT filling */ 263 /* Snoop address candidates from DHCPACKs for early DAT filling */
264 batadv_dat_snoop_outgoing_dhcp_ack(bat_priv, skb, proto, vid); 264 batadv_dat_snoop_outgoing_dhcp_ack(bat_priv, skb, proto, vid);
265 265
266 /* don't accept stp packets. STP does not help in meshes. 266 /* don't accept stp packets. STP does not help in meshes.
267 * better use the bridge loop avoidance ... 267 * better use the bridge loop avoidance ...
268 * 268 *
269 * The same goes for ECTP sent at least by some Cisco Switches, 269 * The same goes for ECTP sent at least by some Cisco Switches,
270 * it might confuse the mesh when used with bridge loop avoidance. 270 * it might confuse the mesh when used with bridge loop avoidance.
271 */ 271 */
272 if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) 272 if (batadv_compare_eth(ethhdr->h_dest, stp_addr))
273 goto dropped; 273 goto dropped;
274 274
275 if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) 275 if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
276 goto dropped; 276 goto dropped;
277 277
278 gw_mode = atomic_read(&bat_priv->gw.mode); 278 gw_mode = atomic_read(&bat_priv->gw.mode);
279 if (is_multicast_ether_addr(ethhdr->h_dest)) { 279 if (is_multicast_ether_addr(ethhdr->h_dest)) {
280 /* if gw mode is off, broadcast every packet */ 280 /* if gw mode is off, broadcast every packet */
281 if (gw_mode == BATADV_GW_MODE_OFF) { 281 if (gw_mode == BATADV_GW_MODE_OFF) {
282 do_bcast = true; 282 do_bcast = true;
283 goto send; 283 goto send;
284 } 284 }
285 285
286 dhcp_rcp = batadv_gw_dhcp_recipient_get(skb, &header_len, 286 dhcp_rcp = batadv_gw_dhcp_recipient_get(skb, &header_len,
287 chaddr); 287 chaddr);
288 /* skb->data may have been modified by 288 /* skb->data may have been modified by
289 * batadv_gw_dhcp_recipient_get() 289 * batadv_gw_dhcp_recipient_get()
290 */ 290 */
291 ethhdr = eth_hdr(skb); 291 ethhdr = eth_hdr(skb);
292 /* if gw_mode is on, broadcast any non-DHCP message. 292 /* if gw_mode is on, broadcast any non-DHCP message.
293 * All the DHCP packets are going to be sent as unicast 293 * All the DHCP packets are going to be sent as unicast
294 */ 294 */
295 if (dhcp_rcp == BATADV_DHCP_NO) { 295 if (dhcp_rcp == BATADV_DHCP_NO) {
296 do_bcast = true; 296 do_bcast = true;
297 goto send; 297 goto send;
298 } 298 }
299 299
300 if (dhcp_rcp == BATADV_DHCP_TO_CLIENT) 300 if (dhcp_rcp == BATADV_DHCP_TO_CLIENT)
301 dst_hint = chaddr; 301 dst_hint = chaddr;
302 else if ((gw_mode == BATADV_GW_MODE_SERVER) && 302 else if ((gw_mode == BATADV_GW_MODE_SERVER) &&
303 (dhcp_rcp == BATADV_DHCP_TO_SERVER)) 303 (dhcp_rcp == BATADV_DHCP_TO_SERVER))
304 /* gateways should not forward any DHCP message if 304 /* gateways should not forward any DHCP message if
305 * directed to a DHCP server 305 * directed to a DHCP server
306 */ 306 */
307 goto dropped; 307 goto dropped;
308 308
309 send: 309 send:
310 if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { 310 if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) {
311 forw_mode = batadv_mcast_forw_mode(bat_priv, skb, 311 forw_mode = batadv_mcast_forw_mode(bat_priv, skb,
312 &mcast_single_orig); 312 &mcast_single_orig);
313 if (forw_mode == BATADV_FORW_NONE) 313 if (forw_mode == BATADV_FORW_NONE)
314 goto dropped; 314 goto dropped;
315 315
316 if (forw_mode == BATADV_FORW_SINGLE) 316 if (forw_mode == BATADV_FORW_SINGLE)
317 do_bcast = false; 317 do_bcast = false;
318 } 318 }
319 } 319 }
320 320
321 batadv_skb_set_priority(skb, 0); 321 batadv_skb_set_priority(skb, 0);
322 322
323 /* ethernet packet should be broadcasted */ 323 /* ethernet packet should be broadcasted */
324 if (do_bcast) { 324 if (do_bcast) {
325 primary_if = batadv_primary_if_get_selected(bat_priv); 325 primary_if = batadv_primary_if_get_selected(bat_priv);
326 if (!primary_if) 326 if (!primary_if)
327 goto dropped; 327 goto dropped;
328 328
329 /* in case of ARP request, we do not immediately broadcasti the 329 /* in case of ARP request, we do not immediately broadcasti the
330 * packet, instead we first wait for DAT to try to retrieve the 330 * packet, instead we first wait for DAT to try to retrieve the
331 * correct ARP entry 331 * correct ARP entry
332 */ 332 */
333 if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) 333 if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
334 brd_delay = msecs_to_jiffies(ARP_REQ_DELAY); 334 brd_delay = msecs_to_jiffies(ARP_REQ_DELAY);
335 335
336 if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) 336 if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
337 goto dropped; 337 goto dropped;
338 338
339 bcast_packet = (struct batadv_bcast_packet *)skb->data; 339 bcast_packet = (struct batadv_bcast_packet *)skb->data;
340 bcast_packet->version = BATADV_COMPAT_VERSION; 340 bcast_packet->version = BATADV_COMPAT_VERSION;
341 bcast_packet->ttl = BATADV_TTL; 341 bcast_packet->ttl = BATADV_TTL;
342 342
343 /* batman packet type: broadcast */ 343 /* batman packet type: broadcast */
344 bcast_packet->packet_type = BATADV_BCAST; 344 bcast_packet->packet_type = BATADV_BCAST;
345 bcast_packet->reserved = 0; 345 bcast_packet->reserved = 0;
346 346
347 /* hw address of first interface is the orig mac because only 347 /* hw address of first interface is the orig mac because only
348 * this mac is known throughout the mesh 348 * this mac is known throughout the mesh
349 */ 349 */
350 ether_addr_copy(bcast_packet->orig, 350 ether_addr_copy(bcast_packet->orig,
351 primary_if->net_dev->dev_addr); 351 primary_if->net_dev->dev_addr);
352 352
353 /* set broadcast sequence number */ 353 /* set broadcast sequence number */
354 seqno = atomic_inc_return(&bat_priv->bcast_seqno); 354 seqno = atomic_inc_return(&bat_priv->bcast_seqno);
355 bcast_packet->seqno = htonl(seqno); 355 bcast_packet->seqno = htonl(seqno);
356 356
357 batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay, true); 357 batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay, true);
358 358
359 /* a copy is stored in the bcast list, therefore removing 359 /* a copy is stored in the bcast list, therefore removing
360 * the original skb. 360 * the original skb.
361 */ 361 */
362 consume_skb(skb); 362 consume_skb(skb);
363 363
364 /* unicast packet */ 364 /* unicast packet */
365 } else { 365 } else {
366 /* DHCP packets going to a server will use the GW feature */ 366 /* DHCP packets going to a server will use the GW feature */
367 if (dhcp_rcp == BATADV_DHCP_TO_SERVER) { 367 if (dhcp_rcp == BATADV_DHCP_TO_SERVER) {
368 ret = batadv_gw_out_of_range(bat_priv, skb); 368 ret = batadv_gw_out_of_range(bat_priv, skb);
369 if (ret) 369 if (ret)
370 goto dropped; 370 goto dropped;
371 ret = batadv_send_skb_via_gw(bat_priv, skb, vid); 371 ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
372 } else if (mcast_single_orig) { 372 } else if (mcast_single_orig) {
373 ret = batadv_send_skb_unicast(bat_priv, skb, 373 ret = batadv_send_skb_unicast(bat_priv, skb,
374 BATADV_UNICAST, 0, 374 BATADV_UNICAST, 0,
375 mcast_single_orig, vid); 375 mcast_single_orig, vid);
376 } else { 376 } else {
377 if (batadv_dat_snoop_outgoing_arp_request(bat_priv, 377 if (batadv_dat_snoop_outgoing_arp_request(bat_priv,
378 skb)) 378 skb))
379 goto dropped; 379 goto dropped;
380 380
381 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); 381 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
382 382
383 ret = batadv_send_skb_via_tt(bat_priv, skb, dst_hint, 383 ret = batadv_send_skb_via_tt(bat_priv, skb, dst_hint,
384 vid); 384 vid);
385 } 385 }
386 if (ret != NET_XMIT_SUCCESS) 386 if (ret != NET_XMIT_SUCCESS)
387 goto dropped_freed; 387 goto dropped_freed;
388 } 388 }
389 389
390 batadv_inc_counter(bat_priv, BATADV_CNT_TX); 390 batadv_inc_counter(bat_priv, BATADV_CNT_TX);
391 batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); 391 batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len);
392 goto end; 392 goto end;
393 393
394 dropped: 394 dropped:
395 kfree_skb(skb); 395 kfree_skb(skb);
396 dropped_freed: 396 dropped_freed:
397 batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); 397 batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED);
398 end: 398 end:
399 if (mcast_single_orig) 399 if (mcast_single_orig)
400 batadv_orig_node_put(mcast_single_orig); 400 batadv_orig_node_put(mcast_single_orig);
401 if (primary_if) 401 if (primary_if)
402 batadv_hardif_put(primary_if); 402 batadv_hardif_put(primary_if);
403 return NETDEV_TX_OK; 403 return NETDEV_TX_OK;
404 } 404 }
405 405
406 /** 406 /**
407 * batadv_interface_rx() - receive ethernet frame on local batman-adv interface 407 * batadv_interface_rx() - receive ethernet frame on local batman-adv interface
408 * @soft_iface: local interface which will receive the ethernet frame 408 * @soft_iface: local interface which will receive the ethernet frame
409 * @skb: ethernet frame for @soft_iface 409 * @skb: ethernet frame for @soft_iface
410 * @hdr_size: size of already parsed batman-adv header 410 * @hdr_size: size of already parsed batman-adv header
411 * @orig_node: originator from which the batman-adv packet was sent 411 * @orig_node: originator from which the batman-adv packet was sent
412 * 412 *
413 * Sends a ethernet frame to the receive path of the local @soft_iface. 413 * Sends a ethernet frame to the receive path of the local @soft_iface.
414 * skb->data has still point to the batman-adv header with the size @hdr_size. 414 * skb->data has still point to the batman-adv header with the size @hdr_size.
415 * The caller has to have parsed this header already and made sure that at least 415 * The caller has to have parsed this header already and made sure that at least
416 * @hdr_size bytes are still available for pull in @skb. 416 * @hdr_size bytes are still available for pull in @skb.
417 * 417 *
418 * The packet may still get dropped. This can happen when the encapsulated 418 * The packet may still get dropped. This can happen when the encapsulated
419 * ethernet frame is invalid or contains again an batman-adv packet. Also 419 * ethernet frame is invalid or contains again an batman-adv packet. Also
420 * unicast packets will be dropped directly when it was sent between two 420 * unicast packets will be dropped directly when it was sent between two
421 * isolated clients. 421 * isolated clients.
422 */ 422 */
423 void batadv_interface_rx(struct net_device *soft_iface, 423 void batadv_interface_rx(struct net_device *soft_iface,
424 struct sk_buff *skb, int hdr_size, 424 struct sk_buff *skb, int hdr_size,
425 struct batadv_orig_node *orig_node) 425 struct batadv_orig_node *orig_node)
426 { 426 {
427 struct batadv_bcast_packet *batadv_bcast_packet; 427 struct batadv_bcast_packet *batadv_bcast_packet;
428 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 428 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
429 struct vlan_ethhdr *vhdr; 429 struct vlan_ethhdr *vhdr;
430 struct ethhdr *ethhdr; 430 struct ethhdr *ethhdr;
431 unsigned short vid; 431 unsigned short vid;
432 bool is_bcast; 432 bool is_bcast;
433 433
434 batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; 434 batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
435 is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); 435 is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST);
436 436
437 skb_pull_rcsum(skb, hdr_size); 437 skb_pull_rcsum(skb, hdr_size);
438 skb_reset_mac_header(skb); 438 skb_reset_mac_header(skb);
439 439
440 /* clean the netfilter state now that the batman-adv header has been 440 /* clean the netfilter state now that the batman-adv header has been
441 * removed 441 * removed
442 */ 442 */
443 nf_reset(skb); 443 nf_reset(skb);
444 444
445 if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) 445 if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
446 goto dropped; 446 goto dropped;
447 447
448 vid = batadv_get_vid(skb, 0); 448 vid = batadv_get_vid(skb, 0);
449 ethhdr = eth_hdr(skb); 449 ethhdr = eth_hdr(skb);
450 450
451 switch (ntohs(ethhdr->h_proto)) { 451 switch (ntohs(ethhdr->h_proto)) {
452 case ETH_P_8021Q: 452 case ETH_P_8021Q:
453 if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) 453 if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
454 goto dropped; 454 goto dropped;
455 455
456 vhdr = (struct vlan_ethhdr *)skb->data; 456 vhdr = (struct vlan_ethhdr *)skb->data;
457 457
458 /* drop batman-in-batman packets to prevent loops */ 458 /* drop batman-in-batman packets to prevent loops */
459 if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) 459 if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN))
460 break; 460 break;
461 461
462 /* fall through */ 462 /* fall through */
463 case ETH_P_BATMAN: 463 case ETH_P_BATMAN:
464 goto dropped; 464 goto dropped;
465 } 465 }
466 466
467 /* skb->dev & skb->pkt_type are set here */ 467 /* skb->dev & skb->pkt_type are set here */
468 skb->protocol = eth_type_trans(skb, soft_iface); 468 skb->protocol = eth_type_trans(skb, soft_iface);
469 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); 469 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
470 470
471 batadv_inc_counter(bat_priv, BATADV_CNT_RX); 471 batadv_inc_counter(bat_priv, BATADV_CNT_RX);
472 batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, 472 batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
473 skb->len + ETH_HLEN); 473 skb->len + ETH_HLEN);
474 474
475 /* Let the bridge loop avoidance check the packet. If will 475 /* Let the bridge loop avoidance check the packet. If will
476 * not handle it, we can safely push it up. 476 * not handle it, we can safely push it up.
477 */ 477 */
478 if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) 478 if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
479 goto out; 479 goto out;
480 480
481 if (orig_node) 481 if (orig_node)
482 batadv_tt_add_temporary_global_entry(bat_priv, orig_node, 482 batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
483 ethhdr->h_source, vid); 483 ethhdr->h_source, vid);
484 484
485 if (is_multicast_ether_addr(ethhdr->h_dest)) { 485 if (is_multicast_ether_addr(ethhdr->h_dest)) {
486 /* set the mark on broadcast packets if AP isolation is ON and 486 /* set the mark on broadcast packets if AP isolation is ON and
487 * the packet is coming from an "isolated" client 487 * the packet is coming from an "isolated" client
488 */ 488 */
489 if (batadv_vlan_ap_isola_get(bat_priv, vid) && 489 if (batadv_vlan_ap_isola_get(bat_priv, vid) &&
490 batadv_tt_global_is_isolated(bat_priv, ethhdr->h_source, 490 batadv_tt_global_is_isolated(bat_priv, ethhdr->h_source,
491 vid)) { 491 vid)) {
492 /* save bits in skb->mark not covered by the mask and 492 /* save bits in skb->mark not covered by the mask and
493 * apply the mark on the rest 493 * apply the mark on the rest
494 */ 494 */
495 skb->mark &= ~bat_priv->isolation_mark_mask; 495 skb->mark &= ~bat_priv->isolation_mark_mask;
496 skb->mark |= bat_priv->isolation_mark; 496 skb->mark |= bat_priv->isolation_mark;
497 } 497 }
498 } else if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, 498 } else if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source,
499 ethhdr->h_dest, vid)) { 499 ethhdr->h_dest, vid)) {
500 goto dropped; 500 goto dropped;
501 } 501 }
502 502
503 netif_rx(skb); 503 netif_rx(skb);
504 goto out; 504 goto out;
505 505
506 dropped: 506 dropped:
507 kfree_skb(skb); 507 kfree_skb(skb);
508 out: 508 out:
509 return; 509 return;
510 } 510 }
511 511
512 /** 512 /**
513 * batadv_softif_vlan_release() - release vlan from lists and queue for free 513 * batadv_softif_vlan_release() - release vlan from lists and queue for free
514 * after rcu grace period 514 * after rcu grace period
515 * @ref: kref pointer of the vlan object 515 * @ref: kref pointer of the vlan object
516 */ 516 */
517 static void batadv_softif_vlan_release(struct kref *ref) 517 static void batadv_softif_vlan_release(struct kref *ref)
518 { 518 {
519 struct batadv_softif_vlan *vlan; 519 struct batadv_softif_vlan *vlan;
520 520
521 vlan = container_of(ref, struct batadv_softif_vlan, refcount); 521 vlan = container_of(ref, struct batadv_softif_vlan, refcount);
522 522
523 spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock); 523 spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock);
524 hlist_del_rcu(&vlan->list); 524 hlist_del_rcu(&vlan->list);
525 spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock); 525 spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock);
526 526
527 kfree_rcu(vlan, rcu); 527 kfree_rcu(vlan, rcu);
528 } 528 }
529 529
530 /** 530 /**
531 * batadv_softif_vlan_put() - decrease the vlan object refcounter and 531 * batadv_softif_vlan_put() - decrease the vlan object refcounter and
532 * possibly release it 532 * possibly release it
533 * @vlan: the vlan object to release 533 * @vlan: the vlan object to release
534 */ 534 */
535 void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan) 535 void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan)
536 { 536 {
537 if (!vlan) 537 if (!vlan)
538 return; 538 return;
539 539
540 kref_put(&vlan->refcount, batadv_softif_vlan_release); 540 kref_put(&vlan->refcount, batadv_softif_vlan_release);
541 } 541 }
542 542
543 /** 543 /**
544 * batadv_softif_vlan_get() - get the vlan object for a specific vid 544 * batadv_softif_vlan_get() - get the vlan object for a specific vid
545 * @bat_priv: the bat priv with all the soft interface information 545 * @bat_priv: the bat priv with all the soft interface information
546 * @vid: the identifier of the vlan object to retrieve 546 * @vid: the identifier of the vlan object to retrieve
547 * 547 *
548 * Return: the private data of the vlan matching the vid passed as argument or 548 * Return: the private data of the vlan matching the vid passed as argument or
549 * NULL otherwise. The refcounter of the returned object is incremented by 1. 549 * NULL otherwise. The refcounter of the returned object is incremented by 1.
550 */ 550 */
551 struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv, 551 struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
552 unsigned short vid) 552 unsigned short vid)
553 { 553 {
554 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL; 554 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
555 555
556 rcu_read_lock(); 556 rcu_read_lock();
557 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) { 557 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
558 if (vlan_tmp->vid != vid) 558 if (vlan_tmp->vid != vid)
559 continue; 559 continue;
560 560
561 if (!kref_get_unless_zero(&vlan_tmp->refcount)) 561 if (!kref_get_unless_zero(&vlan_tmp->refcount))
562 continue; 562 continue;
563 563
564 vlan = vlan_tmp; 564 vlan = vlan_tmp;
565 break; 565 break;
566 } 566 }
567 rcu_read_unlock(); 567 rcu_read_unlock();
568 568
569 return vlan; 569 return vlan;
570 } 570 }
571 571
572 /** 572 /**
573 * batadv_softif_create_vlan() - allocate the needed resources for a new vlan 573 * batadv_softif_create_vlan() - allocate the needed resources for a new vlan
574 * @bat_priv: the bat priv with all the soft interface information 574 * @bat_priv: the bat priv with all the soft interface information
575 * @vid: the VLAN identifier 575 * @vid: the VLAN identifier
576 * 576 *
577 * Return: 0 on success, a negative error otherwise. 577 * Return: 0 on success, a negative error otherwise.
578 */ 578 */
579 int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) 579 int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
580 { 580 {
581 struct batadv_softif_vlan *vlan; 581 struct batadv_softif_vlan *vlan;
582 int err; 582 int err;
583 583
584 spin_lock_bh(&bat_priv->softif_vlan_list_lock); 584 spin_lock_bh(&bat_priv->softif_vlan_list_lock);
585 585
586 vlan = batadv_softif_vlan_get(bat_priv, vid); 586 vlan = batadv_softif_vlan_get(bat_priv, vid);
587 if (vlan) { 587 if (vlan) {
588 batadv_softif_vlan_put(vlan); 588 batadv_softif_vlan_put(vlan);
589 spin_unlock_bh(&bat_priv->softif_vlan_list_lock); 589 spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
590 return -EEXIST; 590 return -EEXIST;
591 } 591 }
592 592
593 vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); 593 vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
594 if (!vlan) { 594 if (!vlan) {
595 spin_unlock_bh(&bat_priv->softif_vlan_list_lock); 595 spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
596 return -ENOMEM; 596 return -ENOMEM;
597 } 597 }
598 598
599 vlan->bat_priv = bat_priv; 599 vlan->bat_priv = bat_priv;
600 vlan->vid = vid; 600 vlan->vid = vid;
601 kref_init(&vlan->refcount); 601 kref_init(&vlan->refcount);
602 602
603 atomic_set(&vlan->ap_isolation, 0); 603 atomic_set(&vlan->ap_isolation, 0);
604 604
605 kref_get(&vlan->refcount); 605 kref_get(&vlan->refcount);
606 hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list); 606 hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
607 spin_unlock_bh(&bat_priv->softif_vlan_list_lock); 607 spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
608 608
609 /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the 609 /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the
610 * sleeping behavior of the sysfs functions and the fs_reclaim lock 610 * sleeping behavior of the sysfs functions and the fs_reclaim lock
611 */ 611 */
612 err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); 612 err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
613 if (err) { 613 if (err) {
614 /* ref for the function */ 614 /* ref for the function */
615 batadv_softif_vlan_put(vlan); 615 batadv_softif_vlan_put(vlan);
616 616
617 /* ref for the list */ 617 /* ref for the list */
618 batadv_softif_vlan_put(vlan); 618 batadv_softif_vlan_put(vlan);
619 return err; 619 return err;
620 } 620 }
621 621
622 /* add a new TT local entry. This one will be marked with the NOPURGE 622 /* add a new TT local entry. This one will be marked with the NOPURGE
623 * flag 623 * flag
624 */ 624 */
625 batadv_tt_local_add(bat_priv->soft_iface, 625 batadv_tt_local_add(bat_priv->soft_iface,
626 bat_priv->soft_iface->dev_addr, vid, 626 bat_priv->soft_iface->dev_addr, vid,
627 BATADV_NULL_IFINDEX, BATADV_NO_MARK); 627 BATADV_NULL_IFINDEX, BATADV_NO_MARK);
628 628
629 /* don't return reference to new softif_vlan */ 629 /* don't return reference to new softif_vlan */
630 batadv_softif_vlan_put(vlan); 630 batadv_softif_vlan_put(vlan);
631 631
632 return 0; 632 return 0;
633 } 633 }
634 634
635 /** 635 /**
636 * batadv_softif_destroy_vlan() - remove and destroy a softif_vlan object 636 * batadv_softif_destroy_vlan() - remove and destroy a softif_vlan object
637 * @bat_priv: the bat priv with all the soft interface information 637 * @bat_priv: the bat priv with all the soft interface information
638 * @vlan: the object to remove 638 * @vlan: the object to remove
639 */ 639 */
640 static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, 640 static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv,
641 struct batadv_softif_vlan *vlan) 641 struct batadv_softif_vlan *vlan)
642 { 642 {
643 /* explicitly remove the associated TT local entry because it is marked 643 /* explicitly remove the associated TT local entry because it is marked
644 * with the NOPURGE flag 644 * with the NOPURGE flag
645 */ 645 */
646 batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr, 646 batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr,
647 vlan->vid, "vlan interface destroyed", false); 647 vlan->vid, "vlan interface destroyed", false);
648 648
649 batadv_sysfs_del_vlan(bat_priv, vlan); 649 batadv_sysfs_del_vlan(bat_priv, vlan);
650 batadv_softif_vlan_put(vlan); 650 batadv_softif_vlan_put(vlan);
651 } 651 }
652 652
653 /** 653 /**
654 * batadv_interface_add_vid() - ndo_add_vid API implementation 654 * batadv_interface_add_vid() - ndo_add_vid API implementation
655 * @dev: the netdev of the mesh interface 655 * @dev: the netdev of the mesh interface
656 * @proto: protocol of the the vlan id 656 * @proto: protocol of the the vlan id
657 * @vid: identifier of the new vlan 657 * @vid: identifier of the new vlan
658 * 658 *
659 * Set up all the internal structures for handling the new vlan on top of the 659 * Set up all the internal structures for handling the new vlan on top of the
660 * mesh interface 660 * mesh interface
661 * 661 *
662 * Return: 0 on success or a negative error code in case of failure. 662 * Return: 0 on success or a negative error code in case of failure.
663 */ 663 */
664 static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, 664 static int batadv_interface_add_vid(struct net_device *dev, __be16 proto,
665 unsigned short vid) 665 unsigned short vid)
666 { 666 {
667 struct batadv_priv *bat_priv = netdev_priv(dev); 667 struct batadv_priv *bat_priv = netdev_priv(dev);
668 struct batadv_softif_vlan *vlan; 668 struct batadv_softif_vlan *vlan;
669 int ret; 669 int ret;
670 670
671 /* only 802.1Q vlans are supported. 671 /* only 802.1Q vlans are supported.
672 * batman-adv does not know how to handle other types 672 * batman-adv does not know how to handle other types
673 */ 673 */
674 if (proto != htons(ETH_P_8021Q)) 674 if (proto != htons(ETH_P_8021Q))
675 return -EINVAL; 675 return -EINVAL;
676 676
677 vid |= BATADV_VLAN_HAS_TAG; 677 vid |= BATADV_VLAN_HAS_TAG;
678 678
679 /* if a new vlan is getting created and it already exists, it means that 679 /* if a new vlan is getting created and it already exists, it means that
680 * it was not deleted yet. batadv_softif_vlan_get() increases the 680 * it was not deleted yet. batadv_softif_vlan_get() increases the
681 * refcount in order to revive the object. 681 * refcount in order to revive the object.
682 * 682 *
683 * if it does not exist then create it. 683 * if it does not exist then create it.
684 */ 684 */
685 vlan = batadv_softif_vlan_get(bat_priv, vid); 685 vlan = batadv_softif_vlan_get(bat_priv, vid);
686 if (!vlan) 686 if (!vlan)
687 return batadv_softif_create_vlan(bat_priv, vid); 687 return batadv_softif_create_vlan(bat_priv, vid);
688 688
689 /* recreate the sysfs object if it was already destroyed (and it should 689 /* recreate the sysfs object if it was already destroyed (and it should
690 * be since we received a kill_vid() for this vlan 690 * be since we received a kill_vid() for this vlan
691 */ 691 */
692 if (!vlan->kobj) { 692 if (!vlan->kobj) {
693 ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); 693 ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
694 if (ret) { 694 if (ret) {
695 batadv_softif_vlan_put(vlan); 695 batadv_softif_vlan_put(vlan);
696 return ret; 696 return ret;
697 } 697 }
698 } 698 }
699 699
700 /* add a new TT local entry. This one will be marked with the NOPURGE 700 /* add a new TT local entry. This one will be marked with the NOPURGE
701 * flag. This must be added again, even if the vlan object already 701 * flag. This must be added again, even if the vlan object already
702 * exists, because the entry was deleted by kill_vid() 702 * exists, because the entry was deleted by kill_vid()
703 */ 703 */
704 batadv_tt_local_add(bat_priv->soft_iface, 704 batadv_tt_local_add(bat_priv->soft_iface,
705 bat_priv->soft_iface->dev_addr, vid, 705 bat_priv->soft_iface->dev_addr, vid,
706 BATADV_NULL_IFINDEX, BATADV_NO_MARK); 706 BATADV_NULL_IFINDEX, BATADV_NO_MARK);
707 707
708 return 0; 708 return 0;
709 } 709 }
710 710
711 /** 711 /**
712 * batadv_interface_kill_vid() - ndo_kill_vid API implementation 712 * batadv_interface_kill_vid() - ndo_kill_vid API implementation
713 * @dev: the netdev of the mesh interface 713 * @dev: the netdev of the mesh interface
714 * @proto: protocol of the the vlan id 714 * @proto: protocol of the the vlan id
715 * @vid: identifier of the deleted vlan 715 * @vid: identifier of the deleted vlan
716 * 716 *
717 * Destroy all the internal structures used to handle the vlan identified by vid 717 * Destroy all the internal structures used to handle the vlan identified by vid
718 * on top of the mesh interface 718 * on top of the mesh interface
719 * 719 *
720 * Return: 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q 720 * Return: 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q
721 * or -ENOENT if the specified vlan id wasn't registered. 721 * or -ENOENT if the specified vlan id wasn't registered.
722 */ 722 */
723 static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, 723 static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto,
724 unsigned short vid) 724 unsigned short vid)
725 { 725 {
726 struct batadv_priv *bat_priv = netdev_priv(dev); 726 struct batadv_priv *bat_priv = netdev_priv(dev);
727 struct batadv_softif_vlan *vlan; 727 struct batadv_softif_vlan *vlan;
728 728
729 /* only 802.1Q vlans are supported. batman-adv does not know how to 729 /* only 802.1Q vlans are supported. batman-adv does not know how to
730 * handle other types 730 * handle other types
731 */ 731 */
732 if (proto != htons(ETH_P_8021Q)) 732 if (proto != htons(ETH_P_8021Q))
733 return -EINVAL; 733 return -EINVAL;
734 734
735 vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); 735 vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG);
736 if (!vlan) 736 if (!vlan)
737 return -ENOENT; 737 return -ENOENT;
738 738
739 batadv_softif_destroy_vlan(bat_priv, vlan); 739 batadv_softif_destroy_vlan(bat_priv, vlan);
740 740
741 /* finally free the vlan object */ 741 /* finally free the vlan object */
742 batadv_softif_vlan_put(vlan); 742 batadv_softif_vlan_put(vlan);
743 743
744 return 0; 744 return 0;
745 } 745 }
746 746
747 /* batman-adv network devices have devices nesting below it and are a special 747 /* batman-adv network devices have devices nesting below it and are a special
748 * "super class" of normal network devices; split their locks off into a 748 * "super class" of normal network devices; split their locks off into a
749 * separate class since they always nest. 749 * separate class since they always nest.
750 */ 750 */
751 static struct lock_class_key batadv_netdev_xmit_lock_key; 751 static struct lock_class_key batadv_netdev_xmit_lock_key;
752 static struct lock_class_key batadv_netdev_addr_lock_key; 752 static struct lock_class_key batadv_netdev_addr_lock_key;
753 753
754 /** 754 /**
755 * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue 755 * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue
756 * @dev: device which owns the tx queue 756 * @dev: device which owns the tx queue
757 * @txq: tx queue to modify 757 * @txq: tx queue to modify
758 * @_unused: always NULL 758 * @_unused: always NULL
759 */ 759 */
760 static void batadv_set_lockdep_class_one(struct net_device *dev, 760 static void batadv_set_lockdep_class_one(struct net_device *dev,
761 struct netdev_queue *txq, 761 struct netdev_queue *txq,
762 void *_unused) 762 void *_unused)
763 { 763 {
764 lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); 764 lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key);
765 } 765 }
766 766
767 /** 767 /**
768 * batadv_set_lockdep_class() - Set txq and addr_list lockdep class 768 * batadv_set_lockdep_class() - Set txq and addr_list lockdep class
769 * @dev: network device to modify 769 * @dev: network device to modify
770 */ 770 */
771 static void batadv_set_lockdep_class(struct net_device *dev) 771 static void batadv_set_lockdep_class(struct net_device *dev)
772 { 772 {
773 lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); 773 lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key);
774 netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); 774 netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL);
775 } 775 }
776 776
777 /** 777 /**
778 * batadv_softif_init_late() - late stage initialization of soft interface 778 * batadv_softif_init_late() - late stage initialization of soft interface
779 * @dev: registered network device to modify 779 * @dev: registered network device to modify
780 * 780 *
781 * Return: error code on failures 781 * Return: error code on failures
782 */ 782 */
783 static int batadv_softif_init_late(struct net_device *dev) 783 static int batadv_softif_init_late(struct net_device *dev)
784 { 784 {
785 struct batadv_priv *bat_priv; 785 struct batadv_priv *bat_priv;
786 u32 random_seqno; 786 u32 random_seqno;
787 int ret; 787 int ret;
788 size_t cnt_len = sizeof(u64) * BATADV_CNT_NUM; 788 size_t cnt_len = sizeof(u64) * BATADV_CNT_NUM;
789 789
790 batadv_set_lockdep_class(dev); 790 batadv_set_lockdep_class(dev);
791 791
792 bat_priv = netdev_priv(dev); 792 bat_priv = netdev_priv(dev);
793 bat_priv->soft_iface = dev; 793 bat_priv->soft_iface = dev;
794 794
795 /* batadv_interface_stats() needs to be available as soon as 795 /* batadv_interface_stats() needs to be available as soon as
796 * register_netdevice() has been called 796 * register_netdevice() has been called
797 */ 797 */
798 bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(u64)); 798 bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(u64));
799 if (!bat_priv->bat_counters) 799 if (!bat_priv->bat_counters)
800 return -ENOMEM; 800 return -ENOMEM;
801 801
802 atomic_set(&bat_priv->aggregated_ogms, 1); 802 atomic_set(&bat_priv->aggregated_ogms, 1);
803 atomic_set(&bat_priv->bonding, 0); 803 atomic_set(&bat_priv->bonding, 0);
804 #ifdef CONFIG_BATMAN_ADV_BLA 804 #ifdef CONFIG_BATMAN_ADV_BLA
805 atomic_set(&bat_priv->bridge_loop_avoidance, 1); 805 atomic_set(&bat_priv->bridge_loop_avoidance, 1);
806 #endif 806 #endif
807 #ifdef CONFIG_BATMAN_ADV_DAT 807 #ifdef CONFIG_BATMAN_ADV_DAT
808 atomic_set(&bat_priv->distributed_arp_table, 1); 808 atomic_set(&bat_priv->distributed_arp_table, 1);
809 #endif 809 #endif
810 #ifdef CONFIG_BATMAN_ADV_MCAST 810 #ifdef CONFIG_BATMAN_ADV_MCAST
811 bat_priv->mcast.querier_ipv4.exists = false; 811 bat_priv->mcast.querier_ipv4.exists = false;
812 bat_priv->mcast.querier_ipv4.shadowing = false; 812 bat_priv->mcast.querier_ipv4.shadowing = false;
813 bat_priv->mcast.querier_ipv6.exists = false; 813 bat_priv->mcast.querier_ipv6.exists = false;
814 bat_priv->mcast.querier_ipv6.shadowing = false; 814 bat_priv->mcast.querier_ipv6.shadowing = false;
815 bat_priv->mcast.flags = BATADV_NO_FLAGS; 815 bat_priv->mcast.flags = BATADV_NO_FLAGS;
816 atomic_set(&bat_priv->multicast_mode, 1); 816 atomic_set(&bat_priv->multicast_mode, 1);
817 atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); 817 atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0);
818 atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); 818 atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0);
819 atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); 819 atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
820 #endif 820 #endif
821 atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); 821 atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF);
822 atomic_set(&bat_priv->gw.bandwidth_down, 100); 822 atomic_set(&bat_priv->gw.bandwidth_down, 100);
823 atomic_set(&bat_priv->gw.bandwidth_up, 20); 823 atomic_set(&bat_priv->gw.bandwidth_up, 20);
824 atomic_set(&bat_priv->orig_interval, 1000); 824 atomic_set(&bat_priv->orig_interval, 1000);
825 atomic_set(&bat_priv->hop_penalty, 30); 825 atomic_set(&bat_priv->hop_penalty, 30);
826 #ifdef CONFIG_BATMAN_ADV_DEBUG 826 #ifdef CONFIG_BATMAN_ADV_DEBUG
827 atomic_set(&bat_priv->log_level, 0); 827 atomic_set(&bat_priv->log_level, 0);
828 #endif 828 #endif
829 atomic_set(&bat_priv->fragmentation, 1); 829 atomic_set(&bat_priv->fragmentation, 1);
830 atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN); 830 atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN);
831 atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); 831 atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
832 atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); 832 atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
833 833
834 atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); 834 atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
835 atomic_set(&bat_priv->bcast_seqno, 1); 835 atomic_set(&bat_priv->bcast_seqno, 1);
836 atomic_set(&bat_priv->tt.vn, 0); 836 atomic_set(&bat_priv->tt.vn, 0);
837 atomic_set(&bat_priv->tt.local_changes, 0); 837 atomic_set(&bat_priv->tt.local_changes, 0);
838 atomic_set(&bat_priv->tt.ogm_append_cnt, 0); 838 atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
839 #ifdef CONFIG_BATMAN_ADV_BLA 839 #ifdef CONFIG_BATMAN_ADV_BLA
840 atomic_set(&bat_priv->bla.num_requests, 0); 840 atomic_set(&bat_priv->bla.num_requests, 0);
841 #endif 841 #endif
842 atomic_set(&bat_priv->tp_num, 0); 842 atomic_set(&bat_priv->tp_num, 0);
843 843
844 bat_priv->tt.last_changeset = NULL; 844 bat_priv->tt.last_changeset = NULL;
845 bat_priv->tt.last_changeset_len = 0; 845 bat_priv->tt.last_changeset_len = 0;
846 bat_priv->isolation_mark = 0; 846 bat_priv->isolation_mark = 0;
847 bat_priv->isolation_mark_mask = 0; 847 bat_priv->isolation_mark_mask = 0;
848 848
849 /* randomize initial seqno to avoid collision */ 849 /* randomize initial seqno to avoid collision */
850 get_random_bytes(&random_seqno, sizeof(random_seqno)); 850 get_random_bytes(&random_seqno, sizeof(random_seqno));
851 atomic_set(&bat_priv->frag_seqno, random_seqno); 851 atomic_set(&bat_priv->frag_seqno, random_seqno);
852 852
853 bat_priv->primary_if = NULL; 853 bat_priv->primary_if = NULL;
854 854
855 batadv_nc_init_bat_priv(bat_priv); 855 batadv_nc_init_bat_priv(bat_priv);
856 856
857 ret = batadv_algo_select(bat_priv, batadv_routing_algo); 857 ret = batadv_algo_select(bat_priv, batadv_routing_algo);
858 if (ret < 0) 858 if (ret < 0)
859 goto free_bat_counters; 859 goto free_bat_counters;
860 860
861 ret = batadv_debugfs_add_meshif(dev); 861 ret = batadv_debugfs_add_meshif(dev);
862 if (ret < 0) 862 if (ret < 0)
863 goto free_bat_counters; 863 goto free_bat_counters;
864 864
865 ret = batadv_mesh_init(dev); 865 ret = batadv_mesh_init(dev);
866 if (ret < 0) 866 if (ret < 0)
867 goto unreg_debugfs; 867 goto unreg_debugfs;
868 868
869 return 0; 869 return 0;
870 870
871 unreg_debugfs: 871 unreg_debugfs:
872 batadv_debugfs_del_meshif(dev); 872 batadv_debugfs_del_meshif(dev);
873 free_bat_counters: 873 free_bat_counters:
874 free_percpu(bat_priv->bat_counters); 874 free_percpu(bat_priv->bat_counters);
875 bat_priv->bat_counters = NULL; 875 bat_priv->bat_counters = NULL;
876 876
877 return ret; 877 return ret;
878 } 878 }
879 879
880 /** 880 /**
881 * batadv_softif_slave_add() - Add a slave interface to a batadv_soft_interface 881 * batadv_softif_slave_add() - Add a slave interface to a batadv_soft_interface
882 * @dev: batadv_soft_interface used as master interface 882 * @dev: batadv_soft_interface used as master interface
883 * @slave_dev: net_device which should become the slave interface 883 * @slave_dev: net_device which should become the slave interface
884 * @extack: extended ACK report struct 884 * @extack: extended ACK report struct
885 * 885 *
886 * Return: 0 if successful or error otherwise. 886 * Return: 0 if successful or error otherwise.
887 */ 887 */
888 static int batadv_softif_slave_add(struct net_device *dev, 888 static int batadv_softif_slave_add(struct net_device *dev,
889 struct net_device *slave_dev, 889 struct net_device *slave_dev,
890 struct netlink_ext_ack *extack) 890 struct netlink_ext_ack *extack)
891 { 891 {
892 struct batadv_hard_iface *hard_iface; 892 struct batadv_hard_iface *hard_iface;
893 struct net *net = dev_net(dev); 893 struct net *net = dev_net(dev);
894 int ret = -EINVAL; 894 int ret = -EINVAL;
895 895
896 hard_iface = batadv_hardif_get_by_netdev(slave_dev); 896 hard_iface = batadv_hardif_get_by_netdev(slave_dev);
897 if (!hard_iface || hard_iface->soft_iface) 897 if (!hard_iface || hard_iface->soft_iface)
898 goto out; 898 goto out;
899 899
900 ret = batadv_hardif_enable_interface(hard_iface, net, dev->name); 900 ret = batadv_hardif_enable_interface(hard_iface, net, dev->name);
901 901
902 out: 902 out:
903 if (hard_iface) 903 if (hard_iface)
904 batadv_hardif_put(hard_iface); 904 batadv_hardif_put(hard_iface);
905 return ret; 905 return ret;
906 } 906 }
907 907
908 /** 908 /**
909 * batadv_softif_slave_del() - Delete a slave iface from a batadv_soft_interface 909 * batadv_softif_slave_del() - Delete a slave iface from a batadv_soft_interface
910 * @dev: batadv_soft_interface used as master interface 910 * @dev: batadv_soft_interface used as master interface
911 * @slave_dev: net_device which should be removed from the master interface 911 * @slave_dev: net_device which should be removed from the master interface
912 * 912 *
913 * Return: 0 if successful or error otherwise. 913 * Return: 0 if successful or error otherwise.
914 */ 914 */
915 static int batadv_softif_slave_del(struct net_device *dev, 915 static int batadv_softif_slave_del(struct net_device *dev,
916 struct net_device *slave_dev) 916 struct net_device *slave_dev)
917 { 917 {
918 struct batadv_hard_iface *hard_iface; 918 struct batadv_hard_iface *hard_iface;
919 int ret = -EINVAL; 919 int ret = -EINVAL;
920 920
921 hard_iface = batadv_hardif_get_by_netdev(slave_dev); 921 hard_iface = batadv_hardif_get_by_netdev(slave_dev);
922 922
923 if (!hard_iface || hard_iface->soft_iface != dev) 923 if (!hard_iface || hard_iface->soft_iface != dev)
924 goto out; 924 goto out;
925 925
926 batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP); 926 batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP);
927 ret = 0; 927 ret = 0;
928 928
929 out: 929 out:
930 if (hard_iface) 930 if (hard_iface)
931 batadv_hardif_put(hard_iface); 931 batadv_hardif_put(hard_iface);
932 return ret; 932 return ret;
933 } 933 }
934 934
935 static const struct net_device_ops batadv_netdev_ops = { 935 static const struct net_device_ops batadv_netdev_ops = {
936 .ndo_init = batadv_softif_init_late, 936 .ndo_init = batadv_softif_init_late,
937 .ndo_open = batadv_interface_open, 937 .ndo_open = batadv_interface_open,
938 .ndo_stop = batadv_interface_release, 938 .ndo_stop = batadv_interface_release,
939 .ndo_get_stats = batadv_interface_stats, 939 .ndo_get_stats = batadv_interface_stats,
940 .ndo_vlan_rx_add_vid = batadv_interface_add_vid, 940 .ndo_vlan_rx_add_vid = batadv_interface_add_vid,
941 .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid, 941 .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid,
942 .ndo_set_mac_address = batadv_interface_set_mac_addr, 942 .ndo_set_mac_address = batadv_interface_set_mac_addr,
943 .ndo_change_mtu = batadv_interface_change_mtu, 943 .ndo_change_mtu = batadv_interface_change_mtu,
944 .ndo_set_rx_mode = batadv_interface_set_rx_mode, 944 .ndo_set_rx_mode = batadv_interface_set_rx_mode,
945 .ndo_start_xmit = batadv_interface_tx, 945 .ndo_start_xmit = batadv_interface_tx,
946 .ndo_validate_addr = eth_validate_addr, 946 .ndo_validate_addr = eth_validate_addr,
947 .ndo_add_slave = batadv_softif_slave_add, 947 .ndo_add_slave = batadv_softif_slave_add,
948 .ndo_del_slave = batadv_softif_slave_del, 948 .ndo_del_slave = batadv_softif_slave_del,
949 }; 949 };
950 950
951 static void batadv_get_drvinfo(struct net_device *dev, 951 static void batadv_get_drvinfo(struct net_device *dev,
952 struct ethtool_drvinfo *info) 952 struct ethtool_drvinfo *info)
953 { 953 {
954 strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); 954 strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver));
955 strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); 955 strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version));
956 strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); 956 strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
957 strlcpy(info->bus_info, "batman", sizeof(info->bus_info)); 957 strlcpy(info->bus_info, "batman", sizeof(info->bus_info));
958 } 958 }
959 959
960 /* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 960 /* Inspired by drivers/net/ethernet/dlink/sundance.c:1702
961 * Declare each description string in struct.name[] to get fixed sized buffer 961 * Declare each description string in struct.name[] to get fixed sized buffer
962 * and compile time checking for strings longer than ETH_GSTRING_LEN. 962 * and compile time checking for strings longer than ETH_GSTRING_LEN.
963 */ 963 */
964 static const struct { 964 static const struct {
965 const char name[ETH_GSTRING_LEN]; 965 const char name[ETH_GSTRING_LEN];
966 } batadv_counters_strings[] = { 966 } batadv_counters_strings[] = {
967 { "tx" }, 967 { "tx" },
968 { "tx_bytes" }, 968 { "tx_bytes" },
969 { "tx_dropped" }, 969 { "tx_dropped" },
970 { "rx" }, 970 { "rx" },
971 { "rx_bytes" }, 971 { "rx_bytes" },
972 { "forward" }, 972 { "forward" },
973 { "forward_bytes" }, 973 { "forward_bytes" },
974 { "mgmt_tx" }, 974 { "mgmt_tx" },
975 { "mgmt_tx_bytes" }, 975 { "mgmt_tx_bytes" },
976 { "mgmt_rx" }, 976 { "mgmt_rx" },
977 { "mgmt_rx_bytes" }, 977 { "mgmt_rx_bytes" },
978 { "frag_tx" }, 978 { "frag_tx" },
979 { "frag_tx_bytes" }, 979 { "frag_tx_bytes" },
980 { "frag_rx" }, 980 { "frag_rx" },
981 { "frag_rx_bytes" }, 981 { "frag_rx_bytes" },
982 { "frag_fwd" }, 982 { "frag_fwd" },
983 { "frag_fwd_bytes" }, 983 { "frag_fwd_bytes" },
984 { "tt_request_tx" }, 984 { "tt_request_tx" },
985 { "tt_request_rx" }, 985 { "tt_request_rx" },
986 { "tt_response_tx" }, 986 { "tt_response_tx" },
987 { "tt_response_rx" }, 987 { "tt_response_rx" },
988 { "tt_roam_adv_tx" }, 988 { "tt_roam_adv_tx" },
989 { "tt_roam_adv_rx" }, 989 { "tt_roam_adv_rx" },
990 #ifdef CONFIG_BATMAN_ADV_DAT 990 #ifdef CONFIG_BATMAN_ADV_DAT
991 { "dat_get_tx" }, 991 { "dat_get_tx" },
992 { "dat_get_rx" }, 992 { "dat_get_rx" },
993 { "dat_put_tx" }, 993 { "dat_put_tx" },
994 { "dat_put_rx" }, 994 { "dat_put_rx" },
995 { "dat_cached_reply_tx" }, 995 { "dat_cached_reply_tx" },
996 #endif 996 #endif
997 #ifdef CONFIG_BATMAN_ADV_NC 997 #ifdef CONFIG_BATMAN_ADV_NC
998 { "nc_code" }, 998 { "nc_code" },
999 { "nc_code_bytes" }, 999 { "nc_code_bytes" },
1000 { "nc_recode" }, 1000 { "nc_recode" },
1001 { "nc_recode_bytes" }, 1001 { "nc_recode_bytes" },
1002 { "nc_buffer" }, 1002 { "nc_buffer" },
1003 { "nc_decode" }, 1003 { "nc_decode" },
1004 { "nc_decode_bytes" }, 1004 { "nc_decode_bytes" },
1005 { "nc_decode_failed" }, 1005 { "nc_decode_failed" },
1006 { "nc_sniffed" }, 1006 { "nc_sniffed" },
1007 #endif 1007 #endif
1008 }; 1008 };
1009 1009
1010 static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data) 1010 static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1011 { 1011 {
1012 if (stringset == ETH_SS_STATS) 1012 if (stringset == ETH_SS_STATS)
1013 memcpy(data, batadv_counters_strings, 1013 memcpy(data, batadv_counters_strings,
1014 sizeof(batadv_counters_strings)); 1014 sizeof(batadv_counters_strings));
1015 } 1015 }
1016 1016
1017 static void batadv_get_ethtool_stats(struct net_device *dev, 1017 static void batadv_get_ethtool_stats(struct net_device *dev,
1018 struct ethtool_stats *stats, u64 *data) 1018 struct ethtool_stats *stats, u64 *data)
1019 { 1019 {
1020 struct batadv_priv *bat_priv = netdev_priv(dev); 1020 struct batadv_priv *bat_priv = netdev_priv(dev);
1021 int i; 1021 int i;
1022 1022
1023 for (i = 0; i < BATADV_CNT_NUM; i++) 1023 for (i = 0; i < BATADV_CNT_NUM; i++)
1024 data[i] = batadv_sum_counter(bat_priv, i); 1024 data[i] = batadv_sum_counter(bat_priv, i);
1025 } 1025 }
1026 1026
1027 static int batadv_get_sset_count(struct net_device *dev, int stringset) 1027 static int batadv_get_sset_count(struct net_device *dev, int stringset)
1028 { 1028 {
1029 if (stringset == ETH_SS_STATS) 1029 if (stringset == ETH_SS_STATS)
1030 return BATADV_CNT_NUM; 1030 return BATADV_CNT_NUM;
1031 1031
1032 return -EOPNOTSUPP; 1032 return -EOPNOTSUPP;
1033 } 1033 }
1034 1034
1035 static const struct ethtool_ops batadv_ethtool_ops = { 1035 static const struct ethtool_ops batadv_ethtool_ops = {
1036 .get_drvinfo = batadv_get_drvinfo, 1036 .get_drvinfo = batadv_get_drvinfo,
1037 .get_link = ethtool_op_get_link, 1037 .get_link = ethtool_op_get_link,
1038 .get_strings = batadv_get_strings, 1038 .get_strings = batadv_get_strings,
1039 .get_ethtool_stats = batadv_get_ethtool_stats, 1039 .get_ethtool_stats = batadv_get_ethtool_stats,
1040 .get_sset_count = batadv_get_sset_count, 1040 .get_sset_count = batadv_get_sset_count,
1041 }; 1041 };
1042 1042
1043 /** 1043 /**
1044 * batadv_softif_free() - Deconstructor of batadv_soft_interface 1044 * batadv_softif_free() - Deconstructor of batadv_soft_interface
1045 * @dev: Device to cleanup and remove 1045 * @dev: Device to cleanup and remove
1046 */ 1046 */
1047 static void batadv_softif_free(struct net_device *dev) 1047 static void batadv_softif_free(struct net_device *dev)
1048 { 1048 {
1049 batadv_debugfs_del_meshif(dev); 1049 batadv_debugfs_del_meshif(dev);
1050 batadv_mesh_free(dev); 1050 batadv_mesh_free(dev);
1051 1051
1052 /* some scheduled RCU callbacks need the bat_priv struct to accomplish 1052 /* some scheduled RCU callbacks need the bat_priv struct to accomplish
1053 * their tasks. Wait for them all to be finished before freeing the 1053 * their tasks. Wait for them all to be finished before freeing the
1054 * netdev and its private data (bat_priv) 1054 * netdev and its private data (bat_priv)
1055 */ 1055 */
1056 rcu_barrier(); 1056 rcu_barrier();
1057 } 1057 }
1058 1058
1059 /** 1059 /**
1060 * batadv_softif_init_early() - early stage initialization of soft interface 1060 * batadv_softif_init_early() - early stage initialization of soft interface
1061 * @dev: registered network device to modify 1061 * @dev: registered network device to modify
1062 */ 1062 */
1063 static void batadv_softif_init_early(struct net_device *dev) 1063 static void batadv_softif_init_early(struct net_device *dev)
1064 { 1064 {
1065 ether_setup(dev); 1065 ether_setup(dev);
1066 1066
1067 dev->netdev_ops = &batadv_netdev_ops; 1067 dev->netdev_ops = &batadv_netdev_ops;
1068 dev->needs_free_netdev = true; 1068 dev->needs_free_netdev = true;
1069 dev->priv_destructor = batadv_softif_free; 1069 dev->priv_destructor = batadv_softif_free;
1070 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; 1070 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL;
1071 dev->features |= NETIF_F_LLTX; 1071 dev->features |= NETIF_F_LLTX;
1072 dev->priv_flags |= IFF_NO_QUEUE; 1072 dev->priv_flags |= IFF_NO_QUEUE;
1073 1073
1074 /* can't call min_mtu, because the needed variables 1074 /* can't call min_mtu, because the needed variables
1075 * have not been initialized yet 1075 * have not been initialized yet
1076 */ 1076 */
1077 dev->mtu = ETH_DATA_LEN; 1077 dev->mtu = ETH_DATA_LEN;
1078 1078
1079 /* generate random address */ 1079 /* generate random address */
1080 eth_hw_addr_random(dev); 1080 eth_hw_addr_random(dev);
1081 1081
1082 dev->ethtool_ops = &batadv_ethtool_ops; 1082 dev->ethtool_ops = &batadv_ethtool_ops;
1083 } 1083 }
1084 1084
1085 /** 1085 /**
1086 * batadv_softif_create() - Create and register soft interface 1086 * batadv_softif_create() - Create and register soft interface
1087 * @net: the applicable net namespace 1087 * @net: the applicable net namespace
1088 * @name: name of the new soft interface 1088 * @name: name of the new soft interface
1089 * 1089 *
1090 * Return: newly allocated soft_interface, NULL on errors 1090 * Return: newly allocated soft_interface, NULL on errors
1091 */ 1091 */
1092 struct net_device *batadv_softif_create(struct net *net, const char *name) 1092 struct net_device *batadv_softif_create(struct net *net, const char *name)
1093 { 1093 {
1094 struct net_device *soft_iface; 1094 struct net_device *soft_iface;
1095 int ret; 1095 int ret;
1096 1096
1097 soft_iface = alloc_netdev(sizeof(struct batadv_priv), name, 1097 soft_iface = alloc_netdev(sizeof(struct batadv_priv), name,
1098 NET_NAME_UNKNOWN, batadv_softif_init_early); 1098 NET_NAME_UNKNOWN, batadv_softif_init_early);
1099 if (!soft_iface) 1099 if (!soft_iface)
1100 return NULL; 1100 return NULL;
1101 1101
1102 dev_net_set(soft_iface, net); 1102 dev_net_set(soft_iface, net);
1103 1103
1104 soft_iface->rtnl_link_ops = &batadv_link_ops; 1104 soft_iface->rtnl_link_ops = &batadv_link_ops;
1105 1105
1106 ret = register_netdevice(soft_iface); 1106 ret = register_netdevice(soft_iface);
1107 if (ret < 0) { 1107 if (ret < 0) {
1108 pr_err("Unable to register the batman interface '%s': %i\n", 1108 pr_err("Unable to register the batman interface '%s': %i\n",
1109 name, ret); 1109 name, ret);
1110 free_netdev(soft_iface); 1110 free_netdev(soft_iface);
1111 return NULL; 1111 return NULL;
1112 } 1112 }
1113 1113
1114 return soft_iface; 1114 return soft_iface;
1115 } 1115 }
1116 1116
1117 /** 1117 /**
1118 * batadv_softif_destroy_sysfs() - deletion of batadv_soft_interface via sysfs 1118 * batadv_softif_destroy_sysfs() - deletion of batadv_soft_interface via sysfs
1119 * @soft_iface: the to-be-removed batman-adv interface 1119 * @soft_iface: the to-be-removed batman-adv interface
1120 */ 1120 */
1121 void batadv_softif_destroy_sysfs(struct net_device *soft_iface) 1121 void batadv_softif_destroy_sysfs(struct net_device *soft_iface)
1122 { 1122 {
1123 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 1123 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
1124 struct batadv_softif_vlan *vlan; 1124 struct batadv_softif_vlan *vlan;
1125 1125
1126 ASSERT_RTNL(); 1126 ASSERT_RTNL();
1127 1127
1128 /* destroy the "untagged" VLAN */ 1128 /* destroy the "untagged" VLAN */
1129 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); 1129 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
1130 if (vlan) { 1130 if (vlan) {
1131 batadv_softif_destroy_vlan(bat_priv, vlan); 1131 batadv_softif_destroy_vlan(bat_priv, vlan);
1132 batadv_softif_vlan_put(vlan); 1132 batadv_softif_vlan_put(vlan);
1133 } 1133 }
1134 1134
1135 batadv_sysfs_del_meshif(soft_iface); 1135 batadv_sysfs_del_meshif(soft_iface);
1136 unregister_netdevice(soft_iface); 1136 unregister_netdevice(soft_iface);
1137 } 1137 }
1138 1138
1139 /** 1139 /**
1140 * batadv_softif_destroy_netlink() - deletion of batadv_soft_interface via 1140 * batadv_softif_destroy_netlink() - deletion of batadv_soft_interface via
1141 * netlink 1141 * netlink
1142 * @soft_iface: the to-be-removed batman-adv interface 1142 * @soft_iface: the to-be-removed batman-adv interface
1143 * @head: list pointer 1143 * @head: list pointer
1144 */ 1144 */
1145 static void batadv_softif_destroy_netlink(struct net_device *soft_iface, 1145 static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
1146 struct list_head *head) 1146 struct list_head *head)
1147 { 1147 {
1148 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 1148 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
1149 struct batadv_hard_iface *hard_iface; 1149 struct batadv_hard_iface *hard_iface;
1150 struct batadv_softif_vlan *vlan; 1150 struct batadv_softif_vlan *vlan;
1151 1151
1152 list_for_each_entry(hard_iface, &batadv_hardif_list, list) { 1152 list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
1153 if (hard_iface->soft_iface == soft_iface) 1153 if (hard_iface->soft_iface == soft_iface)
1154 batadv_hardif_disable_interface(hard_iface, 1154 batadv_hardif_disable_interface(hard_iface,
1155 BATADV_IF_CLEANUP_KEEP); 1155 BATADV_IF_CLEANUP_KEEP);
1156 } 1156 }
1157 1157
1158 /* destroy the "untagged" VLAN */ 1158 /* destroy the "untagged" VLAN */
1159 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); 1159 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
1160 if (vlan) { 1160 if (vlan) {
1161 batadv_softif_destroy_vlan(bat_priv, vlan); 1161 batadv_softif_destroy_vlan(bat_priv, vlan);
1162 batadv_softif_vlan_put(vlan); 1162 batadv_softif_vlan_put(vlan);
1163 } 1163 }
1164 1164
1165 batadv_sysfs_del_meshif(soft_iface); 1165 batadv_sysfs_del_meshif(soft_iface);
1166 unregister_netdevice_queue(soft_iface, head); 1166 unregister_netdevice_queue(soft_iface, head);
1167 } 1167 }
1168 1168
1169 /** 1169 /**
1170 * batadv_softif_is_valid() - Check whether device is a batadv soft interface 1170 * batadv_softif_is_valid() - Check whether device is a batadv soft interface
1171 * @net_dev: device which should be checked 1171 * @net_dev: device which should be checked
1172 * 1172 *
1173 * Return: true when net_dev is a batman-adv interface, false otherwise 1173 * Return: true when net_dev is a batman-adv interface, false otherwise
1174 */ 1174 */
1175 bool batadv_softif_is_valid(const struct net_device *net_dev) 1175 bool batadv_softif_is_valid(const struct net_device *net_dev)
1176 { 1176 {
1177 if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) 1177 if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx)
1178 return true; 1178 return true;
1179 1179
1180 return false; 1180 return false;
1181 } 1181 }
1182 1182
1183 struct rtnl_link_ops batadv_link_ops __read_mostly = { 1183 struct rtnl_link_ops batadv_link_ops __read_mostly = {
1184 .kind = "batadv", 1184 .kind = "batadv",
1185 .priv_size = sizeof(struct batadv_priv), 1185 .priv_size = sizeof(struct batadv_priv),
1186 .setup = batadv_softif_init_early, 1186 .setup = batadv_softif_init_early,
1187 .dellink = batadv_softif_destroy_netlink, 1187 .dellink = batadv_softif_destroy_netlink,
1188 }; 1188 };
net/batman-adv/sysfs.c
1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2010-2019 B.A.T.M.A.N. contributors: 2 /* Copyright (C) 2010-2019 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public 7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation. 8 * License as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details. 13 * General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include "sysfs.h" 19 #include "sysfs.h"
20 #include "main.h" 20 #include "main.h"
21 21
22 #include <linux/atomic.h> 22 #include <linux/atomic.h>
23 #include <linux/compiler.h> 23 #include <linux/compiler.h>
24 #include <linux/device.h> 24 #include <linux/device.h>
25 #include <linux/errno.h> 25 #include <linux/errno.h>
26 #include <linux/gfp.h> 26 #include <linux/gfp.h>
27 #include <linux/if.h> 27 #include <linux/if.h>
28 #include <linux/if_vlan.h> 28 #include <linux/if_vlan.h>
29 #include <linux/kernel.h> 29 #include <linux/kernel.h>
30 #include <linux/kobject.h> 30 #include <linux/kobject.h>
31 #include <linux/kref.h> 31 #include <linux/kref.h>
32 #include <linux/netdevice.h> 32 #include <linux/netdevice.h>
33 #include <linux/printk.h> 33 #include <linux/printk.h>
34 #include <linux/rculist.h> 34 #include <linux/rculist.h>
35 #include <linux/rcupdate.h> 35 #include <linux/rcupdate.h>
36 #include <linux/rtnetlink.h> 36 #include <linux/rtnetlink.h>
37 #include <linux/slab.h> 37 #include <linux/slab.h>
38 #include <linux/stddef.h> 38 #include <linux/stddef.h>
39 #include <linux/string.h> 39 #include <linux/string.h>
40 #include <linux/stringify.h> 40 #include <linux/stringify.h>
41 #include <linux/workqueue.h> 41 #include <linux/workqueue.h>
42 #include <uapi/linux/batadv_packet.h> 42 #include <uapi/linux/batadv_packet.h>
43 #include <uapi/linux/batman_adv.h>
43 44
44 #include "bridge_loop_avoidance.h" 45 #include "bridge_loop_avoidance.h"
45 #include "distributed-arp-table.h" 46 #include "distributed-arp-table.h"
46 #include "gateway_client.h" 47 #include "gateway_client.h"
47 #include "gateway_common.h" 48 #include "gateway_common.h"
48 #include "hard-interface.h" 49 #include "hard-interface.h"
49 #include "log.h" 50 #include "log.h"
50 #include "network-coding.h" 51 #include "network-coding.h"
51 #include "soft-interface.h" 52 #include "soft-interface.h"
52 53
53 static struct net_device *batadv_kobj_to_netdev(struct kobject *obj) 54 static struct net_device *batadv_kobj_to_netdev(struct kobject *obj)
54 { 55 {
55 struct device *dev = container_of(obj->parent, struct device, kobj); 56 struct device *dev = container_of(obj->parent, struct device, kobj);
56 57
57 return to_net_dev(dev); 58 return to_net_dev(dev);
58 } 59 }
59 60
60 static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj) 61 static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj)
61 { 62 {
62 struct net_device *net_dev = batadv_kobj_to_netdev(obj); 63 struct net_device *net_dev = batadv_kobj_to_netdev(obj);
63 64
64 return netdev_priv(net_dev); 65 return netdev_priv(net_dev);
65 } 66 }
66 67
67 /** 68 /**
68 * batadv_vlan_kobj_to_batpriv() - convert a vlan kobj in the associated batpriv 69 * batadv_vlan_kobj_to_batpriv() - convert a vlan kobj in the associated batpriv
69 * @obj: kobject to covert 70 * @obj: kobject to covert
70 * 71 *
71 * Return: the associated batadv_priv struct. 72 * Return: the associated batadv_priv struct.
72 */ 73 */
73 static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj) 74 static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj)
74 { 75 {
75 /* VLAN specific attributes are located in the root sysfs folder if they 76 /* VLAN specific attributes are located in the root sysfs folder if they
76 * refer to the untagged VLAN.. 77 * refer to the untagged VLAN..
77 */ 78 */
78 if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name)) 79 if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name))
79 return batadv_kobj_to_batpriv(obj); 80 return batadv_kobj_to_batpriv(obj);
80 81
81 /* ..while the attributes for the tagged vlans are located in 82 /* ..while the attributes for the tagged vlans are located in
82 * the in the corresponding "vlan%VID" subfolder 83 * the in the corresponding "vlan%VID" subfolder
83 */ 84 */
84 return batadv_kobj_to_batpriv(obj->parent); 85 return batadv_kobj_to_batpriv(obj->parent);
85 } 86 }
86 87
87 /** 88 /**
88 * batadv_kobj_to_vlan() - convert a kobj in the associated softif_vlan struct 89 * batadv_kobj_to_vlan() - convert a kobj in the associated softif_vlan struct
89 * @bat_priv: the bat priv with all the soft interface information 90 * @bat_priv: the bat priv with all the soft interface information
90 * @obj: kobject to covert 91 * @obj: kobject to covert
91 * 92 *
92 * Return: the associated softif_vlan struct if found, NULL otherwise. 93 * Return: the associated softif_vlan struct if found, NULL otherwise.
93 */ 94 */
94 static struct batadv_softif_vlan * 95 static struct batadv_softif_vlan *
95 batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj) 96 batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj)
96 { 97 {
97 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL; 98 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
98 99
99 rcu_read_lock(); 100 rcu_read_lock();
100 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) { 101 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
101 if (vlan_tmp->kobj != obj) 102 if (vlan_tmp->kobj != obj)
102 continue; 103 continue;
103 104
104 if (!kref_get_unless_zero(&vlan_tmp->refcount)) 105 if (!kref_get_unless_zero(&vlan_tmp->refcount))
105 continue; 106 continue;
106 107
107 vlan = vlan_tmp; 108 vlan = vlan_tmp;
108 break; 109 break;
109 } 110 }
110 rcu_read_unlock(); 111 rcu_read_unlock();
111 112
112 return vlan; 113 return vlan;
113 } 114 }
114 115
115 #define BATADV_UEV_TYPE_VAR "BATTYPE=" 116 #define BATADV_UEV_TYPE_VAR "BATTYPE="
116 #define BATADV_UEV_ACTION_VAR "BATACTION=" 117 #define BATADV_UEV_ACTION_VAR "BATACTION="
117 #define BATADV_UEV_DATA_VAR "BATDATA=" 118 #define BATADV_UEV_DATA_VAR "BATDATA="
118 119
119 static char *batadv_uev_action_str[] = { 120 static char *batadv_uev_action_str[] = {
120 "add", 121 "add",
121 "del", 122 "del",
122 "change", 123 "change",
123 "loopdetect", 124 "loopdetect",
124 }; 125 };
125 126
126 static char *batadv_uev_type_str[] = { 127 static char *batadv_uev_type_str[] = {
127 "gw", 128 "gw",
128 "bla", 129 "bla",
129 }; 130 };
130 131
131 /* Use this, if you have customized show and store functions for vlan attrs */ 132 /* Use this, if you have customized show and store functions for vlan attrs */
132 #define BATADV_ATTR_VLAN(_name, _mode, _show, _store) \ 133 #define BATADV_ATTR_VLAN(_name, _mode, _show, _store) \
133 struct batadv_attribute batadv_attr_vlan_##_name = { \ 134 struct batadv_attribute batadv_attr_vlan_##_name = { \
134 .attr = {.name = __stringify(_name), \ 135 .attr = {.name = __stringify(_name), \
135 .mode = _mode }, \ 136 .mode = _mode }, \
136 .show = _show, \ 137 .show = _show, \
137 .store = _store, \ 138 .store = _store, \
138 } 139 }
139 140
140 /* Use this, if you have customized show and store functions */ 141 /* Use this, if you have customized show and store functions */
141 #define BATADV_ATTR(_name, _mode, _show, _store) \ 142 #define BATADV_ATTR(_name, _mode, _show, _store) \
142 struct batadv_attribute batadv_attr_##_name = { \ 143 struct batadv_attribute batadv_attr_##_name = { \
143 .attr = {.name = __stringify(_name), \ 144 .attr = {.name = __stringify(_name), \
144 .mode = _mode }, \ 145 .mode = _mode }, \
145 .show = _show, \ 146 .show = _show, \
146 .store = _store, \ 147 .store = _store, \
147 } 148 }
148 149
149 #define BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \ 150 #define BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \
150 ssize_t batadv_store_##_name(struct kobject *kobj, \ 151 ssize_t batadv_store_##_name(struct kobject *kobj, \
151 struct attribute *attr, char *buff, \ 152 struct attribute *attr, char *buff, \
152 size_t count) \ 153 size_t count) \
153 { \ 154 { \
154 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ 155 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
155 struct batadv_priv *bat_priv = netdev_priv(net_dev); \ 156 struct batadv_priv *bat_priv = netdev_priv(net_dev); \
156 \ 157 \
157 return __batadv_store_bool_attr(buff, count, _post_func, attr, \ 158 return __batadv_store_bool_attr(buff, count, _post_func, attr, \
158 &bat_priv->_name, net_dev); \ 159 &bat_priv->_name, net_dev); \
159 } 160 }
160 161
161 #define BATADV_ATTR_SIF_SHOW_BOOL(_name) \ 162 #define BATADV_ATTR_SIF_SHOW_BOOL(_name) \
162 ssize_t batadv_show_##_name(struct kobject *kobj, \ 163 ssize_t batadv_show_##_name(struct kobject *kobj, \
163 struct attribute *attr, char *buff) \ 164 struct attribute *attr, char *buff) \
164 { \ 165 { \
165 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \ 166 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \
166 \ 167 \
167 return sprintf(buff, "%s\n", \ 168 return sprintf(buff, "%s\n", \
168 atomic_read(&bat_priv->_name) == 0 ? \ 169 atomic_read(&bat_priv->_name) == 0 ? \
169 "disabled" : "enabled"); \ 170 "disabled" : "enabled"); \
170 } \ 171 } \
171 172
172 /* Use this, if you are going to turn a [name] in the soft-interface 173 /* Use this, if you are going to turn a [name] in the soft-interface
173 * (bat_priv) on or off 174 * (bat_priv) on or off
174 */ 175 */
175 #define BATADV_ATTR_SIF_BOOL(_name, _mode, _post_func) \ 176 #define BATADV_ATTR_SIF_BOOL(_name, _mode, _post_func) \
176 static BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \ 177 static BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \
177 static BATADV_ATTR_SIF_SHOW_BOOL(_name) \ 178 static BATADV_ATTR_SIF_SHOW_BOOL(_name) \
178 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ 179 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
179 batadv_store_##_name) 180 batadv_store_##_name)
180 181
181 #define BATADV_ATTR_SIF_STORE_UINT(_name, _var, _min, _max, _post_func) \ 182 #define BATADV_ATTR_SIF_STORE_UINT(_name, _var, _min, _max, _post_func) \
182 ssize_t batadv_store_##_name(struct kobject *kobj, \ 183 ssize_t batadv_store_##_name(struct kobject *kobj, \
183 struct attribute *attr, char *buff, \ 184 struct attribute *attr, char *buff, \
184 size_t count) \ 185 size_t count) \
185 { \ 186 { \
186 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ 187 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
187 struct batadv_priv *bat_priv = netdev_priv(net_dev); \ 188 struct batadv_priv *bat_priv = netdev_priv(net_dev); \
188 \ 189 \
189 return __batadv_store_uint_attr(buff, count, _min, _max, \ 190 return __batadv_store_uint_attr(buff, count, _min, _max, \
190 _post_func, attr, \ 191 _post_func, attr, \
191 &bat_priv->_var, net_dev, \ 192 &bat_priv->_var, net_dev, \
192 NULL); \ 193 NULL); \
193 } 194 }
194 195
195 #define BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \ 196 #define BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \
196 ssize_t batadv_show_##_name(struct kobject *kobj, \ 197 ssize_t batadv_show_##_name(struct kobject *kobj, \
197 struct attribute *attr, char *buff) \ 198 struct attribute *attr, char *buff) \
198 { \ 199 { \
199 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \ 200 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \
200 \ 201 \
201 return sprintf(buff, "%i\n", atomic_read(&bat_priv->_var)); \ 202 return sprintf(buff, "%i\n", atomic_read(&bat_priv->_var)); \
202 } \ 203 } \
203 204
204 /* Use this, if you are going to set [name] in the soft-interface 205 /* Use this, if you are going to set [name] in the soft-interface
205 * (bat_priv) to an unsigned integer value 206 * (bat_priv) to an unsigned integer value
206 */ 207 */
207 #define BATADV_ATTR_SIF_UINT(_name, _var, _mode, _min, _max, _post_func)\ 208 #define BATADV_ATTR_SIF_UINT(_name, _var, _mode, _min, _max, _post_func)\
208 static BATADV_ATTR_SIF_STORE_UINT(_name, _var, _min, _max, _post_func)\ 209 static BATADV_ATTR_SIF_STORE_UINT(_name, _var, _min, _max, _post_func)\
209 static BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \ 210 static BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \
210 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ 211 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
211 batadv_store_##_name) 212 batadv_store_##_name)
212 213
213 #define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \ 214 #define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
214 ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \ 215 ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \
215 struct attribute *attr, char *buff, \ 216 struct attribute *attr, char *buff, \
216 size_t count) \ 217 size_t count) \
217 { \ 218 { \
218 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\ 219 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
219 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \ 220 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
220 kobj); \ 221 kobj); \
221 size_t res = __batadv_store_bool_attr(buff, count, _post_func, \ 222 size_t res = __batadv_store_bool_attr(buff, count, _post_func, \
222 attr, &vlan->_name, \ 223 attr, &vlan->_name, \
223 bat_priv->soft_iface); \ 224 bat_priv->soft_iface); \
224 \ 225 \
225 batadv_softif_vlan_put(vlan); \ 226 batadv_softif_vlan_put(vlan); \
226 return res; \ 227 return res; \
227 } 228 }
228 229
229 #define BATADV_ATTR_VLAN_SHOW_BOOL(_name) \ 230 #define BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
230 ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \ 231 ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
231 struct attribute *attr, char *buff) \ 232 struct attribute *attr, char *buff) \
232 { \ 233 { \
233 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\ 234 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
234 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \ 235 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
235 kobj); \ 236 kobj); \
236 size_t res = sprintf(buff, "%s\n", \ 237 size_t res = sprintf(buff, "%s\n", \
237 atomic_read(&vlan->_name) == 0 ? \ 238 atomic_read(&vlan->_name) == 0 ? \
238 "disabled" : "enabled"); \ 239 "disabled" : "enabled"); \
239 \ 240 \
240 batadv_softif_vlan_put(vlan); \ 241 batadv_softif_vlan_put(vlan); \
241 return res; \ 242 return res; \
242 } 243 }
243 244
244 /* Use this, if you are going to turn a [name] in the vlan struct on or off */ 245 /* Use this, if you are going to turn a [name] in the vlan struct on or off */
245 #define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func) \ 246 #define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func) \
246 static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \ 247 static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
247 static BATADV_ATTR_VLAN_SHOW_BOOL(_name) \ 248 static BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
248 static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \ 249 static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \
249 batadv_store_vlan_##_name) 250 batadv_store_vlan_##_name)
250 251
251 #define BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, _max, _post_func) \ 252 #define BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, _max, _post_func) \
252 ssize_t batadv_store_##_name(struct kobject *kobj, \ 253 ssize_t batadv_store_##_name(struct kobject *kobj, \
253 struct attribute *attr, char *buff, \ 254 struct attribute *attr, char *buff, \
254 size_t count) \ 255 size_t count) \
255 { \ 256 { \
256 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ 257 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
257 struct batadv_hard_iface *hard_iface; \ 258 struct batadv_hard_iface *hard_iface; \
258 ssize_t length; \ 259 ssize_t length; \
259 \ 260 \
260 hard_iface = batadv_hardif_get_by_netdev(net_dev); \ 261 hard_iface = batadv_hardif_get_by_netdev(net_dev); \
261 if (!hard_iface) \ 262 if (!hard_iface) \
262 return 0; \ 263 return 0; \
263 \ 264 \
264 length = __batadv_store_uint_attr(buff, count, _min, _max, \ 265 length = __batadv_store_uint_attr(buff, count, _min, _max, \
265 _post_func, attr, \ 266 _post_func, attr, \
266 &hard_iface->_var, \ 267 &hard_iface->_var, \
267 hard_iface->soft_iface, \ 268 hard_iface->soft_iface, \
268 net_dev); \ 269 net_dev); \
269 \ 270 \
270 batadv_hardif_put(hard_iface); \ 271 batadv_hardif_put(hard_iface); \
271 return length; \ 272 return length; \
272 } 273 }
273 274
274 #define BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \ 275 #define BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \
275 ssize_t batadv_show_##_name(struct kobject *kobj, \ 276 ssize_t batadv_show_##_name(struct kobject *kobj, \
276 struct attribute *attr, char *buff) \ 277 struct attribute *attr, char *buff) \
277 { \ 278 { \
278 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ 279 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
279 struct batadv_hard_iface *hard_iface; \ 280 struct batadv_hard_iface *hard_iface; \
280 ssize_t length; \ 281 ssize_t length; \
281 \ 282 \
282 hard_iface = batadv_hardif_get_by_netdev(net_dev); \ 283 hard_iface = batadv_hardif_get_by_netdev(net_dev); \
283 if (!hard_iface) \ 284 if (!hard_iface) \
284 return 0; \ 285 return 0; \
285 \ 286 \
286 length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_var)); \ 287 length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_var)); \
287 \ 288 \
288 batadv_hardif_put(hard_iface); \ 289 batadv_hardif_put(hard_iface); \
289 return length; \ 290 return length; \
290 } 291 }
291 292
292 /* Use this, if you are going to set [name] in hard_iface to an 293 /* Use this, if you are going to set [name] in hard_iface to an
293 * unsigned integer value 294 * unsigned integer value
294 */ 295 */
295 #define BATADV_ATTR_HIF_UINT(_name, _var, _mode, _min, _max, _post_func)\ 296 #define BATADV_ATTR_HIF_UINT(_name, _var, _mode, _min, _max, _post_func)\
296 static BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, \ 297 static BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, \
297 _max, _post_func) \ 298 _max, _post_func) \
298 static BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \ 299 static BATADV_ATTR_HIF_SHOW_UINT(_name, _var) \
299 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ 300 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
300 batadv_store_##_name) 301 batadv_store_##_name)
301 302
302 static int batadv_store_bool_attr(char *buff, size_t count, 303 static int batadv_store_bool_attr(char *buff, size_t count,
303 struct net_device *net_dev, 304 struct net_device *net_dev,
304 const char *attr_name, atomic_t *attr, 305 const char *attr_name, atomic_t *attr,
305 bool *changed) 306 bool *changed)
306 { 307 {
307 int enabled = -1; 308 int enabled = -1;
308 309
309 *changed = false; 310 *changed = false;
310 311
311 if (buff[count - 1] == '\n') 312 if (buff[count - 1] == '\n')
312 buff[count - 1] = '\0'; 313 buff[count - 1] = '\0';
313 314
314 if ((strncmp(buff, "1", 2) == 0) || 315 if ((strncmp(buff, "1", 2) == 0) ||
315 (strncmp(buff, "enable", 7) == 0) || 316 (strncmp(buff, "enable", 7) == 0) ||
316 (strncmp(buff, "enabled", 8) == 0)) 317 (strncmp(buff, "enabled", 8) == 0))
317 enabled = 1; 318 enabled = 1;
318 319
319 if ((strncmp(buff, "0", 2) == 0) || 320 if ((strncmp(buff, "0", 2) == 0) ||
320 (strncmp(buff, "disable", 8) == 0) || 321 (strncmp(buff, "disable", 8) == 0) ||
321 (strncmp(buff, "disabled", 9) == 0)) 322 (strncmp(buff, "disabled", 9) == 0))
322 enabled = 0; 323 enabled = 0;
323 324
324 if (enabled < 0) { 325 if (enabled < 0) {
325 batadv_info(net_dev, "%s: Invalid parameter received: %s\n", 326 batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
326 attr_name, buff); 327 attr_name, buff);
327 return -EINVAL; 328 return -EINVAL;
328 } 329 }
329 330
330 if (atomic_read(attr) == enabled) 331 if (atomic_read(attr) == enabled)
331 return count; 332 return count;
332 333
333 batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, 334 batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name,
334 atomic_read(attr) == 1 ? "enabled" : "disabled", 335 atomic_read(attr) == 1 ? "enabled" : "disabled",
335 enabled == 1 ? "enabled" : "disabled"); 336 enabled == 1 ? "enabled" : "disabled");
336 337
337 *changed = true; 338 *changed = true;
338 339
339 atomic_set(attr, (unsigned int)enabled); 340 atomic_set(attr, (unsigned int)enabled);
340 return count; 341 return count;
341 } 342 }
342 343
343 static inline ssize_t 344 static inline ssize_t
344 __batadv_store_bool_attr(char *buff, size_t count, 345 __batadv_store_bool_attr(char *buff, size_t count,
345 void (*post_func)(struct net_device *), 346 void (*post_func)(struct net_device *),
346 struct attribute *attr, 347 struct attribute *attr,
347 atomic_t *attr_store, struct net_device *net_dev) 348 atomic_t *attr_store, struct net_device *net_dev)
348 { 349 {
349 bool changed; 350 bool changed;
350 int ret; 351 int ret;
351 352
352 ret = batadv_store_bool_attr(buff, count, net_dev, attr->name, 353 ret = batadv_store_bool_attr(buff, count, net_dev, attr->name,
353 attr_store, &changed); 354 attr_store, &changed);
354 if (post_func && changed) 355 if (post_func && changed)
355 post_func(net_dev); 356 post_func(net_dev);
356 357
357 return ret; 358 return ret;
358 } 359 }
359 360
360 static int batadv_store_uint_attr(const char *buff, size_t count, 361 static int batadv_store_uint_attr(const char *buff, size_t count,
361 struct net_device *net_dev, 362 struct net_device *net_dev,
362 struct net_device *slave_dev, 363 struct net_device *slave_dev,
363 const char *attr_name, 364 const char *attr_name,
364 unsigned int min, unsigned int max, 365 unsigned int min, unsigned int max,
365 atomic_t *attr) 366 atomic_t *attr)
366 { 367 {
367 char ifname[IFNAMSIZ + 3] = ""; 368 char ifname[IFNAMSIZ + 3] = "";
368 unsigned long uint_val; 369 unsigned long uint_val;
369 int ret; 370 int ret;
370 371
371 ret = kstrtoul(buff, 10, &uint_val); 372 ret = kstrtoul(buff, 10, &uint_val);
372 if (ret) { 373 if (ret) {
373 batadv_info(net_dev, "%s: Invalid parameter received: %s\n", 374 batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
374 attr_name, buff); 375 attr_name, buff);
375 return -EINVAL; 376 return -EINVAL;
376 } 377 }
377 378
378 if (uint_val < min) { 379 if (uint_val < min) {
379 batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n", 380 batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n",
380 attr_name, uint_val, min); 381 attr_name, uint_val, min);
381 return -EINVAL; 382 return -EINVAL;
382 } 383 }
383 384
384 if (uint_val > max) { 385 if (uint_val > max) {
385 batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n", 386 batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n",
386 attr_name, uint_val, max); 387 attr_name, uint_val, max);
387 return -EINVAL; 388 return -EINVAL;
388 } 389 }
389 390
390 if (atomic_read(attr) == uint_val) 391 if (atomic_read(attr) == uint_val)
391 return count; 392 return count;
392 393
393 if (slave_dev) 394 if (slave_dev)
394 snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name); 395 snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name);
395 396
396 batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n", 397 batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n",
397 attr_name, ifname, atomic_read(attr), uint_val); 398 attr_name, ifname, atomic_read(attr), uint_val);
398 399
399 atomic_set(attr, uint_val); 400 atomic_set(attr, uint_val);
400 return count; 401 return count;
401 } 402 }
402 403
403 static ssize_t __batadv_store_uint_attr(const char *buff, size_t count, 404 static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
404 int min, int max, 405 int min, int max,
405 void (*post_func)(struct net_device *), 406 void (*post_func)(struct net_device *),
406 const struct attribute *attr, 407 const struct attribute *attr,
407 atomic_t *attr_store, 408 atomic_t *attr_store,
408 struct net_device *net_dev, 409 struct net_device *net_dev,
409 struct net_device *slave_dev) 410 struct net_device *slave_dev)
410 { 411 {
411 int ret; 412 int ret;
412 413
413 ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev, 414 ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev,
414 attr->name, min, max, attr_store); 415 attr->name, min, max, attr_store);
415 if (post_func && ret) 416 if (post_func && ret)
416 post_func(net_dev); 417 post_func(net_dev);
417 418
418 return ret; 419 return ret;
419 } 420 }
420 421
421 static ssize_t batadv_show_bat_algo(struct kobject *kobj, 422 static ssize_t batadv_show_bat_algo(struct kobject *kobj,
422 struct attribute *attr, char *buff) 423 struct attribute *attr, char *buff)
423 { 424 {
424 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 425 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
425 426
426 return sprintf(buff, "%s\n", bat_priv->algo_ops->name); 427 return sprintf(buff, "%s\n", bat_priv->algo_ops->name);
427 } 428 }
428 429
429 static void batadv_post_gw_reselect(struct net_device *net_dev) 430 static void batadv_post_gw_reselect(struct net_device *net_dev)
430 { 431 {
431 struct batadv_priv *bat_priv = netdev_priv(net_dev); 432 struct batadv_priv *bat_priv = netdev_priv(net_dev);
432 433
433 batadv_gw_reselect(bat_priv); 434 batadv_gw_reselect(bat_priv);
434 } 435 }
435 436
436 static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr, 437 static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr,
437 char *buff) 438 char *buff)
438 { 439 {
439 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 440 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
440 int bytes_written; 441 int bytes_written;
441 442
442 /* GW mode is not available if the routing algorithm in use does not 443 /* GW mode is not available if the routing algorithm in use does not
443 * implement the GW API 444 * implement the GW API
444 */ 445 */
445 if (!bat_priv->algo_ops->gw.get_best_gw_node || 446 if (!bat_priv->algo_ops->gw.get_best_gw_node ||
446 !bat_priv->algo_ops->gw.is_eligible) 447 !bat_priv->algo_ops->gw.is_eligible)
447 return -ENOENT; 448 return -ENOENT;
448 449
449 switch (atomic_read(&bat_priv->gw.mode)) { 450 switch (atomic_read(&bat_priv->gw.mode)) {
450 case BATADV_GW_MODE_CLIENT: 451 case BATADV_GW_MODE_CLIENT:
451 bytes_written = sprintf(buff, "%s\n", 452 bytes_written = sprintf(buff, "%s\n",
452 BATADV_GW_MODE_CLIENT_NAME); 453 BATADV_GW_MODE_CLIENT_NAME);
453 break; 454 break;
454 case BATADV_GW_MODE_SERVER: 455 case BATADV_GW_MODE_SERVER:
455 bytes_written = sprintf(buff, "%s\n", 456 bytes_written = sprintf(buff, "%s\n",
456 BATADV_GW_MODE_SERVER_NAME); 457 BATADV_GW_MODE_SERVER_NAME);
457 break; 458 break;
458 default: 459 default:
459 bytes_written = sprintf(buff, "%s\n", 460 bytes_written = sprintf(buff, "%s\n",
460 BATADV_GW_MODE_OFF_NAME); 461 BATADV_GW_MODE_OFF_NAME);
461 break; 462 break;
462 } 463 }
463 464
464 return bytes_written; 465 return bytes_written;
465 } 466 }
466 467
467 static ssize_t batadv_store_gw_mode(struct kobject *kobj, 468 static ssize_t batadv_store_gw_mode(struct kobject *kobj,
468 struct attribute *attr, char *buff, 469 struct attribute *attr, char *buff,
469 size_t count) 470 size_t count)
470 { 471 {
471 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 472 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
472 struct batadv_priv *bat_priv = netdev_priv(net_dev); 473 struct batadv_priv *bat_priv = netdev_priv(net_dev);
473 char *curr_gw_mode_str; 474 char *curr_gw_mode_str;
474 int gw_mode_tmp = -1; 475 int gw_mode_tmp = -1;
475 476
476 /* toggling GW mode is allowed only if the routing algorithm in use 477 /* toggling GW mode is allowed only if the routing algorithm in use
477 * provides the GW API 478 * provides the GW API
478 */ 479 */
479 if (!bat_priv->algo_ops->gw.get_best_gw_node || 480 if (!bat_priv->algo_ops->gw.get_best_gw_node ||
480 !bat_priv->algo_ops->gw.is_eligible) 481 !bat_priv->algo_ops->gw.is_eligible)
481 return -EINVAL; 482 return -EINVAL;
482 483
483 if (buff[count - 1] == '\n') 484 if (buff[count - 1] == '\n')
484 buff[count - 1] = '\0'; 485 buff[count - 1] = '\0';
485 486
486 if (strncmp(buff, BATADV_GW_MODE_OFF_NAME, 487 if (strncmp(buff, BATADV_GW_MODE_OFF_NAME,
487 strlen(BATADV_GW_MODE_OFF_NAME)) == 0) 488 strlen(BATADV_GW_MODE_OFF_NAME)) == 0)
488 gw_mode_tmp = BATADV_GW_MODE_OFF; 489 gw_mode_tmp = BATADV_GW_MODE_OFF;
489 490
490 if (strncmp(buff, BATADV_GW_MODE_CLIENT_NAME, 491 if (strncmp(buff, BATADV_GW_MODE_CLIENT_NAME,
491 strlen(BATADV_GW_MODE_CLIENT_NAME)) == 0) 492 strlen(BATADV_GW_MODE_CLIENT_NAME)) == 0)
492 gw_mode_tmp = BATADV_GW_MODE_CLIENT; 493 gw_mode_tmp = BATADV_GW_MODE_CLIENT;
493 494
494 if (strncmp(buff, BATADV_GW_MODE_SERVER_NAME, 495 if (strncmp(buff, BATADV_GW_MODE_SERVER_NAME,
495 strlen(BATADV_GW_MODE_SERVER_NAME)) == 0) 496 strlen(BATADV_GW_MODE_SERVER_NAME)) == 0)
496 gw_mode_tmp = BATADV_GW_MODE_SERVER; 497 gw_mode_tmp = BATADV_GW_MODE_SERVER;
497 498
498 if (gw_mode_tmp < 0) { 499 if (gw_mode_tmp < 0) {
499 batadv_info(net_dev, 500 batadv_info(net_dev,
500 "Invalid parameter for 'gw mode' setting received: %s\n", 501 "Invalid parameter for 'gw mode' setting received: %s\n",
501 buff); 502 buff);
502 return -EINVAL; 503 return -EINVAL;
503 } 504 }
504 505
505 if (atomic_read(&bat_priv->gw.mode) == gw_mode_tmp) 506 if (atomic_read(&bat_priv->gw.mode) == gw_mode_tmp)
506 return count; 507 return count;
507 508
508 switch (atomic_read(&bat_priv->gw.mode)) { 509 switch (atomic_read(&bat_priv->gw.mode)) {
509 case BATADV_GW_MODE_CLIENT: 510 case BATADV_GW_MODE_CLIENT:
510 curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME; 511 curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME;
511 break; 512 break;
512 case BATADV_GW_MODE_SERVER: 513 case BATADV_GW_MODE_SERVER:
513 curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME; 514 curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME;
514 break; 515 break;
515 default: 516 default:
516 curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME; 517 curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME;
517 break; 518 break;
518 } 519 }
519 520
520 batadv_info(net_dev, "Changing gw mode from: %s to: %s\n", 521 batadv_info(net_dev, "Changing gw mode from: %s to: %s\n",
521 curr_gw_mode_str, buff); 522 curr_gw_mode_str, buff);
522 523
523 /* Invoking batadv_gw_reselect() is not enough to really de-select the 524 /* Invoking batadv_gw_reselect() is not enough to really de-select the
524 * current GW. It will only instruct the gateway client code to perform 525 * current GW. It will only instruct the gateway client code to perform
525 * a re-election the next time that this is needed. 526 * a re-election the next time that this is needed.
526 * 527 *
527 * When gw client mode is being switched off the current GW must be 528 * When gw client mode is being switched off the current GW must be
528 * de-selected explicitly otherwise no GW_ADD uevent is thrown on 529 * de-selected explicitly otherwise no GW_ADD uevent is thrown on
529 * client mode re-activation. This is operation is performed in 530 * client mode re-activation. This is operation is performed in
530 * batadv_gw_check_client_stop(). 531 * batadv_gw_check_client_stop().
531 */ 532 */
532 batadv_gw_reselect(bat_priv); 533 batadv_gw_reselect(bat_priv);
533 /* always call batadv_gw_check_client_stop() before changing the gateway 534 /* always call batadv_gw_check_client_stop() before changing the gateway
534 * state 535 * state
535 */ 536 */
536 batadv_gw_check_client_stop(bat_priv); 537 batadv_gw_check_client_stop(bat_priv);
537 atomic_set(&bat_priv->gw.mode, (unsigned int)gw_mode_tmp); 538 atomic_set(&bat_priv->gw.mode, (unsigned int)gw_mode_tmp);
538 batadv_gw_tvlv_container_update(bat_priv); 539 batadv_gw_tvlv_container_update(bat_priv);
539 return count; 540 return count;
540 } 541 }
541 542
542 static ssize_t batadv_show_gw_sel_class(struct kobject *kobj, 543 static ssize_t batadv_show_gw_sel_class(struct kobject *kobj,
543 struct attribute *attr, char *buff) 544 struct attribute *attr, char *buff)
544 { 545 {
545 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 546 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
546 547
547 /* GW selection class is not available if the routing algorithm in use 548 /* GW selection class is not available if the routing algorithm in use
548 * does not implement the GW API 549 * does not implement the GW API
549 */ 550 */
550 if (!bat_priv->algo_ops->gw.get_best_gw_node || 551 if (!bat_priv->algo_ops->gw.get_best_gw_node ||
551 !bat_priv->algo_ops->gw.is_eligible) 552 !bat_priv->algo_ops->gw.is_eligible)
552 return -ENOENT; 553 return -ENOENT;
553 554
554 if (bat_priv->algo_ops->gw.show_sel_class) 555 if (bat_priv->algo_ops->gw.show_sel_class)
555 return bat_priv->algo_ops->gw.show_sel_class(bat_priv, buff); 556 return bat_priv->algo_ops->gw.show_sel_class(bat_priv, buff);
556 557
557 return sprintf(buff, "%i\n", atomic_read(&bat_priv->gw.sel_class)); 558 return sprintf(buff, "%i\n", atomic_read(&bat_priv->gw.sel_class));
558 } 559 }
559 560
560 static ssize_t batadv_store_gw_sel_class(struct kobject *kobj, 561 static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
561 struct attribute *attr, char *buff, 562 struct attribute *attr, char *buff,
562 size_t count) 563 size_t count)
563 { 564 {
564 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 565 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
565 566
566 /* setting the GW selection class is allowed only if the routing 567 /* setting the GW selection class is allowed only if the routing
567 * algorithm in use implements the GW API 568 * algorithm in use implements the GW API
568 */ 569 */
569 if (!bat_priv->algo_ops->gw.get_best_gw_node || 570 if (!bat_priv->algo_ops->gw.get_best_gw_node ||
570 !bat_priv->algo_ops->gw.is_eligible) 571 !bat_priv->algo_ops->gw.is_eligible)
571 return -EINVAL; 572 return -EINVAL;
572 573
573 if (buff[count - 1] == '\n') 574 if (buff[count - 1] == '\n')
574 buff[count - 1] = '\0'; 575 buff[count - 1] = '\0';
575 576
576 if (bat_priv->algo_ops->gw.store_sel_class) 577 if (bat_priv->algo_ops->gw.store_sel_class)
577 return bat_priv->algo_ops->gw.store_sel_class(bat_priv, buff, 578 return bat_priv->algo_ops->gw.store_sel_class(bat_priv, buff,
578 count); 579 count);
579 580
580 return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE, 581 return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
581 batadv_post_gw_reselect, attr, 582 batadv_post_gw_reselect, attr,
582 &bat_priv->gw.sel_class, 583 &bat_priv->gw.sel_class,
583 bat_priv->soft_iface, NULL); 584 bat_priv->soft_iface, NULL);
584 } 585 }
585 586
586 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj, 587 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
587 struct attribute *attr, char *buff) 588 struct attribute *attr, char *buff)
588 { 589 {
589 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 590 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
590 u32 down, up; 591 u32 down, up;
591 592
592 down = atomic_read(&bat_priv->gw.bandwidth_down); 593 down = atomic_read(&bat_priv->gw.bandwidth_down);
593 up = atomic_read(&bat_priv->gw.bandwidth_up); 594 up = atomic_read(&bat_priv->gw.bandwidth_up);
594 595
595 return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10, 596 return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10,
596 down % 10, up / 10, up % 10); 597 down % 10, up / 10, up % 10);
597 } 598 }
598 599
599 static ssize_t batadv_store_gw_bwidth(struct kobject *kobj, 600 static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
600 struct attribute *attr, char *buff, 601 struct attribute *attr, char *buff,
601 size_t count) 602 size_t count)
602 { 603 {
603 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 604 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
604 605
605 if (buff[count - 1] == '\n') 606 if (buff[count - 1] == '\n')
606 buff[count - 1] = '\0'; 607 buff[count - 1] = '\0';
607 608
608 return batadv_gw_bandwidth_set(net_dev, buff, count); 609 return batadv_gw_bandwidth_set(net_dev, buff, count);
609 } 610 }
610 611
611 /** 612 /**
612 * batadv_show_isolation_mark() - print the current isolation mark/mask 613 * batadv_show_isolation_mark() - print the current isolation mark/mask
613 * @kobj: kobject representing the private mesh sysfs directory 614 * @kobj: kobject representing the private mesh sysfs directory
614 * @attr: the batman-adv attribute the user is interacting with 615 * @attr: the batman-adv attribute the user is interacting with
615 * @buff: the buffer that will contain the data to send back to the user 616 * @buff: the buffer that will contain the data to send back to the user
616 * 617 *
617 * Return: the number of bytes written into 'buff' on success or a negative 618 * Return: the number of bytes written into 'buff' on success or a negative
618 * error code in case of failure 619 * error code in case of failure
619 */ 620 */
620 static ssize_t batadv_show_isolation_mark(struct kobject *kobj, 621 static ssize_t batadv_show_isolation_mark(struct kobject *kobj,
621 struct attribute *attr, char *buff) 622 struct attribute *attr, char *buff)
622 { 623 {
623 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 624 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
624 625
625 return sprintf(buff, "%#.8x/%#.8x\n", bat_priv->isolation_mark, 626 return sprintf(buff, "%#.8x/%#.8x\n", bat_priv->isolation_mark,
626 bat_priv->isolation_mark_mask); 627 bat_priv->isolation_mark_mask);
627 } 628 }
628 629
629 /** 630 /**
630 * batadv_store_isolation_mark() - parse and store the isolation mark/mask 631 * batadv_store_isolation_mark() - parse and store the isolation mark/mask
631 * entered by the user 632 * entered by the user
632 * @kobj: kobject representing the private mesh sysfs directory 633 * @kobj: kobject representing the private mesh sysfs directory
633 * @attr: the batman-adv attribute the user is interacting with 634 * @attr: the batman-adv attribute the user is interacting with
634 * @buff: the buffer containing the user data 635 * @buff: the buffer containing the user data
635 * @count: number of bytes in the buffer 636 * @count: number of bytes in the buffer
636 * 637 *
637 * Return: 'count' on success or a negative error code in case of failure 638 * Return: 'count' on success or a negative error code in case of failure
638 */ 639 */
639 static ssize_t batadv_store_isolation_mark(struct kobject *kobj, 640 static ssize_t batadv_store_isolation_mark(struct kobject *kobj,
640 struct attribute *attr, char *buff, 641 struct attribute *attr, char *buff,
641 size_t count) 642 size_t count)
642 { 643 {
643 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 644 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
644 struct batadv_priv *bat_priv = netdev_priv(net_dev); 645 struct batadv_priv *bat_priv = netdev_priv(net_dev);
645 u32 mark, mask; 646 u32 mark, mask;
646 char *mask_ptr; 647 char *mask_ptr;
647 648
648 /* parse the mask if it has been specified, otherwise assume the mask is 649 /* parse the mask if it has been specified, otherwise assume the mask is
649 * the biggest possible 650 * the biggest possible
650 */ 651 */
651 mask = 0xFFFFFFFF; 652 mask = 0xFFFFFFFF;
652 mask_ptr = strchr(buff, '/'); 653 mask_ptr = strchr(buff, '/');
653 if (mask_ptr) { 654 if (mask_ptr) {
654 *mask_ptr = '\0'; 655 *mask_ptr = '\0';
655 mask_ptr++; 656 mask_ptr++;
656 657
657 /* the mask must be entered in hex base as it is going to be a 658 /* the mask must be entered in hex base as it is going to be a
658 * bitmask and not a prefix length 659 * bitmask and not a prefix length
659 */ 660 */
660 if (kstrtou32(mask_ptr, 16, &mask) < 0) 661 if (kstrtou32(mask_ptr, 16, &mask) < 0)
661 return -EINVAL; 662 return -EINVAL;
662 } 663 }
663 664
664 /* the mark can be entered in any base */ 665 /* the mark can be entered in any base */
665 if (kstrtou32(buff, 0, &mark) < 0) 666 if (kstrtou32(buff, 0, &mark) < 0)
666 return -EINVAL; 667 return -EINVAL;
667 668
668 bat_priv->isolation_mark_mask = mask; 669 bat_priv->isolation_mark_mask = mask;
669 /* erase bits not covered by the mask */ 670 /* erase bits not covered by the mask */
670 bat_priv->isolation_mark = mark & bat_priv->isolation_mark_mask; 671 bat_priv->isolation_mark = mark & bat_priv->isolation_mark_mask;
671 672
672 batadv_info(net_dev, 673 batadv_info(net_dev,
673 "New skb mark for extended isolation: %#.8x/%#.8x\n", 674 "New skb mark for extended isolation: %#.8x/%#.8x\n",
674 bat_priv->isolation_mark, bat_priv->isolation_mark_mask); 675 bat_priv->isolation_mark, bat_priv->isolation_mark_mask);
675 676
676 return count; 677 return count;
677 } 678 }
678 679
679 BATADV_ATTR_SIF_BOOL(aggregated_ogms, 0644, NULL); 680 BATADV_ATTR_SIF_BOOL(aggregated_ogms, 0644, NULL);
680 BATADV_ATTR_SIF_BOOL(bonding, 0644, NULL); 681 BATADV_ATTR_SIF_BOOL(bonding, 0644, NULL);
681 #ifdef CONFIG_BATMAN_ADV_BLA 682 #ifdef CONFIG_BATMAN_ADV_BLA
682 BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, 0644, batadv_bla_status_update); 683 BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, 0644, batadv_bla_status_update);
683 #endif 684 #endif
684 #ifdef CONFIG_BATMAN_ADV_DAT 685 #ifdef CONFIG_BATMAN_ADV_DAT
685 BATADV_ATTR_SIF_BOOL(distributed_arp_table, 0644, batadv_dat_status_update); 686 BATADV_ATTR_SIF_BOOL(distributed_arp_table, 0644, batadv_dat_status_update);
686 #endif 687 #endif
687 BATADV_ATTR_SIF_BOOL(fragmentation, 0644, batadv_update_min_mtu); 688 BATADV_ATTR_SIF_BOOL(fragmentation, 0644, batadv_update_min_mtu);
688 static BATADV_ATTR(routing_algo, 0444, batadv_show_bat_algo, NULL); 689 static BATADV_ATTR(routing_algo, 0444, batadv_show_bat_algo, NULL);
689 static BATADV_ATTR(gw_mode, 0644, batadv_show_gw_mode, batadv_store_gw_mode); 690 static BATADV_ATTR(gw_mode, 0644, batadv_show_gw_mode, batadv_store_gw_mode);
690 BATADV_ATTR_SIF_UINT(orig_interval, orig_interval, 0644, 2 * BATADV_JITTER, 691 BATADV_ATTR_SIF_UINT(orig_interval, orig_interval, 0644, 2 * BATADV_JITTER,
691 INT_MAX, NULL); 692 INT_MAX, NULL);
692 BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, 0644, 0, BATADV_TQ_MAX_VALUE, 693 BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, 0644, 0, BATADV_TQ_MAX_VALUE,
693 NULL); 694 NULL);
694 static BATADV_ATTR(gw_sel_class, 0644, batadv_show_gw_sel_class, 695 static BATADV_ATTR(gw_sel_class, 0644, batadv_show_gw_sel_class,
695 batadv_store_gw_sel_class); 696 batadv_store_gw_sel_class);
696 static BATADV_ATTR(gw_bandwidth, 0644, batadv_show_gw_bwidth, 697 static BATADV_ATTR(gw_bandwidth, 0644, batadv_show_gw_bwidth,
697 batadv_store_gw_bwidth); 698 batadv_store_gw_bwidth);
698 #ifdef CONFIG_BATMAN_ADV_MCAST 699 #ifdef CONFIG_BATMAN_ADV_MCAST
699 BATADV_ATTR_SIF_BOOL(multicast_mode, 0644, NULL); 700 BATADV_ATTR_SIF_BOOL(multicast_mode, 0644, NULL);
700 #endif 701 #endif
701 #ifdef CONFIG_BATMAN_ADV_DEBUG 702 #ifdef CONFIG_BATMAN_ADV_DEBUG
702 BATADV_ATTR_SIF_UINT(log_level, log_level, 0644, 0, BATADV_DBG_ALL, NULL); 703 BATADV_ATTR_SIF_UINT(log_level, log_level, 0644, 0, BATADV_DBG_ALL, NULL);
703 #endif 704 #endif
704 #ifdef CONFIG_BATMAN_ADV_NC 705 #ifdef CONFIG_BATMAN_ADV_NC
705 BATADV_ATTR_SIF_BOOL(network_coding, 0644, batadv_nc_status_update); 706 BATADV_ATTR_SIF_BOOL(network_coding, 0644, batadv_nc_status_update);
706 #endif 707 #endif
707 static BATADV_ATTR(isolation_mark, 0644, batadv_show_isolation_mark, 708 static BATADV_ATTR(isolation_mark, 0644, batadv_show_isolation_mark,
708 batadv_store_isolation_mark); 709 batadv_store_isolation_mark);
709 710
710 static struct batadv_attribute *batadv_mesh_attrs[] = { 711 static struct batadv_attribute *batadv_mesh_attrs[] = {
711 &batadv_attr_aggregated_ogms, 712 &batadv_attr_aggregated_ogms,
712 &batadv_attr_bonding, 713 &batadv_attr_bonding,
713 #ifdef CONFIG_BATMAN_ADV_BLA 714 #ifdef CONFIG_BATMAN_ADV_BLA
714 &batadv_attr_bridge_loop_avoidance, 715 &batadv_attr_bridge_loop_avoidance,
715 #endif 716 #endif
716 #ifdef CONFIG_BATMAN_ADV_DAT 717 #ifdef CONFIG_BATMAN_ADV_DAT
717 &batadv_attr_distributed_arp_table, 718 &batadv_attr_distributed_arp_table,
718 #endif 719 #endif
719 #ifdef CONFIG_BATMAN_ADV_MCAST 720 #ifdef CONFIG_BATMAN_ADV_MCAST
720 &batadv_attr_multicast_mode, 721 &batadv_attr_multicast_mode,
721 #endif 722 #endif
722 &batadv_attr_fragmentation, 723 &batadv_attr_fragmentation,
723 &batadv_attr_routing_algo, 724 &batadv_attr_routing_algo,
724 &batadv_attr_gw_mode, 725 &batadv_attr_gw_mode,
725 &batadv_attr_orig_interval, 726 &batadv_attr_orig_interval,
726 &batadv_attr_hop_penalty, 727 &batadv_attr_hop_penalty,
727 &batadv_attr_gw_sel_class, 728 &batadv_attr_gw_sel_class,
728 &batadv_attr_gw_bandwidth, 729 &batadv_attr_gw_bandwidth,
729 #ifdef CONFIG_BATMAN_ADV_DEBUG 730 #ifdef CONFIG_BATMAN_ADV_DEBUG
730 &batadv_attr_log_level, 731 &batadv_attr_log_level,
731 #endif 732 #endif
732 #ifdef CONFIG_BATMAN_ADV_NC 733 #ifdef CONFIG_BATMAN_ADV_NC
733 &batadv_attr_network_coding, 734 &batadv_attr_network_coding,
734 #endif 735 #endif
735 &batadv_attr_isolation_mark, 736 &batadv_attr_isolation_mark,
736 NULL, 737 NULL,
737 }; 738 };
738 739
739 BATADV_ATTR_VLAN_BOOL(ap_isolation, 0644, NULL); 740 BATADV_ATTR_VLAN_BOOL(ap_isolation, 0644, NULL);
740 741
741 /* array of vlan specific sysfs attributes */ 742 /* array of vlan specific sysfs attributes */
742 static struct batadv_attribute *batadv_vlan_attrs[] = { 743 static struct batadv_attribute *batadv_vlan_attrs[] = {
743 &batadv_attr_vlan_ap_isolation, 744 &batadv_attr_vlan_ap_isolation,
744 NULL, 745 NULL,
745 }; 746 };
746 747
747 /** 748 /**
748 * batadv_sysfs_add_meshif() - Add soft interface specific sysfs entries 749 * batadv_sysfs_add_meshif() - Add soft interface specific sysfs entries
749 * @dev: netdev struct of the soft interface 750 * @dev: netdev struct of the soft interface
750 * 751 *
751 * Return: 0 on success or negative error number in case of failure 752 * Return: 0 on success or negative error number in case of failure
752 */ 753 */
753 int batadv_sysfs_add_meshif(struct net_device *dev) 754 int batadv_sysfs_add_meshif(struct net_device *dev)
754 { 755 {
755 struct kobject *batif_kobject = &dev->dev.kobj; 756 struct kobject *batif_kobject = &dev->dev.kobj;
756 struct batadv_priv *bat_priv = netdev_priv(dev); 757 struct batadv_priv *bat_priv = netdev_priv(dev);
757 struct batadv_attribute **bat_attr; 758 struct batadv_attribute **bat_attr;
758 int err; 759 int err;
759 760
760 bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR, 761 bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR,
761 batif_kobject); 762 batif_kobject);
762 if (!bat_priv->mesh_obj) { 763 if (!bat_priv->mesh_obj) {
763 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, 764 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
764 BATADV_SYSFS_IF_MESH_SUBDIR); 765 BATADV_SYSFS_IF_MESH_SUBDIR);
765 goto out; 766 goto out;
766 } 767 }
767 768
768 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) { 769 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) {
769 err = sysfs_create_file(bat_priv->mesh_obj, 770 err = sysfs_create_file(bat_priv->mesh_obj,
770 &((*bat_attr)->attr)); 771 &((*bat_attr)->attr));
771 if (err) { 772 if (err) {
772 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", 773 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
773 dev->name, BATADV_SYSFS_IF_MESH_SUBDIR, 774 dev->name, BATADV_SYSFS_IF_MESH_SUBDIR,
774 ((*bat_attr)->attr).name); 775 ((*bat_attr)->attr).name);
775 goto rem_attr; 776 goto rem_attr;
776 } 777 }
777 } 778 }
778 779
779 return 0; 780 return 0;
780 781
781 rem_attr: 782 rem_attr:
782 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) 783 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
783 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); 784 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
784 785
785 kobject_uevent(bat_priv->mesh_obj, KOBJ_REMOVE); 786 kobject_uevent(bat_priv->mesh_obj, KOBJ_REMOVE);
786 kobject_del(bat_priv->mesh_obj); 787 kobject_del(bat_priv->mesh_obj);
787 kobject_put(bat_priv->mesh_obj); 788 kobject_put(bat_priv->mesh_obj);
788 bat_priv->mesh_obj = NULL; 789 bat_priv->mesh_obj = NULL;
789 out: 790 out:
790 return -ENOMEM; 791 return -ENOMEM;
791 } 792 }
792 793
793 /** 794 /**
794 * batadv_sysfs_del_meshif() - Remove soft interface specific sysfs entries 795 * batadv_sysfs_del_meshif() - Remove soft interface specific sysfs entries
795 * @dev: netdev struct of the soft interface 796 * @dev: netdev struct of the soft interface
796 */ 797 */
797 void batadv_sysfs_del_meshif(struct net_device *dev) 798 void batadv_sysfs_del_meshif(struct net_device *dev)
798 { 799 {
799 struct batadv_priv *bat_priv = netdev_priv(dev); 800 struct batadv_priv *bat_priv = netdev_priv(dev);
800 struct batadv_attribute **bat_attr; 801 struct batadv_attribute **bat_attr;
801 802
802 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) 803 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
803 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); 804 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
804 805
805 kobject_uevent(bat_priv->mesh_obj, KOBJ_REMOVE); 806 kobject_uevent(bat_priv->mesh_obj, KOBJ_REMOVE);
806 kobject_del(bat_priv->mesh_obj); 807 kobject_del(bat_priv->mesh_obj);
807 kobject_put(bat_priv->mesh_obj); 808 kobject_put(bat_priv->mesh_obj);
808 bat_priv->mesh_obj = NULL; 809 bat_priv->mesh_obj = NULL;
809 } 810 }
810 811
811 /** 812 /**
812 * batadv_sysfs_add_vlan() - add all the needed sysfs objects for the new vlan 813 * batadv_sysfs_add_vlan() - add all the needed sysfs objects for the new vlan
813 * @dev: netdev of the mesh interface 814 * @dev: netdev of the mesh interface
814 * @vlan: private data of the newly added VLAN interface 815 * @vlan: private data of the newly added VLAN interface
815 * 816 *
816 * Return: 0 on success and -ENOMEM if any of the structure allocations fails. 817 * Return: 0 on success and -ENOMEM if any of the structure allocations fails.
817 */ 818 */
818 int batadv_sysfs_add_vlan(struct net_device *dev, 819 int batadv_sysfs_add_vlan(struct net_device *dev,
819 struct batadv_softif_vlan *vlan) 820 struct batadv_softif_vlan *vlan)
820 { 821 {
821 char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5]; 822 char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5];
822 struct batadv_priv *bat_priv = netdev_priv(dev); 823 struct batadv_priv *bat_priv = netdev_priv(dev);
823 struct batadv_attribute **bat_attr; 824 struct batadv_attribute **bat_attr;
824 int err; 825 int err;
825 826
826 if (vlan->vid & BATADV_VLAN_HAS_TAG) { 827 if (vlan->vid & BATADV_VLAN_HAS_TAG) {
827 sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu", 828 sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu",
828 vlan->vid & VLAN_VID_MASK); 829 vlan->vid & VLAN_VID_MASK);
829 830
830 vlan->kobj = kobject_create_and_add(vlan_subdir, 831 vlan->kobj = kobject_create_and_add(vlan_subdir,
831 bat_priv->mesh_obj); 832 bat_priv->mesh_obj);
832 if (!vlan->kobj) { 833 if (!vlan->kobj) {
833 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", 834 batadv_err(dev, "Can't add sysfs directory: %s/%s\n",
834 dev->name, vlan_subdir); 835 dev->name, vlan_subdir);
835 goto out; 836 goto out;
836 } 837 }
837 } else { 838 } else {
838 /* the untagged LAN uses the root folder to store its "VLAN 839 /* the untagged LAN uses the root folder to store its "VLAN
839 * specific attributes" 840 * specific attributes"
840 */ 841 */
841 vlan->kobj = bat_priv->mesh_obj; 842 vlan->kobj = bat_priv->mesh_obj;
842 kobject_get(bat_priv->mesh_obj); 843 kobject_get(bat_priv->mesh_obj);
843 } 844 }
844 845
845 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) { 846 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) {
846 err = sysfs_create_file(vlan->kobj, 847 err = sysfs_create_file(vlan->kobj,
847 &((*bat_attr)->attr)); 848 &((*bat_attr)->attr));
848 if (err) { 849 if (err) {
849 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", 850 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
850 dev->name, vlan_subdir, 851 dev->name, vlan_subdir,
851 ((*bat_attr)->attr).name); 852 ((*bat_attr)->attr).name);
852 goto rem_attr; 853 goto rem_attr;
853 } 854 }
854 } 855 }
855 856
856 return 0; 857 return 0;
857 858
858 rem_attr: 859 rem_attr:
859 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) 860 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
860 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr)); 861 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
861 862
862 if (vlan->kobj != bat_priv->mesh_obj) { 863 if (vlan->kobj != bat_priv->mesh_obj) {
863 kobject_uevent(vlan->kobj, KOBJ_REMOVE); 864 kobject_uevent(vlan->kobj, KOBJ_REMOVE);
864 kobject_del(vlan->kobj); 865 kobject_del(vlan->kobj);
865 } 866 }
866 kobject_put(vlan->kobj); 867 kobject_put(vlan->kobj);
867 vlan->kobj = NULL; 868 vlan->kobj = NULL;
868 out: 869 out:
869 return -ENOMEM; 870 return -ENOMEM;
870 } 871 }
871 872
872 /** 873 /**
873 * batadv_sysfs_del_vlan() - remove all the sysfs objects for a given VLAN 874 * batadv_sysfs_del_vlan() - remove all the sysfs objects for a given VLAN
874 * @bat_priv: the bat priv with all the soft interface information 875 * @bat_priv: the bat priv with all the soft interface information
875 * @vlan: the private data of the VLAN to destroy 876 * @vlan: the private data of the VLAN to destroy
876 */ 877 */
877 void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv, 878 void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
878 struct batadv_softif_vlan *vlan) 879 struct batadv_softif_vlan *vlan)
879 { 880 {
880 struct batadv_attribute **bat_attr; 881 struct batadv_attribute **bat_attr;
881 882
882 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) 883 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
883 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr)); 884 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
884 885
885 if (vlan->kobj != bat_priv->mesh_obj) { 886 if (vlan->kobj != bat_priv->mesh_obj) {
886 kobject_uevent(vlan->kobj, KOBJ_REMOVE); 887 kobject_uevent(vlan->kobj, KOBJ_REMOVE);
887 kobject_del(vlan->kobj); 888 kobject_del(vlan->kobj);
888 } 889 }
889 kobject_put(vlan->kobj); 890 kobject_put(vlan->kobj);
890 vlan->kobj = NULL; 891 vlan->kobj = NULL;
891 } 892 }
892 893
893 static ssize_t batadv_show_mesh_iface(struct kobject *kobj, 894 static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
894 struct attribute *attr, char *buff) 895 struct attribute *attr, char *buff)
895 { 896 {
896 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 897 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
897 struct batadv_hard_iface *hard_iface; 898 struct batadv_hard_iface *hard_iface;
898 ssize_t length; 899 ssize_t length;
899 const char *ifname; 900 const char *ifname;
900 901
901 hard_iface = batadv_hardif_get_by_netdev(net_dev); 902 hard_iface = batadv_hardif_get_by_netdev(net_dev);
902 if (!hard_iface) 903 if (!hard_iface)
903 return 0; 904 return 0;
904 905
905 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE) 906 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
906 ifname = "none"; 907 ifname = "none";
907 else 908 else
908 ifname = hard_iface->soft_iface->name; 909 ifname = hard_iface->soft_iface->name;
909 910
910 length = sprintf(buff, "%s\n", ifname); 911 length = sprintf(buff, "%s\n", ifname);
911 912
912 batadv_hardif_put(hard_iface); 913 batadv_hardif_put(hard_iface);
913 914
914 return length; 915 return length;
915 } 916 }
916 917
917 /** 918 /**
918 * batadv_store_mesh_iface_finish() - store new hardif mesh_iface state 919 * batadv_store_mesh_iface_finish() - store new hardif mesh_iface state
919 * @net_dev: netdevice to add/remove to/from batman-adv soft-interface 920 * @net_dev: netdevice to add/remove to/from batman-adv soft-interface
920 * @ifname: name of soft-interface to modify 921 * @ifname: name of soft-interface to modify
921 * 922 *
922 * Changes the parts of the hard+soft interface which can not be modified under 923 * Changes the parts of the hard+soft interface which can not be modified under
923 * sysfs lock (to prevent deadlock situations). 924 * sysfs lock (to prevent deadlock situations).
924 * 925 *
925 * Return: 0 on success, 0 < on failure 926 * Return: 0 on success, 0 < on failure
926 */ 927 */
927 static int batadv_store_mesh_iface_finish(struct net_device *net_dev, 928 static int batadv_store_mesh_iface_finish(struct net_device *net_dev,
928 char ifname[IFNAMSIZ]) 929 char ifname[IFNAMSIZ])
929 { 930 {
930 struct net *net = dev_net(net_dev); 931 struct net *net = dev_net(net_dev);
931 struct batadv_hard_iface *hard_iface; 932 struct batadv_hard_iface *hard_iface;
932 int status_tmp; 933 int status_tmp;
933 int ret = 0; 934 int ret = 0;
934 935
935 ASSERT_RTNL(); 936 ASSERT_RTNL();
936 937
937 hard_iface = batadv_hardif_get_by_netdev(net_dev); 938 hard_iface = batadv_hardif_get_by_netdev(net_dev);
938 if (!hard_iface) 939 if (!hard_iface)
939 return 0; 940 return 0;
940 941
941 if (strncmp(ifname, "none", 4) == 0) 942 if (strncmp(ifname, "none", 4) == 0)
942 status_tmp = BATADV_IF_NOT_IN_USE; 943 status_tmp = BATADV_IF_NOT_IN_USE;
943 else 944 else
944 status_tmp = BATADV_IF_I_WANT_YOU; 945 status_tmp = BATADV_IF_I_WANT_YOU;
945 946
946 if (hard_iface->if_status == status_tmp) 947 if (hard_iface->if_status == status_tmp)
947 goto out; 948 goto out;
948 949
949 if (hard_iface->soft_iface && 950 if (hard_iface->soft_iface &&
950 strncmp(hard_iface->soft_iface->name, ifname, IFNAMSIZ) == 0) 951 strncmp(hard_iface->soft_iface->name, ifname, IFNAMSIZ) == 0)
951 goto out; 952 goto out;
952 953
953 if (status_tmp == BATADV_IF_NOT_IN_USE) { 954 if (status_tmp == BATADV_IF_NOT_IN_USE) {
954 batadv_hardif_disable_interface(hard_iface, 955 batadv_hardif_disable_interface(hard_iface,
955 BATADV_IF_CLEANUP_AUTO); 956 BATADV_IF_CLEANUP_AUTO);
956 goto out; 957 goto out;
957 } 958 }
958 959
959 /* if the interface already is in use */ 960 /* if the interface already is in use */
960 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 961 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
961 batadv_hardif_disable_interface(hard_iface, 962 batadv_hardif_disable_interface(hard_iface,
962 BATADV_IF_CLEANUP_AUTO); 963 BATADV_IF_CLEANUP_AUTO);
963 964
964 ret = batadv_hardif_enable_interface(hard_iface, net, ifname); 965 ret = batadv_hardif_enable_interface(hard_iface, net, ifname);
965 out: 966 out:
966 batadv_hardif_put(hard_iface); 967 batadv_hardif_put(hard_iface);
967 return ret; 968 return ret;
968 } 969 }
969 970
970 /** 971 /**
971 * batadv_store_mesh_iface_work() - store new hardif mesh_iface state 972 * batadv_store_mesh_iface_work() - store new hardif mesh_iface state
972 * @work: work queue item 973 * @work: work queue item
973 * 974 *
974 * Changes the parts of the hard+soft interface which can not be modified under 975 * Changes the parts of the hard+soft interface which can not be modified under
975 * sysfs lock (to prevent deadlock situations). 976 * sysfs lock (to prevent deadlock situations).
976 */ 977 */
977 static void batadv_store_mesh_iface_work(struct work_struct *work) 978 static void batadv_store_mesh_iface_work(struct work_struct *work)
978 { 979 {
979 struct batadv_store_mesh_work *store_work; 980 struct batadv_store_mesh_work *store_work;
980 int ret; 981 int ret;
981 982
982 store_work = container_of(work, struct batadv_store_mesh_work, work); 983 store_work = container_of(work, struct batadv_store_mesh_work, work);
983 984
984 rtnl_lock(); 985 rtnl_lock();
985 ret = batadv_store_mesh_iface_finish(store_work->net_dev, 986 ret = batadv_store_mesh_iface_finish(store_work->net_dev,
986 store_work->soft_iface_name); 987 store_work->soft_iface_name);
987 rtnl_unlock(); 988 rtnl_unlock();
988 989
989 if (ret < 0) 990 if (ret < 0)
990 pr_err("Failed to store new mesh_iface state %s for %s: %d\n", 991 pr_err("Failed to store new mesh_iface state %s for %s: %d\n",
991 store_work->soft_iface_name, store_work->net_dev->name, 992 store_work->soft_iface_name, store_work->net_dev->name,
992 ret); 993 ret);
993 994
994 dev_put(store_work->net_dev); 995 dev_put(store_work->net_dev);
995 kfree(store_work); 996 kfree(store_work);
996 } 997 }
997 998
998 static ssize_t batadv_store_mesh_iface(struct kobject *kobj, 999 static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
999 struct attribute *attr, char *buff, 1000 struct attribute *attr, char *buff,
1000 size_t count) 1001 size_t count)
1001 { 1002 {
1002 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 1003 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
1003 struct batadv_store_mesh_work *store_work; 1004 struct batadv_store_mesh_work *store_work;
1004 1005
1005 if (buff[count - 1] == '\n') 1006 if (buff[count - 1] == '\n')
1006 buff[count - 1] = '\0'; 1007 buff[count - 1] = '\0';
1007 1008
1008 if (strlen(buff) >= IFNAMSIZ) { 1009 if (strlen(buff) >= IFNAMSIZ) {
1009 pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n", 1010 pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n",
1010 buff); 1011 buff);
1011 return -EINVAL; 1012 return -EINVAL;
1012 } 1013 }
1013 1014
1014 store_work = kmalloc(sizeof(*store_work), GFP_KERNEL); 1015 store_work = kmalloc(sizeof(*store_work), GFP_KERNEL);
1015 if (!store_work) 1016 if (!store_work)
1016 return -ENOMEM; 1017 return -ENOMEM;
1017 1018
1018 dev_hold(net_dev); 1019 dev_hold(net_dev);
1019 INIT_WORK(&store_work->work, batadv_store_mesh_iface_work); 1020 INIT_WORK(&store_work->work, batadv_store_mesh_iface_work);
1020 store_work->net_dev = net_dev; 1021 store_work->net_dev = net_dev;
1021 strlcpy(store_work->soft_iface_name, buff, 1022 strlcpy(store_work->soft_iface_name, buff,
1022 sizeof(store_work->soft_iface_name)); 1023 sizeof(store_work->soft_iface_name));
1023 1024
1024 queue_work(batadv_event_workqueue, &store_work->work); 1025 queue_work(batadv_event_workqueue, &store_work->work);
1025 1026
1026 return count; 1027 return count;
1027 } 1028 }
1028 1029
1029 static ssize_t batadv_show_iface_status(struct kobject *kobj, 1030 static ssize_t batadv_show_iface_status(struct kobject *kobj,
1030 struct attribute *attr, char *buff) 1031 struct attribute *attr, char *buff)
1031 { 1032 {
1032 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 1033 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
1033 struct batadv_hard_iface *hard_iface; 1034 struct batadv_hard_iface *hard_iface;
1034 ssize_t length; 1035 ssize_t length;
1035 1036
1036 hard_iface = batadv_hardif_get_by_netdev(net_dev); 1037 hard_iface = batadv_hardif_get_by_netdev(net_dev);
1037 if (!hard_iface) 1038 if (!hard_iface)
1038 return 0; 1039 return 0;
1039 1040
1040 switch (hard_iface->if_status) { 1041 switch (hard_iface->if_status) {
1041 case BATADV_IF_TO_BE_REMOVED: 1042 case BATADV_IF_TO_BE_REMOVED:
1042 length = sprintf(buff, "disabling\n"); 1043 length = sprintf(buff, "disabling\n");
1043 break; 1044 break;
1044 case BATADV_IF_INACTIVE: 1045 case BATADV_IF_INACTIVE:
1045 length = sprintf(buff, "inactive\n"); 1046 length = sprintf(buff, "inactive\n");
1046 break; 1047 break;
1047 case BATADV_IF_ACTIVE: 1048 case BATADV_IF_ACTIVE:
1048 length = sprintf(buff, "active\n"); 1049 length = sprintf(buff, "active\n");
1049 break; 1050 break;
1050 case BATADV_IF_TO_BE_ACTIVATED: 1051 case BATADV_IF_TO_BE_ACTIVATED:
1051 length = sprintf(buff, "enabling\n"); 1052 length = sprintf(buff, "enabling\n");
1052 break; 1053 break;
1053 case BATADV_IF_NOT_IN_USE: 1054 case BATADV_IF_NOT_IN_USE:
1054 default: 1055 default:
1055 length = sprintf(buff, "not in use\n"); 1056 length = sprintf(buff, "not in use\n");
1056 break; 1057 break;
1057 } 1058 }
1058 1059
1059 batadv_hardif_put(hard_iface); 1060 batadv_hardif_put(hard_iface);
1060 1061
1061 return length; 1062 return length;
1062 } 1063 }
1063 1064
1064 #ifdef CONFIG_BATMAN_ADV_BATMAN_V 1065 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
1065 1066
1066 /** 1067 /**
1067 * batadv_store_throughput_override() - parse and store throughput override 1068 * batadv_store_throughput_override() - parse and store throughput override
1068 * entered by the user 1069 * entered by the user
1069 * @kobj: kobject representing the private mesh sysfs directory 1070 * @kobj: kobject representing the private mesh sysfs directory
1070 * @attr: the batman-adv attribute the user is interacting with 1071 * @attr: the batman-adv attribute the user is interacting with
1071 * @buff: the buffer containing the user data 1072 * @buff: the buffer containing the user data
1072 * @count: number of bytes in the buffer 1073 * @count: number of bytes in the buffer
1073 * 1074 *
1074 * Return: 'count' on success or a negative error code in case of failure 1075 * Return: 'count' on success or a negative error code in case of failure
1075 */ 1076 */
1076 static ssize_t batadv_store_throughput_override(struct kobject *kobj, 1077 static ssize_t batadv_store_throughput_override(struct kobject *kobj,
1077 struct attribute *attr, 1078 struct attribute *attr,
1078 char *buff, size_t count) 1079 char *buff, size_t count)
1079 { 1080 {
1080 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 1081 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
1081 struct batadv_hard_iface *hard_iface; 1082 struct batadv_hard_iface *hard_iface;
1082 u32 tp_override; 1083 u32 tp_override;
1083 u32 old_tp_override; 1084 u32 old_tp_override;
1084 bool ret; 1085 bool ret;
1085 1086
1086 hard_iface = batadv_hardif_get_by_netdev(net_dev); 1087 hard_iface = batadv_hardif_get_by_netdev(net_dev);
1087 if (!hard_iface) 1088 if (!hard_iface)
1088 return -EINVAL; 1089 return -EINVAL;
1089 1090
1090 if (buff[count - 1] == '\n') 1091 if (buff[count - 1] == '\n')
1091 buff[count - 1] = '\0'; 1092 buff[count - 1] = '\0';
1092 1093
1093 ret = batadv_parse_throughput(net_dev, buff, "throughput_override", 1094 ret = batadv_parse_throughput(net_dev, buff, "throughput_override",
1094 &tp_override); 1095 &tp_override);
1095 if (!ret) 1096 if (!ret)
1096 return count; 1097 return count;
1097 1098
1098 old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override); 1099 old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
1099 if (old_tp_override == tp_override) 1100 if (old_tp_override == tp_override)
1100 goto out; 1101 goto out;
1101 1102
1102 batadv_info(hard_iface->soft_iface, 1103 batadv_info(hard_iface->soft_iface,
1103 "%s: %s: Changing from: %u.%u MBit to: %u.%u MBit\n", 1104 "%s: %s: Changing from: %u.%u MBit to: %u.%u MBit\n",
1104 "throughput_override", net_dev->name, 1105 "throughput_override", net_dev->name,
1105 old_tp_override / 10, old_tp_override % 10, 1106 old_tp_override / 10, old_tp_override % 10,
1106 tp_override / 10, tp_override % 10); 1107 tp_override / 10, tp_override % 10);
1107 1108
1108 atomic_set(&hard_iface->bat_v.throughput_override, tp_override); 1109 atomic_set(&hard_iface->bat_v.throughput_override, tp_override);
1109 1110
1110 out: 1111 out:
1111 batadv_hardif_put(hard_iface); 1112 batadv_hardif_put(hard_iface);
1112 return count; 1113 return count;
1113 } 1114 }
1114 1115
1115 static ssize_t batadv_show_throughput_override(struct kobject *kobj, 1116 static ssize_t batadv_show_throughput_override(struct kobject *kobj,
1116 struct attribute *attr, 1117 struct attribute *attr,
1117 char *buff) 1118 char *buff)
1118 { 1119 {
1119 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 1120 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
1120 struct batadv_hard_iface *hard_iface; 1121 struct batadv_hard_iface *hard_iface;
1121 u32 tp_override; 1122 u32 tp_override;
1122 1123
1123 hard_iface = batadv_hardif_get_by_netdev(net_dev); 1124 hard_iface = batadv_hardif_get_by_netdev(net_dev);
1124 if (!hard_iface) 1125 if (!hard_iface)
1125 return -EINVAL; 1126 return -EINVAL;
1126 1127
1127 tp_override = atomic_read(&hard_iface->bat_v.throughput_override); 1128 tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
1128 1129
1129 return sprintf(buff, "%u.%u MBit\n", tp_override / 10, 1130 return sprintf(buff, "%u.%u MBit\n", tp_override / 10,
1130 tp_override % 10); 1131 tp_override % 10);
1131 } 1132 }
1132 1133
1133 #endif 1134 #endif
1134 1135
1135 static BATADV_ATTR(mesh_iface, 0644, batadv_show_mesh_iface, 1136 static BATADV_ATTR(mesh_iface, 0644, batadv_show_mesh_iface,
1136 batadv_store_mesh_iface); 1137 batadv_store_mesh_iface);
1137 static BATADV_ATTR(iface_status, 0444, batadv_show_iface_status, NULL); 1138 static BATADV_ATTR(iface_status, 0444, batadv_show_iface_status, NULL);
1138 #ifdef CONFIG_BATMAN_ADV_BATMAN_V 1139 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
1139 BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, 0644, 1140 BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, 0644,
1140 2 * BATADV_JITTER, INT_MAX, NULL); 1141 2 * BATADV_JITTER, INT_MAX, NULL);
1141 static BATADV_ATTR(throughput_override, 0644, batadv_show_throughput_override, 1142 static BATADV_ATTR(throughput_override, 0644, batadv_show_throughput_override,
1142 batadv_store_throughput_override); 1143 batadv_store_throughput_override);
1143 #endif 1144 #endif
1144 1145
1145 static struct batadv_attribute *batadv_batman_attrs[] = { 1146 static struct batadv_attribute *batadv_batman_attrs[] = {
1146 &batadv_attr_mesh_iface, 1147 &batadv_attr_mesh_iface,
1147 &batadv_attr_iface_status, 1148 &batadv_attr_iface_status,
1148 #ifdef CONFIG_BATMAN_ADV_BATMAN_V 1149 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
1149 &batadv_attr_elp_interval, 1150 &batadv_attr_elp_interval,
1150 &batadv_attr_throughput_override, 1151 &batadv_attr_throughput_override,
1151 #endif 1152 #endif
1152 NULL, 1153 NULL,
1153 }; 1154 };
1154 1155
1155 /** 1156 /**
1156 * batadv_sysfs_add_hardif() - Add hard interface specific sysfs entries 1157 * batadv_sysfs_add_hardif() - Add hard interface specific sysfs entries
1157 * @hardif_obj: address where to store the pointer to new sysfs folder 1158 * @hardif_obj: address where to store the pointer to new sysfs folder
1158 * @dev: netdev struct of the hard interface 1159 * @dev: netdev struct of the hard interface
1159 * 1160 *
1160 * Return: 0 on success or negative error number in case of failure 1161 * Return: 0 on success or negative error number in case of failure
1161 */ 1162 */
1162 int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) 1163 int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
1163 { 1164 {
1164 struct kobject *hardif_kobject = &dev->dev.kobj; 1165 struct kobject *hardif_kobject = &dev->dev.kobj;
1165 struct batadv_attribute **bat_attr; 1166 struct batadv_attribute **bat_attr;
1166 int err; 1167 int err;
1167 1168
1168 *hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR, 1169 *hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR,
1169 hardif_kobject); 1170 hardif_kobject);
1170 1171
1171 if (!*hardif_obj) { 1172 if (!*hardif_obj) {
1172 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, 1173 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
1173 BATADV_SYSFS_IF_BAT_SUBDIR); 1174 BATADV_SYSFS_IF_BAT_SUBDIR);
1174 goto out; 1175 goto out;
1175 } 1176 }
1176 1177
1177 for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) { 1178 for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) {
1178 err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); 1179 err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
1179 if (err) { 1180 if (err) {
1180 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", 1181 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
1181 dev->name, BATADV_SYSFS_IF_BAT_SUBDIR, 1182 dev->name, BATADV_SYSFS_IF_BAT_SUBDIR,
1182 ((*bat_attr)->attr).name); 1183 ((*bat_attr)->attr).name);
1183 goto rem_attr; 1184 goto rem_attr;
1184 } 1185 }
1185 } 1186 }
1186 1187
1187 return 0; 1188 return 0;
1188 1189
1189 rem_attr: 1190 rem_attr:
1190 for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) 1191 for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr)
1191 sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr)); 1192 sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
1192 out: 1193 out:
1193 return -ENOMEM; 1194 return -ENOMEM;
1194 } 1195 }
1195 1196
1196 /** 1197 /**
1197 * batadv_sysfs_del_hardif() - Remove hard interface specific sysfs entries 1198 * batadv_sysfs_del_hardif() - Remove hard interface specific sysfs entries
1198 * @hardif_obj: address to the pointer to which stores batman-adv sysfs folder 1199 * @hardif_obj: address to the pointer to which stores batman-adv sysfs folder
1199 * of the hard interface 1200 * of the hard interface
1200 */ 1201 */
1201 void batadv_sysfs_del_hardif(struct kobject **hardif_obj) 1202 void batadv_sysfs_del_hardif(struct kobject **hardif_obj)
1202 { 1203 {
1203 kobject_uevent(*hardif_obj, KOBJ_REMOVE); 1204 kobject_uevent(*hardif_obj, KOBJ_REMOVE);
1204 kobject_del(*hardif_obj); 1205 kobject_del(*hardif_obj);
1205 kobject_put(*hardif_obj); 1206 kobject_put(*hardif_obj);
1206 *hardif_obj = NULL; 1207 *hardif_obj = NULL;
1207 } 1208 }
1208 1209
1209 /** 1210 /**
1210 * batadv_throw_uevent() - Send an uevent with batman-adv specific env data 1211 * batadv_throw_uevent() - Send an uevent with batman-adv specific env data
1211 * @bat_priv: the bat priv with all the soft interface information 1212 * @bat_priv: the bat priv with all the soft interface information
1212 * @type: subsystem type of event. Stored in uevent's BATTYPE 1213 * @type: subsystem type of event. Stored in uevent's BATTYPE
1213 * @action: action type of event. Stored in uevent's BATACTION 1214 * @action: action type of event. Stored in uevent's BATACTION
1214 * @data: string with additional information to the event (ignored for 1215 * @data: string with additional information to the event (ignored for
1215 * BATADV_UEV_DEL). Stored in uevent's BATDATA 1216 * BATADV_UEV_DEL). Stored in uevent's BATDATA
1216 * 1217 *
1217 * Return: 0 on success or negative error number in case of failure 1218 * Return: 0 on success or negative error number in case of failure
1218 */ 1219 */
1219 int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type, 1220 int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
1220 enum batadv_uev_action action, const char *data) 1221 enum batadv_uev_action action, const char *data)
1221 { 1222 {
1222 int ret = -ENOMEM; 1223 int ret = -ENOMEM;
1223 struct kobject *bat_kobj; 1224 struct kobject *bat_kobj;
1224 char *uevent_env[4] = { NULL, NULL, NULL, NULL }; 1225 char *uevent_env[4] = { NULL, NULL, NULL, NULL };
1225 1226
1226 bat_kobj = &bat_priv->soft_iface->dev.kobj; 1227 bat_kobj = &bat_priv->soft_iface->dev.kobj;
1227 1228
1228 uevent_env[0] = kasprintf(GFP_ATOMIC, 1229 uevent_env[0] = kasprintf(GFP_ATOMIC,
1229 "%s%s", BATADV_UEV_TYPE_VAR, 1230 "%s%s", BATADV_UEV_TYPE_VAR,
1230 batadv_uev_type_str[type]); 1231 batadv_uev_type_str[type]);
1231 if (!uevent_env[0]) 1232 if (!uevent_env[0])
1232 goto out; 1233 goto out;
1233 1234
1234 uevent_env[1] = kasprintf(GFP_ATOMIC, 1235 uevent_env[1] = kasprintf(GFP_ATOMIC,
1235 "%s%s", BATADV_UEV_ACTION_VAR, 1236 "%s%s", BATADV_UEV_ACTION_VAR,
1236 batadv_uev_action_str[action]); 1237 batadv_uev_action_str[action]);
1237 if (!uevent_env[1]) 1238 if (!uevent_env[1])
1238 goto out; 1239 goto out;
1239 1240
1240 /* If the event is DEL, ignore the data field */ 1241 /* If the event is DEL, ignore the data field */
1241 if (action != BATADV_UEV_DEL) { 1242 if (action != BATADV_UEV_DEL) {
1242 uevent_env[2] = kasprintf(GFP_ATOMIC, 1243 uevent_env[2] = kasprintf(GFP_ATOMIC,
1243 "%s%s", BATADV_UEV_DATA_VAR, data); 1244 "%s%s", BATADV_UEV_DATA_VAR, data);
1244 if (!uevent_env[2]) 1245 if (!uevent_env[2])
1245 goto out; 1246 goto out;
1246 } 1247 }
1247 1248
1248 ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env); 1249 ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
1249 out: 1250 out:
1250 kfree(uevent_env[0]); 1251 kfree(uevent_env[0]);
1251 kfree(uevent_env[1]); 1252 kfree(uevent_env[1]);
1252 kfree(uevent_env[2]); 1253 kfree(uevent_env[2]);
1253 1254
1254 if (ret) 1255 if (ret)
1255 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1256 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1256 "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n", 1257 "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
1257 batadv_uev_type_str[type], 1258 batadv_uev_type_str[type],
1258 batadv_uev_action_str[action], 1259 batadv_uev_action_str[action],
1259 (action == BATADV_UEV_DEL ? "NULL" : data), ret); 1260 (action == BATADV_UEV_DEL ? "NULL" : data), ret);
1260 return ret; 1261 return ret;
1261 } 1262 }
1262 1263