.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
---|
2 | | -/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: |
---|
| 2 | +/* Copyright (C) 2007-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 "main.h" |
---|
.. | .. |
---|
22 | 10 | #include <linux/build_bug.h> |
---|
23 | 11 | #include <linux/byteorder/generic.h> |
---|
24 | 12 | #include <linux/crc32c.h> |
---|
| 13 | +#include <linux/device.h> |
---|
25 | 14 | #include <linux/errno.h> |
---|
26 | 15 | #include <linux/genetlink.h> |
---|
27 | 16 | #include <linux/gfp.h> |
---|
.. | .. |
---|
31 | 20 | #include <linux/ip.h> |
---|
32 | 21 | #include <linux/ipv6.h> |
---|
33 | 22 | #include <linux/kernel.h> |
---|
| 23 | +#include <linux/kobject.h> |
---|
34 | 24 | #include <linux/kref.h> |
---|
35 | 25 | #include <linux/list.h> |
---|
36 | 26 | #include <linux/module.h> |
---|
.. | .. |
---|
40 | 30 | #include <linux/rcupdate.h> |
---|
41 | 31 | #include <linux/seq_file.h> |
---|
42 | 32 | #include <linux/skbuff.h> |
---|
| 33 | +#include <linux/slab.h> |
---|
43 | 34 | #include <linux/spinlock.h> |
---|
44 | 35 | #include <linux/stddef.h> |
---|
45 | 36 | #include <linux/string.h> |
---|
.. | .. |
---|
74 | 65 | * list traversals just rcu-locked |
---|
75 | 66 | */ |
---|
76 | 67 | struct list_head batadv_hardif_list; |
---|
| 68 | +unsigned int batadv_hardif_generation; |
---|
77 | 69 | static int (*batadv_rx_handler[256])(struct sk_buff *skb, |
---|
78 | 70 | struct batadv_hard_iface *recv_if); |
---|
79 | 71 | |
---|
.. | .. |
---|
82 | 74 | struct workqueue_struct *batadv_event_workqueue; |
---|
83 | 75 | |
---|
84 | 76 | static void batadv_recv_handler_init(void); |
---|
| 77 | + |
---|
| 78 | +#define BATADV_UEV_TYPE_VAR "BATTYPE=" |
---|
| 79 | +#define BATADV_UEV_ACTION_VAR "BATACTION=" |
---|
| 80 | +#define BATADV_UEV_DATA_VAR "BATDATA=" |
---|
| 81 | + |
---|
| 82 | +static char *batadv_uev_action_str[] = { |
---|
| 83 | + "add", |
---|
| 84 | + "del", |
---|
| 85 | + "change", |
---|
| 86 | + "loopdetect", |
---|
| 87 | +}; |
---|
| 88 | + |
---|
| 89 | +static char *batadv_uev_type_str[] = { |
---|
| 90 | + "gw", |
---|
| 91 | + "bla", |
---|
| 92 | +}; |
---|
85 | 93 | |
---|
86 | 94 | static int __init batadv_init(void) |
---|
87 | 95 | { |
---|
.. | .. |
---|
129 | 137 | batadv_netlink_unregister(); |
---|
130 | 138 | rtnl_link_unregister(&batadv_link_ops); |
---|
131 | 139 | unregister_netdevice_notifier(&batadv_hard_if_notifier); |
---|
132 | | - batadv_hardif_remove_interfaces(); |
---|
133 | 140 | |
---|
134 | 141 | flush_workqueue(batadv_event_workqueue); |
---|
135 | 142 | destroy_workqueue(batadv_event_workqueue); |
---|
.. | .. |
---|
186 | 193 | INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list); |
---|
187 | 194 | INIT_HLIST_HEAD(&bat_priv->softif_vlan_list); |
---|
188 | 195 | INIT_HLIST_HEAD(&bat_priv->tp_list); |
---|
| 196 | + |
---|
| 197 | + bat_priv->gw.generation = 0; |
---|
189 | 198 | |
---|
190 | 199 | ret = batadv_originator_init(bat_priv); |
---|
191 | 200 | if (ret < 0) { |
---|
.. | .. |
---|
562 | 571 | BUILD_BUG_ON(sizeof(struct batadv_tvlv_tt_change) != 12); |
---|
563 | 572 | BUILD_BUG_ON(sizeof(struct batadv_tvlv_roam_adv) != 8); |
---|
564 | 573 | |
---|
565 | | - i = FIELD_SIZEOF(struct sk_buff, cb); |
---|
| 574 | + i = sizeof_field(struct sk_buff, cb); |
---|
566 | 575 | BUILD_BUG_ON(sizeof(struct batadv_skb_cb) > i); |
---|
567 | 576 | |
---|
568 | 577 | /* broadcast packet */ |
---|
.. | .. |
---|
680 | 689 | * @vid: the VLAN identifier for which the AP isolation attributed as to be |
---|
681 | 690 | * looked up |
---|
682 | 691 | * |
---|
683 | | - * Return: true if AP isolation is on for the VLAN idenfied by vid, false |
---|
| 692 | + * Return: true if AP isolation is on for the VLAN identified by vid, false |
---|
684 | 693 | * otherwise |
---|
685 | 694 | */ |
---|
686 | 695 | bool batadv_vlan_ap_isola_get(struct batadv_priv *bat_priv, unsigned short vid) |
---|
.. | .. |
---|
700 | 709 | return ap_isolation_enabled; |
---|
701 | 710 | } |
---|
702 | 711 | |
---|
| 712 | +/** |
---|
| 713 | + * batadv_throw_uevent() - Send an uevent with batman-adv specific env data |
---|
| 714 | + * @bat_priv: the bat priv with all the soft interface information |
---|
| 715 | + * @type: subsystem type of event. Stored in uevent's BATTYPE |
---|
| 716 | + * @action: action type of event. Stored in uevent's BATACTION |
---|
| 717 | + * @data: string with additional information to the event (ignored for |
---|
| 718 | + * BATADV_UEV_DEL). Stored in uevent's BATDATA |
---|
| 719 | + * |
---|
| 720 | + * Return: 0 on success or negative error number in case of failure |
---|
| 721 | + */ |
---|
| 722 | +int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type, |
---|
| 723 | + enum batadv_uev_action action, const char *data) |
---|
| 724 | +{ |
---|
| 725 | + int ret = -ENOMEM; |
---|
| 726 | + struct kobject *bat_kobj; |
---|
| 727 | + char *uevent_env[4] = { NULL, NULL, NULL, NULL }; |
---|
| 728 | + |
---|
| 729 | + bat_kobj = &bat_priv->soft_iface->dev.kobj; |
---|
| 730 | + |
---|
| 731 | + uevent_env[0] = kasprintf(GFP_ATOMIC, |
---|
| 732 | + "%s%s", BATADV_UEV_TYPE_VAR, |
---|
| 733 | + batadv_uev_type_str[type]); |
---|
| 734 | + if (!uevent_env[0]) |
---|
| 735 | + goto out; |
---|
| 736 | + |
---|
| 737 | + uevent_env[1] = kasprintf(GFP_ATOMIC, |
---|
| 738 | + "%s%s", BATADV_UEV_ACTION_VAR, |
---|
| 739 | + batadv_uev_action_str[action]); |
---|
| 740 | + if (!uevent_env[1]) |
---|
| 741 | + goto out; |
---|
| 742 | + |
---|
| 743 | + /* If the event is DEL, ignore the data field */ |
---|
| 744 | + if (action != BATADV_UEV_DEL) { |
---|
| 745 | + uevent_env[2] = kasprintf(GFP_ATOMIC, |
---|
| 746 | + "%s%s", BATADV_UEV_DATA_VAR, data); |
---|
| 747 | + if (!uevent_env[2]) |
---|
| 748 | + goto out; |
---|
| 749 | + } |
---|
| 750 | + |
---|
| 751 | + ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env); |
---|
| 752 | +out: |
---|
| 753 | + kfree(uevent_env[0]); |
---|
| 754 | + kfree(uevent_env[1]); |
---|
| 755 | + kfree(uevent_env[2]); |
---|
| 756 | + |
---|
| 757 | + if (ret) |
---|
| 758 | + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
---|
| 759 | + "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n", |
---|
| 760 | + batadv_uev_type_str[type], |
---|
| 761 | + batadv_uev_action_str[action], |
---|
| 762 | + (action == BATADV_UEV_DEL ? "NULL" : data), ret); |
---|
| 763 | + return ret; |
---|
| 764 | +} |
---|
| 765 | + |
---|
703 | 766 | module_init(batadv_init); |
---|
704 | 767 | module_exit(batadv_exit); |
---|
705 | 768 | |
---|