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