~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/batman-adv/hard-interface.c

Version: ~ [ linux-5.5-rc6 ] ~ [ linux-5.4.11 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.95 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.164 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.209 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.209 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* Copyright (C) 2007-2018  B.A.T.M.A.N. contributors:
  3  *
  4  * Marek Lindner, Simon Wunderlich
  5  *
  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
  8  * License as published by the Free Software Foundation.
  9  *
 10  * This program is distributed in the hope that it will be useful, but
 11  * WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 13  * General Public License for more details.
 14  *
 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/>.
 17  */
 18 
 19 #include "hard-interface.h"
 20 #include "main.h"
 21 
 22 #include <linux/atomic.h>
 23 #include <linux/byteorder/generic.h>
 24 #include <linux/errno.h>
 25 #include <linux/gfp.h>
 26 #include <linux/if.h>
 27 #include <linux/if_arp.h>
 28 #include <linux/if_ether.h>
 29 #include <linux/kernel.h>
 30 #include <linux/kref.h>
 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>
 37 #include <linux/spinlock.h>
 38 #include <net/net_namespace.h>
 39 #include <net/rtnetlink.h>
 40 #include <uapi/linux/batadv_packet.h>
 41 
 42 #include "bat_v.h"
 43 #include "bridge_loop_avoidance.h"
 44 #include "debugfs.h"
 45 #include "distributed-arp-table.h"
 46 #include "gateway_client.h"
 47 #include "log.h"
 48 #include "originator.h"
 49 #include "send.h"
 50 #include "soft-interface.h"
 51 #include "sysfs.h"
 52 #include "translation-table.h"
 53 
 54 /**
 55  * batadv_hardif_release() - release hard interface from lists and queue for
 56  *  free after rcu grace period
 57  * @ref: kref pointer of the hard interface
 58  */
 59 void batadv_hardif_release(struct kref *ref)
 60 {
 61         struct batadv_hard_iface *hard_iface;
 62 
 63         hard_iface = container_of(ref, struct batadv_hard_iface, refcount);
 64         dev_put(hard_iface->net_dev);
 65 
 66         kfree_rcu(hard_iface, rcu);
 67 }
 68 
 69 /**
 70  * batadv_hardif_get_by_netdev() - Get hard interface object of a net_device
 71  * @net_dev: net_device to search for
 72  *
 73  * Return: batadv_hard_iface of net_dev (with increased refcnt), NULL on errors
 74  */
 75 struct batadv_hard_iface *
 76 batadv_hardif_get_by_netdev(const struct net_device *net_dev)
 77 {
 78         struct batadv_hard_iface *hard_iface;
 79 
 80         rcu_read_lock();
 81         list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
 82                 if (hard_iface->net_dev == net_dev &&
 83                     kref_get_unless_zero(&hard_iface->refcount))
 84                         goto out;
 85         }
 86 
 87         hard_iface = NULL;
 88 
 89 out:
 90         rcu_read_unlock();
 91         return hard_iface;
 92 }
 93 
 94 /**
 95  * batadv_getlink_net() - return link net namespace (of use fallback)
 96  * @netdev: net_device to check
 97  * @fallback_net: return in case get_link_net is not available for @netdev
 98  *
 99  * Return: result of rtnl_link_ops->get_link_net or @fallback_net
100  */
101 static struct net *batadv_getlink_net(const struct net_device *netdev,
102                                       struct net *fallback_net)
103 {
104         if (!netdev->rtnl_link_ops)
105                 return fallback_net;
106 
107         if (!netdev->rtnl_link_ops->get_link_net)
108                 return fallback_net;
109 
110         return netdev->rtnl_link_ops->get_link_net(netdev);
111 }
112 
113 /**
114  * batadv_mutual_parents() - check if two devices are each others parent
115  * @dev1: 1st net dev
116  * @net1: 1st devices netns
117  * @dev2: 2nd net dev
118  * @net2: 2nd devices netns
119  *
120  * veth devices come in pairs and each is the parent of the other!
121  *
122  * Return: true if the devices are each others parent, otherwise false
123  */
124 static bool batadv_mutual_parents(const struct net_device *dev1,
125                                   struct net *net1,
126                                   const struct net_device *dev2,
127                                   struct net *net2)
128 {
129         int dev1_parent_iflink = dev_get_iflink(dev1);
130         int dev2_parent_iflink = dev_get_iflink(dev2);
131         const struct net *dev1_parent_net;
132         const struct net *dev2_parent_net;
133 
134         dev1_parent_net = batadv_getlink_net(dev1, net1);
135         dev2_parent_net = batadv_getlink_net(dev2, net2);
136 
137         if (!dev1_parent_iflink || !dev2_parent_iflink)
138                 return false;
139 
140         return (dev1_parent_iflink == dev2->ifindex) &&
141                (dev2_parent_iflink == dev1->ifindex) &&
142                net_eq(dev1_parent_net, net2) &&
143                net_eq(dev2_parent_net, net1);
144 }
145 
146 /**
147  * batadv_is_on_batman_iface() - check if a device is a batman iface descendant
148  * @net_dev: the device to check
149  *
150  * If the user creates any virtual device on top of a batman-adv interface, it
151  * is important to prevent this new interface to be used to create a new mesh
152  * network (this behaviour would lead to a batman-over-batman configuration).
153  * This function recursively checks all the fathers of the device passed as
154  * argument looking for a batman-adv soft interface.
155  *
156  * Return: true if the device is descendant of a batman-adv mesh interface (or
157  * if it is a batman-adv interface itself), false otherwise
158  */
159 static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
160 {
161         struct net *net = dev_net(net_dev);
162         struct net_device *parent_dev;
163         struct net *parent_net;
164         bool ret;
165 
166         /* check if this is a batman-adv mesh interface */
167         if (batadv_softif_is_valid(net_dev))
168                 return true;
169 
170         /* no more parents..stop recursion */
171         if (dev_get_iflink(net_dev) == 0 ||
172             dev_get_iflink(net_dev) == net_dev->ifindex)
173                 return false;
174 
175         parent_net = batadv_getlink_net(net_dev, net);
176 
177         /* recurse over the parent device */
178         parent_dev = __dev_get_by_index((struct net *)parent_net,
179                                         dev_get_iflink(net_dev));
180         /* if we got a NULL parent_dev there is something broken.. */
181         if (!parent_dev) {
182                 pr_err("Cannot find parent device\n");
183                 return false;
184         }
185 
186         if (batadv_mutual_parents(net_dev, net, parent_dev, parent_net))
187                 return false;
188 
189         ret = batadv_is_on_batman_iface(parent_dev);
190 
191         return ret;
192 }
193 
194 static bool batadv_is_valid_iface(const struct net_device *net_dev)
195 {
196         if (net_dev->flags & IFF_LOOPBACK)
197                 return false;
198 
199         if (net_dev->type != ARPHRD_ETHER)
200                 return false;
201 
202         if (net_dev->addr_len != ETH_ALEN)
203                 return false;
204 
205         /* no batman over batman */
206         if (batadv_is_on_batman_iface(net_dev))
207                 return false;
208 
209         return true;
210 }
211 
212 /**
213  * batadv_get_real_netdevice() - check if the given netdev struct is a virtual
214  *  interface on top of another 'real' interface
215  * @netdev: the device to check
216  *
217  * Callers must hold the rtnl semaphore. You may want batadv_get_real_netdev()
218  * instead of this.
219  *
220  * Return: the 'real' net device or the original net device and NULL in case
221  *  of an error.
222  */
223 static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
224 {
225         struct batadv_hard_iface *hard_iface = NULL;
226         struct net_device *real_netdev = NULL;
227         struct net *real_net;
228         struct net *net;
229         int ifindex;
230 
231         ASSERT_RTNL();
232 
233         if (!netdev)
234                 return NULL;
235 
236         if (netdev->ifindex == dev_get_iflink(netdev)) {
237                 dev_hold(netdev);
238                 return netdev;
239         }
240 
241         hard_iface = batadv_hardif_get_by_netdev(netdev);
242         if (!hard_iface || !hard_iface->soft_iface)
243                 goto out;
244 
245         net = dev_net(hard_iface->soft_iface);
246         ifindex = dev_get_iflink(netdev);
247         real_net = batadv_getlink_net(netdev, net);
248         real_netdev = dev_get_by_index(real_net, ifindex);
249 
250 out:
251         if (hard_iface)
252                 batadv_hardif_put(hard_iface);
253         return real_netdev;
254 }
255 
256 /**
257  * batadv_get_real_netdev() - check if the given net_device struct is a virtual
258  *  interface on top of another 'real' interface
259  * @net_device: the device to check
260  *
261  * Return: the 'real' net device or the original net device and NULL in case
262  *  of an error.
263  */
264 struct net_device *batadv_get_real_netdev(struct net_device *net_device)
265 {
266         struct net_device *real_netdev;
267 
268         rtnl_lock();
269         real_netdev = batadv_get_real_netdevice(net_device);
270         rtnl_unlock();
271 
272         return real_netdev;
273 }
274 
275 /**
276  * batadv_is_wext_netdev() - check if the given net_device struct is a
277  *  wext wifi interface
278  * @net_device: the device to check
279  *
280  * Return: true if the net device is a wext wireless device, false
281  *  otherwise.
282  */
283 static bool batadv_is_wext_netdev(struct net_device *net_device)
284 {
285         if (!net_device)
286                 return false;
287 
288 #ifdef CONFIG_WIRELESS_EXT
289         /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
290          * check for wireless_handlers != NULL
291          */
292         if (net_device->wireless_handlers)
293                 return true;
294 #endif
295 
296         return false;
297 }
298 
299 /**
300  * batadv_is_cfg80211_netdev() - check if the given net_device struct is a
301  *  cfg80211 wifi interface
302  * @net_device: the device to check
303  *
304  * Return: true if the net device is a cfg80211 wireless device, false
305  *  otherwise.
306  */
307 static bool batadv_is_cfg80211_netdev(struct net_device *net_device)
308 {
309         if (!net_device)
310                 return false;
311 
312         /* cfg80211 drivers have to set ieee80211_ptr */
313         if (net_device->ieee80211_ptr)
314                 return true;
315 
316         return false;
317 }
318 
319 /**
320  * batadv_wifi_flags_evaluate() - calculate wifi flags for net_device
321  * @net_device: the device to check
322  *
323  * Return: batadv_hard_iface_wifi_flags flags of the device
324  */
325 static u32 batadv_wifi_flags_evaluate(struct net_device *net_device)
326 {
327         u32 wifi_flags = 0;
328         struct net_device *real_netdev;
329 
330         if (batadv_is_wext_netdev(net_device))
331                 wifi_flags |= BATADV_HARDIF_WIFI_WEXT_DIRECT;
332 
333         if (batadv_is_cfg80211_netdev(net_device))
334                 wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
335 
336         real_netdev = batadv_get_real_netdevice(net_device);
337         if (!real_netdev)
338                 return wifi_flags;
339 
340         if (real_netdev == net_device)
341                 goto out;
342 
343         if (batadv_is_wext_netdev(real_netdev))
344                 wifi_flags |= BATADV_HARDIF_WIFI_WEXT_INDIRECT;
345 
346         if (batadv_is_cfg80211_netdev(real_netdev))
347                 wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
348 
349 out:
350         dev_put(real_netdev);
351         return wifi_flags;
352 }
353 
354 /**
355  * batadv_is_cfg80211_hardif() - check if the given hardif is a cfg80211 wifi
356  *  interface
357  * @hard_iface: the device to check
358  *
359  * Return: true if the net device is a cfg80211 wireless device, false
360  *  otherwise.
361  */
362 bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface)
363 {
364         u32 allowed_flags = 0;
365 
366         allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
367         allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
368 
369         return !!(hard_iface->wifi_flags & allowed_flags);
370 }
371 
372 /**
373  * batadv_is_wifi_hardif() - check if the given hardif is a wifi interface
374  * @hard_iface: the device to check
375  *
376  * Return: true if the net device is a 802.11 wireless device, false otherwise.
377  */
378 bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface)
379 {
380         if (!hard_iface)
381                 return false;
382 
383         return hard_iface->wifi_flags != 0;
384 }
385 
386 /**
387  * batadv_hardif_no_broadcast() - check whether (re)broadcast is necessary
388  * @if_outgoing: the outgoing interface checked and considered for (re)broadcast
389  * @orig_addr: the originator of this packet
390  * @orig_neigh: originator address of the forwarder we just got the packet from
391  *  (NULL if we originated)
392  *
393  * Checks whether a packet needs to be (re)broadcasted on the given interface.
394  *
395  * Return:
396  *      BATADV_HARDIF_BCAST_NORECIPIENT: No neighbor on interface
397  *      BATADV_HARDIF_BCAST_DUPFWD: Just one neighbor, but it is the forwarder
398  *      BATADV_HARDIF_BCAST_DUPORIG: Just one neighbor, but it is the originator
399  *      BATADV_HARDIF_BCAST_OK: Several neighbors, must broadcast
400  */
401 int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
402                                u8 *orig_addr, u8 *orig_neigh)
403 {
404         struct batadv_hardif_neigh_node *hardif_neigh;
405         struct hlist_node *first;
406         int ret = BATADV_HARDIF_BCAST_OK;
407 
408         rcu_read_lock();
409 
410         /* 0 neighbors -> no (re)broadcast */
411         first = rcu_dereference(hlist_first_rcu(&if_outgoing->neigh_list));
412         if (!first) {
413                 ret = BATADV_HARDIF_BCAST_NORECIPIENT;
414                 goto out;
415         }
416 
417         /* >1 neighbors -> (re)brodcast */
418         if (rcu_dereference(hlist_next_rcu(first)))
419                 goto out;
420 
421         hardif_neigh = hlist_entry(first, struct batadv_hardif_neigh_node,
422                                    list);
423 
424         /* 1 neighbor, is the originator -> no rebroadcast */
425         if (orig_addr && batadv_compare_eth(hardif_neigh->orig, orig_addr)) {
426                 ret = BATADV_HARDIF_BCAST_DUPORIG;
427         /* 1 neighbor, is the one we received from -> no rebroadcast */
428         } else if (orig_neigh &&
429                    batadv_compare_eth(hardif_neigh->orig, orig_neigh)) {
430                 ret = BATADV_HARDIF_BCAST_DUPFWD;
431         }
432 
433 out:
434         rcu_read_unlock();
435         return ret;
436 }
437 
438 static struct batadv_hard_iface *
439 batadv_hardif_get_active(const struct net_device *soft_iface)
440 {
441         struct batadv_hard_iface *hard_iface;
442 
443         rcu_read_lock();
444         list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
445                 if (hard_iface->soft_iface != soft_iface)
446                         continue;
447 
448                 if (hard_iface->if_status == BATADV_IF_ACTIVE &&
449                     kref_get_unless_zero(&hard_iface->refcount))
450                         goto out;
451         }
452 
453         hard_iface = NULL;
454 
455 out:
456         rcu_read_unlock();
457         return hard_iface;
458 }
459 
460 static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
461                                           struct batadv_hard_iface *oldif)
462 {
463         struct batadv_hard_iface *primary_if;
464 
465         primary_if = batadv_primary_if_get_selected(bat_priv);
466         if (!primary_if)
467                 goto out;
468 
469         batadv_dat_init_own_addr(bat_priv, primary_if);
470         batadv_bla_update_orig_address(bat_priv, primary_if, oldif);
471 out:
472         if (primary_if)
473                 batadv_hardif_put(primary_if);
474 }
475 
476 static void batadv_primary_if_select(struct batadv_priv *bat_priv,
477                                      struct batadv_hard_iface *new_hard_iface)
478 {
479         struct batadv_hard_iface *curr_hard_iface;
480 
481         ASSERT_RTNL();
482 
483         if (new_hard_iface)
484                 kref_get(&new_hard_iface->refcount);
485 
486         curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1);
487         rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
488 
489         if (!new_hard_iface)
490                 goto out;
491 
492         bat_priv->algo_ops->iface.primary_set(new_hard_iface);
493         batadv_primary_if_update_addr(bat_priv, curr_hard_iface);
494 
495 out:
496         if (curr_hard_iface)
497                 batadv_hardif_put(curr_hard_iface);
498 }
499 
500 static bool
501 batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface)
502 {
503         if (hard_iface->net_dev->flags & IFF_UP)
504                 return true;
505 
506         return false;
507 }
508 
509 static void batadv_check_known_mac_addr(const struct net_device *net_dev)
510 {
511         const struct batadv_hard_iface *hard_iface;
512 
513         rcu_read_lock();
514         list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
515                 if (hard_iface->if_status != BATADV_IF_ACTIVE &&
516                     hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
517                         continue;
518 
519                 if (hard_iface->net_dev == net_dev)
520                         continue;
521 
522                 if (!batadv_compare_eth(hard_iface->net_dev->dev_addr,
523                                         net_dev->dev_addr))
524                         continue;
525 
526                 pr_warn("The newly added mac address (%pM) already exists on: %s\n",
527                         net_dev->dev_addr, hard_iface->net_dev->name);
528                 pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
529         }
530         rcu_read_unlock();
531 }
532 
533 /**
534  * batadv_hardif_recalc_extra_skbroom() - Recalculate skbuff extra head/tailroom
535  * @soft_iface: netdev struct of the mesh interface
536  */
537 static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface)
538 {
539         const struct batadv_hard_iface *hard_iface;
540         unsigned short lower_header_len = ETH_HLEN;
541         unsigned short lower_headroom = 0;
542         unsigned short lower_tailroom = 0;
543         unsigned short needed_headroom;
544 
545         rcu_read_lock();
546         list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
547                 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
548                         continue;
549 
550                 if (hard_iface->soft_iface != soft_iface)
551                         continue;
552 
553                 lower_header_len = max_t(unsigned short, lower_header_len,
554                                          hard_iface->net_dev->hard_header_len);
555 
556                 lower_headroom = max_t(unsigned short, lower_headroom,
557                                        hard_iface->net_dev->needed_headroom);
558 
559                 lower_tailroom = max_t(unsigned short, lower_tailroom,
560                                        hard_iface->net_dev->needed_tailroom);
561         }
562         rcu_read_unlock();
563 
564         needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN);
565         needed_headroom += batadv_max_header_len();
566 
567         soft_iface->needed_headroom = needed_headroom;
568         soft_iface->needed_tailroom = lower_tailroom;
569 }
570 
571 /**
572  * batadv_hardif_min_mtu() - Calculate maximum MTU for soft interface
573  * @soft_iface: netdev struct of the soft interface
574  *
575  * Return: MTU for the soft-interface (limited by the minimal MTU of all active
576  *  slave interfaces)
577  */
578 int batadv_hardif_min_mtu(struct net_device *soft_iface)
579 {
580         struct batadv_priv *bat_priv = netdev_priv(soft_iface);
581         const struct batadv_hard_iface *hard_iface;
582         int min_mtu = INT_MAX;
583 
584         rcu_read_lock();
585         list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
586                 if (hard_iface->if_status != BATADV_IF_ACTIVE &&
587                     hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
588                         continue;
589 
590                 if (hard_iface->soft_iface != soft_iface)
591                         continue;
592 
593                 min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
594         }
595         rcu_read_unlock();
596 
597         if (atomic_read(&bat_priv->fragmentation) == 0)
598                 goto out;
599 
600         /* with fragmentation enabled the maximum size of internally generated
601          * packets such as translation table exchanges or tvlv containers, etc
602          * has to be calculated
603          */
604         min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
605         min_mtu -= sizeof(struct batadv_frag_packet);
606         min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
607 
608 out:
609         /* report to the other components the maximum amount of bytes that
610          * batman-adv can send over the wire (without considering the payload
611          * overhead). For example, this value is used by TT to compute the
612          * maximum local table table size
613          */
614         atomic_set(&bat_priv->packet_size_max, min_mtu);
615 
616         /* the real soft-interface MTU is computed by removing the payload
617          * overhead from the maximum amount of bytes that was just computed.
618          *
619          * However batman-adv does not support MTUs bigger than ETH_DATA_LEN
620          */
621         return min_t(int, min_mtu - batadv_max_header_len(), ETH_DATA_LEN);
622 }
623 
624 /**
625  * batadv_update_min_mtu() - Adjusts the MTU if a new interface with a smaller
626  *  MTU appeared
627  * @soft_iface: netdev struct of the soft interface
628  */
629 void batadv_update_min_mtu(struct net_device *soft_iface)
630 {
631         soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
632 
633         /* Check if the local translate table should be cleaned up to match a
634          * new (and smaller) MTU.
635          */
636         batadv_tt_local_resize_to_mtu(soft_iface);
637 }
638 
639 static void
640 batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface)
641 {
642         struct batadv_priv *bat_priv;
643         struct batadv_hard_iface *primary_if = NULL;
644 
645         if (hard_iface->if_status != BATADV_IF_INACTIVE)
646                 goto out;
647 
648         bat_priv = netdev_priv(hard_iface->soft_iface);
649 
650         bat_priv->algo_ops->iface.update_mac(hard_iface);
651         hard_iface->if_status = BATADV_IF_TO_BE_ACTIVATED;
652 
653         /* the first active interface becomes our primary interface or
654          * the next active interface after the old primary interface was removed
655          */
656         primary_if = batadv_primary_if_get_selected(bat_priv);
657         if (!primary_if)
658                 batadv_primary_if_select(bat_priv, hard_iface);
659 
660         batadv_info(hard_iface->soft_iface, "Interface activated: %s\n",
661                     hard_iface->net_dev->name);
662 
663         batadv_update_min_mtu(hard_iface->soft_iface);
664 
665         if (bat_priv->algo_ops->iface.activate)
666                 bat_priv->algo_ops->iface.activate(hard_iface);
667 
668 out:
669         if (primary_if)
670                 batadv_hardif_put(primary_if);
671 }
672 
673 static void
674 batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
675 {
676         if (hard_iface->if_status != BATADV_IF_ACTIVE &&
677             hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
678                 return;
679 
680         hard_iface->if_status = BATADV_IF_INACTIVE;
681 
682         batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n",
683                     hard_iface->net_dev->name);
684 
685         batadv_update_min_mtu(hard_iface->soft_iface);
686 }
687 
688 /**
689  * batadv_master_del_slave() - remove hard_iface from the current master iface
690  * @slave: the interface enslaved in another master
691  * @master: the master from which slave has to be removed
692  *
693  * Invoke ndo_del_slave on master passing slave as argument. In this way slave
694  * is free'd and master can correctly change its internal state.
695  *
696  * Return: 0 on success, a negative value representing the error otherwise
697  */
698 static int batadv_master_del_slave(struct batadv_hard_iface *slave,
699                                    struct net_device *master)
700 {
701         int ret;
702 
703         if (!master)
704                 return 0;
705 
706         ret = -EBUSY;
707         if (master->netdev_ops->ndo_del_slave)
708                 ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev);
709 
710         return ret;
711 }
712 
713 /**
714  * batadv_hardif_enable_interface() - Enslave hard interface to soft interface
715  * @hard_iface: hard interface to add to soft interface
716  * @net: the applicable net namespace
717  * @iface_name: name of the soft interface
718  *
719  * Return: 0 on success or negative error number in case of failure
720  */
721 int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
722                                    struct net *net, const char *iface_name)
723 {
724         struct batadv_priv *bat_priv;
725         struct net_device *soft_iface, *master;
726         __be16 ethertype = htons(ETH_P_BATMAN);
727         int max_header_len = batadv_max_header_len();
728         int ret;
729 
730         if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
731                 goto out;
732 
733         kref_get(&hard_iface->refcount);
734 
735         soft_iface = dev_get_by_name(net, iface_name);
736 
737         if (!soft_iface) {
738                 soft_iface = batadv_softif_create(net, iface_name);
739 
740                 if (!soft_iface) {
741                         ret = -ENOMEM;
742                         goto err;
743                 }
744 
745                 /* dev_get_by_name() increases the reference counter for us */
746                 dev_hold(soft_iface);
747         }
748 
749         if (!batadv_softif_is_valid(soft_iface)) {
750                 pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
751                        soft_iface->name);
752                 ret = -EINVAL;
753                 goto err_dev;
754         }
755 
756         /* check if the interface is enslaved in another virtual one and
757          * in that case unlink it first
758          */
759         master = netdev_master_upper_dev_get(hard_iface->net_dev);
760         ret = batadv_master_del_slave(hard_iface, master);
761         if (ret)
762                 goto err_dev;
763 
764         hard_iface->soft_iface = soft_iface;
765         bat_priv = netdev_priv(hard_iface->soft_iface);
766 
767         ret = netdev_master_upper_dev_link(hard_iface->net_dev,
768                                            soft_iface, NULL, NULL, NULL);
769         if (ret)
770                 goto err_dev;
771 
772         ret = bat_priv->algo_ops->iface.enable(hard_iface);
773         if (ret < 0)
774                 goto err_upper;
775 
776         hard_iface->if_status = BATADV_IF_INACTIVE;
777 
778         kref_get(&hard_iface->refcount);
779         hard_iface->batman_adv_ptype.type = ethertype;
780         hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
781         hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
782         dev_add_pack(&hard_iface->batman_adv_ptype);
783 
784         batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
785                     hard_iface->net_dev->name);
786 
787         if (atomic_read(&bat_priv->fragmentation) &&
788             hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
789                 batadv_info(hard_iface->soft_iface,
790                             "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",
791                             hard_iface->net_dev->name, hard_iface->net_dev->mtu,
792                             ETH_DATA_LEN + max_header_len);
793 
794         if (!atomic_read(&bat_priv->fragmentation) &&
795             hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
796                 batadv_info(hard_iface->soft_iface,
797                             "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",
798                             hard_iface->net_dev->name, hard_iface->net_dev->mtu,
799                             ETH_DATA_LEN + max_header_len);
800 
801         if (batadv_hardif_is_iface_up(hard_iface))
802                 batadv_hardif_activate_interface(hard_iface);
803         else
804                 batadv_err(hard_iface->soft_iface,
805                            "Not using interface %s (retrying later): interface not active\n",
806                            hard_iface->net_dev->name);
807 
808         batadv_hardif_recalc_extra_skbroom(soft_iface);
809 
810 out:
811         return 0;
812 
813 err_upper:
814         netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface);
815 err_dev:
816         hard_iface->soft_iface = NULL;
817         dev_put(soft_iface);
818 err:
819         batadv_hardif_put(hard_iface);
820         return ret;
821 }
822 
823 /**
824  * batadv_hardif_cnt() - get number of interfaces enslaved to soft interface
825  * @soft_iface: soft interface to check
826  *
827  * This function is only using RCU for locking - the result can therefore be
828  * off when another functions is modifying the list at the same time. The
829  * caller can use the rtnl_lock to make sure that the count is accurate.
830  *
831  * Return: number of connected/enslaved hard interfaces
832  */
833 static size_t batadv_hardif_cnt(const struct net_device *soft_iface)
834 {
835         struct batadv_hard_iface *hard_iface;
836         size_t count = 0;
837 
838         rcu_read_lock();
839         list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
840                 if (hard_iface->soft_iface != soft_iface)
841                         continue;
842 
843                 count++;
844         }
845         rcu_read_unlock();
846 
847         return count;
848 }
849 
850 /**
851  * batadv_hardif_disable_interface() - Remove hard interface from soft interface
852  * @hard_iface: hard interface to be removed
853  * @autodel: whether to delete soft interface when it doesn't contain any other
854  *  slave interfaces
855  */
856 void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
857                                      enum batadv_hard_if_cleanup autodel)
858 {
859         struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
860         struct batadv_hard_iface *primary_if = NULL;
861 
862         batadv_hardif_deactivate_interface(hard_iface);
863 
864         if (hard_iface->if_status != BATADV_IF_INACTIVE)
865                 goto out;
866 
867         batadv_info(hard_iface->soft_iface, "Removing interface: %s\n",
868                     hard_iface->net_dev->name);
869         dev_remove_pack(&hard_iface->batman_adv_ptype);
870         batadv_hardif_put(hard_iface);
871 
872         primary_if = batadv_primary_if_get_selected(bat_priv);
873         if (hard_iface == primary_if) {
874                 struct batadv_hard_iface *new_if;
875 
876                 new_if = batadv_hardif_get_active(hard_iface->soft_iface);
877                 batadv_primary_if_select(bat_priv, new_if);
878 
879                 if (new_if)
880                         batadv_hardif_put(new_if);
881         }
882 
883         bat_priv->algo_ops->iface.disable(hard_iface);
884         hard_iface->if_status = BATADV_IF_NOT_IN_USE;
885 
886         /* delete all references to this hard_iface */
887         batadv_purge_orig_ref(bat_priv);
888         batadv_purge_outstanding_packets(bat_priv, hard_iface);
889         dev_put(hard_iface->soft_iface);
890 
891         netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
892         batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
893 
894         /* nobody uses this interface anymore */
895         if (batadv_hardif_cnt(hard_iface->soft_iface) <= 1) {
896                 batadv_gw_check_client_stop(bat_priv);
897 
898                 if (autodel == BATADV_IF_CLEANUP_AUTO)
899                         batadv_softif_destroy_sysfs(hard_iface->soft_iface);
900         }
901 
902         hard_iface->soft_iface = NULL;
903         batadv_hardif_put(hard_iface);
904 
905 out:
906         if (primary_if)
907                 batadv_hardif_put(primary_if);
908 }
909 
910 static struct batadv_hard_iface *
911 batadv_hardif_add_interface(struct net_device *net_dev)
912 {
913         struct batadv_hard_iface *hard_iface;
914         int ret;
915 
916         ASSERT_RTNL();
917 
918         if (!batadv_is_valid_iface(net_dev))
919                 goto out;
920 
921         dev_hold(net_dev);
922 
923         hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
924         if (!hard_iface)
925                 goto release_dev;
926 
927         ret = batadv_sysfs_add_hardif(&hard_iface->hardif_obj, net_dev);
928         if (ret)
929                 goto free_if;
930 
931         hard_iface->net_dev = net_dev;
932         hard_iface->soft_iface = NULL;
933         hard_iface->if_status = BATADV_IF_NOT_IN_USE;
934 
935         ret = batadv_debugfs_add_hardif(hard_iface);
936         if (ret)
937                 goto free_sysfs;
938 
939         INIT_LIST_HEAD(&hard_iface->list);
940         INIT_HLIST_HEAD(&hard_iface->neigh_list);
941 
942         spin_lock_init(&hard_iface->neigh_list_lock);
943         kref_init(&hard_iface->refcount);
944 
945         hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
946         hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
947         if (batadv_is_wifi_hardif(hard_iface))
948                 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
949 
950         batadv_v_hardif_init(hard_iface);
951 
952         batadv_check_known_mac_addr(hard_iface->net_dev);
953         kref_get(&hard_iface->refcount);
954         list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
955 
956         return hard_iface;
957 
958 free_sysfs:
959         batadv_sysfs_del_hardif(&hard_iface->hardif_obj);
960 free_if:
961         kfree(hard_iface);
962 release_dev:
963         dev_put(net_dev);
964 out:
965         return NULL;
966 }
967 
968 static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface)
969 {
970         ASSERT_RTNL();
971 
972         /* first deactivate interface */
973         if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
974                 batadv_hardif_disable_interface(hard_iface,
975                                                 BATADV_IF_CLEANUP_KEEP);
976 
977         if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
978                 return;
979 
980         hard_iface->if_status = BATADV_IF_TO_BE_REMOVED;
981         batadv_debugfs_del_hardif(hard_iface);
982         batadv_sysfs_del_hardif(&hard_iface->hardif_obj);
983         batadv_hardif_put(hard_iface);
984 }
985 
986 /**
987  * batadv_hardif_remove_interfaces() - Remove all hard interfaces
988  */
989 void batadv_hardif_remove_interfaces(void)
990 {
991         struct batadv_hard_iface *hard_iface, *hard_iface_tmp;
992 
993         rtnl_lock();
994         list_for_each_entry_safe(hard_iface, hard_iface_tmp,
995                                  &batadv_hardif_list, list) {
996                 list_del_rcu(&hard_iface->list);
997                 batadv_hardif_remove_interface(hard_iface);
998         }
999         rtnl_unlock();
1000 }
1001 
1002 /**
1003  * batadv_hard_if_event_softif() - Handle events for soft interfaces
1004  * @event: NETDEV_* event to handle
1005  * @net_dev: net_device which generated an event
1006  *
1007  * Return: NOTIFY_* result
1008  */
1009 static int batadv_hard_if_event_softif(unsigned long event,
1010                                        struct net_device *net_dev)
1011 {
1012         struct batadv_priv *bat_priv;
1013 
1014         switch (event) {
1015         case NETDEV_REGISTER:
1016                 batadv_sysfs_add_meshif(net_dev);
1017                 bat_priv = netdev_priv(net_dev);
1018                 batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
1019                 break;
1020         case NETDEV_CHANGENAME:
1021                 batadv_debugfs_rename_meshif(net_dev);
1022                 break;
1023         }
1024 
1025         return NOTIFY_DONE;
1026 }
1027 
1028 static int batadv_hard_if_event(struct notifier_block *this,
1029                                 unsigned long event, void *ptr)
1030 {
1031         struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
1032         struct batadv_hard_iface *hard_iface;
1033         struct batadv_hard_iface *primary_if = NULL;
1034         struct batadv_priv *bat_priv;
1035 
1036         if (batadv_softif_is_valid(net_dev))
1037                 return batadv_hard_if_event_softif(event, net_dev);
1038 
1039         hard_iface = batadv_hardif_get_by_netdev(net_dev);
1040         if (!hard_iface && (event == NETDEV_REGISTER ||
1041                             event == NETDEV_POST_TYPE_CHANGE))
1042                 hard_iface = batadv_hardif_add_interface(net_dev);
1043 
1044         if (!hard_iface)
1045                 goto out;
1046 
1047         switch (event) {
1048         case NETDEV_UP:
1049                 batadv_hardif_activate_interface(hard_iface);
1050                 break;
1051         case NETDEV_GOING_DOWN:
1052         case NETDEV_DOWN:
1053                 batadv_hardif_deactivate_interface(hard_iface);
1054                 break;
1055         case NETDEV_UNREGISTER:
1056         case NETDEV_PRE_TYPE_CHANGE:
1057                 list_del_rcu(&hard_iface->list);
1058 
1059                 batadv_hardif_remove_interface(hard_iface);
1060                 break;
1061         case NETDEV_CHANGEMTU:
1062                 if (hard_iface->soft_iface)
1063                         batadv_update_min_mtu(hard_iface->soft_iface);
1064                 break;
1065         case NETDEV_CHANGEADDR:
1066                 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
1067                         goto hardif_put;
1068 
1069                 batadv_check_known_mac_addr(hard_iface->net_dev);
1070 
1071                 bat_priv = netdev_priv(hard_iface->soft_iface);
1072                 bat_priv->algo_ops->iface.update_mac(hard_iface);
1073 
1074                 primary_if = batadv_primary_if_get_selected(bat_priv);
1075                 if (!primary_if)
1076                         goto hardif_put;
1077 
1078                 if (hard_iface == primary_if)
1079                         batadv_primary_if_update_addr(bat_priv, NULL);
1080                 break;
1081         case NETDEV_CHANGEUPPER:
1082                 hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
1083                 if (batadv_is_wifi_hardif(hard_iface))
1084                         hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
1085                 break;
1086         case NETDEV_CHANGENAME:
1087                 batadv_debugfs_rename_hardif(hard_iface);
1088                 break;
1089         default:
1090                 break;
1091         }
1092 
1093 hardif_put:
1094         batadv_hardif_put(hard_iface);
1095 out:
1096         if (primary_if)
1097                 batadv_hardif_put(primary_if);
1098         return NOTIFY_DONE;
1099 }
1100 
1101 struct notifier_block batadv_hard_if_notifier = {
1102         .notifier_call = batadv_hard_if_event,
1103 };
1104 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp