| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | | -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: |
|---|
| 2 | +/* Copyright (C) 2009-2020 B.A.T.M.A.N. contributors: |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Marek Lindner, Simon Wunderlich |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of version 2 of the GNU General Public |
|---|
| 8 | | - * License as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | | - * General Public License for more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License |
|---|
| 16 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | 5 | */ |
|---|
| 18 | 6 | |
|---|
| 19 | 7 | #include "originator.h" |
|---|
| .. | .. |
|---|
| 39 | 27 | #include <linux/stddef.h> |
|---|
| 40 | 28 | #include <linux/workqueue.h> |
|---|
| 41 | 29 | #include <net/sock.h> |
|---|
| 30 | +#include <uapi/linux/batadv_packet.h> |
|---|
| 42 | 31 | #include <uapi/linux/batman_adv.h> |
|---|
| 43 | 32 | |
|---|
| 44 | 33 | #include "bat_algo.h" |
|---|
| .. | .. |
|---|
| 189 | 178 | * and queue for free after rcu grace period |
|---|
| 190 | 179 | * @ref: kref pointer of the originator-vlan object |
|---|
| 191 | 180 | */ |
|---|
| 192 | | -static void batadv_orig_node_vlan_release(struct kref *ref) |
|---|
| 181 | +void batadv_orig_node_vlan_release(struct kref *ref) |
|---|
| 193 | 182 | { |
|---|
| 194 | 183 | struct batadv_orig_node_vlan *orig_vlan; |
|---|
| 195 | 184 | |
|---|
| 196 | 185 | orig_vlan = container_of(ref, struct batadv_orig_node_vlan, refcount); |
|---|
| 197 | 186 | |
|---|
| 198 | 187 | kfree_rcu(orig_vlan, rcu); |
|---|
| 199 | | -} |
|---|
| 200 | | - |
|---|
| 201 | | -/** |
|---|
| 202 | | - * batadv_orig_node_vlan_put() - decrement the refcounter and possibly release |
|---|
| 203 | | - * the originator-vlan object |
|---|
| 204 | | - * @orig_vlan: the originator-vlan object to release |
|---|
| 205 | | - */ |
|---|
| 206 | | -void batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan) |
|---|
| 207 | | -{ |
|---|
| 208 | | - kref_put(&orig_vlan->refcount, batadv_orig_node_vlan_release); |
|---|
| 209 | 188 | } |
|---|
| 210 | 189 | |
|---|
| 211 | 190 | /** |
|---|
| .. | .. |
|---|
| 243 | 222 | * free after rcu grace period |
|---|
| 244 | 223 | * @ref: kref pointer of the neigh_ifinfo |
|---|
| 245 | 224 | */ |
|---|
| 246 | | -static void batadv_neigh_ifinfo_release(struct kref *ref) |
|---|
| 225 | +void batadv_neigh_ifinfo_release(struct kref *ref) |
|---|
| 247 | 226 | { |
|---|
| 248 | 227 | struct batadv_neigh_ifinfo *neigh_ifinfo; |
|---|
| 249 | 228 | |
|---|
| .. | .. |
|---|
| 256 | 235 | } |
|---|
| 257 | 236 | |
|---|
| 258 | 237 | /** |
|---|
| 259 | | - * batadv_neigh_ifinfo_put() - decrement the refcounter and possibly release |
|---|
| 260 | | - * the neigh_ifinfo |
|---|
| 261 | | - * @neigh_ifinfo: the neigh_ifinfo object to release |
|---|
| 262 | | - */ |
|---|
| 263 | | -void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo) |
|---|
| 264 | | -{ |
|---|
| 265 | | - kref_put(&neigh_ifinfo->refcount, batadv_neigh_ifinfo_release); |
|---|
| 266 | | -} |
|---|
| 267 | | - |
|---|
| 268 | | -/** |
|---|
| 269 | 238 | * batadv_hardif_neigh_release() - release hardif neigh node from lists and |
|---|
| 270 | 239 | * queue for free after rcu grace period |
|---|
| 271 | 240 | * @ref: kref pointer of the neigh_node |
|---|
| 272 | 241 | */ |
|---|
| 273 | | -static void batadv_hardif_neigh_release(struct kref *ref) |
|---|
| 242 | +void batadv_hardif_neigh_release(struct kref *ref) |
|---|
| 274 | 243 | { |
|---|
| 275 | 244 | struct batadv_hardif_neigh_node *hardif_neigh; |
|---|
| 276 | 245 | |
|---|
| .. | .. |
|---|
| 286 | 255 | } |
|---|
| 287 | 256 | |
|---|
| 288 | 257 | /** |
|---|
| 289 | | - * batadv_hardif_neigh_put() - decrement the hardif neighbors refcounter |
|---|
| 290 | | - * and possibly release it |
|---|
| 291 | | - * @hardif_neigh: hardif neigh neighbor to free |
|---|
| 292 | | - */ |
|---|
| 293 | | -void batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh) |
|---|
| 294 | | -{ |
|---|
| 295 | | - kref_put(&hardif_neigh->refcount, batadv_hardif_neigh_release); |
|---|
| 296 | | -} |
|---|
| 297 | | - |
|---|
| 298 | | -/** |
|---|
| 299 | 258 | * batadv_neigh_node_release() - release neigh_node from lists and queue for |
|---|
| 300 | 259 | * free after rcu grace period |
|---|
| 301 | 260 | * @ref: kref pointer of the neigh_node |
|---|
| 302 | 261 | */ |
|---|
| 303 | | -static void batadv_neigh_node_release(struct kref *ref) |
|---|
| 262 | +void batadv_neigh_node_release(struct kref *ref) |
|---|
| 304 | 263 | { |
|---|
| 305 | 264 | struct hlist_node *node_tmp; |
|---|
| 306 | 265 | struct batadv_neigh_node *neigh_node; |
|---|
| .. | .. |
|---|
| 321 | 280 | } |
|---|
| 322 | 281 | |
|---|
| 323 | 282 | /** |
|---|
| 324 | | - * batadv_neigh_node_put() - decrement the neighbors refcounter and possibly |
|---|
| 325 | | - * release it |
|---|
| 326 | | - * @neigh_node: neigh neighbor to free |
|---|
| 327 | | - */ |
|---|
| 328 | | -void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node) |
|---|
| 329 | | -{ |
|---|
| 330 | | - kref_put(&neigh_node->refcount, batadv_neigh_node_release); |
|---|
| 331 | | -} |
|---|
| 332 | | - |
|---|
| 333 | | -/** |
|---|
| 334 | 283 | * batadv_orig_router_get() - router to the originator depending on iface |
|---|
| 335 | 284 | * @orig_node: the orig node for the router |
|---|
| 336 | 285 | * @if_outgoing: the interface where the payload packet has been received or |
|---|
| 337 | 286 | * the OGM should be sent to |
|---|
| 338 | 287 | * |
|---|
| 339 | | - * Return: the neighbor which should be router for this orig_node/iface. |
|---|
| 288 | + * Return: the neighbor which should be the router for this orig_node/iface. |
|---|
| 340 | 289 | * |
|---|
| 341 | 290 | * The object is returned with refcounter increased by 1. |
|---|
| 342 | 291 | */ |
|---|
| .. | .. |
|---|
| 526 | 475 | * Looks for and possibly returns a neighbour belonging to this originator list |
|---|
| 527 | 476 | * which is connected through the provided hard interface. |
|---|
| 528 | 477 | * |
|---|
| 529 | | - * Return: neighbor when found. Othwerwise NULL |
|---|
| 478 | + * Return: neighbor when found. Otherwise NULL |
|---|
| 530 | 479 | */ |
|---|
| 531 | 480 | static struct batadv_neigh_node * |
|---|
| 532 | 481 | batadv_neigh_node_get(const struct batadv_orig_node *orig_node, |
|---|
| .. | .. |
|---|
| 631 | 580 | * |
|---|
| 632 | 581 | * Looks for and possibly returns a neighbour belonging to this hard interface. |
|---|
| 633 | 582 | * |
|---|
| 634 | | - * Return: neighbor when found. Othwerwise NULL |
|---|
| 583 | + * Return: neighbor when found. Otherwise NULL |
|---|
| 635 | 584 | */ |
|---|
| 636 | 585 | struct batadv_hardif_neigh_node * |
|---|
| 637 | 586 | batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface, |
|---|
| .. | .. |
|---|
| 862 | 811 | * free after rcu grace period |
|---|
| 863 | 812 | * @ref: kref pointer of the orig_ifinfo |
|---|
| 864 | 813 | */ |
|---|
| 865 | | -static void batadv_orig_ifinfo_release(struct kref *ref) |
|---|
| 814 | +void batadv_orig_ifinfo_release(struct kref *ref) |
|---|
| 866 | 815 | { |
|---|
| 867 | 816 | struct batadv_orig_ifinfo *orig_ifinfo; |
|---|
| 868 | 817 | struct batadv_neigh_node *router; |
|---|
| .. | .. |
|---|
| 881 | 830 | } |
|---|
| 882 | 831 | |
|---|
| 883 | 832 | /** |
|---|
| 884 | | - * batadv_orig_ifinfo_put() - decrement the refcounter and possibly release |
|---|
| 885 | | - * the orig_ifinfo |
|---|
| 886 | | - * @orig_ifinfo: the orig_ifinfo object to release |
|---|
| 887 | | - */ |
|---|
| 888 | | -void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo) |
|---|
| 889 | | -{ |
|---|
| 890 | | - kref_put(&orig_ifinfo->refcount, batadv_orig_ifinfo_release); |
|---|
| 891 | | -} |
|---|
| 892 | | - |
|---|
| 893 | | -/** |
|---|
| 894 | 833 | * batadv_orig_node_free_rcu() - free the orig_node |
|---|
| 895 | 834 | * @rcu: rcu pointer of the orig_node |
|---|
| 896 | 835 | */ |
|---|
| .. | .. |
|---|
| 904 | 843 | |
|---|
| 905 | 844 | batadv_frag_purge_orig(orig_node, NULL); |
|---|
| 906 | 845 | |
|---|
| 907 | | - if (orig_node->bat_priv->algo_ops->orig.free) |
|---|
| 908 | | - orig_node->bat_priv->algo_ops->orig.free(orig_node); |
|---|
| 909 | | - |
|---|
| 910 | 846 | kfree(orig_node->tt_buff); |
|---|
| 911 | 847 | kfree(orig_node); |
|---|
| 912 | 848 | } |
|---|
| .. | .. |
|---|
| 916 | 852 | * free after rcu grace period |
|---|
| 917 | 853 | * @ref: kref pointer of the orig_node |
|---|
| 918 | 854 | */ |
|---|
| 919 | | -static void batadv_orig_node_release(struct kref *ref) |
|---|
| 855 | +void batadv_orig_node_release(struct kref *ref) |
|---|
| 920 | 856 | { |
|---|
| 921 | 857 | struct hlist_node *node_tmp; |
|---|
| 922 | 858 | struct batadv_neigh_node *neigh_node; |
|---|
| .. | .. |
|---|
| 963 | 899 | } |
|---|
| 964 | 900 | |
|---|
| 965 | 901 | /** |
|---|
| 966 | | - * batadv_orig_node_put() - decrement the orig node refcounter and possibly |
|---|
| 967 | | - * release it |
|---|
| 968 | | - * @orig_node: the orig node to free |
|---|
| 969 | | - */ |
|---|
| 970 | | -void batadv_orig_node_put(struct batadv_orig_node *orig_node) |
|---|
| 971 | | -{ |
|---|
| 972 | | - kref_put(&orig_node->refcount, batadv_orig_node_release); |
|---|
| 973 | | -} |
|---|
| 974 | | - |
|---|
| 975 | | -/** |
|---|
| 976 | 902 | * batadv_originator_free() - Free all originator structures |
|---|
| 977 | 903 | * @bat_priv: the bat priv with all the soft interface information |
|---|
| 978 | 904 | */ |
|---|
| .. | .. |
|---|
| 1013 | 939 | * @bat_priv: the bat priv with all the soft interface information |
|---|
| 1014 | 940 | * @addr: the mac address of the originator |
|---|
| 1015 | 941 | * |
|---|
| 1016 | | - * Creates a new originator object and initialise all the generic fields. |
|---|
| 942 | + * Creates a new originator object and initialises all the generic fields. |
|---|
| 1017 | 943 | * The new object is not added to the originator list. |
|---|
| 1018 | 944 | * |
|---|
| 1019 | 945 | * Return: the newly created object or NULL on failure. |
|---|
| .. | .. |
|---|
| 1058 | 984 | orig_node->bcast_seqno_reset = reset_time; |
|---|
| 1059 | 985 | |
|---|
| 1060 | 986 | #ifdef CONFIG_BATMAN_ADV_MCAST |
|---|
| 1061 | | - orig_node->mcast_flags = BATADV_NO_FLAGS; |
|---|
| 987 | + orig_node->mcast_flags = BATADV_MCAST_WANT_NO_RTR4; |
|---|
| 988 | + orig_node->mcast_flags |= BATADV_MCAST_WANT_NO_RTR6; |
|---|
| 1062 | 989 | INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node); |
|---|
| 1063 | 990 | INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node); |
|---|
| 1064 | 991 | INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node); |
|---|
| .. | .. |
|---|
| 1554 | 1481 | dev_put(soft_iface); |
|---|
| 1555 | 1482 | |
|---|
| 1556 | 1483 | return ret; |
|---|
| 1557 | | -} |
|---|
| 1558 | | - |
|---|
| 1559 | | -/** |
|---|
| 1560 | | - * batadv_orig_hash_add_if() - Add interface to originators in orig_hash |
|---|
| 1561 | | - * @hard_iface: hard interface to add (already slave of the soft interface) |
|---|
| 1562 | | - * @max_if_num: new number of interfaces |
|---|
| 1563 | | - * |
|---|
| 1564 | | - * Return: 0 on success or negative error number in case of failure |
|---|
| 1565 | | - */ |
|---|
| 1566 | | -int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, |
|---|
| 1567 | | - unsigned int max_if_num) |
|---|
| 1568 | | -{ |
|---|
| 1569 | | - struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
|---|
| 1570 | | - struct batadv_algo_ops *bao = bat_priv->algo_ops; |
|---|
| 1571 | | - struct batadv_hashtable *hash = bat_priv->orig_hash; |
|---|
| 1572 | | - struct hlist_head *head; |
|---|
| 1573 | | - struct batadv_orig_node *orig_node; |
|---|
| 1574 | | - u32 i; |
|---|
| 1575 | | - int ret; |
|---|
| 1576 | | - |
|---|
| 1577 | | - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
|---|
| 1578 | | - * if_num |
|---|
| 1579 | | - */ |
|---|
| 1580 | | - for (i = 0; i < hash->size; i++) { |
|---|
| 1581 | | - head = &hash->table[i]; |
|---|
| 1582 | | - |
|---|
| 1583 | | - rcu_read_lock(); |
|---|
| 1584 | | - hlist_for_each_entry_rcu(orig_node, head, hash_entry) { |
|---|
| 1585 | | - ret = 0; |
|---|
| 1586 | | - if (bao->orig.add_if) |
|---|
| 1587 | | - ret = bao->orig.add_if(orig_node, max_if_num); |
|---|
| 1588 | | - if (ret == -ENOMEM) |
|---|
| 1589 | | - goto err; |
|---|
| 1590 | | - } |
|---|
| 1591 | | - rcu_read_unlock(); |
|---|
| 1592 | | - } |
|---|
| 1593 | | - |
|---|
| 1594 | | - return 0; |
|---|
| 1595 | | - |
|---|
| 1596 | | -err: |
|---|
| 1597 | | - rcu_read_unlock(); |
|---|
| 1598 | | - return -ENOMEM; |
|---|
| 1599 | | -} |
|---|
| 1600 | | - |
|---|
| 1601 | | -/** |
|---|
| 1602 | | - * batadv_orig_hash_del_if() - Remove interface from originators in orig_hash |
|---|
| 1603 | | - * @hard_iface: hard interface to remove (still slave of the soft interface) |
|---|
| 1604 | | - * @max_if_num: new number of interfaces |
|---|
| 1605 | | - * |
|---|
| 1606 | | - * Return: 0 on success or negative error number in case of failure |
|---|
| 1607 | | - */ |
|---|
| 1608 | | -int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, |
|---|
| 1609 | | - unsigned int max_if_num) |
|---|
| 1610 | | -{ |
|---|
| 1611 | | - struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
|---|
| 1612 | | - struct batadv_hashtable *hash = bat_priv->orig_hash; |
|---|
| 1613 | | - struct hlist_head *head; |
|---|
| 1614 | | - struct batadv_hard_iface *hard_iface_tmp; |
|---|
| 1615 | | - struct batadv_orig_node *orig_node; |
|---|
| 1616 | | - struct batadv_algo_ops *bao = bat_priv->algo_ops; |
|---|
| 1617 | | - u32 i; |
|---|
| 1618 | | - int ret; |
|---|
| 1619 | | - |
|---|
| 1620 | | - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
|---|
| 1621 | | - * if_num |
|---|
| 1622 | | - */ |
|---|
| 1623 | | - for (i = 0; i < hash->size; i++) { |
|---|
| 1624 | | - head = &hash->table[i]; |
|---|
| 1625 | | - |
|---|
| 1626 | | - rcu_read_lock(); |
|---|
| 1627 | | - hlist_for_each_entry_rcu(orig_node, head, hash_entry) { |
|---|
| 1628 | | - ret = 0; |
|---|
| 1629 | | - if (bao->orig.del_if) |
|---|
| 1630 | | - ret = bao->orig.del_if(orig_node, max_if_num, |
|---|
| 1631 | | - hard_iface->if_num); |
|---|
| 1632 | | - if (ret == -ENOMEM) |
|---|
| 1633 | | - goto err; |
|---|
| 1634 | | - } |
|---|
| 1635 | | - rcu_read_unlock(); |
|---|
| 1636 | | - } |
|---|
| 1637 | | - |
|---|
| 1638 | | - /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ |
|---|
| 1639 | | - rcu_read_lock(); |
|---|
| 1640 | | - list_for_each_entry_rcu(hard_iface_tmp, &batadv_hardif_list, list) { |
|---|
| 1641 | | - if (hard_iface_tmp->if_status == BATADV_IF_NOT_IN_USE) |
|---|
| 1642 | | - continue; |
|---|
| 1643 | | - |
|---|
| 1644 | | - if (hard_iface == hard_iface_tmp) |
|---|
| 1645 | | - continue; |
|---|
| 1646 | | - |
|---|
| 1647 | | - if (hard_iface->soft_iface != hard_iface_tmp->soft_iface) |
|---|
| 1648 | | - continue; |
|---|
| 1649 | | - |
|---|
| 1650 | | - if (hard_iface_tmp->if_num > hard_iface->if_num) |
|---|
| 1651 | | - hard_iface_tmp->if_num--; |
|---|
| 1652 | | - } |
|---|
| 1653 | | - rcu_read_unlock(); |
|---|
| 1654 | | - |
|---|
| 1655 | | - hard_iface->if_num = -1; |
|---|
| 1656 | | - return 0; |
|---|
| 1657 | | - |
|---|
| 1658 | | -err: |
|---|
| 1659 | | - rcu_read_unlock(); |
|---|
| 1660 | | - return -ENOMEM; |
|---|
| 1661 | 1484 | } |
|---|