aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-07-01 17:05:00 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-01 17:05:00 -0400
commit3ea00443f1b17405ce9e1421bb7706777339926e (patch)
treebc2708a8e693cc19ca8a6501c4307a3f62055d99 /net/batman-adv
parentca9354a1d47d8e30dee114fc946fd71f1d403ca7 (diff)
parent4e3e823b5a503235630921287f130e1d8d22d200 (diff)
Merge tag 'batadv-next-for-davem-20160701' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says: ==================== This feature patchset includes the following changes: - two patches with minimal clean up work by Antonio Quartulli and Simon Wunderlich - eight patches of B.A.T.M.A.N. V, API and documentation clean up work, by Antonio Quartulli and Marek Lindner - Andrew Lunn fixed the skb priority adoption when forwarding fragmented packets (two patches) - Multicast optimization support is now enabled for bridges which comes with some protocol updates, by Linus Luessing ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/Kconfig2
-rw-r--r--net/batman-adv/bat_algo.h7
-rw-r--r--net/batman-adv/bat_iv_ogm.c72
-rw-r--r--net/batman-adv/bat_v.c29
-rw-r--r--net/batman-adv/bat_v_elp.c4
-rw-r--r--net/batman-adv/bat_v_ogm.c4
-rw-r--r--net/batman-adv/debugfs.c23
-rw-r--r--net/batman-adv/fragmentation.c12
-rw-r--r--net/batman-adv/gateway_client.c15
-rw-r--r--net/batman-adv/gateway_common.c6
-rw-r--r--net/batman-adv/hard-interface.c6
-rw-r--r--net/batman-adv/main.c2
-rw-r--r--net/batman-adv/main.h6
-rw-r--r--net/batman-adv/multicast.c499
-rw-r--r--net/batman-adv/multicast.h3
-rw-r--r--net/batman-adv/originator.c40
-rw-r--r--net/batman-adv/originator.h6
-rw-r--r--net/batman-adv/packet.h7
-rw-r--r--net/batman-adv/routing.c2
-rw-r--r--net/batman-adv/send.c61
-rw-r--r--net/batman-adv/send.h4
-rw-r--r--net/batman-adv/soft-interface.c10
-rw-r--r--net/batman-adv/sysfs.c22
-rw-r--r--net/batman-adv/translation-table.c2
-rw-r--r--net/batman-adv/types.h32
25 files changed, 694 insertions, 182 deletions
diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig
index f66930ee3c0b..833bb145ba3c 100644
--- a/net/batman-adv/Kconfig
+++ b/net/batman-adv/Kconfig
@@ -66,7 +66,7 @@ config BATMAN_ADV_NC
66 66
67config BATMAN_ADV_MCAST 67config BATMAN_ADV_MCAST
68 bool "Multicast optimisation" 68 bool "Multicast optimisation"
69 depends on BATMAN_ADV 69 depends on BATMAN_ADV && INET && !(BRIDGE=m && BATMAN_ADV=y)
70 default n 70 default n
71 help 71 help
72 This option enables the multicast optimisation which aims to 72 This option enables the multicast optimisation which aims to
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h
index 03dafd33d23b..36542962de7d 100644
--- a/net/batman-adv/bat_algo.h
+++ b/net/batman-adv/bat_algo.h
@@ -18,13 +18,14 @@
18#ifndef _NET_BATMAN_ADV_BAT_ALGO_H_ 18#ifndef _NET_BATMAN_ADV_BAT_ALGO_H_
19#define _NET_BATMAN_ADV_BAT_ALGO_H_ 19#define _NET_BATMAN_ADV_BAT_ALGO_H_
20 20
21struct batadv_priv; 21#include "main.h"
22 22
23int batadv_iv_init(void); 23int batadv_iv_init(void);
24 24
25#ifdef CONFIG_BATMAN_ADV_BATMAN_V 25#ifdef CONFIG_BATMAN_ADV_BATMAN_V
26 26
27int batadv_v_init(void); 27int batadv_v_init(void);
28void batadv_v_hardif_init(struct batadv_hard_iface *hardif);
28int batadv_v_mesh_init(struct batadv_priv *bat_priv); 29int batadv_v_mesh_init(struct batadv_priv *bat_priv);
29void batadv_v_mesh_free(struct batadv_priv *bat_priv); 30void batadv_v_mesh_free(struct batadv_priv *bat_priv);
30 31
@@ -35,6 +36,10 @@ static inline int batadv_v_init(void)
35 return 0; 36 return 0;
36} 37}
37 38
39static inline void batadv_v_hardif_init(struct batadv_hard_iface *hardif)
40{
41}
42
38static inline int batadv_v_mesh_init(struct batadv_priv *bat_priv) 43static inline int batadv_v_mesh_init(struct batadv_priv *bat_priv)
39{ 44{
40 return 0; 45 return 0;
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index ce2f203048d3..4815db978c27 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -30,6 +30,7 @@
30#include <linux/if_ether.h> 30#include <linux/if_ether.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <linux/kernel.h>
33#include <linux/list.h> 34#include <linux/list.h>
34#include <linux/kref.h> 35#include <linux/kref.h>
35#include <linux/lockdep.h> 36#include <linux/lockdep.h>
@@ -58,6 +59,8 @@
58#include "send.h" 59#include "send.h"
59#include "translation-table.h" 60#include "translation-table.h"
60 61
62static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work);
63
61/** 64/**
62 * enum batadv_dup_status - duplicate status 65 * enum batadv_dup_status - duplicate status
63 * @BATADV_NO_DUP: the packet is no duplicate 66 * @BATADV_NO_DUP: the packet is no duplicate
@@ -336,7 +339,8 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
336{ 339{
337 struct batadv_neigh_node *neigh_node; 340 struct batadv_neigh_node *neigh_node;
338 341
339 neigh_node = batadv_neigh_node_new(orig_node, hard_iface, neigh_addr); 342 neigh_node = batadv_neigh_node_get_or_create(orig_node,
343 hard_iface, neigh_addr);
340 if (!neigh_node) 344 if (!neigh_node)
341 goto out; 345 goto out;
342 346
@@ -730,7 +734,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
730 734
731 /* start timer for this packet */ 735 /* start timer for this packet */
732 INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, 736 INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
733 batadv_send_outstanding_bat_ogm_packet); 737 batadv_iv_send_outstanding_bat_ogm_packet);
734 queue_delayed_work(batadv_event_workqueue, 738 queue_delayed_work(batadv_event_workqueue,
735 &forw_packet_aggr->delayed_work, 739 &forw_packet_aggr->delayed_work,
736 send_time - jiffies); 740 send_time - jiffies);
@@ -937,6 +941,19 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
937 u16 tvlv_len = 0; 941 u16 tvlv_len = 0;
938 unsigned long send_time; 942 unsigned long send_time;
939 943
944 if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
945 (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
946 return;
947
948 /* the interface gets activated here to avoid race conditions between
949 * the moment of activating the interface in
950 * hardif_activate_interface() where the originator mac is set and
951 * outdated packets (especially uninitialized mac addresses) in the
952 * packet queue
953 */
954 if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
955 hard_iface->if_status = BATADV_IF_ACTIVE;
956
940 primary_if = batadv_primary_if_get_selected(bat_priv); 957 primary_if = batadv_primary_if_get_selected(bat_priv);
941 958
942 if (hard_iface == primary_if) { 959 if (hard_iface == primary_if) {
@@ -1778,6 +1795,45 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
1778 batadv_orig_node_put(orig_node); 1795 batadv_orig_node_put(orig_node);
1779} 1796}
1780 1797
1798static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
1799{
1800 struct delayed_work *delayed_work;
1801 struct batadv_forw_packet *forw_packet;
1802 struct batadv_priv *bat_priv;
1803
1804 delayed_work = to_delayed_work(work);
1805 forw_packet = container_of(delayed_work, struct batadv_forw_packet,
1806 delayed_work);
1807 bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
1808 spin_lock_bh(&bat_priv->forw_bat_list_lock);
1809 hlist_del(&forw_packet->list);
1810 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
1811
1812 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
1813 goto out;
1814
1815 batadv_iv_ogm_emit(forw_packet);
1816
1817 /* we have to have at least one packet in the queue to determine the
1818 * queues wake up time unless we are shutting down.
1819 *
1820 * only re-schedule if this is the "original" copy, e.g. the OGM of the
1821 * primary interface should only be rescheduled once per period, but
1822 * this function will be called for the forw_packet instances of the
1823 * other secondary interfaces as well.
1824 */
1825 if (forw_packet->own &&
1826 forw_packet->if_incoming == forw_packet->if_outgoing)
1827 batadv_iv_ogm_schedule(forw_packet->if_incoming);
1828
1829out:
1830 /* don't count own packet */
1831 if (!forw_packet->own)
1832 atomic_inc(&bat_priv->batman_queue_left);
1833
1834 batadv_forw_packet_free(forw_packet);
1835}
1836
1781static int batadv_iv_ogm_receive(struct sk_buff *skb, 1837static int batadv_iv_ogm_receive(struct sk_buff *skb,
1782 struct batadv_hard_iface *if_incoming) 1838 struct batadv_hard_iface *if_incoming)
1783{ 1839{
@@ -1794,7 +1850,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1794 /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface 1850 /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
1795 * that does not have B.A.T.M.A.N. IV enabled ? 1851 * that does not have B.A.T.M.A.N. IV enabled ?
1796 */ 1852 */
1797 if (bat_priv->bat_algo_ops->bat_ogm_emit != batadv_iv_ogm_emit) 1853 if (bat_priv->bat_algo_ops->bat_iface_enable !=
1854 batadv_iv_ogm_iface_enable)
1798 return NET_RX_DROP; 1855 return NET_RX_DROP;
1799 1856
1800 batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX); 1857 batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
@@ -2052,14 +2109,19 @@ out:
2052 return ret; 2109 return ret;
2053} 2110}
2054 2111
2112static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
2113{
2114 /* begin scheduling originator messages on that interface */
2115 batadv_iv_ogm_schedule(hard_iface);
2116}
2117
2055static struct batadv_algo_ops batadv_batman_iv __read_mostly = { 2118static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
2056 .name = "BATMAN_IV", 2119 .name = "BATMAN_IV",
2120 .bat_iface_activate = batadv_iv_iface_activate,
2057 .bat_iface_enable = batadv_iv_ogm_iface_enable, 2121 .bat_iface_enable = batadv_iv_ogm_iface_enable,
2058 .bat_iface_disable = batadv_iv_ogm_iface_disable, 2122 .bat_iface_disable = batadv_iv_ogm_iface_disable,
2059 .bat_iface_update_mac = batadv_iv_ogm_iface_update_mac, 2123 .bat_iface_update_mac = batadv_iv_ogm_iface_update_mac,
2060 .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set, 2124 .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set,
2061 .bat_ogm_schedule = batadv_iv_ogm_schedule,
2062 .bat_ogm_emit = batadv_iv_ogm_emit,
2063 .bat_neigh_cmp = batadv_iv_ogm_neigh_cmp, 2125 .bat_neigh_cmp = batadv_iv_ogm_neigh_cmp,
2064 .bat_neigh_is_similar_or_better = batadv_iv_ogm_neigh_is_sob, 2126 .bat_neigh_is_similar_or_better = batadv_iv_ogm_neigh_is_sob,
2065 .bat_neigh_print = batadv_iv_neigh_print, 2127 .bat_neigh_print = batadv_iv_neigh_print,
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 0a12e5cdd65d..c2fea812fb48 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -70,11 +70,6 @@ static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
70 if (ret < 0) 70 if (ret < 0)
71 batadv_v_elp_iface_disable(hard_iface); 71 batadv_v_elp_iface_disable(hard_iface);
72 72
73 /* enable link throughput auto-detection by setting the throughput
74 * override to zero
75 */
76 atomic_set(&hard_iface->bat_v.throughput_override, 0);
77
78 return ret; 73 return ret;
79} 74}
80 75
@@ -119,14 +114,6 @@ batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
119 batadv_v_elp_throughput_metric_update); 114 batadv_v_elp_throughput_metric_update);
120} 115}
121 116
122static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface)
123{
124}
125
126static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet)
127{
128}
129
130/** 117/**
131 * batadv_v_orig_print_neigh - print neighbors for the originator table 118 * batadv_v_orig_print_neigh - print neighbors for the originator table
132 * @orig_node: the orig_node for which the neighbors are printed 119 * @orig_node: the orig_node for which the neighbors are printed
@@ -340,8 +327,6 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
340 .bat_iface_update_mac = batadv_v_iface_update_mac, 327 .bat_iface_update_mac = batadv_v_iface_update_mac,
341 .bat_primary_iface_set = batadv_v_primary_iface_set, 328 .bat_primary_iface_set = batadv_v_primary_iface_set,
342 .bat_hardif_neigh_init = batadv_v_hardif_neigh_init, 329 .bat_hardif_neigh_init = batadv_v_hardif_neigh_init,
343 .bat_ogm_emit = batadv_v_ogm_emit,
344 .bat_ogm_schedule = batadv_v_ogm_schedule,
345 .bat_orig_print = batadv_v_orig_print, 330 .bat_orig_print = batadv_v_orig_print,
346 .bat_neigh_cmp = batadv_v_neigh_cmp, 331 .bat_neigh_cmp = batadv_v_neigh_cmp,
347 .bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob, 332 .bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob,
@@ -349,6 +334,20 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
349}; 334};
350 335
351/** 336/**
337 * batadv_v_hardif_init - initialize the algorithm specific fields in the
338 * hard-interface object
339 * @hard_iface: the hard-interface to initialize
340 */
341void batadv_v_hardif_init(struct batadv_hard_iface *hard_iface)
342{
343 /* enable link throughput auto-detection by setting the throughput
344 * override to zero
345 */
346 atomic_set(&hard_iface->bat_v.throughput_override, 0);
347 atomic_set(&hard_iface->bat_v.elp_interval, 500);
348}
349
350/**
352 * batadv_v_mesh_init - initialize the B.A.T.M.A.N. V private resources for a 351 * batadv_v_mesh_init - initialize the B.A.T.M.A.N. V private resources for a
353 * mesh 352 * mesh
354 * @bat_priv: the object representing the mesh interface to initialise 353 * @bat_priv: the object representing the mesh interface to initialise
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index df42eb1365a0..cf0262becd08 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -344,7 +344,6 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
344 /* randomize initial seqno to avoid collision */ 344 /* randomize initial seqno to avoid collision */
345 get_random_bytes(&random_seqno, sizeof(random_seqno)); 345 get_random_bytes(&random_seqno, sizeof(random_seqno));
346 atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno); 346 atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno);
347 atomic_set(&hard_iface->bat_v.elp_interval, 500);
348 347
349 /* assume full-duplex by default */ 348 /* assume full-duplex by default */
350 hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX; 349 hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
@@ -443,7 +442,8 @@ static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv,
443 if (!orig_neigh) 442 if (!orig_neigh)
444 return; 443 return;
445 444
446 neigh = batadv_neigh_node_new(orig_neigh, if_incoming, neigh_addr); 445 neigh = batadv_neigh_node_get_or_create(orig_neigh,
446 if_incoming, neigh_addr);
447 if (!neigh) 447 if (!neigh)
448 goto orig_free; 448 goto orig_free;
449 449
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index 473ebb9a0e73..23ea9bfb9f67 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -683,8 +683,8 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
683 if (!orig_node) 683 if (!orig_node)
684 return; 684 return;
685 685
686 neigh_node = batadv_neigh_node_new(orig_node, if_incoming, 686 neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming,
687 ethhdr->h_source); 687 ethhdr->h_source);
688 if (!neigh_node) 688 if (!neigh_node)
689 goto out; 689 goto out;
690 690
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index 952900466d88..f187a8ff2184 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -48,6 +48,7 @@
48#include "distributed-arp-table.h" 48#include "distributed-arp-table.h"
49#include "gateway_client.h" 49#include "gateway_client.h"
50#include "icmp_socket.h" 50#include "icmp_socket.h"
51#include "multicast.h"
51#include "network-coding.h" 52#include "network-coding.h"
52#include "originator.h" 53#include "originator.h"
53#include "translation-table.h" 54#include "translation-table.h"
@@ -363,6 +364,22 @@ static int batadv_nc_nodes_open(struct inode *inode, struct file *file)
363} 364}
364#endif 365#endif
365 366
367#ifdef CONFIG_BATMAN_ADV_MCAST
368/**
369 * batadv_mcast_flags_open - prepare file handler for reads from mcast_flags
370 * @inode: inode which was opened
371 * @file: file handle to be initialized
372 *
373 * Return: 0 on success or negative error number in case of failure
374 */
375static int batadv_mcast_flags_open(struct inode *inode, struct file *file)
376{
377 struct net_device *net_dev = (struct net_device *)inode->i_private;
378
379 return single_open(file, batadv_mcast_flags_seq_print_text, net_dev);
380}
381#endif
382
366#define BATADV_DEBUGINFO(_name, _mode, _open) \ 383#define BATADV_DEBUGINFO(_name, _mode, _open) \
367struct batadv_debuginfo batadv_debuginfo_##_name = { \ 384struct batadv_debuginfo batadv_debuginfo_##_name = { \
368 .attr = { \ 385 .attr = { \
@@ -407,6 +424,9 @@ static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
407#ifdef CONFIG_BATMAN_ADV_NC 424#ifdef CONFIG_BATMAN_ADV_NC
408static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open); 425static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open);
409#endif 426#endif
427#ifdef CONFIG_BATMAN_ADV_MCAST
428static BATADV_DEBUGINFO(mcast_flags, S_IRUGO, batadv_mcast_flags_open);
429#endif
410 430
411static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { 431static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
412 &batadv_debuginfo_neighbors, 432 &batadv_debuginfo_neighbors,
@@ -424,6 +444,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
424#ifdef CONFIG_BATMAN_ADV_NC 444#ifdef CONFIG_BATMAN_ADV_NC
425 &batadv_debuginfo_nc_nodes, 445 &batadv_debuginfo_nc_nodes,
426#endif 446#endif
447#ifdef CONFIG_BATMAN_ADV_MCAST
448 &batadv_debuginfo_mcast_flags,
449#endif
427 NULL, 450 NULL,
428}; 451};
429 452
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index 65536db1bff7..9f41a0a0d6ab 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -27,7 +27,6 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/lockdep.h> 28#include <linux/lockdep.h>
29#include <linux/netdevice.h> 29#include <linux/netdevice.h>
30#include <linux/pkt_sched.h>
31#include <linux/skbuff.h> 30#include <linux/skbuff.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
33#include <linux/spinlock.h> 32#include <linux/spinlock.h>
@@ -414,7 +413,7 @@ static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
414 if (!skb_fragment) 413 if (!skb_fragment)
415 goto err; 414 goto err;
416 415
417 skb->priority = TC_PRIO_CONTROL; 416 skb_fragment->priority = skb->priority;
418 417
419 /* Eat the last mtu-bytes of the skb */ 418 /* Eat the last mtu-bytes of the skb */
420 skb_reserve(skb_fragment, header_size + ETH_HLEN); 419 skb_reserve(skb_fragment, header_size + ETH_HLEN);
@@ -473,6 +472,15 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
473 frag_header.reserved = 0; 472 frag_header.reserved = 0;
474 frag_header.no = 0; 473 frag_header.no = 0;
475 frag_header.total_size = htons(skb->len); 474 frag_header.total_size = htons(skb->len);
475
476 /* skb->priority values from 256->263 are magic values to
477 * directly indicate a specific 802.1d priority. This is used
478 * to allow 802.1d priority to be passed directly in from VLAN
479 * tags, etc.
480 */
481 if (skb->priority >= 256 && skb->priority <= 263)
482 frag_header.priority = skb->priority - 256;
483
476 ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); 484 ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr);
477 ether_addr_copy(frag_header.dest, orig_node->orig); 485 ether_addr_copy(frag_header.dest, orig_node->orig);
478 486
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 5839c569f769..18c3715e5e27 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -192,7 +192,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
192 192
193 tq_avg = router_ifinfo->bat_iv.tq_avg; 193 tq_avg = router_ifinfo->bat_iv.tq_avg;
194 194
195 switch (atomic_read(&bat_priv->gw_sel_class)) { 195 switch (atomic_read(&bat_priv->gw.sel_class)) {
196 case 1: /* fast connection */ 196 case 1: /* fast connection */
197 tmp_gw_factor = tq_avg * tq_avg; 197 tmp_gw_factor = tq_avg * tq_avg;
198 tmp_gw_factor *= gw_node->bandwidth_down; 198 tmp_gw_factor *= gw_node->bandwidth_down;
@@ -255,7 +255,7 @@ void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
255{ 255{
256 struct batadv_gw_node *curr_gw; 256 struct batadv_gw_node *curr_gw;
257 257
258 if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) 258 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
259 return; 259 return;
260 260
261 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 261 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
@@ -283,7 +283,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
283 struct batadv_neigh_ifinfo *router_ifinfo = NULL; 283 struct batadv_neigh_ifinfo *router_ifinfo = NULL;
284 char gw_addr[18] = { '\0' }; 284 char gw_addr[18] = { '\0' };
285 285
286 if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) 286 if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
287 goto out; 287 goto out;
288 288
289 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 289 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
@@ -402,8 +402,8 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
402 /* if the routing class is greater than 3 the value tells us how much 402 /* if the routing class is greater than 3 the value tells us how much
403 * greater the TQ value of the new gateway must be 403 * greater the TQ value of the new gateway must be
404 */ 404 */
405 if ((atomic_read(&bat_priv->gw_sel_class) > 3) && 405 if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
406 (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) 406 (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
407 goto out; 407 goto out;
408 408
409 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 409 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
@@ -638,8 +638,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
638 goto out; 638 goto out;
639 639
640 seq_printf(seq, 640 seq_printf(seq,
641 " %-12s (%s/%i) %17s [%10s]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", 641 " Gateway (#/255) Nexthop [outgoingIF]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
642 "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF",
643 BATADV_SOURCE_VERSION, primary_if->net_dev->name, 642 BATADV_SOURCE_VERSION, primary_if->net_dev->name,
644 primary_if->net_dev->dev_addr, net_dev->name); 643 primary_if->net_dev->dev_addr, net_dev->name);
645 644
@@ -821,7 +820,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
821 if (!gw_node) 820 if (!gw_node)
822 goto out; 821 goto out;
823 822
824 switch (atomic_read(&bat_priv->gw_mode)) { 823 switch (atomic_read(&bat_priv->gw.mode)) {
825 case BATADV_GW_MODE_SERVER: 824 case BATADV_GW_MODE_SERVER:
826 /* If we are a GW then we are our best GW. We can artificially 825 /* If we are a GW then we are our best GW. We can artificially
827 * set the tq towards ourself as the maximum value 826 * set the tq towards ourself as the maximum value
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 4423047889e1..3c269457776e 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -144,7 +144,7 @@ void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
144 u32 down, up; 144 u32 down, up;
145 char gw_mode; 145 char gw_mode;
146 146
147 gw_mode = atomic_read(&bat_priv->gw_mode); 147 gw_mode = atomic_read(&bat_priv->gw.mode);
148 148
149 switch (gw_mode) { 149 switch (gw_mode) {
150 case BATADV_GW_MODE_OFF: 150 case BATADV_GW_MODE_OFF:
@@ -241,8 +241,8 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
241 241
242 /* restart gateway selection if fast or late switching was enabled */ 242 /* restart gateway selection if fast or late switching was enabled */
243 if ((gateway.bandwidth_down != 0) && 243 if ((gateway.bandwidth_down != 0) &&
244 (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) && 244 (atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT) &&
245 (atomic_read(&bat_priv->gw_sel_class) > 2)) 245 (atomic_read(&bat_priv->gw.sel_class) > 2))
246 batadv_gw_check_election(bat_priv, orig); 246 batadv_gw_check_election(bat_priv, orig);
247} 247}
248 248
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 8c2f39962fa5..3696929e5692 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -37,6 +37,7 @@
37#include <linux/spinlock.h> 37#include <linux/spinlock.h>
38#include <linux/workqueue.h> 38#include <linux/workqueue.h>
39 39
40#include "bat_algo.h"
40#include "bridge_loop_avoidance.h" 41#include "bridge_loop_avoidance.h"
41#include "debugfs.h" 42#include "debugfs.h"
42#include "distributed-arp-table.h" 43#include "distributed-arp-table.h"
@@ -553,9 +554,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
553 554
554 batadv_hardif_recalc_extra_skbroom(soft_iface); 555 batadv_hardif_recalc_extra_skbroom(soft_iface);
555 556
556 /* begin scheduling originator messages on that interface */
557 batadv_schedule_bat_ogm(hard_iface);
558
559out: 557out:
560 return 0; 558 return 0;
561 559
@@ -686,6 +684,8 @@ batadv_hardif_add_interface(struct net_device *net_dev)
686 if (batadv_is_wifi_netdev(net_dev)) 684 if (batadv_is_wifi_netdev(net_dev))
687 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; 685 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
688 686
687 batadv_v_hardif_init(hard_iface);
688
689 /* extra reference for return */ 689 /* extra reference for return */
690 kref_init(&hard_iface->refcount); 690 kref_init(&hard_iface->refcount);
691 kref_get(&hard_iface->refcount); 691 kref_get(&hard_iface->refcount);
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 5f2974bd1227..627d14ececaf 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -569,8 +569,6 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops)
569 !bat_algo_ops->bat_iface_disable || 569 !bat_algo_ops->bat_iface_disable ||
570 !bat_algo_ops->bat_iface_update_mac || 570 !bat_algo_ops->bat_iface_update_mac ||
571 !bat_algo_ops->bat_primary_iface_set || 571 !bat_algo_ops->bat_primary_iface_set ||
572 !bat_algo_ops->bat_ogm_schedule ||
573 !bat_algo_ops->bat_ogm_emit ||
574 !bat_algo_ops->bat_neigh_cmp || 572 !bat_algo_ops->bat_neigh_cmp ||
575 !bat_algo_ops->bat_neigh_is_similar_or_better) { 573 !bat_algo_ops->bat_neigh_is_similar_or_better) {
576 pr_info("Routing algo '%s' does not implement required ops\n", 574 pr_info("Routing algo '%s' does not implement required ops\n",
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 76925266deed..cd83e2824f70 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -24,7 +24,7 @@
24#define BATADV_DRIVER_DEVICE "batman-adv" 24#define BATADV_DRIVER_DEVICE "batman-adv"
25 25
26#ifndef BATADV_SOURCE_VERSION 26#ifndef BATADV_SOURCE_VERSION
27#define BATADV_SOURCE_VERSION "2016.2" 27#define BATADV_SOURCE_VERSION "2016.3"
28#endif 28#endif
29 29
30/* B.A.T.M.A.N. parameters */ 30/* B.A.T.M.A.N. parameters */
@@ -231,6 +231,7 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr);
231 * @BATADV_DBG_BLA: bridge loop avoidance messages 231 * @BATADV_DBG_BLA: bridge loop avoidance messages
232 * @BATADV_DBG_DAT: ARP snooping and DAT related messages 232 * @BATADV_DBG_DAT: ARP snooping and DAT related messages
233 * @BATADV_DBG_NC: network coding related messages 233 * @BATADV_DBG_NC: network coding related messages
234 * @BATADV_DBG_MCAST: multicast related messages
234 * @BATADV_DBG_ALL: the union of all the above log levels 235 * @BATADV_DBG_ALL: the union of all the above log levels
235 */ 236 */
236enum batadv_dbg_level { 237enum batadv_dbg_level {
@@ -240,7 +241,8 @@ enum batadv_dbg_level {
240 BATADV_DBG_BLA = BIT(3), 241 BATADV_DBG_BLA = BIT(3),
241 BATADV_DBG_DAT = BIT(4), 242 BATADV_DBG_DAT = BIT(4),
242 BATADV_DBG_NC = BIT(5), 243 BATADV_DBG_NC = BIT(5),
243 BATADV_DBG_ALL = 63, 244 BATADV_DBG_MCAST = BIT(6),
245 BATADV_DBG_ALL = 127,
244}; 246};
245 247
246#ifdef CONFIG_BATMAN_ADV_DEBUG 248#ifdef CONFIG_BATMAN_ADV_DEBUG
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index c32f24fafe67..d3222db60fd0 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -25,17 +25,23 @@
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
27#include <linux/fs.h> 27#include <linux/fs.h>
28#include <linux/icmpv6.h>
29#include <linux/if_bridge.h>
28#include <linux/if_ether.h> 30#include <linux/if_ether.h>
29#include <linux/in6.h> 31#include <linux/igmp.h>
30#include <linux/in.h> 32#include <linux/in.h>
33#include <linux/in6.h>
31#include <linux/ip.h> 34#include <linux/ip.h>
32#include <linux/ipv6.h> 35#include <linux/ipv6.h>
36#include <linux/kernel.h>
33#include <linux/kref.h> 37#include <linux/kref.h>
34#include <linux/list.h> 38#include <linux/list.h>
35#include <linux/lockdep.h> 39#include <linux/lockdep.h>
36#include <linux/netdevice.h> 40#include <linux/netdevice.h>
41#include <linux/printk.h>
37#include <linux/rculist.h> 42#include <linux/rculist.h>
38#include <linux/rcupdate.h> 43#include <linux/rcupdate.h>
44#include <linux/seq_file.h>
39#include <linux/skbuff.h> 45#include <linux/skbuff.h>
40#include <linux/slab.h> 46#include <linux/slab.h>
41#include <linux/spinlock.h> 47#include <linux/spinlock.h>
@@ -43,18 +49,55 @@
43#include <linux/string.h> 49#include <linux/string.h>
44#include <linux/types.h> 50#include <linux/types.h>
45#include <net/addrconf.h> 51#include <net/addrconf.h>
52#include <net/if_inet6.h>
53#include <net/ip.h>
46#include <net/ipv6.h> 54#include <net/ipv6.h>
47 55
56#include "hard-interface.h"
57#include "hash.h"
48#include "packet.h" 58#include "packet.h"
49#include "translation-table.h" 59#include "translation-table.h"
50 60
51/** 61/**
62 * batadv_mcast_get_bridge - get the bridge on top of the softif if it exists
63 * @soft_iface: netdev struct of the mesh interface
64 *
65 * If the given soft interface has a bridge on top then the refcount
66 * of the according net device is increased.
67 *
68 * Return: NULL if no such bridge exists. Otherwise the net device of the
69 * bridge.
70 */
71static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
72{
73 struct net_device *upper = soft_iface;
74
75 rcu_read_lock();
76 do {
77 upper = netdev_master_upper_dev_get_rcu(upper);
78 } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
79
80 if (upper)
81 dev_hold(upper);
82 rcu_read_unlock();
83
84 return upper;
85}
86
87/**
52 * batadv_mcast_mla_softif_get - get softif multicast listeners 88 * batadv_mcast_mla_softif_get - get softif multicast listeners
53 * @dev: the device to collect multicast addresses from 89 * @dev: the device to collect multicast addresses from
54 * @mcast_list: a list to put found addresses into 90 * @mcast_list: a list to put found addresses into
55 * 91 *
56 * Collect multicast addresses of the local multicast listeners 92 * Collects multicast addresses of multicast listeners residing
57 * on the given soft interface, dev, in the given mcast_list. 93 * on this kernel on the given soft interface, dev, in
94 * the given mcast_list. In general, multicast listeners provided by
95 * your multicast receiving applications run directly on this node.
96 *
97 * If there is a bridge interface on top of dev, collects from that one
98 * instead. Just like with IP addresses and routes, multicast listeners
99 * will(/should) register to the bridge interface instead of an
100 * enslaved bat0.
58 * 101 *
59 * Return: -ENOMEM on memory allocation error or the number of 102 * Return: -ENOMEM on memory allocation error or the number of
60 * items added to the mcast_list otherwise. 103 * items added to the mcast_list otherwise.
@@ -62,12 +105,13 @@
62static int batadv_mcast_mla_softif_get(struct net_device *dev, 105static int batadv_mcast_mla_softif_get(struct net_device *dev,
63 struct hlist_head *mcast_list) 106 struct hlist_head *mcast_list)
64{ 107{
108 struct net_device *bridge = batadv_mcast_get_bridge(dev);
65 struct netdev_hw_addr *mc_list_entry; 109 struct netdev_hw_addr *mc_list_entry;
66 struct batadv_hw_addr *new; 110 struct batadv_hw_addr *new;
67 int ret = 0; 111 int ret = 0;
68 112
69 netif_addr_lock_bh(dev); 113 netif_addr_lock_bh(bridge ? bridge : dev);
70 netdev_for_each_mc_addr(mc_list_entry, dev) { 114 netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) {
71 new = kmalloc(sizeof(*new), GFP_ATOMIC); 115 new = kmalloc(sizeof(*new), GFP_ATOMIC);
72 if (!new) { 116 if (!new) {
73 ret = -ENOMEM; 117 ret = -ENOMEM;
@@ -78,7 +122,10 @@ static int batadv_mcast_mla_softif_get(struct net_device *dev,
78 hlist_add_head(&new->list, mcast_list); 122 hlist_add_head(&new->list, mcast_list);
79 ret++; 123 ret++;
80 } 124 }
81 netif_addr_unlock_bh(dev); 125 netif_addr_unlock_bh(bridge ? bridge : dev);
126
127 if (bridge)
128 dev_put(bridge);
82 129
83 return ret; 130 return ret;
84} 131}
@@ -104,6 +151,83 @@ static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr,
104} 151}
105 152
106/** 153/**
154 * batadv_mcast_mla_br_addr_cpy - copy a bridge multicast address
155 * @dst: destination to write to - a multicast MAC address
156 * @src: source to read from - a multicast IP address
157 *
158 * Converts a given multicast IPv4/IPv6 address from a bridge
159 * to its matching multicast MAC address and copies it into the given
160 * destination buffer.
161 *
162 * Caller needs to make sure the destination buffer can hold
163 * at least ETH_ALEN bytes.
164 */
165static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
166{
167 if (src->proto == htons(ETH_P_IP))
168 ip_eth_mc_map(src->u.ip4, dst);
169#if IS_ENABLED(CONFIG_IPV6)
170 else if (src->proto == htons(ETH_P_IPV6))
171 ipv6_eth_mc_map(&src->u.ip6, dst);
172#endif
173 else
174 eth_zero_addr(dst);
175}
176
177/**
178 * batadv_mcast_mla_bridge_get - get bridged-in multicast listeners
179 * @dev: a bridge slave whose bridge to collect multicast addresses from
180 * @mcast_list: a list to put found addresses into
181 *
182 * Collects multicast addresses of multicast listeners residing
183 * on foreign, non-mesh devices which we gave access to our mesh via
184 * a bridge on top of the given soft interface, dev, in the given
185 * mcast_list.
186 *
187 * Return: -ENOMEM on memory allocation error or the number of
188 * items added to the mcast_list otherwise.
189 */
190static int batadv_mcast_mla_bridge_get(struct net_device *dev,
191 struct hlist_head *mcast_list)
192{
193 struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
194 struct br_ip_list *br_ip_entry, *tmp;
195 struct batadv_hw_addr *new;
196 u8 mcast_addr[ETH_ALEN];
197 int ret;
198
199 /* we don't need to detect these devices/listeners, the IGMP/MLD
200 * snooping code of the Linux bridge already does that for us
201 */
202 ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
203 if (ret < 0)
204 goto out;
205
206 list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
207 batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
208 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
209 continue;
210
211 new = kmalloc(sizeof(*new), GFP_ATOMIC);
212 if (!new) {
213 ret = -ENOMEM;
214 break;
215 }
216
217 ether_addr_copy(new->addr, mcast_addr);
218 hlist_add_head(&new->list, mcast_list);
219 }
220
221out:
222 list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
223 list_del(&br_ip_entry->list);
224 kfree(br_ip_entry);
225 }
226
227 return ret;
228}
229
230/**
107 * batadv_mcast_mla_list_free - free a list of multicast addresses 231 * batadv_mcast_mla_list_free - free a list of multicast addresses
108 * @bat_priv: the bat priv with all the soft interface information 232 * @bat_priv: the bat priv with all the soft interface information
109 * @mcast_list: the list to free 233 * @mcast_list: the list to free
@@ -214,44 +338,195 @@ static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
214} 338}
215 339
216/** 340/**
341 * batadv_mcast_querier_log - debug output regarding the querier status on link
342 * @bat_priv: the bat priv with all the soft interface information
343 * @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD")
344 * @old_state: the previous querier state on our link
345 * @new_state: the new querier state on our link
346 *
347 * Outputs debug messages to the logging facility with log level 'mcast'
348 * regarding changes to the querier status on the link which are relevant
349 * to our multicast optimizations.
350 *
351 * Usually this is about whether a querier appeared or vanished in
352 * our mesh or whether the querier is in the suboptimal position of being
353 * behind our local bridge segment: Snooping switches will directly
354 * forward listener reports to the querier, therefore batman-adv and
355 * the bridge will potentially not see these listeners - the querier is
356 * potentially shadowing listeners from us then.
357 *
358 * This is only interesting for nodes with a bridge on top of their
359 * soft interface.
360 */
361static void
362batadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto,
363 struct batadv_mcast_querier_state *old_state,
364 struct batadv_mcast_querier_state *new_state)
365{
366 if (!old_state->exists && new_state->exists)
367 batadv_info(bat_priv->soft_iface, "%s Querier appeared\n",
368 str_proto);
369 else if (old_state->exists && !new_state->exists)
370 batadv_info(bat_priv->soft_iface,
371 "%s Querier disappeared - multicast optimizations disabled\n",
372 str_proto);
373 else if (!bat_priv->mcast.bridged && !new_state->exists)
374 batadv_info(bat_priv->soft_iface,
375 "No %s Querier present - multicast optimizations disabled\n",
376 str_proto);
377
378 if (new_state->exists) {
379 if ((!old_state->shadowing && new_state->shadowing) ||
380 (!old_state->exists && new_state->shadowing))
381 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
382 "%s Querier is behind our bridged segment: Might shadow listeners\n",
383 str_proto);
384 else if (old_state->shadowing && !new_state->shadowing)
385 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
386 "%s Querier is not behind our bridged segment\n",
387 str_proto);
388 }
389}
390
391/**
392 * batadv_mcast_bridge_log - debug output for topology changes in bridged setups
393 * @bat_priv: the bat priv with all the soft interface information
394 * @bridged: a flag about whether the soft interface is currently bridged or not
395 * @querier_ipv4: (maybe) new status of a potential, selected IGMP querier
396 * @querier_ipv6: (maybe) new status of a potential, selected MLD querier
397 *
398 * If no bridges are ever used on this node, then this function does nothing.
399 *
400 * Otherwise this function outputs debug information to the 'mcast' log level
401 * which might be relevant to our multicast optimizations.
402 *
403 * More precisely, it outputs information when a bridge interface is added or
404 * removed from a soft interface. And when a bridge is present, it further
405 * outputs information about the querier state which is relevant for the
406 * multicast flags this node is going to set.
407 */
408static void
409batadv_mcast_bridge_log(struct batadv_priv *bat_priv, bool bridged,
410 struct batadv_mcast_querier_state *querier_ipv4,
411 struct batadv_mcast_querier_state *querier_ipv6)
412{
413 if (!bat_priv->mcast.bridged && bridged)
414 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
415 "Bridge added: Setting Unsnoopables(U)-flag\n");
416 else if (bat_priv->mcast.bridged && !bridged)
417 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
418 "Bridge removed: Unsetting Unsnoopables(U)-flag\n");
419
420 if (bridged) {
421 batadv_mcast_querier_log(bat_priv, "IGMP",
422 &bat_priv->mcast.querier_ipv4,
423 querier_ipv4);
424 batadv_mcast_querier_log(bat_priv, "MLD",
425 &bat_priv->mcast.querier_ipv6,
426 querier_ipv6);
427 }
428}
429
430/**
431 * batadv_mcast_flags_logs - output debug information about mcast flag changes
432 * @bat_priv: the bat priv with all the soft interface information
433 * @flags: flags indicating the new multicast state
434 *
435 * Whenever the multicast flags this nodes announces changes (@mcast_flags vs.
436 * bat_priv->mcast.flags), this notifies userspace via the 'mcast' log level.
437 */
438static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
439{
440 u8 old_flags = bat_priv->mcast.flags;
441 char str_old_flags[] = "[...]";
442
443 sprintf(str_old_flags, "[%c%c%c]",
444 (old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
445 (old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
446 (old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
447
448 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
449 "Changing multicast flags from '%s' to '[%c%c%c]'\n",
450 bat_priv->mcast.enabled ? str_old_flags : "<undefined>",
451 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
452 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
453 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
454}
455
456/**
217 * batadv_mcast_mla_tvlv_update - update multicast tvlv 457 * batadv_mcast_mla_tvlv_update - update multicast tvlv
218 * @bat_priv: the bat priv with all the soft interface information 458 * @bat_priv: the bat priv with all the soft interface information
219 * 459 *
220 * Updates the own multicast tvlv with our current multicast related settings, 460 * Updates the own multicast tvlv with our current multicast related settings,
221 * capabilities and inabilities. 461 * capabilities and inabilities.
222 * 462 *
223 * Return: true if the tvlv container is registered afterwards. Otherwise 463 * Return: false if we want all IPv4 && IPv6 multicast traffic and true
224 * returns false. 464 * otherwise.
225 */ 465 */
226static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv) 466static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv)
227{ 467{
228 struct batadv_tvlv_mcast_data mcast_data; 468 struct batadv_tvlv_mcast_data mcast_data;
469 struct batadv_mcast_querier_state querier4 = {false, false};
470 struct batadv_mcast_querier_state querier6 = {false, false};
471 struct net_device *dev = bat_priv->soft_iface;
472 bool bridged;
229 473
230 mcast_data.flags = BATADV_NO_FLAGS; 474 mcast_data.flags = BATADV_NO_FLAGS;
231 memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved)); 475 memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
232 476
233 /* Avoid attaching MLAs, if there is a bridge on top of our soft 477 bridged = batadv_mcast_has_bridge(bat_priv);
234 * interface, we don't support that yet (TODO) 478 if (!bridged)
479 goto update;
480
481#if !IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
482 pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n");
483#endif
484
485 querier4.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP);
486 querier4.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP);
487
488 querier6.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6);
489 querier6.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6);
490
491 mcast_data.flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;
492
493 /* 1) If no querier exists at all, then multicast listeners on
494 * our local TT clients behind the bridge will keep silent.
495 * 2) If the selected querier is on one of our local TT clients,
496 * behind the bridge, then this querier might shadow multicast
497 * listeners on our local TT clients, behind this bridge.
498 *
499 * In both cases, we will signalize other batman nodes that
500 * we need all multicast traffic of the according protocol.
235 */ 501 */
236 if (batadv_mcast_has_bridge(bat_priv)) { 502 if (!querier4.exists || querier4.shadowing)
237 if (bat_priv->mcast.enabled) { 503 mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV4;
238 batadv_tvlv_container_unregister(bat_priv,
239 BATADV_TVLV_MCAST, 1);
240 bat_priv->mcast.enabled = false;
241 }
242 504
243 return false; 505 if (!querier6.exists || querier6.shadowing)
244 } 506 mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV6;
507
508update:
509 batadv_mcast_bridge_log(bat_priv, bridged, &querier4, &querier6);
510
511 bat_priv->mcast.querier_ipv4.exists = querier4.exists;
512 bat_priv->mcast.querier_ipv4.shadowing = querier4.shadowing;
513
514 bat_priv->mcast.querier_ipv6.exists = querier6.exists;
515 bat_priv->mcast.querier_ipv6.shadowing = querier6.shadowing;
516
517 bat_priv->mcast.bridged = bridged;
245 518
246 if (!bat_priv->mcast.enabled || 519 if (!bat_priv->mcast.enabled ||
247 mcast_data.flags != bat_priv->mcast.flags) { 520 mcast_data.flags != bat_priv->mcast.flags) {
248 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 1, 521 batadv_mcast_flags_log(bat_priv, mcast_data.flags);
522 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2,
249 &mcast_data, sizeof(mcast_data)); 523 &mcast_data, sizeof(mcast_data));
250 bat_priv->mcast.flags = mcast_data.flags; 524 bat_priv->mcast.flags = mcast_data.flags;
251 bat_priv->mcast.enabled = true; 525 bat_priv->mcast.enabled = true;
252 } 526 }
253 527
254 return true; 528 return !(mcast_data.flags &
529 (BATADV_MCAST_WANT_ALL_IPV4 + BATADV_MCAST_WANT_ALL_IPV6));
255} 530}
256 531
257/** 532/**
@@ -274,6 +549,10 @@ void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
274 if (ret < 0) 549 if (ret < 0)
275 goto out; 550 goto out;
276 551
552 ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list);
553 if (ret < 0)
554 goto out;
555
277update: 556update:
278 batadv_mcast_mla_tt_retract(bat_priv, &mcast_list); 557 batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
279 batadv_mcast_mla_tt_add(bat_priv, &mcast_list); 558 batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
@@ -283,6 +562,31 @@ out:
283} 562}
284 563
285/** 564/**
565 * batadv_mcast_is_report_ipv4 - check for IGMP reports
566 * @skb: the ethernet frame destined for the mesh
567 *
568 * This call might reallocate skb data.
569 *
570 * Checks whether the given frame is a valid IGMP report.
571 *
572 * Return: If so then true, otherwise false.
573 */
574static bool batadv_mcast_is_report_ipv4(struct sk_buff *skb)
575{
576 if (ip_mc_check_igmp(skb, NULL) < 0)
577 return false;
578
579 switch (igmp_hdr(skb)->type) {
580 case IGMP_HOST_MEMBERSHIP_REPORT:
581 case IGMPV2_HOST_MEMBERSHIP_REPORT:
582 case IGMPV3_HOST_MEMBERSHIP_REPORT:
583 return true;
584 }
585
586 return false;
587}
588
589/**
286 * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential 590 * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential
287 * @bat_priv: the bat priv with all the soft interface information 591 * @bat_priv: the bat priv with all the soft interface information
288 * @skb: the IPv4 packet to check 592 * @skb: the IPv4 packet to check
@@ -304,6 +608,9 @@ static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
304 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr))) 608 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
305 return -ENOMEM; 609 return -ENOMEM;
306 610
611 if (batadv_mcast_is_report_ipv4(skb))
612 return -EINVAL;
613
307 iphdr = ip_hdr(skb); 614 iphdr = ip_hdr(skb);
308 615
309 /* TODO: Implement Multicast Router Discovery (RFC4286), 616 /* TODO: Implement Multicast Router Discovery (RFC4286),
@@ -320,6 +627,31 @@ static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
320 return 0; 627 return 0;
321} 628}
322 629
630#if IS_ENABLED(CONFIG_IPV6)
631/**
632 * batadv_mcast_is_report_ipv6 - check for MLD reports
633 * @skb: the ethernet frame destined for the mesh
634 *
635 * This call might reallocate skb data.
636 *
637 * Checks whether the given frame is a valid MLD report.
638 *
639 * Return: If so then true, otherwise false.
640 */
641static bool batadv_mcast_is_report_ipv6(struct sk_buff *skb)
642{
643 if (ipv6_mc_check_mld(skb, NULL) < 0)
644 return false;
645
646 switch (icmp6_hdr(skb)->icmp6_type) {
647 case ICMPV6_MGM_REPORT:
648 case ICMPV6_MLD2_REPORT:
649 return true;
650 }
651
652 return false;
653}
654
323/** 655/**
324 * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential 656 * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential
325 * @bat_priv: the bat priv with all the soft interface information 657 * @bat_priv: the bat priv with all the soft interface information
@@ -341,6 +673,9 @@ static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
341 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr))) 673 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
342 return -ENOMEM; 674 return -ENOMEM;
343 675
676 if (batadv_mcast_is_report_ipv6(skb))
677 return -EINVAL;
678
344 ip6hdr = ipv6_hdr(skb); 679 ip6hdr = ipv6_hdr(skb);
345 680
346 /* TODO: Implement Multicast Router Discovery (RFC4286), 681 /* TODO: Implement Multicast Router Discovery (RFC4286),
@@ -357,6 +692,7 @@ static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
357 692
358 return 0; 693 return 0;
359} 694}
695#endif
360 696
361/** 697/**
362 * batadv_mcast_forw_mode_check - check for optimized forwarding potential 698 * batadv_mcast_forw_mode_check - check for optimized forwarding potential
@@ -385,9 +721,11 @@ static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
385 case ETH_P_IP: 721 case ETH_P_IP:
386 return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb, 722 return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,
387 is_unsnoopable); 723 is_unsnoopable);
724#if IS_ENABLED(CONFIG_IPV6)
388 case ETH_P_IPV6: 725 case ETH_P_IPV6:
389 return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb, 726 return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,
390 is_unsnoopable); 727 is_unsnoopable);
728#endif
391 default: 729 default:
392 return -EINVAL; 730 return -EINVAL;
393 } 731 }
@@ -728,18 +1066,18 @@ static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
728} 1066}
729 1067
730/** 1068/**
731 * batadv_mcast_tvlv_ogm_handler_v1 - process incoming multicast tvlv container 1069 * batadv_mcast_tvlv_ogm_handler - process incoming multicast tvlv container
732 * @bat_priv: the bat priv with all the soft interface information 1070 * @bat_priv: the bat priv with all the soft interface information
733 * @orig: the orig_node of the ogm 1071 * @orig: the orig_node of the ogm
734 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) 1072 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
735 * @tvlv_value: tvlv buffer containing the multicast data 1073 * @tvlv_value: tvlv buffer containing the multicast data
736 * @tvlv_value_len: tvlv buffer length 1074 * @tvlv_value_len: tvlv buffer length
737 */ 1075 */
738static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, 1076static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
739 struct batadv_orig_node *orig, 1077 struct batadv_orig_node *orig,
740 u8 flags, 1078 u8 flags,
741 void *tvlv_value, 1079 void *tvlv_value,
742 u16 tvlv_value_len) 1080 u16 tvlv_value_len)
743{ 1081{
744 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 1082 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
745 u8 mcast_flags = BATADV_NO_FLAGS; 1083 u8 mcast_flags = BATADV_NO_FLAGS;
@@ -789,19 +1127,120 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
789 */ 1127 */
790void batadv_mcast_init(struct batadv_priv *bat_priv) 1128void batadv_mcast_init(struct batadv_priv *bat_priv)
791{ 1129{
792 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler_v1, 1130 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
793 NULL, BATADV_TVLV_MCAST, 1, 1131 NULL, BATADV_TVLV_MCAST, 2,
794 BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 1132 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
795} 1133}
796 1134
797/** 1135/**
1136 * batadv_mcast_flags_print_header - print own mcast flags to debugfs table
1137 * @bat_priv: the bat priv with all the soft interface information
1138 * @seq: debugfs table seq_file struct
1139 *
1140 * Prints our own multicast flags including a more specific reason why
1141 * they are set, that is prints the bridge and querier state too, to
1142 * the debugfs table specified via @seq.
1143 */
1144static void batadv_mcast_flags_print_header(struct batadv_priv *bat_priv,
1145 struct seq_file *seq)
1146{
1147 u8 flags = bat_priv->mcast.flags;
1148 char querier4, querier6, shadowing4, shadowing6;
1149 bool bridged = bat_priv->mcast.bridged;
1150
1151 if (bridged) {
1152 querier4 = bat_priv->mcast.querier_ipv4.exists ? '.' : '4';
1153 querier6 = bat_priv->mcast.querier_ipv6.exists ? '.' : '6';
1154 shadowing4 = bat_priv->mcast.querier_ipv4.shadowing ? '4' : '.';
1155 shadowing6 = bat_priv->mcast.querier_ipv6.shadowing ? '6' : '.';
1156 } else {
1157 querier4 = '?';
1158 querier6 = '?';
1159 shadowing4 = '?';
1160 shadowing6 = '?';
1161 }
1162
1163 seq_printf(seq, "Multicast flags (own flags: [%c%c%c])\n",
1164 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
1165 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
1166 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
1167 seq_printf(seq, "* Bridged [U]\t\t\t\t%c\n", bridged ? 'U' : '.');
1168 seq_printf(seq, "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n",
1169 querier4, querier6);
1170 seq_printf(seq, "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n",
1171 shadowing4, shadowing6);
1172 seq_puts(seq, "-------------------------------------------\n");
1173 seq_printf(seq, " %-10s %s\n", "Originator", "Flags");
1174}
1175
1176/**
1177 * batadv_mcast_flags_seq_print_text - print the mcast flags of other nodes
1178 * @seq: seq file to print on
1179 * @offset: not used
1180 *
1181 * This prints a table of (primary) originators and their according
1182 * multicast flags, including (in the header) our own.
1183 *
1184 * Return: always 0
1185 */
1186int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset)
1187{
1188 struct net_device *net_dev = (struct net_device *)seq->private;
1189 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1190 struct batadv_hard_iface *primary_if;
1191 struct batadv_hashtable *hash = bat_priv->orig_hash;
1192 struct batadv_orig_node *orig_node;
1193 struct hlist_head *head;
1194 u8 flags;
1195 u32 i;
1196
1197 primary_if = batadv_seq_print_text_primary_if_get(seq);
1198 if (!primary_if)
1199 return 0;
1200
1201 batadv_mcast_flags_print_header(bat_priv, seq);
1202
1203 for (i = 0; i < hash->size; i++) {
1204 head = &hash->table[i];
1205
1206 rcu_read_lock();
1207 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1208 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1209 &orig_node->capa_initialized))
1210 continue;
1211
1212 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1213 &orig_node->capabilities)) {
1214 seq_printf(seq, "%pM -\n", orig_node->orig);
1215 continue;
1216 }
1217
1218 flags = orig_node->mcast_flags;
1219
1220 seq_printf(seq, "%pM [%c%c%c]\n", orig_node->orig,
1221 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)
1222 ? 'U' : '.',
1223 (flags & BATADV_MCAST_WANT_ALL_IPV4)
1224 ? '4' : '.',
1225 (flags & BATADV_MCAST_WANT_ALL_IPV6)
1226 ? '6' : '.');
1227 }
1228 rcu_read_unlock();
1229 }
1230
1231 batadv_hardif_put(primary_if);
1232
1233 return 0;
1234}
1235
1236/**
798 * batadv_mcast_free - free the multicast optimizations structures 1237 * batadv_mcast_free - free the multicast optimizations structures
799 * @bat_priv: the bat priv with all the soft interface information 1238 * @bat_priv: the bat priv with all the soft interface information
800 */ 1239 */
801void batadv_mcast_free(struct batadv_priv *bat_priv) 1240void batadv_mcast_free(struct batadv_priv *bat_priv)
802{ 1241{
803 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1); 1242 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
804 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1); 1243 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
805 1244
806 spin_lock_bh(&bat_priv->tt.commit_lock); 1245 spin_lock_bh(&bat_priv->tt.commit_lock);
807 batadv_mcast_mla_tt_retract(bat_priv, NULL); 1246 batadv_mcast_mla_tt_retract(bat_priv, NULL);
diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h
index 80bceec55592..1fb00ba84907 100644
--- a/net/batman-adv/multicast.h
+++ b/net/batman-adv/multicast.h
@@ -20,6 +20,7 @@
20 20
21#include "main.h" 21#include "main.h"
22 22
23struct seq_file;
23struct sk_buff; 24struct sk_buff;
24 25
25/** 26/**
@@ -46,6 +47,8 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
46 47
47void batadv_mcast_init(struct batadv_priv *bat_priv); 48void batadv_mcast_init(struct batadv_priv *bat_priv);
48 49
50int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset);
51
49void batadv_mcast_free(struct batadv_priv *bat_priv); 52void batadv_mcast_free(struct batadv_priv *bat_priv);
50 53
51void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node); 54void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 7f51bc2c06eb..076d258c92e1 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -251,10 +251,8 @@ static void batadv_neigh_node_release(struct kref *ref)
251 struct hlist_node *node_tmp; 251 struct hlist_node *node_tmp;
252 struct batadv_neigh_node *neigh_node; 252 struct batadv_neigh_node *neigh_node;
253 struct batadv_neigh_ifinfo *neigh_ifinfo; 253 struct batadv_neigh_ifinfo *neigh_ifinfo;
254 struct batadv_algo_ops *bao;
255 254
256 neigh_node = container_of(ref, struct batadv_neigh_node, refcount); 255 neigh_node = container_of(ref, struct batadv_neigh_node, refcount);
257 bao = neigh_node->orig_node->bat_priv->bat_algo_ops;
258 256
259 hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, 257 hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
260 &neigh_node->ifinfo_list, list) { 258 &neigh_node->ifinfo_list, list) {
@@ -263,9 +261,6 @@ static void batadv_neigh_node_release(struct kref *ref)
263 261
264 batadv_hardif_neigh_put(neigh_node->hardif_neigh); 262 batadv_hardif_neigh_put(neigh_node->hardif_neigh);
265 263
266 if (bao->bat_neigh_free)
267 bao->bat_neigh_free(neigh_node);
268
269 batadv_hardif_put(neigh_node->if_incoming); 264 batadv_hardif_put(neigh_node->if_incoming);
270 265
271 kfree_rcu(neigh_node, rcu); 266 kfree_rcu(neigh_node, rcu);
@@ -602,19 +597,19 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
602} 597}
603 598
604/** 599/**
605 * batadv_neigh_node_new - create and init a new neigh_node object 600 * batadv_neigh_node_create - create a neigh node object
606 * @orig_node: originator object representing the neighbour 601 * @orig_node: originator object representing the neighbour
607 * @hard_iface: the interface where the neighbour is connected to 602 * @hard_iface: the interface where the neighbour is connected to
608 * @neigh_addr: the mac address of the neighbour interface 603 * @neigh_addr: the mac address of the neighbour interface
609 * 604 *
610 * Allocates a new neigh_node object and initialises all the generic fields. 605 * Allocates a new neigh_node object and initialises all the generic fields.
611 * 606 *
612 * Return: neighbor when found. Othwerwise NULL 607 * Return: the neighbour node if found or created or NULL otherwise.
613 */ 608 */
614struct batadv_neigh_node * 609static struct batadv_neigh_node *
615batadv_neigh_node_new(struct batadv_orig_node *orig_node, 610batadv_neigh_node_create(struct batadv_orig_node *orig_node,
616 struct batadv_hard_iface *hard_iface, 611 struct batadv_hard_iface *hard_iface,
617 const u8 *neigh_addr) 612 const u8 *neigh_addr)
618{ 613{
619 struct batadv_neigh_node *neigh_node; 614 struct batadv_neigh_node *neigh_node;
620 struct batadv_hardif_neigh_node *hardif_neigh = NULL; 615 struct batadv_hardif_neigh_node *hardif_neigh = NULL;
@@ -667,6 +662,29 @@ out:
667} 662}
668 663
669/** 664/**
665 * batadv_neigh_node_get_or_create - retrieve or create a neigh node object
666 * @orig_node: originator object representing the neighbour
667 * @hard_iface: the interface where the neighbour is connected to
668 * @neigh_addr: the mac address of the neighbour interface
669 *
670 * Return: the neighbour node if found or created or NULL otherwise.
671 */
672struct batadv_neigh_node *
673batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node,
674 struct batadv_hard_iface *hard_iface,
675 const u8 *neigh_addr)
676{
677 struct batadv_neigh_node *neigh_node = NULL;
678
679 /* first check without locking to avoid the overhead */
680 neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
681 if (neigh_node)
682 return neigh_node;
683
684 return batadv_neigh_node_create(orig_node, hard_iface, neigh_addr);
685}
686
687/**
670 * batadv_hardif_neigh_seq_print_text - print the single hop neighbour list 688 * batadv_hardif_neigh_seq_print_text - print the single hop neighbour list
671 * @seq: neighbour table seq_file struct 689 * @seq: neighbour table seq_file struct
672 * @offset: not used 690 * @offset: not used
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 64a8951e5844..566306bf05dc 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -46,9 +46,9 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
46void 46void
47batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh); 47batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh);
48struct batadv_neigh_node * 48struct batadv_neigh_node *
49batadv_neigh_node_new(struct batadv_orig_node *orig_node, 49batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node,
50 struct batadv_hard_iface *hard_iface, 50 struct batadv_hard_iface *hard_iface,
51 const u8 *neigh_addr); 51 const u8 *neigh_addr);
52void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node); 52void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node);
53struct batadv_neigh_node * 53struct batadv_neigh_node *
54batadv_orig_router_get(struct batadv_orig_node *orig_node, 54batadv_orig_router_get(struct batadv_orig_node *orig_node,
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 372128ddb474..71567794df17 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -420,6 +420,7 @@ struct batadv_unicast_4addr_packet {
420 * @dest: final destination used when routing fragments 420 * @dest: final destination used when routing fragments
421 * @orig: originator of the fragment used when merging the packet 421 * @orig: originator of the fragment used when merging the packet
422 * @no: fragment number within this sequence 422 * @no: fragment number within this sequence
423 * @priority: priority of frame, from ToS IP precedence or 802.1p
423 * @reserved: reserved byte for alignment 424 * @reserved: reserved byte for alignment
424 * @seqno: sequence identification 425 * @seqno: sequence identification
425 * @total_size: size of the merged packet 426 * @total_size: size of the merged packet
@@ -430,9 +431,11 @@ struct batadv_frag_packet {
430 u8 ttl; 431 u8 ttl;
431#if defined(__BIG_ENDIAN_BITFIELD) 432#if defined(__BIG_ENDIAN_BITFIELD)
432 u8 no:4; 433 u8 no:4;
433 u8 reserved:4; 434 u8 priority:3;
435 u8 reserved:1;
434#elif defined(__LITTLE_ENDIAN_BITFIELD) 436#elif defined(__LITTLE_ENDIAN_BITFIELD)
435 u8 reserved:4; 437 u8 reserved:1;
438 u8 priority:3;
436 u8 no:4; 439 u8 no:4;
437#else 440#else
438#error "unknown bitfield endianness" 441#error "unknown bitfield endianness"
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 396c0134c5ab..319a58820197 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1007,6 +1007,8 @@ int batadv_recv_frag_packet(struct sk_buff *skb,
1007 if (!orig_node_src) 1007 if (!orig_node_src)
1008 goto out; 1008 goto out;
1009 1009
1010 skb->priority = frag_packet->priority + 256;
1011
1010 /* Route the fragment if it is not for us and too big to be merged. */ 1012 /* Route the fragment if it is not for us and too big to be merged. */
1011 if (!batadv_is_my_mac(bat_priv, frag_packet->dest) && 1013 if (!batadv_is_my_mac(bat_priv, frag_packet->dest) &&
1012 batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) { 1014 batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) {
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index b1a4e8a811c8..59e695b5cfbd 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -428,27 +428,7 @@ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
428 orig_node, vid); 428 orig_node, vid);
429} 429}
430 430
431void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface) 431void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet)
432{
433 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
434
435 if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
436 (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
437 return;
438
439 /* the interface gets activated here to avoid race conditions between
440 * the moment of activating the interface in
441 * hardif_activate_interface() where the originator mac is set and
442 * outdated packets (especially uninitialized mac addresses) in the
443 * packet queue
444 */
445 if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
446 hard_iface->if_status = BATADV_IF_ACTIVE;
447
448 bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface);
449}
450
451static void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet)
452{ 432{
453 kfree_skb(forw_packet->skb); 433 kfree_skb(forw_packet->skb);
454 if (forw_packet->if_incoming) 434 if (forw_packet->if_incoming)
@@ -604,45 +584,6 @@ out:
604 atomic_inc(&bat_priv->bcast_queue_left); 584 atomic_inc(&bat_priv->bcast_queue_left);
605} 585}
606 586
607void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work)
608{
609 struct delayed_work *delayed_work;
610 struct batadv_forw_packet *forw_packet;
611 struct batadv_priv *bat_priv;
612
613 delayed_work = to_delayed_work(work);
614 forw_packet = container_of(delayed_work, struct batadv_forw_packet,
615 delayed_work);
616 bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
617 spin_lock_bh(&bat_priv->forw_bat_list_lock);
618 hlist_del(&forw_packet->list);
619 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
620
621 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
622 goto out;
623
624 bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet);
625
626 /* we have to have at least one packet in the queue to determine the
627 * queues wake up time unless we are shutting down.
628 *
629 * only re-schedule if this is the "original" copy, e.g. the OGM of the
630 * primary interface should only be rescheduled once per period, but
631 * this function will be called for the forw_packet instances of the
632 * other secondary interfaces as well.
633 */
634 if (forw_packet->own &&
635 forw_packet->if_incoming == forw_packet->if_outgoing)
636 batadv_schedule_bat_ogm(forw_packet->if_incoming);
637
638out:
639 /* don't count own packet */
640 if (!forw_packet->own)
641 atomic_inc(&bat_priv->batman_queue_left);
642
643 batadv_forw_packet_free(forw_packet);
644}
645
646void 587void
647batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, 588batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
648 const struct batadv_hard_iface *hard_iface) 589 const struct batadv_hard_iface *hard_iface)
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 6fd7270d8ce6..7cecb7563b45 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -26,8 +26,8 @@
26#include "packet.h" 26#include "packet.h"
27 27
28struct sk_buff; 28struct sk_buff;
29struct work_struct;
30 29
30void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet);
31int batadv_send_skb_to_orig(struct sk_buff *skb, 31int batadv_send_skb_to_orig(struct sk_buff *skb,
32 struct batadv_orig_node *orig_node, 32 struct batadv_orig_node *orig_node,
33 struct batadv_hard_iface *recv_if); 33 struct batadv_hard_iface *recv_if);
@@ -38,11 +38,9 @@ int batadv_send_broadcast_skb(struct sk_buff *skb,
38 struct batadv_hard_iface *hard_iface); 38 struct batadv_hard_iface *hard_iface);
39int batadv_send_unicast_skb(struct sk_buff *skb, 39int batadv_send_unicast_skb(struct sk_buff *skb,
40 struct batadv_neigh_node *neigh_node); 40 struct batadv_neigh_node *neigh_node);
41void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
42int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, 41int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
43 const struct sk_buff *skb, 42 const struct sk_buff *skb,
44 unsigned long delay); 43 unsigned long delay);
45void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work);
46void 44void
47batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, 45batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
48 const struct batadv_hard_iface *hard_iface); 46 const struct batadv_hard_iface *hard_iface);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 287a3879ed7e..4ba894ca8b2a 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -255,7 +255,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
255 if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) 255 if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
256 goto dropped; 256 goto dropped;
257 257
258 gw_mode = atomic_read(&bat_priv->gw_mode); 258 gw_mode = atomic_read(&bat_priv->gw.mode);
259 if (is_multicast_ether_addr(ethhdr->h_dest)) { 259 if (is_multicast_ether_addr(ethhdr->h_dest)) {
260 /* if gw mode is off, broadcast every packet */ 260 /* if gw mode is off, broadcast every packet */
261 if (gw_mode == BATADV_GW_MODE_OFF) { 261 if (gw_mode == BATADV_GW_MODE_OFF) {
@@ -808,6 +808,10 @@ static int batadv_softif_init_late(struct net_device *dev)
808 atomic_set(&bat_priv->distributed_arp_table, 1); 808 atomic_set(&bat_priv->distributed_arp_table, 1);
809#endif 809#endif
810#ifdef CONFIG_BATMAN_ADV_MCAST 810#ifdef CONFIG_BATMAN_ADV_MCAST
811 bat_priv->mcast.querier_ipv4.exists = false;
812 bat_priv->mcast.querier_ipv4.shadowing = false;
813 bat_priv->mcast.querier_ipv6.exists = false;
814 bat_priv->mcast.querier_ipv6.shadowing = false;
811 bat_priv->mcast.flags = BATADV_NO_FLAGS; 815 bat_priv->mcast.flags = BATADV_NO_FLAGS;
812 atomic_set(&bat_priv->multicast_mode, 1); 816 atomic_set(&bat_priv->multicast_mode, 1);
813 atomic_set(&bat_priv->mcast.num_disabled, 0); 817 atomic_set(&bat_priv->mcast.num_disabled, 0);
@@ -815,8 +819,8 @@ static int batadv_softif_init_late(struct net_device *dev)
815 atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); 819 atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0);
816 atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); 820 atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
817#endif 821#endif
818 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); 822 atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF);
819 atomic_set(&bat_priv->gw_sel_class, 20); 823 atomic_set(&bat_priv->gw.sel_class, 20);
820 atomic_set(&bat_priv->gw.bandwidth_down, 100); 824 atomic_set(&bat_priv->gw.bandwidth_down, 100);
821 atomic_set(&bat_priv->gw.bandwidth_up, 20); 825 atomic_set(&bat_priv->gw.bandwidth_up, 20);
822 atomic_set(&bat_priv->orig_interval, 1000); 826 atomic_set(&bat_priv->orig_interval, 1000);
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 414b2074165f..233abcf33c03 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -389,12 +389,12 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
389 return count; 389 return count;
390} 390}
391 391
392static inline ssize_t 392static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
393__batadv_store_uint_attr(const char *buff, size_t count, 393 int min, int max,
394 int min, int max, 394 void (*post_func)(struct net_device *),
395 void (*post_func)(struct net_device *), 395 const struct attribute *attr,
396 const struct attribute *attr, 396 atomic_t *attr_store,
397 atomic_t *attr_store, struct net_device *net_dev) 397 struct net_device *net_dev)
398{ 398{
399 int ret; 399 int ret;
400 400
@@ -427,7 +427,7 @@ static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr,
427 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 427 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
428 int bytes_written; 428 int bytes_written;
429 429
430 switch (atomic_read(&bat_priv->gw_mode)) { 430 switch (atomic_read(&bat_priv->gw.mode)) {
431 case BATADV_GW_MODE_CLIENT: 431 case BATADV_GW_MODE_CLIENT:
432 bytes_written = sprintf(buff, "%s\n", 432 bytes_written = sprintf(buff, "%s\n",
433 BATADV_GW_MODE_CLIENT_NAME); 433 BATADV_GW_MODE_CLIENT_NAME);
@@ -476,10 +476,10 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
476 return -EINVAL; 476 return -EINVAL;
477 } 477 }
478 478
479 if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) 479 if (atomic_read(&bat_priv->gw.mode) == gw_mode_tmp)
480 return count; 480 return count;
481 481
482 switch (atomic_read(&bat_priv->gw_mode)) { 482 switch (atomic_read(&bat_priv->gw.mode)) {
483 case BATADV_GW_MODE_CLIENT: 483 case BATADV_GW_MODE_CLIENT:
484 curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME; 484 curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME;
485 break; 485 break;
@@ -508,7 +508,7 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
508 * state 508 * state
509 */ 509 */
510 batadv_gw_check_client_stop(bat_priv); 510 batadv_gw_check_client_stop(bat_priv);
511 atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); 511 atomic_set(&bat_priv->gw.mode, (unsigned int)gw_mode_tmp);
512 batadv_gw_tvlv_container_update(bat_priv); 512 batadv_gw_tvlv_container_update(bat_priv);
513 return count; 513 return count;
514} 514}
@@ -624,7 +624,7 @@ BATADV_ATTR_SIF_UINT(orig_interval, orig_interval, S_IRUGO | S_IWUSR,
624 2 * BATADV_JITTER, INT_MAX, NULL); 624 2 * BATADV_JITTER, INT_MAX, NULL);
625BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, S_IRUGO | S_IWUSR, 0, 625BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, S_IRUGO | S_IWUSR, 0,
626 BATADV_TQ_MAX_VALUE, NULL); 626 BATADV_TQ_MAX_VALUE, NULL);
627BATADV_ATTR_SIF_UINT(gw_sel_class, gw_sel_class, S_IRUGO | S_IWUSR, 1, 627BATADV_ATTR_SIF_UINT(gw_sel_class, gw.sel_class, S_IRUGO | S_IWUSR, 1,
628 BATADV_TQ_MAX_VALUE, batadv_post_gw_reselect); 628 BATADV_TQ_MAX_VALUE, batadv_post_gw_reselect);
629static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, 629static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
630 batadv_store_gw_bwidth); 630 batadv_store_gw_bwidth);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 57ec87f37050..0d441aac1ad5 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -996,7 +996,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
996 struct batadv_tt_local_entry *tt_local; 996 struct batadv_tt_local_entry *tt_local;
997 struct batadv_hard_iface *primary_if; 997 struct batadv_hard_iface *primary_if;
998 struct hlist_head *head; 998 struct hlist_head *head;
999 unsigned short vid;
1000 u32 i; 999 u32 i;
1001 int last_seen_secs; 1000 int last_seen_secs;
1002 int last_seen_msecs; 1001 int last_seen_msecs;
@@ -1023,7 +1022,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
1023 tt_local = container_of(tt_common_entry, 1022 tt_local = container_of(tt_common_entry,
1024 struct batadv_tt_local_entry, 1023 struct batadv_tt_local_entry,
1025 common); 1024 common);
1026 vid = tt_common_entry->vid;
1027 last_seen_jiffies = jiffies - tt_local->last_seen; 1025 last_seen_jiffies = jiffies - tt_local->last_seen;
1028 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); 1026 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
1029 last_seen_secs = last_seen_msecs / 1000; 1027 last_seen_secs = last_seen_msecs / 1000;
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index ba846b078af8..02e22763a880 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -707,6 +707,8 @@ struct batadv_priv_debug_log {
707 * @list: list of available gateway nodes 707 * @list: list of available gateway nodes
708 * @list_lock: lock protecting gw_list & curr_gw 708 * @list_lock: lock protecting gw_list & curr_gw
709 * @curr_gw: pointer to currently selected gateway node 709 * @curr_gw: pointer to currently selected gateway node
710 * @mode: gateway operation: off, client or server (see batadv_gw_modes)
711 * @sel_class: gateway selection class (applies if gw_mode client)
710 * @bandwidth_down: advertised uplink download bandwidth (if gw_mode server) 712 * @bandwidth_down: advertised uplink download bandwidth (if gw_mode server)
711 * @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server) 713 * @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server)
712 * @reselect: bool indicating a gateway re-selection is in progress 714 * @reselect: bool indicating a gateway re-selection is in progress
@@ -715,6 +717,8 @@ struct batadv_priv_gw {
715 struct hlist_head list; 717 struct hlist_head list;
716 spinlock_t list_lock; /* protects gw_list & curr_gw */ 718 spinlock_t list_lock; /* protects gw_list & curr_gw */
717 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ 719 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
720 atomic_t mode;
721 atomic_t sel_class;
718 atomic_t bandwidth_down; 722 atomic_t bandwidth_down;
719 atomic_t bandwidth_up; 723 atomic_t bandwidth_up;
720 atomic_t reselect; 724 atomic_t reselect;
@@ -751,14 +755,28 @@ struct batadv_priv_dat {
751 755
752#ifdef CONFIG_BATMAN_ADV_MCAST 756#ifdef CONFIG_BATMAN_ADV_MCAST
753/** 757/**
758 * struct batadv_mcast_querier_state - IGMP/MLD querier state when bridged
759 * @exists: whether a querier exists in the mesh
760 * @shadowing: if a querier exists, whether it is potentially shadowing
761 * multicast listeners (i.e. querier is behind our own bridge segment)
762 */
763struct batadv_mcast_querier_state {
764 bool exists;
765 bool shadowing;
766};
767
768/**
754 * struct batadv_priv_mcast - per mesh interface mcast data 769 * struct batadv_priv_mcast - per mesh interface mcast data
755 * @mla_list: list of multicast addresses we are currently announcing via TT 770 * @mla_list: list of multicast addresses we are currently announcing via TT
756 * @want_all_unsnoopables_list: a list of orig_nodes wanting all unsnoopable 771 * @want_all_unsnoopables_list: a list of orig_nodes wanting all unsnoopable
757 * multicast traffic 772 * multicast traffic
758 * @want_all_ipv4_list: a list of orig_nodes wanting all IPv4 multicast traffic 773 * @want_all_ipv4_list: a list of orig_nodes wanting all IPv4 multicast traffic
759 * @want_all_ipv6_list: a list of orig_nodes wanting all IPv6 multicast traffic 774 * @want_all_ipv6_list: a list of orig_nodes wanting all IPv6 multicast traffic
775 * @querier_ipv4: the current state of an IGMP querier in the mesh
776 * @querier_ipv6: the current state of an MLD querier in the mesh
760 * @flags: the flags we have last sent in our mcast tvlv 777 * @flags: the flags we have last sent in our mcast tvlv
761 * @enabled: whether the multicast tvlv is currently enabled 778 * @enabled: whether the multicast tvlv is currently enabled
779 * @bridged: whether the soft interface has a bridge on top
762 * @num_disabled: number of nodes that have no mcast tvlv 780 * @num_disabled: number of nodes that have no mcast tvlv
763 * @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP traffic 781 * @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP traffic
764 * @num_want_all_ipv4: counter for items in want_all_ipv4_list 782 * @num_want_all_ipv4: counter for items in want_all_ipv4_list
@@ -771,8 +789,11 @@ struct batadv_priv_mcast {
771 struct hlist_head want_all_unsnoopables_list; 789 struct hlist_head want_all_unsnoopables_list;
772 struct hlist_head want_all_ipv4_list; 790 struct hlist_head want_all_ipv4_list;
773 struct hlist_head want_all_ipv6_list; 791 struct hlist_head want_all_ipv6_list;
792 struct batadv_mcast_querier_state querier_ipv4;
793 struct batadv_mcast_querier_state querier_ipv6;
774 u8 flags; 794 u8 flags;
775 bool enabled; 795 bool enabled;
796 bool bridged;
776 atomic_t num_disabled; 797 atomic_t num_disabled;
777 atomic_t num_want_all_unsnoopables; 798 atomic_t num_want_all_unsnoopables;
778 atomic_t num_want_all_ipv4; 799 atomic_t num_want_all_ipv4;
@@ -865,8 +886,6 @@ struct batadv_priv_bat_v {
865 * enabled 886 * enabled
866 * @multicast_mode: Enable or disable multicast optimizations on this node's 887 * @multicast_mode: Enable or disable multicast optimizations on this node's
867 * sender/originating side 888 * sender/originating side
868 * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes)
869 * @gw_sel_class: gateway selection class (applies if gw_mode client)
870 * @orig_interval: OGM broadcast interval in milliseconds 889 * @orig_interval: OGM broadcast interval in milliseconds
871 * @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop 890 * @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop
872 * @log_level: configured log level (see batadv_dbg_level) 891 * @log_level: configured log level (see batadv_dbg_level)
@@ -922,8 +941,6 @@ struct batadv_priv {
922#ifdef CONFIG_BATMAN_ADV_MCAST 941#ifdef CONFIG_BATMAN_ADV_MCAST
923 atomic_t multicast_mode; 942 atomic_t multicast_mode;
924#endif 943#endif
925 atomic_t gw_mode;
926 atomic_t gw_sel_class;
927 atomic_t orig_interval; 944 atomic_t orig_interval;
928 atomic_t hop_penalty; 945 atomic_t hop_penalty;
929#ifdef CONFIG_BATMAN_ADV_DEBUG 946#ifdef CONFIG_BATMAN_ADV_DEBUG
@@ -1271,8 +1288,6 @@ struct batadv_forw_packet {
1271 * @bat_iface_update_mac: (re-)init mac addresses of the protocol information 1288 * @bat_iface_update_mac: (re-)init mac addresses of the protocol information
1272 * belonging to this hard-interface 1289 * belonging to this hard-interface
1273 * @bat_primary_iface_set: called when primary interface is selected / changed 1290 * @bat_primary_iface_set: called when primary interface is selected / changed
1274 * @bat_ogm_schedule: prepare a new outgoing OGM for the send queue
1275 * @bat_ogm_emit: send scheduled OGM
1276 * @bat_hardif_neigh_init: called on creation of single hop entry 1291 * @bat_hardif_neigh_init: called on creation of single hop entry
1277 * @bat_neigh_cmp: compare the metrics of two neighbors for their respective 1292 * @bat_neigh_cmp: compare the metrics of two neighbors for their respective
1278 * outgoing interfaces 1293 * outgoing interfaces
@@ -1280,8 +1295,6 @@ struct batadv_forw_packet {
1280 * better than neigh2 for their respective outgoing interface from the metric 1295 * better than neigh2 for their respective outgoing interface from the metric
1281 * prospective 1296 * prospective
1282 * @bat_neigh_print: print the single hop neighbor list (optional) 1297 * @bat_neigh_print: print the single hop neighbor list (optional)
1283 * @bat_neigh_free: free the resources allocated by the routing algorithm for a
1284 * neigh_node object
1285 * @bat_orig_print: print the originator table (optional) 1298 * @bat_orig_print: print the originator table (optional)
1286 * @bat_orig_free: free the resources allocated by the routing algorithm for an 1299 * @bat_orig_free: free the resources allocated by the routing algorithm for an
1287 * orig_node object 1300 * orig_node object
@@ -1298,8 +1311,6 @@ struct batadv_algo_ops {
1298 void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); 1311 void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface);
1299 void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); 1312 void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface);
1300 void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface); 1313 void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface);
1301 void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface);
1302 void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
1303 /* neigh_node handling API */ 1314 /* neigh_node handling API */
1304 void (*bat_hardif_neigh_init)(struct batadv_hardif_neigh_node *neigh); 1315 void (*bat_hardif_neigh_init)(struct batadv_hardif_neigh_node *neigh);
1305 int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1, 1316 int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1,
@@ -1312,7 +1323,6 @@ struct batadv_algo_ops {
1312 struct batadv_neigh_node *neigh2, 1323 struct batadv_neigh_node *neigh2,
1313 struct batadv_hard_iface *if_outgoing2); 1324 struct batadv_hard_iface *if_outgoing2);
1314 void (*bat_neigh_print)(struct batadv_priv *priv, struct seq_file *seq); 1325 void (*bat_neigh_print)(struct batadv_priv *priv, struct seq_file *seq);
1315 void (*bat_neigh_free)(struct batadv_neigh_node *neigh);
1316 /* orig_node handling API */ 1326 /* orig_node handling API */
1317 void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq, 1327 void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq,
1318 struct batadv_hard_iface *hard_iface); 1328 struct batadv_hard_iface *hard_iface);