batman-adv: Cache the type of wifi device for each hardif
[linux-2.6-block.git] / net / batman-adv / hard-interface.c
CommitLineData
0046b040 1/* Copyright (C) 2007-2016 B.A.T.M.A.N. contributors:
c6c8fea2
SE
2 *
3 * Marek Lindner, Simon Wunderlich
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
ebf38fb7 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
c6c8fea2
SE
16 */
17
c6c8fea2 18#include "hard-interface.h"
1e2c2a4f 19#include "main.h"
c6c8fea2 20
7a659d56 21#include <linux/atomic.h>
1e2c2a4f
SE
22#include <linux/bug.h>
23#include <linux/byteorder/generic.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
fcafa5e7 26#include <linux/if.h>
c6c8fea2 27#include <linux/if_arp.h>
af5d4f77 28#include <linux/if_ether.h>
1e2c2a4f 29#include <linux/kernel.h>
7a659d56 30#include <linux/kref.h>
1e2c2a4f
SE
31#include <linux/list.h>
32#include <linux/netdevice.h>
33#include <linux/printk.h>
34#include <linux/rculist.h>
35#include <linux/rtnetlink.h>
36#include <linux/slab.h>
cef63419 37#include <linux/spinlock.h>
275019d2
AL
38#include <net/net_namespace.h>
39#include <net/rtnetlink.h>
1e2c2a4f 40
a2d08166 41#include "bat_v.h"
1e2c2a4f
SE
42#include "bridge_loop_avoidance.h"
43#include "debugfs.h"
44#include "distributed-arp-table.h"
45#include "gateway_client.h"
ba412080 46#include "log.h"
1e2c2a4f
SE
47#include "originator.h"
48#include "packet.h"
49#include "send.h"
50#include "soft-interface.h"
51#include "sysfs.h"
52#include "translation-table.h"
c6c8fea2 53
140ed8e8
SE
54/**
55 * batadv_hardif_release - release hard interface from lists and queue for
56 * free after rcu grace period
7a659d56 57 * @ref: kref pointer of the hard interface
140ed8e8 58 */
7a659d56 59void batadv_hardif_release(struct kref *ref)
c6c8fea2 60{
7a659d56
SE
61 struct batadv_hard_iface *hard_iface;
62
63 hard_iface = container_of(ref, struct batadv_hard_iface, refcount);
e6c10f43 64 dev_put(hard_iface->net_dev);
140ed8e8
SE
65
66 kfree_rcu(hard_iface, rcu);
c6c8fea2
SE
67}
68
56303d34
SE
69struct batadv_hard_iface *
70batadv_hardif_get_by_netdev(const struct net_device *net_dev)
c6c8fea2 71{
56303d34 72 struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
73
74 rcu_read_lock();
3193e8fd 75 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e6c10f43 76 if (hard_iface->net_dev == net_dev &&
7a659d56 77 kref_get_unless_zero(&hard_iface->refcount))
c6c8fea2
SE
78 goto out;
79 }
80
e6c10f43 81 hard_iface = NULL;
c6c8fea2
SE
82
83out:
c6c8fea2 84 rcu_read_unlock();
e6c10f43 85 return hard_iface;
c6c8fea2
SE
86}
87
275019d2
AL
88/**
89 * batadv_getlink_net - return link net namespace (of use fallback)
90 * @netdev: net_device to check
91 * @fallback_net: return in case get_link_net is not available for @netdev
92 *
93 * Return: result of rtnl_link_ops->get_link_net or @fallback_net
94 */
88ffc7d0
SE
95static struct net *batadv_getlink_net(const struct net_device *netdev,
96 struct net *fallback_net)
275019d2
AL
97{
98 if (!netdev->rtnl_link_ops)
99 return fallback_net;
100
101 if (!netdev->rtnl_link_ops->get_link_net)
102 return fallback_net;
103
104 return netdev->rtnl_link_ops->get_link_net(netdev);
105}
106
1bc4e2b0
AL
107/**
108 * batadv_mutual_parents - check if two devices are each others parent
275019d2
AL
109 * @dev1: 1st net dev
110 * @net1: 1st devices netns
111 * @dev2: 2nd net dev
112 * @net2: 2nd devices netns
1bc4e2b0
AL
113 *
114 * veth devices come in pairs and each is the parent of the other!
115 *
116 * Return: true if the devices are each others parent, otherwise false
117 */
118static bool batadv_mutual_parents(const struct net_device *dev1,
88ffc7d0 119 struct net *net1,
275019d2 120 const struct net_device *dev2,
88ffc7d0 121 struct net *net2)
1bc4e2b0
AL
122{
123 int dev1_parent_iflink = dev_get_iflink(dev1);
124 int dev2_parent_iflink = dev_get_iflink(dev2);
275019d2
AL
125 const struct net *dev1_parent_net;
126 const struct net *dev2_parent_net;
127
128 dev1_parent_net = batadv_getlink_net(dev1, net1);
129 dev2_parent_net = batadv_getlink_net(dev2, net2);
1bc4e2b0
AL
130
131 if (!dev1_parent_iflink || !dev2_parent_iflink)
132 return false;
133
134 return (dev1_parent_iflink == dev2->ifindex) &&
275019d2
AL
135 (dev2_parent_iflink == dev1->ifindex) &&
136 net_eq(dev1_parent_net, net2) &&
137 net_eq(dev2_parent_net, net1);
1bc4e2b0
AL
138}
139
b7eddd0b
AQ
140/**
141 * batadv_is_on_batman_iface - check if a device is a batman iface descendant
142 * @net_dev: the device to check
143 *
144 * If the user creates any virtual device on top of a batman-adv interface, it
145 * is important to prevent this new interface to be used to create a new mesh
146 * network (this behaviour would lead to a batman-over-batman configuration).
147 * This function recursively checks all the fathers of the device passed as
148 * argument looking for a batman-adv soft interface.
149 *
62fe710f 150 * Return: true if the device is descendant of a batman-adv mesh interface (or
b7eddd0b
AQ
151 * if it is a batman-adv interface itself), false otherwise
152 */
153static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
154{
2cd45a06 155 struct net *net = dev_net(net_dev);
275019d2 156 struct net_device *parent_dev;
88ffc7d0 157 struct net *parent_net;
b7eddd0b
AQ
158 bool ret;
159
160 /* check if this is a batman-adv mesh interface */
161 if (batadv_softif_is_valid(net_dev))
162 return true;
163
164 /* no more parents..stop recursion */
a54acb3a
ND
165 if (dev_get_iflink(net_dev) == 0 ||
166 dev_get_iflink(net_dev) == net_dev->ifindex)
b7eddd0b
AQ
167 return false;
168
275019d2
AL
169 parent_net = batadv_getlink_net(net_dev, net);
170
b7eddd0b 171 /* recurse over the parent device */
275019d2
AL
172 parent_dev = __dev_get_by_index((struct net *)parent_net,
173 dev_get_iflink(net_dev));
b7eddd0b
AQ
174 /* if we got a NULL parent_dev there is something broken.. */
175 if (WARN(!parent_dev, "Cannot find parent device"))
176 return false;
177
275019d2 178 if (batadv_mutual_parents(net_dev, net, parent_dev, parent_net))
1bc4e2b0
AL
179 return false;
180
b7eddd0b
AQ
181 ret = batadv_is_on_batman_iface(parent_dev);
182
b7eddd0b
AQ
183 return ret;
184}
185
4b426b10 186static bool batadv_is_valid_iface(const struct net_device *net_dev)
c6c8fea2
SE
187{
188 if (net_dev->flags & IFF_LOOPBACK)
4b426b10 189 return false;
c6c8fea2
SE
190
191 if (net_dev->type != ARPHRD_ETHER)
4b426b10 192 return false;
c6c8fea2
SE
193
194 if (net_dev->addr_len != ETH_ALEN)
4b426b10 195 return false;
c6c8fea2
SE
196
197 /* no batman over batman */
b7eddd0b 198 if (batadv_is_on_batman_iface(net_dev))
4b426b10 199 return false;
c6c8fea2 200
4b426b10 201 return true;
c6c8fea2
SE
202}
203
10b1bbb4
SE
204/**
205 * batadv_is_wext_netdev - check if the given net_device struct is a
206 * wext wifi interface
207 * @net_device: the device to check
208 *
209 * Return: true if the net device is a wext wireless device, false
210 * otherwise.
211 */
212static bool batadv_is_wext_netdev(struct net_device *net_device)
213{
214 if (!net_device)
215 return false;
216
217#ifdef CONFIG_WIRELESS_EXT
218 /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
219 * check for wireless_handlers != NULL
220 */
221 if (net_device->wireless_handlers)
222 return true;
223#endif
224
225 return false;
226}
227
f44a3ae9
ML
228/**
229 * batadv_is_cfg80211_netdev - check if the given net_device struct is a
230 * cfg80211 wifi interface
231 * @net_device: the device to check
232 *
233 * Return: true if the net device is a cfg80211 wireless device, false
234 * otherwise.
235 */
10b1bbb4 236static bool batadv_is_cfg80211_netdev(struct net_device *net_device)
f44a3ae9
ML
237{
238 if (!net_device)
239 return false;
240
241 /* cfg80211 drivers have to set ieee80211_ptr */
242 if (net_device->ieee80211_ptr)
243 return true;
244
245 return false;
246}
247
de68d100 248/**
10b1bbb4 249 * batadv_wifi_flags_evaluate - calculate wifi flags for net_device
de68d100
MS
250 * @net_device: the device to check
251 *
10b1bbb4
SE
252 * Return: batadv_hard_iface_wifi_flags flags of the device
253 */
254static u32 batadv_wifi_flags_evaluate(struct net_device *net_device)
255{
256 u32 wifi_flags = 0;
257
258 if (batadv_is_wext_netdev(net_device))
259 wifi_flags |= BATADV_HARDIF_WIFI_WEXT_DIRECT;
260
261 if (batadv_is_cfg80211_netdev(net_device))
262 wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
263
264 return wifi_flags;
265}
266
267/**
268 * batadv_is_cfg80211_hardif - check if the given hardif is a cfg80211 wifi
269 * interface
270 * @hard_iface: the device to check
271 *
272 * Return: true if the net device is a cfg80211 wireless device, false
273 * otherwise.
274 */
275bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface)
276{
277 u32 allowed_flags = 0;
278
279 allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
280
281 return !!(hard_iface->wifi_flags & allowed_flags);
282}
283
284/**
285 * batadv_is_wifi_hardif - check if the given hardif is a wifi interface
286 * @hard_iface: the device to check
287 *
62fe710f 288 * Return: true if the net device is a 802.11 wireless device, false otherwise.
de68d100 289 */
10b1bbb4 290bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface)
de68d100 291{
10b1bbb4 292 if (!hard_iface)
0c69aecc
AQ
293 return false;
294
10b1bbb4 295 return hard_iface->wifi_flags != 0;
de68d100
MS
296}
297
3111beed
LL
298/**
299 * batadv_hardif_no_broadcast - check whether (re)broadcast is necessary
300 * @if_outgoing: the outgoing interface checked and considered for (re)broadcast
301 * @orig_addr: the originator of this packet
302 * @orig_neigh: originator address of the forwarder we just got the packet from
303 * (NULL if we originated)
304 *
305 * Checks whether a packet needs to be (re)broadcasted on the given interface.
306 *
307 * Return:
308 * BATADV_HARDIF_BCAST_NORECIPIENT: No neighbor on interface
309 * BATADV_HARDIF_BCAST_DUPFWD: Just one neighbor, but it is the forwarder
310 * BATADV_HARDIF_BCAST_DUPORIG: Just one neighbor, but it is the originator
311 * BATADV_HARDIF_BCAST_OK: Several neighbors, must broadcast
312 */
313int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
314 u8 *orig_addr, u8 *orig_neigh)
315{
316 struct batadv_hardif_neigh_node *hardif_neigh;
317 struct hlist_node *first;
318 int ret = BATADV_HARDIF_BCAST_OK;
319
320 rcu_read_lock();
321
322 /* 0 neighbors -> no (re)broadcast */
323 first = rcu_dereference(hlist_first_rcu(&if_outgoing->neigh_list));
324 if (!first) {
325 ret = BATADV_HARDIF_BCAST_NORECIPIENT;
326 goto out;
327 }
328
329 /* >1 neighbors -> (re)brodcast */
330 if (rcu_dereference(hlist_next_rcu(first)))
331 goto out;
332
333 hardif_neigh = hlist_entry(first, struct batadv_hardif_neigh_node,
334 list);
335
336 /* 1 neighbor, is the originator -> no rebroadcast */
337 if (orig_addr && batadv_compare_eth(hardif_neigh->orig, orig_addr)) {
338 ret = BATADV_HARDIF_BCAST_DUPORIG;
339 /* 1 neighbor, is the one we received from -> no rebroadcast */
340 } else if (orig_neigh &&
341 batadv_compare_eth(hardif_neigh->orig, orig_neigh)) {
342 ret = BATADV_HARDIF_BCAST_DUPFWD;
343 }
344
345out:
346 rcu_read_unlock();
347 return ret;
348}
349
56303d34 350static struct batadv_hard_iface *
18a1cb6e 351batadv_hardif_get_active(const struct net_device *soft_iface)
c6c8fea2 352{
56303d34 353 struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
354
355 rcu_read_lock();
3193e8fd 356 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e6c10f43 357 if (hard_iface->soft_iface != soft_iface)
c6c8fea2
SE
358 continue;
359
e9a4f295 360 if (hard_iface->if_status == BATADV_IF_ACTIVE &&
7a659d56 361 kref_get_unless_zero(&hard_iface->refcount))
c6c8fea2
SE
362 goto out;
363 }
364
e6c10f43 365 hard_iface = NULL;
c6c8fea2
SE
366
367out:
c6c8fea2 368 rcu_read_unlock();
e6c10f43 369 return hard_iface;
c6c8fea2
SE
370}
371
56303d34
SE
372static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
373 struct batadv_hard_iface *oldif)
c6c8fea2 374{
56303d34 375 struct batadv_hard_iface *primary_if;
32ae9b22 376
e5d89254 377 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22
ML
378 if (!primary_if)
379 goto out;
c6c8fea2 380
785ea114 381 batadv_dat_init_own_addr(bat_priv, primary_if);
08adf151 382 batadv_bla_update_orig_address(bat_priv, primary_if, oldif);
32ae9b22
ML
383out:
384 if (primary_if)
82047ad7 385 batadv_hardif_put(primary_if);
c6c8fea2
SE
386}
387
56303d34
SE
388static void batadv_primary_if_select(struct batadv_priv *bat_priv,
389 struct batadv_hard_iface *new_hard_iface)
c6c8fea2 390{
56303d34 391 struct batadv_hard_iface *curr_hard_iface;
c6c8fea2 392
c3caf519 393 ASSERT_RTNL();
c6c8fea2 394
17a86915
SE
395 if (new_hard_iface)
396 kref_get(&new_hard_iface->refcount);
c6c8fea2 397
728cbc6a 398 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1);
32ae9b22 399 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
c6c8fea2 400
32ae9b22 401 if (!new_hard_iface)
23721387 402 goto out;
32ae9b22 403
29824a55 404 bat_priv->algo_ops->iface.primary_set(new_hard_iface);
18a1cb6e 405 batadv_primary_if_update_addr(bat_priv, curr_hard_iface);
23721387
SW
406
407out:
408 if (curr_hard_iface)
82047ad7 409 batadv_hardif_put(curr_hard_iface);
c6c8fea2
SE
410}
411
56303d34
SE
412static bool
413batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface)
c6c8fea2 414{
e6c10f43 415 if (hard_iface->net_dev->flags & IFF_UP)
c6c8fea2
SE
416 return true;
417
418 return false;
419}
420
18a1cb6e 421static void batadv_check_known_mac_addr(const struct net_device *net_dev)
c6c8fea2 422{
56303d34 423 const struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
424
425 rcu_read_lock();
3193e8fd 426 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e9a4f295
SE
427 if ((hard_iface->if_status != BATADV_IF_ACTIVE) &&
428 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED))
c6c8fea2
SE
429 continue;
430
e6c10f43 431 if (hard_iface->net_dev == net_dev)
c6c8fea2
SE
432 continue;
433
1eda58bf
SE
434 if (!batadv_compare_eth(hard_iface->net_dev->dev_addr,
435 net_dev->dev_addr))
c6c8fea2
SE
436 continue;
437
67969581
SE
438 pr_warn("The newly added mac address (%pM) already exists on: %s\n",
439 net_dev->dev_addr, hard_iface->net_dev->name);
440 pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
c6c8fea2
SE
441 }
442 rcu_read_unlock();
443}
444
7bca68c7
SE
445/**
446 * batadv_hardif_recalc_extra_skbroom() - Recalculate skbuff extra head/tailroom
447 * @soft_iface: netdev struct of the mesh interface
448 */
449static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface)
450{
451 const struct batadv_hard_iface *hard_iface;
452 unsigned short lower_header_len = ETH_HLEN;
453 unsigned short lower_headroom = 0;
454 unsigned short lower_tailroom = 0;
455 unsigned short needed_headroom;
456
457 rcu_read_lock();
458 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
459 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
460 continue;
461
462 if (hard_iface->soft_iface != soft_iface)
463 continue;
464
465 lower_header_len = max_t(unsigned short, lower_header_len,
466 hard_iface->net_dev->hard_header_len);
467
468 lower_headroom = max_t(unsigned short, lower_headroom,
469 hard_iface->net_dev->needed_headroom);
470
471 lower_tailroom = max_t(unsigned short, lower_tailroom,
472 hard_iface->net_dev->needed_tailroom);
473 }
474 rcu_read_unlock();
475
476 needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN);
477 needed_headroom += batadv_max_header_len();
478
479 soft_iface->needed_headroom = needed_headroom;
480 soft_iface->needed_tailroom = lower_tailroom;
481}
482
9563877e 483int batadv_hardif_min_mtu(struct net_device *soft_iface)
c6c8fea2 484{
a19d3d85 485 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
56303d34 486 const struct batadv_hard_iface *hard_iface;
930cd6e4 487 int min_mtu = INT_MAX;
c6c8fea2
SE
488
489 rcu_read_lock();
3193e8fd 490 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e9a4f295
SE
491 if ((hard_iface->if_status != BATADV_IF_ACTIVE) &&
492 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED))
c6c8fea2
SE
493 continue;
494
e6c10f43 495 if (hard_iface->soft_iface != soft_iface)
c6c8fea2
SE
496 continue;
497
a19d3d85 498 min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
c6c8fea2
SE
499 }
500 rcu_read_unlock();
a19d3d85 501
a19d3d85
ML
502 if (atomic_read(&bat_priv->fragmentation) == 0)
503 goto out;
504
505 /* with fragmentation enabled the maximum size of internally generated
506 * packets such as translation table exchanges or tvlv containers, etc
507 * has to be calculated
508 */
509 min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
510 min_mtu -= sizeof(struct batadv_frag_packet);
511 min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
a19d3d85 512
c6c8fea2 513out:
930cd6e4
AQ
514 /* report to the other components the maximum amount of bytes that
515 * batman-adv can send over the wire (without considering the payload
516 * overhead). For example, this value is used by TT to compute the
517 * maximum local table table size
518 */
519 atomic_set(&bat_priv->packet_size_max, min_mtu);
520
521 /* the real soft-interface MTU is computed by removing the payload
522 * overhead from the maximum amount of bytes that was just computed.
523 *
524 * However batman-adv does not support MTUs bigger than ETH_DATA_LEN
525 */
526 return min_t(int, min_mtu - batadv_max_header_len(), ETH_DATA_LEN);
c6c8fea2
SE
527}
528
529/* adjusts the MTU if a new interface with a smaller MTU appeared. */
9563877e 530void batadv_update_min_mtu(struct net_device *soft_iface)
c6c8fea2 531{
a19d3d85 532 soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
c6c8fea2 533
a19d3d85
ML
534 /* Check if the local translate table should be cleaned up to match a
535 * new (and smaller) MTU.
536 */
537 batadv_tt_local_resize_to_mtu(soft_iface);
c6c8fea2
SE
538}
539
56303d34
SE
540static void
541batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface)
c6c8fea2 542{
56303d34
SE
543 struct batadv_priv *bat_priv;
544 struct batadv_hard_iface *primary_if = NULL;
c6c8fea2 545
e9a4f295 546 if (hard_iface->if_status != BATADV_IF_INACTIVE)
32ae9b22 547 goto out;
c6c8fea2 548
e6c10f43 549 bat_priv = netdev_priv(hard_iface->soft_iface);
c6c8fea2 550
29824a55 551 bat_priv->algo_ops->iface.update_mac(hard_iface);
e9a4f295 552 hard_iface->if_status = BATADV_IF_TO_BE_ACTIVATED;
c6c8fea2 553
9cfc7bd6 554 /* the first active interface becomes our primary interface or
015758d0 555 * the next active interface after the old primary interface was removed
c6c8fea2 556 */
e5d89254 557 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22 558 if (!primary_if)
18a1cb6e 559 batadv_primary_if_select(bat_priv, hard_iface);
c6c8fea2 560
3e34819e
SE
561 batadv_info(hard_iface->soft_iface, "Interface activated: %s\n",
562 hard_iface->net_dev->name);
c6c8fea2 563
9563877e 564 batadv_update_min_mtu(hard_iface->soft_iface);
32ae9b22 565
29824a55
AQ
566 if (bat_priv->algo_ops->iface.activate)
567 bat_priv->algo_ops->iface.activate(hard_iface);
b6cf5d49 568
32ae9b22
ML
569out:
570 if (primary_if)
82047ad7 571 batadv_hardif_put(primary_if);
c6c8fea2
SE
572}
573
56303d34
SE
574static void
575batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
c6c8fea2 576{
e9a4f295
SE
577 if ((hard_iface->if_status != BATADV_IF_ACTIVE) &&
578 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED))
c6c8fea2
SE
579 return;
580
e9a4f295 581 hard_iface->if_status = BATADV_IF_INACTIVE;
c6c8fea2 582
3e34819e
SE
583 batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n",
584 hard_iface->net_dev->name);
c6c8fea2 585
9563877e 586 batadv_update_min_mtu(hard_iface->soft_iface);
c6c8fea2
SE
587}
588
cb4b0d48
AQ
589/**
590 * batadv_master_del_slave - remove hard_iface from the current master interface
591 * @slave: the interface enslaved in another master
592 * @master: the master from which slave has to be removed
593 *
594 * Invoke ndo_del_slave on master passing slave as argument. In this way slave
595 * is free'd and master can correctly change its internal state.
62fe710f
SE
596 *
597 * Return: 0 on success, a negative value representing the error otherwise
cb4b0d48
AQ
598 */
599static int batadv_master_del_slave(struct batadv_hard_iface *slave,
600 struct net_device *master)
601{
602 int ret;
603
604 if (!master)
605 return 0;
606
607 ret = -EBUSY;
608 if (master->netdev_ops->ndo_del_slave)
609 ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev);
610
611 return ret;
612}
613
56303d34 614int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
2cd45a06 615 struct net *net, const char *iface_name)
c6c8fea2 616{
56303d34 617 struct batadv_priv *bat_priv;
cb4b0d48 618 struct net_device *soft_iface, *master;
293e9338 619 __be16 ethertype = htons(ETH_P_BATMAN);
411d6ed9 620 int max_header_len = batadv_max_header_len();
e44d8fe2 621 int ret;
c6c8fea2 622
e9a4f295 623 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
c6c8fea2
SE
624 goto out;
625
17a86915 626 kref_get(&hard_iface->refcount);
ed75ccbe 627
2cd45a06 628 soft_iface = dev_get_by_name(net, iface_name);
c6c8fea2 629
e44d8fe2 630 if (!soft_iface) {
2cd45a06 631 soft_iface = batadv_softif_create(net, iface_name);
c6c8fea2 632
e44d8fe2
SE
633 if (!soft_iface) {
634 ret = -ENOMEM;
c6c8fea2 635 goto err;
e44d8fe2 636 }
c6c8fea2
SE
637
638 /* dev_get_by_name() increases the reference counter for us */
e44d8fe2
SE
639 dev_hold(soft_iface);
640 }
641
04b482a2 642 if (!batadv_softif_is_valid(soft_iface)) {
86ceb360 643 pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
e44d8fe2 644 soft_iface->name);
e44d8fe2 645 ret = -EINVAL;
77af7575 646 goto err_dev;
c6c8fea2
SE
647 }
648
cb4b0d48
AQ
649 /* check if the interface is enslaved in another virtual one and
650 * in that case unlink it first
651 */
652 master = netdev_master_upper_dev_get(hard_iface->net_dev);
653 ret = batadv_master_del_slave(hard_iface, master);
654 if (ret)
655 goto err_dev;
656
e44d8fe2 657 hard_iface->soft_iface = soft_iface;
e6c10f43 658 bat_priv = netdev_priv(hard_iface->soft_iface);
d0b9fd89 659
6dffb044 660 ret = netdev_master_upper_dev_link(hard_iface->net_dev,
29bf24af 661 soft_iface, NULL, NULL);
3dbd550b
SE
662 if (ret)
663 goto err_dev;
664
29824a55 665 ret = bat_priv->algo_ops->iface.enable(hard_iface);
5346c35e 666 if (ret < 0)
3dbd550b 667 goto err_upper;
c6c8fea2 668
e6c10f43 669 hard_iface->if_num = bat_priv->num_ifaces;
c6c8fea2 670 bat_priv->num_ifaces++;
e9a4f295 671 hard_iface->if_status = BATADV_IF_INACTIVE;
62446307
SW
672 ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces);
673 if (ret < 0) {
29824a55 674 bat_priv->algo_ops->iface.disable(hard_iface);
62446307
SW
675 bat_priv->num_ifaces--;
676 hard_iface->if_status = BATADV_IF_NOT_IN_USE;
3dbd550b 677 goto err_upper;
62446307 678 }
c6c8fea2 679
d7d6de95 680 kref_get(&hard_iface->refcount);
7e071c79 681 hard_iface->batman_adv_ptype.type = ethertype;
3193e8fd 682 hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
e6c10f43
ML
683 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
684 dev_add_pack(&hard_iface->batman_adv_ptype);
c6c8fea2 685
3e34819e
SE
686 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
687 hard_iface->net_dev->name);
c6c8fea2 688
0aca2369 689 if (atomic_read(&bat_priv->fragmentation) &&
411d6ed9 690 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
3e34819e 691 batadv_info(hard_iface->soft_iface,
411d6ed9 692 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %i would solve the problem.\n",
3e34819e 693 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
411d6ed9 694 ETH_DATA_LEN + max_header_len);
c6c8fea2 695
0aca2369 696 if (!atomic_read(&bat_priv->fragmentation) &&
411d6ed9 697 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
3e34819e 698 batadv_info(hard_iface->soft_iface,
411d6ed9 699 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %i.\n",
3e34819e 700 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
411d6ed9 701 ETH_DATA_LEN + max_header_len);
c6c8fea2 702
18a1cb6e
SE
703 if (batadv_hardif_is_iface_up(hard_iface))
704 batadv_hardif_activate_interface(hard_iface);
c6c8fea2 705 else
3e34819e
SE
706 batadv_err(hard_iface->soft_iface,
707 "Not using interface %s (retrying later): interface not active\n",
708 hard_iface->net_dev->name);
c6c8fea2 709
7bca68c7
SE
710 batadv_hardif_recalc_extra_skbroom(soft_iface);
711
c6c8fea2
SE
712out:
713 return 0;
714
3dbd550b
SE
715err_upper:
716 netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface);
77af7575 717err_dev:
3dbd550b 718 hard_iface->soft_iface = NULL;
77af7575 719 dev_put(soft_iface);
c6c8fea2 720err:
82047ad7 721 batadv_hardif_put(hard_iface);
e44d8fe2 722 return ret;
c6c8fea2
SE
723}
724
a15fd361
SE
725void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
726 enum batadv_hard_if_cleanup autodel)
c6c8fea2 727{
56303d34
SE
728 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
729 struct batadv_hard_iface *primary_if = NULL;
c6c8fea2 730
f2d23861 731 batadv_hardif_deactivate_interface(hard_iface);
c6c8fea2 732
e9a4f295 733 if (hard_iface->if_status != BATADV_IF_INACTIVE)
32ae9b22 734 goto out;
c6c8fea2 735
3e34819e
SE
736 batadv_info(hard_iface->soft_iface, "Removing interface: %s\n",
737 hard_iface->net_dev->name);
e6c10f43 738 dev_remove_pack(&hard_iface->batman_adv_ptype);
d7d6de95 739 batadv_hardif_put(hard_iface);
c6c8fea2
SE
740
741 bat_priv->num_ifaces--;
7d211efc 742 batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces);
c6c8fea2 743
e5d89254 744 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22 745 if (hard_iface == primary_if) {
56303d34 746 struct batadv_hard_iface *new_if;
c6c8fea2 747
18a1cb6e
SE
748 new_if = batadv_hardif_get_active(hard_iface->soft_iface);
749 batadv_primary_if_select(bat_priv, new_if);
c6c8fea2
SE
750
751 if (new_if)
82047ad7 752 batadv_hardif_put(new_if);
c6c8fea2
SE
753 }
754
29824a55 755 bat_priv->algo_ops->iface.disable(hard_iface);
e9a4f295 756 hard_iface->if_status = BATADV_IF_NOT_IN_USE;
c6c8fea2 757
e6c10f43 758 /* delete all references to this hard_iface */
7d211efc 759 batadv_purge_orig_ref(bat_priv);
9455e34c 760 batadv_purge_outstanding_packets(bat_priv, hard_iface);
e6c10f43 761 dev_put(hard_iface->soft_iface);
c6c8fea2 762
a5256f7e 763 netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
7bca68c7 764 batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
a5256f7e 765
c6c8fea2 766 /* nobody uses this interface anymore */
8257f55a
AQ
767 if (!bat_priv->num_ifaces) {
768 batadv_gw_check_client_stop(bat_priv);
769
770 if (autodel == BATADV_IF_CLEANUP_AUTO)
771 batadv_softif_destroy_sysfs(hard_iface->soft_iface);
772 }
c6c8fea2 773
e6c10f43 774 hard_iface->soft_iface = NULL;
82047ad7 775 batadv_hardif_put(hard_iface);
32ae9b22
ML
776
777out:
778 if (primary_if)
82047ad7 779 batadv_hardif_put(primary_if);
c6c8fea2
SE
780}
781
56303d34 782static struct batadv_hard_iface *
18a1cb6e 783batadv_hardif_add_interface(struct net_device *net_dev)
c6c8fea2 784{
56303d34 785 struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
786 int ret;
787
c3caf519
SE
788 ASSERT_RTNL();
789
4b426b10 790 if (!batadv_is_valid_iface(net_dev))
c6c8fea2
SE
791 goto out;
792
793 dev_hold(net_dev);
794
7db3fc29 795 hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
320f422f 796 if (!hard_iface)
c6c8fea2 797 goto release_dev;
c6c8fea2 798
5853e22c 799 ret = batadv_sysfs_add_hardif(&hard_iface->hardif_obj, net_dev);
c6c8fea2
SE
800 if (ret)
801 goto free_if;
802
e6c10f43
ML
803 hard_iface->if_num = -1;
804 hard_iface->net_dev = net_dev;
805 hard_iface->soft_iface = NULL;
e9a4f295 806 hard_iface->if_status = BATADV_IF_NOT_IN_USE;
5bc7c1eb
SW
807
808 ret = batadv_debugfs_add_hardif(hard_iface);
809 if (ret)
810 goto free_sysfs;
811
e6c10f43 812 INIT_LIST_HEAD(&hard_iface->list);
cef63419 813 INIT_HLIST_HEAD(&hard_iface->neigh_list);
5bc44dc8 814
cef63419 815 spin_lock_init(&hard_iface->neigh_list_lock);
b2367e46 816 kref_init(&hard_iface->refcount);
cef63419 817
caf65bfc 818 hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
10b1bbb4
SE
819 hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
820 if (batadv_is_wifi_hardif(hard_iface))
caf65bfc
MS
821 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
822
7db682d1
ML
823 batadv_v_hardif_init(hard_iface);
824
18a1cb6e 825 batadv_check_known_mac_addr(hard_iface->net_dev);
b2367e46 826 kref_get(&hard_iface->refcount);
3193e8fd 827 list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
c6c8fea2 828
e6c10f43 829 return hard_iface;
c6c8fea2 830
5bc7c1eb
SW
831free_sysfs:
832 batadv_sysfs_del_hardif(&hard_iface->hardif_obj);
c6c8fea2 833free_if:
e6c10f43 834 kfree(hard_iface);
c6c8fea2
SE
835release_dev:
836 dev_put(net_dev);
837out:
838 return NULL;
839}
840
56303d34 841static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface)
c6c8fea2 842{
c3caf519
SE
843 ASSERT_RTNL();
844
c6c8fea2 845 /* first deactivate interface */
e9a4f295 846 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
a15fd361 847 batadv_hardif_disable_interface(hard_iface,
06d640c9 848 BATADV_IF_CLEANUP_KEEP);
c6c8fea2 849
e9a4f295 850 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
c6c8fea2
SE
851 return;
852
e9a4f295 853 hard_iface->if_status = BATADV_IF_TO_BE_REMOVED;
569c9850
SE
854 batadv_debugfs_del_hardif(hard_iface);
855 batadv_sysfs_del_hardif(&hard_iface->hardif_obj);
856 batadv_hardif_put(hard_iface);
c6c8fea2
SE
857}
858
9563877e 859void batadv_hardif_remove_interfaces(void)
c6c8fea2 860{
56303d34 861 struct batadv_hard_iface *hard_iface, *hard_iface_tmp;
c6c8fea2 862
c3caf519 863 rtnl_lock();
e6c10f43 864 list_for_each_entry_safe(hard_iface, hard_iface_tmp,
3193e8fd 865 &batadv_hardif_list, list) {
e6c10f43 866 list_del_rcu(&hard_iface->list);
18a1cb6e 867 batadv_hardif_remove_interface(hard_iface);
c6c8fea2
SE
868 }
869 rtnl_unlock();
870}
871
18a1cb6e
SE
872static int batadv_hard_if_event(struct notifier_block *this,
873 unsigned long event, void *ptr)
c6c8fea2 874{
351638e7 875 struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
56303d34
SE
876 struct batadv_hard_iface *hard_iface;
877 struct batadv_hard_iface *primary_if = NULL;
878 struct batadv_priv *bat_priv;
c6c8fea2 879
37130293
SE
880 if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
881 batadv_sysfs_add_meshif(net_dev);
5d2c05b2
AQ
882 bat_priv = netdev_priv(net_dev);
883 batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
37130293
SE
884 return NOTIFY_DONE;
885 }
886
56303d34 887 hard_iface = batadv_hardif_get_by_netdev(net_dev);
a1a66b11
AL
888 if (!hard_iface && (event == NETDEV_REGISTER ||
889 event == NETDEV_POST_TYPE_CHANGE))
18a1cb6e 890 hard_iface = batadv_hardif_add_interface(net_dev);
c6c8fea2 891
e6c10f43 892 if (!hard_iface)
c6c8fea2
SE
893 goto out;
894
895 switch (event) {
896 case NETDEV_UP:
18a1cb6e 897 batadv_hardif_activate_interface(hard_iface);
c6c8fea2
SE
898 break;
899 case NETDEV_GOING_DOWN:
900 case NETDEV_DOWN:
18a1cb6e 901 batadv_hardif_deactivate_interface(hard_iface);
c6c8fea2
SE
902 break;
903 case NETDEV_UNREGISTER:
a1a66b11 904 case NETDEV_PRE_TYPE_CHANGE:
e6c10f43 905 list_del_rcu(&hard_iface->list);
c6c8fea2 906
18a1cb6e 907 batadv_hardif_remove_interface(hard_iface);
c6c8fea2
SE
908 break;
909 case NETDEV_CHANGEMTU:
e6c10f43 910 if (hard_iface->soft_iface)
9563877e 911 batadv_update_min_mtu(hard_iface->soft_iface);
c6c8fea2
SE
912 break;
913 case NETDEV_CHANGEADDR:
e9a4f295 914 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
c6c8fea2
SE
915 goto hardif_put;
916
18a1cb6e 917 batadv_check_known_mac_addr(hard_iface->net_dev);
c6c8fea2 918
e6c10f43 919 bat_priv = netdev_priv(hard_iface->soft_iface);
29824a55 920 bat_priv->algo_ops->iface.update_mac(hard_iface);
01c4224b 921
e5d89254 922 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22
ML
923 if (!primary_if)
924 goto hardif_put;
925
926 if (hard_iface == primary_if)
18a1cb6e 927 batadv_primary_if_update_addr(bat_priv, NULL);
c6c8fea2
SE
928 break;
929 default:
930 break;
f81c6224 931 }
c6c8fea2
SE
932
933hardif_put:
82047ad7 934 batadv_hardif_put(hard_iface);
c6c8fea2 935out:
32ae9b22 936 if (primary_if)
82047ad7 937 batadv_hardif_put(primary_if);
c6c8fea2
SE
938 return NOTIFY_DONE;
939}
940
9563877e 941struct notifier_block batadv_hard_if_notifier = {
18a1cb6e 942 .notifier_call = batadv_hard_if_event,
c6c8fea2 943};