aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/batman-adv/debugfs.c23
-rw-r--r--net/batman-adv/multicast.c104
-rw-r--r--net/batman-adv/multicast.h3
3 files changed, 130 insertions, 0 deletions
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/multicast.c b/net/batman-adv/multicast.c
index 2d1a896fb66b..d3222db60fd0 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -41,6 +41,7 @@
41#include <linux/printk.h> 41#include <linux/printk.h>
42#include <linux/rculist.h> 42#include <linux/rculist.h>
43#include <linux/rcupdate.h> 43#include <linux/rcupdate.h>
44#include <linux/seq_file.h>
44#include <linux/skbuff.h> 45#include <linux/skbuff.h>
45#include <linux/slab.h> 46#include <linux/slab.h>
46#include <linux/spinlock.h> 47#include <linux/spinlock.h>
@@ -52,6 +53,8 @@
52#include <net/ip.h> 53#include <net/ip.h>
53#include <net/ipv6.h> 54#include <net/ipv6.h>
54 55
56#include "hard-interface.h"
57#include "hash.h"
55#include "packet.h" 58#include "packet.h"
56#include "translation-table.h" 59#include "translation-table.h"
57 60
@@ -1130,6 +1133,107 @@ void batadv_mcast_init(struct batadv_priv *bat_priv)
1130} 1133}
1131 1134
1132/** 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/**
1133 * batadv_mcast_free - free the multicast optimizations structures 1237 * batadv_mcast_free - free the multicast optimizations structures
1134 * @bat_priv: the bat priv with all the soft interface information 1238 * @bat_priv: the bat priv with all the soft interface information
1135 */ 1239 */
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);