Merge branch 'stable/for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / net / batman-adv / hard-interface.c
CommitLineData
9f6446c7 1/* Copyright (C) 2007-2015 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
1e2c2a4f
SE
21#include <linux/bug.h>
22#include <linux/byteorder/generic.h>
23#include <linux/errno.h>
24#include <linux/fs.h>
c6c8fea2 25#include <linux/if_arp.h>
af5d4f77 26#include <linux/if_ether.h>
1e2c2a4f
SE
27#include <linux/if.h>
28#include <linux/kernel.h>
29#include <linux/list.h>
30#include <linux/netdevice.h>
31#include <linux/printk.h>
32#include <linux/rculist.h>
33#include <linux/rtnetlink.h>
34#include <linux/slab.h>
cef63419 35#include <linux/spinlock.h>
1e2c2a4f
SE
36#include <linux/workqueue.h>
37#include <net/net_namespace.h>
38
39#include "bridge_loop_avoidance.h"
40#include "debugfs.h"
41#include "distributed-arp-table.h"
42#include "gateway_client.h"
43#include "originator.h"
44#include "packet.h"
45#include "send.h"
46#include "soft-interface.h"
47#include "sysfs.h"
48#include "translation-table.h"
c6c8fea2 49
9563877e 50void batadv_hardif_free_rcu(struct rcu_head *rcu)
c6c8fea2 51{
56303d34 52 struct batadv_hard_iface *hard_iface;
c6c8fea2 53
56303d34 54 hard_iface = container_of(rcu, struct batadv_hard_iface, rcu);
e6c10f43
ML
55 dev_put(hard_iface->net_dev);
56 kfree(hard_iface);
c6c8fea2
SE
57}
58
56303d34
SE
59struct batadv_hard_iface *
60batadv_hardif_get_by_netdev(const struct net_device *net_dev)
c6c8fea2 61{
56303d34 62 struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
63
64 rcu_read_lock();
3193e8fd 65 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e6c10f43
ML
66 if (hard_iface->net_dev == net_dev &&
67 atomic_inc_not_zero(&hard_iface->refcount))
c6c8fea2
SE
68 goto out;
69 }
70
e6c10f43 71 hard_iface = NULL;
c6c8fea2
SE
72
73out:
c6c8fea2 74 rcu_read_unlock();
e6c10f43 75 return hard_iface;
c6c8fea2
SE
76}
77
1bc4e2b0
AL
78/**
79 * batadv_mutual_parents - check if two devices are each others parent
80 * @dev1: 1st net_device
81 * @dev2: 2nd net_device
82 *
83 * veth devices come in pairs and each is the parent of the other!
84 *
85 * Return: true if the devices are each others parent, otherwise false
86 */
87static bool batadv_mutual_parents(const struct net_device *dev1,
88 const struct net_device *dev2)
89{
90 int dev1_parent_iflink = dev_get_iflink(dev1);
91 int dev2_parent_iflink = dev_get_iflink(dev2);
92
93 if (!dev1_parent_iflink || !dev2_parent_iflink)
94 return false;
95
96 return (dev1_parent_iflink == dev2->ifindex) &&
97 (dev2_parent_iflink == dev1->ifindex);
98}
99
b7eddd0b
AQ
100/**
101 * batadv_is_on_batman_iface - check if a device is a batman iface descendant
102 * @net_dev: the device to check
103 *
104 * If the user creates any virtual device on top of a batman-adv interface, it
105 * is important to prevent this new interface to be used to create a new mesh
106 * network (this behaviour would lead to a batman-over-batman configuration).
107 * This function recursively checks all the fathers of the device passed as
108 * argument looking for a batman-adv soft interface.
109 *
110 * Returns true if the device is descendant of a batman-adv mesh interface (or
111 * if it is a batman-adv interface itself), false otherwise
112 */
113static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
114{
115 struct net_device *parent_dev;
116 bool ret;
117
118 /* check if this is a batman-adv mesh interface */
119 if (batadv_softif_is_valid(net_dev))
120 return true;
121
122 /* no more parents..stop recursion */
a54acb3a
ND
123 if (dev_get_iflink(net_dev) == 0 ||
124 dev_get_iflink(net_dev) == net_dev->ifindex)
b7eddd0b
AQ
125 return false;
126
127 /* recurse over the parent device */
a54acb3a 128 parent_dev = __dev_get_by_index(&init_net, dev_get_iflink(net_dev));
b7eddd0b
AQ
129 /* if we got a NULL parent_dev there is something broken.. */
130 if (WARN(!parent_dev, "Cannot find parent device"))
131 return false;
132
1bc4e2b0
AL
133 if (batadv_mutual_parents(net_dev, parent_dev))
134 return false;
135
b7eddd0b
AQ
136 ret = batadv_is_on_batman_iface(parent_dev);
137
b7eddd0b
AQ
138 return ret;
139}
140
18a1cb6e 141static int batadv_is_valid_iface(const struct net_device *net_dev)
c6c8fea2
SE
142{
143 if (net_dev->flags & IFF_LOOPBACK)
144 return 0;
145
146 if (net_dev->type != ARPHRD_ETHER)
147 return 0;
148
149 if (net_dev->addr_len != ETH_ALEN)
150 return 0;
151
152 /* no batman over batman */
b7eddd0b 153 if (batadv_is_on_batman_iface(net_dev))
c6c8fea2 154 return 0;
c6c8fea2 155
c6c8fea2
SE
156 return 1;
157}
158
de68d100
MS
159/**
160 * batadv_is_wifi_netdev - check if the given net_device struct is a wifi
161 * interface
162 * @net_device: the device to check
163 *
164 * Returns true if the net device is a 802.11 wireless device, false otherwise.
165 */
0c69aecc 166bool batadv_is_wifi_netdev(struct net_device *net_device)
de68d100 167{
0c69aecc
AQ
168 if (!net_device)
169 return false;
170
de68d100
MS
171#ifdef CONFIG_WIRELESS_EXT
172 /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
173 * check for wireless_handlers != NULL
174 */
175 if (net_device->wireless_handlers)
176 return true;
177#endif
178
179 /* cfg80211 drivers have to set ieee80211_ptr */
180 if (net_device->ieee80211_ptr)
181 return true;
182
183 return false;
184}
185
56303d34 186static struct batadv_hard_iface *
18a1cb6e 187batadv_hardif_get_active(const struct net_device *soft_iface)
c6c8fea2 188{
56303d34 189 struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
190
191 rcu_read_lock();
3193e8fd 192 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e6c10f43 193 if (hard_iface->soft_iface != soft_iface)
c6c8fea2
SE
194 continue;
195
e9a4f295 196 if (hard_iface->if_status == BATADV_IF_ACTIVE &&
e6c10f43 197 atomic_inc_not_zero(&hard_iface->refcount))
c6c8fea2
SE
198 goto out;
199 }
200
e6c10f43 201 hard_iface = NULL;
c6c8fea2
SE
202
203out:
c6c8fea2 204 rcu_read_unlock();
e6c10f43 205 return hard_iface;
c6c8fea2
SE
206}
207
56303d34
SE
208static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
209 struct batadv_hard_iface *oldif)
c6c8fea2 210{
56303d34 211 struct batadv_hard_iface *primary_if;
32ae9b22 212
e5d89254 213 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22
ML
214 if (!primary_if)
215 goto out;
c6c8fea2 216
785ea114 217 batadv_dat_init_own_addr(bat_priv, primary_if);
08adf151 218 batadv_bla_update_orig_address(bat_priv, primary_if, oldif);
32ae9b22
ML
219out:
220 if (primary_if)
e5d89254 221 batadv_hardif_free_ref(primary_if);
c6c8fea2
SE
222}
223
56303d34
SE
224static void batadv_primary_if_select(struct batadv_priv *bat_priv,
225 struct batadv_hard_iface *new_hard_iface)
c6c8fea2 226{
56303d34 227 struct batadv_hard_iface *curr_hard_iface;
c6c8fea2 228
c3caf519 229 ASSERT_RTNL();
c6c8fea2 230
32ae9b22
ML
231 if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
232 new_hard_iface = NULL;
c6c8fea2 233
728cbc6a 234 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1);
32ae9b22 235 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
c6c8fea2 236
32ae9b22 237 if (!new_hard_iface)
23721387 238 goto out;
32ae9b22 239
cd8b78e7 240 bat_priv->bat_algo_ops->bat_primary_iface_set(new_hard_iface);
18a1cb6e 241 batadv_primary_if_update_addr(bat_priv, curr_hard_iface);
23721387
SW
242
243out:
244 if (curr_hard_iface)
e5d89254 245 batadv_hardif_free_ref(curr_hard_iface);
c6c8fea2
SE
246}
247
56303d34
SE
248static bool
249batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface)
c6c8fea2 250{
e6c10f43 251 if (hard_iface->net_dev->flags & IFF_UP)
c6c8fea2
SE
252 return true;
253
254 return false;
255}
256
18a1cb6e 257static void batadv_check_known_mac_addr(const struct net_device *net_dev)
c6c8fea2 258{
56303d34 259 const struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
260
261 rcu_read_lock();
3193e8fd 262 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e9a4f295
SE
263 if ((hard_iface->if_status != BATADV_IF_ACTIVE) &&
264 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED))
c6c8fea2
SE
265 continue;
266
e6c10f43 267 if (hard_iface->net_dev == net_dev)
c6c8fea2
SE
268 continue;
269
1eda58bf
SE
270 if (!batadv_compare_eth(hard_iface->net_dev->dev_addr,
271 net_dev->dev_addr))
c6c8fea2
SE
272 continue;
273
67969581
SE
274 pr_warn("The newly added mac address (%pM) already exists on: %s\n",
275 net_dev->dev_addr, hard_iface->net_dev->name);
276 pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
c6c8fea2
SE
277 }
278 rcu_read_unlock();
279}
280
7bca68c7
SE
281/**
282 * batadv_hardif_recalc_extra_skbroom() - Recalculate skbuff extra head/tailroom
283 * @soft_iface: netdev struct of the mesh interface
284 */
285static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface)
286{
287 const struct batadv_hard_iface *hard_iface;
288 unsigned short lower_header_len = ETH_HLEN;
289 unsigned short lower_headroom = 0;
290 unsigned short lower_tailroom = 0;
291 unsigned short needed_headroom;
292
293 rcu_read_lock();
294 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
295 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
296 continue;
297
298 if (hard_iface->soft_iface != soft_iface)
299 continue;
300
301 lower_header_len = max_t(unsigned short, lower_header_len,
302 hard_iface->net_dev->hard_header_len);
303
304 lower_headroom = max_t(unsigned short, lower_headroom,
305 hard_iface->net_dev->needed_headroom);
306
307 lower_tailroom = max_t(unsigned short, lower_tailroom,
308 hard_iface->net_dev->needed_tailroom);
309 }
310 rcu_read_unlock();
311
312 needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN);
313 needed_headroom += batadv_max_header_len();
314
315 soft_iface->needed_headroom = needed_headroom;
316 soft_iface->needed_tailroom = lower_tailroom;
317}
318
9563877e 319int batadv_hardif_min_mtu(struct net_device *soft_iface)
c6c8fea2 320{
a19d3d85 321 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
56303d34 322 const struct batadv_hard_iface *hard_iface;
930cd6e4 323 int min_mtu = INT_MAX;
c6c8fea2
SE
324
325 rcu_read_lock();
3193e8fd 326 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
e9a4f295
SE
327 if ((hard_iface->if_status != BATADV_IF_ACTIVE) &&
328 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED))
c6c8fea2
SE
329 continue;
330
e6c10f43 331 if (hard_iface->soft_iface != soft_iface)
c6c8fea2
SE
332 continue;
333
a19d3d85 334 min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
c6c8fea2
SE
335 }
336 rcu_read_unlock();
a19d3d85 337
a19d3d85
ML
338 if (atomic_read(&bat_priv->fragmentation) == 0)
339 goto out;
340
341 /* with fragmentation enabled the maximum size of internally generated
342 * packets such as translation table exchanges or tvlv containers, etc
343 * has to be calculated
344 */
345 min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
346 min_mtu -= sizeof(struct batadv_frag_packet);
347 min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
a19d3d85 348
c6c8fea2 349out:
930cd6e4
AQ
350 /* report to the other components the maximum amount of bytes that
351 * batman-adv can send over the wire (without considering the payload
352 * overhead). For example, this value is used by TT to compute the
353 * maximum local table table size
354 */
355 atomic_set(&bat_priv->packet_size_max, min_mtu);
356
357 /* the real soft-interface MTU is computed by removing the payload
358 * overhead from the maximum amount of bytes that was just computed.
359 *
360 * However batman-adv does not support MTUs bigger than ETH_DATA_LEN
361 */
362 return min_t(int, min_mtu - batadv_max_header_len(), ETH_DATA_LEN);
c6c8fea2
SE
363}
364
365/* adjusts the MTU if a new interface with a smaller MTU appeared. */
9563877e 366void batadv_update_min_mtu(struct net_device *soft_iface)
c6c8fea2 367{
a19d3d85 368 soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
c6c8fea2 369
a19d3d85
ML
370 /* Check if the local translate table should be cleaned up to match a
371 * new (and smaller) MTU.
372 */
373 batadv_tt_local_resize_to_mtu(soft_iface);
c6c8fea2
SE
374}
375
56303d34
SE
376static void
377batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface)
c6c8fea2 378{
56303d34
SE
379 struct batadv_priv *bat_priv;
380 struct batadv_hard_iface *primary_if = NULL;
c6c8fea2 381
e9a4f295 382 if (hard_iface->if_status != BATADV_IF_INACTIVE)
32ae9b22 383 goto out;
c6c8fea2 384
e6c10f43 385 bat_priv = netdev_priv(hard_iface->soft_iface);
c6c8fea2 386
c3229398 387 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface);
e9a4f295 388 hard_iface->if_status = BATADV_IF_TO_BE_ACTIVATED;
c6c8fea2 389
9cfc7bd6 390 /* the first active interface becomes our primary interface or
015758d0 391 * the next active interface after the old primary interface was removed
c6c8fea2 392 */
e5d89254 393 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22 394 if (!primary_if)
18a1cb6e 395 batadv_primary_if_select(bat_priv, hard_iface);
c6c8fea2 396
3e34819e
SE
397 batadv_info(hard_iface->soft_iface, "Interface activated: %s\n",
398 hard_iface->net_dev->name);
c6c8fea2 399
9563877e 400 batadv_update_min_mtu(hard_iface->soft_iface);
32ae9b22
ML
401
402out:
403 if (primary_if)
e5d89254 404 batadv_hardif_free_ref(primary_if);
c6c8fea2
SE
405}
406
56303d34
SE
407static void
408batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
c6c8fea2 409{
e9a4f295
SE
410 if ((hard_iface->if_status != BATADV_IF_ACTIVE) &&
411 (hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED))
c6c8fea2
SE
412 return;
413
e9a4f295 414 hard_iface->if_status = BATADV_IF_INACTIVE;
c6c8fea2 415
3e34819e
SE
416 batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n",
417 hard_iface->net_dev->name);
c6c8fea2 418
9563877e 419 batadv_update_min_mtu(hard_iface->soft_iface);
c6c8fea2
SE
420}
421
cb4b0d48
AQ
422/**
423 * batadv_master_del_slave - remove hard_iface from the current master interface
424 * @slave: the interface enslaved in another master
425 * @master: the master from which slave has to be removed
426 *
427 * Invoke ndo_del_slave on master passing slave as argument. In this way slave
428 * is free'd and master can correctly change its internal state.
429 * Return 0 on success, a negative value representing the error otherwise
430 */
431static int batadv_master_del_slave(struct batadv_hard_iface *slave,
432 struct net_device *master)
433{
434 int ret;
435
436 if (!master)
437 return 0;
438
439 ret = -EBUSY;
440 if (master->netdev_ops->ndo_del_slave)
441 ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev);
442
443 return ret;
444}
445
56303d34 446int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
9563877e 447 const char *iface_name)
c6c8fea2 448{
56303d34 449 struct batadv_priv *bat_priv;
cb4b0d48 450 struct net_device *soft_iface, *master;
293e9338 451 __be16 ethertype = htons(ETH_P_BATMAN);
411d6ed9 452 int max_header_len = batadv_max_header_len();
e44d8fe2 453 int ret;
c6c8fea2 454
e9a4f295 455 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
c6c8fea2
SE
456 goto out;
457
e6c10f43 458 if (!atomic_inc_not_zero(&hard_iface->refcount))
ed75ccbe
ML
459 goto out;
460
e44d8fe2 461 soft_iface = dev_get_by_name(&init_net, iface_name);
c6c8fea2 462
e44d8fe2 463 if (!soft_iface) {
04b482a2 464 soft_iface = batadv_softif_create(iface_name);
c6c8fea2 465
e44d8fe2
SE
466 if (!soft_iface) {
467 ret = -ENOMEM;
c6c8fea2 468 goto err;
e44d8fe2 469 }
c6c8fea2
SE
470
471 /* dev_get_by_name() increases the reference counter for us */
e44d8fe2
SE
472 dev_hold(soft_iface);
473 }
474
04b482a2 475 if (!batadv_softif_is_valid(soft_iface)) {
86ceb360 476 pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
e44d8fe2 477 soft_iface->name);
e44d8fe2 478 ret = -EINVAL;
77af7575 479 goto err_dev;
c6c8fea2
SE
480 }
481
cb4b0d48
AQ
482 /* check if the interface is enslaved in another virtual one and
483 * in that case unlink it first
484 */
485 master = netdev_master_upper_dev_get(hard_iface->net_dev);
486 ret = batadv_master_del_slave(hard_iface, master);
487 if (ret)
488 goto err_dev;
489
e44d8fe2 490 hard_iface->soft_iface = soft_iface;
e6c10f43 491 bat_priv = netdev_priv(hard_iface->soft_iface);
d0b9fd89 492
6dffb044 493 ret = netdev_master_upper_dev_link(hard_iface->net_dev,
29bf24af 494 soft_iface, NULL, NULL);
3dbd550b
SE
495 if (ret)
496 goto err_dev;
497
77af7575 498 ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface);
5346c35e 499 if (ret < 0)
3dbd550b 500 goto err_upper;
c6c8fea2 501
e6c10f43 502 hard_iface->if_num = bat_priv->num_ifaces;
c6c8fea2 503 bat_priv->num_ifaces++;
e9a4f295 504 hard_iface->if_status = BATADV_IF_INACTIVE;
62446307
SW
505 ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces);
506 if (ret < 0) {
507 bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
508 bat_priv->num_ifaces--;
509 hard_iface->if_status = BATADV_IF_NOT_IN_USE;
3dbd550b 510 goto err_upper;
62446307 511 }
c6c8fea2 512
7e071c79 513 hard_iface->batman_adv_ptype.type = ethertype;
3193e8fd 514 hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
e6c10f43
ML
515 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
516 dev_add_pack(&hard_iface->batman_adv_ptype);
c6c8fea2 517
3e34819e
SE
518 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
519 hard_iface->net_dev->name);
c6c8fea2 520
0aca2369 521 if (atomic_read(&bat_priv->fragmentation) &&
411d6ed9 522 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
3e34819e 523 batadv_info(hard_iface->soft_iface,
411d6ed9 524 "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 525 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
411d6ed9 526 ETH_DATA_LEN + max_header_len);
c6c8fea2 527
0aca2369 528 if (!atomic_read(&bat_priv->fragmentation) &&
411d6ed9 529 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
3e34819e 530 batadv_info(hard_iface->soft_iface,
411d6ed9 531 "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 532 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
411d6ed9 533 ETH_DATA_LEN + max_header_len);
c6c8fea2 534
18a1cb6e
SE
535 if (batadv_hardif_is_iface_up(hard_iface))
536 batadv_hardif_activate_interface(hard_iface);
c6c8fea2 537 else
3e34819e
SE
538 batadv_err(hard_iface->soft_iface,
539 "Not using interface %s (retrying later): interface not active\n",
540 hard_iface->net_dev->name);
c6c8fea2 541
7bca68c7
SE
542 batadv_hardif_recalc_extra_skbroom(soft_iface);
543
c6c8fea2 544 /* begin scheduling originator messages on that interface */
9455e34c 545 batadv_schedule_bat_ogm(hard_iface);
c6c8fea2
SE
546
547out:
548 return 0;
549
3dbd550b
SE
550err_upper:
551 netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface);
77af7575 552err_dev:
3dbd550b 553 hard_iface->soft_iface = NULL;
77af7575 554 dev_put(soft_iface);
c6c8fea2 555err:
e5d89254 556 batadv_hardif_free_ref(hard_iface);
e44d8fe2 557 return ret;
c6c8fea2
SE
558}
559
a15fd361
SE
560void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
561 enum batadv_hard_if_cleanup autodel)
c6c8fea2 562{
56303d34
SE
563 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
564 struct batadv_hard_iface *primary_if = NULL;
c6c8fea2 565
e9a4f295 566 if (hard_iface->if_status == BATADV_IF_ACTIVE)
18a1cb6e 567 batadv_hardif_deactivate_interface(hard_iface);
c6c8fea2 568
e9a4f295 569 if (hard_iface->if_status != BATADV_IF_INACTIVE)
32ae9b22 570 goto out;
c6c8fea2 571
3e34819e
SE
572 batadv_info(hard_iface->soft_iface, "Removing interface: %s\n",
573 hard_iface->net_dev->name);
e6c10f43 574 dev_remove_pack(&hard_iface->batman_adv_ptype);
c6c8fea2
SE
575
576 bat_priv->num_ifaces--;
7d211efc 577 batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces);
c6c8fea2 578
e5d89254 579 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22 580 if (hard_iface == primary_if) {
56303d34 581 struct batadv_hard_iface *new_if;
c6c8fea2 582
18a1cb6e
SE
583 new_if = batadv_hardif_get_active(hard_iface->soft_iface);
584 batadv_primary_if_select(bat_priv, new_if);
c6c8fea2
SE
585
586 if (new_if)
e5d89254 587 batadv_hardif_free_ref(new_if);
c6c8fea2
SE
588 }
589
00a50076 590 bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
e9a4f295 591 hard_iface->if_status = BATADV_IF_NOT_IN_USE;
c6c8fea2 592
e6c10f43 593 /* delete all references to this hard_iface */
7d211efc 594 batadv_purge_orig_ref(bat_priv);
9455e34c 595 batadv_purge_outstanding_packets(bat_priv, hard_iface);
e6c10f43 596 dev_put(hard_iface->soft_iface);
c6c8fea2 597
a5256f7e 598 netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
7bca68c7 599 batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
a5256f7e 600
c6c8fea2 601 /* nobody uses this interface anymore */
8257f55a
AQ
602 if (!bat_priv->num_ifaces) {
603 batadv_gw_check_client_stop(bat_priv);
604
605 if (autodel == BATADV_IF_CLEANUP_AUTO)
606 batadv_softif_destroy_sysfs(hard_iface->soft_iface);
607 }
c6c8fea2 608
e6c10f43 609 hard_iface->soft_iface = NULL;
e5d89254 610 batadv_hardif_free_ref(hard_iface);
32ae9b22
ML
611
612out:
613 if (primary_if)
e5d89254 614 batadv_hardif_free_ref(primary_if);
c6c8fea2
SE
615}
616
5bc44dc8
SW
617/**
618 * batadv_hardif_remove_interface_finish - cleans up the remains of a hardif
619 * @work: work queue item
620 *
621 * Free the parts of the hard interface which can not be removed under
622 * rtnl lock (to prevent deadlock situations).
623 */
624static void batadv_hardif_remove_interface_finish(struct work_struct *work)
625{
626 struct batadv_hard_iface *hard_iface;
627
628 hard_iface = container_of(work, struct batadv_hard_iface,
629 cleanup_work);
630
5bc7c1eb 631 batadv_debugfs_del_hardif(hard_iface);
5bc44dc8
SW
632 batadv_sysfs_del_hardif(&hard_iface->hardif_obj);
633 batadv_hardif_free_ref(hard_iface);
634}
635
56303d34 636static struct batadv_hard_iface *
18a1cb6e 637batadv_hardif_add_interface(struct net_device *net_dev)
c6c8fea2 638{
56303d34 639 struct batadv_hard_iface *hard_iface;
c6c8fea2
SE
640 int ret;
641
c3caf519
SE
642 ASSERT_RTNL();
643
18a1cb6e 644 ret = batadv_is_valid_iface(net_dev);
c6c8fea2
SE
645 if (ret != 1)
646 goto out;
647
648 dev_hold(net_dev);
649
7db3fc29 650 hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
320f422f 651 if (!hard_iface)
c6c8fea2 652 goto release_dev;
c6c8fea2 653
5853e22c 654 ret = batadv_sysfs_add_hardif(&hard_iface->hardif_obj, net_dev);
c6c8fea2
SE
655 if (ret)
656 goto free_if;
657
e6c10f43
ML
658 hard_iface->if_num = -1;
659 hard_iface->net_dev = net_dev;
660 hard_iface->soft_iface = NULL;
e9a4f295 661 hard_iface->if_status = BATADV_IF_NOT_IN_USE;
5bc7c1eb
SW
662
663 ret = batadv_debugfs_add_hardif(hard_iface);
664 if (ret)
665 goto free_sysfs;
666
e6c10f43 667 INIT_LIST_HEAD(&hard_iface->list);
cef63419 668 INIT_HLIST_HEAD(&hard_iface->neigh_list);
5bc44dc8
SW
669 INIT_WORK(&hard_iface->cleanup_work,
670 batadv_hardif_remove_interface_finish);
671
cef63419
ML
672 spin_lock_init(&hard_iface->neigh_list_lock);
673
caf65bfc
MS
674 hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
675 if (batadv_is_wifi_netdev(net_dev))
676 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
677
ed75ccbe 678 /* extra reference for return */
e6c10f43 679 atomic_set(&hard_iface->refcount, 2);
c6c8fea2 680
18a1cb6e 681 batadv_check_known_mac_addr(hard_iface->net_dev);
3193e8fd 682 list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
c6c8fea2 683
e6c10f43 684 return hard_iface;
c6c8fea2 685
5bc7c1eb
SW
686free_sysfs:
687 batadv_sysfs_del_hardif(&hard_iface->hardif_obj);
c6c8fea2 688free_if:
e6c10f43 689 kfree(hard_iface);
c6c8fea2
SE
690release_dev:
691 dev_put(net_dev);
692out:
693 return NULL;
694}
695
56303d34 696static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface)
c6c8fea2 697{
c3caf519
SE
698 ASSERT_RTNL();
699
c6c8fea2 700 /* first deactivate interface */
e9a4f295 701 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
a15fd361
SE
702 batadv_hardif_disable_interface(hard_iface,
703 BATADV_IF_CLEANUP_AUTO);
c6c8fea2 704
e9a4f295 705 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
c6c8fea2
SE
706 return;
707
e9a4f295 708 hard_iface->if_status = BATADV_IF_TO_BE_REMOVED;
5bc44dc8 709 queue_work(batadv_event_workqueue, &hard_iface->cleanup_work);
c6c8fea2
SE
710}
711
9563877e 712void batadv_hardif_remove_interfaces(void)
c6c8fea2 713{
56303d34 714 struct batadv_hard_iface *hard_iface, *hard_iface_tmp;
c6c8fea2 715
c3caf519 716 rtnl_lock();
e6c10f43 717 list_for_each_entry_safe(hard_iface, hard_iface_tmp,
3193e8fd 718 &batadv_hardif_list, list) {
e6c10f43 719 list_del_rcu(&hard_iface->list);
18a1cb6e 720 batadv_hardif_remove_interface(hard_iface);
c6c8fea2
SE
721 }
722 rtnl_unlock();
723}
724
18a1cb6e
SE
725static int batadv_hard_if_event(struct notifier_block *this,
726 unsigned long event, void *ptr)
c6c8fea2 727{
351638e7 728 struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
56303d34
SE
729 struct batadv_hard_iface *hard_iface;
730 struct batadv_hard_iface *primary_if = NULL;
731 struct batadv_priv *bat_priv;
c6c8fea2 732
37130293
SE
733 if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
734 batadv_sysfs_add_meshif(net_dev);
5d2c05b2
AQ
735 bat_priv = netdev_priv(net_dev);
736 batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
37130293
SE
737 return NOTIFY_DONE;
738 }
739
56303d34 740 hard_iface = batadv_hardif_get_by_netdev(net_dev);
a1a66b11
AL
741 if (!hard_iface && (event == NETDEV_REGISTER ||
742 event == NETDEV_POST_TYPE_CHANGE))
18a1cb6e 743 hard_iface = batadv_hardif_add_interface(net_dev);
c6c8fea2 744
e6c10f43 745 if (!hard_iface)
c6c8fea2
SE
746 goto out;
747
748 switch (event) {
749 case NETDEV_UP:
18a1cb6e 750 batadv_hardif_activate_interface(hard_iface);
c6c8fea2
SE
751 break;
752 case NETDEV_GOING_DOWN:
753 case NETDEV_DOWN:
18a1cb6e 754 batadv_hardif_deactivate_interface(hard_iface);
c6c8fea2
SE
755 break;
756 case NETDEV_UNREGISTER:
a1a66b11 757 case NETDEV_PRE_TYPE_CHANGE:
e6c10f43 758 list_del_rcu(&hard_iface->list);
c6c8fea2 759
18a1cb6e 760 batadv_hardif_remove_interface(hard_iface);
c6c8fea2
SE
761 break;
762 case NETDEV_CHANGEMTU:
e6c10f43 763 if (hard_iface->soft_iface)
9563877e 764 batadv_update_min_mtu(hard_iface->soft_iface);
c6c8fea2
SE
765 break;
766 case NETDEV_CHANGEADDR:
e9a4f295 767 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
c6c8fea2
SE
768 goto hardif_put;
769
18a1cb6e 770 batadv_check_known_mac_addr(hard_iface->net_dev);
c6c8fea2 771
e6c10f43 772 bat_priv = netdev_priv(hard_iface->soft_iface);
c3229398 773 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface);
01c4224b 774
e5d89254 775 primary_if = batadv_primary_if_get_selected(bat_priv);
32ae9b22
ML
776 if (!primary_if)
777 goto hardif_put;
778
779 if (hard_iface == primary_if)
18a1cb6e 780 batadv_primary_if_update_addr(bat_priv, NULL);
c6c8fea2
SE
781 break;
782 default:
783 break;
f81c6224 784 }
c6c8fea2
SE
785
786hardif_put:
e5d89254 787 batadv_hardif_free_ref(hard_iface);
c6c8fea2 788out:
32ae9b22 789 if (primary_if)
e5d89254 790 batadv_hardif_free_ref(primary_if);
c6c8fea2
SE
791 return NOTIFY_DONE;
792}
793
9563877e 794struct notifier_block batadv_hard_if_notifier = {
18a1cb6e 795 .notifier_call = batadv_hard_if_event,
c6c8fea2 796};