1 /* Copyright (C) 2014-2016 B.A.T.M.A.N. contributors: 2 * 3 * Linus Lüssing 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, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "multicast.h" 19 #include "main.h" 20 21 #include <linux/atomic.h> 22 #include <linux/bitops.h> 23 #include <linux/bug.h> 24 #include <linux/byteorder/generic.h> 25 #include <linux/errno.h> 26 #include <linux/etherdevice.h> 27 #include <linux/fs.h> 28 #include <linux/if_ether.h> 29 #include <linux/in6.h> 30 #include <linux/in.h> 31 #include <linux/ip.h> 32 #include <linux/ipv6.h> 33 #include <linux/kref.h> 34 #include <linux/list.h> 35 #include <linux/lockdep.h> 36 #include <linux/netdevice.h> 37 #include <linux/rculist.h> 38 #include <linux/rcupdate.h> 39 #include <linux/skbuff.h> 40 #include <linux/slab.h> 41 #include <linux/spinlock.h> 42 #include <linux/stddef.h> 43 #include <linux/string.h> 44 #include <linux/types.h> 45 #include <net/addrconf.h> 46 #include <net/ipv6.h> 47 48 #include "packet.h" 49 #include "translation-table.h" 50 51 /** 52 * batadv_mcast_mla_softif_get - get softif multicast listeners 53 * @dev: the device to collect multicast addresses from 54 * @mcast_list: a list to put found addresses into 55 * 56 * Collect multicast addresses of the local multicast listeners 57 * on the given soft interface, dev, in the given mcast_list. 58 * 59 * Return: -ENOMEM on memory allocation error or the number of 60 * items added to the mcast_list otherwise. 61 */ 62 static int batadv_mcast_mla_softif_get(struct net_device *dev, 63 struct hlist_head *mcast_list) 64 { 65 struct netdev_hw_addr *mc_list_entry; 66 struct batadv_hw_addr *new; 67 int ret = 0; 68 69 netif_addr_lock_bh(dev); 70 netdev_for_each_mc_addr(mc_list_entry, dev) { 71 new = kmalloc(sizeof(*new), GFP_ATOMIC); 72 if (!new) { 73 ret = -ENOMEM; 74 break; 75 } 76 77 ether_addr_copy(new->addr, mc_list_entry->addr); 78 hlist_add_head(&new->list, mcast_list); 79 ret++; 80 } 81 netif_addr_unlock_bh(dev); 82 83 return ret; 84 } 85 86 /** 87 * batadv_mcast_mla_is_duplicate - check whether an address is in a list 88 * @mcast_addr: the multicast address to check 89 * @mcast_list: the list with multicast addresses to search in 90 * 91 * Return: true if the given address is already in the given list. 92 * Otherwise returns false. 93 */ 94 static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr, 95 struct hlist_head *mcast_list) 96 { 97 struct batadv_hw_addr *mcast_entry; 98 99 hlist_for_each_entry(mcast_entry, mcast_list, list) 100 if (batadv_compare_eth(mcast_entry->addr, mcast_addr)) 101 return true; 102 103 return false; 104 } 105 106 /** 107 * batadv_mcast_mla_list_free - free a list of multicast addresses 108 * @bat_priv: the bat priv with all the soft interface information 109 * @mcast_list: the list to free 110 * 111 * Removes and frees all items in the given mcast_list. 112 */ 113 static void batadv_mcast_mla_list_free(struct batadv_priv *bat_priv, 114 struct hlist_head *mcast_list) 115 { 116 struct batadv_hw_addr *mcast_entry; 117 struct hlist_node *tmp; 118 119 lockdep_assert_held(&bat_priv->tt.commit_lock); 120 121 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) { 122 hlist_del(&mcast_entry->list); 123 kfree(mcast_entry); 124 } 125 } 126 127 /** 128 * batadv_mcast_mla_tt_retract - clean up multicast listener announcements 129 * @bat_priv: the bat priv with all the soft interface information 130 * @mcast_list: a list of addresses which should _not_ be removed 131 * 132 * Retracts the announcement of any multicast listener from the 133 * translation table except the ones listed in the given mcast_list. 134 * 135 * If mcast_list is NULL then all are retracted. 136 */ 137 static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv, 138 struct hlist_head *mcast_list) 139 { 140 struct batadv_hw_addr *mcast_entry; 141 struct hlist_node *tmp; 142 143 lockdep_assert_held(&bat_priv->tt.commit_lock); 144 145 hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list, 146 list) { 147 if (mcast_list && 148 batadv_mcast_mla_is_duplicate(mcast_entry->addr, 149 mcast_list)) 150 continue; 151 152 batadv_tt_local_remove(bat_priv, mcast_entry->addr, 153 BATADV_NO_FLAGS, 154 "mcast TT outdated", false); 155 156 hlist_del(&mcast_entry->list); 157 kfree(mcast_entry); 158 } 159 } 160 161 /** 162 * batadv_mcast_mla_tt_add - add multicast listener announcements 163 * @bat_priv: the bat priv with all the soft interface information 164 * @mcast_list: a list of addresses which are going to get added 165 * 166 * Adds multicast listener announcements from the given mcast_list to the 167 * translation table if they have not been added yet. 168 */ 169 static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv, 170 struct hlist_head *mcast_list) 171 { 172 struct batadv_hw_addr *mcast_entry; 173 struct hlist_node *tmp; 174 175 lockdep_assert_held(&bat_priv->tt.commit_lock); 176 177 if (!mcast_list) 178 return; 179 180 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) { 181 if (batadv_mcast_mla_is_duplicate(mcast_entry->addr, 182 &bat_priv->mcast.mla_list)) 183 continue; 184 185 if (!batadv_tt_local_add(bat_priv->soft_iface, 186 mcast_entry->addr, BATADV_NO_FLAGS, 187 BATADV_NULL_IFINDEX, BATADV_NO_MARK)) 188 continue; 189 190 hlist_del(&mcast_entry->list); 191 hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list); 192 } 193 } 194 195 /** 196 * batadv_mcast_has_bridge - check whether the soft-iface is bridged 197 * @bat_priv: the bat priv with all the soft interface information 198 * 199 * Checks whether there is a bridge on top of our soft interface. 200 * 201 * Return: true if there is a bridge, false otherwise. 202 */ 203 static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv) 204 { 205 struct net_device *upper = bat_priv->soft_iface; 206 207 rcu_read_lock(); 208 do { 209 upper = netdev_master_upper_dev_get_rcu(upper); 210 } while (upper && !(upper->priv_flags & IFF_EBRIDGE)); 211 rcu_read_unlock(); 212 213 return upper; 214 } 215 216 /** 217 * batadv_mcast_mla_tvlv_update - update multicast tvlv 218 * @bat_priv: the bat priv with all the soft interface information 219 * 220 * Updates the own multicast tvlv with our current multicast related settings, 221 * capabilities and inabilities. 222 * 223 * Return: true if the tvlv container is registered afterwards. Otherwise 224 * returns false. 225 */ 226 static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv) 227 { 228 struct batadv_tvlv_mcast_data mcast_data; 229 230 mcast_data.flags = BATADV_NO_FLAGS; 231 memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved)); 232 233 /* Avoid attaching MLAs, if there is a bridge on top of our soft 234 * interface, we don't support that yet (TODO) 235 */ 236 if (batadv_mcast_has_bridge(bat_priv)) { 237 if (bat_priv->mcast.enabled) { 238 batadv_tvlv_container_unregister(bat_priv, 239 BATADV_TVLV_MCAST, 1); 240 bat_priv->mcast.enabled = false; 241 } 242 243 return false; 244 } 245 246 if (!bat_priv->mcast.enabled || 247 mcast_data.flags != bat_priv->mcast.flags) { 248 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 1, 249 &mcast_data, sizeof(mcast_data)); 250 bat_priv->mcast.flags = mcast_data.flags; 251 bat_priv->mcast.enabled = true; 252 } 253 254 return true; 255 } 256 257 /** 258 * batadv_mcast_mla_update - update the own MLAs 259 * @bat_priv: the bat priv with all the soft interface information 260 * 261 * Updates the own multicast listener announcements in the translation 262 * table as well as the own, announced multicast tvlv container. 263 */ 264 void batadv_mcast_mla_update(struct batadv_priv *bat_priv) 265 { 266 struct net_device *soft_iface = bat_priv->soft_iface; 267 struct hlist_head mcast_list = HLIST_HEAD_INIT; 268 int ret; 269 270 if (!batadv_mcast_mla_tvlv_update(bat_priv)) 271 goto update; 272 273 ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list); 274 if (ret < 0) 275 goto out; 276 277 update: 278 batadv_mcast_mla_tt_retract(bat_priv, &mcast_list); 279 batadv_mcast_mla_tt_add(bat_priv, &mcast_list); 280 281 out: 282 batadv_mcast_mla_list_free(bat_priv, &mcast_list); 283 } 284 285 /** 286 * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential 287 * @bat_priv: the bat priv with all the soft interface information 288 * @skb: the IPv4 packet to check 289 * @is_unsnoopable: stores whether the destination is snoopable 290 * 291 * Checks whether the given IPv4 packet has the potential to be forwarded with a 292 * mode more optimal than classic flooding. 293 * 294 * Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory 295 * allocation failure. 296 */ 297 static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv, 298 struct sk_buff *skb, 299 bool *is_unsnoopable) 300 { 301 struct iphdr *iphdr; 302 303 /* We might fail due to out-of-memory -> drop it */ 304 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr))) 305 return -ENOMEM; 306 307 iphdr = ip_hdr(skb); 308 309 /* TODO: Implement Multicast Router Discovery (RFC4286), 310 * then allow scope > link local, too 311 */ 312 if (!ipv4_is_local_multicast(iphdr->daddr)) 313 return -EINVAL; 314 315 /* link-local multicast listeners behind a bridge are 316 * not snoopable (see RFC4541, section 2.1.2.2) 317 */ 318 *is_unsnoopable = true; 319 320 return 0; 321 } 322 323 /** 324 * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential 325 * @bat_priv: the bat priv with all the soft interface information 326 * @skb: the IPv6 packet to check 327 * @is_unsnoopable: stores whether the destination is snoopable 328 * 329 * Checks whether the given IPv6 packet has the potential to be forwarded with a 330 * mode more optimal than classic flooding. 331 * 332 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory 333 */ 334 static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv, 335 struct sk_buff *skb, 336 bool *is_unsnoopable) 337 { 338 struct ipv6hdr *ip6hdr; 339 340 /* We might fail due to out-of-memory -> drop it */ 341 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr))) 342 return -ENOMEM; 343 344 ip6hdr = ipv6_hdr(skb); 345 346 /* TODO: Implement Multicast Router Discovery (RFC4286), 347 * then allow scope > link local, too 348 */ 349 if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) != IPV6_ADDR_SCOPE_LINKLOCAL) 350 return -EINVAL; 351 352 /* link-local-all-nodes multicast listeners behind a bridge are 353 * not snoopable (see RFC4541, section 3, paragraph 3) 354 */ 355 if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr)) 356 *is_unsnoopable = true; 357 358 return 0; 359 } 360 361 /** 362 * batadv_mcast_forw_mode_check - check for optimized forwarding potential 363 * @bat_priv: the bat priv with all the soft interface information 364 * @skb: the multicast frame to check 365 * @is_unsnoopable: stores whether the destination is snoopable 366 * 367 * Checks whether the given multicast ethernet frame has the potential to be 368 * forwarded with a mode more optimal than classic flooding. 369 * 370 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory 371 */ 372 static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv, 373 struct sk_buff *skb, 374 bool *is_unsnoopable) 375 { 376 struct ethhdr *ethhdr = eth_hdr(skb); 377 378 if (!atomic_read(&bat_priv->multicast_mode)) 379 return -EINVAL; 380 381 if (atomic_read(&bat_priv->mcast.num_disabled)) 382 return -EINVAL; 383 384 switch (ntohs(ethhdr->h_proto)) { 385 case ETH_P_IP: 386 return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb, 387 is_unsnoopable); 388 case ETH_P_IPV6: 389 return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb, 390 is_unsnoopable); 391 default: 392 return -EINVAL; 393 } 394 } 395 396 /** 397 * batadv_mcast_forw_want_all_ip_count - count nodes with unspecific mcast 398 * interest 399 * @bat_priv: the bat priv with all the soft interface information 400 * @ethhdr: ethernet header of a packet 401 * 402 * Return: the number of nodes which want all IPv4 multicast traffic if the 403 * given ethhdr is from an IPv4 packet or the number of nodes which want all 404 * IPv6 traffic if it matches an IPv6 packet. 405 */ 406 static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv, 407 struct ethhdr *ethhdr) 408 { 409 switch (ntohs(ethhdr->h_proto)) { 410 case ETH_P_IP: 411 return atomic_read(&bat_priv->mcast.num_want_all_ipv4); 412 case ETH_P_IPV6: 413 return atomic_read(&bat_priv->mcast.num_want_all_ipv6); 414 default: 415 /* we shouldn't be here... */ 416 return 0; 417 } 418 } 419 420 /** 421 * batadv_mcast_forw_tt_node_get - get a multicast tt node 422 * @bat_priv: the bat priv with all the soft interface information 423 * @ethhdr: the ether header containing the multicast destination 424 * 425 * Return: an orig_node matching the multicast address provided by ethhdr 426 * via a translation table lookup. This increases the returned nodes refcount. 427 */ 428 static struct batadv_orig_node * 429 batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv, 430 struct ethhdr *ethhdr) 431 { 432 return batadv_transtable_search(bat_priv, ethhdr->h_source, 433 ethhdr->h_dest, BATADV_NO_FLAGS); 434 } 435 436 /** 437 * batadv_mcast_forw_ipv4_node_get - get a node with an ipv4 flag 438 * @bat_priv: the bat priv with all the soft interface information 439 * 440 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and 441 * increases its refcount. 442 */ 443 static struct batadv_orig_node * 444 batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv) 445 { 446 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL; 447 448 rcu_read_lock(); 449 hlist_for_each_entry_rcu(tmp_orig_node, 450 &bat_priv->mcast.want_all_ipv4_list, 451 mcast_want_all_ipv4_node) { 452 if (!kref_get_unless_zero(&tmp_orig_node->refcount)) 453 continue; 454 455 orig_node = tmp_orig_node; 456 break; 457 } 458 rcu_read_unlock(); 459 460 return orig_node; 461 } 462 463 /** 464 * batadv_mcast_forw_ipv6_node_get - get a node with an ipv6 flag 465 * @bat_priv: the bat priv with all the soft interface information 466 * 467 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set 468 * and increases its refcount. 469 */ 470 static struct batadv_orig_node * 471 batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv) 472 { 473 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL; 474 475 rcu_read_lock(); 476 hlist_for_each_entry_rcu(tmp_orig_node, 477 &bat_priv->mcast.want_all_ipv6_list, 478 mcast_want_all_ipv6_node) { 479 if (!kref_get_unless_zero(&tmp_orig_node->refcount)) 480 continue; 481 482 orig_node = tmp_orig_node; 483 break; 484 } 485 rcu_read_unlock(); 486 487 return orig_node; 488 } 489 490 /** 491 * batadv_mcast_forw_ip_node_get - get a node with an ipv4/ipv6 flag 492 * @bat_priv: the bat priv with all the soft interface information 493 * @ethhdr: an ethernet header to determine the protocol family from 494 * 495 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or 496 * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, set and 497 * increases its refcount. 498 */ 499 static struct batadv_orig_node * 500 batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv, 501 struct ethhdr *ethhdr) 502 { 503 switch (ntohs(ethhdr->h_proto)) { 504 case ETH_P_IP: 505 return batadv_mcast_forw_ipv4_node_get(bat_priv); 506 case ETH_P_IPV6: 507 return batadv_mcast_forw_ipv6_node_get(bat_priv); 508 default: 509 /* we shouldn't be here... */ 510 return NULL; 511 } 512 } 513 514 /** 515 * batadv_mcast_forw_unsnoop_node_get - get a node with an unsnoopable flag 516 * @bat_priv: the bat priv with all the soft interface information 517 * 518 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag 519 * set and increases its refcount. 520 */ 521 static struct batadv_orig_node * 522 batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv) 523 { 524 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL; 525 526 rcu_read_lock(); 527 hlist_for_each_entry_rcu(tmp_orig_node, 528 &bat_priv->mcast.want_all_unsnoopables_list, 529 mcast_want_all_unsnoopables_node) { 530 if (!kref_get_unless_zero(&tmp_orig_node->refcount)) 531 continue; 532 533 orig_node = tmp_orig_node; 534 break; 535 } 536 rcu_read_unlock(); 537 538 return orig_node; 539 } 540 541 /** 542 * batadv_mcast_forw_mode - check on how to forward a multicast packet 543 * @bat_priv: the bat priv with all the soft interface information 544 * @skb: The multicast packet to check 545 * @orig: an originator to be set to forward the skb to 546 * 547 * Return: the forwarding mode as enum batadv_forw_mode and in case of 548 * BATADV_FORW_SINGLE set the orig to the single originator the skb 549 * should be forwarded to. 550 */ 551 enum batadv_forw_mode 552 batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, 553 struct batadv_orig_node **orig) 554 { 555 int ret, tt_count, ip_count, unsnoop_count, total_count; 556 bool is_unsnoopable = false; 557 struct ethhdr *ethhdr; 558 559 ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable); 560 if (ret == -ENOMEM) 561 return BATADV_FORW_NONE; 562 else if (ret < 0) 563 return BATADV_FORW_ALL; 564 565 ethhdr = eth_hdr(skb); 566 567 tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest, 568 BATADV_NO_FLAGS); 569 ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr); 570 unsnoop_count = !is_unsnoopable ? 0 : 571 atomic_read(&bat_priv->mcast.num_want_all_unsnoopables); 572 573 total_count = tt_count + ip_count + unsnoop_count; 574 575 switch (total_count) { 576 case 1: 577 if (tt_count) 578 *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr); 579 else if (ip_count) 580 *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr); 581 else if (unsnoop_count) 582 *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv); 583 584 if (*orig) 585 return BATADV_FORW_SINGLE; 586 587 /* fall through */ 588 case 0: 589 return BATADV_FORW_NONE; 590 default: 591 return BATADV_FORW_ALL; 592 } 593 } 594 595 /** 596 * batadv_mcast_want_unsnoop_update - update unsnoop counter and list 597 * @bat_priv: the bat priv with all the soft interface information 598 * @orig: the orig_node which multicast state might have changed of 599 * @mcast_flags: flags indicating the new multicast state 600 * 601 * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator, 602 * orig, has toggled then this method updates counter and list accordingly. 603 * 604 * Caller needs to hold orig->mcast_handler_lock. 605 */ 606 static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv, 607 struct batadv_orig_node *orig, 608 u8 mcast_flags) 609 { 610 struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node; 611 struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list; 612 613 lockdep_assert_held(&orig->mcast_handler_lock); 614 615 /* switched from flag unset to set */ 616 if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && 617 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) { 618 atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables); 619 620 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 621 /* flag checks above + mcast_handler_lock prevents this */ 622 WARN_ON(!hlist_unhashed(node)); 623 624 hlist_add_head_rcu(node, head); 625 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 626 /* switched from flag set to unset */ 627 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) && 628 orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) { 629 atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables); 630 631 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 632 /* flag checks above + mcast_handler_lock prevents this */ 633 WARN_ON(hlist_unhashed(node)); 634 635 hlist_del_init_rcu(node); 636 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 637 } 638 } 639 640 /** 641 * batadv_mcast_want_ipv4_update - update want-all-ipv4 counter and list 642 * @bat_priv: the bat priv with all the soft interface information 643 * @orig: the orig_node which multicast state might have changed of 644 * @mcast_flags: flags indicating the new multicast state 645 * 646 * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has 647 * toggled then this method updates counter and list accordingly. 648 * 649 * Caller needs to hold orig->mcast_handler_lock. 650 */ 651 static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv, 652 struct batadv_orig_node *orig, 653 u8 mcast_flags) 654 { 655 struct hlist_node *node = &orig->mcast_want_all_ipv4_node; 656 struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list; 657 658 lockdep_assert_held(&orig->mcast_handler_lock); 659 660 /* switched from flag unset to set */ 661 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 && 662 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) { 663 atomic_inc(&bat_priv->mcast.num_want_all_ipv4); 664 665 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 666 /* flag checks above + mcast_handler_lock prevents this */ 667 WARN_ON(!hlist_unhashed(node)); 668 669 hlist_add_head_rcu(node, head); 670 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 671 /* switched from flag set to unset */ 672 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) && 673 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) { 674 atomic_dec(&bat_priv->mcast.num_want_all_ipv4); 675 676 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 677 /* flag checks above + mcast_handler_lock prevents this */ 678 WARN_ON(hlist_unhashed(node)); 679 680 hlist_del_init_rcu(node); 681 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 682 } 683 } 684 685 /** 686 * batadv_mcast_want_ipv6_update - update want-all-ipv6 counter and list 687 * @bat_priv: the bat priv with all the soft interface information 688 * @orig: the orig_node which multicast state might have changed of 689 * @mcast_flags: flags indicating the new multicast state 690 * 691 * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has 692 * toggled then this method updates counter and list accordingly. 693 * 694 * Caller needs to hold orig->mcast_handler_lock. 695 */ 696 static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv, 697 struct batadv_orig_node *orig, 698 u8 mcast_flags) 699 { 700 struct hlist_node *node = &orig->mcast_want_all_ipv6_node; 701 struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list; 702 703 lockdep_assert_held(&orig->mcast_handler_lock); 704 705 /* switched from flag unset to set */ 706 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 && 707 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) { 708 atomic_inc(&bat_priv->mcast.num_want_all_ipv6); 709 710 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 711 /* flag checks above + mcast_handler_lock prevents this */ 712 WARN_ON(!hlist_unhashed(node)); 713 714 hlist_add_head_rcu(node, head); 715 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 716 /* switched from flag set to unset */ 717 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) && 718 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) { 719 atomic_dec(&bat_priv->mcast.num_want_all_ipv6); 720 721 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 722 /* flag checks above + mcast_handler_lock prevents this */ 723 WARN_ON(hlist_unhashed(node)); 724 725 hlist_del_init_rcu(node); 726 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 727 } 728 } 729 730 /** 731 * batadv_mcast_tvlv_ogm_handler_v1 - process incoming multicast tvlv container 732 * @bat_priv: the bat priv with all the soft interface information 733 * @orig: the orig_node of the ogm 734 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) 735 * @tvlv_value: tvlv buffer containing the multicast data 736 * @tvlv_value_len: tvlv buffer length 737 */ 738 static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, 739 struct batadv_orig_node *orig, 740 u8 flags, 741 void *tvlv_value, 742 u16 tvlv_value_len) 743 { 744 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 745 u8 mcast_flags = BATADV_NO_FLAGS; 746 bool orig_initialized; 747 748 if (orig_mcast_enabled && tvlv_value && 749 (tvlv_value_len >= sizeof(mcast_flags))) 750 mcast_flags = *(u8 *)tvlv_value; 751 752 spin_lock_bh(&orig->mcast_handler_lock); 753 orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST, 754 &orig->capa_initialized); 755 756 /* If mcast support is turned on decrease the disabled mcast node 757 * counter only if we had increased it for this node before. If this 758 * is a completely new orig_node no need to decrease the counter. 759 */ 760 if (orig_mcast_enabled && 761 !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) { 762 if (orig_initialized) 763 atomic_dec(&bat_priv->mcast.num_disabled); 764 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities); 765 /* If mcast support is being switched off or if this is an initial 766 * OGM without mcast support then increase the disabled mcast 767 * node counter. 768 */ 769 } else if (!orig_mcast_enabled && 770 (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) || 771 !orig_initialized)) { 772 atomic_inc(&bat_priv->mcast.num_disabled); 773 clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities); 774 } 775 776 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized); 777 778 batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags); 779 batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags); 780 batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags); 781 782 orig->mcast_flags = mcast_flags; 783 spin_unlock_bh(&orig->mcast_handler_lock); 784 } 785 786 /** 787 * batadv_mcast_init - initialize the multicast optimizations structures 788 * @bat_priv: the bat priv with all the soft interface information 789 */ 790 void batadv_mcast_init(struct batadv_priv *bat_priv) 791 { 792 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler_v1, 793 NULL, BATADV_TVLV_MCAST, 1, 794 BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 795 } 796 797 /** 798 * batadv_mcast_free - free the multicast optimizations structures 799 * @bat_priv: the bat priv with all the soft interface information 800 */ 801 void batadv_mcast_free(struct batadv_priv *bat_priv) 802 { 803 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1); 804 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1); 805 806 spin_lock_bh(&bat_priv->tt.commit_lock); 807 batadv_mcast_mla_tt_retract(bat_priv, NULL); 808 spin_unlock_bh(&bat_priv->tt.commit_lock); 809 } 810 811 /** 812 * batadv_mcast_purge_orig - reset originator global mcast state modifications 813 * @orig: the originator which is going to get purged 814 */ 815 void batadv_mcast_purge_orig(struct batadv_orig_node *orig) 816 { 817 struct batadv_priv *bat_priv = orig->bat_priv; 818 819 spin_lock_bh(&orig->mcast_handler_lock); 820 821 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) && 822 test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized)) 823 atomic_dec(&bat_priv->mcast.num_disabled); 824 825 batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); 826 batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS); 827 batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS); 828 829 spin_unlock_bh(&orig->mcast_handler_lock); 830 } 831