aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wunderlich <siwu@hrz.tu-chemnitz.de>2013-04-25 05:57:42 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-09 15:22:32 -0400
commit9f4980e68b4b72e6a4d7caadfacc54260d05ebf6 (patch)
treeddff273e32b44ba11aefcf9d380f47563504a194
parent0035f97e65761099cbfa9554ee8cd9bfc395eeea (diff)
batman-adv: remove vis functionality
This is replaced by a userspace program, we don't need this functionality to bloat the kernel. Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
-rw-r--r--Documentation/ABI/testing/sysfs-class-net-mesh11
-rw-r--r--Documentation/networking/batman-adv.txt50
-rw-r--r--net/batman-adv/Makefile1
-rw-r--r--net/batman-adv/bat_iv_ogm.c8
-rw-r--r--net/batman-adv/debugfs.c9
-rw-r--r--net/batman-adv/hard-interface.c9
-rw-r--r--net/batman-adv/main.c11
-rw-r--r--net/batman-adv/main.h2
-rw-r--r--net/batman-adv/packet.h21
-rw-r--r--net/batman-adv/routing.c51
-rw-r--r--net/batman-adv/routing.h2
-rw-r--r--net/batman-adv/send.c1
-rw-r--r--net/batman-adv/soft-interface.c1
-rw-r--r--net/batman-adv/sysfs.c72
-rw-r--r--net/batman-adv/types.h84
-rw-r--r--net/batman-adv/vis.c938
-rw-r--r--net/batman-adv/vis.h36
17 files changed, 3 insertions, 1304 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh
index bdcd8b4e38f2..f00a69b68a25 100644
--- a/Documentation/ABI/testing/sysfs-class-net-mesh
+++ b/Documentation/ABI/testing/sysfs-class-net-mesh
@@ -88,14 +88,3 @@ Contact: Marek Lindner <lindner_marek@yahoo.de>
88Description: 88Description:
89 Defines the routing procotol this mesh instance 89 Defines the routing procotol this mesh instance
90 uses to find the optimal paths through the mesh. 90 uses to find the optimal paths through the mesh.
91
92What: /sys/class/net/<mesh_iface>/mesh/vis_mode
93Date: May 2010
94Contact: Marek Lindner <lindner_marek@yahoo.de>
95Description:
96 Each batman node only maintains information about its
97 own local neighborhood, therefore generating graphs
98 showing the topology of the entire mesh is not easily
99 feasible without having a central instance to collect
100 the local topologies from all nodes. This file allows
101 to activate the collecting (server) mode.
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt
index c1d82047a4b1..897d1f4e1df1 100644
--- a/Documentation/networking/batman-adv.txt
+++ b/Documentation/networking/batman-adv.txt
@@ -69,8 +69,7 @@ folder:
69# aggregated_ogms gw_bandwidth log_level 69# aggregated_ogms gw_bandwidth log_level
70# ap_isolation gw_mode orig_interval 70# ap_isolation gw_mode orig_interval
71# bonding gw_sel_class routing_algo 71# bonding gw_sel_class routing_algo
72# bridge_loop_avoidance hop_penalty vis_mode 72# bridge_loop_avoidance hop_penalty fragmentation
73# fragmentation
74 73
75 74
76There is a special folder for debugging information: 75There is a special folder for debugging information:
@@ -78,7 +77,7 @@ There is a special folder for debugging information:
78# ls /sys/kernel/debug/batman_adv/bat0/ 77# ls /sys/kernel/debug/batman_adv/bat0/
79# bla_backbone_table log transtable_global 78# bla_backbone_table log transtable_global
80# bla_claim_table originators transtable_local 79# bla_claim_table originators transtable_local
81# gateways socket vis_data 80# gateways socket
82 81
83Some of the files contain all sort of status information regard- 82Some of the files contain all sort of status information regard-
84ing the mesh network. For example, you can view the table of 83ing the mesh network. For example, you can view the table of
@@ -127,51 +126,6 @@ ously assigned to interfaces now used by batman advanced, e.g.
127# ifconfig eth0 0.0.0.0 126# ifconfig eth0 0.0.0.0
128 127
129 128
130VISUALIZATION
131-------------
132
133If you want topology visualization, at least one mesh node must
134be configured as VIS-server:
135
136# echo "server" > /sys/class/net/bat0/mesh/vis_mode
137
138Each node is either configured as "server" or as "client" (de-
139fault: "client"). Clients send their topology data to the server
140next to them, and server synchronize with other servers. If there
141is no server configured (default) within the mesh, no topology
142information will be transmitted. With these "synchronizing
143servers", there can be 1 or more vis servers sharing the same (or
144at least very similar) data.
145
146When configured as server, you can get a topology snapshot of
147your mesh:
148
149# cat /sys/kernel/debug/batman_adv/bat0/vis_data
150
151This raw output is intended to be easily parsable and convertable
152with other tools. Have a look at the batctl README if you want a
153vis output in dot or json format for instance and how those out-
154puts could then be visualised in an image.
155
156The raw format consists of comma separated values per entry where
157each entry is giving information about a certain source inter-
158face. Each entry can/has to have the following values:
159-> "mac" - mac address of an originator's source interface
160 (each line begins with it)
161-> "TQ mac value" - src mac's link quality towards mac address
162 of a neighbor originator's interface which
163 is being used for routing
164-> "TT mac" - TT announced by source mac
165-> "PRIMARY" - this is a primary interface
166-> "SEC mac" - secondary mac address of source
167 (requires preceding PRIMARY)
168
169The TQ value has a range from 4 to 255 with 255 being the best.
170The TT entries are showing which hosts are connected to the mesh
171via bat0 or being bridged into the mesh network. The PRIMARY/SEC
172values are only applied on primary interfaces
173
174
175LOGGING/DEBUGGING 129LOGGING/DEBUGGING
176----------------- 130-----------------
177 131
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 489bb36f1b94..8ddbfe66d637 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -38,4 +38,3 @@ batman-adv-y += soft-interface.o
38batman-adv-y += sysfs.o 38batman-adv-y += sysfs.o
39batman-adv-y += translation-table.o 39batman-adv-y += translation-table.o
40batman-adv-y += unicast.o 40batman-adv-y += unicast.o
41batman-adv-y += vis.o
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 871ba672bdc2..97b42d3c4bef 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -687,11 +687,9 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
687 struct batadv_ogm_packet *batadv_ogm_packet; 687 struct batadv_ogm_packet *batadv_ogm_packet;
688 struct batadv_hard_iface *primary_if; 688 struct batadv_hard_iface *primary_if;
689 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; 689 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
690 int vis_server;
691 uint32_t seqno; 690 uint32_t seqno;
692 uint16_t tvlv_len = 0; 691 uint16_t tvlv_len = 0;
693 692
694 vis_server = atomic_read(&bat_priv->vis_mode);
695 primary_if = batadv_primary_if_get_selected(bat_priv); 693 primary_if = batadv_primary_if_get_selected(bat_priv);
696 694
697 if (hard_iface == primary_if) { 695 if (hard_iface == primary_if) {
@@ -712,11 +710,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
712 batadv_ogm_packet->seqno = htonl(seqno); 710 batadv_ogm_packet->seqno = htonl(seqno);
713 atomic_inc(&hard_iface->bat_iv.ogm_seqno); 711 atomic_inc(&hard_iface->bat_iv.ogm_seqno);
714 712
715 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC)
716 batadv_ogm_packet->flags |= BATADV_VIS_SERVER;
717 else
718 batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
719
720 batadv_iv_ogm_slide_own_bcast_window(hard_iface); 713 batadv_iv_ogm_slide_own_bcast_window(hard_iface);
721 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff, 714 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
722 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1, 715 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
@@ -790,7 +783,6 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
790 783
791 rcu_read_unlock(); 784 rcu_read_unlock();
792 785
793 orig_node->flags = batadv_ogm_packet->flags;
794 neigh_node->last_seen = jiffies; 786 neigh_node->last_seen = jiffies;
795 787
796 spin_lock_bh(&neigh_node->lq_update_lock); 788 spin_lock_bh(&neigh_node->lq_update_lock);
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index f186a55b23c3..049a7a2ac5b6 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -28,7 +28,6 @@
28#include "gateway_common.h" 28#include "gateway_common.h"
29#include "gateway_client.h" 29#include "gateway_client.h"
30#include "soft-interface.h" 30#include "soft-interface.h"
31#include "vis.h"
32#include "icmp_socket.h" 31#include "icmp_socket.h"
33#include "bridge_loop_avoidance.h" 32#include "bridge_loop_avoidance.h"
34#include "distributed-arp-table.h" 33#include "distributed-arp-table.h"
@@ -300,12 +299,6 @@ static int batadv_transtable_local_open(struct inode *inode, struct file *file)
300 return single_open(file, batadv_tt_local_seq_print_text, net_dev); 299 return single_open(file, batadv_tt_local_seq_print_text, net_dev);
301} 300}
302 301
303static int batadv_vis_data_open(struct inode *inode, struct file *file)
304{
305 struct net_device *net_dev = (struct net_device *)inode->i_private;
306 return single_open(file, batadv_vis_seq_print_text, net_dev);
307}
308
309struct batadv_debuginfo { 302struct batadv_debuginfo {
310 struct attribute attr; 303 struct attribute attr;
311 const struct file_operations fops; 304 const struct file_operations fops;
@@ -356,7 +349,6 @@ static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open);
356#endif 349#endif
357static BATADV_DEBUGINFO(transtable_local, S_IRUGO, 350static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
358 batadv_transtable_local_open); 351 batadv_transtable_local_open);
359static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open);
360#ifdef CONFIG_BATMAN_ADV_NC 352#ifdef CONFIG_BATMAN_ADV_NC
361static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open); 353static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open);
362#endif 354#endif
@@ -373,7 +365,6 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
373 &batadv_debuginfo_dat_cache, 365 &batadv_debuginfo_dat_cache,
374#endif 366#endif
375 &batadv_debuginfo_transtable_local, 367 &batadv_debuginfo_transtable_local,
376 &batadv_debuginfo_vis_data,
377#ifdef CONFIG_BATMAN_ADV_NC 368#ifdef CONFIG_BATMAN_ADV_NC
378 &batadv_debuginfo_nc_nodes, 369 &batadv_debuginfo_nc_nodes,
379#endif 370#endif
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c478e6bcf89b..eeb667112d64 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -194,22 +194,13 @@ out:
194static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv, 194static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
195 struct batadv_hard_iface *oldif) 195 struct batadv_hard_iface *oldif)
196{ 196{
197 struct batadv_vis_packet *vis_packet;
198 struct batadv_hard_iface *primary_if; 197 struct batadv_hard_iface *primary_if;
199 struct sk_buff *skb;
200 198
201 primary_if = batadv_primary_if_get_selected(bat_priv); 199 primary_if = batadv_primary_if_get_selected(bat_priv);
202 if (!primary_if) 200 if (!primary_if)
203 goto out; 201 goto out;
204 202
205 batadv_dat_init_own_addr(bat_priv, primary_if); 203 batadv_dat_init_own_addr(bat_priv, primary_if);
206
207 skb = bat_priv->vis.my_info->skb_packet;
208 vis_packet = (struct batadv_vis_packet *)skb->data;
209 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
210 memcpy(vis_packet->sender_orig,
211 primary_if->net_dev->dev_addr, ETH_ALEN);
212
213 batadv_bla_update_orig_address(bat_priv, primary_if, oldif); 204 batadv_bla_update_orig_address(bat_priv, primary_if, oldif);
214out: 205out:
215 if (primary_if) 206 if (primary_if)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index fc55acbacacf..43dc92e79a76 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -38,7 +38,6 @@
38#include "distributed-arp-table.h" 38#include "distributed-arp-table.h"
39#include "unicast.h" 39#include "unicast.h"
40#include "gateway_common.h" 40#include "gateway_common.h"
41#include "vis.h"
42#include "hash.h" 41#include "hash.h"
43#include "bat_algo.h" 42#include "bat_algo.h"
44#include "network-coding.h" 43#include "network-coding.h"
@@ -112,8 +111,6 @@ int batadv_mesh_init(struct net_device *soft_iface)
112 spin_lock_init(&bat_priv->tt.roam_list_lock); 111 spin_lock_init(&bat_priv->tt.roam_list_lock);
113 spin_lock_init(&bat_priv->tt.last_changeset_lock); 112 spin_lock_init(&bat_priv->tt.last_changeset_lock);
114 spin_lock_init(&bat_priv->gw.list_lock); 113 spin_lock_init(&bat_priv->gw.list_lock);
115 spin_lock_init(&bat_priv->vis.hash_lock);
116 spin_lock_init(&bat_priv->vis.list_lock);
117 spin_lock_init(&bat_priv->tvlv.container_list_lock); 114 spin_lock_init(&bat_priv->tvlv.container_list_lock);
118 spin_lock_init(&bat_priv->tvlv.handler_list_lock); 115 spin_lock_init(&bat_priv->tvlv.handler_list_lock);
119 116
@@ -137,10 +134,6 @@ int batadv_mesh_init(struct net_device *soft_iface)
137 batadv_tt_local_add(soft_iface, soft_iface->dev_addr, 134 batadv_tt_local_add(soft_iface, soft_iface->dev_addr,
138 BATADV_NULL_IFINDEX); 135 BATADV_NULL_IFINDEX);
139 136
140 ret = batadv_vis_init(bat_priv);
141 if (ret < 0)
142 goto err;
143
144 ret = batadv_bla_init(bat_priv); 137 ret = batadv_bla_init(bat_priv);
145 if (ret < 0) 138 if (ret < 0)
146 goto err; 139 goto err;
@@ -173,8 +166,6 @@ void batadv_mesh_free(struct net_device *soft_iface)
173 166
174 batadv_purge_outstanding_packets(bat_priv, NULL); 167 batadv_purge_outstanding_packets(bat_priv, NULL);
175 168
176 batadv_vis_quit(bat_priv);
177
178 batadv_gw_node_purge(bat_priv); 169 batadv_gw_node_purge(bat_priv);
179 batadv_nc_mesh_free(bat_priv); 170 batadv_nc_mesh_free(bat_priv);
180 batadv_dat_free(bat_priv); 171 batadv_dat_free(bat_priv);
@@ -412,8 +403,6 @@ static void batadv_recv_handler_init(void)
412 batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_ucast_frag_packet; 403 batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_ucast_frag_packet;
413 /* broadcast packet */ 404 /* broadcast packet */
414 batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet; 405 batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
415 /* vis packet */
416 batadv_rx_handler[BATADV_VIS] = batadv_recv_vis_packet;
417 /* unicast tvlv packet */ 406 /* unicast tvlv packet */
418 batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv; 407 batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv;
419} 408}
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 397722fb509b..e11c2ec7a739 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -86,8 +86,6 @@
86/* numbers of originator to contact for any PUT/GET DHT operation */ 86/* numbers of originator to contact for any PUT/GET DHT operation */
87#define BATADV_DAT_CANDIDATES_NUM 3 87#define BATADV_DAT_CANDIDATES_NUM 3
88 88
89#define BATADV_VIS_INTERVAL 5000 /* 5 seconds */
90
91/* how much worse secondary interfaces may be to be considered as bonding 89/* how much worse secondary interfaces may be to be considered as bonding
92 * candidates 90 * candidates
93 */ 91 */
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index ab3084f4f8ff..87fcf2e7883c 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -29,7 +29,6 @@ enum batadv_packettype {
29 BATADV_ICMP = 0x02, 29 BATADV_ICMP = 0x02,
30 BATADV_UNICAST = 0x03, 30 BATADV_UNICAST = 0x03,
31 BATADV_BCAST = 0x04, 31 BATADV_BCAST = 0x04,
32 BATADV_VIS = 0x05,
33 BATADV_UNICAST_FRAG = 0x06, 32 BATADV_UNICAST_FRAG = 0x06,
34 BATADV_UNICAST_4ADDR = 0x09, 33 BATADV_UNICAST_4ADDR = 0x09,
35 BATADV_CODED = 0x0a, 34 BATADV_CODED = 0x0a,
@@ -56,7 +55,6 @@ enum batadv_subtype {
56enum batadv_iv_flags { 55enum batadv_iv_flags {
57 BATADV_NOT_BEST_NEXT_HOP = BIT(3), 56 BATADV_NOT_BEST_NEXT_HOP = BIT(3),
58 BATADV_PRIMARIES_FIRST_HOP = BIT(4), 57 BATADV_PRIMARIES_FIRST_HOP = BIT(4),
59 BATADV_VIS_SERVER = BIT(5),
60 BATADV_DIRECTLINK = BIT(6), 58 BATADV_DIRECTLINK = BIT(6),
61}; 59};
62 60
@@ -69,12 +67,6 @@ enum batadv_icmp_packettype {
69 BATADV_PARAMETER_PROBLEM = 12, 67 BATADV_PARAMETER_PROBLEM = 12,
70}; 68};
71 69
72/* vis defines */
73enum batadv_vis_packettype {
74 BATADV_VIS_TYPE_SERVER_SYNC = 0,
75 BATADV_VIS_TYPE_CLIENT_UPDATE = 1,
76};
77
78/* fragmentation defines */ 70/* fragmentation defines */
79enum batadv_unicast_frag_flags { 71enum batadv_unicast_frag_flags {
80 BATADV_UNI_FRAG_HEAD = BIT(0), 72 BATADV_UNI_FRAG_HEAD = BIT(0),
@@ -161,7 +153,7 @@ struct batadv_header {
161 */ 153 */
162struct batadv_ogm_packet { 154struct batadv_ogm_packet {
163 struct batadv_header header; 155 struct batadv_header header;
164 uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ 156 uint8_t flags; /* 0x40: DIRECTLINK flag ... */
165 __be32 seqno; 157 __be32 seqno;
166 uint8_t orig[ETH_ALEN]; 158 uint8_t orig[ETH_ALEN];
167 uint8_t prev_sender[ETH_ALEN]; 159 uint8_t prev_sender[ETH_ALEN];
@@ -257,17 +249,6 @@ struct batadv_bcast_packet {
257 249
258#pragma pack() 250#pragma pack()
259 251
260struct batadv_vis_packet {
261 struct batadv_header header;
262 uint8_t vis_type; /* which type of vis-participant sent this? */
263 __be32 seqno; /* sequence number */
264 uint8_t entries; /* number of entries behind this struct */
265 uint8_t reserved;
266 uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */
267 uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */
268 uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */
269};
270
271/** 252/**
272 * struct batadv_coded_packet - network coded packet 253 * struct batadv_coded_packet - network coded packet
273 * @header: common batman packet header and ttl of first included packet 254 * @header: common batman packet header and ttl of first included packet
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index a5bf8fffdcea..2a9318bd9026 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -25,7 +25,6 @@
25#include "icmp_socket.h" 25#include "icmp_socket.h"
26#include "translation-table.h" 26#include "translation-table.h"
27#include "originator.h" 27#include "originator.h"
28#include "vis.h"
29#include "unicast.h" 28#include "unicast.h"
30#include "bridge_loop_avoidance.h" 29#include "bridge_loop_avoidance.h"
31#include "distributed-arp-table.h" 30#include "distributed-arp-table.h"
@@ -1168,53 +1167,3 @@ out:
1168 batadv_orig_node_free_ref(orig_node); 1167 batadv_orig_node_free_ref(orig_node);
1169 return ret; 1168 return ret;
1170} 1169}
1171
1172int batadv_recv_vis_packet(struct sk_buff *skb,
1173 struct batadv_hard_iface *recv_if)
1174{
1175 struct batadv_vis_packet *vis_packet;
1176 struct ethhdr *ethhdr;
1177 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1178 int hdr_size = sizeof(*vis_packet);
1179
1180 /* keep skb linear */
1181 if (skb_linearize(skb) < 0)
1182 return NET_RX_DROP;
1183
1184 if (unlikely(!pskb_may_pull(skb, hdr_size)))
1185 return NET_RX_DROP;
1186
1187 vis_packet = (struct batadv_vis_packet *)skb->data;
1188 ethhdr = eth_hdr(skb);
1189
1190 /* not for me */
1191 if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
1192 return NET_RX_DROP;
1193
1194 /* ignore own packets */
1195 if (batadv_is_my_mac(bat_priv, vis_packet->vis_orig))
1196 return NET_RX_DROP;
1197
1198 if (batadv_is_my_mac(bat_priv, vis_packet->sender_orig))
1199 return NET_RX_DROP;
1200
1201 switch (vis_packet->vis_type) {
1202 case BATADV_VIS_TYPE_SERVER_SYNC:
1203 batadv_receive_server_sync_packet(bat_priv, vis_packet,
1204 skb_headlen(skb));
1205 break;
1206
1207 case BATADV_VIS_TYPE_CLIENT_UPDATE:
1208 batadv_receive_client_update_packet(bat_priv, vis_packet,
1209 skb_headlen(skb));
1210 break;
1211
1212 default: /* ignore unknown packet */
1213 break;
1214 }
1215
1216 /* We take a copy of the data in the packet, so we should
1217 * always free the skbuf.
1218 */
1219 return NET_RX_DROP;
1220}
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index 0a7983b25395..b3f53d492b3c 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -34,8 +34,6 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
34 struct batadv_hard_iface *recv_if); 34 struct batadv_hard_iface *recv_if);
35int batadv_recv_bcast_packet(struct sk_buff *skb, 35int batadv_recv_bcast_packet(struct sk_buff *skb,
36 struct batadv_hard_iface *recv_if); 36 struct batadv_hard_iface *recv_if);
37int batadv_recv_vis_packet(struct sk_buff *skb,
38 struct batadv_hard_iface *recv_if);
39int batadv_recv_tt_query(struct sk_buff *skb, 37int batadv_recv_tt_query(struct sk_buff *skb,
40 struct batadv_hard_iface *recv_if); 38 struct batadv_hard_iface *recv_if);
41int batadv_recv_roam_adv(struct sk_buff *skb, 39int batadv_recv_roam_adv(struct sk_buff *skb,
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 0266edd0fa7f..81d69fb97c17 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -24,7 +24,6 @@
24#include "translation-table.h" 24#include "translation-table.h"
25#include "soft-interface.h" 25#include "soft-interface.h"
26#include "hard-interface.h" 26#include "hard-interface.h"
27#include "vis.h"
28#include "gateway_common.h" 27#include "gateway_common.h"
29#include "originator.h" 28#include "originator.h"
30#include "network-coding.h" 29#include "network-coding.h"
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 84623a955d52..25e6004e8e01 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -469,7 +469,6 @@ static int batadv_softif_init_late(struct net_device *dev)
469 atomic_set(&bat_priv->distributed_arp_table, 1); 469 atomic_set(&bat_priv->distributed_arp_table, 1);
470#endif 470#endif
471 atomic_set(&bat_priv->ap_isolation, 0); 471 atomic_set(&bat_priv->ap_isolation, 0);
472 atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
473 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); 472 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
474 atomic_set(&bat_priv->gw_sel_class, 20); 473 atomic_set(&bat_priv->gw_sel_class, 20);
475 atomic_set(&bat_priv->gw.bandwidth_down, 100); 474 atomic_set(&bat_priv->gw.bandwidth_down, 100);
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index fbc1c251711d..869eb46329cb 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -26,7 +26,6 @@
26#include "hard-interface.h" 26#include "hard-interface.h"
27#include "gateway_common.h" 27#include "gateway_common.h"
28#include "gateway_client.h" 28#include "gateway_client.h"
29#include "vis.h"
30 29
31static struct net_device *batadv_kobj_to_netdev(struct kobject *obj) 30static struct net_device *batadv_kobj_to_netdev(struct kobject *obj)
32{ 31{
@@ -231,74 +230,6 @@ __batadv_store_uint_attr(const char *buff, size_t count,
231 return ret; 230 return ret;
232} 231}
233 232
234static ssize_t batadv_show_vis_mode(struct kobject *kobj,
235 struct attribute *attr, char *buff)
236{
237 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
238 int vis_mode = atomic_read(&bat_priv->vis_mode);
239 const char *mode;
240
241 if (vis_mode == BATADV_VIS_TYPE_CLIENT_UPDATE)
242 mode = "client";
243 else
244 mode = "server";
245
246 return sprintf(buff, "%s\n", mode);
247}
248
249static ssize_t batadv_store_vis_mode(struct kobject *kobj,
250 struct attribute *attr, char *buff,
251 size_t count)
252{
253 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
254 struct batadv_priv *bat_priv = netdev_priv(net_dev);
255 unsigned long val;
256 int ret, vis_mode_tmp = -1;
257 const char *old_mode, *new_mode;
258
259 ret = kstrtoul(buff, 10, &val);
260
261 if (((count == 2) && (!ret) &&
262 (val == BATADV_VIS_TYPE_CLIENT_UPDATE)) ||
263 (strncmp(buff, "client", 6) == 0) ||
264 (strncmp(buff, "off", 3) == 0))
265 vis_mode_tmp = BATADV_VIS_TYPE_CLIENT_UPDATE;
266
267 if (((count == 2) && (!ret) &&
268 (val == BATADV_VIS_TYPE_SERVER_SYNC)) ||
269 (strncmp(buff, "server", 6) == 0))
270 vis_mode_tmp = BATADV_VIS_TYPE_SERVER_SYNC;
271
272 if (vis_mode_tmp < 0) {
273 if (buff[count - 1] == '\n')
274 buff[count - 1] = '\0';
275
276 batadv_info(net_dev,
277 "Invalid parameter for 'vis mode' setting received: %s\n",
278 buff);
279 return -EINVAL;
280 }
281
282 if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
283 return count;
284
285 if (atomic_read(&bat_priv->vis_mode) == BATADV_VIS_TYPE_CLIENT_UPDATE)
286 old_mode = "client";
287 else
288 old_mode = "server";
289
290 if (vis_mode_tmp == BATADV_VIS_TYPE_CLIENT_UPDATE)
291 new_mode = "client";
292 else
293 new_mode = "server";
294
295 batadv_info(net_dev, "Changing vis mode from: %s to: %s\n", old_mode,
296 new_mode);
297
298 atomic_set(&bat_priv->vis_mode, (unsigned int)vis_mode_tmp);
299 return count;
300}
301
302static ssize_t batadv_show_bat_algo(struct kobject *kobj, 233static ssize_t batadv_show_bat_algo(struct kobject *kobj,
303 struct attribute *attr, char *buff) 234 struct attribute *attr, char *buff)
304{ 235{
@@ -431,8 +362,6 @@ BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR,
431#endif 362#endif
432BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); 363BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
433BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); 364BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
434static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode,
435 batadv_store_vis_mode);
436static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL); 365static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL);
437static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode, 366static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode,
438 batadv_store_gw_mode); 367 batadv_store_gw_mode);
@@ -463,7 +392,6 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
463#endif 392#endif
464 &batadv_attr_fragmentation, 393 &batadv_attr_fragmentation,
465 &batadv_attr_ap_isolation, 394 &batadv_attr_ap_isolation,
466 &batadv_attr_vis_mode,
467 &batadv_attr_routing_algo, 395 &batadv_attr_routing_algo,
468 &batadv_attr_gw_mode, 396 &batadv_attr_gw_mode,
469 &batadv_attr_orig_interval, 397 &batadv_attr_orig_interval,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index e98915ac2a66..8fbd89d167cd 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -99,7 +99,6 @@ struct batadv_hard_iface {
99 * @last_seen: time when last packet from this node was received 99 * @last_seen: time when last packet from this node was received
100 * @bcast_seqno_reset: time when the broadcast seqno window was reset 100 * @bcast_seqno_reset: time when the broadcast seqno window was reset
101 * @batman_seqno_reset: time when the batman seqno window was reset 101 * @batman_seqno_reset: time when the batman seqno window was reset
102 * @flags: for now only VIS_SERVER flag
103 * @capabilities: announced capabilities of this originator 102 * @capabilities: announced capabilities of this originator
104 * @last_ttvn: last seen translation table version number 103 * @last_ttvn: last seen translation table version number
105 * @tt_crc: CRC of the translation table 104 * @tt_crc: CRC of the translation table
@@ -147,7 +146,6 @@ struct batadv_orig_node {
147 unsigned long last_seen; 146 unsigned long last_seen;
148 unsigned long bcast_seqno_reset; 147 unsigned long bcast_seqno_reset;
149 unsigned long batman_seqno_reset; 148 unsigned long batman_seqno_reset;
150 uint8_t flags;
151 uint8_t capabilities; 149 uint8_t capabilities;
152 atomic_t last_ttvn; 150 atomic_t last_ttvn;
153 uint32_t tt_crc; 151 uint32_t tt_crc;
@@ -462,24 +460,6 @@ struct batadv_priv_tvlv {
462}; 460};
463 461
464/** 462/**
465 * struct batadv_priv_vis - per mesh interface vis data
466 * @send_list: list of batadv_vis_info packets to sent
467 * @hash: hash table containing vis data from other nodes in the network
468 * @hash_lock: lock protecting the hash table
469 * @list_lock: lock protecting my_info::recv_list
470 * @work: work queue callback item for vis packet sending
471 * @my_info: holds this node's vis data sent on a regular basis
472 */
473struct batadv_priv_vis {
474 struct list_head send_list;
475 struct batadv_hashtable *hash;
476 spinlock_t hash_lock; /* protects hash */
477 spinlock_t list_lock; /* protects my_info::recv_list */
478 struct delayed_work work;
479 struct batadv_vis_info *my_info;
480};
481
482/**
483 * struct batadv_priv_dat - per mesh interface DAT private data 463 * struct batadv_priv_dat - per mesh interface DAT private data
484 * @addr: node DAT address 464 * @addr: node DAT address
485 * @hash: hashtable representing the local ARP cache 465 * @hash: hashtable representing the local ARP cache
@@ -536,7 +516,6 @@ struct batadv_priv_nc {
536 * enabled 516 * enabled
537 * @distributed_arp_table: bool indicating whether distributed ARP table is 517 * @distributed_arp_table: bool indicating whether distributed ARP table is
538 * enabled 518 * enabled
539 * @vis_mode: vis operation: client or server (see batadv_vis_packettype)
540 * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes) 519 * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes)
541 * @gw_sel_class: gateway selection class (applies if gw_mode client) 520 * @gw_sel_class: gateway selection class (applies if gw_mode client)
542 * @orig_interval: OGM broadcast interval in milliseconds 521 * @orig_interval: OGM broadcast interval in milliseconds
@@ -563,7 +542,6 @@ struct batadv_priv_nc {
563 * @gw: gateway data 542 * @gw: gateway data
564 * @tt: translation table data 543 * @tt: translation table data
565 * @tvlv: type-version-length-value data 544 * @tvlv: type-version-length-value data
566 * @vis: vis data
567 * @dat: distributed arp table data 545 * @dat: distributed arp table data
568 * @network_coding: bool indicating whether network coding is enabled 546 * @network_coding: bool indicating whether network coding is enabled
569 * @batadv_priv_nc: network coding data 547 * @batadv_priv_nc: network coding data
@@ -583,7 +561,6 @@ struct batadv_priv {
583#ifdef CONFIG_BATMAN_ADV_DAT 561#ifdef CONFIG_BATMAN_ADV_DAT
584 atomic_t distributed_arp_table; 562 atomic_t distributed_arp_table;
585#endif 563#endif
586 atomic_t vis_mode;
587 atomic_t gw_mode; 564 atomic_t gw_mode;
588 atomic_t gw_sel_class; 565 atomic_t gw_sel_class;
589 atomic_t orig_interval; 566 atomic_t orig_interval;
@@ -615,7 +592,6 @@ struct batadv_priv {
615 struct batadv_priv_gw gw; 592 struct batadv_priv_gw gw;
616 struct batadv_priv_tt tt; 593 struct batadv_priv_tt tt;
617 struct batadv_priv_tvlv tvlv; 594 struct batadv_priv_tvlv tvlv;
618 struct batadv_priv_vis vis;
619#ifdef CONFIG_BATMAN_ADV_DAT 595#ifdef CONFIG_BATMAN_ADV_DAT
620 struct batadv_priv_dat dat; 596 struct batadv_priv_dat dat;
621#endif 597#endif
@@ -910,66 +886,6 @@ struct batadv_frag_packet_list_entry {
910}; 886};
911 887
912/** 888/**
913 * struct batadv_vis_info - local data for vis information
914 * @first_seen: timestamp used for purging stale vis info entries
915 * @recv_list: List of server-neighbors we have received this packet from. This
916 * packet should not be re-forward to them again. List elements are struct
917 * batadv_vis_recvlist_node
918 * @send_list: list of packets to be forwarded
919 * @refcount: number of contexts the object is used
920 * @hash_entry: hlist node for batadv_priv_vis::hash
921 * @bat_priv: pointer to soft_iface this orig node belongs to
922 * @skb_packet: contains the vis packet
923 */
924struct batadv_vis_info {
925 unsigned long first_seen;
926 struct list_head recv_list;
927 struct list_head send_list;
928 struct kref refcount;
929 struct hlist_node hash_entry;
930 struct batadv_priv *bat_priv;
931 struct sk_buff *skb_packet;
932} __packed;
933
934/**
935 * struct batadv_vis_info_entry - contains link information for vis
936 * @src: source MAC of the link, all zero for local TT entry
937 * @dst: destination MAC of the link, client mac address for local TT entry
938 * @quality: transmission quality of the link, or 0 for local TT entry
939 */
940struct batadv_vis_info_entry {
941 uint8_t src[ETH_ALEN];
942 uint8_t dest[ETH_ALEN];
943 uint8_t quality;
944} __packed;
945
946/**
947 * struct batadv_vis_recvlist_node - list entry for batadv_vis_info::recv_list
948 * @list: list node for batadv_vis_info::recv_list
949 * @mac: MAC address of the originator from where the vis_info was received
950 */
951struct batadv_vis_recvlist_node {
952 struct list_head list;
953 uint8_t mac[ETH_ALEN];
954};
955
956/**
957 * struct batadv_vis_if_list_entry - auxiliary data for vis data generation
958 * @addr: MAC address of the interface
959 * @primary: true if this interface is the primary interface
960 * @list: list node the interface list
961 *
962 * While scanning for vis-entries of a particular vis-originator
963 * this list collects its interfaces to create a subgraph/cluster
964 * out of them later
965 */
966struct batadv_vis_if_list_entry {
967 uint8_t addr[ETH_ALEN];
968 bool primary;
969 struct hlist_node list;
970};
971
972/**
973 * struct batadv_algo_ops - mesh algorithm callbacks 889 * struct batadv_algo_ops - mesh algorithm callbacks
974 * @list: list node for the batadv_algo_list 890 * @list: list node for the batadv_algo_list
975 * @name: name of the algorithm 891 * @name: name of the algorithm
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
deleted file mode 100644
index d8ea31a58457..000000000000
--- a/net/batman-adv/vis.c
+++ /dev/null
@@ -1,938 +0,0 @@
1/* Copyright (C) 2008-2013 B.A.T.M.A.N. contributors:
2 *
3 * Simon Wunderlich
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA
18 */
19
20#include "main.h"
21#include "send.h"
22#include "translation-table.h"
23#include "vis.h"
24#include "soft-interface.h"
25#include "hard-interface.h"
26#include "hash.h"
27#include "originator.h"
28
29#define BATADV_MAX_VIS_PACKET_SIZE 1000
30
31/* hash class keys */
32static struct lock_class_key batadv_vis_hash_lock_class_key;
33
34/* free the info */
35static void batadv_free_info(struct kref *ref)
36{
37 struct batadv_vis_info *info;
38 struct batadv_priv *bat_priv;
39 struct batadv_vis_recvlist_node *entry, *tmp;
40
41 info = container_of(ref, struct batadv_vis_info, refcount);
42 bat_priv = info->bat_priv;
43
44 list_del_init(&info->send_list);
45 spin_lock_bh(&bat_priv->vis.list_lock);
46 list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
47 list_del(&entry->list);
48 kfree(entry);
49 }
50
51 spin_unlock_bh(&bat_priv->vis.list_lock);
52 kfree_skb(info->skb_packet);
53 kfree(info);
54}
55
56/* Compare two vis packets, used by the hashing algorithm */
57static int batadv_vis_info_cmp(const struct hlist_node *node, const void *data2)
58{
59 const struct batadv_vis_info *d1, *d2;
60 const struct batadv_vis_packet *p1, *p2;
61
62 d1 = container_of(node, struct batadv_vis_info, hash_entry);
63 d2 = data2;
64 p1 = (struct batadv_vis_packet *)d1->skb_packet->data;
65 p2 = (struct batadv_vis_packet *)d2->skb_packet->data;
66 return batadv_compare_eth(p1->vis_orig, p2->vis_orig);
67}
68
69/* hash function to choose an entry in a hash table of given size
70 * hash algorithm from http://en.wikipedia.org/wiki/Hash_table
71 */
72static uint32_t batadv_vis_info_choose(const void *data, uint32_t size)
73{
74 const struct batadv_vis_info *vis_info = data;
75 const struct batadv_vis_packet *packet;
76 const unsigned char *key;
77 uint32_t hash = 0;
78 size_t i;
79
80 packet = (struct batadv_vis_packet *)vis_info->skb_packet->data;
81 key = packet->vis_orig;
82 for (i = 0; i < ETH_ALEN; i++) {
83 hash += key[i];
84 hash += (hash << 10);
85 hash ^= (hash >> 6);
86 }
87
88 hash += (hash << 3);
89 hash ^= (hash >> 11);
90 hash += (hash << 15);
91
92 return hash % size;
93}
94
95static struct batadv_vis_info *
96batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
97{
98 struct batadv_hashtable *hash = bat_priv->vis.hash;
99 struct hlist_head *head;
100 struct batadv_vis_info *vis_info, *vis_info_tmp = NULL;
101 uint32_t index;
102
103 if (!hash)
104 return NULL;
105
106 index = batadv_vis_info_choose(data, hash->size);
107 head = &hash->table[index];
108
109 rcu_read_lock();
110 hlist_for_each_entry_rcu(vis_info, head, hash_entry) {
111 if (!batadv_vis_info_cmp(&vis_info->hash_entry, data))
112 continue;
113
114 vis_info_tmp = vis_info;
115 break;
116 }
117 rcu_read_unlock();
118
119 return vis_info_tmp;
120}
121
122/* insert interface to the list of interfaces of one originator, if it
123 * does not already exist in the list
124 */
125static void batadv_vis_data_insert_interface(const uint8_t *interface,
126 struct hlist_head *if_list,
127 bool primary)
128{
129 struct batadv_vis_if_list_entry *entry;
130
131 hlist_for_each_entry(entry, if_list, list) {
132 if (batadv_compare_eth(entry->addr, interface))
133 return;
134 }
135
136 /* it's a new address, add it to the list */
137 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
138 if (!entry)
139 return;
140 memcpy(entry->addr, interface, ETH_ALEN);
141 entry->primary = primary;
142 hlist_add_head(&entry->list, if_list);
143}
144
145static void batadv_vis_data_read_prim_sec(struct seq_file *seq,
146 const struct hlist_head *if_list)
147{
148 struct batadv_vis_if_list_entry *entry;
149
150 hlist_for_each_entry(entry, if_list, list) {
151 if (entry->primary)
152 seq_puts(seq, "PRIMARY, ");
153 else
154 seq_printf(seq, "SEC %pM, ", entry->addr);
155 }
156}
157
158/* read an entry */
159static ssize_t
160batadv_vis_data_read_entry(struct seq_file *seq,
161 const struct batadv_vis_info_entry *entry,
162 const uint8_t *src, bool primary)
163{
164 if (primary && entry->quality == 0)
165 return seq_printf(seq, "TT %pM, ", entry->dest);
166 else if (batadv_compare_eth(entry->src, src))
167 return seq_printf(seq, "TQ %pM %d, ", entry->dest,
168 entry->quality);
169
170 return 0;
171}
172
173static void
174batadv_vis_data_insert_interfaces(struct hlist_head *list,
175 struct batadv_vis_packet *packet,
176 struct batadv_vis_info_entry *entries)
177{
178 int i;
179
180 for (i = 0; i < packet->entries; i++) {
181 if (entries[i].quality == 0)
182 continue;
183
184 if (batadv_compare_eth(entries[i].src, packet->vis_orig))
185 continue;
186
187 batadv_vis_data_insert_interface(entries[i].src, list, false);
188 }
189}
190
191static void batadv_vis_data_read_entries(struct seq_file *seq,
192 struct hlist_head *list,
193 struct batadv_vis_packet *packet,
194 struct batadv_vis_info_entry *entries)
195{
196 int i;
197 struct batadv_vis_if_list_entry *entry;
198
199 hlist_for_each_entry(entry, list, list) {
200 seq_printf(seq, "%pM,", entry->addr);
201
202 for (i = 0; i < packet->entries; i++)
203 batadv_vis_data_read_entry(seq, &entries[i],
204 entry->addr, entry->primary);
205
206 /* add primary/secondary records */
207 if (batadv_compare_eth(entry->addr, packet->vis_orig))
208 batadv_vis_data_read_prim_sec(seq, list);
209
210 seq_puts(seq, "\n");
211 }
212}
213
214static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
215 const struct hlist_head *head)
216{
217 struct batadv_vis_info *info;
218 struct batadv_vis_packet *packet;
219 uint8_t *entries_pos;
220 struct batadv_vis_info_entry *entries;
221 struct batadv_vis_if_list_entry *entry;
222 struct hlist_node *n;
223
224 HLIST_HEAD(vis_if_list);
225
226 hlist_for_each_entry_rcu(info, head, hash_entry) {
227 packet = (struct batadv_vis_packet *)info->skb_packet->data;
228 entries_pos = (uint8_t *)packet + sizeof(*packet);
229 entries = (struct batadv_vis_info_entry *)entries_pos;
230
231 batadv_vis_data_insert_interface(packet->vis_orig, &vis_if_list,
232 true);
233 batadv_vis_data_insert_interfaces(&vis_if_list, packet,
234 entries);
235 batadv_vis_data_read_entries(seq, &vis_if_list, packet,
236 entries);
237
238 hlist_for_each_entry_safe(entry, n, &vis_if_list, list) {
239 hlist_del(&entry->list);
240 kfree(entry);
241 }
242 }
243}
244
245int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
246{
247 struct batadv_hard_iface *primary_if;
248 struct hlist_head *head;
249 struct net_device *net_dev = (struct net_device *)seq->private;
250 struct batadv_priv *bat_priv = netdev_priv(net_dev);
251 struct batadv_hashtable *hash = bat_priv->vis.hash;
252 uint32_t i;
253 int ret = 0;
254 int vis_server = atomic_read(&bat_priv->vis_mode);
255
256 primary_if = batadv_primary_if_get_selected(bat_priv);
257 if (!primary_if)
258 goto out;
259
260 if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE)
261 goto out;
262
263 spin_lock_bh(&bat_priv->vis.hash_lock);
264 for (i = 0; i < hash->size; i++) {
265 head = &hash->table[i];
266 batadv_vis_seq_print_text_bucket(seq, head);
267 }
268 spin_unlock_bh(&bat_priv->vis.hash_lock);
269
270out:
271 if (primary_if)
272 batadv_hardif_free_ref(primary_if);
273 return ret;
274}
275
276/* add the info packet to the send list, if it was not
277 * already linked in.
278 */
279static void batadv_send_list_add(struct batadv_priv *bat_priv,
280 struct batadv_vis_info *info)
281{
282 if (list_empty(&info->send_list)) {
283 kref_get(&info->refcount);
284 list_add_tail(&info->send_list, &bat_priv->vis.send_list);
285 }
286}
287
288/* delete the info packet from the send list, if it was
289 * linked in.
290 */
291static void batadv_send_list_del(struct batadv_vis_info *info)
292{
293 if (!list_empty(&info->send_list)) {
294 list_del_init(&info->send_list);
295 kref_put(&info->refcount, batadv_free_info);
296 }
297}
298
299/* tries to add one entry to the receive list. */
300static void batadv_recv_list_add(struct batadv_priv *bat_priv,
301 struct list_head *recv_list, const char *mac)
302{
303 struct batadv_vis_recvlist_node *entry;
304
305 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
306 if (!entry)
307 return;
308
309 memcpy(entry->mac, mac, ETH_ALEN);
310 spin_lock_bh(&bat_priv->vis.list_lock);
311 list_add_tail(&entry->list, recv_list);
312 spin_unlock_bh(&bat_priv->vis.list_lock);
313}
314
315/* returns 1 if this mac is in the recv_list */
316static int batadv_recv_list_is_in(struct batadv_priv *bat_priv,
317 const struct list_head *recv_list,
318 const char *mac)
319{
320 const struct batadv_vis_recvlist_node *entry;
321
322 spin_lock_bh(&bat_priv->vis.list_lock);
323 list_for_each_entry(entry, recv_list, list) {
324 if (batadv_compare_eth(entry->mac, mac)) {
325 spin_unlock_bh(&bat_priv->vis.list_lock);
326 return 1;
327 }
328 }
329 spin_unlock_bh(&bat_priv->vis.list_lock);
330 return 0;
331}
332
333/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
334 * broken.. ). vis hash must be locked outside. is_new is set when the packet
335 * is newer than old entries in the hash.
336 */
337static struct batadv_vis_info *
338batadv_add_packet(struct batadv_priv *bat_priv,
339 struct batadv_vis_packet *vis_packet, int vis_info_len,
340 int *is_new, int make_broadcast)
341{
342 struct batadv_vis_info *info, *old_info;
343 struct batadv_vis_packet *search_packet, *old_packet;
344 struct batadv_vis_info search_elem;
345 struct batadv_vis_packet *packet;
346 struct sk_buff *tmp_skb;
347 int hash_added;
348 size_t len;
349 size_t max_entries;
350
351 *is_new = 0;
352 /* sanity check */
353 if (!bat_priv->vis.hash)
354 return NULL;
355
356 /* see if the packet is already in vis_hash */
357 search_elem.skb_packet = dev_alloc_skb(sizeof(*search_packet));
358 if (!search_elem.skb_packet)
359 return NULL;
360 len = sizeof(*search_packet);
361 tmp_skb = search_elem.skb_packet;
362 search_packet = (struct batadv_vis_packet *)skb_put(tmp_skb, len);
363
364 memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
365 old_info = batadv_vis_hash_find(bat_priv, &search_elem);
366 kfree_skb(search_elem.skb_packet);
367
368 if (old_info) {
369 tmp_skb = old_info->skb_packet;
370 old_packet = (struct batadv_vis_packet *)tmp_skb->data;
371 if (!batadv_seq_after(ntohl(vis_packet->seqno),
372 ntohl(old_packet->seqno))) {
373 if (old_packet->seqno == vis_packet->seqno) {
374 batadv_recv_list_add(bat_priv,
375 &old_info->recv_list,
376 vis_packet->sender_orig);
377 return old_info;
378 } else {
379 /* newer packet is already in hash. */
380 return NULL;
381 }
382 }
383 /* remove old entry */
384 batadv_hash_remove(bat_priv->vis.hash, batadv_vis_info_cmp,
385 batadv_vis_info_choose, old_info);
386 batadv_send_list_del(old_info);
387 kref_put(&old_info->refcount, batadv_free_info);
388 }
389
390 info = kmalloc(sizeof(*info), GFP_ATOMIC);
391 if (!info)
392 return NULL;
393
394 len = sizeof(*packet) + vis_info_len;
395 info->skb_packet = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
396 if (!info->skb_packet) {
397 kfree(info);
398 return NULL;
399 }
400 info->skb_packet->priority = TC_PRIO_CONTROL;
401 skb_reserve(info->skb_packet, ETH_HLEN);
402 packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
403
404 kref_init(&info->refcount);
405 INIT_LIST_HEAD(&info->send_list);
406 INIT_LIST_HEAD(&info->recv_list);
407 info->first_seen = jiffies;
408 info->bat_priv = bat_priv;
409 memcpy(packet, vis_packet, len);
410
411 /* initialize and add new packet. */
412 *is_new = 1;
413
414 /* Make it a broadcast packet, if required */
415 if (make_broadcast)
416 memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);
417
418 /* repair if entries is longer than packet. */
419 max_entries = vis_info_len / sizeof(struct batadv_vis_info_entry);
420 if (packet->entries > max_entries)
421 packet->entries = max_entries;
422
423 batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
424
425 /* try to add it */
426 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
427 batadv_vis_info_choose, info,
428 &info->hash_entry);
429 if (hash_added != 0) {
430 /* did not work (for some reason) */
431 kref_put(&info->refcount, batadv_free_info);
432 info = NULL;
433 }
434
435 return info;
436}
437
438/* handle the server sync packet, forward if needed. */
439void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
440 struct batadv_vis_packet *vis_packet,
441 int vis_info_len)
442{
443 struct batadv_vis_info *info;
444 int is_new, make_broadcast;
445 int vis_server = atomic_read(&bat_priv->vis_mode);
446
447 make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC);
448
449 spin_lock_bh(&bat_priv->vis.hash_lock);
450 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
451 &is_new, make_broadcast);
452 if (!info)
453 goto end;
454
455 /* only if we are server ourselves and packet is newer than the one in
456 * hash.
457 */
458 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new)
459 batadv_send_list_add(bat_priv, info);
460end:
461 spin_unlock_bh(&bat_priv->vis.hash_lock);
462}
463
464/* handle an incoming client update packet and schedule forward if needed. */
465void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
466 struct batadv_vis_packet *vis_packet,
467 int vis_info_len)
468{
469 struct batadv_vis_info *info;
470 struct batadv_vis_packet *packet;
471 int is_new;
472 int vis_server = atomic_read(&bat_priv->vis_mode);
473 int are_target = 0;
474
475 /* clients shall not broadcast. */
476 if (is_broadcast_ether_addr(vis_packet->target_orig))
477 return;
478
479 /* Are we the target for this VIS packet? */
480 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC &&
481 batadv_is_my_mac(bat_priv, vis_packet->target_orig))
482 are_target = 1;
483
484 spin_lock_bh(&bat_priv->vis.hash_lock);
485 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
486 &is_new, are_target);
487
488 if (!info)
489 goto end;
490 /* note that outdated packets will be dropped at this point. */
491
492 packet = (struct batadv_vis_packet *)info->skb_packet->data;
493
494 /* send only if we're the target server or ... */
495 if (are_target && is_new) {
496 packet->vis_type = BATADV_VIS_TYPE_SERVER_SYNC; /* upgrade! */
497 batadv_send_list_add(bat_priv, info);
498
499 /* ... we're not the recipient (and thus need to forward). */
500 } else if (!batadv_is_my_mac(bat_priv, packet->target_orig)) {
501 batadv_send_list_add(bat_priv, info);
502 }
503
504end:
505 spin_unlock_bh(&bat_priv->vis.hash_lock);
506}
507
508/* Walk the originators and find the VIS server with the best tq. Set the packet
509 * address to its address and return the best_tq.
510 *
511 * Must be called with the originator hash locked
512 */
513static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
514 struct batadv_vis_info *info)
515{
516 struct batadv_hashtable *hash = bat_priv->orig_hash;
517 struct batadv_neigh_node *router;
518 struct hlist_head *head;
519 struct batadv_orig_node *orig_node;
520 struct batadv_vis_packet *packet;
521 int best_tq = -1;
522 uint32_t i;
523
524 packet = (struct batadv_vis_packet *)info->skb_packet->data;
525
526 for (i = 0; i < hash->size; i++) {
527 head = &hash->table[i];
528
529 rcu_read_lock();
530 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
531 router = batadv_orig_node_get_router(orig_node);
532 if (!router)
533 continue;
534
535 if ((orig_node->flags & BATADV_VIS_SERVER) &&
536 (router->tq_avg > best_tq)) {
537 best_tq = router->tq_avg;
538 memcpy(packet->target_orig, orig_node->orig,
539 ETH_ALEN);
540 }
541 batadv_neigh_node_free_ref(router);
542 }
543 rcu_read_unlock();
544 }
545
546 return best_tq;
547}
548
549/* Return true if the vis packet is full. */
550static bool batadv_vis_packet_full(const struct batadv_vis_info *info)
551{
552 const struct batadv_vis_packet *packet;
553 size_t num;
554
555 packet = (struct batadv_vis_packet *)info->skb_packet->data;
556 num = BATADV_MAX_VIS_PACKET_SIZE / sizeof(struct batadv_vis_info_entry);
557
558 if (num < packet->entries + 1)
559 return true;
560 return false;
561}
562
563/* generates a packet of own vis data,
564 * returns 0 on success, -1 if no packet could be generated
565 */
566static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
567{
568 struct batadv_hashtable *hash = bat_priv->orig_hash;
569 struct hlist_head *head;
570 struct batadv_orig_node *orig_node;
571 struct batadv_neigh_node *router;
572 struct batadv_vis_info *info = bat_priv->vis.my_info;
573 struct batadv_vis_packet *packet;
574 struct batadv_vis_info_entry *entry;
575 struct batadv_tt_common_entry *tt_common_entry;
576 uint8_t *packet_pos;
577 int best_tq = -1;
578 uint32_t i;
579
580 info->first_seen = jiffies;
581 packet = (struct batadv_vis_packet *)info->skb_packet->data;
582 packet->vis_type = atomic_read(&bat_priv->vis_mode);
583
584 memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);
585 packet->header.ttl = BATADV_TTL;
586 packet->seqno = htonl(ntohl(packet->seqno) + 1);
587 packet->entries = 0;
588 packet->reserved = 0;
589 skb_trim(info->skb_packet, sizeof(*packet));
590
591 if (packet->vis_type == BATADV_VIS_TYPE_CLIENT_UPDATE) {
592 best_tq = batadv_find_best_vis_server(bat_priv, info);
593
594 if (best_tq < 0)
595 return best_tq;
596 }
597
598 for (i = 0; i < hash->size; i++) {
599 head = &hash->table[i];
600
601 rcu_read_lock();
602 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
603 router = batadv_orig_node_get_router(orig_node);
604 if (!router)
605 continue;
606
607 if (!batadv_compare_eth(router->addr, orig_node->orig))
608 goto next;
609
610 if (router->if_incoming->if_status != BATADV_IF_ACTIVE)
611 goto next;
612
613 if (router->tq_avg < 1)
614 goto next;
615
616 /* fill one entry into buffer. */
617 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
618 entry = (struct batadv_vis_info_entry *)packet_pos;
619 memcpy(entry->src,
620 router->if_incoming->net_dev->dev_addr,
621 ETH_ALEN);
622 memcpy(entry->dest, orig_node->orig, ETH_ALEN);
623 entry->quality = router->tq_avg;
624 packet->entries++;
625
626next:
627 batadv_neigh_node_free_ref(router);
628
629 if (batadv_vis_packet_full(info))
630 goto unlock;
631 }
632 rcu_read_unlock();
633 }
634
635 hash = bat_priv->tt.local_hash;
636
637 for (i = 0; i < hash->size; i++) {
638 head = &hash->table[i];
639
640 rcu_read_lock();
641 hlist_for_each_entry_rcu(tt_common_entry, head,
642 hash_entry) {
643 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
644 entry = (struct batadv_vis_info_entry *)packet_pos;
645 memset(entry->src, 0, ETH_ALEN);
646 memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN);
647 entry->quality = 0; /* 0 means TT */
648 packet->entries++;
649
650 if (batadv_vis_packet_full(info))
651 goto unlock;
652 }
653 rcu_read_unlock();
654 }
655
656 return 0;
657
658unlock:
659 rcu_read_unlock();
660 return 0;
661}
662
663/* free old vis packets. Must be called with this vis_hash_lock
664 * held
665 */
666static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
667{
668 uint32_t i;
669 struct batadv_hashtable *hash = bat_priv->vis.hash;
670 struct hlist_node *node_tmp;
671 struct hlist_head *head;
672 struct batadv_vis_info *info;
673
674 for (i = 0; i < hash->size; i++) {
675 head = &hash->table[i];
676
677 hlist_for_each_entry_safe(info, node_tmp,
678 head, hash_entry) {
679 /* never purge own data. */
680 if (info == bat_priv->vis.my_info)
681 continue;
682
683 if (batadv_has_timed_out(info->first_seen,
684 BATADV_VIS_TIMEOUT)) {
685 hlist_del(&info->hash_entry);
686 batadv_send_list_del(info);
687 kref_put(&info->refcount, batadv_free_info);
688 }
689 }
690 }
691}
692
693static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
694 struct batadv_vis_info *info)
695{
696 struct batadv_hashtable *hash = bat_priv->orig_hash;
697 struct hlist_head *head;
698 struct batadv_orig_node *orig_node;
699 struct batadv_vis_packet *packet;
700 struct sk_buff *skb;
701 uint32_t i, res;
702
703
704 packet = (struct batadv_vis_packet *)info->skb_packet->data;
705
706 /* send to all routers in range. */
707 for (i = 0; i < hash->size; i++) {
708 head = &hash->table[i];
709
710 rcu_read_lock();
711 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
712 /* if it's a vis server and reachable, send it. */
713 if (!(orig_node->flags & BATADV_VIS_SERVER))
714 continue;
715
716 /* don't send it if we already received the packet from
717 * this node.
718 */
719 if (batadv_recv_list_is_in(bat_priv, &info->recv_list,
720 orig_node->orig))
721 continue;
722
723 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
724 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
725 if (!skb)
726 continue;
727
728 res = batadv_send_skb_to_orig(skb, orig_node, NULL);
729 if (res == NET_XMIT_DROP)
730 kfree_skb(skb);
731 }
732 rcu_read_unlock();
733 }
734}
735
736static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
737 struct batadv_vis_info *info)
738{
739 struct batadv_orig_node *orig_node;
740 struct sk_buff *skb;
741 struct batadv_vis_packet *packet;
742
743 packet = (struct batadv_vis_packet *)info->skb_packet->data;
744
745 orig_node = batadv_orig_hash_find(bat_priv, packet->target_orig);
746 if (!orig_node)
747 goto out;
748
749 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
750 if (!skb)
751 goto out;
752
753 if (batadv_send_skb_to_orig(skb, orig_node, NULL) == NET_XMIT_DROP)
754 kfree_skb(skb);
755
756out:
757 if (orig_node)
758 batadv_orig_node_free_ref(orig_node);
759}
760
761/* only send one vis packet. called from batadv_send_vis_packets() */
762static void batadv_send_vis_packet(struct batadv_priv *bat_priv,
763 struct batadv_vis_info *info)
764{
765 struct batadv_hard_iface *primary_if;
766 struct batadv_vis_packet *packet;
767
768 primary_if = batadv_primary_if_get_selected(bat_priv);
769 if (!primary_if)
770 goto out;
771
772 packet = (struct batadv_vis_packet *)info->skb_packet->data;
773 if (packet->header.ttl < 2) {
774 pr_debug("Error - can't send vis packet: ttl exceeded\n");
775 goto out;
776 }
777
778 memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
779 packet->header.ttl--;
780
781 if (is_broadcast_ether_addr(packet->target_orig))
782 batadv_broadcast_vis_packet(bat_priv, info);
783 else
784 batadv_unicast_vis_packet(bat_priv, info);
785 packet->header.ttl++; /* restore TTL */
786
787out:
788 if (primary_if)
789 batadv_hardif_free_ref(primary_if);
790}
791
792/* called from timer; send (and maybe generate) vis packet. */
793static void batadv_send_vis_packets(struct work_struct *work)
794{
795 struct delayed_work *delayed_work;
796 struct batadv_priv *bat_priv;
797 struct batadv_priv_vis *priv_vis;
798 struct batadv_vis_info *info;
799
800 delayed_work = container_of(work, struct delayed_work, work);
801 priv_vis = container_of(delayed_work, struct batadv_priv_vis, work);
802 bat_priv = container_of(priv_vis, struct batadv_priv, vis);
803 spin_lock_bh(&bat_priv->vis.hash_lock);
804 batadv_purge_vis_packets(bat_priv);
805
806 if (batadv_generate_vis_packet(bat_priv) == 0) {
807 /* schedule if generation was successful */
808 batadv_send_list_add(bat_priv, bat_priv->vis.my_info);
809 }
810
811 while (!list_empty(&bat_priv->vis.send_list)) {
812 info = list_first_entry(&bat_priv->vis.send_list,
813 typeof(*info), send_list);
814
815 kref_get(&info->refcount);
816 spin_unlock_bh(&bat_priv->vis.hash_lock);
817
818 batadv_send_vis_packet(bat_priv, info);
819
820 spin_lock_bh(&bat_priv->vis.hash_lock);
821 batadv_send_list_del(info);
822 kref_put(&info->refcount, batadv_free_info);
823 }
824 spin_unlock_bh(&bat_priv->vis.hash_lock);
825
826 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
827 msecs_to_jiffies(BATADV_VIS_INTERVAL));
828}
829
830/* init the vis server. this may only be called when if_list is already
831 * initialized (e.g. bat0 is initialized, interfaces have been added)
832 */
833int batadv_vis_init(struct batadv_priv *bat_priv)
834{
835 struct batadv_vis_packet *packet;
836 int hash_added;
837 unsigned int len;
838 unsigned long first_seen;
839 struct sk_buff *tmp_skb;
840
841 if (bat_priv->vis.hash)
842 return 0;
843
844 spin_lock_bh(&bat_priv->vis.hash_lock);
845
846 bat_priv->vis.hash = batadv_hash_new(256);
847 if (!bat_priv->vis.hash) {
848 pr_err("Can't initialize vis_hash\n");
849 goto err;
850 }
851
852 batadv_hash_set_lock_class(bat_priv->vis.hash,
853 &batadv_vis_hash_lock_class_key);
854
855 bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
856 if (!bat_priv->vis.my_info)
857 goto err;
858
859 len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN;
860 bat_priv->vis.my_info->skb_packet = netdev_alloc_skb_ip_align(NULL,
861 len);
862 if (!bat_priv->vis.my_info->skb_packet)
863 goto free_info;
864
865 bat_priv->vis.my_info->skb_packet->priority = TC_PRIO_CONTROL;
866 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
867 tmp_skb = bat_priv->vis.my_info->skb_packet;
868 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
869
870 /* prefill the vis info */
871 first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL);
872 bat_priv->vis.my_info->first_seen = first_seen;
873 INIT_LIST_HEAD(&bat_priv->vis.my_info->recv_list);
874 INIT_LIST_HEAD(&bat_priv->vis.my_info->send_list);
875 kref_init(&bat_priv->vis.my_info->refcount);
876 bat_priv->vis.my_info->bat_priv = bat_priv;
877 packet->header.version = BATADV_COMPAT_VERSION;
878 packet->header.packet_type = BATADV_VIS;
879 packet->header.ttl = BATADV_TTL;
880 packet->seqno = 0;
881 packet->reserved = 0;
882 packet->entries = 0;
883
884 INIT_LIST_HEAD(&bat_priv->vis.send_list);
885
886 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
887 batadv_vis_info_choose,
888 bat_priv->vis.my_info,
889 &bat_priv->vis.my_info->hash_entry);
890 if (hash_added != 0) {
891 pr_err("Can't add own vis packet into hash\n");
892 /* not in hash, need to remove it manually. */
893 kref_put(&bat_priv->vis.my_info->refcount, batadv_free_info);
894 goto err;
895 }
896
897 spin_unlock_bh(&bat_priv->vis.hash_lock);
898
899 INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets);
900 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
901 msecs_to_jiffies(BATADV_VIS_INTERVAL));
902
903 return 0;
904
905free_info:
906 kfree(bat_priv->vis.my_info);
907 bat_priv->vis.my_info = NULL;
908err:
909 spin_unlock_bh(&bat_priv->vis.hash_lock);
910 batadv_vis_quit(bat_priv);
911 return -ENOMEM;
912}
913
914/* Decrease the reference count on a hash item info */
915static void batadv_free_info_ref(struct hlist_node *node, void *arg)
916{
917 struct batadv_vis_info *info;
918
919 info = container_of(node, struct batadv_vis_info, hash_entry);
920 batadv_send_list_del(info);
921 kref_put(&info->refcount, batadv_free_info);
922}
923
924/* shutdown vis-server */
925void batadv_vis_quit(struct batadv_priv *bat_priv)
926{
927 if (!bat_priv->vis.hash)
928 return;
929
930 cancel_delayed_work_sync(&bat_priv->vis.work);
931
932 spin_lock_bh(&bat_priv->vis.hash_lock);
933 /* properly remove, kill timers ... */
934 batadv_hash_delete(bat_priv->vis.hash, batadv_free_info_ref, NULL);
935 bat_priv->vis.hash = NULL;
936 bat_priv->vis.my_info = NULL;
937 spin_unlock_bh(&bat_priv->vis.hash_lock);
938}
diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h
deleted file mode 100644
index ad92b0e3c230..000000000000
--- a/net/batman-adv/vis.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/* Copyright (C) 2008-2013 B.A.T.M.A.N. contributors:
2 *
3 * Simon Wunderlich, Marek Lindner
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA
18 */
19
20#ifndef _NET_BATMAN_ADV_VIS_H_
21#define _NET_BATMAN_ADV_VIS_H_
22
23/* timeout of vis packets in milliseconds */
24#define BATADV_VIS_TIMEOUT 200000
25
26int batadv_vis_seq_print_text(struct seq_file *seq, void *offset);
27void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
28 struct batadv_vis_packet *vis_packet,
29 int vis_info_len);
30void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
31 struct batadv_vis_packet *vis_packet,
32 int vis_info_len);
33int batadv_vis_init(struct batadv_priv *bat_priv);
34void batadv_vis_quit(struct batadv_priv *bat_priv);
35
36#endif /* _NET_BATMAN_ADV_VIS_H_ */