aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@web.de>2014-02-15 11:47:51 -0500
committerAntonio Quartulli <antonio@meshcoding.com>2014-03-22 04:18:57 -0400
commit60432d756cf06e597ef9da511402dd059b112447 (patch)
tree69a5059678690c49672ebf430dc21763710060c3 /net/batman-adv
parente17931d1a61d189845d3ca923c5baf99e729156a (diff)
batman-adv: Announce new capability via multicast TVLV
If the soft interface of a node is not part of a bridge then a node announces a new multicast TVLV: The existence of this TVLV signalizes that this node is announcing all of its multicast listeners via the translation table infrastructure. Signed-off-by: Linus Lüssing <linus.luessing@web.de> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/main.c1
-rw-r--r--net/batman-adv/multicast.c123
-rw-r--r--net/batman-adv/multicast.h14
-rw-r--r--net/batman-adv/originator.c6
-rw-r--r--net/batman-adv/packet.h12
-rw-r--r--net/batman-adv/soft-interface.c4
-rw-r--r--net/batman-adv/types.h13
7 files changed, 167 insertions, 6 deletions
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 58e98c89a68f..8f11b67bc4f4 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -149,6 +149,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
149 goto err; 149 goto err;
150 150
151 batadv_gw_init(bat_priv); 151 batadv_gw_init(bat_priv);
152 batadv_mcast_init(bat_priv);
152 153
153 atomic_set(&bat_priv->gw.reselect, 0); 154 atomic_set(&bat_priv->gw.reselect, 0);
154 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); 155 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index e099fd67403c..3ba9a18a906c 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -178,11 +178,52 @@ static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
178} 178}
179 179
180/** 180/**
181 * batadv_mcast_mla_tvlv_update - update multicast tvlv
182 * @bat_priv: the bat priv with all the soft interface information
183 *
184 * Updates the own multicast tvlv with our current multicast related settings,
185 * capabilities and inabilities.
186 *
187 * Returns true if the tvlv container is registered afterwards. Otherwise
188 * returns false.
189 */
190static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv)
191{
192 struct batadv_tvlv_mcast_data mcast_data;
193
194 mcast_data.flags = BATADV_NO_FLAGS;
195 memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
196
197 /* Avoid attaching MLAs, if there is a bridge on top of our soft
198 * interface, we don't support that yet (TODO)
199 */
200 if (batadv_mcast_has_bridge(bat_priv)) {
201 if (bat_priv->mcast.enabled) {
202 batadv_tvlv_container_unregister(bat_priv,
203 BATADV_TVLV_MCAST, 1);
204 bat_priv->mcast.enabled = false;
205 }
206
207 return false;
208 }
209
210 if (!bat_priv->mcast.enabled ||
211 mcast_data.flags != bat_priv->mcast.flags) {
212 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 1,
213 &mcast_data, sizeof(mcast_data));
214 bat_priv->mcast.flags = mcast_data.flags;
215 bat_priv->mcast.enabled = true;
216 }
217
218 return true;
219}
220
221/**
181 * batadv_mcast_mla_update - update the own MLAs 222 * batadv_mcast_mla_update - update the own MLAs
182 * @bat_priv: the bat priv with all the soft interface information 223 * @bat_priv: the bat priv with all the soft interface information
183 * 224 *
184 * Update the own multicast listener announcements in the translation 225 * Updates the own multicast listener announcements in the translation
185 * table. 226 * table as well as the own, announced multicast tvlv container.
186 */ 227 */
187void batadv_mcast_mla_update(struct batadv_priv *bat_priv) 228void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
188{ 229{
@@ -190,10 +231,7 @@ void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
190 struct hlist_head mcast_list = HLIST_HEAD_INIT; 231 struct hlist_head mcast_list = HLIST_HEAD_INIT;
191 int ret; 232 int ret;
192 233
193 /* Avoid attaching MLAs, if there is a bridge on top of our soft 234 if (!batadv_mcast_mla_tvlv_update(bat_priv))
194 * interface, we don't support that yet (TODO)
195 */
196 if (batadv_mcast_has_bridge(bat_priv))
197 goto update; 235 goto update;
198 236
199 ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list); 237 ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
@@ -209,10 +247,83 @@ out:
209} 247}
210 248
211/** 249/**
250 * batadv_mcast_tvlv_ogm_handler_v1 - process incoming multicast tvlv container
251 * @bat_priv: the bat priv with all the soft interface information
252 * @orig: the orig_node of the ogm
253 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
254 * @tvlv_value: tvlv buffer containing the multicast data
255 * @tvlv_value_len: tvlv buffer length
256 */
257static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
258 struct batadv_orig_node *orig,
259 uint8_t flags,
260 void *tvlv_value,
261 uint16_t tvlv_value_len)
262{
263 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
264 uint8_t mcast_flags = BATADV_NO_FLAGS;
265 bool orig_initialized;
266
267 orig_initialized = orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST;
268
269 /* If mcast support is turned on decrease the disabled mcast node
270 * counter only if we had increased it for this node before. If this
271 * is a completely new orig_node no need to decrease the counter.
272 */
273 if (orig_mcast_enabled &&
274 !(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST)) {
275 if (orig_initialized)
276 atomic_dec(&bat_priv->mcast.num_disabled);
277 orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST;
278 /* If mcast support is being switched off increase the disabled
279 * mcast node counter.
280 */
281 } else if (!orig_mcast_enabled &&
282 orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) {
283 atomic_inc(&bat_priv->mcast.num_disabled);
284 orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST;
285 }
286
287 orig->capa_initialized |= BATADV_ORIG_CAPA_HAS_MCAST;
288
289 if (orig_mcast_enabled && tvlv_value &&
290 (tvlv_value_len >= sizeof(mcast_flags)))
291 mcast_flags = *(uint8_t *)tvlv_value;
292
293 orig->mcast_flags = mcast_flags;
294}
295
296/**
297 * batadv_mcast_init - initialize the multicast optimizations structures
298 * @bat_priv: the bat priv with all the soft interface information
299 */
300void batadv_mcast_init(struct batadv_priv *bat_priv)
301{
302 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler_v1,
303 NULL, BATADV_TVLV_MCAST, 1,
304 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
305}
306
307/**
212 * batadv_mcast_free - free the multicast optimizations structures 308 * batadv_mcast_free - free the multicast optimizations structures
213 * @bat_priv: the bat priv with all the soft interface information 309 * @bat_priv: the bat priv with all the soft interface information
214 */ 310 */
215void batadv_mcast_free(struct batadv_priv *bat_priv) 311void batadv_mcast_free(struct batadv_priv *bat_priv)
216{ 312{
313 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
314 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
315
217 batadv_mcast_mla_tt_retract(bat_priv, NULL); 316 batadv_mcast_mla_tt_retract(bat_priv, NULL);
218} 317}
318
319/**
320 * batadv_mcast_purge_orig - reset originator global mcast state modifications
321 * @orig: the originator which is going to get purged
322 */
323void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
324{
325 struct batadv_priv *bat_priv = orig->bat_priv;
326
327 if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST))
328 atomic_dec(&bat_priv->mcast.num_disabled);
329}
diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h
index 7513e024b807..c029eaca7c44 100644
--- a/net/batman-adv/multicast.h
+++ b/net/batman-adv/multicast.h
@@ -22,8 +22,12 @@
22 22
23void batadv_mcast_mla_update(struct batadv_priv *bat_priv); 23void batadv_mcast_mla_update(struct batadv_priv *bat_priv);
24 24
25void batadv_mcast_init(struct batadv_priv *bat_priv);
26
25void batadv_mcast_free(struct batadv_priv *bat_priv); 27void batadv_mcast_free(struct batadv_priv *bat_priv);
26 28
29void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
30
27#else 31#else
28 32
29static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv) 33static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
@@ -31,11 +35,21 @@ static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
31 return; 35 return;
32} 36}
33 37
38static inline int batadv_mcast_init(struct batadv_priv *bat_priv)
39{
40 return 0;
41}
42
34static inline void batadv_mcast_free(struct batadv_priv *bat_priv) 43static inline void batadv_mcast_free(struct batadv_priv *bat_priv)
35{ 44{
36 return; 45 return;
37} 46}
38 47
48static inline void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node)
49{
50 return;
51}
52
39#endif /* CONFIG_BATMAN_ADV_MCAST */ 53#endif /* CONFIG_BATMAN_ADV_MCAST */
40 54
41#endif /* _NET_BATMAN_ADV_MULTICAST_H_ */ 55#endif /* _NET_BATMAN_ADV_MULTICAST_H_ */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 24a9300b08e0..ffd9dfbd9b0e 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -27,6 +27,7 @@
27#include "bridge_loop_avoidance.h" 27#include "bridge_loop_avoidance.h"
28#include "network-coding.h" 28#include "network-coding.h"
29#include "fragmentation.h" 29#include "fragmentation.h"
30#include "multicast.h"
30 31
31/* hash class keys */ 32/* hash class keys */
32static struct lock_class_key batadv_orig_hash_lock_class_key; 33static struct lock_class_key batadv_orig_hash_lock_class_key;
@@ -557,6 +558,8 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
557 } 558 }
558 spin_unlock_bh(&orig_node->neigh_list_lock); 559 spin_unlock_bh(&orig_node->neigh_list_lock);
559 560
561 batadv_mcast_purge_orig(orig_node);
562
560 /* Free nc_nodes */ 563 /* Free nc_nodes */
561 batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); 564 batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
562 565
@@ -672,6 +675,9 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
672 orig_node->tt_buff_len = 0; 675 orig_node->tt_buff_len = 0;
673 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); 676 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
674 orig_node->bcast_seqno_reset = reset_time; 677 orig_node->bcast_seqno_reset = reset_time;
678#ifdef CONFIG_BATMAN_ADV_MCAST
679 orig_node->mcast_flags = BATADV_NO_FLAGS;
680#endif
675 681
676 /* create a vlan object for the "untagged" LAN */ 682 /* create a vlan object for the "untagged" LAN */
677 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS); 683 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 0a381d1174c1..e8c483d2da72 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -145,6 +145,7 @@ enum batadv_bla_claimframe {
145 * @BATADV_TVLV_NC: network coding tvlv 145 * @BATADV_TVLV_NC: network coding tvlv
146 * @BATADV_TVLV_TT: translation table tvlv 146 * @BATADV_TVLV_TT: translation table tvlv
147 * @BATADV_TVLV_ROAM: roaming advertisement tvlv 147 * @BATADV_TVLV_ROAM: roaming advertisement tvlv
148 * @BATADV_TVLV_MCAST: multicast capability tvlv
148 */ 149 */
149enum batadv_tvlv_type { 150enum batadv_tvlv_type {
150 BATADV_TVLV_GW = 0x01, 151 BATADV_TVLV_GW = 0x01,
@@ -152,6 +153,7 @@ enum batadv_tvlv_type {
152 BATADV_TVLV_NC = 0x03, 153 BATADV_TVLV_NC = 0x03,
153 BATADV_TVLV_TT = 0x04, 154 BATADV_TVLV_TT = 0x04,
154 BATADV_TVLV_ROAM = 0x05, 155 BATADV_TVLV_ROAM = 0x05,
156 BATADV_TVLV_MCAST = 0x06,
155}; 157};
156 158
157#pragma pack(2) 159#pragma pack(2)
@@ -504,4 +506,14 @@ struct batadv_tvlv_roam_adv {
504 __be16 vid; 506 __be16 vid;
505}; 507};
506 508
509/**
510 * struct batadv_tvlv_mcast_data - payload of a multicast tvlv
511 * @flags: multicast flags announced by the orig node
512 * @reserved: reserved field
513 */
514struct batadv_tvlv_mcast_data {
515 uint8_t flags;
516 uint8_t reserved[3];
517};
518
507#endif /* _NET_BATMAN_ADV_PACKET_H_ */ 519#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 633e9d67d925..8ff47b7a0e04 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -689,6 +689,10 @@ static int batadv_softif_init_late(struct net_device *dev)
689#ifdef CONFIG_BATMAN_ADV_DAT 689#ifdef CONFIG_BATMAN_ADV_DAT
690 atomic_set(&bat_priv->distributed_arp_table, 1); 690 atomic_set(&bat_priv->distributed_arp_table, 1);
691#endif 691#endif
692#ifdef CONFIG_BATMAN_ADV_MCAST
693 bat_priv->mcast.flags = BATADV_NO_FLAGS;
694 atomic_set(&bat_priv->mcast.num_disabled, 0);
695#endif
692 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); 696 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
693 atomic_set(&bat_priv->gw_sel_class, 20); 697 atomic_set(&bat_priv->gw_sel_class, 20);
694 atomic_set(&bat_priv->gw.bandwidth_down, 100); 698 atomic_set(&bat_priv->gw.bandwidth_down, 100);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index b46117ca5989..96ee0d2b11d9 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -204,6 +204,7 @@ struct batadv_orig_bat_iv {
204 * @batadv_dat_addr_t: address of the orig node in the distributed hash 204 * @batadv_dat_addr_t: address of the orig node in the distributed hash
205 * @last_seen: time when last packet from this node was received 205 * @last_seen: time when last packet from this node was received
206 * @bcast_seqno_reset: time when the broadcast seqno window was reset 206 * @bcast_seqno_reset: time when the broadcast seqno window was reset
207 * @mcast_flags: multicast flags announced by the orig node
207 * @capabilities: announced capabilities of this originator 208 * @capabilities: announced capabilities of this originator
208 * @capa_initialized: bitfield to remember whether a capability was initialized 209 * @capa_initialized: bitfield to remember whether a capability was initialized
209 * @last_ttvn: last seen translation table version number 210 * @last_ttvn: last seen translation table version number
@@ -246,6 +247,9 @@ struct batadv_orig_node {
246#endif 247#endif
247 unsigned long last_seen; 248 unsigned long last_seen;
248 unsigned long bcast_seqno_reset; 249 unsigned long bcast_seqno_reset;
250#ifdef CONFIG_BATMAN_ADV_MCAST
251 uint8_t mcast_flags;
252#endif
249 uint8_t capabilities; 253 uint8_t capabilities;
250 uint8_t capa_initialized; 254 uint8_t capa_initialized;
251 atomic_t last_ttvn; 255 atomic_t last_ttvn;
@@ -282,11 +286,14 @@ struct batadv_orig_node {
282 * @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled 286 * @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled
283 * @BATADV_ORIG_CAPA_HAS_NC: orig node has network coding enabled 287 * @BATADV_ORIG_CAPA_HAS_NC: orig node has network coding enabled
284 * @BATADV_ORIG_CAPA_HAS_TT: orig node has tt capability 288 * @BATADV_ORIG_CAPA_HAS_TT: orig node has tt capability
289 * @BATADV_ORIG_CAPA_HAS_MCAST: orig node has some multicast capability
290 * (= orig node announces a tvlv of type BATADV_TVLV_MCAST)
285 */ 291 */
286enum batadv_orig_capabilities { 292enum batadv_orig_capabilities {
287 BATADV_ORIG_CAPA_HAS_DAT = BIT(0), 293 BATADV_ORIG_CAPA_HAS_DAT = BIT(0),
288 BATADV_ORIG_CAPA_HAS_NC = BIT(1), 294 BATADV_ORIG_CAPA_HAS_NC = BIT(1),
289 BATADV_ORIG_CAPA_HAS_TT = BIT(2), 295 BATADV_ORIG_CAPA_HAS_TT = BIT(2),
296 BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
290}; 297};
291 298
292/** 299/**
@@ -612,9 +619,15 @@ struct batadv_priv_dat {
612/** 619/**
613 * struct batadv_priv_mcast - per mesh interface mcast data 620 * struct batadv_priv_mcast - per mesh interface mcast data
614 * @mla_list: list of multicast addresses we are currently announcing via TT 621 * @mla_list: list of multicast addresses we are currently announcing via TT
622 * @flags: the flags we have last sent in our mcast tvlv
623 * @enabled: whether the multicast tvlv is currently enabled
624 * @num_disabled: number of nodes that have no mcast tvlv
615 */ 625 */
616struct batadv_priv_mcast { 626struct batadv_priv_mcast {
617 struct hlist_head mla_list; 627 struct hlist_head mla_list;
628 uint8_t flags;
629 bool enabled;
630 atomic_t num_disabled;
618}; 631};
619#endif 632#endif
620 633