diff options
author | Linus Lüssing <linus.luessing@web.de> | 2014-02-15 11:47:51 -0500 |
---|---|---|
committer | Antonio Quartulli <antonio@meshcoding.com> | 2014-03-22 04:18:57 -0400 |
commit | 60432d756cf06e597ef9da511402dd059b112447 (patch) | |
tree | 69a5059678690c49672ebf430dc21763710060c3 /net/batman-adv | |
parent | e17931d1a61d189845d3ca923c5baf99e729156a (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.c | 1 | ||||
-rw-r--r-- | net/batman-adv/multicast.c | 123 | ||||
-rw-r--r-- | net/batman-adv/multicast.h | 14 | ||||
-rw-r--r-- | net/batman-adv/originator.c | 6 | ||||
-rw-r--r-- | net/batman-adv/packet.h | 12 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 4 | ||||
-rw-r--r-- | net/batman-adv/types.h | 13 |
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 | */ | ||
190 | static 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 | */ |
187 | void batadv_mcast_mla_update(struct batadv_priv *bat_priv) | 228 | void 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 | */ | ||
257 | static 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 | */ | ||
300 | void 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 | */ |
215 | void batadv_mcast_free(struct batadv_priv *bat_priv) | 311 | void 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 | */ | ||
323 | void 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 | ||
23 | void batadv_mcast_mla_update(struct batadv_priv *bat_priv); | 23 | void batadv_mcast_mla_update(struct batadv_priv *bat_priv); |
24 | 24 | ||
25 | void batadv_mcast_init(struct batadv_priv *bat_priv); | ||
26 | |||
25 | void batadv_mcast_free(struct batadv_priv *bat_priv); | 27 | void batadv_mcast_free(struct batadv_priv *bat_priv); |
26 | 28 | ||
29 | void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node); | ||
30 | |||
27 | #else | 31 | #else |
28 | 32 | ||
29 | static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv) | 33 | static 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 | ||
38 | static inline int batadv_mcast_init(struct batadv_priv *bat_priv) | ||
39 | { | ||
40 | return 0; | ||
41 | } | ||
42 | |||
34 | static inline void batadv_mcast_free(struct batadv_priv *bat_priv) | 43 | static inline void batadv_mcast_free(struct batadv_priv *bat_priv) |
35 | { | 44 | { |
36 | return; | 45 | return; |
37 | } | 46 | } |
38 | 47 | ||
48 | static 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 */ |
32 | static struct lock_class_key batadv_orig_hash_lock_class_key; | 33 | static 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 | */ |
149 | enum batadv_tvlv_type { | 150 | enum 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 | */ | ||
514 | struct 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 | */ |
286 | enum batadv_orig_capabilities { | 292 | enum 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 | */ |
616 | struct batadv_priv_mcast { | 626 | struct 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 | ||