.. | .. |
---|
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 | } |
---|