aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/hard-interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r--net/batman-adv/hard-interface.c170
1 files changed, 31 insertions, 139 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 377897701a85..dc334fa89847 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -28,15 +28,10 @@
28#include "bat_sysfs.h" 28#include "bat_sysfs.h"
29#include "originator.h" 29#include "originator.h"
30#include "hash.h" 30#include "hash.h"
31#include "bridge_loop_avoidance.h"
31 32
32#include <linux/if_arp.h> 33#include <linux/if_arp.h>
33 34
34
35static int batman_skb_recv(struct sk_buff *skb,
36 struct net_device *dev,
37 struct packet_type *ptype,
38 struct net_device *orig_dev);
39
40void hardif_free_rcu(struct rcu_head *rcu) 35void hardif_free_rcu(struct rcu_head *rcu)
41{ 36{
42 struct hard_iface *hard_iface; 37 struct hard_iface *hard_iface;
@@ -107,7 +102,8 @@ out:
107 return hard_iface; 102 return hard_iface;
108} 103}
109 104
110static void primary_if_update_addr(struct bat_priv *bat_priv) 105static void primary_if_update_addr(struct bat_priv *bat_priv,
106 struct hard_iface *oldif)
111{ 107{
112 struct vis_packet *vis_packet; 108 struct vis_packet *vis_packet;
113 struct hard_iface *primary_if; 109 struct hard_iface *primary_if;
@@ -122,6 +118,7 @@ static void primary_if_update_addr(struct bat_priv *bat_priv)
122 memcpy(vis_packet->sender_orig, 118 memcpy(vis_packet->sender_orig,
123 primary_if->net_dev->dev_addr, ETH_ALEN); 119 primary_if->net_dev->dev_addr, ETH_ALEN);
124 120
121 bla_update_orig_address(bat_priv, primary_if, oldif);
125out: 122out:
126 if (primary_if) 123 if (primary_if)
127 hardif_free_ref(primary_if); 124 hardif_free_ref(primary_if);
@@ -140,14 +137,15 @@ static void primary_if_select(struct bat_priv *bat_priv,
140 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); 137 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1);
141 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); 138 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
142 139
143 if (curr_hard_iface)
144 hardif_free_ref(curr_hard_iface);
145
146 if (!new_hard_iface) 140 if (!new_hard_iface)
147 return; 141 goto out;
142
143 bat_priv->bat_algo_ops->bat_primary_iface_set(new_hard_iface);
144 primary_if_update_addr(bat_priv, curr_hard_iface);
148 145
149 bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface); 146out:
150 primary_if_update_addr(bat_priv); 147 if (curr_hard_iface)
148 hardif_free_ref(curr_hard_iface);
151} 149}
152 150
153static bool hardif_is_iface_up(const struct hard_iface *hard_iface) 151static bool hardif_is_iface_up(const struct hard_iface *hard_iface)
@@ -175,9 +173,9 @@ static void check_known_mac_addr(const struct net_device *net_dev)
175 net_dev->dev_addr)) 173 net_dev->dev_addr))
176 continue; 174 continue;
177 175
178 pr_warning("The newly added mac address (%pM) already exists on: %s\n", 176 pr_warn("The newly added mac address (%pM) already exists on: %s\n",
179 net_dev->dev_addr, hard_iface->net_dev->name); 177 net_dev->dev_addr, hard_iface->net_dev->name);
180 pr_warning("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); 178 pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
181 } 179 }
182 rcu_read_unlock(); 180 rcu_read_unlock();
183} 181}
@@ -230,7 +228,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
230 228
231 bat_priv = netdev_priv(hard_iface->soft_iface); 229 bat_priv = netdev_priv(hard_iface->soft_iface);
232 230
233 bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); 231 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface);
234 hard_iface->if_status = IF_TO_BE_ACTIVATED; 232 hard_iface->if_status = IF_TO_BE_ACTIVATED;
235 233
236 /** 234 /**
@@ -300,22 +298,17 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
300 if (!softif_is_valid(soft_iface)) { 298 if (!softif_is_valid(soft_iface)) {
301 pr_err("Can't create batman mesh interface %s: already exists as regular interface\n", 299 pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
302 soft_iface->name); 300 soft_iface->name);
303 dev_put(soft_iface);
304 ret = -EINVAL; 301 ret = -EINVAL;
305 goto err; 302 goto err_dev;
306 } 303 }
307 304
308 hard_iface->soft_iface = soft_iface; 305 hard_iface->soft_iface = soft_iface;
309 bat_priv = netdev_priv(hard_iface->soft_iface); 306 bat_priv = netdev_priv(hard_iface->soft_iface);
310 307
311 bat_priv->bat_algo_ops->bat_ogm_init(hard_iface); 308 ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface);
312 309 if (ret < 0) {
313 if (!hard_iface->packet_buff) {
314 bat_err(hard_iface->soft_iface,
315 "Can't add interface packet (%s): out of memory\n",
316 hard_iface->net_dev->name);
317 ret = -ENOMEM; 310 ret = -ENOMEM;
318 goto err; 311 goto err_dev;
319 } 312 }
320 313
321 hard_iface->if_num = bat_priv->num_ifaces; 314 hard_iface->if_num = bat_priv->num_ifaces;
@@ -328,7 +321,6 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
328 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; 321 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
329 dev_add_pack(&hard_iface->batman_adv_ptype); 322 dev_add_pack(&hard_iface->batman_adv_ptype);
330 323
331 atomic_set(&hard_iface->seqno, 1);
332 atomic_set(&hard_iface->frag_seqno, 1); 324 atomic_set(&hard_iface->frag_seqno, 1);
333 bat_info(hard_iface->soft_iface, "Adding interface: %s\n", 325 bat_info(hard_iface->soft_iface, "Adding interface: %s\n",
334 hard_iface->net_dev->name); 326 hard_iface->net_dev->name);
@@ -360,6 +352,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
360out: 352out:
361 return 0; 353 return 0;
362 354
355err_dev:
356 dev_put(soft_iface);
363err: 357err:
364 hardif_free_ref(hard_iface); 358 hardif_free_ref(hard_iface);
365 return ret; 359 return ret;
@@ -394,8 +388,7 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
394 hardif_free_ref(new_if); 388 hardif_free_ref(new_if);
395 } 389 }
396 390
397 kfree(hard_iface->packet_buff); 391 bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
398 hard_iface->packet_buff = NULL;
399 hard_iface->if_status = IF_NOT_IN_USE; 392 hard_iface->if_status = IF_NOT_IN_USE;
400 393
401 /* delete all references to this hard_iface */ 394 /* delete all references to this hard_iface */
@@ -447,6 +440,13 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
447 check_known_mac_addr(hard_iface->net_dev); 440 check_known_mac_addr(hard_iface->net_dev);
448 list_add_tail_rcu(&hard_iface->list, &hardif_list); 441 list_add_tail_rcu(&hard_iface->list, &hardif_list);
449 442
443 /**
444 * This can't be called via a bat_priv callback because
445 * we have no bat_priv yet.
446 */
447 atomic_set(&hard_iface->seqno, 1);
448 hard_iface->packet_buff = NULL;
449
450 return hard_iface; 450 return hard_iface;
451 451
452free_if: 452free_if:
@@ -524,14 +524,14 @@ static int hard_if_event(struct notifier_block *this,
524 check_known_mac_addr(hard_iface->net_dev); 524 check_known_mac_addr(hard_iface->net_dev);
525 525
526 bat_priv = netdev_priv(hard_iface->soft_iface); 526 bat_priv = netdev_priv(hard_iface->soft_iface);
527 bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); 527 bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface);
528 528
529 primary_if = primary_if_get_selected(bat_priv); 529 primary_if = primary_if_get_selected(bat_priv);
530 if (!primary_if) 530 if (!primary_if)
531 goto hardif_put; 531 goto hardif_put;
532 532
533 if (hard_iface == primary_if) 533 if (hard_iface == primary_if)
534 primary_if_update_addr(bat_priv); 534 primary_if_update_addr(bat_priv, NULL);
535 break; 535 break;
536 default: 536 default:
537 break; 537 break;
@@ -545,114 +545,6 @@ out:
545 return NOTIFY_DONE; 545 return NOTIFY_DONE;
546} 546}
547 547
548/* incoming packets with the batman ethertype received on any active hard
549 * interface */
550static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
551 struct packet_type *ptype,
552 struct net_device *orig_dev)
553{
554 struct bat_priv *bat_priv;
555 struct batman_ogm_packet *batman_ogm_packet;
556 struct hard_iface *hard_iface;
557 int ret;
558
559 hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype);
560 skb = skb_share_check(skb, GFP_ATOMIC);
561
562 /* skb was released by skb_share_check() */
563 if (!skb)
564 goto err_out;
565
566 /* packet should hold at least type and version */
567 if (unlikely(!pskb_may_pull(skb, 2)))
568 goto err_free;
569
570 /* expect a valid ethernet header here. */
571 if (unlikely(skb->mac_len != sizeof(struct ethhdr) ||
572 !skb_mac_header(skb)))
573 goto err_free;
574
575 if (!hard_iface->soft_iface)
576 goto err_free;
577
578 bat_priv = netdev_priv(hard_iface->soft_iface);
579
580 if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
581 goto err_free;
582
583 /* discard frames on not active interfaces */
584 if (hard_iface->if_status != IF_ACTIVE)
585 goto err_free;
586
587 batman_ogm_packet = (struct batman_ogm_packet *)skb->data;
588
589 if (batman_ogm_packet->header.version != COMPAT_VERSION) {
590 bat_dbg(DBG_BATMAN, bat_priv,
591 "Drop packet: incompatible batman version (%i)\n",
592 batman_ogm_packet->header.version);
593 goto err_free;
594 }
595
596 /* all receive handlers return whether they received or reused
597 * the supplied skb. if not, we have to free the skb. */
598
599 switch (batman_ogm_packet->header.packet_type) {
600 /* batman originator packet */
601 case BAT_OGM:
602 ret = recv_bat_ogm_packet(skb, hard_iface);
603 break;
604
605 /* batman icmp packet */
606 case BAT_ICMP:
607 ret = recv_icmp_packet(skb, hard_iface);
608 break;
609
610 /* unicast packet */
611 case BAT_UNICAST:
612 ret = recv_unicast_packet(skb, hard_iface);
613 break;
614
615 /* fragmented unicast packet */
616 case BAT_UNICAST_FRAG:
617 ret = recv_ucast_frag_packet(skb, hard_iface);
618 break;
619
620 /* broadcast packet */
621 case BAT_BCAST:
622 ret = recv_bcast_packet(skb, hard_iface);
623 break;
624
625 /* vis packet */
626 case BAT_VIS:
627 ret = recv_vis_packet(skb, hard_iface);
628 break;
629 /* Translation table query (request or response) */
630 case BAT_TT_QUERY:
631 ret = recv_tt_query(skb, hard_iface);
632 break;
633 /* Roaming advertisement */
634 case BAT_ROAM_ADV:
635 ret = recv_roam_adv(skb, hard_iface);
636 break;
637 default:
638 ret = NET_RX_DROP;
639 }
640
641 if (ret == NET_RX_DROP)
642 kfree_skb(skb);
643
644 /* return NET_RX_SUCCESS in any case as we
645 * most probably dropped the packet for
646 * routing-logical reasons. */
647
648 return NET_RX_SUCCESS;
649
650err_free:
651 kfree_skb(skb);
652err_out:
653 return NET_RX_DROP;
654}
655
656/* This function returns true if the interface represented by ifindex is a 548/* This function returns true if the interface represented by ifindex is a
657 * 802.11 wireless device */ 549 * 802.11 wireless device */
658bool is_wifi_iface(int ifindex) 550bool is_wifi_iface(int ifindex)