Commit b61ec31c85756bbc898fb892555509afe709459a
Committed by
Simon Wunderlich
1 parent
25c097ca41
batman-adv: Snoop DHCPACKs for DAT
In a 1000 nodes mesh network (Freifunk Hamburg) we can still see 30KBit/s of ARP traffic (equalling about 25% of all layer two specific overhead, remaining after some filtering) flooded through the mesh. These 30KBit/s are mainly ARP Requests from the gateways / DHCP servers. By snooping DHCPACKs we can learn about MAC/IP address pairs in the DHCP range without relying on ARP. This patch is in preparation to eliminate the need for mesh wide message flooding for IPv4 address resolution. Also this allows to quickly update a MAC/IP pair at least in the DHT when DHCP reassigns an IP address to a new host. Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Showing 4 changed files with 431 additions and 2 deletions Inline Diff
net/batman-adv/distributed-arp-table.c
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors: | 2 | /* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Antonio Quartulli | 4 | * Antonio Quartulli |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 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 | 7 | * modify it under the terms of version 2 of the GNU General Public |
8 | * License as published by the Free Software Foundation. | 8 | * License as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, but | 10 | * This program is distributed in the hope that it will be useful, but |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * General Public License for more details. | 13 | * General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 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/>. | 16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "distributed-arp-table.h" | 19 | #include "distributed-arp-table.h" |
20 | #include "main.h" | 20 | #include "main.h" |
21 | 21 | ||
22 | #include <asm/unaligned.h> | ||
22 | #include <linux/atomic.h> | 23 | #include <linux/atomic.h> |
23 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
24 | #include <linux/byteorder/generic.h> | 25 | #include <linux/byteorder/generic.h> |
25 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
26 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
27 | #include <linux/gfp.h> | 28 | #include <linux/gfp.h> |
28 | #include <linux/if_arp.h> | 29 | #include <linux/if_arp.h> |
29 | #include <linux/if_ether.h> | 30 | #include <linux/if_ether.h> |
30 | #include <linux/if_vlan.h> | 31 | #include <linux/if_vlan.h> |
31 | #include <linux/in.h> | 32 | #include <linux/in.h> |
33 | #include <linux/ip.h> | ||
32 | #include <linux/jiffies.h> | 34 | #include <linux/jiffies.h> |
33 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
34 | #include <linux/kref.h> | 36 | #include <linux/kref.h> |
35 | #include <linux/list.h> | 37 | #include <linux/list.h> |
36 | #include <linux/netlink.h> | 38 | #include <linux/netlink.h> |
37 | #include <linux/rculist.h> | 39 | #include <linux/rculist.h> |
38 | #include <linux/rcupdate.h> | 40 | #include <linux/rcupdate.h> |
39 | #include <linux/seq_file.h> | 41 | #include <linux/seq_file.h> |
40 | #include <linux/skbuff.h> | 42 | #include <linux/skbuff.h> |
41 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
42 | #include <linux/spinlock.h> | 44 | #include <linux/spinlock.h> |
43 | #include <linux/stddef.h> | 45 | #include <linux/stddef.h> |
44 | #include <linux/string.h> | 46 | #include <linux/string.h> |
47 | #include <linux/udp.h> | ||
45 | #include <linux/workqueue.h> | 48 | #include <linux/workqueue.h> |
46 | #include <net/arp.h> | 49 | #include <net/arp.h> |
47 | #include <net/genetlink.h> | 50 | #include <net/genetlink.h> |
48 | #include <net/netlink.h> | 51 | #include <net/netlink.h> |
49 | #include <net/sock.h> | 52 | #include <net/sock.h> |
50 | #include <uapi/linux/batman_adv.h> | 53 | #include <uapi/linux/batman_adv.h> |
51 | 54 | ||
52 | #include "bridge_loop_avoidance.h" | 55 | #include "bridge_loop_avoidance.h" |
53 | #include "hard-interface.h" | 56 | #include "hard-interface.h" |
54 | #include "hash.h" | 57 | #include "hash.h" |
55 | #include "log.h" | 58 | #include "log.h" |
56 | #include "netlink.h" | 59 | #include "netlink.h" |
57 | #include "originator.h" | 60 | #include "originator.h" |
58 | #include "send.h" | 61 | #include "send.h" |
59 | #include "soft-interface.h" | 62 | #include "soft-interface.h" |
60 | #include "translation-table.h" | 63 | #include "translation-table.h" |
61 | #include "tvlv.h" | 64 | #include "tvlv.h" |
62 | 65 | ||
66 | enum batadv_bootpop { | ||
67 | BATADV_BOOTREPLY = 2, | ||
68 | }; | ||
69 | |||
70 | enum batadv_boothtype { | ||
71 | BATADV_HTYPE_ETHERNET = 1, | ||
72 | }; | ||
73 | |||
74 | enum batadv_dhcpoptioncode { | ||
75 | BATADV_DHCP_OPT_PAD = 0, | ||
76 | BATADV_DHCP_OPT_MSG_TYPE = 53, | ||
77 | BATADV_DHCP_OPT_END = 255, | ||
78 | }; | ||
79 | |||
80 | enum batadv_dhcptype { | ||
81 | BATADV_DHCPACK = 5, | ||
82 | }; | ||
83 | |||
84 | /* { 99, 130, 83, 99 } */ | ||
85 | #define BATADV_DHCP_MAGIC 1669485411 | ||
86 | |||
87 | struct batadv_dhcp_packet { | ||
88 | __u8 op; | ||
89 | __u8 htype; | ||
90 | __u8 hlen; | ||
91 | __u8 hops; | ||
92 | __be32 xid; | ||
93 | __be16 secs; | ||
94 | __be16 flags; | ||
95 | __be32 ciaddr; | ||
96 | __be32 yiaddr; | ||
97 | __be32 siaddr; | ||
98 | __be32 giaddr; | ||
99 | __u8 chaddr[16]; | ||
100 | __u8 sname[64]; | ||
101 | __u8 file[128]; | ||
102 | __be32 magic; | ||
103 | __u8 options[0]; | ||
104 | }; | ||
105 | |||
106 | #define BATADV_DHCP_YIADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->yiaddr) | ||
107 | #define BATADV_DHCP_CHADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->chaddr) | ||
108 | |||
63 | static void batadv_dat_purge(struct work_struct *work); | 109 | static void batadv_dat_purge(struct work_struct *work); |
64 | 110 | ||
65 | /** | 111 | /** |
66 | * batadv_dat_start_timer() - initialise the DAT periodic worker | 112 | * batadv_dat_start_timer() - initialise the DAT periodic worker |
67 | * @bat_priv: the bat priv with all the soft interface information | 113 | * @bat_priv: the bat priv with all the soft interface information |
68 | */ | 114 | */ |
69 | static void batadv_dat_start_timer(struct batadv_priv *bat_priv) | 115 | static void batadv_dat_start_timer(struct batadv_priv *bat_priv) |
70 | { | 116 | { |
71 | INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge); | 117 | INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge); |
72 | queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work, | 118 | queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work, |
73 | msecs_to_jiffies(10000)); | 119 | msecs_to_jiffies(10000)); |
74 | } | 120 | } |
75 | 121 | ||
76 | /** | 122 | /** |
77 | * batadv_dat_entry_release() - release dat_entry from lists and queue for free | 123 | * batadv_dat_entry_release() - release dat_entry from lists and queue for free |
78 | * after rcu grace period | 124 | * after rcu grace period |
79 | * @ref: kref pointer of the dat_entry | 125 | * @ref: kref pointer of the dat_entry |
80 | */ | 126 | */ |
81 | static void batadv_dat_entry_release(struct kref *ref) | 127 | static void batadv_dat_entry_release(struct kref *ref) |
82 | { | 128 | { |
83 | struct batadv_dat_entry *dat_entry; | 129 | struct batadv_dat_entry *dat_entry; |
84 | 130 | ||
85 | dat_entry = container_of(ref, struct batadv_dat_entry, refcount); | 131 | dat_entry = container_of(ref, struct batadv_dat_entry, refcount); |
86 | 132 | ||
87 | kfree_rcu(dat_entry, rcu); | 133 | kfree_rcu(dat_entry, rcu); |
88 | } | 134 | } |
89 | 135 | ||
90 | /** | 136 | /** |
91 | * batadv_dat_entry_put() - decrement the dat_entry refcounter and possibly | 137 | * batadv_dat_entry_put() - decrement the dat_entry refcounter and possibly |
92 | * release it | 138 | * release it |
93 | * @dat_entry: dat_entry to be free'd | 139 | * @dat_entry: dat_entry to be free'd |
94 | */ | 140 | */ |
95 | static void batadv_dat_entry_put(struct batadv_dat_entry *dat_entry) | 141 | static void batadv_dat_entry_put(struct batadv_dat_entry *dat_entry) |
96 | { | 142 | { |
97 | kref_put(&dat_entry->refcount, batadv_dat_entry_release); | 143 | kref_put(&dat_entry->refcount, batadv_dat_entry_release); |
98 | } | 144 | } |
99 | 145 | ||
100 | /** | 146 | /** |
101 | * batadv_dat_to_purge() - check whether a dat_entry has to be purged or not | 147 | * batadv_dat_to_purge() - check whether a dat_entry has to be purged or not |
102 | * @dat_entry: the entry to check | 148 | * @dat_entry: the entry to check |
103 | * | 149 | * |
104 | * Return: true if the entry has to be purged now, false otherwise. | 150 | * Return: true if the entry has to be purged now, false otherwise. |
105 | */ | 151 | */ |
106 | static bool batadv_dat_to_purge(struct batadv_dat_entry *dat_entry) | 152 | static bool batadv_dat_to_purge(struct batadv_dat_entry *dat_entry) |
107 | { | 153 | { |
108 | return batadv_has_timed_out(dat_entry->last_update, | 154 | return batadv_has_timed_out(dat_entry->last_update, |
109 | BATADV_DAT_ENTRY_TIMEOUT); | 155 | BATADV_DAT_ENTRY_TIMEOUT); |
110 | } | 156 | } |
111 | 157 | ||
112 | /** | 158 | /** |
113 | * __batadv_dat_purge() - delete entries from the DAT local storage | 159 | * __batadv_dat_purge() - delete entries from the DAT local storage |
114 | * @bat_priv: the bat priv with all the soft interface information | 160 | * @bat_priv: the bat priv with all the soft interface information |
115 | * @to_purge: function in charge to decide whether an entry has to be purged or | 161 | * @to_purge: function in charge to decide whether an entry has to be purged or |
116 | * not. This function takes the dat_entry as argument and has to | 162 | * not. This function takes the dat_entry as argument and has to |
117 | * returns a boolean value: true is the entry has to be deleted, | 163 | * returns a boolean value: true is the entry has to be deleted, |
118 | * false otherwise | 164 | * false otherwise |
119 | * | 165 | * |
120 | * Loops over each entry in the DAT local storage and deletes it if and only if | 166 | * Loops over each entry in the DAT local storage and deletes it if and only if |
121 | * the to_purge function passed as argument returns true. | 167 | * the to_purge function passed as argument returns true. |
122 | */ | 168 | */ |
123 | static void __batadv_dat_purge(struct batadv_priv *bat_priv, | 169 | static void __batadv_dat_purge(struct batadv_priv *bat_priv, |
124 | bool (*to_purge)(struct batadv_dat_entry *)) | 170 | bool (*to_purge)(struct batadv_dat_entry *)) |
125 | { | 171 | { |
126 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 172 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
127 | struct batadv_dat_entry *dat_entry; | 173 | struct batadv_dat_entry *dat_entry; |
128 | struct hlist_node *node_tmp; | 174 | struct hlist_node *node_tmp; |
129 | struct hlist_head *head; | 175 | struct hlist_head *head; |
130 | u32 i; | 176 | u32 i; |
131 | 177 | ||
132 | if (!bat_priv->dat.hash) | 178 | if (!bat_priv->dat.hash) |
133 | return; | 179 | return; |
134 | 180 | ||
135 | for (i = 0; i < bat_priv->dat.hash->size; i++) { | 181 | for (i = 0; i < bat_priv->dat.hash->size; i++) { |
136 | head = &bat_priv->dat.hash->table[i]; | 182 | head = &bat_priv->dat.hash->table[i]; |
137 | list_lock = &bat_priv->dat.hash->list_locks[i]; | 183 | list_lock = &bat_priv->dat.hash->list_locks[i]; |
138 | 184 | ||
139 | spin_lock_bh(list_lock); | 185 | spin_lock_bh(list_lock); |
140 | hlist_for_each_entry_safe(dat_entry, node_tmp, head, | 186 | hlist_for_each_entry_safe(dat_entry, node_tmp, head, |
141 | hash_entry) { | 187 | hash_entry) { |
142 | /* if a helper function has been passed as parameter, | 188 | /* if a helper function has been passed as parameter, |
143 | * ask it if the entry has to be purged or not | 189 | * ask it if the entry has to be purged or not |
144 | */ | 190 | */ |
145 | if (to_purge && !to_purge(dat_entry)) | 191 | if (to_purge && !to_purge(dat_entry)) |
146 | continue; | 192 | continue; |
147 | 193 | ||
148 | hlist_del_rcu(&dat_entry->hash_entry); | 194 | hlist_del_rcu(&dat_entry->hash_entry); |
149 | batadv_dat_entry_put(dat_entry); | 195 | batadv_dat_entry_put(dat_entry); |
150 | } | 196 | } |
151 | spin_unlock_bh(list_lock); | 197 | spin_unlock_bh(list_lock); |
152 | } | 198 | } |
153 | } | 199 | } |
154 | 200 | ||
155 | /** | 201 | /** |
156 | * batadv_dat_purge() - periodic task that deletes old entries from the local | 202 | * batadv_dat_purge() - periodic task that deletes old entries from the local |
157 | * DAT hash table | 203 | * DAT hash table |
158 | * @work: kernel work struct | 204 | * @work: kernel work struct |
159 | */ | 205 | */ |
160 | static void batadv_dat_purge(struct work_struct *work) | 206 | static void batadv_dat_purge(struct work_struct *work) |
161 | { | 207 | { |
162 | struct delayed_work *delayed_work; | 208 | struct delayed_work *delayed_work; |
163 | struct batadv_priv_dat *priv_dat; | 209 | struct batadv_priv_dat *priv_dat; |
164 | struct batadv_priv *bat_priv; | 210 | struct batadv_priv *bat_priv; |
165 | 211 | ||
166 | delayed_work = to_delayed_work(work); | 212 | delayed_work = to_delayed_work(work); |
167 | priv_dat = container_of(delayed_work, struct batadv_priv_dat, work); | 213 | priv_dat = container_of(delayed_work, struct batadv_priv_dat, work); |
168 | bat_priv = container_of(priv_dat, struct batadv_priv, dat); | 214 | bat_priv = container_of(priv_dat, struct batadv_priv, dat); |
169 | 215 | ||
170 | __batadv_dat_purge(bat_priv, batadv_dat_to_purge); | 216 | __batadv_dat_purge(bat_priv, batadv_dat_to_purge); |
171 | batadv_dat_start_timer(bat_priv); | 217 | batadv_dat_start_timer(bat_priv); |
172 | } | 218 | } |
173 | 219 | ||
174 | /** | 220 | /** |
175 | * batadv_compare_dat() - comparing function used in the local DAT hash table | 221 | * batadv_compare_dat() - comparing function used in the local DAT hash table |
176 | * @node: node in the local table | 222 | * @node: node in the local table |
177 | * @data2: second object to compare the node to | 223 | * @data2: second object to compare the node to |
178 | * | 224 | * |
179 | * Return: true if the two entries are the same, false otherwise. | 225 | * Return: true if the two entries are the same, false otherwise. |
180 | */ | 226 | */ |
181 | static bool batadv_compare_dat(const struct hlist_node *node, const void *data2) | 227 | static bool batadv_compare_dat(const struct hlist_node *node, const void *data2) |
182 | { | 228 | { |
183 | const void *data1 = container_of(node, struct batadv_dat_entry, | 229 | const void *data1 = container_of(node, struct batadv_dat_entry, |
184 | hash_entry); | 230 | hash_entry); |
185 | 231 | ||
186 | return memcmp(data1, data2, sizeof(__be32)) == 0; | 232 | return memcmp(data1, data2, sizeof(__be32)) == 0; |
187 | } | 233 | } |
188 | 234 | ||
189 | /** | 235 | /** |
190 | * batadv_arp_hw_src() - extract the hw_src field from an ARP packet | 236 | * batadv_arp_hw_src() - extract the hw_src field from an ARP packet |
191 | * @skb: ARP packet | 237 | * @skb: ARP packet |
192 | * @hdr_size: size of the possible header before the ARP packet | 238 | * @hdr_size: size of the possible header before the ARP packet |
193 | * | 239 | * |
194 | * Return: the value of the hw_src field in the ARP packet. | 240 | * Return: the value of the hw_src field in the ARP packet. |
195 | */ | 241 | */ |
196 | static u8 *batadv_arp_hw_src(struct sk_buff *skb, int hdr_size) | 242 | static u8 *batadv_arp_hw_src(struct sk_buff *skb, int hdr_size) |
197 | { | 243 | { |
198 | u8 *addr; | 244 | u8 *addr; |
199 | 245 | ||
200 | addr = (u8 *)(skb->data + hdr_size); | 246 | addr = (u8 *)(skb->data + hdr_size); |
201 | addr += ETH_HLEN + sizeof(struct arphdr); | 247 | addr += ETH_HLEN + sizeof(struct arphdr); |
202 | 248 | ||
203 | return addr; | 249 | return addr; |
204 | } | 250 | } |
205 | 251 | ||
206 | /** | 252 | /** |
207 | * batadv_arp_ip_src() - extract the ip_src field from an ARP packet | 253 | * batadv_arp_ip_src() - extract the ip_src field from an ARP packet |
208 | * @skb: ARP packet | 254 | * @skb: ARP packet |
209 | * @hdr_size: size of the possible header before the ARP packet | 255 | * @hdr_size: size of the possible header before the ARP packet |
210 | * | 256 | * |
211 | * Return: the value of the ip_src field in the ARP packet. | 257 | * Return: the value of the ip_src field in the ARP packet. |
212 | */ | 258 | */ |
213 | static __be32 batadv_arp_ip_src(struct sk_buff *skb, int hdr_size) | 259 | static __be32 batadv_arp_ip_src(struct sk_buff *skb, int hdr_size) |
214 | { | 260 | { |
215 | return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN); | 261 | return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN); |
216 | } | 262 | } |
217 | 263 | ||
218 | /** | 264 | /** |
219 | * batadv_arp_hw_dst() - extract the hw_dst field from an ARP packet | 265 | * batadv_arp_hw_dst() - extract the hw_dst field from an ARP packet |
220 | * @skb: ARP packet | 266 | * @skb: ARP packet |
221 | * @hdr_size: size of the possible header before the ARP packet | 267 | * @hdr_size: size of the possible header before the ARP packet |
222 | * | 268 | * |
223 | * Return: the value of the hw_dst field in the ARP packet. | 269 | * Return: the value of the hw_dst field in the ARP packet. |
224 | */ | 270 | */ |
225 | static u8 *batadv_arp_hw_dst(struct sk_buff *skb, int hdr_size) | 271 | static u8 *batadv_arp_hw_dst(struct sk_buff *skb, int hdr_size) |
226 | { | 272 | { |
227 | return batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN + 4; | 273 | return batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN + 4; |
228 | } | 274 | } |
229 | 275 | ||
230 | /** | 276 | /** |
231 | * batadv_arp_ip_dst() - extract the ip_dst field from an ARP packet | 277 | * batadv_arp_ip_dst() - extract the ip_dst field from an ARP packet |
232 | * @skb: ARP packet | 278 | * @skb: ARP packet |
233 | * @hdr_size: size of the possible header before the ARP packet | 279 | * @hdr_size: size of the possible header before the ARP packet |
234 | * | 280 | * |
235 | * Return: the value of the ip_dst field in the ARP packet. | 281 | * Return: the value of the ip_dst field in the ARP packet. |
236 | */ | 282 | */ |
237 | static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size) | 283 | static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size) |
238 | { | 284 | { |
239 | return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN * 2 + 4); | 285 | return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN * 2 + 4); |
240 | } | 286 | } |
241 | 287 | ||
242 | /** | 288 | /** |
243 | * batadv_hash_dat() - compute the hash value for an IP address | 289 | * batadv_hash_dat() - compute the hash value for an IP address |
244 | * @data: data to hash | 290 | * @data: data to hash |
245 | * @size: size of the hash table | 291 | * @size: size of the hash table |
246 | * | 292 | * |
247 | * Return: the selected index in the hash table for the given data. | 293 | * Return: the selected index in the hash table for the given data. |
248 | */ | 294 | */ |
249 | static u32 batadv_hash_dat(const void *data, u32 size) | 295 | static u32 batadv_hash_dat(const void *data, u32 size) |
250 | { | 296 | { |
251 | u32 hash = 0; | 297 | u32 hash = 0; |
252 | const struct batadv_dat_entry *dat = data; | 298 | const struct batadv_dat_entry *dat = data; |
253 | const unsigned char *key; | 299 | const unsigned char *key; |
254 | u32 i; | 300 | u32 i; |
255 | 301 | ||
256 | key = (const unsigned char *)&dat->ip; | 302 | key = (const unsigned char *)&dat->ip; |
257 | for (i = 0; i < sizeof(dat->ip); i++) { | 303 | for (i = 0; i < sizeof(dat->ip); i++) { |
258 | hash += key[i]; | 304 | hash += key[i]; |
259 | hash += (hash << 10); | 305 | hash += (hash << 10); |
260 | hash ^= (hash >> 6); | 306 | hash ^= (hash >> 6); |
261 | } | 307 | } |
262 | 308 | ||
263 | key = (const unsigned char *)&dat->vid; | 309 | key = (const unsigned char *)&dat->vid; |
264 | for (i = 0; i < sizeof(dat->vid); i++) { | 310 | for (i = 0; i < sizeof(dat->vid); i++) { |
265 | hash += key[i]; | 311 | hash += key[i]; |
266 | hash += (hash << 10); | 312 | hash += (hash << 10); |
267 | hash ^= (hash >> 6); | 313 | hash ^= (hash >> 6); |
268 | } | 314 | } |
269 | 315 | ||
270 | hash += (hash << 3); | 316 | hash += (hash << 3); |
271 | hash ^= (hash >> 11); | 317 | hash ^= (hash >> 11); |
272 | hash += (hash << 15); | 318 | hash += (hash << 15); |
273 | 319 | ||
274 | return hash % size; | 320 | return hash % size; |
275 | } | 321 | } |
276 | 322 | ||
277 | /** | 323 | /** |
278 | * batadv_dat_entry_hash_find() - look for a given dat_entry in the local hash | 324 | * batadv_dat_entry_hash_find() - look for a given dat_entry in the local hash |
279 | * table | 325 | * table |
280 | * @bat_priv: the bat priv with all the soft interface information | 326 | * @bat_priv: the bat priv with all the soft interface information |
281 | * @ip: search key | 327 | * @ip: search key |
282 | * @vid: VLAN identifier | 328 | * @vid: VLAN identifier |
283 | * | 329 | * |
284 | * Return: the dat_entry if found, NULL otherwise. | 330 | * Return: the dat_entry if found, NULL otherwise. |
285 | */ | 331 | */ |
286 | static struct batadv_dat_entry * | 332 | static struct batadv_dat_entry * |
287 | batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip, | 333 | batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip, |
288 | unsigned short vid) | 334 | unsigned short vid) |
289 | { | 335 | { |
290 | struct hlist_head *head; | 336 | struct hlist_head *head; |
291 | struct batadv_dat_entry to_find, *dat_entry, *dat_entry_tmp = NULL; | 337 | struct batadv_dat_entry to_find, *dat_entry, *dat_entry_tmp = NULL; |
292 | struct batadv_hashtable *hash = bat_priv->dat.hash; | 338 | struct batadv_hashtable *hash = bat_priv->dat.hash; |
293 | u32 index; | 339 | u32 index; |
294 | 340 | ||
295 | if (!hash) | 341 | if (!hash) |
296 | return NULL; | 342 | return NULL; |
297 | 343 | ||
298 | to_find.ip = ip; | 344 | to_find.ip = ip; |
299 | to_find.vid = vid; | 345 | to_find.vid = vid; |
300 | 346 | ||
301 | index = batadv_hash_dat(&to_find, hash->size); | 347 | index = batadv_hash_dat(&to_find, hash->size); |
302 | head = &hash->table[index]; | 348 | head = &hash->table[index]; |
303 | 349 | ||
304 | rcu_read_lock(); | 350 | rcu_read_lock(); |
305 | hlist_for_each_entry_rcu(dat_entry, head, hash_entry) { | 351 | hlist_for_each_entry_rcu(dat_entry, head, hash_entry) { |
306 | if (dat_entry->ip != ip) | 352 | if (dat_entry->ip != ip) |
307 | continue; | 353 | continue; |
308 | 354 | ||
309 | if (!kref_get_unless_zero(&dat_entry->refcount)) | 355 | if (!kref_get_unless_zero(&dat_entry->refcount)) |
310 | continue; | 356 | continue; |
311 | 357 | ||
312 | dat_entry_tmp = dat_entry; | 358 | dat_entry_tmp = dat_entry; |
313 | break; | 359 | break; |
314 | } | 360 | } |
315 | rcu_read_unlock(); | 361 | rcu_read_unlock(); |
316 | 362 | ||
317 | return dat_entry_tmp; | 363 | return dat_entry_tmp; |
318 | } | 364 | } |
319 | 365 | ||
320 | /** | 366 | /** |
321 | * batadv_dat_entry_add() - add a new dat entry or update it if already exists | 367 | * batadv_dat_entry_add() - add a new dat entry or update it if already exists |
322 | * @bat_priv: the bat priv with all the soft interface information | 368 | * @bat_priv: the bat priv with all the soft interface information |
323 | * @ip: ipv4 to add/edit | 369 | * @ip: ipv4 to add/edit |
324 | * @mac_addr: mac address to assign to the given ipv4 | 370 | * @mac_addr: mac address to assign to the given ipv4 |
325 | * @vid: VLAN identifier | 371 | * @vid: VLAN identifier |
326 | */ | 372 | */ |
327 | static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, | 373 | static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, |
328 | u8 *mac_addr, unsigned short vid) | 374 | u8 *mac_addr, unsigned short vid) |
329 | { | 375 | { |
330 | struct batadv_dat_entry *dat_entry; | 376 | struct batadv_dat_entry *dat_entry; |
331 | int hash_added; | 377 | int hash_added; |
332 | 378 | ||
333 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, vid); | 379 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, vid); |
334 | /* if this entry is already known, just update it */ | 380 | /* if this entry is already known, just update it */ |
335 | if (dat_entry) { | 381 | if (dat_entry) { |
336 | if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) | 382 | if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) |
337 | ether_addr_copy(dat_entry->mac_addr, mac_addr); | 383 | ether_addr_copy(dat_entry->mac_addr, mac_addr); |
338 | dat_entry->last_update = jiffies; | 384 | dat_entry->last_update = jiffies; |
339 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 385 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
340 | "Entry updated: %pI4 %pM (vid: %d)\n", | 386 | "Entry updated: %pI4 %pM (vid: %d)\n", |
341 | &dat_entry->ip, dat_entry->mac_addr, | 387 | &dat_entry->ip, dat_entry->mac_addr, |
342 | batadv_print_vid(vid)); | 388 | batadv_print_vid(vid)); |
343 | goto out; | 389 | goto out; |
344 | } | 390 | } |
345 | 391 | ||
346 | dat_entry = kmalloc(sizeof(*dat_entry), GFP_ATOMIC); | 392 | dat_entry = kmalloc(sizeof(*dat_entry), GFP_ATOMIC); |
347 | if (!dat_entry) | 393 | if (!dat_entry) |
348 | goto out; | 394 | goto out; |
349 | 395 | ||
350 | dat_entry->ip = ip; | 396 | dat_entry->ip = ip; |
351 | dat_entry->vid = vid; | 397 | dat_entry->vid = vid; |
352 | ether_addr_copy(dat_entry->mac_addr, mac_addr); | 398 | ether_addr_copy(dat_entry->mac_addr, mac_addr); |
353 | dat_entry->last_update = jiffies; | 399 | dat_entry->last_update = jiffies; |
354 | kref_init(&dat_entry->refcount); | 400 | kref_init(&dat_entry->refcount); |
355 | 401 | ||
356 | kref_get(&dat_entry->refcount); | 402 | kref_get(&dat_entry->refcount); |
357 | hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, | 403 | hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, |
358 | batadv_hash_dat, dat_entry, | 404 | batadv_hash_dat, dat_entry, |
359 | &dat_entry->hash_entry); | 405 | &dat_entry->hash_entry); |
360 | 406 | ||
361 | if (unlikely(hash_added != 0)) { | 407 | if (unlikely(hash_added != 0)) { |
362 | /* remove the reference for the hash */ | 408 | /* remove the reference for the hash */ |
363 | batadv_dat_entry_put(dat_entry); | 409 | batadv_dat_entry_put(dat_entry); |
364 | goto out; | 410 | goto out; |
365 | } | 411 | } |
366 | 412 | ||
367 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM (vid: %d)\n", | 413 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM (vid: %d)\n", |
368 | &dat_entry->ip, dat_entry->mac_addr, batadv_print_vid(vid)); | 414 | &dat_entry->ip, dat_entry->mac_addr, batadv_print_vid(vid)); |
369 | 415 | ||
370 | out: | 416 | out: |
371 | if (dat_entry) | 417 | if (dat_entry) |
372 | batadv_dat_entry_put(dat_entry); | 418 | batadv_dat_entry_put(dat_entry); |
373 | } | 419 | } |
374 | 420 | ||
375 | #ifdef CONFIG_BATMAN_ADV_DEBUG | 421 | #ifdef CONFIG_BATMAN_ADV_DEBUG |
376 | 422 | ||
377 | /** | 423 | /** |
378 | * batadv_dbg_arp() - print a debug message containing all the ARP packet | 424 | * batadv_dbg_arp() - print a debug message containing all the ARP packet |
379 | * details | 425 | * details |
380 | * @bat_priv: the bat priv with all the soft interface information | 426 | * @bat_priv: the bat priv with all the soft interface information |
381 | * @skb: ARP packet | 427 | * @skb: ARP packet |
382 | * @hdr_size: size of the possible header before the ARP packet | 428 | * @hdr_size: size of the possible header before the ARP packet |
383 | * @msg: message to print together with the debugging information | 429 | * @msg: message to print together with the debugging information |
384 | */ | 430 | */ |
385 | static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | 431 | static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, |
386 | int hdr_size, char *msg) | 432 | int hdr_size, char *msg) |
387 | { | 433 | { |
388 | struct batadv_unicast_4addr_packet *unicast_4addr_packet; | 434 | struct batadv_unicast_4addr_packet *unicast_4addr_packet; |
389 | struct batadv_bcast_packet *bcast_pkt; | 435 | struct batadv_bcast_packet *bcast_pkt; |
390 | u8 *orig_addr; | 436 | u8 *orig_addr; |
391 | __be32 ip_src, ip_dst; | 437 | __be32 ip_src, ip_dst; |
392 | 438 | ||
393 | if (msg) | 439 | if (msg) |
394 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "%s\n", msg); | 440 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "%s\n", msg); |
395 | 441 | ||
396 | ip_src = batadv_arp_ip_src(skb, hdr_size); | 442 | ip_src = batadv_arp_ip_src(skb, hdr_size); |
397 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | 443 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); |
398 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 444 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
399 | "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n", | 445 | "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n", |
400 | batadv_arp_hw_src(skb, hdr_size), &ip_src, | 446 | batadv_arp_hw_src(skb, hdr_size), &ip_src, |
401 | batadv_arp_hw_dst(skb, hdr_size), &ip_dst); | 447 | batadv_arp_hw_dst(skb, hdr_size), &ip_dst); |
402 | 448 | ||
403 | if (hdr_size < sizeof(struct batadv_unicast_packet)) | 449 | if (hdr_size < sizeof(struct batadv_unicast_packet)) |
404 | return; | 450 | return; |
405 | 451 | ||
406 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | 452 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; |
407 | 453 | ||
408 | switch (unicast_4addr_packet->u.packet_type) { | 454 | switch (unicast_4addr_packet->u.packet_type) { |
409 | case BATADV_UNICAST: | 455 | case BATADV_UNICAST: |
410 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 456 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
411 | "* encapsulated within a UNICAST packet\n"); | 457 | "* encapsulated within a UNICAST packet\n"); |
412 | break; | 458 | break; |
413 | case BATADV_UNICAST_4ADDR: | 459 | case BATADV_UNICAST_4ADDR: |
414 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 460 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
415 | "* encapsulated within a UNICAST_4ADDR packet (src: %pM)\n", | 461 | "* encapsulated within a UNICAST_4ADDR packet (src: %pM)\n", |
416 | unicast_4addr_packet->src); | 462 | unicast_4addr_packet->src); |
417 | switch (unicast_4addr_packet->subtype) { | 463 | switch (unicast_4addr_packet->subtype) { |
418 | case BATADV_P_DAT_DHT_PUT: | 464 | case BATADV_P_DAT_DHT_PUT: |
419 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_PUT\n"); | 465 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_PUT\n"); |
420 | break; | 466 | break; |
421 | case BATADV_P_DAT_DHT_GET: | 467 | case BATADV_P_DAT_DHT_GET: |
422 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_GET\n"); | 468 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_GET\n"); |
423 | break; | 469 | break; |
424 | case BATADV_P_DAT_CACHE_REPLY: | 470 | case BATADV_P_DAT_CACHE_REPLY: |
425 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 471 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
426 | "* type: DAT_CACHE_REPLY\n"); | 472 | "* type: DAT_CACHE_REPLY\n"); |
427 | break; | 473 | break; |
428 | case BATADV_P_DATA: | 474 | case BATADV_P_DATA: |
429 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DATA\n"); | 475 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DATA\n"); |
430 | break; | 476 | break; |
431 | default: | 477 | default: |
432 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n", | 478 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n", |
433 | unicast_4addr_packet->u.packet_type); | 479 | unicast_4addr_packet->u.packet_type); |
434 | } | 480 | } |
435 | break; | 481 | break; |
436 | case BATADV_BCAST: | 482 | case BATADV_BCAST: |
437 | bcast_pkt = (struct batadv_bcast_packet *)unicast_4addr_packet; | 483 | bcast_pkt = (struct batadv_bcast_packet *)unicast_4addr_packet; |
438 | orig_addr = bcast_pkt->orig; | 484 | orig_addr = bcast_pkt->orig; |
439 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 485 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
440 | "* encapsulated within a BCAST packet (src: %pM)\n", | 486 | "* encapsulated within a BCAST packet (src: %pM)\n", |
441 | orig_addr); | 487 | orig_addr); |
442 | break; | 488 | break; |
443 | default: | 489 | default: |
444 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 490 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
445 | "* encapsulated within an unknown packet type (0x%x)\n", | 491 | "* encapsulated within an unknown packet type (0x%x)\n", |
446 | unicast_4addr_packet->u.packet_type); | 492 | unicast_4addr_packet->u.packet_type); |
447 | } | 493 | } |
448 | } | 494 | } |
449 | 495 | ||
450 | #else | 496 | #else |
451 | 497 | ||
452 | static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | 498 | static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, |
453 | int hdr_size, char *msg) | 499 | int hdr_size, char *msg) |
454 | { | 500 | { |
455 | } | 501 | } |
456 | 502 | ||
457 | #endif /* CONFIG_BATMAN_ADV_DEBUG */ | 503 | #endif /* CONFIG_BATMAN_ADV_DEBUG */ |
458 | 504 | ||
459 | /** | 505 | /** |
460 | * batadv_is_orig_node_eligible() - check whether a node can be a DHT candidate | 506 | * batadv_is_orig_node_eligible() - check whether a node can be a DHT candidate |
461 | * @res: the array with the already selected candidates | 507 | * @res: the array with the already selected candidates |
462 | * @select: number of already selected candidates | 508 | * @select: number of already selected candidates |
463 | * @tmp_max: address of the currently evaluated node | 509 | * @tmp_max: address of the currently evaluated node |
464 | * @max: current round max address | 510 | * @max: current round max address |
465 | * @last_max: address of the last selected candidate | 511 | * @last_max: address of the last selected candidate |
466 | * @candidate: orig_node under evaluation | 512 | * @candidate: orig_node under evaluation |
467 | * @max_orig_node: last selected candidate | 513 | * @max_orig_node: last selected candidate |
468 | * | 514 | * |
469 | * Return: true if the node has been elected as next candidate or false | 515 | * Return: true if the node has been elected as next candidate or false |
470 | * otherwise. | 516 | * otherwise. |
471 | */ | 517 | */ |
472 | static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res, | 518 | static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res, |
473 | int select, batadv_dat_addr_t tmp_max, | 519 | int select, batadv_dat_addr_t tmp_max, |
474 | batadv_dat_addr_t max, | 520 | batadv_dat_addr_t max, |
475 | batadv_dat_addr_t last_max, | 521 | batadv_dat_addr_t last_max, |
476 | struct batadv_orig_node *candidate, | 522 | struct batadv_orig_node *candidate, |
477 | struct batadv_orig_node *max_orig_node) | 523 | struct batadv_orig_node *max_orig_node) |
478 | { | 524 | { |
479 | bool ret = false; | 525 | bool ret = false; |
480 | int j; | 526 | int j; |
481 | 527 | ||
482 | /* check if orig node candidate is running DAT */ | 528 | /* check if orig node candidate is running DAT */ |
483 | if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities)) | 529 | if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities)) |
484 | goto out; | 530 | goto out; |
485 | 531 | ||
486 | /* Check if this node has already been selected... */ | 532 | /* Check if this node has already been selected... */ |
487 | for (j = 0; j < select; j++) | 533 | for (j = 0; j < select; j++) |
488 | if (res[j].orig_node == candidate) | 534 | if (res[j].orig_node == candidate) |
489 | break; | 535 | break; |
490 | /* ..and possibly skip it */ | 536 | /* ..and possibly skip it */ |
491 | if (j < select) | 537 | if (j < select) |
492 | goto out; | 538 | goto out; |
493 | /* sanity check: has it already been selected? This should not happen */ | 539 | /* sanity check: has it already been selected? This should not happen */ |
494 | if (tmp_max > last_max) | 540 | if (tmp_max > last_max) |
495 | goto out; | 541 | goto out; |
496 | /* check if during this iteration an originator with a closer dht | 542 | /* check if during this iteration an originator with a closer dht |
497 | * address has already been found | 543 | * address has already been found |
498 | */ | 544 | */ |
499 | if (tmp_max < max) | 545 | if (tmp_max < max) |
500 | goto out; | 546 | goto out; |
501 | /* this is an hash collision with the temporary selected node. Choose | 547 | /* this is an hash collision with the temporary selected node. Choose |
502 | * the one with the lowest address | 548 | * the one with the lowest address |
503 | */ | 549 | */ |
504 | if (tmp_max == max && max_orig_node && | 550 | if (tmp_max == max && max_orig_node && |
505 | batadv_compare_eth(candidate->orig, max_orig_node->orig)) | 551 | batadv_compare_eth(candidate->orig, max_orig_node->orig)) |
506 | goto out; | 552 | goto out; |
507 | 553 | ||
508 | ret = true; | 554 | ret = true; |
509 | out: | 555 | out: |
510 | return ret; | 556 | return ret; |
511 | } | 557 | } |
512 | 558 | ||
513 | /** | 559 | /** |
514 | * batadv_choose_next_candidate() - select the next DHT candidate | 560 | * batadv_choose_next_candidate() - select the next DHT candidate |
515 | * @bat_priv: the bat priv with all the soft interface information | 561 | * @bat_priv: the bat priv with all the soft interface information |
516 | * @cands: candidates array | 562 | * @cands: candidates array |
517 | * @select: number of candidates already present in the array | 563 | * @select: number of candidates already present in the array |
518 | * @ip_key: key to look up in the DHT | 564 | * @ip_key: key to look up in the DHT |
519 | * @last_max: pointer where the address of the selected candidate will be saved | 565 | * @last_max: pointer where the address of the selected candidate will be saved |
520 | */ | 566 | */ |
521 | static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, | 567 | static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, |
522 | struct batadv_dat_candidate *cands, | 568 | struct batadv_dat_candidate *cands, |
523 | int select, batadv_dat_addr_t ip_key, | 569 | int select, batadv_dat_addr_t ip_key, |
524 | batadv_dat_addr_t *last_max) | 570 | batadv_dat_addr_t *last_max) |
525 | { | 571 | { |
526 | batadv_dat_addr_t max = 0; | 572 | batadv_dat_addr_t max = 0; |
527 | batadv_dat_addr_t tmp_max = 0; | 573 | batadv_dat_addr_t tmp_max = 0; |
528 | struct batadv_orig_node *orig_node, *max_orig_node = NULL; | 574 | struct batadv_orig_node *orig_node, *max_orig_node = NULL; |
529 | struct batadv_hashtable *hash = bat_priv->orig_hash; | 575 | struct batadv_hashtable *hash = bat_priv->orig_hash; |
530 | struct hlist_head *head; | 576 | struct hlist_head *head; |
531 | int i; | 577 | int i; |
532 | 578 | ||
533 | /* if no node is eligible as candidate, leave the candidate type as | 579 | /* if no node is eligible as candidate, leave the candidate type as |
534 | * NOT_FOUND | 580 | * NOT_FOUND |
535 | */ | 581 | */ |
536 | cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND; | 582 | cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND; |
537 | 583 | ||
538 | /* iterate over the originator list and find the node with the closest | 584 | /* iterate over the originator list and find the node with the closest |
539 | * dat_address which has not been selected yet | 585 | * dat_address which has not been selected yet |
540 | */ | 586 | */ |
541 | for (i = 0; i < hash->size; i++) { | 587 | for (i = 0; i < hash->size; i++) { |
542 | head = &hash->table[i]; | 588 | head = &hash->table[i]; |
543 | 589 | ||
544 | rcu_read_lock(); | 590 | rcu_read_lock(); |
545 | hlist_for_each_entry_rcu(orig_node, head, hash_entry) { | 591 | hlist_for_each_entry_rcu(orig_node, head, hash_entry) { |
546 | /* the dht space is a ring using unsigned addresses */ | 592 | /* the dht space is a ring using unsigned addresses */ |
547 | tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr + | 593 | tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr + |
548 | ip_key; | 594 | ip_key; |
549 | 595 | ||
550 | if (!batadv_is_orig_node_eligible(cands, select, | 596 | if (!batadv_is_orig_node_eligible(cands, select, |
551 | tmp_max, max, | 597 | tmp_max, max, |
552 | *last_max, orig_node, | 598 | *last_max, orig_node, |
553 | max_orig_node)) | 599 | max_orig_node)) |
554 | continue; | 600 | continue; |
555 | 601 | ||
556 | if (!kref_get_unless_zero(&orig_node->refcount)) | 602 | if (!kref_get_unless_zero(&orig_node->refcount)) |
557 | continue; | 603 | continue; |
558 | 604 | ||
559 | max = tmp_max; | 605 | max = tmp_max; |
560 | if (max_orig_node) | 606 | if (max_orig_node) |
561 | batadv_orig_node_put(max_orig_node); | 607 | batadv_orig_node_put(max_orig_node); |
562 | max_orig_node = orig_node; | 608 | max_orig_node = orig_node; |
563 | } | 609 | } |
564 | rcu_read_unlock(); | 610 | rcu_read_unlock(); |
565 | } | 611 | } |
566 | if (max_orig_node) { | 612 | if (max_orig_node) { |
567 | cands[select].type = BATADV_DAT_CANDIDATE_ORIG; | 613 | cands[select].type = BATADV_DAT_CANDIDATE_ORIG; |
568 | cands[select].orig_node = max_orig_node; | 614 | cands[select].orig_node = max_orig_node; |
569 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 615 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
570 | "dat_select_candidates() %d: selected %pM addr=%u dist=%u\n", | 616 | "dat_select_candidates() %d: selected %pM addr=%u dist=%u\n", |
571 | select, max_orig_node->orig, max_orig_node->dat_addr, | 617 | select, max_orig_node->orig, max_orig_node->dat_addr, |
572 | max); | 618 | max); |
573 | } | 619 | } |
574 | *last_max = max; | 620 | *last_max = max; |
575 | } | 621 | } |
576 | 622 | ||
577 | /** | 623 | /** |
578 | * batadv_dat_select_candidates() - select the nodes which the DHT message has | 624 | * batadv_dat_select_candidates() - select the nodes which the DHT message has |
579 | * to be sent to | 625 | * to be sent to |
580 | * @bat_priv: the bat priv with all the soft interface information | 626 | * @bat_priv: the bat priv with all the soft interface information |
581 | * @ip_dst: ipv4 to look up in the DHT | 627 | * @ip_dst: ipv4 to look up in the DHT |
582 | * @vid: VLAN identifier | 628 | * @vid: VLAN identifier |
583 | * | 629 | * |
584 | * An originator O is selected if and only if its DHT_ID value is one of three | 630 | * An originator O is selected if and only if its DHT_ID value is one of three |
585 | * closest values (from the LEFT, with wrap around if needed) then the hash | 631 | * closest values (from the LEFT, with wrap around if needed) then the hash |
586 | * value of the key. ip_dst is the key. | 632 | * value of the key. ip_dst is the key. |
587 | * | 633 | * |
588 | * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. | 634 | * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. |
589 | */ | 635 | */ |
590 | static struct batadv_dat_candidate * | 636 | static struct batadv_dat_candidate * |
591 | batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, | 637 | batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, |
592 | unsigned short vid) | 638 | unsigned short vid) |
593 | { | 639 | { |
594 | int select; | 640 | int select; |
595 | batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; | 641 | batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; |
596 | struct batadv_dat_candidate *res; | 642 | struct batadv_dat_candidate *res; |
597 | struct batadv_dat_entry dat; | 643 | struct batadv_dat_entry dat; |
598 | 644 | ||
599 | if (!bat_priv->orig_hash) | 645 | if (!bat_priv->orig_hash) |
600 | return NULL; | 646 | return NULL; |
601 | 647 | ||
602 | res = kmalloc_array(BATADV_DAT_CANDIDATES_NUM, sizeof(*res), | 648 | res = kmalloc_array(BATADV_DAT_CANDIDATES_NUM, sizeof(*res), |
603 | GFP_ATOMIC); | 649 | GFP_ATOMIC); |
604 | if (!res) | 650 | if (!res) |
605 | return NULL; | 651 | return NULL; |
606 | 652 | ||
607 | dat.ip = ip_dst; | 653 | dat.ip = ip_dst; |
608 | dat.vid = vid; | 654 | dat.vid = vid; |
609 | ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, | 655 | ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, |
610 | BATADV_DAT_ADDR_MAX); | 656 | BATADV_DAT_ADDR_MAX); |
611 | 657 | ||
612 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 658 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
613 | "%s(): IP=%pI4 hash(IP)=%u\n", __func__, &ip_dst, | 659 | "%s(): IP=%pI4 hash(IP)=%u\n", __func__, &ip_dst, |
614 | ip_key); | 660 | ip_key); |
615 | 661 | ||
616 | for (select = 0; select < BATADV_DAT_CANDIDATES_NUM; select++) | 662 | for (select = 0; select < BATADV_DAT_CANDIDATES_NUM; select++) |
617 | batadv_choose_next_candidate(bat_priv, res, select, ip_key, | 663 | batadv_choose_next_candidate(bat_priv, res, select, ip_key, |
618 | &last_max); | 664 | &last_max); |
619 | 665 | ||
620 | return res; | 666 | return res; |
621 | } | 667 | } |
622 | 668 | ||
623 | /** | 669 | /** |
624 | * batadv_dat_send_data() - send a payload to the selected candidates | 670 | * batadv_dat_send_data() - send a payload to the selected candidates |
625 | * @bat_priv: the bat priv with all the soft interface information | 671 | * @bat_priv: the bat priv with all the soft interface information |
626 | * @skb: payload to send | 672 | * @skb: payload to send |
627 | * @ip: the DHT key | 673 | * @ip: the DHT key |
628 | * @vid: VLAN identifier | 674 | * @vid: VLAN identifier |
629 | * @packet_subtype: unicast4addr packet subtype to use | 675 | * @packet_subtype: unicast4addr packet subtype to use |
630 | * | 676 | * |
631 | * This function copies the skb with pskb_copy() and is sent as unicast packet | 677 | * This function copies the skb with pskb_copy() and is sent as unicast packet |
632 | * to each of the selected candidates. | 678 | * to each of the selected candidates. |
633 | * | 679 | * |
634 | * Return: true if the packet is sent to at least one candidate, false | 680 | * Return: true if the packet is sent to at least one candidate, false |
635 | * otherwise. | 681 | * otherwise. |
636 | */ | 682 | */ |
637 | static bool batadv_dat_send_data(struct batadv_priv *bat_priv, | 683 | static bool batadv_dat_send_data(struct batadv_priv *bat_priv, |
638 | struct sk_buff *skb, __be32 ip, | 684 | struct sk_buff *skb, __be32 ip, |
639 | unsigned short vid, int packet_subtype) | 685 | unsigned short vid, int packet_subtype) |
640 | { | 686 | { |
641 | int i; | 687 | int i; |
642 | bool ret = false; | 688 | bool ret = false; |
643 | int send_status; | 689 | int send_status; |
644 | struct batadv_neigh_node *neigh_node = NULL; | 690 | struct batadv_neigh_node *neigh_node = NULL; |
645 | struct sk_buff *tmp_skb; | 691 | struct sk_buff *tmp_skb; |
646 | struct batadv_dat_candidate *cand; | 692 | struct batadv_dat_candidate *cand; |
647 | 693 | ||
648 | cand = batadv_dat_select_candidates(bat_priv, ip, vid); | 694 | cand = batadv_dat_select_candidates(bat_priv, ip, vid); |
649 | if (!cand) | 695 | if (!cand) |
650 | goto out; | 696 | goto out; |
651 | 697 | ||
652 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "DHT_SEND for %pI4\n", &ip); | 698 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "DHT_SEND for %pI4\n", &ip); |
653 | 699 | ||
654 | for (i = 0; i < BATADV_DAT_CANDIDATES_NUM; i++) { | 700 | for (i = 0; i < BATADV_DAT_CANDIDATES_NUM; i++) { |
655 | if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND) | 701 | if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND) |
656 | continue; | 702 | continue; |
657 | 703 | ||
658 | neigh_node = batadv_orig_router_get(cand[i].orig_node, | 704 | neigh_node = batadv_orig_router_get(cand[i].orig_node, |
659 | BATADV_IF_DEFAULT); | 705 | BATADV_IF_DEFAULT); |
660 | if (!neigh_node) | 706 | if (!neigh_node) |
661 | goto free_orig; | 707 | goto free_orig; |
662 | 708 | ||
663 | tmp_skb = pskb_copy_for_clone(skb, GFP_ATOMIC); | 709 | tmp_skb = pskb_copy_for_clone(skb, GFP_ATOMIC); |
664 | if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb, | 710 | if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb, |
665 | cand[i].orig_node, | 711 | cand[i].orig_node, |
666 | packet_subtype)) { | 712 | packet_subtype)) { |
667 | kfree_skb(tmp_skb); | 713 | kfree_skb(tmp_skb); |
668 | goto free_neigh; | 714 | goto free_neigh; |
669 | } | 715 | } |
670 | 716 | ||
671 | send_status = batadv_send_unicast_skb(tmp_skb, neigh_node); | 717 | send_status = batadv_send_unicast_skb(tmp_skb, neigh_node); |
672 | if (send_status == NET_XMIT_SUCCESS) { | 718 | if (send_status == NET_XMIT_SUCCESS) { |
673 | /* count the sent packet */ | 719 | /* count the sent packet */ |
674 | switch (packet_subtype) { | 720 | switch (packet_subtype) { |
675 | case BATADV_P_DAT_DHT_GET: | 721 | case BATADV_P_DAT_DHT_GET: |
676 | batadv_inc_counter(bat_priv, | 722 | batadv_inc_counter(bat_priv, |
677 | BATADV_CNT_DAT_GET_TX); | 723 | BATADV_CNT_DAT_GET_TX); |
678 | break; | 724 | break; |
679 | case BATADV_P_DAT_DHT_PUT: | 725 | case BATADV_P_DAT_DHT_PUT: |
680 | batadv_inc_counter(bat_priv, | 726 | batadv_inc_counter(bat_priv, |
681 | BATADV_CNT_DAT_PUT_TX); | 727 | BATADV_CNT_DAT_PUT_TX); |
682 | break; | 728 | break; |
683 | } | 729 | } |
684 | 730 | ||
685 | /* packet sent to a candidate: return true */ | 731 | /* packet sent to a candidate: return true */ |
686 | ret = true; | 732 | ret = true; |
687 | } | 733 | } |
688 | free_neigh: | 734 | free_neigh: |
689 | batadv_neigh_node_put(neigh_node); | 735 | batadv_neigh_node_put(neigh_node); |
690 | free_orig: | 736 | free_orig: |
691 | batadv_orig_node_put(cand[i].orig_node); | 737 | batadv_orig_node_put(cand[i].orig_node); |
692 | } | 738 | } |
693 | 739 | ||
694 | out: | 740 | out: |
695 | kfree(cand); | 741 | kfree(cand); |
696 | return ret; | 742 | return ret; |
697 | } | 743 | } |
698 | 744 | ||
699 | /** | 745 | /** |
700 | * batadv_dat_tvlv_container_update() - update the dat tvlv container after dat | 746 | * batadv_dat_tvlv_container_update() - update the dat tvlv container after dat |
701 | * setting change | 747 | * setting change |
702 | * @bat_priv: the bat priv with all the soft interface information | 748 | * @bat_priv: the bat priv with all the soft interface information |
703 | */ | 749 | */ |
704 | static void batadv_dat_tvlv_container_update(struct batadv_priv *bat_priv) | 750 | static void batadv_dat_tvlv_container_update(struct batadv_priv *bat_priv) |
705 | { | 751 | { |
706 | char dat_mode; | 752 | char dat_mode; |
707 | 753 | ||
708 | dat_mode = atomic_read(&bat_priv->distributed_arp_table); | 754 | dat_mode = atomic_read(&bat_priv->distributed_arp_table); |
709 | 755 | ||
710 | switch (dat_mode) { | 756 | switch (dat_mode) { |
711 | case 0: | 757 | case 0: |
712 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1); | 758 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1); |
713 | break; | 759 | break; |
714 | case 1: | 760 | case 1: |
715 | batadv_tvlv_container_register(bat_priv, BATADV_TVLV_DAT, 1, | 761 | batadv_tvlv_container_register(bat_priv, BATADV_TVLV_DAT, 1, |
716 | NULL, 0); | 762 | NULL, 0); |
717 | break; | 763 | break; |
718 | } | 764 | } |
719 | } | 765 | } |
720 | 766 | ||
721 | /** | 767 | /** |
722 | * batadv_dat_status_update() - update the dat tvlv container after dat | 768 | * batadv_dat_status_update() - update the dat tvlv container after dat |
723 | * setting change | 769 | * setting change |
724 | * @net_dev: the soft interface net device | 770 | * @net_dev: the soft interface net device |
725 | */ | 771 | */ |
726 | void batadv_dat_status_update(struct net_device *net_dev) | 772 | void batadv_dat_status_update(struct net_device *net_dev) |
727 | { | 773 | { |
728 | struct batadv_priv *bat_priv = netdev_priv(net_dev); | 774 | struct batadv_priv *bat_priv = netdev_priv(net_dev); |
729 | 775 | ||
730 | batadv_dat_tvlv_container_update(bat_priv); | 776 | batadv_dat_tvlv_container_update(bat_priv); |
731 | } | 777 | } |
732 | 778 | ||
733 | /** | 779 | /** |
734 | * batadv_dat_tvlv_ogm_handler_v1() - process incoming dat tvlv container | 780 | * batadv_dat_tvlv_ogm_handler_v1() - process incoming dat tvlv container |
735 | * @bat_priv: the bat priv with all the soft interface information | 781 | * @bat_priv: the bat priv with all the soft interface information |
736 | * @orig: the orig_node of the ogm | 782 | * @orig: the orig_node of the ogm |
737 | * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) | 783 | * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) |
738 | * @tvlv_value: tvlv buffer containing the gateway data | 784 | * @tvlv_value: tvlv buffer containing the gateway data |
739 | * @tvlv_value_len: tvlv buffer length | 785 | * @tvlv_value_len: tvlv buffer length |
740 | */ | 786 | */ |
741 | static void batadv_dat_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, | 787 | static void batadv_dat_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, |
742 | struct batadv_orig_node *orig, | 788 | struct batadv_orig_node *orig, |
743 | u8 flags, | 789 | u8 flags, |
744 | void *tvlv_value, u16 tvlv_value_len) | 790 | void *tvlv_value, u16 tvlv_value_len) |
745 | { | 791 | { |
746 | if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) | 792 | if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) |
747 | clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); | 793 | clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); |
748 | else | 794 | else |
749 | set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); | 795 | set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); |
750 | } | 796 | } |
751 | 797 | ||
752 | /** | 798 | /** |
753 | * batadv_dat_hash_free() - free the local DAT hash table | 799 | * batadv_dat_hash_free() - free the local DAT hash table |
754 | * @bat_priv: the bat priv with all the soft interface information | 800 | * @bat_priv: the bat priv with all the soft interface information |
755 | */ | 801 | */ |
756 | static void batadv_dat_hash_free(struct batadv_priv *bat_priv) | 802 | static void batadv_dat_hash_free(struct batadv_priv *bat_priv) |
757 | { | 803 | { |
758 | if (!bat_priv->dat.hash) | 804 | if (!bat_priv->dat.hash) |
759 | return; | 805 | return; |
760 | 806 | ||
761 | __batadv_dat_purge(bat_priv, NULL); | 807 | __batadv_dat_purge(bat_priv, NULL); |
762 | 808 | ||
763 | batadv_hash_destroy(bat_priv->dat.hash); | 809 | batadv_hash_destroy(bat_priv->dat.hash); |
764 | 810 | ||
765 | bat_priv->dat.hash = NULL; | 811 | bat_priv->dat.hash = NULL; |
766 | } | 812 | } |
767 | 813 | ||
768 | /** | 814 | /** |
769 | * batadv_dat_init() - initialise the DAT internals | 815 | * batadv_dat_init() - initialise the DAT internals |
770 | * @bat_priv: the bat priv with all the soft interface information | 816 | * @bat_priv: the bat priv with all the soft interface information |
771 | * | 817 | * |
772 | * Return: 0 in case of success, a negative error code otherwise | 818 | * Return: 0 in case of success, a negative error code otherwise |
773 | */ | 819 | */ |
774 | int batadv_dat_init(struct batadv_priv *bat_priv) | 820 | int batadv_dat_init(struct batadv_priv *bat_priv) |
775 | { | 821 | { |
776 | if (bat_priv->dat.hash) | 822 | if (bat_priv->dat.hash) |
777 | return 0; | 823 | return 0; |
778 | 824 | ||
779 | bat_priv->dat.hash = batadv_hash_new(1024); | 825 | bat_priv->dat.hash = batadv_hash_new(1024); |
780 | 826 | ||
781 | if (!bat_priv->dat.hash) | 827 | if (!bat_priv->dat.hash) |
782 | return -ENOMEM; | 828 | return -ENOMEM; |
783 | 829 | ||
784 | batadv_dat_start_timer(bat_priv); | 830 | batadv_dat_start_timer(bat_priv); |
785 | 831 | ||
786 | batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1, | 832 | batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1, |
787 | NULL, BATADV_TVLV_DAT, 1, | 833 | NULL, BATADV_TVLV_DAT, 1, |
788 | BATADV_TVLV_HANDLER_OGM_CIFNOTFND); | 834 | BATADV_TVLV_HANDLER_OGM_CIFNOTFND); |
789 | batadv_dat_tvlv_container_update(bat_priv); | 835 | batadv_dat_tvlv_container_update(bat_priv); |
790 | return 0; | 836 | return 0; |
791 | } | 837 | } |
792 | 838 | ||
793 | /** | 839 | /** |
794 | * batadv_dat_free() - free the DAT internals | 840 | * batadv_dat_free() - free the DAT internals |
795 | * @bat_priv: the bat priv with all the soft interface information | 841 | * @bat_priv: the bat priv with all the soft interface information |
796 | */ | 842 | */ |
797 | void batadv_dat_free(struct batadv_priv *bat_priv) | 843 | void batadv_dat_free(struct batadv_priv *bat_priv) |
798 | { | 844 | { |
799 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1); | 845 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1); |
800 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_DAT, 1); | 846 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_DAT, 1); |
801 | 847 | ||
802 | cancel_delayed_work_sync(&bat_priv->dat.work); | 848 | cancel_delayed_work_sync(&bat_priv->dat.work); |
803 | 849 | ||
804 | batadv_dat_hash_free(bat_priv); | 850 | batadv_dat_hash_free(bat_priv); |
805 | } | 851 | } |
806 | 852 | ||
807 | #ifdef CONFIG_BATMAN_ADV_DEBUGFS | 853 | #ifdef CONFIG_BATMAN_ADV_DEBUGFS |
808 | /** | 854 | /** |
809 | * batadv_dat_cache_seq_print_text() - print the local DAT hash table | 855 | * batadv_dat_cache_seq_print_text() - print the local DAT hash table |
810 | * @seq: seq file to print on | 856 | * @seq: seq file to print on |
811 | * @offset: not used | 857 | * @offset: not used |
812 | * | 858 | * |
813 | * Return: always 0 | 859 | * Return: always 0 |
814 | */ | 860 | */ |
815 | int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset) | 861 | int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset) |
816 | { | 862 | { |
817 | struct net_device *net_dev = (struct net_device *)seq->private; | 863 | struct net_device *net_dev = (struct net_device *)seq->private; |
818 | struct batadv_priv *bat_priv = netdev_priv(net_dev); | 864 | struct batadv_priv *bat_priv = netdev_priv(net_dev); |
819 | struct batadv_hashtable *hash = bat_priv->dat.hash; | 865 | struct batadv_hashtable *hash = bat_priv->dat.hash; |
820 | struct batadv_dat_entry *dat_entry; | 866 | struct batadv_dat_entry *dat_entry; |
821 | struct batadv_hard_iface *primary_if; | 867 | struct batadv_hard_iface *primary_if; |
822 | struct hlist_head *head; | 868 | struct hlist_head *head; |
823 | unsigned long last_seen_jiffies; | 869 | unsigned long last_seen_jiffies; |
824 | int last_seen_msecs, last_seen_secs, last_seen_mins; | 870 | int last_seen_msecs, last_seen_secs, last_seen_mins; |
825 | u32 i; | 871 | u32 i; |
826 | 872 | ||
827 | primary_if = batadv_seq_print_text_primary_if_get(seq); | 873 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
828 | if (!primary_if) | 874 | if (!primary_if) |
829 | goto out; | 875 | goto out; |
830 | 876 | ||
831 | seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name); | 877 | seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name); |
832 | seq_puts(seq, | 878 | seq_puts(seq, |
833 | " IPv4 MAC VID last-seen\n"); | 879 | " IPv4 MAC VID last-seen\n"); |
834 | 880 | ||
835 | for (i = 0; i < hash->size; i++) { | 881 | for (i = 0; i < hash->size; i++) { |
836 | head = &hash->table[i]; | 882 | head = &hash->table[i]; |
837 | 883 | ||
838 | rcu_read_lock(); | 884 | rcu_read_lock(); |
839 | hlist_for_each_entry_rcu(dat_entry, head, hash_entry) { | 885 | hlist_for_each_entry_rcu(dat_entry, head, hash_entry) { |
840 | last_seen_jiffies = jiffies - dat_entry->last_update; | 886 | last_seen_jiffies = jiffies - dat_entry->last_update; |
841 | last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); | 887 | last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); |
842 | last_seen_mins = last_seen_msecs / 60000; | 888 | last_seen_mins = last_seen_msecs / 60000; |
843 | last_seen_msecs = last_seen_msecs % 60000; | 889 | last_seen_msecs = last_seen_msecs % 60000; |
844 | last_seen_secs = last_seen_msecs / 1000; | 890 | last_seen_secs = last_seen_msecs / 1000; |
845 | 891 | ||
846 | seq_printf(seq, " * %15pI4 %pM %4i %6i:%02i\n", | 892 | seq_printf(seq, " * %15pI4 %pM %4i %6i:%02i\n", |
847 | &dat_entry->ip, dat_entry->mac_addr, | 893 | &dat_entry->ip, dat_entry->mac_addr, |
848 | batadv_print_vid(dat_entry->vid), | 894 | batadv_print_vid(dat_entry->vid), |
849 | last_seen_mins, last_seen_secs); | 895 | last_seen_mins, last_seen_secs); |
850 | } | 896 | } |
851 | rcu_read_unlock(); | 897 | rcu_read_unlock(); |
852 | } | 898 | } |
853 | 899 | ||
854 | out: | 900 | out: |
855 | if (primary_if) | 901 | if (primary_if) |
856 | batadv_hardif_put(primary_if); | 902 | batadv_hardif_put(primary_if); |
857 | return 0; | 903 | return 0; |
858 | } | 904 | } |
859 | #endif | 905 | #endif |
860 | 906 | ||
861 | /** | 907 | /** |
862 | * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a | 908 | * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a |
863 | * netlink socket | 909 | * netlink socket |
864 | * @msg: buffer for the message | 910 | * @msg: buffer for the message |
865 | * @portid: netlink port | 911 | * @portid: netlink port |
866 | * @cb: Control block containing additional options | 912 | * @cb: Control block containing additional options |
867 | * @dat_entry: entry to dump | 913 | * @dat_entry: entry to dump |
868 | * | 914 | * |
869 | * Return: 0 or error code. | 915 | * Return: 0 or error code. |
870 | */ | 916 | */ |
871 | static int | 917 | static int |
872 | batadv_dat_cache_dump_entry(struct sk_buff *msg, u32 portid, | 918 | batadv_dat_cache_dump_entry(struct sk_buff *msg, u32 portid, |
873 | struct netlink_callback *cb, | 919 | struct netlink_callback *cb, |
874 | struct batadv_dat_entry *dat_entry) | 920 | struct batadv_dat_entry *dat_entry) |
875 | { | 921 | { |
876 | int msecs; | 922 | int msecs; |
877 | void *hdr; | 923 | void *hdr; |
878 | 924 | ||
879 | hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, | 925 | hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, |
880 | &batadv_netlink_family, NLM_F_MULTI, | 926 | &batadv_netlink_family, NLM_F_MULTI, |
881 | BATADV_CMD_GET_DAT_CACHE); | 927 | BATADV_CMD_GET_DAT_CACHE); |
882 | if (!hdr) | 928 | if (!hdr) |
883 | return -ENOBUFS; | 929 | return -ENOBUFS; |
884 | 930 | ||
885 | genl_dump_check_consistent(cb, hdr); | 931 | genl_dump_check_consistent(cb, hdr); |
886 | 932 | ||
887 | msecs = jiffies_to_msecs(jiffies - dat_entry->last_update); | 933 | msecs = jiffies_to_msecs(jiffies - dat_entry->last_update); |
888 | 934 | ||
889 | if (nla_put_in_addr(msg, BATADV_ATTR_DAT_CACHE_IP4ADDRESS, | 935 | if (nla_put_in_addr(msg, BATADV_ATTR_DAT_CACHE_IP4ADDRESS, |
890 | dat_entry->ip) || | 936 | dat_entry->ip) || |
891 | nla_put(msg, BATADV_ATTR_DAT_CACHE_HWADDRESS, ETH_ALEN, | 937 | nla_put(msg, BATADV_ATTR_DAT_CACHE_HWADDRESS, ETH_ALEN, |
892 | dat_entry->mac_addr) || | 938 | dat_entry->mac_addr) || |
893 | nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) || | 939 | nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) || |
894 | nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) { | 940 | nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) { |
895 | genlmsg_cancel(msg, hdr); | 941 | genlmsg_cancel(msg, hdr); |
896 | return -EMSGSIZE; | 942 | return -EMSGSIZE; |
897 | } | 943 | } |
898 | 944 | ||
899 | genlmsg_end(msg, hdr); | 945 | genlmsg_end(msg, hdr); |
900 | return 0; | 946 | return 0; |
901 | } | 947 | } |
902 | 948 | ||
903 | /** | 949 | /** |
904 | * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to | 950 | * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to |
905 | * a netlink socket | 951 | * a netlink socket |
906 | * @msg: buffer for the message | 952 | * @msg: buffer for the message |
907 | * @portid: netlink port | 953 | * @portid: netlink port |
908 | * @cb: Control block containing additional options | 954 | * @cb: Control block containing additional options |
909 | * @hash: hash to dump | 955 | * @hash: hash to dump |
910 | * @bucket: bucket index to dump | 956 | * @bucket: bucket index to dump |
911 | * @idx_skip: How many entries to skip | 957 | * @idx_skip: How many entries to skip |
912 | * | 958 | * |
913 | * Return: 0 or error code. | 959 | * Return: 0 or error code. |
914 | */ | 960 | */ |
915 | static int | 961 | static int |
916 | batadv_dat_cache_dump_bucket(struct sk_buff *msg, u32 portid, | 962 | batadv_dat_cache_dump_bucket(struct sk_buff *msg, u32 portid, |
917 | struct netlink_callback *cb, | 963 | struct netlink_callback *cb, |
918 | struct batadv_hashtable *hash, unsigned int bucket, | 964 | struct batadv_hashtable *hash, unsigned int bucket, |
919 | int *idx_skip) | 965 | int *idx_skip) |
920 | { | 966 | { |
921 | struct batadv_dat_entry *dat_entry; | 967 | struct batadv_dat_entry *dat_entry; |
922 | int idx = 0; | 968 | int idx = 0; |
923 | 969 | ||
924 | spin_lock_bh(&hash->list_locks[bucket]); | 970 | spin_lock_bh(&hash->list_locks[bucket]); |
925 | cb->seq = atomic_read(&hash->generation) << 1 | 1; | 971 | cb->seq = atomic_read(&hash->generation) << 1 | 1; |
926 | 972 | ||
927 | hlist_for_each_entry(dat_entry, &hash->table[bucket], hash_entry) { | 973 | hlist_for_each_entry(dat_entry, &hash->table[bucket], hash_entry) { |
928 | if (idx < *idx_skip) | 974 | if (idx < *idx_skip) |
929 | goto skip; | 975 | goto skip; |
930 | 976 | ||
931 | if (batadv_dat_cache_dump_entry(msg, portid, cb, dat_entry)) { | 977 | if (batadv_dat_cache_dump_entry(msg, portid, cb, dat_entry)) { |
932 | spin_unlock_bh(&hash->list_locks[bucket]); | 978 | spin_unlock_bh(&hash->list_locks[bucket]); |
933 | *idx_skip = idx; | 979 | *idx_skip = idx; |
934 | 980 | ||
935 | return -EMSGSIZE; | 981 | return -EMSGSIZE; |
936 | } | 982 | } |
937 | 983 | ||
938 | skip: | 984 | skip: |
939 | idx++; | 985 | idx++; |
940 | } | 986 | } |
941 | spin_unlock_bh(&hash->list_locks[bucket]); | 987 | spin_unlock_bh(&hash->list_locks[bucket]); |
942 | 988 | ||
943 | return 0; | 989 | return 0; |
944 | } | 990 | } |
945 | 991 | ||
946 | /** | 992 | /** |
947 | * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket | 993 | * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket |
948 | * @msg: buffer for the message | 994 | * @msg: buffer for the message |
949 | * @cb: callback structure containing arguments | 995 | * @cb: callback structure containing arguments |
950 | * | 996 | * |
951 | * Return: message length. | 997 | * Return: message length. |
952 | */ | 998 | */ |
953 | int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb) | 999 | int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb) |
954 | { | 1000 | { |
955 | struct batadv_hard_iface *primary_if = NULL; | 1001 | struct batadv_hard_iface *primary_if = NULL; |
956 | int portid = NETLINK_CB(cb->skb).portid; | 1002 | int portid = NETLINK_CB(cb->skb).portid; |
957 | struct net *net = sock_net(cb->skb->sk); | 1003 | struct net *net = sock_net(cb->skb->sk); |
958 | struct net_device *soft_iface; | 1004 | struct net_device *soft_iface; |
959 | struct batadv_hashtable *hash; | 1005 | struct batadv_hashtable *hash; |
960 | struct batadv_priv *bat_priv; | 1006 | struct batadv_priv *bat_priv; |
961 | int bucket = cb->args[0]; | 1007 | int bucket = cb->args[0]; |
962 | int idx = cb->args[1]; | 1008 | int idx = cb->args[1]; |
963 | int ifindex; | 1009 | int ifindex; |
964 | int ret = 0; | 1010 | int ret = 0; |
965 | 1011 | ||
966 | ifindex = batadv_netlink_get_ifindex(cb->nlh, | 1012 | ifindex = batadv_netlink_get_ifindex(cb->nlh, |
967 | BATADV_ATTR_MESH_IFINDEX); | 1013 | BATADV_ATTR_MESH_IFINDEX); |
968 | if (!ifindex) | 1014 | if (!ifindex) |
969 | return -EINVAL; | 1015 | return -EINVAL; |
970 | 1016 | ||
971 | soft_iface = dev_get_by_index(net, ifindex); | 1017 | soft_iface = dev_get_by_index(net, ifindex); |
972 | if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { | 1018 | if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { |
973 | ret = -ENODEV; | 1019 | ret = -ENODEV; |
974 | goto out; | 1020 | goto out; |
975 | } | 1021 | } |
976 | 1022 | ||
977 | bat_priv = netdev_priv(soft_iface); | 1023 | bat_priv = netdev_priv(soft_iface); |
978 | hash = bat_priv->dat.hash; | 1024 | hash = bat_priv->dat.hash; |
979 | 1025 | ||
980 | primary_if = batadv_primary_if_get_selected(bat_priv); | 1026 | primary_if = batadv_primary_if_get_selected(bat_priv); |
981 | if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { | 1027 | if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { |
982 | ret = -ENOENT; | 1028 | ret = -ENOENT; |
983 | goto out; | 1029 | goto out; |
984 | } | 1030 | } |
985 | 1031 | ||
986 | while (bucket < hash->size) { | 1032 | while (bucket < hash->size) { |
987 | if (batadv_dat_cache_dump_bucket(msg, portid, cb, hash, bucket, | 1033 | if (batadv_dat_cache_dump_bucket(msg, portid, cb, hash, bucket, |
988 | &idx)) | 1034 | &idx)) |
989 | break; | 1035 | break; |
990 | 1036 | ||
991 | bucket++; | 1037 | bucket++; |
992 | idx = 0; | 1038 | idx = 0; |
993 | } | 1039 | } |
994 | 1040 | ||
995 | cb->args[0] = bucket; | 1041 | cb->args[0] = bucket; |
996 | cb->args[1] = idx; | 1042 | cb->args[1] = idx; |
997 | 1043 | ||
998 | ret = msg->len; | 1044 | ret = msg->len; |
999 | 1045 | ||
1000 | out: | 1046 | out: |
1001 | if (primary_if) | 1047 | if (primary_if) |
1002 | batadv_hardif_put(primary_if); | 1048 | batadv_hardif_put(primary_if); |
1003 | 1049 | ||
1004 | if (soft_iface) | 1050 | if (soft_iface) |
1005 | dev_put(soft_iface); | 1051 | dev_put(soft_iface); |
1006 | 1052 | ||
1007 | return ret; | 1053 | return ret; |
1008 | } | 1054 | } |
1009 | 1055 | ||
1010 | /** | 1056 | /** |
1011 | * batadv_arp_get_type() - parse an ARP packet and gets the type | 1057 | * batadv_arp_get_type() - parse an ARP packet and gets the type |
1012 | * @bat_priv: the bat priv with all the soft interface information | 1058 | * @bat_priv: the bat priv with all the soft interface information |
1013 | * @skb: packet to analyse | 1059 | * @skb: packet to analyse |
1014 | * @hdr_size: size of the possible header before the ARP packet in the skb | 1060 | * @hdr_size: size of the possible header before the ARP packet in the skb |
1015 | * | 1061 | * |
1016 | * Return: the ARP type if the skb contains a valid ARP packet, 0 otherwise. | 1062 | * Return: the ARP type if the skb contains a valid ARP packet, 0 otherwise. |
1017 | */ | 1063 | */ |
1018 | static u16 batadv_arp_get_type(struct batadv_priv *bat_priv, | 1064 | static u16 batadv_arp_get_type(struct batadv_priv *bat_priv, |
1019 | struct sk_buff *skb, int hdr_size) | 1065 | struct sk_buff *skb, int hdr_size) |
1020 | { | 1066 | { |
1021 | struct arphdr *arphdr; | 1067 | struct arphdr *arphdr; |
1022 | struct ethhdr *ethhdr; | 1068 | struct ethhdr *ethhdr; |
1023 | __be32 ip_src, ip_dst; | 1069 | __be32 ip_src, ip_dst; |
1024 | u8 *hw_src, *hw_dst; | 1070 | u8 *hw_src, *hw_dst; |
1025 | u16 type = 0; | 1071 | u16 type = 0; |
1026 | 1072 | ||
1027 | /* pull the ethernet header */ | 1073 | /* pull the ethernet header */ |
1028 | if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN))) | 1074 | if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN))) |
1029 | goto out; | 1075 | goto out; |
1030 | 1076 | ||
1031 | ethhdr = (struct ethhdr *)(skb->data + hdr_size); | 1077 | ethhdr = (struct ethhdr *)(skb->data + hdr_size); |
1032 | 1078 | ||
1033 | if (ethhdr->h_proto != htons(ETH_P_ARP)) | 1079 | if (ethhdr->h_proto != htons(ETH_P_ARP)) |
1034 | goto out; | 1080 | goto out; |
1035 | 1081 | ||
1036 | /* pull the ARP payload */ | 1082 | /* pull the ARP payload */ |
1037 | if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN + | 1083 | if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN + |
1038 | arp_hdr_len(skb->dev)))) | 1084 | arp_hdr_len(skb->dev)))) |
1039 | goto out; | 1085 | goto out; |
1040 | 1086 | ||
1041 | arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN); | 1087 | arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN); |
1042 | 1088 | ||
1043 | /* check whether the ARP packet carries a valid IP information */ | 1089 | /* check whether the ARP packet carries a valid IP information */ |
1044 | if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) | 1090 | if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) |
1045 | goto out; | 1091 | goto out; |
1046 | 1092 | ||
1047 | if (arphdr->ar_pro != htons(ETH_P_IP)) | 1093 | if (arphdr->ar_pro != htons(ETH_P_IP)) |
1048 | goto out; | 1094 | goto out; |
1049 | 1095 | ||
1050 | if (arphdr->ar_hln != ETH_ALEN) | 1096 | if (arphdr->ar_hln != ETH_ALEN) |
1051 | goto out; | 1097 | goto out; |
1052 | 1098 | ||
1053 | if (arphdr->ar_pln != 4) | 1099 | if (arphdr->ar_pln != 4) |
1054 | goto out; | 1100 | goto out; |
1055 | 1101 | ||
1056 | /* Check for bad reply/request. If the ARP message is not sane, DAT | 1102 | /* Check for bad reply/request. If the ARP message is not sane, DAT |
1057 | * will simply ignore it | 1103 | * will simply ignore it |
1058 | */ | 1104 | */ |
1059 | ip_src = batadv_arp_ip_src(skb, hdr_size); | 1105 | ip_src = batadv_arp_ip_src(skb, hdr_size); |
1060 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | 1106 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); |
1061 | if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) || | 1107 | if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) || |
1062 | ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst) || | 1108 | ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst) || |
1063 | ipv4_is_zeronet(ip_src) || ipv4_is_lbcast(ip_src) || | 1109 | ipv4_is_zeronet(ip_src) || ipv4_is_lbcast(ip_src) || |
1064 | ipv4_is_zeronet(ip_dst) || ipv4_is_lbcast(ip_dst)) | 1110 | ipv4_is_zeronet(ip_dst) || ipv4_is_lbcast(ip_dst)) |
1065 | goto out; | 1111 | goto out; |
1066 | 1112 | ||
1067 | hw_src = batadv_arp_hw_src(skb, hdr_size); | 1113 | hw_src = batadv_arp_hw_src(skb, hdr_size); |
1068 | if (is_zero_ether_addr(hw_src) || is_multicast_ether_addr(hw_src)) | 1114 | if (is_zero_ether_addr(hw_src) || is_multicast_ether_addr(hw_src)) |
1069 | goto out; | 1115 | goto out; |
1070 | 1116 | ||
1071 | /* don't care about the destination MAC address in ARP requests */ | 1117 | /* don't care about the destination MAC address in ARP requests */ |
1072 | if (arphdr->ar_op != htons(ARPOP_REQUEST)) { | 1118 | if (arphdr->ar_op != htons(ARPOP_REQUEST)) { |
1073 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); | 1119 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); |
1074 | if (is_zero_ether_addr(hw_dst) || | 1120 | if (is_zero_ether_addr(hw_dst) || |
1075 | is_multicast_ether_addr(hw_dst)) | 1121 | is_multicast_ether_addr(hw_dst)) |
1076 | goto out; | 1122 | goto out; |
1077 | } | 1123 | } |
1078 | 1124 | ||
1079 | type = ntohs(arphdr->ar_op); | 1125 | type = ntohs(arphdr->ar_op); |
1080 | out: | 1126 | out: |
1081 | return type; | 1127 | return type; |
1082 | } | 1128 | } |
1083 | 1129 | ||
1084 | /** | 1130 | /** |
1085 | * batadv_dat_get_vid() - extract the VLAN identifier from skb if any | 1131 | * batadv_dat_get_vid() - extract the VLAN identifier from skb if any |
1086 | * @skb: the buffer containing the packet to extract the VID from | 1132 | * @skb: the buffer containing the packet to extract the VID from |
1087 | * @hdr_size: the size of the batman-adv header encapsulating the packet | 1133 | * @hdr_size: the size of the batman-adv header encapsulating the packet |
1088 | * | 1134 | * |
1089 | * Return: If the packet embedded in the skb is vlan tagged this function | 1135 | * Return: If the packet embedded in the skb is vlan tagged this function |
1090 | * returns the VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS | 1136 | * returns the VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS |
1091 | * is returned. | 1137 | * is returned. |
1092 | */ | 1138 | */ |
1093 | static unsigned short batadv_dat_get_vid(struct sk_buff *skb, int *hdr_size) | 1139 | static unsigned short batadv_dat_get_vid(struct sk_buff *skb, int *hdr_size) |
1094 | { | 1140 | { |
1095 | unsigned short vid; | 1141 | unsigned short vid; |
1096 | 1142 | ||
1097 | vid = batadv_get_vid(skb, *hdr_size); | 1143 | vid = batadv_get_vid(skb, *hdr_size); |
1098 | 1144 | ||
1099 | /* ARP parsing functions jump forward of hdr_size + ETH_HLEN. | 1145 | /* ARP parsing functions jump forward of hdr_size + ETH_HLEN. |
1100 | * If the header contained in the packet is a VLAN one (which is longer) | 1146 | * If the header contained in the packet is a VLAN one (which is longer) |
1101 | * hdr_size is updated so that the functions will still skip the | 1147 | * hdr_size is updated so that the functions will still skip the |
1102 | * correct amount of bytes. | 1148 | * correct amount of bytes. |
1103 | */ | 1149 | */ |
1104 | if (vid & BATADV_VLAN_HAS_TAG) | 1150 | if (vid & BATADV_VLAN_HAS_TAG) |
1105 | *hdr_size += VLAN_HLEN; | 1151 | *hdr_size += VLAN_HLEN; |
1106 | 1152 | ||
1107 | return vid; | 1153 | return vid; |
1108 | } | 1154 | } |
1109 | 1155 | ||
1110 | /** | 1156 | /** |
1111 | * batadv_dat_arp_create_reply() - create an ARP Reply | 1157 | * batadv_dat_arp_create_reply() - create an ARP Reply |
1112 | * @bat_priv: the bat priv with all the soft interface information | 1158 | * @bat_priv: the bat priv with all the soft interface information |
1113 | * @ip_src: ARP sender IP | 1159 | * @ip_src: ARP sender IP |
1114 | * @ip_dst: ARP target IP | 1160 | * @ip_dst: ARP target IP |
1115 | * @hw_src: Ethernet source and ARP sender MAC | 1161 | * @hw_src: Ethernet source and ARP sender MAC |
1116 | * @hw_dst: Ethernet destination and ARP target MAC | 1162 | * @hw_dst: Ethernet destination and ARP target MAC |
1117 | * @vid: VLAN identifier (optional, set to zero otherwise) | 1163 | * @vid: VLAN identifier (optional, set to zero otherwise) |
1118 | * | 1164 | * |
1119 | * Creates an ARP Reply from the given values, optionally encapsulated in a | 1165 | * Creates an ARP Reply from the given values, optionally encapsulated in a |
1120 | * VLAN header. | 1166 | * VLAN header. |
1121 | * | 1167 | * |
1122 | * Return: An skb containing an ARP Reply. | 1168 | * Return: An skb containing an ARP Reply. |
1123 | */ | 1169 | */ |
1124 | static struct sk_buff * | 1170 | static struct sk_buff * |
1125 | batadv_dat_arp_create_reply(struct batadv_priv *bat_priv, __be32 ip_src, | 1171 | batadv_dat_arp_create_reply(struct batadv_priv *bat_priv, __be32 ip_src, |
1126 | __be32 ip_dst, u8 *hw_src, u8 *hw_dst, | 1172 | __be32 ip_dst, u8 *hw_src, u8 *hw_dst, |
1127 | unsigned short vid) | 1173 | unsigned short vid) |
1128 | { | 1174 | { |
1129 | struct sk_buff *skb; | 1175 | struct sk_buff *skb; |
1130 | 1176 | ||
1131 | skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->soft_iface, | 1177 | skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->soft_iface, |
1132 | ip_src, hw_dst, hw_src, hw_dst); | 1178 | ip_src, hw_dst, hw_src, hw_dst); |
1133 | if (!skb) | 1179 | if (!skb) |
1134 | return NULL; | 1180 | return NULL; |
1135 | 1181 | ||
1136 | skb_reset_mac_header(skb); | 1182 | skb_reset_mac_header(skb); |
1137 | 1183 | ||
1138 | if (vid & BATADV_VLAN_HAS_TAG) | 1184 | if (vid & BATADV_VLAN_HAS_TAG) |
1139 | skb = vlan_insert_tag(skb, htons(ETH_P_8021Q), | 1185 | skb = vlan_insert_tag(skb, htons(ETH_P_8021Q), |
1140 | vid & VLAN_VID_MASK); | 1186 | vid & VLAN_VID_MASK); |
1141 | 1187 | ||
1142 | return skb; | 1188 | return skb; |
1143 | } | 1189 | } |
1144 | 1190 | ||
1145 | /** | 1191 | /** |
1146 | * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to | 1192 | * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to |
1147 | * answer using DAT | 1193 | * answer using DAT |
1148 | * @bat_priv: the bat priv with all the soft interface information | 1194 | * @bat_priv: the bat priv with all the soft interface information |
1149 | * @skb: packet to check | 1195 | * @skb: packet to check |
1150 | * | 1196 | * |
1151 | * Return: true if the message has been sent to the dht candidates, false | 1197 | * Return: true if the message has been sent to the dht candidates, false |
1152 | * otherwise. In case of a positive return value the message has to be enqueued | 1198 | * otherwise. In case of a positive return value the message has to be enqueued |
1153 | * to permit the fallback. | 1199 | * to permit the fallback. |
1154 | */ | 1200 | */ |
1155 | bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | 1201 | bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, |
1156 | struct sk_buff *skb) | 1202 | struct sk_buff *skb) |
1157 | { | 1203 | { |
1158 | u16 type = 0; | 1204 | u16 type = 0; |
1159 | __be32 ip_dst, ip_src; | 1205 | __be32 ip_dst, ip_src; |
1160 | u8 *hw_src; | 1206 | u8 *hw_src; |
1161 | bool ret = false; | 1207 | bool ret = false; |
1162 | struct batadv_dat_entry *dat_entry = NULL; | 1208 | struct batadv_dat_entry *dat_entry = NULL; |
1163 | struct sk_buff *skb_new; | 1209 | struct sk_buff *skb_new; |
1164 | struct net_device *soft_iface = bat_priv->soft_iface; | 1210 | struct net_device *soft_iface = bat_priv->soft_iface; |
1165 | int hdr_size = 0; | 1211 | int hdr_size = 0; |
1166 | unsigned short vid; | 1212 | unsigned short vid; |
1167 | 1213 | ||
1168 | if (!atomic_read(&bat_priv->distributed_arp_table)) | 1214 | if (!atomic_read(&bat_priv->distributed_arp_table)) |
1169 | goto out; | 1215 | goto out; |
1170 | 1216 | ||
1171 | vid = batadv_dat_get_vid(skb, &hdr_size); | 1217 | vid = batadv_dat_get_vid(skb, &hdr_size); |
1172 | 1218 | ||
1173 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); | 1219 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); |
1174 | /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast | 1220 | /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast |
1175 | * message to the selected DHT candidates | 1221 | * message to the selected DHT candidates |
1176 | */ | 1222 | */ |
1177 | if (type != ARPOP_REQUEST) | 1223 | if (type != ARPOP_REQUEST) |
1178 | goto out; | 1224 | goto out; |
1179 | 1225 | ||
1180 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing outgoing ARP REQUEST"); | 1226 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing outgoing ARP REQUEST"); |
1181 | 1227 | ||
1182 | ip_src = batadv_arp_ip_src(skb, hdr_size); | 1228 | ip_src = batadv_arp_ip_src(skb, hdr_size); |
1183 | hw_src = batadv_arp_hw_src(skb, hdr_size); | 1229 | hw_src = batadv_arp_hw_src(skb, hdr_size); |
1184 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | 1230 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); |
1185 | 1231 | ||
1186 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); | 1232 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); |
1187 | 1233 | ||
1188 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid); | 1234 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid); |
1189 | if (dat_entry) { | 1235 | if (dat_entry) { |
1190 | /* If the ARP request is destined for a local client the local | 1236 | /* If the ARP request is destined for a local client the local |
1191 | * client will answer itself. DAT would only generate a | 1237 | * client will answer itself. DAT would only generate a |
1192 | * duplicate packet. | 1238 | * duplicate packet. |
1193 | * | 1239 | * |
1194 | * Moreover, if the soft-interface is enslaved into a bridge, an | 1240 | * Moreover, if the soft-interface is enslaved into a bridge, an |
1195 | * additional DAT answer may trigger kernel warnings about | 1241 | * additional DAT answer may trigger kernel warnings about |
1196 | * a packet coming from the wrong port. | 1242 | * a packet coming from the wrong port. |
1197 | */ | 1243 | */ |
1198 | if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) { | 1244 | if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) { |
1199 | ret = true; | 1245 | ret = true; |
1200 | goto out; | 1246 | goto out; |
1201 | } | 1247 | } |
1202 | 1248 | ||
1203 | /* If BLA is enabled, only send ARP replies if we have claimed | 1249 | /* If BLA is enabled, only send ARP replies if we have claimed |
1204 | * the destination for the ARP request or if no one else of | 1250 | * the destination for the ARP request or if no one else of |
1205 | * the backbone gws belonging to our backbone has claimed the | 1251 | * the backbone gws belonging to our backbone has claimed the |
1206 | * destination. | 1252 | * destination. |
1207 | */ | 1253 | */ |
1208 | if (!batadv_bla_check_claim(bat_priv, | 1254 | if (!batadv_bla_check_claim(bat_priv, |
1209 | dat_entry->mac_addr, vid)) { | 1255 | dat_entry->mac_addr, vid)) { |
1210 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 1256 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
1211 | "Device %pM claimed by another backbone gw. Don't send ARP reply!", | 1257 | "Device %pM claimed by another backbone gw. Don't send ARP reply!", |
1212 | dat_entry->mac_addr); | 1258 | dat_entry->mac_addr); |
1213 | ret = true; | 1259 | ret = true; |
1214 | goto out; | 1260 | goto out; |
1215 | } | 1261 | } |
1216 | 1262 | ||
1217 | skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src, | 1263 | skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src, |
1218 | dat_entry->mac_addr, | 1264 | dat_entry->mac_addr, |
1219 | hw_src, vid); | 1265 | hw_src, vid); |
1220 | if (!skb_new) | 1266 | if (!skb_new) |
1221 | goto out; | 1267 | goto out; |
1222 | 1268 | ||
1223 | skb_new->protocol = eth_type_trans(skb_new, soft_iface); | 1269 | skb_new->protocol = eth_type_trans(skb_new, soft_iface); |
1224 | 1270 | ||
1225 | batadv_inc_counter(bat_priv, BATADV_CNT_RX); | 1271 | batadv_inc_counter(bat_priv, BATADV_CNT_RX); |
1226 | batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, | 1272 | batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, |
1227 | skb->len + ETH_HLEN + hdr_size); | 1273 | skb->len + ETH_HLEN + hdr_size); |
1228 | 1274 | ||
1229 | netif_rx(skb_new); | 1275 | netif_rx(skb_new); |
1230 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n"); | 1276 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n"); |
1231 | ret = true; | 1277 | ret = true; |
1232 | } else { | 1278 | } else { |
1233 | /* Send the request to the DHT */ | 1279 | /* Send the request to the DHT */ |
1234 | ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid, | 1280 | ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid, |
1235 | BATADV_P_DAT_DHT_GET); | 1281 | BATADV_P_DAT_DHT_GET); |
1236 | } | 1282 | } |
1237 | out: | 1283 | out: |
1238 | if (dat_entry) | 1284 | if (dat_entry) |
1239 | batadv_dat_entry_put(dat_entry); | 1285 | batadv_dat_entry_put(dat_entry); |
1240 | return ret; | 1286 | return ret; |
1241 | } | 1287 | } |
1242 | 1288 | ||
1243 | /** | 1289 | /** |
1244 | * batadv_dat_snoop_incoming_arp_request() - snoop the ARP request and try to | 1290 | * batadv_dat_snoop_incoming_arp_request() - snoop the ARP request and try to |
1245 | * answer using the local DAT storage | 1291 | * answer using the local DAT storage |
1246 | * @bat_priv: the bat priv with all the soft interface information | 1292 | * @bat_priv: the bat priv with all the soft interface information |
1247 | * @skb: packet to check | 1293 | * @skb: packet to check |
1248 | * @hdr_size: size of the encapsulation header | 1294 | * @hdr_size: size of the encapsulation header |
1249 | * | 1295 | * |
1250 | * Return: true if the request has been answered, false otherwise. | 1296 | * Return: true if the request has been answered, false otherwise. |
1251 | */ | 1297 | */ |
1252 | bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, | 1298 | bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, |
1253 | struct sk_buff *skb, int hdr_size) | 1299 | struct sk_buff *skb, int hdr_size) |
1254 | { | 1300 | { |
1255 | u16 type; | 1301 | u16 type; |
1256 | __be32 ip_src, ip_dst; | 1302 | __be32 ip_src, ip_dst; |
1257 | u8 *hw_src; | 1303 | u8 *hw_src; |
1258 | struct sk_buff *skb_new; | 1304 | struct sk_buff *skb_new; |
1259 | struct batadv_dat_entry *dat_entry = NULL; | 1305 | struct batadv_dat_entry *dat_entry = NULL; |
1260 | bool ret = false; | 1306 | bool ret = false; |
1261 | unsigned short vid; | 1307 | unsigned short vid; |
1262 | int err; | 1308 | int err; |
1263 | 1309 | ||
1264 | if (!atomic_read(&bat_priv->distributed_arp_table)) | 1310 | if (!atomic_read(&bat_priv->distributed_arp_table)) |
1265 | goto out; | 1311 | goto out; |
1266 | 1312 | ||
1267 | vid = batadv_dat_get_vid(skb, &hdr_size); | 1313 | vid = batadv_dat_get_vid(skb, &hdr_size); |
1268 | 1314 | ||
1269 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); | 1315 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); |
1270 | if (type != ARPOP_REQUEST) | 1316 | if (type != ARPOP_REQUEST) |
1271 | goto out; | 1317 | goto out; |
1272 | 1318 | ||
1273 | hw_src = batadv_arp_hw_src(skb, hdr_size); | 1319 | hw_src = batadv_arp_hw_src(skb, hdr_size); |
1274 | ip_src = batadv_arp_ip_src(skb, hdr_size); | 1320 | ip_src = batadv_arp_ip_src(skb, hdr_size); |
1275 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | 1321 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); |
1276 | 1322 | ||
1277 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing incoming ARP REQUEST"); | 1323 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing incoming ARP REQUEST"); |
1278 | 1324 | ||
1279 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); | 1325 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); |
1280 | 1326 | ||
1281 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid); | 1327 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid); |
1282 | if (!dat_entry) | 1328 | if (!dat_entry) |
1283 | goto out; | 1329 | goto out; |
1284 | 1330 | ||
1285 | skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src, | 1331 | skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src, |
1286 | dat_entry->mac_addr, hw_src, vid); | 1332 | dat_entry->mac_addr, hw_src, vid); |
1287 | if (!skb_new) | 1333 | if (!skb_new) |
1288 | goto out; | 1334 | goto out; |
1289 | 1335 | ||
1290 | /* To preserve backwards compatibility, the node has choose the outgoing | 1336 | /* To preserve backwards compatibility, the node has choose the outgoing |
1291 | * format based on the incoming request packet type. The assumption is | 1337 | * format based on the incoming request packet type. The assumption is |
1292 | * that a node not using the 4addr packet format doesn't support it. | 1338 | * that a node not using the 4addr packet format doesn't support it. |
1293 | */ | 1339 | */ |
1294 | if (hdr_size == sizeof(struct batadv_unicast_4addr_packet)) | 1340 | if (hdr_size == sizeof(struct batadv_unicast_4addr_packet)) |
1295 | err = batadv_send_skb_via_tt_4addr(bat_priv, skb_new, | 1341 | err = batadv_send_skb_via_tt_4addr(bat_priv, skb_new, |
1296 | BATADV_P_DAT_CACHE_REPLY, | 1342 | BATADV_P_DAT_CACHE_REPLY, |
1297 | NULL, vid); | 1343 | NULL, vid); |
1298 | else | 1344 | else |
1299 | err = batadv_send_skb_via_tt(bat_priv, skb_new, NULL, vid); | 1345 | err = batadv_send_skb_via_tt(bat_priv, skb_new, NULL, vid); |
1300 | 1346 | ||
1301 | if (err != NET_XMIT_DROP) { | 1347 | if (err != NET_XMIT_DROP) { |
1302 | batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX); | 1348 | batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX); |
1303 | ret = true; | 1349 | ret = true; |
1304 | } | 1350 | } |
1305 | out: | 1351 | out: |
1306 | if (dat_entry) | 1352 | if (dat_entry) |
1307 | batadv_dat_entry_put(dat_entry); | 1353 | batadv_dat_entry_put(dat_entry); |
1308 | if (ret) | 1354 | if (ret) |
1309 | kfree_skb(skb); | 1355 | kfree_skb(skb); |
1310 | return ret; | 1356 | return ret; |
1311 | } | 1357 | } |
1312 | 1358 | ||
1313 | /** | 1359 | /** |
1314 | * batadv_dat_snoop_outgoing_arp_reply() - snoop the ARP reply and fill the DHT | 1360 | * batadv_dat_snoop_outgoing_arp_reply() - snoop the ARP reply and fill the DHT |
1315 | * @bat_priv: the bat priv with all the soft interface information | 1361 | * @bat_priv: the bat priv with all the soft interface information |
1316 | * @skb: packet to check | 1362 | * @skb: packet to check |
1317 | */ | 1363 | */ |
1318 | void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, | 1364 | void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, |
1319 | struct sk_buff *skb) | 1365 | struct sk_buff *skb) |
1320 | { | 1366 | { |
1321 | u16 type; | 1367 | u16 type; |
1322 | __be32 ip_src, ip_dst; | 1368 | __be32 ip_src, ip_dst; |
1323 | u8 *hw_src, *hw_dst; | 1369 | u8 *hw_src, *hw_dst; |
1324 | int hdr_size = 0; | 1370 | int hdr_size = 0; |
1325 | unsigned short vid; | 1371 | unsigned short vid; |
1326 | 1372 | ||
1327 | if (!atomic_read(&bat_priv->distributed_arp_table)) | 1373 | if (!atomic_read(&bat_priv->distributed_arp_table)) |
1328 | return; | 1374 | return; |
1329 | 1375 | ||
1330 | vid = batadv_dat_get_vid(skb, &hdr_size); | 1376 | vid = batadv_dat_get_vid(skb, &hdr_size); |
1331 | 1377 | ||
1332 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); | 1378 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); |
1333 | if (type != ARPOP_REPLY) | 1379 | if (type != ARPOP_REPLY) |
1334 | return; | 1380 | return; |
1335 | 1381 | ||
1336 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing outgoing ARP REPLY"); | 1382 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing outgoing ARP REPLY"); |
1337 | 1383 | ||
1338 | hw_src = batadv_arp_hw_src(skb, hdr_size); | 1384 | hw_src = batadv_arp_hw_src(skb, hdr_size); |
1339 | ip_src = batadv_arp_ip_src(skb, hdr_size); | 1385 | ip_src = batadv_arp_ip_src(skb, hdr_size); |
1340 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); | 1386 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); |
1341 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | 1387 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); |
1342 | 1388 | ||
1343 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); | 1389 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); |
1344 | batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid); | 1390 | batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid); |
1345 | 1391 | ||
1346 | /* Send the ARP reply to the candidates for both the IP addresses that | 1392 | /* Send the ARP reply to the candidates for both the IP addresses that |
1347 | * the node obtained from the ARP reply | 1393 | * the node obtained from the ARP reply |
1348 | */ | 1394 | */ |
1349 | batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT); | 1395 | batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT); |
1350 | batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); | 1396 | batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); |
1351 | } | 1397 | } |
1352 | 1398 | ||
1353 | /** | 1399 | /** |
1354 | * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the | 1400 | * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the |
1355 | * local DAT storage only | 1401 | * local DAT storage only |
1356 | * @bat_priv: the bat priv with all the soft interface information | 1402 | * @bat_priv: the bat priv with all the soft interface information |
1357 | * @skb: packet to check | 1403 | * @skb: packet to check |
1358 | * @hdr_size: size of the encapsulation header | 1404 | * @hdr_size: size of the encapsulation header |
1359 | * | 1405 | * |
1360 | * Return: true if the packet was snooped and consumed by DAT. False if the | 1406 | * Return: true if the packet was snooped and consumed by DAT. False if the |
1361 | * packet has to be delivered to the interface | 1407 | * packet has to be delivered to the interface |
1362 | */ | 1408 | */ |
1363 | bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, | 1409 | bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, |
1364 | struct sk_buff *skb, int hdr_size) | 1410 | struct sk_buff *skb, int hdr_size) |
1365 | { | 1411 | { |
1366 | struct batadv_dat_entry *dat_entry = NULL; | 1412 | struct batadv_dat_entry *dat_entry = NULL; |
1367 | u16 type; | 1413 | u16 type; |
1368 | __be32 ip_src, ip_dst; | 1414 | __be32 ip_src, ip_dst; |
1369 | u8 *hw_src, *hw_dst; | 1415 | u8 *hw_src, *hw_dst; |
1370 | bool dropped = false; | 1416 | bool dropped = false; |
1371 | unsigned short vid; | 1417 | unsigned short vid; |
1372 | 1418 | ||
1373 | if (!atomic_read(&bat_priv->distributed_arp_table)) | 1419 | if (!atomic_read(&bat_priv->distributed_arp_table)) |
1374 | goto out; | 1420 | goto out; |
1375 | 1421 | ||
1376 | vid = batadv_dat_get_vid(skb, &hdr_size); | 1422 | vid = batadv_dat_get_vid(skb, &hdr_size); |
1377 | 1423 | ||
1378 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); | 1424 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); |
1379 | if (type != ARPOP_REPLY) | 1425 | if (type != ARPOP_REPLY) |
1380 | goto out; | 1426 | goto out; |
1381 | 1427 | ||
1382 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing incoming ARP REPLY"); | 1428 | batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing incoming ARP REPLY"); |
1383 | 1429 | ||
1384 | hw_src = batadv_arp_hw_src(skb, hdr_size); | 1430 | hw_src = batadv_arp_hw_src(skb, hdr_size); |
1385 | ip_src = batadv_arp_ip_src(skb, hdr_size); | 1431 | ip_src = batadv_arp_ip_src(skb, hdr_size); |
1386 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); | 1432 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); |
1387 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | 1433 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); |
1388 | 1434 | ||
1389 | /* If ip_dst is already in cache and has the right mac address, | 1435 | /* If ip_dst is already in cache and has the right mac address, |
1390 | * drop this frame if this ARP reply is destined for us because it's | 1436 | * drop this frame if this ARP reply is destined for us because it's |
1391 | * most probably an ARP reply generated by another node of the DHT. | 1437 | * most probably an ARP reply generated by another node of the DHT. |
1392 | * We have most probably received already a reply earlier. Delivering | 1438 | * We have most probably received already a reply earlier. Delivering |
1393 | * this frame would lead to doubled receive of an ARP reply. | 1439 | * this frame would lead to doubled receive of an ARP reply. |
1394 | */ | 1440 | */ |
1395 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_src, vid); | 1441 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_src, vid); |
1396 | if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) { | 1442 | if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) { |
1397 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "Doubled ARP reply removed: ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]; dat_entry: %pM-%pI4\n", | 1443 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "Doubled ARP reply removed: ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]; dat_entry: %pM-%pI4\n", |
1398 | hw_src, &ip_src, hw_dst, &ip_dst, | 1444 | hw_src, &ip_src, hw_dst, &ip_dst, |
1399 | dat_entry->mac_addr, &dat_entry->ip); | 1445 | dat_entry->mac_addr, &dat_entry->ip); |
1400 | dropped = true; | 1446 | dropped = true; |
1401 | goto out; | 1447 | goto out; |
1402 | } | 1448 | } |
1403 | 1449 | ||
1404 | /* Update our internal cache with both the IP addresses the node got | 1450 | /* Update our internal cache with both the IP addresses the node got |
1405 | * within the ARP reply | 1451 | * within the ARP reply |
1406 | */ | 1452 | */ |
1407 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); | 1453 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); |
1408 | batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid); | 1454 | batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid); |
1409 | 1455 | ||
1410 | /* If BLA is enabled, only forward ARP replies if we have claimed the | 1456 | /* If BLA is enabled, only forward ARP replies if we have claimed the |
1411 | * source of the ARP reply or if no one else of the same backbone has | 1457 | * source of the ARP reply or if no one else of the same backbone has |
1412 | * already claimed that client. This prevents that different gateways | 1458 | * already claimed that client. This prevents that different gateways |
1413 | * to the same backbone all forward the ARP reply leading to multiple | 1459 | * to the same backbone all forward the ARP reply leading to multiple |
1414 | * replies in the backbone. | 1460 | * replies in the backbone. |
1415 | */ | 1461 | */ |
1416 | if (!batadv_bla_check_claim(bat_priv, hw_src, vid)) { | 1462 | if (!batadv_bla_check_claim(bat_priv, hw_src, vid)) { |
1417 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 1463 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
1418 | "Device %pM claimed by another backbone gw. Drop ARP reply.\n", | 1464 | "Device %pM claimed by another backbone gw. Drop ARP reply.\n", |
1419 | hw_src); | 1465 | hw_src); |
1420 | dropped = true; | 1466 | dropped = true; |
1421 | goto out; | 1467 | goto out; |
1422 | } | 1468 | } |
1423 | 1469 | ||
1424 | /* if this REPLY is directed to a client of mine, let's deliver the | 1470 | /* if this REPLY is directed to a client of mine, let's deliver the |
1425 | * packet to the interface | 1471 | * packet to the interface |
1426 | */ | 1472 | */ |
1427 | dropped = !batadv_is_my_client(bat_priv, hw_dst, vid); | 1473 | dropped = !batadv_is_my_client(bat_priv, hw_dst, vid); |
1428 | 1474 | ||
1429 | /* if this REPLY is sent on behalf of a client of mine, let's drop the | 1475 | /* if this REPLY is sent on behalf of a client of mine, let's drop the |
1430 | * packet because the client will reply by itself | 1476 | * packet because the client will reply by itself |
1431 | */ | 1477 | */ |
1432 | dropped |= batadv_is_my_client(bat_priv, hw_src, vid); | 1478 | dropped |= batadv_is_my_client(bat_priv, hw_src, vid); |
1433 | out: | 1479 | out: |
1434 | if (dropped) | 1480 | if (dropped) |
1435 | kfree_skb(skb); | 1481 | kfree_skb(skb); |
1436 | if (dat_entry) | 1482 | if (dat_entry) |
1437 | batadv_dat_entry_put(dat_entry); | 1483 | batadv_dat_entry_put(dat_entry); |
1438 | /* if dropped == false -> deliver to the interface */ | 1484 | /* if dropped == false -> deliver to the interface */ |
1439 | return dropped; | 1485 | return dropped; |
1486 | } | ||
1487 | |||
1488 | /** | ||
1489 | * batadv_dat_check_dhcp_ipudp() - check skb for IP+UDP headers valid for DHCP | ||
1490 | * @skb: the packet to check | ||
1491 | * @ip_src: a buffer to store the IPv4 source address in | ||
1492 | * | ||
1493 | * Checks whether the given skb has an IP and UDP header valid for a DHCP | ||
1494 | * message from a DHCP server. And if so, stores the IPv4 source address in | ||
1495 | * the provided buffer. | ||
1496 | * | ||
1497 | * Return: True if valid, false otherwise. | ||
1498 | */ | ||
1499 | static bool | ||
1500 | batadv_dat_check_dhcp_ipudp(struct sk_buff *skb, __be32 *ip_src) | ||
1501 | { | ||
1502 | unsigned int offset = skb_network_offset(skb); | ||
1503 | struct udphdr *udphdr, _udphdr; | ||
1504 | struct iphdr *iphdr, _iphdr; | ||
1505 | |||
1506 | iphdr = skb_header_pointer(skb, offset, sizeof(_iphdr), &_iphdr); | ||
1507 | if (!iphdr || iphdr->version != 4 || iphdr->ihl * 4 < sizeof(_iphdr)) | ||
1508 | return false; | ||
1509 | |||
1510 | if (iphdr->protocol != IPPROTO_UDP) | ||
1511 | return false; | ||
1512 | |||
1513 | offset += iphdr->ihl * 4; | ||
1514 | skb_set_transport_header(skb, offset); | ||
1515 | |||
1516 | udphdr = skb_header_pointer(skb, offset, sizeof(_udphdr), &_udphdr); | ||
1517 | if (!udphdr || udphdr->source != htons(67)) | ||
1518 | return false; | ||
1519 | |||
1520 | *ip_src = get_unaligned(&iphdr->saddr); | ||
1521 | |||
1522 | return true; | ||
1523 | } | ||
1524 | |||
1525 | /** | ||
1526 | * batadv_dat_check_dhcp() - examine packet for valid DHCP message | ||
1527 | * @skb: the packet to check | ||
1528 | * @proto: ethernet protocol hint (behind a potential vlan) | ||
1529 | * @ip_src: a buffer to store the IPv4 source address in | ||
1530 | * | ||
1531 | * Checks whether the given skb is a valid DHCP packet. And if so, stores the | ||
1532 | * IPv4 source address in the provided buffer. | ||
1533 | * | ||
1534 | * Caller needs to ensure that the skb network header is set correctly. | ||
1535 | * | ||
1536 | * Return: If skb is a valid DHCP packet, then returns its op code | ||
1537 | * (e.g. BOOTREPLY vs. BOOTREQUEST). Otherwise returns -EINVAL. | ||
1538 | */ | ||
1539 | static int | ||
1540 | batadv_dat_check_dhcp(struct sk_buff *skb, __be16 proto, __be32 *ip_src) | ||
1541 | { | ||
1542 | __be32 *magic, _magic; | ||
1543 | unsigned int offset; | ||
1544 | struct { | ||
1545 | __u8 op; | ||
1546 | __u8 htype; | ||
1547 | __u8 hlen; | ||
1548 | __u8 hops; | ||
1549 | } *dhcp_h, _dhcp_h; | ||
1550 | |||
1551 | if (proto != htons(ETH_P_IP)) | ||
1552 | return -EINVAL; | ||
1553 | |||
1554 | if (!batadv_dat_check_dhcp_ipudp(skb, ip_src)) | ||
1555 | return -EINVAL; | ||
1556 | |||
1557 | offset = skb_transport_offset(skb) + sizeof(struct udphdr); | ||
1558 | if (skb->len < offset + sizeof(struct batadv_dhcp_packet)) | ||
1559 | return -EINVAL; | ||
1560 | |||
1561 | dhcp_h = skb_header_pointer(skb, offset, sizeof(_dhcp_h), &_dhcp_h); | ||
1562 | if (!dhcp_h || dhcp_h->htype != BATADV_HTYPE_ETHERNET || | ||
1563 | dhcp_h->hlen != ETH_ALEN) | ||
1564 | return -EINVAL; | ||
1565 | |||
1566 | offset += offsetof(struct batadv_dhcp_packet, magic); | ||
1567 | |||
1568 | magic = skb_header_pointer(skb, offset, sizeof(_magic), &_magic); | ||
1569 | if (!magic || get_unaligned(magic) != htonl(BATADV_DHCP_MAGIC)) | ||
1570 | return -EINVAL; | ||
1571 | |||
1572 | return dhcp_h->op; | ||
1573 | } | ||
1574 | |||
1575 | /** | ||
1576 | * batadv_dat_get_dhcp_message_type() - get message type of a DHCP packet | ||
1577 | * @skb: the DHCP packet to parse | ||
1578 | * | ||
1579 | * Iterates over the DHCP options of the given DHCP packet to find a | ||
1580 | * DHCP Message Type option and parse it. | ||
1581 | * | ||
1582 | * Caller needs to ensure that the given skb is a valid DHCP packet and | ||
1583 | * that the skb transport header is set correctly. | ||
1584 | * | ||
1585 | * Return: The found DHCP message type value, if found. -EINVAL otherwise. | ||
1586 | */ | ||
1587 | static int batadv_dat_get_dhcp_message_type(struct sk_buff *skb) | ||
1588 | { | ||
1589 | unsigned int offset = skb_transport_offset(skb) + sizeof(struct udphdr); | ||
1590 | u8 *type, _type; | ||
1591 | struct { | ||
1592 | u8 type; | ||
1593 | u8 len; | ||
1594 | } *tl, _tl; | ||
1595 | |||
1596 | offset += sizeof(struct batadv_dhcp_packet); | ||
1597 | |||
1598 | while ((tl = skb_header_pointer(skb, offset, sizeof(_tl), &_tl))) { | ||
1599 | if (tl->type == BATADV_DHCP_OPT_MSG_TYPE) | ||
1600 | break; | ||
1601 | |||
1602 | if (tl->type == BATADV_DHCP_OPT_END) | ||
1603 | break; | ||
1604 | |||
1605 | if (tl->type == BATADV_DHCP_OPT_PAD) | ||
1606 | offset++; | ||
1607 | else | ||
1608 | offset += tl->len + sizeof(_tl); | ||
1609 | } | ||
1610 | |||
1611 | /* Option Overload Code not supported */ | ||
1612 | if (!tl || tl->type != BATADV_DHCP_OPT_MSG_TYPE || | ||
1613 | tl->len != sizeof(_type)) | ||
1614 | return -EINVAL; | ||
1615 | |||
1616 | offset += sizeof(_tl); | ||
1617 | |||
1618 | type = skb_header_pointer(skb, offset, sizeof(_type), &_type); | ||
1619 | if (!type) | ||
1620 | return -EINVAL; | ||
1621 | |||
1622 | return *type; | ||
1623 | } | ||
1624 | |||
1625 | /** | ||
1626 | * batadv_dat_get_dhcp_yiaddr() - get yiaddr from a DHCP packet | ||
1627 | * @skb: the DHCP packet to parse | ||
1628 | * @buf: a buffer to store the yiaddr in | ||
1629 | * | ||
1630 | * Caller needs to ensure that the given skb is a valid DHCP packet and | ||
1631 | * that the skb transport header is set correctly. | ||
1632 | * | ||
1633 | * Return: True on success, false otherwise. | ||
1634 | */ | ||
1635 | static bool batadv_dat_dhcp_get_yiaddr(struct sk_buff *skb, __be32 *buf) | ||
1636 | { | ||
1637 | unsigned int offset = skb_transport_offset(skb) + sizeof(struct udphdr); | ||
1638 | __be32 *yiaddr; | ||
1639 | |||
1640 | offset += offsetof(struct batadv_dhcp_packet, yiaddr); | ||
1641 | yiaddr = skb_header_pointer(skb, offset, BATADV_DHCP_YIADDR_LEN, buf); | ||
1642 | |||
1643 | if (!yiaddr) | ||
1644 | return false; | ||
1645 | |||
1646 | if (yiaddr != buf) | ||
1647 | *buf = get_unaligned(yiaddr); | ||
1648 | |||
1649 | return true; | ||
1650 | } | ||
1651 | |||
1652 | /** | ||
1653 | * batadv_dat_get_dhcp_chaddr() - get chaddr from a DHCP packet | ||
1654 | * @skb: the DHCP packet to parse | ||
1655 | * @buf: a buffer to store the chaddr in | ||
1656 | * | ||
1657 | * Caller needs to ensure that the given skb is a valid DHCP packet and | ||
1658 | * that the skb transport header is set correctly. | ||
1659 | * | ||
1660 | * Return: True on success, false otherwise | ||
1661 | */ | ||
1662 | static bool batadv_dat_get_dhcp_chaddr(struct sk_buff *skb, u8 *buf) | ||
1663 | { | ||
1664 | unsigned int offset = skb_transport_offset(skb) + sizeof(struct udphdr); | ||
1665 | u8 *chaddr; | ||
1666 | |||
1667 | offset += offsetof(struct batadv_dhcp_packet, chaddr); | ||
1668 | chaddr = skb_header_pointer(skb, offset, BATADV_DHCP_CHADDR_LEN, buf); | ||
1669 | |||
1670 | if (!chaddr) | ||
1671 | return false; | ||
1672 | |||
1673 | if (chaddr != buf) | ||
1674 | memcpy(buf, chaddr, BATADV_DHCP_CHADDR_LEN); | ||
1675 | |||
1676 | return true; | ||
1677 | } | ||
1678 | |||
1679 | /** | ||
1680 | * batadv_dat_put_dhcp() - puts addresses from a DHCP packet into the DHT and | ||
1681 | * DAT cache | ||
1682 | * @bat_priv: the bat priv with all the soft interface information | ||
1683 | * @chaddr: the DHCP client MAC address | ||
1684 | * @yiaddr: the DHCP client IP address | ||
1685 | * @hw_dst: the DHCP server MAC address | ||
1686 | * @ip_dst: the DHCP server IP address | ||
1687 | * @vid: VLAN identifier | ||
1688 | * | ||
1689 | * Adds given MAC/IP pairs to the local DAT cache and propagates them further | ||
1690 | * into the DHT. | ||
1691 | * | ||
1692 | * For the DHT propagation, client MAC + IP will appear as the ARP Reply | ||
1693 | * transmitter (and hw_dst/ip_dst as the target). | ||
1694 | */ | ||
1695 | static void batadv_dat_put_dhcp(struct batadv_priv *bat_priv, u8 *chaddr, | ||
1696 | __be32 yiaddr, u8 *hw_dst, __be32 ip_dst, | ||
1697 | unsigned short vid) | ||
1698 | { | ||
1699 | struct sk_buff *skb; | ||
1700 | |||
1701 | skb = batadv_dat_arp_create_reply(bat_priv, yiaddr, ip_dst, chaddr, | ||
1702 | hw_dst, vid); | ||
1703 | if (!skb) | ||
1704 | return; | ||
1705 | |||
1706 | skb_set_network_header(skb, ETH_HLEN); | ||
1707 | |||
1708 | batadv_dat_entry_add(bat_priv, yiaddr, chaddr, vid); | ||
1709 | batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid); | ||
1710 | |||
1711 | batadv_dat_send_data(bat_priv, skb, yiaddr, vid, BATADV_P_DAT_DHT_PUT); | ||
1712 | batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); | ||
1713 | |||
1714 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
1715 | "Snooped from outgoing DHCPACK (server address): %pI4, %pM (vid: %i)\n", | ||
1716 | &ip_dst, hw_dst, batadv_print_vid(vid)); | ||
1717 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
1718 | "Snooped from outgoing DHCPACK (client address): %pI4, %pM (vid: %i)\n", | ||
1719 | &yiaddr, chaddr, batadv_print_vid(vid)); | ||
1720 | } | ||
1721 | |||
1722 | /** | ||
1723 | * batadv_dat_check_dhcp_ack() - examine packet for valid DHCP message | ||
1724 | * @skb: the packet to check | ||
1725 | * @proto: ethernet protocol hint (behind a potential vlan) | ||
1726 | * @ip_src: a buffer to store the IPv4 source address in | ||
1727 | * @chaddr: a buffer to store the DHCP Client Hardware Address in | ||
1728 | * @yiaddr: a buffer to store the DHCP Your IP Address in | ||
1729 | * | ||
1730 | * Checks whether the given skb is a valid DHCPACK. And if so, stores the | ||
1731 | * IPv4 server source address (ip_src), client MAC address (chaddr) and client | ||
1732 | * IPv4 address (yiaddr) in the provided buffers. | ||
1733 | * | ||
1734 | * Caller needs to ensure that the skb network header is set correctly. | ||
1735 | * | ||
1736 | * Return: True if the skb is a valid DHCPACK. False otherwise. | ||
1737 | */ | ||
1738 | static bool | ||
1739 | batadv_dat_check_dhcp_ack(struct sk_buff *skb, __be16 proto, __be32 *ip_src, | ||
1740 | u8 *chaddr, __be32 *yiaddr) | ||
1741 | { | ||
1742 | int type; | ||
1743 | |||
1744 | type = batadv_dat_check_dhcp(skb, proto, ip_src); | ||
1745 | if (type != BATADV_BOOTREPLY) | ||
1746 | return false; | ||
1747 | |||
1748 | type = batadv_dat_get_dhcp_message_type(skb); | ||
1749 | if (type != BATADV_DHCPACK) | ||
1750 | return false; | ||
1751 | |||
1752 | if (!batadv_dat_dhcp_get_yiaddr(skb, yiaddr)) | ||
1753 | return false; | ||
1754 | |||
1755 | if (!batadv_dat_get_dhcp_chaddr(skb, chaddr)) | ||
1756 | return false; | ||
1757 | |||
1758 | return true; | ||
1759 | } | ||
1760 | |||
1761 | /** | ||
1762 | * batadv_dat_snoop_outgoing_dhcp_ack() - snoop DHCPACK and fill DAT with it | ||
1763 | * @bat_priv: the bat priv with all the soft interface information | ||
1764 | * @skb: the packet to snoop | ||
1765 | * @proto: ethernet protocol hint (behind a potential vlan) | ||
1766 | * @vid: VLAN identifier | ||
1767 | * | ||
1768 | * This function first checks whether the given skb is a valid DHCPACK. If | ||
1769 | * so then its source MAC and IP as well as its DHCP Client Hardware Address | ||
1770 | * field and DHCP Your IP Address field are added to the local DAT cache and | ||
1771 | * propagated into the DHT. | ||
1772 | * | ||
1773 | * Caller needs to ensure that the skb mac and network headers are set | ||
1774 | * correctly. | ||
1775 | */ | ||
1776 | void batadv_dat_snoop_outgoing_dhcp_ack(struct batadv_priv *bat_priv, | ||
1777 | struct sk_buff *skb, | ||
1778 | __be16 proto, | ||
1779 | unsigned short vid) | ||
1780 | { | ||
1781 | u8 chaddr[BATADV_DHCP_CHADDR_LEN]; | ||
1782 | __be32 ip_src, yiaddr; | ||
1783 | |||
1784 | if (!atomic_read(&bat_priv->distributed_arp_table)) | ||
1785 | return; | ||
1786 | |||
1787 | if (!batadv_dat_check_dhcp_ack(skb, proto, &ip_src, chaddr, &yiaddr)) | ||
1788 | return; | ||
1789 | |||
1790 | batadv_dat_put_dhcp(bat_priv, chaddr, yiaddr, eth_hdr(skb)->h_source, | ||
1791 | ip_src, vid); | ||
1792 | } | ||
1793 | |||
1794 | /** | ||
1795 | * batadv_dat_snoop_incoming_dhcp_ack() - snoop DHCPACK and fill DAT cache | ||
1796 | * @bat_priv: the bat priv with all the soft interface information | ||
1797 | * @skb: the packet to snoop | ||
1798 | * @hdr_size: header size, up to the tail of the batman-adv header | ||
1799 | * | ||
1800 | * This function first checks whether the given skb is a valid DHCPACK. If | ||
1801 | * so then its source MAC and IP as well as its DHCP Client Hardware Address | ||
1802 | * field and DHCP Your IP Address field are added to the local DAT cache. | ||
1803 | */ | ||
1804 | void batadv_dat_snoop_incoming_dhcp_ack(struct batadv_priv *bat_priv, | ||
1805 | struct sk_buff *skb, int hdr_size) | ||
1806 | { | ||
1807 | u8 chaddr[BATADV_DHCP_CHADDR_LEN]; | ||
1808 | struct ethhdr *ethhdr; | ||
1809 | __be32 ip_src, yiaddr; | ||
1810 | unsigned short vid; | ||
1811 | __be16 proto; | ||
1812 | u8 *hw_src; | ||
1813 | |||
1814 | if (!atomic_read(&bat_priv->distributed_arp_table)) | ||
1815 | return; | ||
1816 | |||
1817 | if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN))) | ||
1818 | return; | ||
1819 | |||
1820 | ethhdr = (struct ethhdr *)(skb->data + hdr_size); | ||
1821 | skb_set_network_header(skb, hdr_size + ETH_HLEN); | ||
1822 | proto = ethhdr->h_proto; | ||
1823 | |||
1824 | if (!batadv_dat_check_dhcp_ack(skb, proto, &ip_src, chaddr, &yiaddr)) | ||
1825 | return; | ||
1826 | |||
1827 | hw_src = ethhdr->h_source; | ||
1828 | vid = batadv_dat_get_vid(skb, &hdr_size); | ||
1829 | |||
1830 | batadv_dat_entry_add(bat_priv, yiaddr, chaddr, vid); | ||
1831 | batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid); | ||
1832 | |||
1833 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
1834 | "Snooped from incoming DHCPACK (server address): %pI4, %pM (vid: %i)\n", | ||
1835 | &ip_src, hw_src, batadv_print_vid(vid)); | ||
1836 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
1837 | "Snooped from incoming DHCPACK (client address): %pI4, %pM (vid: %i)\n", | ||
1838 | &yiaddr, chaddr, batadv_print_vid(vid)); | ||
1440 | } | 1839 | } |
1441 | 1840 | ||
1442 | /** | 1841 | /** |
1443 | * batadv_dat_drop_broadcast_packet() - check if an ARP request has to be | 1842 | * batadv_dat_drop_broadcast_packet() - check if an ARP request has to be |
1444 | * dropped (because the node has already obtained the reply via DAT) or not | 1843 | * dropped (because the node has already obtained the reply via DAT) or not |
1445 | * @bat_priv: the bat priv with all the soft interface information | 1844 | * @bat_priv: the bat priv with all the soft interface information |
1446 | * @forw_packet: the broadcast packet | 1845 | * @forw_packet: the broadcast packet |
1447 | * | 1846 | * |
1448 | * Return: true if the node can drop the packet, false otherwise. | 1847 | * Return: true if the node can drop the packet, false otherwise. |
1449 | */ | 1848 | */ |
1450 | bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, | 1849 | bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, |
1451 | struct batadv_forw_packet *forw_packet) | 1850 | struct batadv_forw_packet *forw_packet) |
1452 | { | 1851 | { |
1453 | u16 type; | 1852 | u16 type; |
1454 | __be32 ip_dst; | 1853 | __be32 ip_dst; |
1455 | struct batadv_dat_entry *dat_entry = NULL; | 1854 | struct batadv_dat_entry *dat_entry = NULL; |
1456 | bool ret = false; | 1855 | bool ret = false; |
1457 | int hdr_size = sizeof(struct batadv_bcast_packet); | 1856 | int hdr_size = sizeof(struct batadv_bcast_packet); |
1458 | unsigned short vid; | 1857 | unsigned short vid; |
1459 | 1858 | ||
1460 | if (!atomic_read(&bat_priv->distributed_arp_table)) | 1859 | if (!atomic_read(&bat_priv->distributed_arp_table)) |
1461 | goto out; | 1860 | goto out; |
1462 | 1861 | ||
1463 | /* If this packet is an ARP_REQUEST and the node already has the | 1862 | /* If this packet is an ARP_REQUEST and the node already has the |
1464 | * information that it is going to ask, then the packet can be dropped | 1863 | * information that it is going to ask, then the packet can be dropped |
1465 | */ | 1864 | */ |
1466 | if (batadv_forw_packet_is_rebroadcast(forw_packet)) | 1865 | if (batadv_forw_packet_is_rebroadcast(forw_packet)) |
1467 | goto out; | 1866 | goto out; |
1468 | 1867 | ||
1469 | vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size); | 1868 | vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size); |
1470 | 1869 | ||
1471 | type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size); | 1870 | type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size); |
1472 | if (type != ARPOP_REQUEST) | 1871 | if (type != ARPOP_REQUEST) |
1473 | goto out; | 1872 | goto out; |
1474 | 1873 | ||
1475 | ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size); | 1874 | ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size); |
1476 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid); | 1875 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid); |
1477 | /* check if the node already got this entry */ | 1876 | /* check if the node already got this entry */ |
1478 | if (!dat_entry) { | 1877 | if (!dat_entry) { |
1479 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 1878 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
1480 | "ARP Request for %pI4: fallback\n", &ip_dst); | 1879 | "ARP Request for %pI4: fallback\n", &ip_dst); |
1481 | goto out; | 1880 | goto out; |
1482 | } | 1881 | } |
1483 | 1882 | ||
1484 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | 1883 | batadv_dbg(BATADV_DBG_DAT, bat_priv, |
1485 | "ARP Request for %pI4: fallback prevented\n", &ip_dst); | 1884 | "ARP Request for %pI4: fallback prevented\n", &ip_dst); |
1486 | ret = true; | 1885 | ret = true; |
1487 | 1886 | ||
1488 | out: | 1887 | out: |
1489 | if (dat_entry) | 1888 | if (dat_entry) |
1490 | batadv_dat_entry_put(dat_entry); | 1889 | batadv_dat_entry_put(dat_entry); |
1491 | return ret; | 1890 | return ret; |
1492 | } | 1891 | } |
1493 | 1892 |
net/batman-adv/distributed-arp-table.h
1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors: | 2 | /* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Antonio Quartulli | 4 | * Antonio Quartulli |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 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 | 7 | * modify it under the terms of version 2 of the GNU General Public |
8 | * License as published by the Free Software Foundation. | 8 | * License as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, but | 10 | * This program is distributed in the hope that it will be useful, but |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * General Public License for more details. | 13 | * General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 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/>. | 16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #ifndef _NET_BATMAN_ADV_DISTRIBUTED_ARP_TABLE_H_ | 19 | #ifndef _NET_BATMAN_ADV_DISTRIBUTED_ARP_TABLE_H_ |
20 | #define _NET_BATMAN_ADV_DISTRIBUTED_ARP_TABLE_H_ | 20 | #define _NET_BATMAN_ADV_DISTRIBUTED_ARP_TABLE_H_ |
21 | 21 | ||
22 | #include "main.h" | 22 | #include "main.h" |
23 | 23 | ||
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <uapi/linux/batadv_packet.h> | 27 | #include <uapi/linux/batadv_packet.h> |
28 | 28 | ||
29 | #include "originator.h" | 29 | #include "originator.h" |
30 | 30 | ||
31 | struct netlink_callback; | 31 | struct netlink_callback; |
32 | struct seq_file; | 32 | struct seq_file; |
33 | struct sk_buff; | 33 | struct sk_buff; |
34 | 34 | ||
35 | #ifdef CONFIG_BATMAN_ADV_DAT | 35 | #ifdef CONFIG_BATMAN_ADV_DAT |
36 | 36 | ||
37 | /* BATADV_DAT_ADDR_MAX - maximum address value in the DHT space */ | 37 | /* BATADV_DAT_ADDR_MAX - maximum address value in the DHT space */ |
38 | #define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0) | 38 | #define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0) |
39 | 39 | ||
40 | void batadv_dat_status_update(struct net_device *net_dev); | 40 | void batadv_dat_status_update(struct net_device *net_dev); |
41 | bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | 41 | bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, |
42 | struct sk_buff *skb); | 42 | struct sk_buff *skb); |
43 | bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, | 43 | bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, |
44 | struct sk_buff *skb, int hdr_size); | 44 | struct sk_buff *skb, int hdr_size); |
45 | void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, | 45 | void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, |
46 | struct sk_buff *skb); | 46 | struct sk_buff *skb); |
47 | bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, | 47 | bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, |
48 | struct sk_buff *skb, int hdr_size); | 48 | struct sk_buff *skb, int hdr_size); |
49 | void batadv_dat_snoop_outgoing_dhcp_ack(struct batadv_priv *bat_priv, | ||
50 | struct sk_buff *skb, | ||
51 | __be16 proto, | ||
52 | unsigned short vid); | ||
53 | void batadv_dat_snoop_incoming_dhcp_ack(struct batadv_priv *bat_priv, | ||
54 | struct sk_buff *skb, int hdr_size); | ||
49 | bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, | 55 | bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, |
50 | struct batadv_forw_packet *forw_packet); | 56 | struct batadv_forw_packet *forw_packet); |
51 | 57 | ||
52 | /** | 58 | /** |
53 | * batadv_dat_init_orig_node_addr() - assign a DAT address to the orig_node | 59 | * batadv_dat_init_orig_node_addr() - assign a DAT address to the orig_node |
54 | * @orig_node: the node to assign the DAT address to | 60 | * @orig_node: the node to assign the DAT address to |
55 | */ | 61 | */ |
56 | static inline void | 62 | static inline void |
57 | batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node) | 63 | batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node) |
58 | { | 64 | { |
59 | u32 addr; | 65 | u32 addr; |
60 | 66 | ||
61 | addr = batadv_choose_orig(orig_node->orig, BATADV_DAT_ADDR_MAX); | 67 | addr = batadv_choose_orig(orig_node->orig, BATADV_DAT_ADDR_MAX); |
62 | orig_node->dat_addr = (batadv_dat_addr_t)addr; | 68 | orig_node->dat_addr = (batadv_dat_addr_t)addr; |
63 | } | 69 | } |
64 | 70 | ||
65 | /** | 71 | /** |
66 | * batadv_dat_init_own_addr() - assign a DAT address to the node itself | 72 | * batadv_dat_init_own_addr() - assign a DAT address to the node itself |
67 | * @bat_priv: the bat priv with all the soft interface information | 73 | * @bat_priv: the bat priv with all the soft interface information |
68 | * @primary_if: a pointer to the primary interface | 74 | * @primary_if: a pointer to the primary interface |
69 | */ | 75 | */ |
70 | static inline void | 76 | static inline void |
71 | batadv_dat_init_own_addr(struct batadv_priv *bat_priv, | 77 | batadv_dat_init_own_addr(struct batadv_priv *bat_priv, |
72 | struct batadv_hard_iface *primary_if) | 78 | struct batadv_hard_iface *primary_if) |
73 | { | 79 | { |
74 | u32 addr; | 80 | u32 addr; |
75 | 81 | ||
76 | addr = batadv_choose_orig(primary_if->net_dev->dev_addr, | 82 | addr = batadv_choose_orig(primary_if->net_dev->dev_addr, |
77 | BATADV_DAT_ADDR_MAX); | 83 | BATADV_DAT_ADDR_MAX); |
78 | 84 | ||
79 | bat_priv->dat.addr = (batadv_dat_addr_t)addr; | 85 | bat_priv->dat.addr = (batadv_dat_addr_t)addr; |
80 | } | 86 | } |
81 | 87 | ||
82 | int batadv_dat_init(struct batadv_priv *bat_priv); | 88 | int batadv_dat_init(struct batadv_priv *bat_priv); |
83 | void batadv_dat_free(struct batadv_priv *bat_priv); | 89 | void batadv_dat_free(struct batadv_priv *bat_priv); |
84 | int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset); | 90 | int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset); |
85 | int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb); | 91 | int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb); |
86 | 92 | ||
87 | /** | 93 | /** |
88 | * batadv_dat_inc_counter() - increment the correct DAT packet counter | 94 | * batadv_dat_inc_counter() - increment the correct DAT packet counter |
89 | * @bat_priv: the bat priv with all the soft interface information | 95 | * @bat_priv: the bat priv with all the soft interface information |
90 | * @subtype: the 4addr subtype of the packet to be counted | 96 | * @subtype: the 4addr subtype of the packet to be counted |
91 | * | 97 | * |
92 | * Updates the ethtool statistics for the received packet if it is a DAT subtype | 98 | * Updates the ethtool statistics for the received packet if it is a DAT subtype |
93 | */ | 99 | */ |
94 | static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, | 100 | static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, |
95 | u8 subtype) | 101 | u8 subtype) |
96 | { | 102 | { |
97 | switch (subtype) { | 103 | switch (subtype) { |
98 | case BATADV_P_DAT_DHT_GET: | 104 | case BATADV_P_DAT_DHT_GET: |
99 | batadv_inc_counter(bat_priv, | 105 | batadv_inc_counter(bat_priv, |
100 | BATADV_CNT_DAT_GET_RX); | 106 | BATADV_CNT_DAT_GET_RX); |
101 | break; | 107 | break; |
102 | case BATADV_P_DAT_DHT_PUT: | 108 | case BATADV_P_DAT_DHT_PUT: |
103 | batadv_inc_counter(bat_priv, | 109 | batadv_inc_counter(bat_priv, |
104 | BATADV_CNT_DAT_PUT_RX); | 110 | BATADV_CNT_DAT_PUT_RX); |
105 | break; | 111 | break; |
106 | } | 112 | } |
107 | } | 113 | } |
108 | 114 | ||
109 | #else | 115 | #else |
110 | 116 | ||
111 | static inline void batadv_dat_status_update(struct net_device *net_dev) | 117 | static inline void batadv_dat_status_update(struct net_device *net_dev) |
112 | { | 118 | { |
113 | } | 119 | } |
114 | 120 | ||
115 | static inline bool | 121 | static inline bool |
116 | batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | 122 | batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, |
117 | struct sk_buff *skb) | 123 | struct sk_buff *skb) |
118 | { | 124 | { |
119 | return false; | 125 | return false; |
120 | } | 126 | } |
121 | 127 | ||
122 | static inline bool | 128 | static inline bool |
123 | batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, | 129 | batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, |
124 | struct sk_buff *skb, int hdr_size) | 130 | struct sk_buff *skb, int hdr_size) |
125 | { | 131 | { |
126 | return false; | 132 | return false; |
127 | } | 133 | } |
128 | 134 | ||
129 | static inline bool | 135 | static inline bool |
130 | batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, | 136 | batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, |
131 | struct sk_buff *skb) | 137 | struct sk_buff *skb) |
132 | { | 138 | { |
133 | return false; | 139 | return false; |
134 | } | 140 | } |
135 | 141 | ||
136 | static inline bool | 142 | static inline bool |
137 | batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, | 143 | batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, |
138 | struct sk_buff *skb, int hdr_size) | 144 | struct sk_buff *skb, int hdr_size) |
139 | { | 145 | { |
140 | return false; | 146 | return false; |
147 | } | ||
148 | |||
149 | static inline void | ||
150 | batadv_dat_snoop_outgoing_dhcp_ack(struct batadv_priv *bat_priv, | ||
151 | struct sk_buff *skb, __be16 proto, | ||
152 | unsigned short vid) | ||
153 | { | ||
154 | } | ||
155 | |||
156 | static inline void | ||
157 | batadv_dat_snoop_incoming_dhcp_ack(struct batadv_priv *bat_priv, | ||
158 | struct sk_buff *skb, int hdr_size) | ||
159 | { | ||
141 | } | 160 | } |
142 | 161 | ||
143 | static inline bool | 162 | static inline bool |
144 | batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, | 163 | batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, |
145 | struct batadv_forw_packet *forw_packet) | 164 | struct batadv_forw_packet *forw_packet) |
146 | { | 165 | { |
147 | return false; | 166 | return false; |
148 | } | 167 | } |
149 | 168 | ||
150 | static inline void | 169 | static inline void |
151 | batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node) | 170 | batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node) |
152 | { | 171 | { |
153 | } | 172 | } |
154 | 173 | ||
155 | static inline void batadv_dat_init_own_addr(struct batadv_priv *bat_priv, | 174 | static inline void batadv_dat_init_own_addr(struct batadv_priv *bat_priv, |
156 | struct batadv_hard_iface *iface) | 175 | struct batadv_hard_iface *iface) |
157 | { | 176 | { |
158 | } | 177 | } |
159 | 178 | ||
160 | static inline void batadv_arp_change_timeout(struct net_device *soft_iface, | 179 | static inline void batadv_arp_change_timeout(struct net_device *soft_iface, |
161 | const char *name) | 180 | const char *name) |
162 | { | 181 | { |
163 | } | 182 | } |
164 | 183 | ||
165 | static inline int batadv_dat_init(struct batadv_priv *bat_priv) | 184 | static inline int batadv_dat_init(struct batadv_priv *bat_priv) |
166 | { | 185 | { |
167 | return 0; | 186 | return 0; |
168 | } | 187 | } |
169 | 188 | ||
170 | static inline void batadv_dat_free(struct batadv_priv *bat_priv) | 189 | static inline void batadv_dat_free(struct batadv_priv *bat_priv) |
171 | { | 190 | { |
172 | } | 191 | } |
173 | 192 | ||
174 | static inline int | 193 | static inline int |
175 | batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb) | 194 | batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb) |
176 | { | 195 | { |
177 | return -EOPNOTSUPP; | 196 | return -EOPNOTSUPP; |
178 | } | 197 | } |
179 | 198 | ||
180 | static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, | 199 | static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, |
181 | u8 subtype) | 200 | u8 subtype) |
182 | { | 201 | { |
183 | } | 202 | } |
184 | 203 | ||
185 | #endif /* CONFIG_BATMAN_ADV_DAT */ | 204 | #endif /* CONFIG_BATMAN_ADV_DAT */ |
186 | 205 | ||
187 | #endif /* _NET_BATMAN_ADV_DISTRIBUTED_ARP_TABLE_H_ */ | 206 | #endif /* _NET_BATMAN_ADV_DISTRIBUTED_ARP_TABLE_H_ */ |
188 | 207 |
net/batman-adv/routing.c
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: | 2 | /* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Marek Lindner, Simon Wunderlich | 4 | * Marek Lindner, Simon Wunderlich |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 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 | 7 | * modify it under the terms of version 2 of the GNU General Public |
8 | * License as published by the Free Software Foundation. | 8 | * License as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, but | 10 | * This program is distributed in the hope that it will be useful, but |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * General Public License for more details. | 13 | * General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 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/>. | 16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "routing.h" | 19 | #include "routing.h" |
20 | #include "main.h" | 20 | #include "main.h" |
21 | 21 | ||
22 | #include <linux/atomic.h> | 22 | #include <linux/atomic.h> |
23 | #include <linux/byteorder/generic.h> | 23 | #include <linux/byteorder/generic.h> |
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
27 | #include <linux/if_ether.h> | 27 | #include <linux/if_ether.h> |
28 | #include <linux/jiffies.h> | 28 | #include <linux/jiffies.h> |
29 | #include <linux/kref.h> | 29 | #include <linux/kref.h> |
30 | #include <linux/netdevice.h> | 30 | #include <linux/netdevice.h> |
31 | #include <linux/printk.h> | 31 | #include <linux/printk.h> |
32 | #include <linux/rculist.h> | 32 | #include <linux/rculist.h> |
33 | #include <linux/rcupdate.h> | 33 | #include <linux/rcupdate.h> |
34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/stddef.h> | 36 | #include <linux/stddef.h> |
37 | #include <uapi/linux/batadv_packet.h> | 37 | #include <uapi/linux/batadv_packet.h> |
38 | 38 | ||
39 | #include "bitarray.h" | 39 | #include "bitarray.h" |
40 | #include "bridge_loop_avoidance.h" | 40 | #include "bridge_loop_avoidance.h" |
41 | #include "distributed-arp-table.h" | 41 | #include "distributed-arp-table.h" |
42 | #include "fragmentation.h" | 42 | #include "fragmentation.h" |
43 | #include "hard-interface.h" | 43 | #include "hard-interface.h" |
44 | #include "icmp_socket.h" | 44 | #include "icmp_socket.h" |
45 | #include "log.h" | 45 | #include "log.h" |
46 | #include "network-coding.h" | 46 | #include "network-coding.h" |
47 | #include "originator.h" | 47 | #include "originator.h" |
48 | #include "send.h" | 48 | #include "send.h" |
49 | #include "soft-interface.h" | 49 | #include "soft-interface.h" |
50 | #include "tp_meter.h" | 50 | #include "tp_meter.h" |
51 | #include "translation-table.h" | 51 | #include "translation-table.h" |
52 | #include "tvlv.h" | 52 | #include "tvlv.h" |
53 | 53 | ||
54 | static int batadv_route_unicast_packet(struct sk_buff *skb, | 54 | static int batadv_route_unicast_packet(struct sk_buff *skb, |
55 | struct batadv_hard_iface *recv_if); | 55 | struct batadv_hard_iface *recv_if); |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * _batadv_update_route() - set the router for this originator | 58 | * _batadv_update_route() - set the router for this originator |
59 | * @bat_priv: the bat priv with all the soft interface information | 59 | * @bat_priv: the bat priv with all the soft interface information |
60 | * @orig_node: orig node which is to be configured | 60 | * @orig_node: orig node which is to be configured |
61 | * @recv_if: the receive interface for which this route is set | 61 | * @recv_if: the receive interface for which this route is set |
62 | * @neigh_node: neighbor which should be the next router | 62 | * @neigh_node: neighbor which should be the next router |
63 | * | 63 | * |
64 | * This function does not perform any error checks | 64 | * This function does not perform any error checks |
65 | */ | 65 | */ |
66 | static void _batadv_update_route(struct batadv_priv *bat_priv, | 66 | static void _batadv_update_route(struct batadv_priv *bat_priv, |
67 | struct batadv_orig_node *orig_node, | 67 | struct batadv_orig_node *orig_node, |
68 | struct batadv_hard_iface *recv_if, | 68 | struct batadv_hard_iface *recv_if, |
69 | struct batadv_neigh_node *neigh_node) | 69 | struct batadv_neigh_node *neigh_node) |
70 | { | 70 | { |
71 | struct batadv_orig_ifinfo *orig_ifinfo; | 71 | struct batadv_orig_ifinfo *orig_ifinfo; |
72 | struct batadv_neigh_node *curr_router; | 72 | struct batadv_neigh_node *curr_router; |
73 | 73 | ||
74 | orig_ifinfo = batadv_orig_ifinfo_get(orig_node, recv_if); | 74 | orig_ifinfo = batadv_orig_ifinfo_get(orig_node, recv_if); |
75 | if (!orig_ifinfo) | 75 | if (!orig_ifinfo) |
76 | return; | 76 | return; |
77 | 77 | ||
78 | spin_lock_bh(&orig_node->neigh_list_lock); | 78 | spin_lock_bh(&orig_node->neigh_list_lock); |
79 | /* curr_router used earlier may not be the current orig_ifinfo->router | 79 | /* curr_router used earlier may not be the current orig_ifinfo->router |
80 | * anymore because it was dereferenced outside of the neigh_list_lock | 80 | * anymore because it was dereferenced outside of the neigh_list_lock |
81 | * protected region. After the new best neighbor has replace the current | 81 | * protected region. After the new best neighbor has replace the current |
82 | * best neighbor the reference counter needs to decrease. Consequently, | 82 | * best neighbor the reference counter needs to decrease. Consequently, |
83 | * the code needs to ensure the curr_router variable contains a pointer | 83 | * the code needs to ensure the curr_router variable contains a pointer |
84 | * to the replaced best neighbor. | 84 | * to the replaced best neighbor. |
85 | */ | 85 | */ |
86 | curr_router = rcu_dereference_protected(orig_ifinfo->router, true); | 86 | curr_router = rcu_dereference_protected(orig_ifinfo->router, true); |
87 | 87 | ||
88 | /* increase refcount of new best neighbor */ | 88 | /* increase refcount of new best neighbor */ |
89 | if (neigh_node) | 89 | if (neigh_node) |
90 | kref_get(&neigh_node->refcount); | 90 | kref_get(&neigh_node->refcount); |
91 | 91 | ||
92 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); | 92 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); |
93 | spin_unlock_bh(&orig_node->neigh_list_lock); | 93 | spin_unlock_bh(&orig_node->neigh_list_lock); |
94 | batadv_orig_ifinfo_put(orig_ifinfo); | 94 | batadv_orig_ifinfo_put(orig_ifinfo); |
95 | 95 | ||
96 | /* route deleted */ | 96 | /* route deleted */ |
97 | if (curr_router && !neigh_node) { | 97 | if (curr_router && !neigh_node) { |
98 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, | 98 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, |
99 | "Deleting route towards: %pM\n", orig_node->orig); | 99 | "Deleting route towards: %pM\n", orig_node->orig); |
100 | batadv_tt_global_del_orig(bat_priv, orig_node, -1, | 100 | batadv_tt_global_del_orig(bat_priv, orig_node, -1, |
101 | "Deleted route towards originator"); | 101 | "Deleted route towards originator"); |
102 | 102 | ||
103 | /* route added */ | 103 | /* route added */ |
104 | } else if (!curr_router && neigh_node) { | 104 | } else if (!curr_router && neigh_node) { |
105 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, | 105 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, |
106 | "Adding route towards: %pM (via %pM)\n", | 106 | "Adding route towards: %pM (via %pM)\n", |
107 | orig_node->orig, neigh_node->addr); | 107 | orig_node->orig, neigh_node->addr); |
108 | /* route changed */ | 108 | /* route changed */ |
109 | } else if (neigh_node && curr_router) { | 109 | } else if (neigh_node && curr_router) { |
110 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, | 110 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, |
111 | "Changing route towards: %pM (now via %pM - was via %pM)\n", | 111 | "Changing route towards: %pM (now via %pM - was via %pM)\n", |
112 | orig_node->orig, neigh_node->addr, | 112 | orig_node->orig, neigh_node->addr, |
113 | curr_router->addr); | 113 | curr_router->addr); |
114 | } | 114 | } |
115 | 115 | ||
116 | /* decrease refcount of previous best neighbor */ | 116 | /* decrease refcount of previous best neighbor */ |
117 | if (curr_router) | 117 | if (curr_router) |
118 | batadv_neigh_node_put(curr_router); | 118 | batadv_neigh_node_put(curr_router); |
119 | } | 119 | } |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * batadv_update_route() - set the router for this originator | 122 | * batadv_update_route() - set the router for this originator |
123 | * @bat_priv: the bat priv with all the soft interface information | 123 | * @bat_priv: the bat priv with all the soft interface information |
124 | * @orig_node: orig node which is to be configured | 124 | * @orig_node: orig node which is to be configured |
125 | * @recv_if: the receive interface for which this route is set | 125 | * @recv_if: the receive interface for which this route is set |
126 | * @neigh_node: neighbor which should be the next router | 126 | * @neigh_node: neighbor which should be the next router |
127 | */ | 127 | */ |
128 | void batadv_update_route(struct batadv_priv *bat_priv, | 128 | void batadv_update_route(struct batadv_priv *bat_priv, |
129 | struct batadv_orig_node *orig_node, | 129 | struct batadv_orig_node *orig_node, |
130 | struct batadv_hard_iface *recv_if, | 130 | struct batadv_hard_iface *recv_if, |
131 | struct batadv_neigh_node *neigh_node) | 131 | struct batadv_neigh_node *neigh_node) |
132 | { | 132 | { |
133 | struct batadv_neigh_node *router = NULL; | 133 | struct batadv_neigh_node *router = NULL; |
134 | 134 | ||
135 | if (!orig_node) | 135 | if (!orig_node) |
136 | goto out; | 136 | goto out; |
137 | 137 | ||
138 | router = batadv_orig_router_get(orig_node, recv_if); | 138 | router = batadv_orig_router_get(orig_node, recv_if); |
139 | 139 | ||
140 | if (router != neigh_node) | 140 | if (router != neigh_node) |
141 | _batadv_update_route(bat_priv, orig_node, recv_if, neigh_node); | 141 | _batadv_update_route(bat_priv, orig_node, recv_if, neigh_node); |
142 | 142 | ||
143 | out: | 143 | out: |
144 | if (router) | 144 | if (router) |
145 | batadv_neigh_node_put(router); | 145 | batadv_neigh_node_put(router); |
146 | } | 146 | } |
147 | 147 | ||
148 | /** | 148 | /** |
149 | * batadv_window_protected() - checks whether the host restarted and is in the | 149 | * batadv_window_protected() - checks whether the host restarted and is in the |
150 | * protection time. | 150 | * protection time. |
151 | * @bat_priv: the bat priv with all the soft interface information | 151 | * @bat_priv: the bat priv with all the soft interface information |
152 | * @seq_num_diff: difference between the current/received sequence number and | 152 | * @seq_num_diff: difference between the current/received sequence number and |
153 | * the last sequence number | 153 | * the last sequence number |
154 | * @seq_old_max_diff: maximum age of sequence number not considered as restart | 154 | * @seq_old_max_diff: maximum age of sequence number not considered as restart |
155 | * @last_reset: jiffies timestamp of the last reset, will be updated when reset | 155 | * @last_reset: jiffies timestamp of the last reset, will be updated when reset |
156 | * is detected | 156 | * is detected |
157 | * @protection_started: is set to true if the protection window was started, | 157 | * @protection_started: is set to true if the protection window was started, |
158 | * doesn't change otherwise. | 158 | * doesn't change otherwise. |
159 | * | 159 | * |
160 | * Return: | 160 | * Return: |
161 | * false if the packet is to be accepted. | 161 | * false if the packet is to be accepted. |
162 | * true if the packet is to be ignored. | 162 | * true if the packet is to be ignored. |
163 | */ | 163 | */ |
164 | bool batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, | 164 | bool batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, |
165 | s32 seq_old_max_diff, unsigned long *last_reset, | 165 | s32 seq_old_max_diff, unsigned long *last_reset, |
166 | bool *protection_started) | 166 | bool *protection_started) |
167 | { | 167 | { |
168 | if (seq_num_diff <= -seq_old_max_diff || | 168 | if (seq_num_diff <= -seq_old_max_diff || |
169 | seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { | 169 | seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { |
170 | if (!batadv_has_timed_out(*last_reset, | 170 | if (!batadv_has_timed_out(*last_reset, |
171 | BATADV_RESET_PROTECTION_MS)) | 171 | BATADV_RESET_PROTECTION_MS)) |
172 | return true; | 172 | return true; |
173 | 173 | ||
174 | *last_reset = jiffies; | 174 | *last_reset = jiffies; |
175 | if (protection_started) | 175 | if (protection_started) |
176 | *protection_started = true; | 176 | *protection_started = true; |
177 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 177 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
178 | "old packet received, start protection\n"); | 178 | "old packet received, start protection\n"); |
179 | } | 179 | } |
180 | 180 | ||
181 | return false; | 181 | return false; |
182 | } | 182 | } |
183 | 183 | ||
184 | /** | 184 | /** |
185 | * batadv_check_management_packet() - Check preconditions for management packets | 185 | * batadv_check_management_packet() - Check preconditions for management packets |
186 | * @skb: incoming packet buffer | 186 | * @skb: incoming packet buffer |
187 | * @hard_iface: incoming hard interface | 187 | * @hard_iface: incoming hard interface |
188 | * @header_len: minimal header length of packet type | 188 | * @header_len: minimal header length of packet type |
189 | * | 189 | * |
190 | * Return: true when management preconditions are met, false otherwise | 190 | * Return: true when management preconditions are met, false otherwise |
191 | */ | 191 | */ |
192 | bool batadv_check_management_packet(struct sk_buff *skb, | 192 | bool batadv_check_management_packet(struct sk_buff *skb, |
193 | struct batadv_hard_iface *hard_iface, | 193 | struct batadv_hard_iface *hard_iface, |
194 | int header_len) | 194 | int header_len) |
195 | { | 195 | { |
196 | struct ethhdr *ethhdr; | 196 | struct ethhdr *ethhdr; |
197 | 197 | ||
198 | /* drop packet if it has not necessary minimum size */ | 198 | /* drop packet if it has not necessary minimum size */ |
199 | if (unlikely(!pskb_may_pull(skb, header_len))) | 199 | if (unlikely(!pskb_may_pull(skb, header_len))) |
200 | return false; | 200 | return false; |
201 | 201 | ||
202 | ethhdr = eth_hdr(skb); | 202 | ethhdr = eth_hdr(skb); |
203 | 203 | ||
204 | /* packet with broadcast indication but unicast recipient */ | 204 | /* packet with broadcast indication but unicast recipient */ |
205 | if (!is_broadcast_ether_addr(ethhdr->h_dest)) | 205 | if (!is_broadcast_ether_addr(ethhdr->h_dest)) |
206 | return false; | 206 | return false; |
207 | 207 | ||
208 | /* packet with invalid sender address */ | 208 | /* packet with invalid sender address */ |
209 | if (!is_valid_ether_addr(ethhdr->h_source)) | 209 | if (!is_valid_ether_addr(ethhdr->h_source)) |
210 | return false; | 210 | return false; |
211 | 211 | ||
212 | /* create a copy of the skb, if needed, to modify it. */ | 212 | /* create a copy of the skb, if needed, to modify it. */ |
213 | if (skb_cow(skb, 0) < 0) | 213 | if (skb_cow(skb, 0) < 0) |
214 | return false; | 214 | return false; |
215 | 215 | ||
216 | /* keep skb linear */ | 216 | /* keep skb linear */ |
217 | if (skb_linearize(skb) < 0) | 217 | if (skb_linearize(skb) < 0) |
218 | return false; | 218 | return false; |
219 | 219 | ||
220 | return true; | 220 | return true; |
221 | } | 221 | } |
222 | 222 | ||
223 | /** | 223 | /** |
224 | * batadv_recv_my_icmp_packet() - receive an icmp packet locally | 224 | * batadv_recv_my_icmp_packet() - receive an icmp packet locally |
225 | * @bat_priv: the bat priv with all the soft interface information | 225 | * @bat_priv: the bat priv with all the soft interface information |
226 | * @skb: icmp packet to process | 226 | * @skb: icmp packet to process |
227 | * | 227 | * |
228 | * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP | 228 | * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP |
229 | * otherwise. | 229 | * otherwise. |
230 | */ | 230 | */ |
231 | static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, | 231 | static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, |
232 | struct sk_buff *skb) | 232 | struct sk_buff *skb) |
233 | { | 233 | { |
234 | struct batadv_hard_iface *primary_if = NULL; | 234 | struct batadv_hard_iface *primary_if = NULL; |
235 | struct batadv_orig_node *orig_node = NULL; | 235 | struct batadv_orig_node *orig_node = NULL; |
236 | struct batadv_icmp_header *icmph; | 236 | struct batadv_icmp_header *icmph; |
237 | int res, ret = NET_RX_DROP; | 237 | int res, ret = NET_RX_DROP; |
238 | 238 | ||
239 | icmph = (struct batadv_icmp_header *)skb->data; | 239 | icmph = (struct batadv_icmp_header *)skb->data; |
240 | 240 | ||
241 | switch (icmph->msg_type) { | 241 | switch (icmph->msg_type) { |
242 | case BATADV_ECHO_REPLY: | 242 | case BATADV_ECHO_REPLY: |
243 | case BATADV_DESTINATION_UNREACHABLE: | 243 | case BATADV_DESTINATION_UNREACHABLE: |
244 | case BATADV_TTL_EXCEEDED: | 244 | case BATADV_TTL_EXCEEDED: |
245 | /* receive the packet */ | 245 | /* receive the packet */ |
246 | if (skb_linearize(skb) < 0) | 246 | if (skb_linearize(skb) < 0) |
247 | break; | 247 | break; |
248 | 248 | ||
249 | batadv_socket_receive_packet(icmph, skb->len); | 249 | batadv_socket_receive_packet(icmph, skb->len); |
250 | break; | 250 | break; |
251 | case BATADV_ECHO_REQUEST: | 251 | case BATADV_ECHO_REQUEST: |
252 | /* answer echo request (ping) */ | 252 | /* answer echo request (ping) */ |
253 | primary_if = batadv_primary_if_get_selected(bat_priv); | 253 | primary_if = batadv_primary_if_get_selected(bat_priv); |
254 | if (!primary_if) | 254 | if (!primary_if) |
255 | goto out; | 255 | goto out; |
256 | 256 | ||
257 | /* get routing information */ | 257 | /* get routing information */ |
258 | orig_node = batadv_orig_hash_find(bat_priv, icmph->orig); | 258 | orig_node = batadv_orig_hash_find(bat_priv, icmph->orig); |
259 | if (!orig_node) | 259 | if (!orig_node) |
260 | goto out; | 260 | goto out; |
261 | 261 | ||
262 | /* create a copy of the skb, if needed, to modify it. */ | 262 | /* create a copy of the skb, if needed, to modify it. */ |
263 | if (skb_cow(skb, ETH_HLEN) < 0) | 263 | if (skb_cow(skb, ETH_HLEN) < 0) |
264 | goto out; | 264 | goto out; |
265 | 265 | ||
266 | icmph = (struct batadv_icmp_header *)skb->data; | 266 | icmph = (struct batadv_icmp_header *)skb->data; |
267 | 267 | ||
268 | ether_addr_copy(icmph->dst, icmph->orig); | 268 | ether_addr_copy(icmph->dst, icmph->orig); |
269 | ether_addr_copy(icmph->orig, primary_if->net_dev->dev_addr); | 269 | ether_addr_copy(icmph->orig, primary_if->net_dev->dev_addr); |
270 | icmph->msg_type = BATADV_ECHO_REPLY; | 270 | icmph->msg_type = BATADV_ECHO_REPLY; |
271 | icmph->ttl = BATADV_TTL; | 271 | icmph->ttl = BATADV_TTL; |
272 | 272 | ||
273 | res = batadv_send_skb_to_orig(skb, orig_node, NULL); | 273 | res = batadv_send_skb_to_orig(skb, orig_node, NULL); |
274 | if (res == NET_XMIT_SUCCESS) | 274 | if (res == NET_XMIT_SUCCESS) |
275 | ret = NET_RX_SUCCESS; | 275 | ret = NET_RX_SUCCESS; |
276 | 276 | ||
277 | /* skb was consumed */ | 277 | /* skb was consumed */ |
278 | skb = NULL; | 278 | skb = NULL; |
279 | break; | 279 | break; |
280 | case BATADV_TP: | 280 | case BATADV_TP: |
281 | if (!pskb_may_pull(skb, sizeof(struct batadv_icmp_tp_packet))) | 281 | if (!pskb_may_pull(skb, sizeof(struct batadv_icmp_tp_packet))) |
282 | goto out; | 282 | goto out; |
283 | 283 | ||
284 | batadv_tp_meter_recv(bat_priv, skb); | 284 | batadv_tp_meter_recv(bat_priv, skb); |
285 | ret = NET_RX_SUCCESS; | 285 | ret = NET_RX_SUCCESS; |
286 | /* skb was consumed */ | 286 | /* skb was consumed */ |
287 | skb = NULL; | 287 | skb = NULL; |
288 | goto out; | 288 | goto out; |
289 | default: | 289 | default: |
290 | /* drop unknown type */ | 290 | /* drop unknown type */ |
291 | goto out; | 291 | goto out; |
292 | } | 292 | } |
293 | out: | 293 | out: |
294 | if (primary_if) | 294 | if (primary_if) |
295 | batadv_hardif_put(primary_if); | 295 | batadv_hardif_put(primary_if); |
296 | if (orig_node) | 296 | if (orig_node) |
297 | batadv_orig_node_put(orig_node); | 297 | batadv_orig_node_put(orig_node); |
298 | 298 | ||
299 | kfree_skb(skb); | 299 | kfree_skb(skb); |
300 | 300 | ||
301 | return ret; | 301 | return ret; |
302 | } | 302 | } |
303 | 303 | ||
304 | static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, | 304 | static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, |
305 | struct sk_buff *skb) | 305 | struct sk_buff *skb) |
306 | { | 306 | { |
307 | struct batadv_hard_iface *primary_if = NULL; | 307 | struct batadv_hard_iface *primary_if = NULL; |
308 | struct batadv_orig_node *orig_node = NULL; | 308 | struct batadv_orig_node *orig_node = NULL; |
309 | struct batadv_icmp_packet *icmp_packet; | 309 | struct batadv_icmp_packet *icmp_packet; |
310 | int res, ret = NET_RX_DROP; | 310 | int res, ret = NET_RX_DROP; |
311 | 311 | ||
312 | icmp_packet = (struct batadv_icmp_packet *)skb->data; | 312 | icmp_packet = (struct batadv_icmp_packet *)skb->data; |
313 | 313 | ||
314 | /* send TTL exceeded if packet is an echo request (traceroute) */ | 314 | /* send TTL exceeded if packet is an echo request (traceroute) */ |
315 | if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { | 315 | if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { |
316 | pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", | 316 | pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", |
317 | icmp_packet->orig, icmp_packet->dst); | 317 | icmp_packet->orig, icmp_packet->dst); |
318 | goto out; | 318 | goto out; |
319 | } | 319 | } |
320 | 320 | ||
321 | primary_if = batadv_primary_if_get_selected(bat_priv); | 321 | primary_if = batadv_primary_if_get_selected(bat_priv); |
322 | if (!primary_if) | 322 | if (!primary_if) |
323 | goto out; | 323 | goto out; |
324 | 324 | ||
325 | /* get routing information */ | 325 | /* get routing information */ |
326 | orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); | 326 | orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); |
327 | if (!orig_node) | 327 | if (!orig_node) |
328 | goto out; | 328 | goto out; |
329 | 329 | ||
330 | /* create a copy of the skb, if needed, to modify it. */ | 330 | /* create a copy of the skb, if needed, to modify it. */ |
331 | if (skb_cow(skb, ETH_HLEN) < 0) | 331 | if (skb_cow(skb, ETH_HLEN) < 0) |
332 | goto out; | 332 | goto out; |
333 | 333 | ||
334 | icmp_packet = (struct batadv_icmp_packet *)skb->data; | 334 | icmp_packet = (struct batadv_icmp_packet *)skb->data; |
335 | 335 | ||
336 | ether_addr_copy(icmp_packet->dst, icmp_packet->orig); | 336 | ether_addr_copy(icmp_packet->dst, icmp_packet->orig); |
337 | ether_addr_copy(icmp_packet->orig, primary_if->net_dev->dev_addr); | 337 | ether_addr_copy(icmp_packet->orig, primary_if->net_dev->dev_addr); |
338 | icmp_packet->msg_type = BATADV_TTL_EXCEEDED; | 338 | icmp_packet->msg_type = BATADV_TTL_EXCEEDED; |
339 | icmp_packet->ttl = BATADV_TTL; | 339 | icmp_packet->ttl = BATADV_TTL; |
340 | 340 | ||
341 | res = batadv_send_skb_to_orig(skb, orig_node, NULL); | 341 | res = batadv_send_skb_to_orig(skb, orig_node, NULL); |
342 | if (res == NET_RX_SUCCESS) | 342 | if (res == NET_RX_SUCCESS) |
343 | ret = NET_XMIT_SUCCESS; | 343 | ret = NET_XMIT_SUCCESS; |
344 | 344 | ||
345 | /* skb was consumed */ | 345 | /* skb was consumed */ |
346 | skb = NULL; | 346 | skb = NULL; |
347 | 347 | ||
348 | out: | 348 | out: |
349 | if (primary_if) | 349 | if (primary_if) |
350 | batadv_hardif_put(primary_if); | 350 | batadv_hardif_put(primary_if); |
351 | if (orig_node) | 351 | if (orig_node) |
352 | batadv_orig_node_put(orig_node); | 352 | batadv_orig_node_put(orig_node); |
353 | 353 | ||
354 | kfree_skb(skb); | 354 | kfree_skb(skb); |
355 | 355 | ||
356 | return ret; | 356 | return ret; |
357 | } | 357 | } |
358 | 358 | ||
359 | /** | 359 | /** |
360 | * batadv_recv_icmp_packet() - Process incoming icmp packet | 360 | * batadv_recv_icmp_packet() - Process incoming icmp packet |
361 | * @skb: incoming packet buffer | 361 | * @skb: incoming packet buffer |
362 | * @recv_if: incoming hard interface | 362 | * @recv_if: incoming hard interface |
363 | * | 363 | * |
364 | * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure | 364 | * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure |
365 | */ | 365 | */ |
366 | int batadv_recv_icmp_packet(struct sk_buff *skb, | 366 | int batadv_recv_icmp_packet(struct sk_buff *skb, |
367 | struct batadv_hard_iface *recv_if) | 367 | struct batadv_hard_iface *recv_if) |
368 | { | 368 | { |
369 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 369 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
370 | struct batadv_icmp_header *icmph; | 370 | struct batadv_icmp_header *icmph; |
371 | struct batadv_icmp_packet_rr *icmp_packet_rr; | 371 | struct batadv_icmp_packet_rr *icmp_packet_rr; |
372 | struct ethhdr *ethhdr; | 372 | struct ethhdr *ethhdr; |
373 | struct batadv_orig_node *orig_node = NULL; | 373 | struct batadv_orig_node *orig_node = NULL; |
374 | int hdr_size = sizeof(struct batadv_icmp_header); | 374 | int hdr_size = sizeof(struct batadv_icmp_header); |
375 | int res, ret = NET_RX_DROP; | 375 | int res, ret = NET_RX_DROP; |
376 | 376 | ||
377 | /* drop packet if it has not necessary minimum size */ | 377 | /* drop packet if it has not necessary minimum size */ |
378 | if (unlikely(!pskb_may_pull(skb, hdr_size))) | 378 | if (unlikely(!pskb_may_pull(skb, hdr_size))) |
379 | goto free_skb; | 379 | goto free_skb; |
380 | 380 | ||
381 | ethhdr = eth_hdr(skb); | 381 | ethhdr = eth_hdr(skb); |
382 | 382 | ||
383 | /* packet with unicast indication but non-unicast recipient */ | 383 | /* packet with unicast indication but non-unicast recipient */ |
384 | if (!is_valid_ether_addr(ethhdr->h_dest)) | 384 | if (!is_valid_ether_addr(ethhdr->h_dest)) |
385 | goto free_skb; | 385 | goto free_skb; |
386 | 386 | ||
387 | /* packet with broadcast/multicast sender address */ | 387 | /* packet with broadcast/multicast sender address */ |
388 | if (is_multicast_ether_addr(ethhdr->h_source)) | 388 | if (is_multicast_ether_addr(ethhdr->h_source)) |
389 | goto free_skb; | 389 | goto free_skb; |
390 | 390 | ||
391 | /* not for me */ | 391 | /* not for me */ |
392 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) | 392 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) |
393 | goto free_skb; | 393 | goto free_skb; |
394 | 394 | ||
395 | icmph = (struct batadv_icmp_header *)skb->data; | 395 | icmph = (struct batadv_icmp_header *)skb->data; |
396 | 396 | ||
397 | /* add record route information if not full */ | 397 | /* add record route information if not full */ |
398 | if ((icmph->msg_type == BATADV_ECHO_REPLY || | 398 | if ((icmph->msg_type == BATADV_ECHO_REPLY || |
399 | icmph->msg_type == BATADV_ECHO_REQUEST) && | 399 | icmph->msg_type == BATADV_ECHO_REQUEST) && |
400 | skb->len >= sizeof(struct batadv_icmp_packet_rr)) { | 400 | skb->len >= sizeof(struct batadv_icmp_packet_rr)) { |
401 | if (skb_linearize(skb) < 0) | 401 | if (skb_linearize(skb) < 0) |
402 | goto free_skb; | 402 | goto free_skb; |
403 | 403 | ||
404 | /* create a copy of the skb, if needed, to modify it. */ | 404 | /* create a copy of the skb, if needed, to modify it. */ |
405 | if (skb_cow(skb, ETH_HLEN) < 0) | 405 | if (skb_cow(skb, ETH_HLEN) < 0) |
406 | goto free_skb; | 406 | goto free_skb; |
407 | 407 | ||
408 | ethhdr = eth_hdr(skb); | 408 | ethhdr = eth_hdr(skb); |
409 | icmph = (struct batadv_icmp_header *)skb->data; | 409 | icmph = (struct batadv_icmp_header *)skb->data; |
410 | icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph; | 410 | icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph; |
411 | if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN) | 411 | if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN) |
412 | goto free_skb; | 412 | goto free_skb; |
413 | 413 | ||
414 | ether_addr_copy(icmp_packet_rr->rr[icmp_packet_rr->rr_cur], | 414 | ether_addr_copy(icmp_packet_rr->rr[icmp_packet_rr->rr_cur], |
415 | ethhdr->h_dest); | 415 | ethhdr->h_dest); |
416 | icmp_packet_rr->rr_cur++; | 416 | icmp_packet_rr->rr_cur++; |
417 | } | 417 | } |
418 | 418 | ||
419 | /* packet for me */ | 419 | /* packet for me */ |
420 | if (batadv_is_my_mac(bat_priv, icmph->dst)) | 420 | if (batadv_is_my_mac(bat_priv, icmph->dst)) |
421 | return batadv_recv_my_icmp_packet(bat_priv, skb); | 421 | return batadv_recv_my_icmp_packet(bat_priv, skb); |
422 | 422 | ||
423 | /* TTL exceeded */ | 423 | /* TTL exceeded */ |
424 | if (icmph->ttl < 2) | 424 | if (icmph->ttl < 2) |
425 | return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); | 425 | return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); |
426 | 426 | ||
427 | /* get routing information */ | 427 | /* get routing information */ |
428 | orig_node = batadv_orig_hash_find(bat_priv, icmph->dst); | 428 | orig_node = batadv_orig_hash_find(bat_priv, icmph->dst); |
429 | if (!orig_node) | 429 | if (!orig_node) |
430 | goto free_skb; | 430 | goto free_skb; |
431 | 431 | ||
432 | /* create a copy of the skb, if needed, to modify it. */ | 432 | /* create a copy of the skb, if needed, to modify it. */ |
433 | if (skb_cow(skb, ETH_HLEN) < 0) | 433 | if (skb_cow(skb, ETH_HLEN) < 0) |
434 | goto put_orig_node; | 434 | goto put_orig_node; |
435 | 435 | ||
436 | icmph = (struct batadv_icmp_header *)skb->data; | 436 | icmph = (struct batadv_icmp_header *)skb->data; |
437 | 437 | ||
438 | /* decrement ttl */ | 438 | /* decrement ttl */ |
439 | icmph->ttl--; | 439 | icmph->ttl--; |
440 | 440 | ||
441 | /* route it */ | 441 | /* route it */ |
442 | res = batadv_send_skb_to_orig(skb, orig_node, recv_if); | 442 | res = batadv_send_skb_to_orig(skb, orig_node, recv_if); |
443 | if (res == NET_XMIT_SUCCESS) | 443 | if (res == NET_XMIT_SUCCESS) |
444 | ret = NET_RX_SUCCESS; | 444 | ret = NET_RX_SUCCESS; |
445 | 445 | ||
446 | /* skb was consumed */ | 446 | /* skb was consumed */ |
447 | skb = NULL; | 447 | skb = NULL; |
448 | 448 | ||
449 | put_orig_node: | 449 | put_orig_node: |
450 | if (orig_node) | 450 | if (orig_node) |
451 | batadv_orig_node_put(orig_node); | 451 | batadv_orig_node_put(orig_node); |
452 | free_skb: | 452 | free_skb: |
453 | kfree_skb(skb); | 453 | kfree_skb(skb); |
454 | 454 | ||
455 | return ret; | 455 | return ret; |
456 | } | 456 | } |
457 | 457 | ||
458 | /** | 458 | /** |
459 | * batadv_check_unicast_packet() - Check for malformed unicast packets | 459 | * batadv_check_unicast_packet() - Check for malformed unicast packets |
460 | * @bat_priv: the bat priv with all the soft interface information | 460 | * @bat_priv: the bat priv with all the soft interface information |
461 | * @skb: packet to check | 461 | * @skb: packet to check |
462 | * @hdr_size: size of header to pull | 462 | * @hdr_size: size of header to pull |
463 | * | 463 | * |
464 | * Check for short header and bad addresses in given packet. | 464 | * Check for short header and bad addresses in given packet. |
465 | * | 465 | * |
466 | * Return: negative value when check fails and 0 otherwise. The negative value | 466 | * Return: negative value when check fails and 0 otherwise. The negative value |
467 | * depends on the reason: -ENODATA for bad header, -EBADR for broadcast | 467 | * depends on the reason: -ENODATA for bad header, -EBADR for broadcast |
468 | * destination or source, and -EREMOTE for non-local (other host) destination. | 468 | * destination or source, and -EREMOTE for non-local (other host) destination. |
469 | */ | 469 | */ |
470 | static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, | 470 | static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, |
471 | struct sk_buff *skb, int hdr_size) | 471 | struct sk_buff *skb, int hdr_size) |
472 | { | 472 | { |
473 | struct ethhdr *ethhdr; | 473 | struct ethhdr *ethhdr; |
474 | 474 | ||
475 | /* drop packet if it has not necessary minimum size */ | 475 | /* drop packet if it has not necessary minimum size */ |
476 | if (unlikely(!pskb_may_pull(skb, hdr_size))) | 476 | if (unlikely(!pskb_may_pull(skb, hdr_size))) |
477 | return -ENODATA; | 477 | return -ENODATA; |
478 | 478 | ||
479 | ethhdr = eth_hdr(skb); | 479 | ethhdr = eth_hdr(skb); |
480 | 480 | ||
481 | /* packet with unicast indication but non-unicast recipient */ | 481 | /* packet with unicast indication but non-unicast recipient */ |
482 | if (!is_valid_ether_addr(ethhdr->h_dest)) | 482 | if (!is_valid_ether_addr(ethhdr->h_dest)) |
483 | return -EBADR; | 483 | return -EBADR; |
484 | 484 | ||
485 | /* packet with broadcast/multicast sender address */ | 485 | /* packet with broadcast/multicast sender address */ |
486 | if (is_multicast_ether_addr(ethhdr->h_source)) | 486 | if (is_multicast_ether_addr(ethhdr->h_source)) |
487 | return -EBADR; | 487 | return -EBADR; |
488 | 488 | ||
489 | /* not for me */ | 489 | /* not for me */ |
490 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) | 490 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) |
491 | return -EREMOTE; | 491 | return -EREMOTE; |
492 | 492 | ||
493 | return 0; | 493 | return 0; |
494 | } | 494 | } |
495 | 495 | ||
496 | /** | 496 | /** |
497 | * batadv_last_bonding_get() - Get last_bonding_candidate of orig_node | 497 | * batadv_last_bonding_get() - Get last_bonding_candidate of orig_node |
498 | * @orig_node: originator node whose last bonding candidate should be retrieved | 498 | * @orig_node: originator node whose last bonding candidate should be retrieved |
499 | * | 499 | * |
500 | * Return: last bonding candidate of router or NULL if not found | 500 | * Return: last bonding candidate of router or NULL if not found |
501 | * | 501 | * |
502 | * The object is returned with refcounter increased by 1. | 502 | * The object is returned with refcounter increased by 1. |
503 | */ | 503 | */ |
504 | static struct batadv_orig_ifinfo * | 504 | static struct batadv_orig_ifinfo * |
505 | batadv_last_bonding_get(struct batadv_orig_node *orig_node) | 505 | batadv_last_bonding_get(struct batadv_orig_node *orig_node) |
506 | { | 506 | { |
507 | struct batadv_orig_ifinfo *last_bonding_candidate; | 507 | struct batadv_orig_ifinfo *last_bonding_candidate; |
508 | 508 | ||
509 | spin_lock_bh(&orig_node->neigh_list_lock); | 509 | spin_lock_bh(&orig_node->neigh_list_lock); |
510 | last_bonding_candidate = orig_node->last_bonding_candidate; | 510 | last_bonding_candidate = orig_node->last_bonding_candidate; |
511 | 511 | ||
512 | if (last_bonding_candidate) | 512 | if (last_bonding_candidate) |
513 | kref_get(&last_bonding_candidate->refcount); | 513 | kref_get(&last_bonding_candidate->refcount); |
514 | spin_unlock_bh(&orig_node->neigh_list_lock); | 514 | spin_unlock_bh(&orig_node->neigh_list_lock); |
515 | 515 | ||
516 | return last_bonding_candidate; | 516 | return last_bonding_candidate; |
517 | } | 517 | } |
518 | 518 | ||
519 | /** | 519 | /** |
520 | * batadv_last_bonding_replace() - Replace last_bonding_candidate of orig_node | 520 | * batadv_last_bonding_replace() - Replace last_bonding_candidate of orig_node |
521 | * @orig_node: originator node whose bonding candidates should be replaced | 521 | * @orig_node: originator node whose bonding candidates should be replaced |
522 | * @new_candidate: new bonding candidate or NULL | 522 | * @new_candidate: new bonding candidate or NULL |
523 | */ | 523 | */ |
524 | static void | 524 | static void |
525 | batadv_last_bonding_replace(struct batadv_orig_node *orig_node, | 525 | batadv_last_bonding_replace(struct batadv_orig_node *orig_node, |
526 | struct batadv_orig_ifinfo *new_candidate) | 526 | struct batadv_orig_ifinfo *new_candidate) |
527 | { | 527 | { |
528 | struct batadv_orig_ifinfo *old_candidate; | 528 | struct batadv_orig_ifinfo *old_candidate; |
529 | 529 | ||
530 | spin_lock_bh(&orig_node->neigh_list_lock); | 530 | spin_lock_bh(&orig_node->neigh_list_lock); |
531 | old_candidate = orig_node->last_bonding_candidate; | 531 | old_candidate = orig_node->last_bonding_candidate; |
532 | 532 | ||
533 | if (new_candidate) | 533 | if (new_candidate) |
534 | kref_get(&new_candidate->refcount); | 534 | kref_get(&new_candidate->refcount); |
535 | orig_node->last_bonding_candidate = new_candidate; | 535 | orig_node->last_bonding_candidate = new_candidate; |
536 | spin_unlock_bh(&orig_node->neigh_list_lock); | 536 | spin_unlock_bh(&orig_node->neigh_list_lock); |
537 | 537 | ||
538 | if (old_candidate) | 538 | if (old_candidate) |
539 | batadv_orig_ifinfo_put(old_candidate); | 539 | batadv_orig_ifinfo_put(old_candidate); |
540 | } | 540 | } |
541 | 541 | ||
542 | /** | 542 | /** |
543 | * batadv_find_router() - find a suitable router for this originator | 543 | * batadv_find_router() - find a suitable router for this originator |
544 | * @bat_priv: the bat priv with all the soft interface information | 544 | * @bat_priv: the bat priv with all the soft interface information |
545 | * @orig_node: the destination node | 545 | * @orig_node: the destination node |
546 | * @recv_if: pointer to interface this packet was received on | 546 | * @recv_if: pointer to interface this packet was received on |
547 | * | 547 | * |
548 | * Return: the router which should be used for this orig_node on | 548 | * Return: the router which should be used for this orig_node on |
549 | * this interface, or NULL if not available. | 549 | * this interface, or NULL if not available. |
550 | */ | 550 | */ |
551 | struct batadv_neigh_node * | 551 | struct batadv_neigh_node * |
552 | batadv_find_router(struct batadv_priv *bat_priv, | 552 | batadv_find_router(struct batadv_priv *bat_priv, |
553 | struct batadv_orig_node *orig_node, | 553 | struct batadv_orig_node *orig_node, |
554 | struct batadv_hard_iface *recv_if) | 554 | struct batadv_hard_iface *recv_if) |
555 | { | 555 | { |
556 | struct batadv_algo_ops *bao = bat_priv->algo_ops; | 556 | struct batadv_algo_ops *bao = bat_priv->algo_ops; |
557 | struct batadv_neigh_node *first_candidate_router = NULL; | 557 | struct batadv_neigh_node *first_candidate_router = NULL; |
558 | struct batadv_neigh_node *next_candidate_router = NULL; | 558 | struct batadv_neigh_node *next_candidate_router = NULL; |
559 | struct batadv_neigh_node *router, *cand_router = NULL; | 559 | struct batadv_neigh_node *router, *cand_router = NULL; |
560 | struct batadv_neigh_node *last_cand_router = NULL; | 560 | struct batadv_neigh_node *last_cand_router = NULL; |
561 | struct batadv_orig_ifinfo *cand, *first_candidate = NULL; | 561 | struct batadv_orig_ifinfo *cand, *first_candidate = NULL; |
562 | struct batadv_orig_ifinfo *next_candidate = NULL; | 562 | struct batadv_orig_ifinfo *next_candidate = NULL; |
563 | struct batadv_orig_ifinfo *last_candidate; | 563 | struct batadv_orig_ifinfo *last_candidate; |
564 | bool last_candidate_found = false; | 564 | bool last_candidate_found = false; |
565 | 565 | ||
566 | if (!orig_node) | 566 | if (!orig_node) |
567 | return NULL; | 567 | return NULL; |
568 | 568 | ||
569 | router = batadv_orig_router_get(orig_node, recv_if); | 569 | router = batadv_orig_router_get(orig_node, recv_if); |
570 | 570 | ||
571 | if (!router) | 571 | if (!router) |
572 | return router; | 572 | return router; |
573 | 573 | ||
574 | /* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop) | 574 | /* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop) |
575 | * and if activated. | 575 | * and if activated. |
576 | */ | 576 | */ |
577 | if (!(recv_if == BATADV_IF_DEFAULT && atomic_read(&bat_priv->bonding))) | 577 | if (!(recv_if == BATADV_IF_DEFAULT && atomic_read(&bat_priv->bonding))) |
578 | return router; | 578 | return router; |
579 | 579 | ||
580 | /* bonding: loop through the list of possible routers found | 580 | /* bonding: loop through the list of possible routers found |
581 | * for the various outgoing interfaces and find a candidate after | 581 | * for the various outgoing interfaces and find a candidate after |
582 | * the last chosen bonding candidate (next_candidate). If no such | 582 | * the last chosen bonding candidate (next_candidate). If no such |
583 | * router is found, use the first candidate found (the previously | 583 | * router is found, use the first candidate found (the previously |
584 | * chosen bonding candidate might have been the last one in the list). | 584 | * chosen bonding candidate might have been the last one in the list). |
585 | * If this can't be found either, return the previously chosen | 585 | * If this can't be found either, return the previously chosen |
586 | * router - obviously there are no other candidates. | 586 | * router - obviously there are no other candidates. |
587 | */ | 587 | */ |
588 | rcu_read_lock(); | 588 | rcu_read_lock(); |
589 | last_candidate = batadv_last_bonding_get(orig_node); | 589 | last_candidate = batadv_last_bonding_get(orig_node); |
590 | if (last_candidate) | 590 | if (last_candidate) |
591 | last_cand_router = rcu_dereference(last_candidate->router); | 591 | last_cand_router = rcu_dereference(last_candidate->router); |
592 | 592 | ||
593 | hlist_for_each_entry_rcu(cand, &orig_node->ifinfo_list, list) { | 593 | hlist_for_each_entry_rcu(cand, &orig_node->ifinfo_list, list) { |
594 | /* acquire some structures and references ... */ | 594 | /* acquire some structures and references ... */ |
595 | if (!kref_get_unless_zero(&cand->refcount)) | 595 | if (!kref_get_unless_zero(&cand->refcount)) |
596 | continue; | 596 | continue; |
597 | 597 | ||
598 | cand_router = rcu_dereference(cand->router); | 598 | cand_router = rcu_dereference(cand->router); |
599 | if (!cand_router) | 599 | if (!cand_router) |
600 | goto next; | 600 | goto next; |
601 | 601 | ||
602 | if (!kref_get_unless_zero(&cand_router->refcount)) { | 602 | if (!kref_get_unless_zero(&cand_router->refcount)) { |
603 | cand_router = NULL; | 603 | cand_router = NULL; |
604 | goto next; | 604 | goto next; |
605 | } | 605 | } |
606 | 606 | ||
607 | /* alternative candidate should be good enough to be | 607 | /* alternative candidate should be good enough to be |
608 | * considered | 608 | * considered |
609 | */ | 609 | */ |
610 | if (!bao->neigh.is_similar_or_better(cand_router, | 610 | if (!bao->neigh.is_similar_or_better(cand_router, |
611 | cand->if_outgoing, router, | 611 | cand->if_outgoing, router, |
612 | recv_if)) | 612 | recv_if)) |
613 | goto next; | 613 | goto next; |
614 | 614 | ||
615 | /* don't use the same router twice */ | 615 | /* don't use the same router twice */ |
616 | if (last_cand_router == cand_router) | 616 | if (last_cand_router == cand_router) |
617 | goto next; | 617 | goto next; |
618 | 618 | ||
619 | /* mark the first possible candidate */ | 619 | /* mark the first possible candidate */ |
620 | if (!first_candidate) { | 620 | if (!first_candidate) { |
621 | kref_get(&cand_router->refcount); | 621 | kref_get(&cand_router->refcount); |
622 | kref_get(&cand->refcount); | 622 | kref_get(&cand->refcount); |
623 | first_candidate = cand; | 623 | first_candidate = cand; |
624 | first_candidate_router = cand_router; | 624 | first_candidate_router = cand_router; |
625 | } | 625 | } |
626 | 626 | ||
627 | /* check if the loop has already passed the previously selected | 627 | /* check if the loop has already passed the previously selected |
628 | * candidate ... this function should select the next candidate | 628 | * candidate ... this function should select the next candidate |
629 | * AFTER the previously used bonding candidate. | 629 | * AFTER the previously used bonding candidate. |
630 | */ | 630 | */ |
631 | if (!last_candidate || last_candidate_found) { | 631 | if (!last_candidate || last_candidate_found) { |
632 | next_candidate = cand; | 632 | next_candidate = cand; |
633 | next_candidate_router = cand_router; | 633 | next_candidate_router = cand_router; |
634 | break; | 634 | break; |
635 | } | 635 | } |
636 | 636 | ||
637 | if (last_candidate == cand) | 637 | if (last_candidate == cand) |
638 | last_candidate_found = true; | 638 | last_candidate_found = true; |
639 | next: | 639 | next: |
640 | /* free references */ | 640 | /* free references */ |
641 | if (cand_router) { | 641 | if (cand_router) { |
642 | batadv_neigh_node_put(cand_router); | 642 | batadv_neigh_node_put(cand_router); |
643 | cand_router = NULL; | 643 | cand_router = NULL; |
644 | } | 644 | } |
645 | batadv_orig_ifinfo_put(cand); | 645 | batadv_orig_ifinfo_put(cand); |
646 | } | 646 | } |
647 | rcu_read_unlock(); | 647 | rcu_read_unlock(); |
648 | 648 | ||
649 | /* After finding candidates, handle the three cases: | 649 | /* After finding candidates, handle the three cases: |
650 | * 1) there is a next candidate, use that | 650 | * 1) there is a next candidate, use that |
651 | * 2) there is no next candidate, use the first of the list | 651 | * 2) there is no next candidate, use the first of the list |
652 | * 3) there is no candidate at all, return the default router | 652 | * 3) there is no candidate at all, return the default router |
653 | */ | 653 | */ |
654 | if (next_candidate) { | 654 | if (next_candidate) { |
655 | batadv_neigh_node_put(router); | 655 | batadv_neigh_node_put(router); |
656 | 656 | ||
657 | kref_get(&next_candidate_router->refcount); | 657 | kref_get(&next_candidate_router->refcount); |
658 | router = next_candidate_router; | 658 | router = next_candidate_router; |
659 | batadv_last_bonding_replace(orig_node, next_candidate); | 659 | batadv_last_bonding_replace(orig_node, next_candidate); |
660 | } else if (first_candidate) { | 660 | } else if (first_candidate) { |
661 | batadv_neigh_node_put(router); | 661 | batadv_neigh_node_put(router); |
662 | 662 | ||
663 | kref_get(&first_candidate_router->refcount); | 663 | kref_get(&first_candidate_router->refcount); |
664 | router = first_candidate_router; | 664 | router = first_candidate_router; |
665 | batadv_last_bonding_replace(orig_node, first_candidate); | 665 | batadv_last_bonding_replace(orig_node, first_candidate); |
666 | } else { | 666 | } else { |
667 | batadv_last_bonding_replace(orig_node, NULL); | 667 | batadv_last_bonding_replace(orig_node, NULL); |
668 | } | 668 | } |
669 | 669 | ||
670 | /* cleanup of candidates */ | 670 | /* cleanup of candidates */ |
671 | if (first_candidate) { | 671 | if (first_candidate) { |
672 | batadv_neigh_node_put(first_candidate_router); | 672 | batadv_neigh_node_put(first_candidate_router); |
673 | batadv_orig_ifinfo_put(first_candidate); | 673 | batadv_orig_ifinfo_put(first_candidate); |
674 | } | 674 | } |
675 | 675 | ||
676 | if (next_candidate) { | 676 | if (next_candidate) { |
677 | batadv_neigh_node_put(next_candidate_router); | 677 | batadv_neigh_node_put(next_candidate_router); |
678 | batadv_orig_ifinfo_put(next_candidate); | 678 | batadv_orig_ifinfo_put(next_candidate); |
679 | } | 679 | } |
680 | 680 | ||
681 | if (last_candidate) | 681 | if (last_candidate) |
682 | batadv_orig_ifinfo_put(last_candidate); | 682 | batadv_orig_ifinfo_put(last_candidate); |
683 | 683 | ||
684 | return router; | 684 | return router; |
685 | } | 685 | } |
686 | 686 | ||
687 | static int batadv_route_unicast_packet(struct sk_buff *skb, | 687 | static int batadv_route_unicast_packet(struct sk_buff *skb, |
688 | struct batadv_hard_iface *recv_if) | 688 | struct batadv_hard_iface *recv_if) |
689 | { | 689 | { |
690 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 690 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
691 | struct batadv_orig_node *orig_node = NULL; | 691 | struct batadv_orig_node *orig_node = NULL; |
692 | struct batadv_unicast_packet *unicast_packet; | 692 | struct batadv_unicast_packet *unicast_packet; |
693 | struct ethhdr *ethhdr = eth_hdr(skb); | 693 | struct ethhdr *ethhdr = eth_hdr(skb); |
694 | int res, hdr_len, ret = NET_RX_DROP; | 694 | int res, hdr_len, ret = NET_RX_DROP; |
695 | unsigned int len; | 695 | unsigned int len; |
696 | 696 | ||
697 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 697 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
698 | 698 | ||
699 | /* TTL exceeded */ | 699 | /* TTL exceeded */ |
700 | if (unicast_packet->ttl < 2) { | 700 | if (unicast_packet->ttl < 2) { |
701 | pr_debug("Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n", | 701 | pr_debug("Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n", |
702 | ethhdr->h_source, unicast_packet->dest); | 702 | ethhdr->h_source, unicast_packet->dest); |
703 | goto free_skb; | 703 | goto free_skb; |
704 | } | 704 | } |
705 | 705 | ||
706 | /* get routing information */ | 706 | /* get routing information */ |
707 | orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->dest); | 707 | orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->dest); |
708 | 708 | ||
709 | if (!orig_node) | 709 | if (!orig_node) |
710 | goto free_skb; | 710 | goto free_skb; |
711 | 711 | ||
712 | /* create a copy of the skb, if needed, to modify it. */ | 712 | /* create a copy of the skb, if needed, to modify it. */ |
713 | if (skb_cow(skb, ETH_HLEN) < 0) | 713 | if (skb_cow(skb, ETH_HLEN) < 0) |
714 | goto put_orig_node; | 714 | goto put_orig_node; |
715 | 715 | ||
716 | /* decrement ttl */ | 716 | /* decrement ttl */ |
717 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 717 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
718 | unicast_packet->ttl--; | 718 | unicast_packet->ttl--; |
719 | 719 | ||
720 | switch (unicast_packet->packet_type) { | 720 | switch (unicast_packet->packet_type) { |
721 | case BATADV_UNICAST_4ADDR: | 721 | case BATADV_UNICAST_4ADDR: |
722 | hdr_len = sizeof(struct batadv_unicast_4addr_packet); | 722 | hdr_len = sizeof(struct batadv_unicast_4addr_packet); |
723 | break; | 723 | break; |
724 | case BATADV_UNICAST: | 724 | case BATADV_UNICAST: |
725 | hdr_len = sizeof(struct batadv_unicast_packet); | 725 | hdr_len = sizeof(struct batadv_unicast_packet); |
726 | break; | 726 | break; |
727 | default: | 727 | default: |
728 | /* other packet types not supported - yet */ | 728 | /* other packet types not supported - yet */ |
729 | hdr_len = -1; | 729 | hdr_len = -1; |
730 | break; | 730 | break; |
731 | } | 731 | } |
732 | 732 | ||
733 | if (hdr_len > 0) | 733 | if (hdr_len > 0) |
734 | batadv_skb_set_priority(skb, hdr_len); | 734 | batadv_skb_set_priority(skb, hdr_len); |
735 | 735 | ||
736 | len = skb->len; | 736 | len = skb->len; |
737 | res = batadv_send_skb_to_orig(skb, orig_node, recv_if); | 737 | res = batadv_send_skb_to_orig(skb, orig_node, recv_if); |
738 | 738 | ||
739 | /* translate transmit result into receive result */ | 739 | /* translate transmit result into receive result */ |
740 | if (res == NET_XMIT_SUCCESS) { | 740 | if (res == NET_XMIT_SUCCESS) { |
741 | ret = NET_RX_SUCCESS; | 741 | ret = NET_RX_SUCCESS; |
742 | /* skb was transmitted and consumed */ | 742 | /* skb was transmitted and consumed */ |
743 | batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD); | 743 | batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD); |
744 | batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES, | 744 | batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES, |
745 | len + ETH_HLEN); | 745 | len + ETH_HLEN); |
746 | } | 746 | } |
747 | 747 | ||
748 | /* skb was consumed */ | 748 | /* skb was consumed */ |
749 | skb = NULL; | 749 | skb = NULL; |
750 | 750 | ||
751 | put_orig_node: | 751 | put_orig_node: |
752 | batadv_orig_node_put(orig_node); | 752 | batadv_orig_node_put(orig_node); |
753 | free_skb: | 753 | free_skb: |
754 | kfree_skb(skb); | 754 | kfree_skb(skb); |
755 | 755 | ||
756 | return ret; | 756 | return ret; |
757 | } | 757 | } |
758 | 758 | ||
759 | /** | 759 | /** |
760 | * batadv_reroute_unicast_packet() - update the unicast header for re-routing | 760 | * batadv_reroute_unicast_packet() - update the unicast header for re-routing |
761 | * @bat_priv: the bat priv with all the soft interface information | 761 | * @bat_priv: the bat priv with all the soft interface information |
762 | * @skb: unicast packet to process | 762 | * @skb: unicast packet to process |
763 | * @unicast_packet: the unicast header to be updated | 763 | * @unicast_packet: the unicast header to be updated |
764 | * @dst_addr: the payload destination | 764 | * @dst_addr: the payload destination |
765 | * @vid: VLAN identifier | 765 | * @vid: VLAN identifier |
766 | * | 766 | * |
767 | * Search the translation table for dst_addr and update the unicast header with | 767 | * Search the translation table for dst_addr and update the unicast header with |
768 | * the new corresponding information (originator address where the destination | 768 | * the new corresponding information (originator address where the destination |
769 | * client currently is and its known TTVN) | 769 | * client currently is and its known TTVN) |
770 | * | 770 | * |
771 | * Return: true if the packet header has been updated, false otherwise | 771 | * Return: true if the packet header has been updated, false otherwise |
772 | */ | 772 | */ |
773 | static bool | 773 | static bool |
774 | batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, | 774 | batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, |
775 | struct batadv_unicast_packet *unicast_packet, | 775 | struct batadv_unicast_packet *unicast_packet, |
776 | u8 *dst_addr, unsigned short vid) | 776 | u8 *dst_addr, unsigned short vid) |
777 | { | 777 | { |
778 | struct batadv_orig_node *orig_node = NULL; | 778 | struct batadv_orig_node *orig_node = NULL; |
779 | struct batadv_hard_iface *primary_if = NULL; | 779 | struct batadv_hard_iface *primary_if = NULL; |
780 | bool ret = false; | 780 | bool ret = false; |
781 | u8 *orig_addr, orig_ttvn; | 781 | u8 *orig_addr, orig_ttvn; |
782 | 782 | ||
783 | if (batadv_is_my_client(bat_priv, dst_addr, vid)) { | 783 | if (batadv_is_my_client(bat_priv, dst_addr, vid)) { |
784 | primary_if = batadv_primary_if_get_selected(bat_priv); | 784 | primary_if = batadv_primary_if_get_selected(bat_priv); |
785 | if (!primary_if) | 785 | if (!primary_if) |
786 | goto out; | 786 | goto out; |
787 | orig_addr = primary_if->net_dev->dev_addr; | 787 | orig_addr = primary_if->net_dev->dev_addr; |
788 | orig_ttvn = (u8)atomic_read(&bat_priv->tt.vn); | 788 | orig_ttvn = (u8)atomic_read(&bat_priv->tt.vn); |
789 | } else { | 789 | } else { |
790 | orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr, | 790 | orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr, |
791 | vid); | 791 | vid); |
792 | if (!orig_node) | 792 | if (!orig_node) |
793 | goto out; | 793 | goto out; |
794 | 794 | ||
795 | if (batadv_compare_eth(orig_node->orig, unicast_packet->dest)) | 795 | if (batadv_compare_eth(orig_node->orig, unicast_packet->dest)) |
796 | goto out; | 796 | goto out; |
797 | 797 | ||
798 | orig_addr = orig_node->orig; | 798 | orig_addr = orig_node->orig; |
799 | orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn); | 799 | orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn); |
800 | } | 800 | } |
801 | 801 | ||
802 | /* update the packet header */ | 802 | /* update the packet header */ |
803 | skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | 803 | skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); |
804 | ether_addr_copy(unicast_packet->dest, orig_addr); | 804 | ether_addr_copy(unicast_packet->dest, orig_addr); |
805 | unicast_packet->ttvn = orig_ttvn; | 805 | unicast_packet->ttvn = orig_ttvn; |
806 | skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | 806 | skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); |
807 | 807 | ||
808 | ret = true; | 808 | ret = true; |
809 | out: | 809 | out: |
810 | if (primary_if) | 810 | if (primary_if) |
811 | batadv_hardif_put(primary_if); | 811 | batadv_hardif_put(primary_if); |
812 | if (orig_node) | 812 | if (orig_node) |
813 | batadv_orig_node_put(orig_node); | 813 | batadv_orig_node_put(orig_node); |
814 | 814 | ||
815 | return ret; | 815 | return ret; |
816 | } | 816 | } |
817 | 817 | ||
818 | static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | 818 | static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, |
819 | struct sk_buff *skb, int hdr_len) | 819 | struct sk_buff *skb, int hdr_len) |
820 | { | 820 | { |
821 | struct batadv_unicast_packet *unicast_packet; | 821 | struct batadv_unicast_packet *unicast_packet; |
822 | struct batadv_hard_iface *primary_if; | 822 | struct batadv_hard_iface *primary_if; |
823 | struct batadv_orig_node *orig_node; | 823 | struct batadv_orig_node *orig_node; |
824 | u8 curr_ttvn, old_ttvn; | 824 | u8 curr_ttvn, old_ttvn; |
825 | struct ethhdr *ethhdr; | 825 | struct ethhdr *ethhdr; |
826 | unsigned short vid; | 826 | unsigned short vid; |
827 | int is_old_ttvn; | 827 | int is_old_ttvn; |
828 | 828 | ||
829 | /* check if there is enough data before accessing it */ | 829 | /* check if there is enough data before accessing it */ |
830 | if (!pskb_may_pull(skb, hdr_len + ETH_HLEN)) | 830 | if (!pskb_may_pull(skb, hdr_len + ETH_HLEN)) |
831 | return false; | 831 | return false; |
832 | 832 | ||
833 | /* create a copy of the skb (in case of for re-routing) to modify it. */ | 833 | /* create a copy of the skb (in case of for re-routing) to modify it. */ |
834 | if (skb_cow(skb, sizeof(*unicast_packet)) < 0) | 834 | if (skb_cow(skb, sizeof(*unicast_packet)) < 0) |
835 | return false; | 835 | return false; |
836 | 836 | ||
837 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 837 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
838 | vid = batadv_get_vid(skb, hdr_len); | 838 | vid = batadv_get_vid(skb, hdr_len); |
839 | ethhdr = (struct ethhdr *)(skb->data + hdr_len); | 839 | ethhdr = (struct ethhdr *)(skb->data + hdr_len); |
840 | 840 | ||
841 | /* check if the destination client was served by this node and it is now | 841 | /* check if the destination client was served by this node and it is now |
842 | * roaming. In this case, it means that the node has got a ROAM_ADV | 842 | * roaming. In this case, it means that the node has got a ROAM_ADV |
843 | * message and that it knows the new destination in the mesh to re-route | 843 | * message and that it knows the new destination in the mesh to re-route |
844 | * the packet to | 844 | * the packet to |
845 | */ | 845 | */ |
846 | if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) { | 846 | if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) { |
847 | if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet, | 847 | if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet, |
848 | ethhdr->h_dest, vid)) | 848 | ethhdr->h_dest, vid)) |
849 | batadv_dbg_ratelimited(BATADV_DBG_TT, | 849 | batadv_dbg_ratelimited(BATADV_DBG_TT, |
850 | bat_priv, | 850 | bat_priv, |
851 | "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n", | 851 | "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n", |
852 | unicast_packet->dest, | 852 | unicast_packet->dest, |
853 | ethhdr->h_dest); | 853 | ethhdr->h_dest); |
854 | /* at this point the mesh destination should have been | 854 | /* at this point the mesh destination should have been |
855 | * substituted with the originator address found in the global | 855 | * substituted with the originator address found in the global |
856 | * table. If not, let the packet go untouched anyway because | 856 | * table. If not, let the packet go untouched anyway because |
857 | * there is nothing the node can do | 857 | * there is nothing the node can do |
858 | */ | 858 | */ |
859 | return true; | 859 | return true; |
860 | } | 860 | } |
861 | 861 | ||
862 | /* retrieve the TTVN known by this node for the packet destination. This | 862 | /* retrieve the TTVN known by this node for the packet destination. This |
863 | * value is used later to check if the node which sent (or re-routed | 863 | * value is used later to check if the node which sent (or re-routed |
864 | * last time) the packet had an updated information or not | 864 | * last time) the packet had an updated information or not |
865 | */ | 865 | */ |
866 | curr_ttvn = (u8)atomic_read(&bat_priv->tt.vn); | 866 | curr_ttvn = (u8)atomic_read(&bat_priv->tt.vn); |
867 | if (!batadv_is_my_mac(bat_priv, unicast_packet->dest)) { | 867 | if (!batadv_is_my_mac(bat_priv, unicast_packet->dest)) { |
868 | orig_node = batadv_orig_hash_find(bat_priv, | 868 | orig_node = batadv_orig_hash_find(bat_priv, |
869 | unicast_packet->dest); | 869 | unicast_packet->dest); |
870 | /* if it is not possible to find the orig_node representing the | 870 | /* if it is not possible to find the orig_node representing the |
871 | * destination, the packet can immediately be dropped as it will | 871 | * destination, the packet can immediately be dropped as it will |
872 | * not be possible to deliver it | 872 | * not be possible to deliver it |
873 | */ | 873 | */ |
874 | if (!orig_node) | 874 | if (!orig_node) |
875 | return false; | 875 | return false; |
876 | 876 | ||
877 | curr_ttvn = (u8)atomic_read(&orig_node->last_ttvn); | 877 | curr_ttvn = (u8)atomic_read(&orig_node->last_ttvn); |
878 | batadv_orig_node_put(orig_node); | 878 | batadv_orig_node_put(orig_node); |
879 | } | 879 | } |
880 | 880 | ||
881 | /* check if the TTVN contained in the packet is fresher than what the | 881 | /* check if the TTVN contained in the packet is fresher than what the |
882 | * node knows | 882 | * node knows |
883 | */ | 883 | */ |
884 | is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn); | 884 | is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn); |
885 | if (!is_old_ttvn) | 885 | if (!is_old_ttvn) |
886 | return true; | 886 | return true; |
887 | 887 | ||
888 | old_ttvn = unicast_packet->ttvn; | 888 | old_ttvn = unicast_packet->ttvn; |
889 | /* the packet was forged based on outdated network information. Its | 889 | /* the packet was forged based on outdated network information. Its |
890 | * destination can possibly be updated and forwarded towards the new | 890 | * destination can possibly be updated and forwarded towards the new |
891 | * target host | 891 | * target host |
892 | */ | 892 | */ |
893 | if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet, | 893 | if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet, |
894 | ethhdr->h_dest, vid)) { | 894 | ethhdr->h_dest, vid)) { |
895 | batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv, | 895 | batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv, |
896 | "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", | 896 | "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", |
897 | unicast_packet->dest, ethhdr->h_dest, | 897 | unicast_packet->dest, ethhdr->h_dest, |
898 | old_ttvn, curr_ttvn); | 898 | old_ttvn, curr_ttvn); |
899 | return true; | 899 | return true; |
900 | } | 900 | } |
901 | 901 | ||
902 | /* the packet has not been re-routed: either the destination is | 902 | /* the packet has not been re-routed: either the destination is |
903 | * currently served by this node or there is no destination at all and | 903 | * currently served by this node or there is no destination at all and |
904 | * it is possible to drop the packet | 904 | * it is possible to drop the packet |
905 | */ | 905 | */ |
906 | if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid)) | 906 | if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid)) |
907 | return false; | 907 | return false; |
908 | 908 | ||
909 | /* update the header in order to let the packet be delivered to this | 909 | /* update the header in order to let the packet be delivered to this |
910 | * node's soft interface | 910 | * node's soft interface |
911 | */ | 911 | */ |
912 | primary_if = batadv_primary_if_get_selected(bat_priv); | 912 | primary_if = batadv_primary_if_get_selected(bat_priv); |
913 | if (!primary_if) | 913 | if (!primary_if) |
914 | return false; | 914 | return false; |
915 | 915 | ||
916 | /* update the packet header */ | 916 | /* update the packet header */ |
917 | skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | 917 | skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); |
918 | ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr); | 918 | ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr); |
919 | unicast_packet->ttvn = curr_ttvn; | 919 | unicast_packet->ttvn = curr_ttvn; |
920 | skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | 920 | skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); |
921 | 921 | ||
922 | batadv_hardif_put(primary_if); | 922 | batadv_hardif_put(primary_if); |
923 | 923 | ||
924 | return true; | 924 | return true; |
925 | } | 925 | } |
926 | 926 | ||
927 | /** | 927 | /** |
928 | * batadv_recv_unhandled_unicast_packet() - receive and process packets which | 928 | * batadv_recv_unhandled_unicast_packet() - receive and process packets which |
929 | * are in the unicast number space but not yet known to the implementation | 929 | * are in the unicast number space but not yet known to the implementation |
930 | * @skb: unicast tvlv packet to process | 930 | * @skb: unicast tvlv packet to process |
931 | * @recv_if: pointer to interface this packet was received on | 931 | * @recv_if: pointer to interface this packet was received on |
932 | * | 932 | * |
933 | * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP | 933 | * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP |
934 | * otherwise. | 934 | * otherwise. |
935 | */ | 935 | */ |
936 | int batadv_recv_unhandled_unicast_packet(struct sk_buff *skb, | 936 | int batadv_recv_unhandled_unicast_packet(struct sk_buff *skb, |
937 | struct batadv_hard_iface *recv_if) | 937 | struct batadv_hard_iface *recv_if) |
938 | { | 938 | { |
939 | struct batadv_unicast_packet *unicast_packet; | 939 | struct batadv_unicast_packet *unicast_packet; |
940 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 940 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
941 | int check, hdr_size = sizeof(*unicast_packet); | 941 | int check, hdr_size = sizeof(*unicast_packet); |
942 | 942 | ||
943 | check = batadv_check_unicast_packet(bat_priv, skb, hdr_size); | 943 | check = batadv_check_unicast_packet(bat_priv, skb, hdr_size); |
944 | if (check < 0) | 944 | if (check < 0) |
945 | goto free_skb; | 945 | goto free_skb; |
946 | 946 | ||
947 | /* we don't know about this type, drop it. */ | 947 | /* we don't know about this type, drop it. */ |
948 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 948 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
949 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) | 949 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) |
950 | goto free_skb; | 950 | goto free_skb; |
951 | 951 | ||
952 | return batadv_route_unicast_packet(skb, recv_if); | 952 | return batadv_route_unicast_packet(skb, recv_if); |
953 | 953 | ||
954 | free_skb: | 954 | free_skb: |
955 | kfree_skb(skb); | 955 | kfree_skb(skb); |
956 | return NET_RX_DROP; | 956 | return NET_RX_DROP; |
957 | } | 957 | } |
958 | 958 | ||
959 | /** | 959 | /** |
960 | * batadv_recv_unicast_packet() - Process incoming unicast packet | 960 | * batadv_recv_unicast_packet() - Process incoming unicast packet |
961 | * @skb: incoming packet buffer | 961 | * @skb: incoming packet buffer |
962 | * @recv_if: incoming hard interface | 962 | * @recv_if: incoming hard interface |
963 | * | 963 | * |
964 | * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure | 964 | * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure |
965 | */ | 965 | */ |
966 | int batadv_recv_unicast_packet(struct sk_buff *skb, | 966 | int batadv_recv_unicast_packet(struct sk_buff *skb, |
967 | struct batadv_hard_iface *recv_if) | 967 | struct batadv_hard_iface *recv_if) |
968 | { | 968 | { |
969 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 969 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
970 | struct batadv_unicast_packet *unicast_packet; | 970 | struct batadv_unicast_packet *unicast_packet; |
971 | struct batadv_unicast_4addr_packet *unicast_4addr_packet; | 971 | struct batadv_unicast_4addr_packet *unicast_4addr_packet; |
972 | u8 *orig_addr, *orig_addr_gw; | 972 | u8 *orig_addr, *orig_addr_gw; |
973 | struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL; | 973 | struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL; |
974 | int check, hdr_size = sizeof(*unicast_packet); | 974 | int check, hdr_size = sizeof(*unicast_packet); |
975 | enum batadv_subtype subtype; | 975 | enum batadv_subtype subtype; |
976 | int ret = NET_RX_DROP; | 976 | int ret = NET_RX_DROP; |
977 | bool is4addr, is_gw; | 977 | bool is4addr, is_gw; |
978 | 978 | ||
979 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 979 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
980 | is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; | 980 | is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; |
981 | /* the caller function should have already pulled 2 bytes */ | 981 | /* the caller function should have already pulled 2 bytes */ |
982 | if (is4addr) | 982 | if (is4addr) |
983 | hdr_size = sizeof(*unicast_4addr_packet); | 983 | hdr_size = sizeof(*unicast_4addr_packet); |
984 | 984 | ||
985 | /* function returns -EREMOTE for promiscuous packets */ | 985 | /* function returns -EREMOTE for promiscuous packets */ |
986 | check = batadv_check_unicast_packet(bat_priv, skb, hdr_size); | 986 | check = batadv_check_unicast_packet(bat_priv, skb, hdr_size); |
987 | 987 | ||
988 | /* Even though the packet is not for us, we might save it to use for | 988 | /* Even though the packet is not for us, we might save it to use for |
989 | * decoding a later received coded packet | 989 | * decoding a later received coded packet |
990 | */ | 990 | */ |
991 | if (check == -EREMOTE) | 991 | if (check == -EREMOTE) |
992 | batadv_nc_skb_store_sniffed_unicast(bat_priv, skb); | 992 | batadv_nc_skb_store_sniffed_unicast(bat_priv, skb); |
993 | 993 | ||
994 | if (check < 0) | 994 | if (check < 0) |
995 | goto free_skb; | 995 | goto free_skb; |
996 | if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) | 996 | if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) |
997 | goto free_skb; | 997 | goto free_skb; |
998 | 998 | ||
999 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 999 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
1000 | 1000 | ||
1001 | /* packet for me */ | 1001 | /* packet for me */ |
1002 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { | 1002 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { |
1003 | /* If this is a unicast packet from another backgone gw, | 1003 | /* If this is a unicast packet from another backgone gw, |
1004 | * drop it. | 1004 | * drop it. |
1005 | */ | 1005 | */ |
1006 | orig_addr_gw = eth_hdr(skb)->h_source; | 1006 | orig_addr_gw = eth_hdr(skb)->h_source; |
1007 | orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw); | 1007 | orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw); |
1008 | if (orig_node_gw) { | 1008 | if (orig_node_gw) { |
1009 | is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw, | 1009 | is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw, |
1010 | hdr_size); | 1010 | hdr_size); |
1011 | batadv_orig_node_put(orig_node_gw); | 1011 | batadv_orig_node_put(orig_node_gw); |
1012 | if (is_gw) { | 1012 | if (is_gw) { |
1013 | batadv_dbg(BATADV_DBG_BLA, bat_priv, | 1013 | batadv_dbg(BATADV_DBG_BLA, bat_priv, |
1014 | "%s(): Dropped unicast pkt received from another backbone gw %pM.\n", | 1014 | "%s(): Dropped unicast pkt received from another backbone gw %pM.\n", |
1015 | __func__, orig_addr_gw); | 1015 | __func__, orig_addr_gw); |
1016 | goto free_skb; | 1016 | goto free_skb; |
1017 | } | 1017 | } |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | if (is4addr) { | 1020 | if (is4addr) { |
1021 | unicast_4addr_packet = | 1021 | unicast_4addr_packet = |
1022 | (struct batadv_unicast_4addr_packet *)skb->data; | 1022 | (struct batadv_unicast_4addr_packet *)skb->data; |
1023 | subtype = unicast_4addr_packet->subtype; | 1023 | subtype = unicast_4addr_packet->subtype; |
1024 | batadv_dat_inc_counter(bat_priv, subtype); | 1024 | batadv_dat_inc_counter(bat_priv, subtype); |
1025 | 1025 | ||
1026 | /* Only payload data should be considered for speedy | 1026 | /* Only payload data should be considered for speedy |
1027 | * join. For example, DAT also uses unicast 4addr | 1027 | * join. For example, DAT also uses unicast 4addr |
1028 | * types, but those packets should not be considered | 1028 | * types, but those packets should not be considered |
1029 | * for speedy join, since the clients do not actually | 1029 | * for speedy join, since the clients do not actually |
1030 | * reside at the sending originator. | 1030 | * reside at the sending originator. |
1031 | */ | 1031 | */ |
1032 | if (subtype == BATADV_P_DATA) { | 1032 | if (subtype == BATADV_P_DATA) { |
1033 | orig_addr = unicast_4addr_packet->src; | 1033 | orig_addr = unicast_4addr_packet->src; |
1034 | orig_node = batadv_orig_hash_find(bat_priv, | 1034 | orig_node = batadv_orig_hash_find(bat_priv, |
1035 | orig_addr); | 1035 | orig_addr); |
1036 | } | 1036 | } |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, | 1039 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, |
1040 | hdr_size)) | 1040 | hdr_size)) |
1041 | goto rx_success; | 1041 | goto rx_success; |
1042 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, | 1042 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, |
1043 | hdr_size)) | 1043 | hdr_size)) |
1044 | goto rx_success; | 1044 | goto rx_success; |
1045 | 1045 | ||
1046 | batadv_dat_snoop_incoming_dhcp_ack(bat_priv, skb, hdr_size); | ||
1047 | |||
1046 | batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, | 1048 | batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, |
1047 | orig_node); | 1049 | orig_node); |
1048 | 1050 | ||
1049 | rx_success: | 1051 | rx_success: |
1050 | if (orig_node) | 1052 | if (orig_node) |
1051 | batadv_orig_node_put(orig_node); | 1053 | batadv_orig_node_put(orig_node); |
1052 | 1054 | ||
1053 | return NET_RX_SUCCESS; | 1055 | return NET_RX_SUCCESS; |
1054 | } | 1056 | } |
1055 | 1057 | ||
1056 | ret = batadv_route_unicast_packet(skb, recv_if); | 1058 | ret = batadv_route_unicast_packet(skb, recv_if); |
1057 | /* skb was consumed */ | 1059 | /* skb was consumed */ |
1058 | skb = NULL; | 1060 | skb = NULL; |
1059 | 1061 | ||
1060 | free_skb: | 1062 | free_skb: |
1061 | kfree_skb(skb); | 1063 | kfree_skb(skb); |
1062 | 1064 | ||
1063 | return ret; | 1065 | return ret; |
1064 | } | 1066 | } |
1065 | 1067 | ||
1066 | /** | 1068 | /** |
1067 | * batadv_recv_unicast_tvlv() - receive and process unicast tvlv packets | 1069 | * batadv_recv_unicast_tvlv() - receive and process unicast tvlv packets |
1068 | * @skb: unicast tvlv packet to process | 1070 | * @skb: unicast tvlv packet to process |
1069 | * @recv_if: pointer to interface this packet was received on | 1071 | * @recv_if: pointer to interface this packet was received on |
1070 | * | 1072 | * |
1071 | * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP | 1073 | * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP |
1072 | * otherwise. | 1074 | * otherwise. |
1073 | */ | 1075 | */ |
1074 | int batadv_recv_unicast_tvlv(struct sk_buff *skb, | 1076 | int batadv_recv_unicast_tvlv(struct sk_buff *skb, |
1075 | struct batadv_hard_iface *recv_if) | 1077 | struct batadv_hard_iface *recv_if) |
1076 | { | 1078 | { |
1077 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 1079 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
1078 | struct batadv_unicast_tvlv_packet *unicast_tvlv_packet; | 1080 | struct batadv_unicast_tvlv_packet *unicast_tvlv_packet; |
1079 | unsigned char *tvlv_buff; | 1081 | unsigned char *tvlv_buff; |
1080 | u16 tvlv_buff_len; | 1082 | u16 tvlv_buff_len; |
1081 | int hdr_size = sizeof(*unicast_tvlv_packet); | 1083 | int hdr_size = sizeof(*unicast_tvlv_packet); |
1082 | int ret = NET_RX_DROP; | 1084 | int ret = NET_RX_DROP; |
1083 | 1085 | ||
1084 | if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) | 1086 | if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) |
1085 | goto free_skb; | 1087 | goto free_skb; |
1086 | 1088 | ||
1087 | /* the header is likely to be modified while forwarding */ | 1089 | /* the header is likely to be modified while forwarding */ |
1088 | if (skb_cow(skb, hdr_size) < 0) | 1090 | if (skb_cow(skb, hdr_size) < 0) |
1089 | goto free_skb; | 1091 | goto free_skb; |
1090 | 1092 | ||
1091 | /* packet needs to be linearized to access the tvlv content */ | 1093 | /* packet needs to be linearized to access the tvlv content */ |
1092 | if (skb_linearize(skb) < 0) | 1094 | if (skb_linearize(skb) < 0) |
1093 | goto free_skb; | 1095 | goto free_skb; |
1094 | 1096 | ||
1095 | unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)skb->data; | 1097 | unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)skb->data; |
1096 | 1098 | ||
1097 | tvlv_buff = (unsigned char *)(skb->data + hdr_size); | 1099 | tvlv_buff = (unsigned char *)(skb->data + hdr_size); |
1098 | tvlv_buff_len = ntohs(unicast_tvlv_packet->tvlv_len); | 1100 | tvlv_buff_len = ntohs(unicast_tvlv_packet->tvlv_len); |
1099 | 1101 | ||
1100 | if (tvlv_buff_len > skb->len - hdr_size) | 1102 | if (tvlv_buff_len > skb->len - hdr_size) |
1101 | goto free_skb; | 1103 | goto free_skb; |
1102 | 1104 | ||
1103 | ret = batadv_tvlv_containers_process(bat_priv, false, NULL, | 1105 | ret = batadv_tvlv_containers_process(bat_priv, false, NULL, |
1104 | unicast_tvlv_packet->src, | 1106 | unicast_tvlv_packet->src, |
1105 | unicast_tvlv_packet->dst, | 1107 | unicast_tvlv_packet->dst, |
1106 | tvlv_buff, tvlv_buff_len); | 1108 | tvlv_buff, tvlv_buff_len); |
1107 | 1109 | ||
1108 | if (ret != NET_RX_SUCCESS) { | 1110 | if (ret != NET_RX_SUCCESS) { |
1109 | ret = batadv_route_unicast_packet(skb, recv_if); | 1111 | ret = batadv_route_unicast_packet(skb, recv_if); |
1110 | /* skb was consumed */ | 1112 | /* skb was consumed */ |
1111 | skb = NULL; | 1113 | skb = NULL; |
1112 | } | 1114 | } |
1113 | 1115 | ||
1114 | free_skb: | 1116 | free_skb: |
1115 | kfree_skb(skb); | 1117 | kfree_skb(skb); |
1116 | 1118 | ||
1117 | return ret; | 1119 | return ret; |
1118 | } | 1120 | } |
1119 | 1121 | ||
1120 | /** | 1122 | /** |
1121 | * batadv_recv_frag_packet() - process received fragment | 1123 | * batadv_recv_frag_packet() - process received fragment |
1122 | * @skb: the received fragment | 1124 | * @skb: the received fragment |
1123 | * @recv_if: interface that the skb is received on | 1125 | * @recv_if: interface that the skb is received on |
1124 | * | 1126 | * |
1125 | * This function does one of the three following things: 1) Forward fragment, if | 1127 | * This function does one of the three following things: 1) Forward fragment, if |
1126 | * the assembled packet will exceed our MTU; 2) Buffer fragment, if we till | 1128 | * the assembled packet will exceed our MTU; 2) Buffer fragment, if we till |
1127 | * lack further fragments; 3) Merge fragments, if we have all needed parts. | 1129 | * lack further fragments; 3) Merge fragments, if we have all needed parts. |
1128 | * | 1130 | * |
1129 | * Return: NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise. | 1131 | * Return: NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise. |
1130 | */ | 1132 | */ |
1131 | int batadv_recv_frag_packet(struct sk_buff *skb, | 1133 | int batadv_recv_frag_packet(struct sk_buff *skb, |
1132 | struct batadv_hard_iface *recv_if) | 1134 | struct batadv_hard_iface *recv_if) |
1133 | { | 1135 | { |
1134 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 1136 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
1135 | struct batadv_orig_node *orig_node_src = NULL; | 1137 | struct batadv_orig_node *orig_node_src = NULL; |
1136 | struct batadv_frag_packet *frag_packet; | 1138 | struct batadv_frag_packet *frag_packet; |
1137 | int ret = NET_RX_DROP; | 1139 | int ret = NET_RX_DROP; |
1138 | 1140 | ||
1139 | if (batadv_check_unicast_packet(bat_priv, skb, | 1141 | if (batadv_check_unicast_packet(bat_priv, skb, |
1140 | sizeof(*frag_packet)) < 0) | 1142 | sizeof(*frag_packet)) < 0) |
1141 | goto free_skb; | 1143 | goto free_skb; |
1142 | 1144 | ||
1143 | frag_packet = (struct batadv_frag_packet *)skb->data; | 1145 | frag_packet = (struct batadv_frag_packet *)skb->data; |
1144 | orig_node_src = batadv_orig_hash_find(bat_priv, frag_packet->orig); | 1146 | orig_node_src = batadv_orig_hash_find(bat_priv, frag_packet->orig); |
1145 | if (!orig_node_src) | 1147 | if (!orig_node_src) |
1146 | goto free_skb; | 1148 | goto free_skb; |
1147 | 1149 | ||
1148 | skb->priority = frag_packet->priority + 256; | 1150 | skb->priority = frag_packet->priority + 256; |
1149 | 1151 | ||
1150 | /* Route the fragment if it is not for us and too big to be merged. */ | 1152 | /* Route the fragment if it is not for us and too big to be merged. */ |
1151 | if (!batadv_is_my_mac(bat_priv, frag_packet->dest) && | 1153 | if (!batadv_is_my_mac(bat_priv, frag_packet->dest) && |
1152 | batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) { | 1154 | batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) { |
1153 | /* skb was consumed */ | 1155 | /* skb was consumed */ |
1154 | skb = NULL; | 1156 | skb = NULL; |
1155 | ret = NET_RX_SUCCESS; | 1157 | ret = NET_RX_SUCCESS; |
1156 | goto put_orig_node; | 1158 | goto put_orig_node; |
1157 | } | 1159 | } |
1158 | 1160 | ||
1159 | batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_RX); | 1161 | batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_RX); |
1160 | batadv_add_counter(bat_priv, BATADV_CNT_FRAG_RX_BYTES, skb->len); | 1162 | batadv_add_counter(bat_priv, BATADV_CNT_FRAG_RX_BYTES, skb->len); |
1161 | 1163 | ||
1162 | /* Add fragment to buffer and merge if possible. */ | 1164 | /* Add fragment to buffer and merge if possible. */ |
1163 | if (!batadv_frag_skb_buffer(&skb, orig_node_src)) | 1165 | if (!batadv_frag_skb_buffer(&skb, orig_node_src)) |
1164 | goto put_orig_node; | 1166 | goto put_orig_node; |
1165 | 1167 | ||
1166 | /* Deliver merged packet to the appropriate handler, if it was | 1168 | /* Deliver merged packet to the appropriate handler, if it was |
1167 | * merged | 1169 | * merged |
1168 | */ | 1170 | */ |
1169 | if (skb) { | 1171 | if (skb) { |
1170 | batadv_batman_skb_recv(skb, recv_if->net_dev, | 1172 | batadv_batman_skb_recv(skb, recv_if->net_dev, |
1171 | &recv_if->batman_adv_ptype, NULL); | 1173 | &recv_if->batman_adv_ptype, NULL); |
1172 | /* skb was consumed */ | 1174 | /* skb was consumed */ |
1173 | skb = NULL; | 1175 | skb = NULL; |
1174 | } | 1176 | } |
1175 | 1177 | ||
1176 | ret = NET_RX_SUCCESS; | 1178 | ret = NET_RX_SUCCESS; |
1177 | 1179 | ||
1178 | put_orig_node: | 1180 | put_orig_node: |
1179 | batadv_orig_node_put(orig_node_src); | 1181 | batadv_orig_node_put(orig_node_src); |
1180 | free_skb: | 1182 | free_skb: |
1181 | kfree_skb(skb); | 1183 | kfree_skb(skb); |
1182 | 1184 | ||
1183 | return ret; | 1185 | return ret; |
1184 | } | 1186 | } |
1185 | 1187 | ||
1186 | /** | 1188 | /** |
1187 | * batadv_recv_bcast_packet() - Process incoming broadcast packet | 1189 | * batadv_recv_bcast_packet() - Process incoming broadcast packet |
1188 | * @skb: incoming packet buffer | 1190 | * @skb: incoming packet buffer |
1189 | * @recv_if: incoming hard interface | 1191 | * @recv_if: incoming hard interface |
1190 | * | 1192 | * |
1191 | * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure | 1193 | * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure |
1192 | */ | 1194 | */ |
1193 | int batadv_recv_bcast_packet(struct sk_buff *skb, | 1195 | int batadv_recv_bcast_packet(struct sk_buff *skb, |
1194 | struct batadv_hard_iface *recv_if) | 1196 | struct batadv_hard_iface *recv_if) |
1195 | { | 1197 | { |
1196 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 1198 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
1197 | struct batadv_orig_node *orig_node = NULL; | 1199 | struct batadv_orig_node *orig_node = NULL; |
1198 | struct batadv_bcast_packet *bcast_packet; | 1200 | struct batadv_bcast_packet *bcast_packet; |
1199 | struct ethhdr *ethhdr; | 1201 | struct ethhdr *ethhdr; |
1200 | int hdr_size = sizeof(*bcast_packet); | 1202 | int hdr_size = sizeof(*bcast_packet); |
1201 | int ret = NET_RX_DROP; | 1203 | int ret = NET_RX_DROP; |
1202 | s32 seq_diff; | 1204 | s32 seq_diff; |
1203 | u32 seqno; | 1205 | u32 seqno; |
1204 | 1206 | ||
1205 | /* drop packet if it has not necessary minimum size */ | 1207 | /* drop packet if it has not necessary minimum size */ |
1206 | if (unlikely(!pskb_may_pull(skb, hdr_size))) | 1208 | if (unlikely(!pskb_may_pull(skb, hdr_size))) |
1207 | goto free_skb; | 1209 | goto free_skb; |
1208 | 1210 | ||
1209 | ethhdr = eth_hdr(skb); | 1211 | ethhdr = eth_hdr(skb); |
1210 | 1212 | ||
1211 | /* packet with broadcast indication but unicast recipient */ | 1213 | /* packet with broadcast indication but unicast recipient */ |
1212 | if (!is_broadcast_ether_addr(ethhdr->h_dest)) | 1214 | if (!is_broadcast_ether_addr(ethhdr->h_dest)) |
1213 | goto free_skb; | 1215 | goto free_skb; |
1214 | 1216 | ||
1215 | /* packet with broadcast/multicast sender address */ | 1217 | /* packet with broadcast/multicast sender address */ |
1216 | if (is_multicast_ether_addr(ethhdr->h_source)) | 1218 | if (is_multicast_ether_addr(ethhdr->h_source)) |
1217 | goto free_skb; | 1219 | goto free_skb; |
1218 | 1220 | ||
1219 | /* ignore broadcasts sent by myself */ | 1221 | /* ignore broadcasts sent by myself */ |
1220 | if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) | 1222 | if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) |
1221 | goto free_skb; | 1223 | goto free_skb; |
1222 | 1224 | ||
1223 | bcast_packet = (struct batadv_bcast_packet *)skb->data; | 1225 | bcast_packet = (struct batadv_bcast_packet *)skb->data; |
1224 | 1226 | ||
1225 | /* ignore broadcasts originated by myself */ | 1227 | /* ignore broadcasts originated by myself */ |
1226 | if (batadv_is_my_mac(bat_priv, bcast_packet->orig)) | 1228 | if (batadv_is_my_mac(bat_priv, bcast_packet->orig)) |
1227 | goto free_skb; | 1229 | goto free_skb; |
1228 | 1230 | ||
1229 | if (bcast_packet->ttl < 2) | 1231 | if (bcast_packet->ttl < 2) |
1230 | goto free_skb; | 1232 | goto free_skb; |
1231 | 1233 | ||
1232 | orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig); | 1234 | orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig); |
1233 | 1235 | ||
1234 | if (!orig_node) | 1236 | if (!orig_node) |
1235 | goto free_skb; | 1237 | goto free_skb; |
1236 | 1238 | ||
1237 | spin_lock_bh(&orig_node->bcast_seqno_lock); | 1239 | spin_lock_bh(&orig_node->bcast_seqno_lock); |
1238 | 1240 | ||
1239 | seqno = ntohl(bcast_packet->seqno); | 1241 | seqno = ntohl(bcast_packet->seqno); |
1240 | /* check whether the packet is a duplicate */ | 1242 | /* check whether the packet is a duplicate */ |
1241 | if (batadv_test_bit(orig_node->bcast_bits, orig_node->last_bcast_seqno, | 1243 | if (batadv_test_bit(orig_node->bcast_bits, orig_node->last_bcast_seqno, |
1242 | seqno)) | 1244 | seqno)) |
1243 | goto spin_unlock; | 1245 | goto spin_unlock; |
1244 | 1246 | ||
1245 | seq_diff = seqno - orig_node->last_bcast_seqno; | 1247 | seq_diff = seqno - orig_node->last_bcast_seqno; |
1246 | 1248 | ||
1247 | /* check whether the packet is old and the host just restarted. */ | 1249 | /* check whether the packet is old and the host just restarted. */ |
1248 | if (batadv_window_protected(bat_priv, seq_diff, | 1250 | if (batadv_window_protected(bat_priv, seq_diff, |
1249 | BATADV_BCAST_MAX_AGE, | 1251 | BATADV_BCAST_MAX_AGE, |
1250 | &orig_node->bcast_seqno_reset, NULL)) | 1252 | &orig_node->bcast_seqno_reset, NULL)) |
1251 | goto spin_unlock; | 1253 | goto spin_unlock; |
1252 | 1254 | ||
1253 | /* mark broadcast in flood history, update window position | 1255 | /* mark broadcast in flood history, update window position |
1254 | * if required. | 1256 | * if required. |
1255 | */ | 1257 | */ |
1256 | if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) | 1258 | if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) |
1257 | orig_node->last_bcast_seqno = seqno; | 1259 | orig_node->last_bcast_seqno = seqno; |
1258 | 1260 | ||
1259 | spin_unlock_bh(&orig_node->bcast_seqno_lock); | 1261 | spin_unlock_bh(&orig_node->bcast_seqno_lock); |
1260 | 1262 | ||
1261 | /* check whether this has been sent by another originator before */ | 1263 | /* check whether this has been sent by another originator before */ |
1262 | if (batadv_bla_check_bcast_duplist(bat_priv, skb)) | 1264 | if (batadv_bla_check_bcast_duplist(bat_priv, skb)) |
1263 | goto free_skb; | 1265 | goto free_skb; |
1264 | 1266 | ||
1265 | batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet)); | 1267 | batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet)); |
1266 | 1268 | ||
1267 | /* rebroadcast packet */ | 1269 | /* rebroadcast packet */ |
1268 | batadv_add_bcast_packet_to_list(bat_priv, skb, 1, false); | 1270 | batadv_add_bcast_packet_to_list(bat_priv, skb, 1, false); |
1269 | 1271 | ||
1270 | /* don't hand the broadcast up if it is from an originator | 1272 | /* don't hand the broadcast up if it is from an originator |
1271 | * from the same backbone. | 1273 | * from the same backbone. |
1272 | */ | 1274 | */ |
1273 | if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) | 1275 | if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) |
1274 | goto free_skb; | 1276 | goto free_skb; |
1275 | 1277 | ||
1276 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size)) | 1278 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size)) |
1277 | goto rx_success; | 1279 | goto rx_success; |
1278 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size)) | 1280 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size)) |
1279 | goto rx_success; | 1281 | goto rx_success; |
1282 | |||
1283 | batadv_dat_snoop_incoming_dhcp_ack(bat_priv, skb, hdr_size); | ||
1280 | 1284 | ||
1281 | /* broadcast for me */ | 1285 | /* broadcast for me */ |
1282 | batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, orig_node); | 1286 | batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, orig_node); |
1283 | 1287 | ||
1284 | rx_success: | 1288 | rx_success: |
1285 | ret = NET_RX_SUCCESS; | 1289 | ret = NET_RX_SUCCESS; |
1286 | goto out; | 1290 | goto out; |
1287 | 1291 | ||
1288 | spin_unlock: | 1292 | spin_unlock: |
1289 | spin_unlock_bh(&orig_node->bcast_seqno_lock); | 1293 | spin_unlock_bh(&orig_node->bcast_seqno_lock); |
1290 | free_skb: | 1294 | free_skb: |
1291 | kfree_skb(skb); | 1295 | kfree_skb(skb); |
1292 | out: | 1296 | out: |
1293 | if (orig_node) | 1297 | if (orig_node) |
1294 | batadv_orig_node_put(orig_node); | 1298 | batadv_orig_node_put(orig_node); |
1295 | return ret; | 1299 | return ret; |
1296 | } | 1300 | } |
1297 | 1301 |
net/batman-adv/soft-interface.c
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: | 2 | /* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Marek Lindner, Simon Wunderlich | 4 | * Marek Lindner, Simon Wunderlich |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 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 | 7 | * modify it under the terms of version 2 of the GNU General Public |
8 | * License as published by the Free Software Foundation. | 8 | * License as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, but | 10 | * This program is distributed in the hope that it will be useful, but |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * General Public License for more details. | 13 | * General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 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/>. | 16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "soft-interface.h" | 19 | #include "soft-interface.h" |
20 | #include "main.h" | 20 | #include "main.h" |
21 | 21 | ||
22 | #include <linux/atomic.h> | 22 | #include <linux/atomic.h> |
23 | #include <linux/byteorder/generic.h> | 23 | #include <linux/byteorder/generic.h> |
24 | #include <linux/cache.h> | 24 | #include <linux/cache.h> |
25 | #include <linux/compiler.h> | 25 | #include <linux/compiler.h> |
26 | #include <linux/cpumask.h> | 26 | #include <linux/cpumask.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
29 | #include <linux/ethtool.h> | 29 | #include <linux/ethtool.h> |
30 | #include <linux/gfp.h> | 30 | #include <linux/gfp.h> |
31 | #include <linux/if_ether.h> | 31 | #include <linux/if_ether.h> |
32 | #include <linux/if_vlan.h> | 32 | #include <linux/if_vlan.h> |
33 | #include <linux/jiffies.h> | 33 | #include <linux/jiffies.h> |
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
36 | #include <linux/list.h> | 36 | #include <linux/list.h> |
37 | #include <linux/lockdep.h> | 37 | #include <linux/lockdep.h> |
38 | #include <linux/netdevice.h> | 38 | #include <linux/netdevice.h> |
39 | #include <linux/percpu.h> | 39 | #include <linux/percpu.h> |
40 | #include <linux/printk.h> | 40 | #include <linux/printk.h> |
41 | #include <linux/random.h> | 41 | #include <linux/random.h> |
42 | #include <linux/rculist.h> | 42 | #include <linux/rculist.h> |
43 | #include <linux/rcupdate.h> | 43 | #include <linux/rcupdate.h> |
44 | #include <linux/rtnetlink.h> | 44 | #include <linux/rtnetlink.h> |
45 | #include <linux/skbuff.h> | 45 | #include <linux/skbuff.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/socket.h> | 47 | #include <linux/socket.h> |
48 | #include <linux/spinlock.h> | 48 | #include <linux/spinlock.h> |
49 | #include <linux/stddef.h> | 49 | #include <linux/stddef.h> |
50 | #include <linux/string.h> | 50 | #include <linux/string.h> |
51 | #include <linux/types.h> | 51 | #include <linux/types.h> |
52 | #include <uapi/linux/batadv_packet.h> | 52 | #include <uapi/linux/batadv_packet.h> |
53 | 53 | ||
54 | #include "bat_algo.h" | 54 | #include "bat_algo.h" |
55 | #include "bridge_loop_avoidance.h" | 55 | #include "bridge_loop_avoidance.h" |
56 | #include "debugfs.h" | 56 | #include "debugfs.h" |
57 | #include "distributed-arp-table.h" | 57 | #include "distributed-arp-table.h" |
58 | #include "gateway_client.h" | 58 | #include "gateway_client.h" |
59 | #include "gateway_common.h" | 59 | #include "gateway_common.h" |
60 | #include "hard-interface.h" | 60 | #include "hard-interface.h" |
61 | #include "multicast.h" | 61 | #include "multicast.h" |
62 | #include "network-coding.h" | 62 | #include "network-coding.h" |
63 | #include "originator.h" | 63 | #include "originator.h" |
64 | #include "send.h" | 64 | #include "send.h" |
65 | #include "sysfs.h" | 65 | #include "sysfs.h" |
66 | #include "translation-table.h" | 66 | #include "translation-table.h" |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * batadv_skb_head_push() - Increase header size and move (push) head pointer | 69 | * batadv_skb_head_push() - Increase header size and move (push) head pointer |
70 | * @skb: packet buffer which should be modified | 70 | * @skb: packet buffer which should be modified |
71 | * @len: number of bytes to add | 71 | * @len: number of bytes to add |
72 | * | 72 | * |
73 | * Return: 0 on success or negative error number in case of failure | 73 | * Return: 0 on success or negative error number in case of failure |
74 | */ | 74 | */ |
75 | int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) | 75 | int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) |
76 | { | 76 | { |
77 | int result; | 77 | int result; |
78 | 78 | ||
79 | /* TODO: We must check if we can release all references to non-payload | 79 | /* TODO: We must check if we can release all references to non-payload |
80 | * data using __skb_header_release in our skbs to allow skb_cow_header | 80 | * data using __skb_header_release in our skbs to allow skb_cow_header |
81 | * to work optimally. This means that those skbs are not allowed to read | 81 | * to work optimally. This means that those skbs are not allowed to read |
82 | * or write any data which is before the current position of skb->data | 82 | * or write any data which is before the current position of skb->data |
83 | * after that call and thus allow other skbs with the same data buffer | 83 | * after that call and thus allow other skbs with the same data buffer |
84 | * to write freely in that area. | 84 | * to write freely in that area. |
85 | */ | 85 | */ |
86 | result = skb_cow_head(skb, len); | 86 | result = skb_cow_head(skb, len); |
87 | if (result < 0) | 87 | if (result < 0) |
88 | return result; | 88 | return result; |
89 | 89 | ||
90 | skb_push(skb, len); | 90 | skb_push(skb, len); |
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
94 | static int batadv_interface_open(struct net_device *dev) | 94 | static int batadv_interface_open(struct net_device *dev) |
95 | { | 95 | { |
96 | netif_start_queue(dev); | 96 | netif_start_queue(dev); |
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | static int batadv_interface_release(struct net_device *dev) | 100 | static int batadv_interface_release(struct net_device *dev) |
101 | { | 101 | { |
102 | netif_stop_queue(dev); | 102 | netif_stop_queue(dev); |
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * batadv_sum_counter() - Sum the cpu-local counters for index 'idx' | 107 | * batadv_sum_counter() - Sum the cpu-local counters for index 'idx' |
108 | * @bat_priv: the bat priv with all the soft interface information | 108 | * @bat_priv: the bat priv with all the soft interface information |
109 | * @idx: index of counter to sum up | 109 | * @idx: index of counter to sum up |
110 | * | 110 | * |
111 | * Return: sum of all cpu-local counters | 111 | * Return: sum of all cpu-local counters |
112 | */ | 112 | */ |
113 | static u64 batadv_sum_counter(struct batadv_priv *bat_priv, size_t idx) | 113 | static u64 batadv_sum_counter(struct batadv_priv *bat_priv, size_t idx) |
114 | { | 114 | { |
115 | u64 *counters, sum = 0; | 115 | u64 *counters, sum = 0; |
116 | int cpu; | 116 | int cpu; |
117 | 117 | ||
118 | for_each_possible_cpu(cpu) { | 118 | for_each_possible_cpu(cpu) { |
119 | counters = per_cpu_ptr(bat_priv->bat_counters, cpu); | 119 | counters = per_cpu_ptr(bat_priv->bat_counters, cpu); |
120 | sum += counters[idx]; | 120 | sum += counters[idx]; |
121 | } | 121 | } |
122 | 122 | ||
123 | return sum; | 123 | return sum; |
124 | } | 124 | } |
125 | 125 | ||
126 | static struct net_device_stats *batadv_interface_stats(struct net_device *dev) | 126 | static struct net_device_stats *batadv_interface_stats(struct net_device *dev) |
127 | { | 127 | { |
128 | struct batadv_priv *bat_priv = netdev_priv(dev); | 128 | struct batadv_priv *bat_priv = netdev_priv(dev); |
129 | struct net_device_stats *stats = &dev->stats; | 129 | struct net_device_stats *stats = &dev->stats; |
130 | 130 | ||
131 | stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); | 131 | stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); |
132 | stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); | 132 | stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); |
133 | stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); | 133 | stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); |
134 | stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); | 134 | stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); |
135 | stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); | 135 | stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); |
136 | return stats; | 136 | return stats; |
137 | } | 137 | } |
138 | 138 | ||
139 | static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) | 139 | static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) |
140 | { | 140 | { |
141 | struct batadv_priv *bat_priv = netdev_priv(dev); | 141 | struct batadv_priv *bat_priv = netdev_priv(dev); |
142 | struct batadv_softif_vlan *vlan; | 142 | struct batadv_softif_vlan *vlan; |
143 | struct sockaddr *addr = p; | 143 | struct sockaddr *addr = p; |
144 | u8 old_addr[ETH_ALEN]; | 144 | u8 old_addr[ETH_ALEN]; |
145 | 145 | ||
146 | if (!is_valid_ether_addr(addr->sa_data)) | 146 | if (!is_valid_ether_addr(addr->sa_data)) |
147 | return -EADDRNOTAVAIL; | 147 | return -EADDRNOTAVAIL; |
148 | 148 | ||
149 | ether_addr_copy(old_addr, dev->dev_addr); | 149 | ether_addr_copy(old_addr, dev->dev_addr); |
150 | ether_addr_copy(dev->dev_addr, addr->sa_data); | 150 | ether_addr_copy(dev->dev_addr, addr->sa_data); |
151 | 151 | ||
152 | /* only modify transtable if it has been initialized before */ | 152 | /* only modify transtable if it has been initialized before */ |
153 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) | 153 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
154 | return 0; | 154 | return 0; |
155 | 155 | ||
156 | rcu_read_lock(); | 156 | rcu_read_lock(); |
157 | hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { | 157 | hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { |
158 | batadv_tt_local_remove(bat_priv, old_addr, vlan->vid, | 158 | batadv_tt_local_remove(bat_priv, old_addr, vlan->vid, |
159 | "mac address changed", false); | 159 | "mac address changed", false); |
160 | batadv_tt_local_add(dev, addr->sa_data, vlan->vid, | 160 | batadv_tt_local_add(dev, addr->sa_data, vlan->vid, |
161 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); | 161 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); |
162 | } | 162 | } |
163 | rcu_read_unlock(); | 163 | rcu_read_unlock(); |
164 | 164 | ||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) | 168 | static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) |
169 | { | 169 | { |
170 | /* check ranges */ | 170 | /* check ranges */ |
171 | if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev)) | 171 | if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev)) |
172 | return -EINVAL; | 172 | return -EINVAL; |
173 | 173 | ||
174 | dev->mtu = new_mtu; | 174 | dev->mtu = new_mtu; |
175 | 175 | ||
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * batadv_interface_set_rx_mode() - set the rx mode of a device | 180 | * batadv_interface_set_rx_mode() - set the rx mode of a device |
181 | * @dev: registered network device to modify | 181 | * @dev: registered network device to modify |
182 | * | 182 | * |
183 | * We do not actually need to set any rx filters for the virtual batman | 183 | * We do not actually need to set any rx filters for the virtual batman |
184 | * soft interface. However a dummy handler enables a user to set static | 184 | * soft interface. However a dummy handler enables a user to set static |
185 | * multicast listeners for instance. | 185 | * multicast listeners for instance. |
186 | */ | 186 | */ |
187 | static void batadv_interface_set_rx_mode(struct net_device *dev) | 187 | static void batadv_interface_set_rx_mode(struct net_device *dev) |
188 | { | 188 | { |
189 | } | 189 | } |
190 | 190 | ||
191 | static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, | 191 | static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, |
192 | struct net_device *soft_iface) | 192 | struct net_device *soft_iface) |
193 | { | 193 | { |
194 | struct ethhdr *ethhdr; | 194 | struct ethhdr *ethhdr; |
195 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 195 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
196 | struct batadv_hard_iface *primary_if = NULL; | 196 | struct batadv_hard_iface *primary_if = NULL; |
197 | struct batadv_bcast_packet *bcast_packet; | 197 | struct batadv_bcast_packet *bcast_packet; |
198 | static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, | 198 | static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, |
199 | 0x00, 0x00}; | 199 | 0x00, 0x00}; |
200 | static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, | 200 | static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, |
201 | 0x00, 0x00}; | 201 | 0x00, 0x00}; |
202 | enum batadv_dhcp_recipient dhcp_rcp = BATADV_DHCP_NO; | 202 | enum batadv_dhcp_recipient dhcp_rcp = BATADV_DHCP_NO; |
203 | u8 *dst_hint = NULL, chaddr[ETH_ALEN]; | 203 | u8 *dst_hint = NULL, chaddr[ETH_ALEN]; |
204 | struct vlan_ethhdr *vhdr; | 204 | struct vlan_ethhdr *vhdr; |
205 | unsigned int header_len = 0; | 205 | unsigned int header_len = 0; |
206 | int data_len = skb->len, ret; | 206 | int data_len = skb->len, ret; |
207 | unsigned long brd_delay = 1; | 207 | unsigned long brd_delay = 1; |
208 | bool do_bcast = false, client_added; | 208 | bool do_bcast = false, client_added; |
209 | unsigned short vid; | 209 | unsigned short vid; |
210 | u32 seqno; | 210 | u32 seqno; |
211 | int gw_mode; | 211 | int gw_mode; |
212 | enum batadv_forw_mode forw_mode; | 212 | enum batadv_forw_mode forw_mode; |
213 | struct batadv_orig_node *mcast_single_orig = NULL; | 213 | struct batadv_orig_node *mcast_single_orig = NULL; |
214 | int network_offset = ETH_HLEN; | 214 | int network_offset = ETH_HLEN; |
215 | __be16 proto; | ||
215 | 216 | ||
216 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) | 217 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
217 | goto dropped; | 218 | goto dropped; |
218 | 219 | ||
219 | /* reset control block to avoid left overs from previous users */ | 220 | /* reset control block to avoid left overs from previous users */ |
220 | memset(skb->cb, 0, sizeof(struct batadv_skb_cb)); | 221 | memset(skb->cb, 0, sizeof(struct batadv_skb_cb)); |
221 | 222 | ||
222 | netif_trans_update(soft_iface); | 223 | netif_trans_update(soft_iface); |
223 | vid = batadv_get_vid(skb, 0); | 224 | vid = batadv_get_vid(skb, 0); |
224 | ethhdr = eth_hdr(skb); | 225 | ethhdr = eth_hdr(skb); |
225 | 226 | ||
226 | switch (ntohs(ethhdr->h_proto)) { | 227 | proto = ethhdr->h_proto; |
228 | |||
229 | switch (ntohs(proto)) { | ||
227 | case ETH_P_8021Q: | 230 | case ETH_P_8021Q: |
228 | vhdr = vlan_eth_hdr(skb); | 231 | vhdr = vlan_eth_hdr(skb); |
232 | proto = vhdr->h_vlan_encapsulated_proto; | ||
229 | 233 | ||
230 | /* drop batman-in-batman packets to prevent loops */ | 234 | /* drop batman-in-batman packets to prevent loops */ |
231 | if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) { | 235 | if (proto != htons(ETH_P_BATMAN)) { |
232 | network_offset += VLAN_HLEN; | 236 | network_offset += VLAN_HLEN; |
233 | break; | 237 | break; |
234 | } | 238 | } |
235 | 239 | ||
236 | /* fall through */ | 240 | /* fall through */ |
237 | case ETH_P_BATMAN: | 241 | case ETH_P_BATMAN: |
238 | goto dropped; | 242 | goto dropped; |
239 | } | 243 | } |
240 | 244 | ||
241 | skb_set_network_header(skb, network_offset); | 245 | skb_set_network_header(skb, network_offset); |
242 | 246 | ||
243 | if (batadv_bla_tx(bat_priv, skb, vid)) | 247 | if (batadv_bla_tx(bat_priv, skb, vid)) |
244 | goto dropped; | 248 | goto dropped; |
245 | 249 | ||
246 | /* skb->data might have been reallocated by batadv_bla_tx() */ | 250 | /* skb->data might have been reallocated by batadv_bla_tx() */ |
247 | ethhdr = eth_hdr(skb); | 251 | ethhdr = eth_hdr(skb); |
248 | 252 | ||
249 | /* Register the client MAC in the transtable */ | 253 | /* Register the client MAC in the transtable */ |
250 | if (!is_multicast_ether_addr(ethhdr->h_source) && | 254 | if (!is_multicast_ether_addr(ethhdr->h_source) && |
251 | !batadv_bla_is_loopdetect_mac(ethhdr->h_source)) { | 255 | !batadv_bla_is_loopdetect_mac(ethhdr->h_source)) { |
252 | client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source, | 256 | client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source, |
253 | vid, skb->skb_iif, | 257 | vid, skb->skb_iif, |
254 | skb->mark); | 258 | skb->mark); |
255 | if (!client_added) | 259 | if (!client_added) |
256 | goto dropped; | 260 | goto dropped; |
257 | } | 261 | } |
262 | |||
263 | /* Snoop address candidates from DHCPACKs for early DAT filling */ | ||
264 | batadv_dat_snoop_outgoing_dhcp_ack(bat_priv, skb, proto, vid); | ||
258 | 265 | ||
259 | /* don't accept stp packets. STP does not help in meshes. | 266 | /* don't accept stp packets. STP does not help in meshes. |
260 | * better use the bridge loop avoidance ... | 267 | * better use the bridge loop avoidance ... |
261 | * | 268 | * |
262 | * The same goes for ECTP sent at least by some Cisco Switches, | 269 | * The same goes for ECTP sent at least by some Cisco Switches, |
263 | * it might confuse the mesh when used with bridge loop avoidance. | 270 | * it might confuse the mesh when used with bridge loop avoidance. |
264 | */ | 271 | */ |
265 | if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) | 272 | if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) |
266 | goto dropped; | 273 | goto dropped; |
267 | 274 | ||
268 | if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) | 275 | if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) |
269 | goto dropped; | 276 | goto dropped; |
270 | 277 | ||
271 | gw_mode = atomic_read(&bat_priv->gw.mode); | 278 | gw_mode = atomic_read(&bat_priv->gw.mode); |
272 | if (is_multicast_ether_addr(ethhdr->h_dest)) { | 279 | if (is_multicast_ether_addr(ethhdr->h_dest)) { |
273 | /* if gw mode is off, broadcast every packet */ | 280 | /* if gw mode is off, broadcast every packet */ |
274 | if (gw_mode == BATADV_GW_MODE_OFF) { | 281 | if (gw_mode == BATADV_GW_MODE_OFF) { |
275 | do_bcast = true; | 282 | do_bcast = true; |
276 | goto send; | 283 | goto send; |
277 | } | 284 | } |
278 | 285 | ||
279 | dhcp_rcp = batadv_gw_dhcp_recipient_get(skb, &header_len, | 286 | dhcp_rcp = batadv_gw_dhcp_recipient_get(skb, &header_len, |
280 | chaddr); | 287 | chaddr); |
281 | /* skb->data may have been modified by | 288 | /* skb->data may have been modified by |
282 | * batadv_gw_dhcp_recipient_get() | 289 | * batadv_gw_dhcp_recipient_get() |
283 | */ | 290 | */ |
284 | ethhdr = eth_hdr(skb); | 291 | ethhdr = eth_hdr(skb); |
285 | /* if gw_mode is on, broadcast any non-DHCP message. | 292 | /* if gw_mode is on, broadcast any non-DHCP message. |
286 | * All the DHCP packets are going to be sent as unicast | 293 | * All the DHCP packets are going to be sent as unicast |
287 | */ | 294 | */ |
288 | if (dhcp_rcp == BATADV_DHCP_NO) { | 295 | if (dhcp_rcp == BATADV_DHCP_NO) { |
289 | do_bcast = true; | 296 | do_bcast = true; |
290 | goto send; | 297 | goto send; |
291 | } | 298 | } |
292 | 299 | ||
293 | if (dhcp_rcp == BATADV_DHCP_TO_CLIENT) | 300 | if (dhcp_rcp == BATADV_DHCP_TO_CLIENT) |
294 | dst_hint = chaddr; | 301 | dst_hint = chaddr; |
295 | else if ((gw_mode == BATADV_GW_MODE_SERVER) && | 302 | else if ((gw_mode == BATADV_GW_MODE_SERVER) && |
296 | (dhcp_rcp == BATADV_DHCP_TO_SERVER)) | 303 | (dhcp_rcp == BATADV_DHCP_TO_SERVER)) |
297 | /* gateways should not forward any DHCP message if | 304 | /* gateways should not forward any DHCP message if |
298 | * directed to a DHCP server | 305 | * directed to a DHCP server |
299 | */ | 306 | */ |
300 | goto dropped; | 307 | goto dropped; |
301 | 308 | ||
302 | send: | 309 | send: |
303 | if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { | 310 | if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { |
304 | forw_mode = batadv_mcast_forw_mode(bat_priv, skb, | 311 | forw_mode = batadv_mcast_forw_mode(bat_priv, skb, |
305 | &mcast_single_orig); | 312 | &mcast_single_orig); |
306 | if (forw_mode == BATADV_FORW_NONE) | 313 | if (forw_mode == BATADV_FORW_NONE) |
307 | goto dropped; | 314 | goto dropped; |
308 | 315 | ||
309 | if (forw_mode == BATADV_FORW_SINGLE) | 316 | if (forw_mode == BATADV_FORW_SINGLE) |
310 | do_bcast = false; | 317 | do_bcast = false; |
311 | } | 318 | } |
312 | } | 319 | } |
313 | 320 | ||
314 | batadv_skb_set_priority(skb, 0); | 321 | batadv_skb_set_priority(skb, 0); |
315 | 322 | ||
316 | /* ethernet packet should be broadcasted */ | 323 | /* ethernet packet should be broadcasted */ |
317 | if (do_bcast) { | 324 | if (do_bcast) { |
318 | primary_if = batadv_primary_if_get_selected(bat_priv); | 325 | primary_if = batadv_primary_if_get_selected(bat_priv); |
319 | if (!primary_if) | 326 | if (!primary_if) |
320 | goto dropped; | 327 | goto dropped; |
321 | 328 | ||
322 | /* in case of ARP request, we do not immediately broadcasti the | 329 | /* in case of ARP request, we do not immediately broadcasti the |
323 | * packet, instead we first wait for DAT to try to retrieve the | 330 | * packet, instead we first wait for DAT to try to retrieve the |
324 | * correct ARP entry | 331 | * correct ARP entry |
325 | */ | 332 | */ |
326 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) | 333 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) |
327 | brd_delay = msecs_to_jiffies(ARP_REQ_DELAY); | 334 | brd_delay = msecs_to_jiffies(ARP_REQ_DELAY); |
328 | 335 | ||
329 | if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) | 336 | if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) |
330 | goto dropped; | 337 | goto dropped; |
331 | 338 | ||
332 | bcast_packet = (struct batadv_bcast_packet *)skb->data; | 339 | bcast_packet = (struct batadv_bcast_packet *)skb->data; |
333 | bcast_packet->version = BATADV_COMPAT_VERSION; | 340 | bcast_packet->version = BATADV_COMPAT_VERSION; |
334 | bcast_packet->ttl = BATADV_TTL; | 341 | bcast_packet->ttl = BATADV_TTL; |
335 | 342 | ||
336 | /* batman packet type: broadcast */ | 343 | /* batman packet type: broadcast */ |
337 | bcast_packet->packet_type = BATADV_BCAST; | 344 | bcast_packet->packet_type = BATADV_BCAST; |
338 | bcast_packet->reserved = 0; | 345 | bcast_packet->reserved = 0; |
339 | 346 | ||
340 | /* hw address of first interface is the orig mac because only | 347 | /* hw address of first interface is the orig mac because only |
341 | * this mac is known throughout the mesh | 348 | * this mac is known throughout the mesh |
342 | */ | 349 | */ |
343 | ether_addr_copy(bcast_packet->orig, | 350 | ether_addr_copy(bcast_packet->orig, |
344 | primary_if->net_dev->dev_addr); | 351 | primary_if->net_dev->dev_addr); |
345 | 352 | ||
346 | /* set broadcast sequence number */ | 353 | /* set broadcast sequence number */ |
347 | seqno = atomic_inc_return(&bat_priv->bcast_seqno); | 354 | seqno = atomic_inc_return(&bat_priv->bcast_seqno); |
348 | bcast_packet->seqno = htonl(seqno); | 355 | bcast_packet->seqno = htonl(seqno); |
349 | 356 | ||
350 | batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay, true); | 357 | batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay, true); |
351 | 358 | ||
352 | /* a copy is stored in the bcast list, therefore removing | 359 | /* a copy is stored in the bcast list, therefore removing |
353 | * the original skb. | 360 | * the original skb. |
354 | */ | 361 | */ |
355 | consume_skb(skb); | 362 | consume_skb(skb); |
356 | 363 | ||
357 | /* unicast packet */ | 364 | /* unicast packet */ |
358 | } else { | 365 | } else { |
359 | /* DHCP packets going to a server will use the GW feature */ | 366 | /* DHCP packets going to a server will use the GW feature */ |
360 | if (dhcp_rcp == BATADV_DHCP_TO_SERVER) { | 367 | if (dhcp_rcp == BATADV_DHCP_TO_SERVER) { |
361 | ret = batadv_gw_out_of_range(bat_priv, skb); | 368 | ret = batadv_gw_out_of_range(bat_priv, skb); |
362 | if (ret) | 369 | if (ret) |
363 | goto dropped; | 370 | goto dropped; |
364 | ret = batadv_send_skb_via_gw(bat_priv, skb, vid); | 371 | ret = batadv_send_skb_via_gw(bat_priv, skb, vid); |
365 | } else if (mcast_single_orig) { | 372 | } else if (mcast_single_orig) { |
366 | ret = batadv_send_skb_unicast(bat_priv, skb, | 373 | ret = batadv_send_skb_unicast(bat_priv, skb, |
367 | BATADV_UNICAST, 0, | 374 | BATADV_UNICAST, 0, |
368 | mcast_single_orig, vid); | 375 | mcast_single_orig, vid); |
369 | } else { | 376 | } else { |
370 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, | 377 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, |
371 | skb)) | 378 | skb)) |
372 | goto dropped; | 379 | goto dropped; |
373 | 380 | ||
374 | batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); | 381 | batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); |
375 | 382 | ||
376 | ret = batadv_send_skb_via_tt(bat_priv, skb, dst_hint, | 383 | ret = batadv_send_skb_via_tt(bat_priv, skb, dst_hint, |
377 | vid); | 384 | vid); |
378 | } | 385 | } |
379 | if (ret != NET_XMIT_SUCCESS) | 386 | if (ret != NET_XMIT_SUCCESS) |
380 | goto dropped_freed; | 387 | goto dropped_freed; |
381 | } | 388 | } |
382 | 389 | ||
383 | batadv_inc_counter(bat_priv, BATADV_CNT_TX); | 390 | batadv_inc_counter(bat_priv, BATADV_CNT_TX); |
384 | batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); | 391 | batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); |
385 | goto end; | 392 | goto end; |
386 | 393 | ||
387 | dropped: | 394 | dropped: |
388 | kfree_skb(skb); | 395 | kfree_skb(skb); |
389 | dropped_freed: | 396 | dropped_freed: |
390 | batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); | 397 | batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); |
391 | end: | 398 | end: |
392 | if (mcast_single_orig) | 399 | if (mcast_single_orig) |
393 | batadv_orig_node_put(mcast_single_orig); | 400 | batadv_orig_node_put(mcast_single_orig); |
394 | if (primary_if) | 401 | if (primary_if) |
395 | batadv_hardif_put(primary_if); | 402 | batadv_hardif_put(primary_if); |
396 | return NETDEV_TX_OK; | 403 | return NETDEV_TX_OK; |
397 | } | 404 | } |
398 | 405 | ||
399 | /** | 406 | /** |
400 | * batadv_interface_rx() - receive ethernet frame on local batman-adv interface | 407 | * batadv_interface_rx() - receive ethernet frame on local batman-adv interface |
401 | * @soft_iface: local interface which will receive the ethernet frame | 408 | * @soft_iface: local interface which will receive the ethernet frame |
402 | * @skb: ethernet frame for @soft_iface | 409 | * @skb: ethernet frame for @soft_iface |
403 | * @hdr_size: size of already parsed batman-adv header | 410 | * @hdr_size: size of already parsed batman-adv header |
404 | * @orig_node: originator from which the batman-adv packet was sent | 411 | * @orig_node: originator from which the batman-adv packet was sent |
405 | * | 412 | * |
406 | * Sends a ethernet frame to the receive path of the local @soft_iface. | 413 | * Sends a ethernet frame to the receive path of the local @soft_iface. |
407 | * skb->data has still point to the batman-adv header with the size @hdr_size. | 414 | * skb->data has still point to the batman-adv header with the size @hdr_size. |
408 | * The caller has to have parsed this header already and made sure that at least | 415 | * The caller has to have parsed this header already and made sure that at least |
409 | * @hdr_size bytes are still available for pull in @skb. | 416 | * @hdr_size bytes are still available for pull in @skb. |
410 | * | 417 | * |
411 | * The packet may still get dropped. This can happen when the encapsulated | 418 | * The packet may still get dropped. This can happen when the encapsulated |
412 | * ethernet frame is invalid or contains again an batman-adv packet. Also | 419 | * ethernet frame is invalid or contains again an batman-adv packet. Also |
413 | * unicast packets will be dropped directly when it was sent between two | 420 | * unicast packets will be dropped directly when it was sent between two |
414 | * isolated clients. | 421 | * isolated clients. |
415 | */ | 422 | */ |
416 | void batadv_interface_rx(struct net_device *soft_iface, | 423 | void batadv_interface_rx(struct net_device *soft_iface, |
417 | struct sk_buff *skb, int hdr_size, | 424 | struct sk_buff *skb, int hdr_size, |
418 | struct batadv_orig_node *orig_node) | 425 | struct batadv_orig_node *orig_node) |
419 | { | 426 | { |
420 | struct batadv_bcast_packet *batadv_bcast_packet; | 427 | struct batadv_bcast_packet *batadv_bcast_packet; |
421 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 428 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
422 | struct vlan_ethhdr *vhdr; | 429 | struct vlan_ethhdr *vhdr; |
423 | struct ethhdr *ethhdr; | 430 | struct ethhdr *ethhdr; |
424 | unsigned short vid; | 431 | unsigned short vid; |
425 | bool is_bcast; | 432 | bool is_bcast; |
426 | 433 | ||
427 | batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; | 434 | batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; |
428 | is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); | 435 | is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); |
429 | 436 | ||
430 | skb_pull_rcsum(skb, hdr_size); | 437 | skb_pull_rcsum(skb, hdr_size); |
431 | skb_reset_mac_header(skb); | 438 | skb_reset_mac_header(skb); |
432 | 439 | ||
433 | /* clean the netfilter state now that the batman-adv header has been | 440 | /* clean the netfilter state now that the batman-adv header has been |
434 | * removed | 441 | * removed |
435 | */ | 442 | */ |
436 | nf_reset(skb); | 443 | nf_reset(skb); |
437 | 444 | ||
438 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | 445 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) |
439 | goto dropped; | 446 | goto dropped; |
440 | 447 | ||
441 | vid = batadv_get_vid(skb, 0); | 448 | vid = batadv_get_vid(skb, 0); |
442 | ethhdr = eth_hdr(skb); | 449 | ethhdr = eth_hdr(skb); |
443 | 450 | ||
444 | switch (ntohs(ethhdr->h_proto)) { | 451 | switch (ntohs(ethhdr->h_proto)) { |
445 | case ETH_P_8021Q: | 452 | case ETH_P_8021Q: |
446 | if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) | 453 | if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) |
447 | goto dropped; | 454 | goto dropped; |
448 | 455 | ||
449 | vhdr = (struct vlan_ethhdr *)skb->data; | 456 | vhdr = (struct vlan_ethhdr *)skb->data; |
450 | 457 | ||
451 | /* drop batman-in-batman packets to prevent loops */ | 458 | /* drop batman-in-batman packets to prevent loops */ |
452 | if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) | 459 | if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) |
453 | break; | 460 | break; |
454 | 461 | ||
455 | /* fall through */ | 462 | /* fall through */ |
456 | case ETH_P_BATMAN: | 463 | case ETH_P_BATMAN: |
457 | goto dropped; | 464 | goto dropped; |
458 | } | 465 | } |
459 | 466 | ||
460 | /* skb->dev & skb->pkt_type are set here */ | 467 | /* skb->dev & skb->pkt_type are set here */ |
461 | skb->protocol = eth_type_trans(skb, soft_iface); | 468 | skb->protocol = eth_type_trans(skb, soft_iface); |
462 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | 469 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); |
463 | 470 | ||
464 | batadv_inc_counter(bat_priv, BATADV_CNT_RX); | 471 | batadv_inc_counter(bat_priv, BATADV_CNT_RX); |
465 | batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, | 472 | batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, |
466 | skb->len + ETH_HLEN); | 473 | skb->len + ETH_HLEN); |
467 | 474 | ||
468 | /* Let the bridge loop avoidance check the packet. If will | 475 | /* Let the bridge loop avoidance check the packet. If will |
469 | * not handle it, we can safely push it up. | 476 | * not handle it, we can safely push it up. |
470 | */ | 477 | */ |
471 | if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) | 478 | if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) |
472 | goto out; | 479 | goto out; |
473 | 480 | ||
474 | if (orig_node) | 481 | if (orig_node) |
475 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, | 482 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, |
476 | ethhdr->h_source, vid); | 483 | ethhdr->h_source, vid); |
477 | 484 | ||
478 | if (is_multicast_ether_addr(ethhdr->h_dest)) { | 485 | if (is_multicast_ether_addr(ethhdr->h_dest)) { |
479 | /* set the mark on broadcast packets if AP isolation is ON and | 486 | /* set the mark on broadcast packets if AP isolation is ON and |
480 | * the packet is coming from an "isolated" client | 487 | * the packet is coming from an "isolated" client |
481 | */ | 488 | */ |
482 | if (batadv_vlan_ap_isola_get(bat_priv, vid) && | 489 | if (batadv_vlan_ap_isola_get(bat_priv, vid) && |
483 | batadv_tt_global_is_isolated(bat_priv, ethhdr->h_source, | 490 | batadv_tt_global_is_isolated(bat_priv, ethhdr->h_source, |
484 | vid)) { | 491 | vid)) { |
485 | /* save bits in skb->mark not covered by the mask and | 492 | /* save bits in skb->mark not covered by the mask and |
486 | * apply the mark on the rest | 493 | * apply the mark on the rest |
487 | */ | 494 | */ |
488 | skb->mark &= ~bat_priv->isolation_mark_mask; | 495 | skb->mark &= ~bat_priv->isolation_mark_mask; |
489 | skb->mark |= bat_priv->isolation_mark; | 496 | skb->mark |= bat_priv->isolation_mark; |
490 | } | 497 | } |
491 | } else if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, | 498 | } else if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, |
492 | ethhdr->h_dest, vid)) { | 499 | ethhdr->h_dest, vid)) { |
493 | goto dropped; | 500 | goto dropped; |
494 | } | 501 | } |
495 | 502 | ||
496 | netif_rx(skb); | 503 | netif_rx(skb); |
497 | goto out; | 504 | goto out; |
498 | 505 | ||
499 | dropped: | 506 | dropped: |
500 | kfree_skb(skb); | 507 | kfree_skb(skb); |
501 | out: | 508 | out: |
502 | return; | 509 | return; |
503 | } | 510 | } |
504 | 511 | ||
505 | /** | 512 | /** |
506 | * batadv_softif_vlan_release() - release vlan from lists and queue for free | 513 | * batadv_softif_vlan_release() - release vlan from lists and queue for free |
507 | * after rcu grace period | 514 | * after rcu grace period |
508 | * @ref: kref pointer of the vlan object | 515 | * @ref: kref pointer of the vlan object |
509 | */ | 516 | */ |
510 | static void batadv_softif_vlan_release(struct kref *ref) | 517 | static void batadv_softif_vlan_release(struct kref *ref) |
511 | { | 518 | { |
512 | struct batadv_softif_vlan *vlan; | 519 | struct batadv_softif_vlan *vlan; |
513 | 520 | ||
514 | vlan = container_of(ref, struct batadv_softif_vlan, refcount); | 521 | vlan = container_of(ref, struct batadv_softif_vlan, refcount); |
515 | 522 | ||
516 | spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock); | 523 | spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock); |
517 | hlist_del_rcu(&vlan->list); | 524 | hlist_del_rcu(&vlan->list); |
518 | spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock); | 525 | spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock); |
519 | 526 | ||
520 | kfree_rcu(vlan, rcu); | 527 | kfree_rcu(vlan, rcu); |
521 | } | 528 | } |
522 | 529 | ||
523 | /** | 530 | /** |
524 | * batadv_softif_vlan_put() - decrease the vlan object refcounter and | 531 | * batadv_softif_vlan_put() - decrease the vlan object refcounter and |
525 | * possibly release it | 532 | * possibly release it |
526 | * @vlan: the vlan object to release | 533 | * @vlan: the vlan object to release |
527 | */ | 534 | */ |
528 | void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan) | 535 | void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan) |
529 | { | 536 | { |
530 | if (!vlan) | 537 | if (!vlan) |
531 | return; | 538 | return; |
532 | 539 | ||
533 | kref_put(&vlan->refcount, batadv_softif_vlan_release); | 540 | kref_put(&vlan->refcount, batadv_softif_vlan_release); |
534 | } | 541 | } |
535 | 542 | ||
536 | /** | 543 | /** |
537 | * batadv_softif_vlan_get() - get the vlan object for a specific vid | 544 | * batadv_softif_vlan_get() - get the vlan object for a specific vid |
538 | * @bat_priv: the bat priv with all the soft interface information | 545 | * @bat_priv: the bat priv with all the soft interface information |
539 | * @vid: the identifier of the vlan object to retrieve | 546 | * @vid: the identifier of the vlan object to retrieve |
540 | * | 547 | * |
541 | * Return: the private data of the vlan matching the vid passed as argument or | 548 | * Return: the private data of the vlan matching the vid passed as argument or |
542 | * NULL otherwise. The refcounter of the returned object is incremented by 1. | 549 | * NULL otherwise. The refcounter of the returned object is incremented by 1. |
543 | */ | 550 | */ |
544 | struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv, | 551 | struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv, |
545 | unsigned short vid) | 552 | unsigned short vid) |
546 | { | 553 | { |
547 | struct batadv_softif_vlan *vlan_tmp, *vlan = NULL; | 554 | struct batadv_softif_vlan *vlan_tmp, *vlan = NULL; |
548 | 555 | ||
549 | rcu_read_lock(); | 556 | rcu_read_lock(); |
550 | hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) { | 557 | hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) { |
551 | if (vlan_tmp->vid != vid) | 558 | if (vlan_tmp->vid != vid) |
552 | continue; | 559 | continue; |
553 | 560 | ||
554 | if (!kref_get_unless_zero(&vlan_tmp->refcount)) | 561 | if (!kref_get_unless_zero(&vlan_tmp->refcount)) |
555 | continue; | 562 | continue; |
556 | 563 | ||
557 | vlan = vlan_tmp; | 564 | vlan = vlan_tmp; |
558 | break; | 565 | break; |
559 | } | 566 | } |
560 | rcu_read_unlock(); | 567 | rcu_read_unlock(); |
561 | 568 | ||
562 | return vlan; | 569 | return vlan; |
563 | } | 570 | } |
564 | 571 | ||
565 | /** | 572 | /** |
566 | * batadv_softif_create_vlan() - allocate the needed resources for a new vlan | 573 | * batadv_softif_create_vlan() - allocate the needed resources for a new vlan |
567 | * @bat_priv: the bat priv with all the soft interface information | 574 | * @bat_priv: the bat priv with all the soft interface information |
568 | * @vid: the VLAN identifier | 575 | * @vid: the VLAN identifier |
569 | * | 576 | * |
570 | * Return: 0 on success, a negative error otherwise. | 577 | * Return: 0 on success, a negative error otherwise. |
571 | */ | 578 | */ |
572 | int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) | 579 | int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) |
573 | { | 580 | { |
574 | struct batadv_softif_vlan *vlan; | 581 | struct batadv_softif_vlan *vlan; |
575 | int err; | 582 | int err; |
576 | 583 | ||
577 | spin_lock_bh(&bat_priv->softif_vlan_list_lock); | 584 | spin_lock_bh(&bat_priv->softif_vlan_list_lock); |
578 | 585 | ||
579 | vlan = batadv_softif_vlan_get(bat_priv, vid); | 586 | vlan = batadv_softif_vlan_get(bat_priv, vid); |
580 | if (vlan) { | 587 | if (vlan) { |
581 | batadv_softif_vlan_put(vlan); | 588 | batadv_softif_vlan_put(vlan); |
582 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | 589 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); |
583 | return -EEXIST; | 590 | return -EEXIST; |
584 | } | 591 | } |
585 | 592 | ||
586 | vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); | 593 | vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); |
587 | if (!vlan) { | 594 | if (!vlan) { |
588 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | 595 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); |
589 | return -ENOMEM; | 596 | return -ENOMEM; |
590 | } | 597 | } |
591 | 598 | ||
592 | vlan->bat_priv = bat_priv; | 599 | vlan->bat_priv = bat_priv; |
593 | vlan->vid = vid; | 600 | vlan->vid = vid; |
594 | kref_init(&vlan->refcount); | 601 | kref_init(&vlan->refcount); |
595 | 602 | ||
596 | atomic_set(&vlan->ap_isolation, 0); | 603 | atomic_set(&vlan->ap_isolation, 0); |
597 | 604 | ||
598 | kref_get(&vlan->refcount); | 605 | kref_get(&vlan->refcount); |
599 | hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list); | 606 | hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list); |
600 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | 607 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); |
601 | 608 | ||
602 | /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the | 609 | /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the |
603 | * sleeping behavior of the sysfs functions and the fs_reclaim lock | 610 | * sleeping behavior of the sysfs functions and the fs_reclaim lock |
604 | */ | 611 | */ |
605 | err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); | 612 | err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); |
606 | if (err) { | 613 | if (err) { |
607 | /* ref for the function */ | 614 | /* ref for the function */ |
608 | batadv_softif_vlan_put(vlan); | 615 | batadv_softif_vlan_put(vlan); |
609 | 616 | ||
610 | /* ref for the list */ | 617 | /* ref for the list */ |
611 | batadv_softif_vlan_put(vlan); | 618 | batadv_softif_vlan_put(vlan); |
612 | return err; | 619 | return err; |
613 | } | 620 | } |
614 | 621 | ||
615 | /* add a new TT local entry. This one will be marked with the NOPURGE | 622 | /* add a new TT local entry. This one will be marked with the NOPURGE |
616 | * flag | 623 | * flag |
617 | */ | 624 | */ |
618 | batadv_tt_local_add(bat_priv->soft_iface, | 625 | batadv_tt_local_add(bat_priv->soft_iface, |
619 | bat_priv->soft_iface->dev_addr, vid, | 626 | bat_priv->soft_iface->dev_addr, vid, |
620 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); | 627 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); |
621 | 628 | ||
622 | /* don't return reference to new softif_vlan */ | 629 | /* don't return reference to new softif_vlan */ |
623 | batadv_softif_vlan_put(vlan); | 630 | batadv_softif_vlan_put(vlan); |
624 | 631 | ||
625 | return 0; | 632 | return 0; |
626 | } | 633 | } |
627 | 634 | ||
628 | /** | 635 | /** |
629 | * batadv_softif_destroy_vlan() - remove and destroy a softif_vlan object | 636 | * batadv_softif_destroy_vlan() - remove and destroy a softif_vlan object |
630 | * @bat_priv: the bat priv with all the soft interface information | 637 | * @bat_priv: the bat priv with all the soft interface information |
631 | * @vlan: the object to remove | 638 | * @vlan: the object to remove |
632 | */ | 639 | */ |
633 | static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, | 640 | static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, |
634 | struct batadv_softif_vlan *vlan) | 641 | struct batadv_softif_vlan *vlan) |
635 | { | 642 | { |
636 | /* explicitly remove the associated TT local entry because it is marked | 643 | /* explicitly remove the associated TT local entry because it is marked |
637 | * with the NOPURGE flag | 644 | * with the NOPURGE flag |
638 | */ | 645 | */ |
639 | batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr, | 646 | batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr, |
640 | vlan->vid, "vlan interface destroyed", false); | 647 | vlan->vid, "vlan interface destroyed", false); |
641 | 648 | ||
642 | batadv_sysfs_del_vlan(bat_priv, vlan); | 649 | batadv_sysfs_del_vlan(bat_priv, vlan); |
643 | batadv_softif_vlan_put(vlan); | 650 | batadv_softif_vlan_put(vlan); |
644 | } | 651 | } |
645 | 652 | ||
646 | /** | 653 | /** |
647 | * batadv_interface_add_vid() - ndo_add_vid API implementation | 654 | * batadv_interface_add_vid() - ndo_add_vid API implementation |
648 | * @dev: the netdev of the mesh interface | 655 | * @dev: the netdev of the mesh interface |
649 | * @proto: protocol of the the vlan id | 656 | * @proto: protocol of the the vlan id |
650 | * @vid: identifier of the new vlan | 657 | * @vid: identifier of the new vlan |
651 | * | 658 | * |
652 | * Set up all the internal structures for handling the new vlan on top of the | 659 | * Set up all the internal structures for handling the new vlan on top of the |
653 | * mesh interface | 660 | * mesh interface |
654 | * | 661 | * |
655 | * Return: 0 on success or a negative error code in case of failure. | 662 | * Return: 0 on success or a negative error code in case of failure. |
656 | */ | 663 | */ |
657 | static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, | 664 | static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, |
658 | unsigned short vid) | 665 | unsigned short vid) |
659 | { | 666 | { |
660 | struct batadv_priv *bat_priv = netdev_priv(dev); | 667 | struct batadv_priv *bat_priv = netdev_priv(dev); |
661 | struct batadv_softif_vlan *vlan; | 668 | struct batadv_softif_vlan *vlan; |
662 | int ret; | 669 | int ret; |
663 | 670 | ||
664 | /* only 802.1Q vlans are supported. | 671 | /* only 802.1Q vlans are supported. |
665 | * batman-adv does not know how to handle other types | 672 | * batman-adv does not know how to handle other types |
666 | */ | 673 | */ |
667 | if (proto != htons(ETH_P_8021Q)) | 674 | if (proto != htons(ETH_P_8021Q)) |
668 | return -EINVAL; | 675 | return -EINVAL; |
669 | 676 | ||
670 | vid |= BATADV_VLAN_HAS_TAG; | 677 | vid |= BATADV_VLAN_HAS_TAG; |
671 | 678 | ||
672 | /* if a new vlan is getting created and it already exists, it means that | 679 | /* if a new vlan is getting created and it already exists, it means that |
673 | * it was not deleted yet. batadv_softif_vlan_get() increases the | 680 | * it was not deleted yet. batadv_softif_vlan_get() increases the |
674 | * refcount in order to revive the object. | 681 | * refcount in order to revive the object. |
675 | * | 682 | * |
676 | * if it does not exist then create it. | 683 | * if it does not exist then create it. |
677 | */ | 684 | */ |
678 | vlan = batadv_softif_vlan_get(bat_priv, vid); | 685 | vlan = batadv_softif_vlan_get(bat_priv, vid); |
679 | if (!vlan) | 686 | if (!vlan) |
680 | return batadv_softif_create_vlan(bat_priv, vid); | 687 | return batadv_softif_create_vlan(bat_priv, vid); |
681 | 688 | ||
682 | /* recreate the sysfs object if it was already destroyed (and it should | 689 | /* recreate the sysfs object if it was already destroyed (and it should |
683 | * be since we received a kill_vid() for this vlan | 690 | * be since we received a kill_vid() for this vlan |
684 | */ | 691 | */ |
685 | if (!vlan->kobj) { | 692 | if (!vlan->kobj) { |
686 | ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); | 693 | ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); |
687 | if (ret) { | 694 | if (ret) { |
688 | batadv_softif_vlan_put(vlan); | 695 | batadv_softif_vlan_put(vlan); |
689 | return ret; | 696 | return ret; |
690 | } | 697 | } |
691 | } | 698 | } |
692 | 699 | ||
693 | /* add a new TT local entry. This one will be marked with the NOPURGE | 700 | /* add a new TT local entry. This one will be marked with the NOPURGE |
694 | * flag. This must be added again, even if the vlan object already | 701 | * flag. This must be added again, even if the vlan object already |
695 | * exists, because the entry was deleted by kill_vid() | 702 | * exists, because the entry was deleted by kill_vid() |
696 | */ | 703 | */ |
697 | batadv_tt_local_add(bat_priv->soft_iface, | 704 | batadv_tt_local_add(bat_priv->soft_iface, |
698 | bat_priv->soft_iface->dev_addr, vid, | 705 | bat_priv->soft_iface->dev_addr, vid, |
699 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); | 706 | BATADV_NULL_IFINDEX, BATADV_NO_MARK); |
700 | 707 | ||
701 | return 0; | 708 | return 0; |
702 | } | 709 | } |
703 | 710 | ||
704 | /** | 711 | /** |
705 | * batadv_interface_kill_vid() - ndo_kill_vid API implementation | 712 | * batadv_interface_kill_vid() - ndo_kill_vid API implementation |
706 | * @dev: the netdev of the mesh interface | 713 | * @dev: the netdev of the mesh interface |
707 | * @proto: protocol of the the vlan id | 714 | * @proto: protocol of the the vlan id |
708 | * @vid: identifier of the deleted vlan | 715 | * @vid: identifier of the deleted vlan |
709 | * | 716 | * |
710 | * Destroy all the internal structures used to handle the vlan identified by vid | 717 | * Destroy all the internal structures used to handle the vlan identified by vid |
711 | * on top of the mesh interface | 718 | * on top of the mesh interface |
712 | * | 719 | * |
713 | * Return: 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q | 720 | * Return: 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q |
714 | * or -ENOENT if the specified vlan id wasn't registered. | 721 | * or -ENOENT if the specified vlan id wasn't registered. |
715 | */ | 722 | */ |
716 | static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, | 723 | static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, |
717 | unsigned short vid) | 724 | unsigned short vid) |
718 | { | 725 | { |
719 | struct batadv_priv *bat_priv = netdev_priv(dev); | 726 | struct batadv_priv *bat_priv = netdev_priv(dev); |
720 | struct batadv_softif_vlan *vlan; | 727 | struct batadv_softif_vlan *vlan; |
721 | 728 | ||
722 | /* only 802.1Q vlans are supported. batman-adv does not know how to | 729 | /* only 802.1Q vlans are supported. batman-adv does not know how to |
723 | * handle other types | 730 | * handle other types |
724 | */ | 731 | */ |
725 | if (proto != htons(ETH_P_8021Q)) | 732 | if (proto != htons(ETH_P_8021Q)) |
726 | return -EINVAL; | 733 | return -EINVAL; |
727 | 734 | ||
728 | vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); | 735 | vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); |
729 | if (!vlan) | 736 | if (!vlan) |
730 | return -ENOENT; | 737 | return -ENOENT; |
731 | 738 | ||
732 | batadv_softif_destroy_vlan(bat_priv, vlan); | 739 | batadv_softif_destroy_vlan(bat_priv, vlan); |
733 | 740 | ||
734 | /* finally free the vlan object */ | 741 | /* finally free the vlan object */ |
735 | batadv_softif_vlan_put(vlan); | 742 | batadv_softif_vlan_put(vlan); |
736 | 743 | ||
737 | return 0; | 744 | return 0; |
738 | } | 745 | } |
739 | 746 | ||
740 | /* batman-adv network devices have devices nesting below it and are a special | 747 | /* batman-adv network devices have devices nesting below it and are a special |
741 | * "super class" of normal network devices; split their locks off into a | 748 | * "super class" of normal network devices; split their locks off into a |
742 | * separate class since they always nest. | 749 | * separate class since they always nest. |
743 | */ | 750 | */ |
744 | static struct lock_class_key batadv_netdev_xmit_lock_key; | 751 | static struct lock_class_key batadv_netdev_xmit_lock_key; |
745 | static struct lock_class_key batadv_netdev_addr_lock_key; | 752 | static struct lock_class_key batadv_netdev_addr_lock_key; |
746 | 753 | ||
747 | /** | 754 | /** |
748 | * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue | 755 | * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue |
749 | * @dev: device which owns the tx queue | 756 | * @dev: device which owns the tx queue |
750 | * @txq: tx queue to modify | 757 | * @txq: tx queue to modify |
751 | * @_unused: always NULL | 758 | * @_unused: always NULL |
752 | */ | 759 | */ |
753 | static void batadv_set_lockdep_class_one(struct net_device *dev, | 760 | static void batadv_set_lockdep_class_one(struct net_device *dev, |
754 | struct netdev_queue *txq, | 761 | struct netdev_queue *txq, |
755 | void *_unused) | 762 | void *_unused) |
756 | { | 763 | { |
757 | lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); | 764 | lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); |
758 | } | 765 | } |
759 | 766 | ||
760 | /** | 767 | /** |
761 | * batadv_set_lockdep_class() - Set txq and addr_list lockdep class | 768 | * batadv_set_lockdep_class() - Set txq and addr_list lockdep class |
762 | * @dev: network device to modify | 769 | * @dev: network device to modify |
763 | */ | 770 | */ |
764 | static void batadv_set_lockdep_class(struct net_device *dev) | 771 | static void batadv_set_lockdep_class(struct net_device *dev) |
765 | { | 772 | { |
766 | lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); | 773 | lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); |
767 | netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); | 774 | netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); |
768 | } | 775 | } |
769 | 776 | ||
770 | /** | 777 | /** |
771 | * batadv_softif_init_late() - late stage initialization of soft interface | 778 | * batadv_softif_init_late() - late stage initialization of soft interface |
772 | * @dev: registered network device to modify | 779 | * @dev: registered network device to modify |
773 | * | 780 | * |
774 | * Return: error code on failures | 781 | * Return: error code on failures |
775 | */ | 782 | */ |
776 | static int batadv_softif_init_late(struct net_device *dev) | 783 | static int batadv_softif_init_late(struct net_device *dev) |
777 | { | 784 | { |
778 | struct batadv_priv *bat_priv; | 785 | struct batadv_priv *bat_priv; |
779 | u32 random_seqno; | 786 | u32 random_seqno; |
780 | int ret; | 787 | int ret; |
781 | size_t cnt_len = sizeof(u64) * BATADV_CNT_NUM; | 788 | size_t cnt_len = sizeof(u64) * BATADV_CNT_NUM; |
782 | 789 | ||
783 | batadv_set_lockdep_class(dev); | 790 | batadv_set_lockdep_class(dev); |
784 | 791 | ||
785 | bat_priv = netdev_priv(dev); | 792 | bat_priv = netdev_priv(dev); |
786 | bat_priv->soft_iface = dev; | 793 | bat_priv->soft_iface = dev; |
787 | 794 | ||
788 | /* batadv_interface_stats() needs to be available as soon as | 795 | /* batadv_interface_stats() needs to be available as soon as |
789 | * register_netdevice() has been called | 796 | * register_netdevice() has been called |
790 | */ | 797 | */ |
791 | bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(u64)); | 798 | bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(u64)); |
792 | if (!bat_priv->bat_counters) | 799 | if (!bat_priv->bat_counters) |
793 | return -ENOMEM; | 800 | return -ENOMEM; |
794 | 801 | ||
795 | atomic_set(&bat_priv->aggregated_ogms, 1); | 802 | atomic_set(&bat_priv->aggregated_ogms, 1); |
796 | atomic_set(&bat_priv->bonding, 0); | 803 | atomic_set(&bat_priv->bonding, 0); |
797 | #ifdef CONFIG_BATMAN_ADV_BLA | 804 | #ifdef CONFIG_BATMAN_ADV_BLA |
798 | atomic_set(&bat_priv->bridge_loop_avoidance, 1); | 805 | atomic_set(&bat_priv->bridge_loop_avoidance, 1); |
799 | #endif | 806 | #endif |
800 | #ifdef CONFIG_BATMAN_ADV_DAT | 807 | #ifdef CONFIG_BATMAN_ADV_DAT |
801 | atomic_set(&bat_priv->distributed_arp_table, 1); | 808 | atomic_set(&bat_priv->distributed_arp_table, 1); |
802 | #endif | 809 | #endif |
803 | #ifdef CONFIG_BATMAN_ADV_MCAST | 810 | #ifdef CONFIG_BATMAN_ADV_MCAST |
804 | bat_priv->mcast.querier_ipv4.exists = false; | 811 | bat_priv->mcast.querier_ipv4.exists = false; |
805 | bat_priv->mcast.querier_ipv4.shadowing = false; | 812 | bat_priv->mcast.querier_ipv4.shadowing = false; |
806 | bat_priv->mcast.querier_ipv6.exists = false; | 813 | bat_priv->mcast.querier_ipv6.exists = false; |
807 | bat_priv->mcast.querier_ipv6.shadowing = false; | 814 | bat_priv->mcast.querier_ipv6.shadowing = false; |
808 | bat_priv->mcast.flags = BATADV_NO_FLAGS; | 815 | bat_priv->mcast.flags = BATADV_NO_FLAGS; |
809 | atomic_set(&bat_priv->multicast_mode, 1); | 816 | atomic_set(&bat_priv->multicast_mode, 1); |
810 | atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); | 817 | atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); |
811 | atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); | 818 | atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); |
812 | atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); | 819 | atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); |
813 | #endif | 820 | #endif |
814 | atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); | 821 | atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); |
815 | atomic_set(&bat_priv->gw.bandwidth_down, 100); | 822 | atomic_set(&bat_priv->gw.bandwidth_down, 100); |
816 | atomic_set(&bat_priv->gw.bandwidth_up, 20); | 823 | atomic_set(&bat_priv->gw.bandwidth_up, 20); |
817 | atomic_set(&bat_priv->orig_interval, 1000); | 824 | atomic_set(&bat_priv->orig_interval, 1000); |
818 | atomic_set(&bat_priv->hop_penalty, 30); | 825 | atomic_set(&bat_priv->hop_penalty, 30); |
819 | #ifdef CONFIG_BATMAN_ADV_DEBUG | 826 | #ifdef CONFIG_BATMAN_ADV_DEBUG |
820 | atomic_set(&bat_priv->log_level, 0); | 827 | atomic_set(&bat_priv->log_level, 0); |
821 | #endif | 828 | #endif |
822 | atomic_set(&bat_priv->fragmentation, 1); | 829 | atomic_set(&bat_priv->fragmentation, 1); |
823 | atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN); | 830 | atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN); |
824 | atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); | 831 | atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); |
825 | atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); | 832 | atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); |
826 | 833 | ||
827 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); | 834 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); |
828 | atomic_set(&bat_priv->bcast_seqno, 1); | 835 | atomic_set(&bat_priv->bcast_seqno, 1); |
829 | atomic_set(&bat_priv->tt.vn, 0); | 836 | atomic_set(&bat_priv->tt.vn, 0); |
830 | atomic_set(&bat_priv->tt.local_changes, 0); | 837 | atomic_set(&bat_priv->tt.local_changes, 0); |
831 | atomic_set(&bat_priv->tt.ogm_append_cnt, 0); | 838 | atomic_set(&bat_priv->tt.ogm_append_cnt, 0); |
832 | #ifdef CONFIG_BATMAN_ADV_BLA | 839 | #ifdef CONFIG_BATMAN_ADV_BLA |
833 | atomic_set(&bat_priv->bla.num_requests, 0); | 840 | atomic_set(&bat_priv->bla.num_requests, 0); |
834 | #endif | 841 | #endif |
835 | atomic_set(&bat_priv->tp_num, 0); | 842 | atomic_set(&bat_priv->tp_num, 0); |
836 | 843 | ||
837 | bat_priv->tt.last_changeset = NULL; | 844 | bat_priv->tt.last_changeset = NULL; |
838 | bat_priv->tt.last_changeset_len = 0; | 845 | bat_priv->tt.last_changeset_len = 0; |
839 | bat_priv->isolation_mark = 0; | 846 | bat_priv->isolation_mark = 0; |
840 | bat_priv->isolation_mark_mask = 0; | 847 | bat_priv->isolation_mark_mask = 0; |
841 | 848 | ||
842 | /* randomize initial seqno to avoid collision */ | 849 | /* randomize initial seqno to avoid collision */ |
843 | get_random_bytes(&random_seqno, sizeof(random_seqno)); | 850 | get_random_bytes(&random_seqno, sizeof(random_seqno)); |
844 | atomic_set(&bat_priv->frag_seqno, random_seqno); | 851 | atomic_set(&bat_priv->frag_seqno, random_seqno); |
845 | 852 | ||
846 | bat_priv->primary_if = NULL; | 853 | bat_priv->primary_if = NULL; |
847 | 854 | ||
848 | batadv_nc_init_bat_priv(bat_priv); | 855 | batadv_nc_init_bat_priv(bat_priv); |
849 | 856 | ||
850 | ret = batadv_algo_select(bat_priv, batadv_routing_algo); | 857 | ret = batadv_algo_select(bat_priv, batadv_routing_algo); |
851 | if (ret < 0) | 858 | if (ret < 0) |
852 | goto free_bat_counters; | 859 | goto free_bat_counters; |
853 | 860 | ||
854 | ret = batadv_debugfs_add_meshif(dev); | 861 | ret = batadv_debugfs_add_meshif(dev); |
855 | if (ret < 0) | 862 | if (ret < 0) |
856 | goto free_bat_counters; | 863 | goto free_bat_counters; |
857 | 864 | ||
858 | ret = batadv_mesh_init(dev); | 865 | ret = batadv_mesh_init(dev); |
859 | if (ret < 0) | 866 | if (ret < 0) |
860 | goto unreg_debugfs; | 867 | goto unreg_debugfs; |
861 | 868 | ||
862 | return 0; | 869 | return 0; |
863 | 870 | ||
864 | unreg_debugfs: | 871 | unreg_debugfs: |
865 | batadv_debugfs_del_meshif(dev); | 872 | batadv_debugfs_del_meshif(dev); |
866 | free_bat_counters: | 873 | free_bat_counters: |
867 | free_percpu(bat_priv->bat_counters); | 874 | free_percpu(bat_priv->bat_counters); |
868 | bat_priv->bat_counters = NULL; | 875 | bat_priv->bat_counters = NULL; |
869 | 876 | ||
870 | return ret; | 877 | return ret; |
871 | } | 878 | } |
872 | 879 | ||
873 | /** | 880 | /** |
874 | * batadv_softif_slave_add() - Add a slave interface to a batadv_soft_interface | 881 | * batadv_softif_slave_add() - Add a slave interface to a batadv_soft_interface |
875 | * @dev: batadv_soft_interface used as master interface | 882 | * @dev: batadv_soft_interface used as master interface |
876 | * @slave_dev: net_device which should become the slave interface | 883 | * @slave_dev: net_device which should become the slave interface |
877 | * @extack: extended ACK report struct | 884 | * @extack: extended ACK report struct |
878 | * | 885 | * |
879 | * Return: 0 if successful or error otherwise. | 886 | * Return: 0 if successful or error otherwise. |
880 | */ | 887 | */ |
881 | static int batadv_softif_slave_add(struct net_device *dev, | 888 | static int batadv_softif_slave_add(struct net_device *dev, |
882 | struct net_device *slave_dev, | 889 | struct net_device *slave_dev, |
883 | struct netlink_ext_ack *extack) | 890 | struct netlink_ext_ack *extack) |
884 | { | 891 | { |
885 | struct batadv_hard_iface *hard_iface; | 892 | struct batadv_hard_iface *hard_iface; |
886 | struct net *net = dev_net(dev); | 893 | struct net *net = dev_net(dev); |
887 | int ret = -EINVAL; | 894 | int ret = -EINVAL; |
888 | 895 | ||
889 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); | 896 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); |
890 | if (!hard_iface || hard_iface->soft_iface) | 897 | if (!hard_iface || hard_iface->soft_iface) |
891 | goto out; | 898 | goto out; |
892 | 899 | ||
893 | ret = batadv_hardif_enable_interface(hard_iface, net, dev->name); | 900 | ret = batadv_hardif_enable_interface(hard_iface, net, dev->name); |
894 | 901 | ||
895 | out: | 902 | out: |
896 | if (hard_iface) | 903 | if (hard_iface) |
897 | batadv_hardif_put(hard_iface); | 904 | batadv_hardif_put(hard_iface); |
898 | return ret; | 905 | return ret; |
899 | } | 906 | } |
900 | 907 | ||
901 | /** | 908 | /** |
902 | * batadv_softif_slave_del() - Delete a slave iface from a batadv_soft_interface | 909 | * batadv_softif_slave_del() - Delete a slave iface from a batadv_soft_interface |
903 | * @dev: batadv_soft_interface used as master interface | 910 | * @dev: batadv_soft_interface used as master interface |
904 | * @slave_dev: net_device which should be removed from the master interface | 911 | * @slave_dev: net_device which should be removed from the master interface |
905 | * | 912 | * |
906 | * Return: 0 if successful or error otherwise. | 913 | * Return: 0 if successful or error otherwise. |
907 | */ | 914 | */ |
908 | static int batadv_softif_slave_del(struct net_device *dev, | 915 | static int batadv_softif_slave_del(struct net_device *dev, |
909 | struct net_device *slave_dev) | 916 | struct net_device *slave_dev) |
910 | { | 917 | { |
911 | struct batadv_hard_iface *hard_iface; | 918 | struct batadv_hard_iface *hard_iface; |
912 | int ret = -EINVAL; | 919 | int ret = -EINVAL; |
913 | 920 | ||
914 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); | 921 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); |
915 | 922 | ||
916 | if (!hard_iface || hard_iface->soft_iface != dev) | 923 | if (!hard_iface || hard_iface->soft_iface != dev) |
917 | goto out; | 924 | goto out; |
918 | 925 | ||
919 | batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP); | 926 | batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP); |
920 | ret = 0; | 927 | ret = 0; |
921 | 928 | ||
922 | out: | 929 | out: |
923 | if (hard_iface) | 930 | if (hard_iface) |
924 | batadv_hardif_put(hard_iface); | 931 | batadv_hardif_put(hard_iface); |
925 | return ret; | 932 | return ret; |
926 | } | 933 | } |
927 | 934 | ||
928 | static const struct net_device_ops batadv_netdev_ops = { | 935 | static const struct net_device_ops batadv_netdev_ops = { |
929 | .ndo_init = batadv_softif_init_late, | 936 | .ndo_init = batadv_softif_init_late, |
930 | .ndo_open = batadv_interface_open, | 937 | .ndo_open = batadv_interface_open, |
931 | .ndo_stop = batadv_interface_release, | 938 | .ndo_stop = batadv_interface_release, |
932 | .ndo_get_stats = batadv_interface_stats, | 939 | .ndo_get_stats = batadv_interface_stats, |
933 | .ndo_vlan_rx_add_vid = batadv_interface_add_vid, | 940 | .ndo_vlan_rx_add_vid = batadv_interface_add_vid, |
934 | .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid, | 941 | .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid, |
935 | .ndo_set_mac_address = batadv_interface_set_mac_addr, | 942 | .ndo_set_mac_address = batadv_interface_set_mac_addr, |
936 | .ndo_change_mtu = batadv_interface_change_mtu, | 943 | .ndo_change_mtu = batadv_interface_change_mtu, |
937 | .ndo_set_rx_mode = batadv_interface_set_rx_mode, | 944 | .ndo_set_rx_mode = batadv_interface_set_rx_mode, |
938 | .ndo_start_xmit = batadv_interface_tx, | 945 | .ndo_start_xmit = batadv_interface_tx, |
939 | .ndo_validate_addr = eth_validate_addr, | 946 | .ndo_validate_addr = eth_validate_addr, |
940 | .ndo_add_slave = batadv_softif_slave_add, | 947 | .ndo_add_slave = batadv_softif_slave_add, |
941 | .ndo_del_slave = batadv_softif_slave_del, | 948 | .ndo_del_slave = batadv_softif_slave_del, |
942 | }; | 949 | }; |
943 | 950 | ||
944 | static void batadv_get_drvinfo(struct net_device *dev, | 951 | static void batadv_get_drvinfo(struct net_device *dev, |
945 | struct ethtool_drvinfo *info) | 952 | struct ethtool_drvinfo *info) |
946 | { | 953 | { |
947 | strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); | 954 | strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); |
948 | strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); | 955 | strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); |
949 | strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); | 956 | strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); |
950 | strlcpy(info->bus_info, "batman", sizeof(info->bus_info)); | 957 | strlcpy(info->bus_info, "batman", sizeof(info->bus_info)); |
951 | } | 958 | } |
952 | 959 | ||
953 | /* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 | 960 | /* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 |
954 | * Declare each description string in struct.name[] to get fixed sized buffer | 961 | * Declare each description string in struct.name[] to get fixed sized buffer |
955 | * and compile time checking for strings longer than ETH_GSTRING_LEN. | 962 | * and compile time checking for strings longer than ETH_GSTRING_LEN. |
956 | */ | 963 | */ |
957 | static const struct { | 964 | static const struct { |
958 | const char name[ETH_GSTRING_LEN]; | 965 | const char name[ETH_GSTRING_LEN]; |
959 | } batadv_counters_strings[] = { | 966 | } batadv_counters_strings[] = { |
960 | { "tx" }, | 967 | { "tx" }, |
961 | { "tx_bytes" }, | 968 | { "tx_bytes" }, |
962 | { "tx_dropped" }, | 969 | { "tx_dropped" }, |
963 | { "rx" }, | 970 | { "rx" }, |
964 | { "rx_bytes" }, | 971 | { "rx_bytes" }, |
965 | { "forward" }, | 972 | { "forward" }, |
966 | { "forward_bytes" }, | 973 | { "forward_bytes" }, |
967 | { "mgmt_tx" }, | 974 | { "mgmt_tx" }, |
968 | { "mgmt_tx_bytes" }, | 975 | { "mgmt_tx_bytes" }, |
969 | { "mgmt_rx" }, | 976 | { "mgmt_rx" }, |
970 | { "mgmt_rx_bytes" }, | 977 | { "mgmt_rx_bytes" }, |
971 | { "frag_tx" }, | 978 | { "frag_tx" }, |
972 | { "frag_tx_bytes" }, | 979 | { "frag_tx_bytes" }, |
973 | { "frag_rx" }, | 980 | { "frag_rx" }, |
974 | { "frag_rx_bytes" }, | 981 | { "frag_rx_bytes" }, |
975 | { "frag_fwd" }, | 982 | { "frag_fwd" }, |
976 | { "frag_fwd_bytes" }, | 983 | { "frag_fwd_bytes" }, |
977 | { "tt_request_tx" }, | 984 | { "tt_request_tx" }, |
978 | { "tt_request_rx" }, | 985 | { "tt_request_rx" }, |
979 | { "tt_response_tx" }, | 986 | { "tt_response_tx" }, |
980 | { "tt_response_rx" }, | 987 | { "tt_response_rx" }, |
981 | { "tt_roam_adv_tx" }, | 988 | { "tt_roam_adv_tx" }, |
982 | { "tt_roam_adv_rx" }, | 989 | { "tt_roam_adv_rx" }, |
983 | #ifdef CONFIG_BATMAN_ADV_DAT | 990 | #ifdef CONFIG_BATMAN_ADV_DAT |
984 | { "dat_get_tx" }, | 991 | { "dat_get_tx" }, |
985 | { "dat_get_rx" }, | 992 | { "dat_get_rx" }, |
986 | { "dat_put_tx" }, | 993 | { "dat_put_tx" }, |
987 | { "dat_put_rx" }, | 994 | { "dat_put_rx" }, |
988 | { "dat_cached_reply_tx" }, | 995 | { "dat_cached_reply_tx" }, |
989 | #endif | 996 | #endif |
990 | #ifdef CONFIG_BATMAN_ADV_NC | 997 | #ifdef CONFIG_BATMAN_ADV_NC |
991 | { "nc_code" }, | 998 | { "nc_code" }, |
992 | { "nc_code_bytes" }, | 999 | { "nc_code_bytes" }, |
993 | { "nc_recode" }, | 1000 | { "nc_recode" }, |
994 | { "nc_recode_bytes" }, | 1001 | { "nc_recode_bytes" }, |
995 | { "nc_buffer" }, | 1002 | { "nc_buffer" }, |
996 | { "nc_decode" }, | 1003 | { "nc_decode" }, |
997 | { "nc_decode_bytes" }, | 1004 | { "nc_decode_bytes" }, |
998 | { "nc_decode_failed" }, | 1005 | { "nc_decode_failed" }, |
999 | { "nc_sniffed" }, | 1006 | { "nc_sniffed" }, |
1000 | #endif | 1007 | #endif |
1001 | }; | 1008 | }; |
1002 | 1009 | ||
1003 | static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data) | 1010 | static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data) |
1004 | { | 1011 | { |
1005 | if (stringset == ETH_SS_STATS) | 1012 | if (stringset == ETH_SS_STATS) |
1006 | memcpy(data, batadv_counters_strings, | 1013 | memcpy(data, batadv_counters_strings, |
1007 | sizeof(batadv_counters_strings)); | 1014 | sizeof(batadv_counters_strings)); |
1008 | } | 1015 | } |
1009 | 1016 | ||
1010 | static void batadv_get_ethtool_stats(struct net_device *dev, | 1017 | static void batadv_get_ethtool_stats(struct net_device *dev, |
1011 | struct ethtool_stats *stats, u64 *data) | 1018 | struct ethtool_stats *stats, u64 *data) |
1012 | { | 1019 | { |
1013 | struct batadv_priv *bat_priv = netdev_priv(dev); | 1020 | struct batadv_priv *bat_priv = netdev_priv(dev); |
1014 | int i; | 1021 | int i; |
1015 | 1022 | ||
1016 | for (i = 0; i < BATADV_CNT_NUM; i++) | 1023 | for (i = 0; i < BATADV_CNT_NUM; i++) |
1017 | data[i] = batadv_sum_counter(bat_priv, i); | 1024 | data[i] = batadv_sum_counter(bat_priv, i); |
1018 | } | 1025 | } |
1019 | 1026 | ||
1020 | static int batadv_get_sset_count(struct net_device *dev, int stringset) | 1027 | static int batadv_get_sset_count(struct net_device *dev, int stringset) |
1021 | { | 1028 | { |
1022 | if (stringset == ETH_SS_STATS) | 1029 | if (stringset == ETH_SS_STATS) |
1023 | return BATADV_CNT_NUM; | 1030 | return BATADV_CNT_NUM; |
1024 | 1031 | ||
1025 | return -EOPNOTSUPP; | 1032 | return -EOPNOTSUPP; |
1026 | } | 1033 | } |
1027 | 1034 | ||
1028 | static const struct ethtool_ops batadv_ethtool_ops = { | 1035 | static const struct ethtool_ops batadv_ethtool_ops = { |
1029 | .get_drvinfo = batadv_get_drvinfo, | 1036 | .get_drvinfo = batadv_get_drvinfo, |
1030 | .get_link = ethtool_op_get_link, | 1037 | .get_link = ethtool_op_get_link, |
1031 | .get_strings = batadv_get_strings, | 1038 | .get_strings = batadv_get_strings, |
1032 | .get_ethtool_stats = batadv_get_ethtool_stats, | 1039 | .get_ethtool_stats = batadv_get_ethtool_stats, |
1033 | .get_sset_count = batadv_get_sset_count, | 1040 | .get_sset_count = batadv_get_sset_count, |
1034 | }; | 1041 | }; |
1035 | 1042 | ||
1036 | /** | 1043 | /** |
1037 | * batadv_softif_free() - Deconstructor of batadv_soft_interface | 1044 | * batadv_softif_free() - Deconstructor of batadv_soft_interface |
1038 | * @dev: Device to cleanup and remove | 1045 | * @dev: Device to cleanup and remove |
1039 | */ | 1046 | */ |
1040 | static void batadv_softif_free(struct net_device *dev) | 1047 | static void batadv_softif_free(struct net_device *dev) |
1041 | { | 1048 | { |
1042 | batadv_debugfs_del_meshif(dev); | 1049 | batadv_debugfs_del_meshif(dev); |
1043 | batadv_mesh_free(dev); | 1050 | batadv_mesh_free(dev); |
1044 | 1051 | ||
1045 | /* some scheduled RCU callbacks need the bat_priv struct to accomplish | 1052 | /* some scheduled RCU callbacks need the bat_priv struct to accomplish |
1046 | * their tasks. Wait for them all to be finished before freeing the | 1053 | * their tasks. Wait for them all to be finished before freeing the |
1047 | * netdev and its private data (bat_priv) | 1054 | * netdev and its private data (bat_priv) |
1048 | */ | 1055 | */ |
1049 | rcu_barrier(); | 1056 | rcu_barrier(); |
1050 | } | 1057 | } |
1051 | 1058 | ||
1052 | /** | 1059 | /** |
1053 | * batadv_softif_init_early() - early stage initialization of soft interface | 1060 | * batadv_softif_init_early() - early stage initialization of soft interface |
1054 | * @dev: registered network device to modify | 1061 | * @dev: registered network device to modify |
1055 | */ | 1062 | */ |
1056 | static void batadv_softif_init_early(struct net_device *dev) | 1063 | static void batadv_softif_init_early(struct net_device *dev) |
1057 | { | 1064 | { |
1058 | ether_setup(dev); | 1065 | ether_setup(dev); |
1059 | 1066 | ||
1060 | dev->netdev_ops = &batadv_netdev_ops; | 1067 | dev->netdev_ops = &batadv_netdev_ops; |
1061 | dev->needs_free_netdev = true; | 1068 | dev->needs_free_netdev = true; |
1062 | dev->priv_destructor = batadv_softif_free; | 1069 | dev->priv_destructor = batadv_softif_free; |
1063 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; | 1070 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; |
1064 | dev->features |= NETIF_F_LLTX; | 1071 | dev->features |= NETIF_F_LLTX; |
1065 | dev->priv_flags |= IFF_NO_QUEUE; | 1072 | dev->priv_flags |= IFF_NO_QUEUE; |
1066 | 1073 | ||
1067 | /* can't call min_mtu, because the needed variables | 1074 | /* can't call min_mtu, because the needed variables |
1068 | * have not been initialized yet | 1075 | * have not been initialized yet |
1069 | */ | 1076 | */ |
1070 | dev->mtu = ETH_DATA_LEN; | 1077 | dev->mtu = ETH_DATA_LEN; |
1071 | 1078 | ||
1072 | /* generate random address */ | 1079 | /* generate random address */ |
1073 | eth_hw_addr_random(dev); | 1080 | eth_hw_addr_random(dev); |
1074 | 1081 | ||
1075 | dev->ethtool_ops = &batadv_ethtool_ops; | 1082 | dev->ethtool_ops = &batadv_ethtool_ops; |
1076 | } | 1083 | } |
1077 | 1084 | ||
1078 | /** | 1085 | /** |
1079 | * batadv_softif_create() - Create and register soft interface | 1086 | * batadv_softif_create() - Create and register soft interface |
1080 | * @net: the applicable net namespace | 1087 | * @net: the applicable net namespace |
1081 | * @name: name of the new soft interface | 1088 | * @name: name of the new soft interface |
1082 | * | 1089 | * |
1083 | * Return: newly allocated soft_interface, NULL on errors | 1090 | * Return: newly allocated soft_interface, NULL on errors |
1084 | */ | 1091 | */ |
1085 | struct net_device *batadv_softif_create(struct net *net, const char *name) | 1092 | struct net_device *batadv_softif_create(struct net *net, const char *name) |
1086 | { | 1093 | { |
1087 | struct net_device *soft_iface; | 1094 | struct net_device *soft_iface; |
1088 | int ret; | 1095 | int ret; |
1089 | 1096 | ||
1090 | soft_iface = alloc_netdev(sizeof(struct batadv_priv), name, | 1097 | soft_iface = alloc_netdev(sizeof(struct batadv_priv), name, |
1091 | NET_NAME_UNKNOWN, batadv_softif_init_early); | 1098 | NET_NAME_UNKNOWN, batadv_softif_init_early); |
1092 | if (!soft_iface) | 1099 | if (!soft_iface) |
1093 | return NULL; | 1100 | return NULL; |
1094 | 1101 | ||
1095 | dev_net_set(soft_iface, net); | 1102 | dev_net_set(soft_iface, net); |
1096 | 1103 | ||
1097 | soft_iface->rtnl_link_ops = &batadv_link_ops; | 1104 | soft_iface->rtnl_link_ops = &batadv_link_ops; |
1098 | 1105 | ||
1099 | ret = register_netdevice(soft_iface); | 1106 | ret = register_netdevice(soft_iface); |
1100 | if (ret < 0) { | 1107 | if (ret < 0) { |
1101 | pr_err("Unable to register the batman interface '%s': %i\n", | 1108 | pr_err("Unable to register the batman interface '%s': %i\n", |
1102 | name, ret); | 1109 | name, ret); |
1103 | free_netdev(soft_iface); | 1110 | free_netdev(soft_iface); |
1104 | return NULL; | 1111 | return NULL; |
1105 | } | 1112 | } |
1106 | 1113 | ||
1107 | return soft_iface; | 1114 | return soft_iface; |
1108 | } | 1115 | } |
1109 | 1116 | ||
1110 | /** | 1117 | /** |
1111 | * batadv_softif_destroy_sysfs() - deletion of batadv_soft_interface via sysfs | 1118 | * batadv_softif_destroy_sysfs() - deletion of batadv_soft_interface via sysfs |
1112 | * @soft_iface: the to-be-removed batman-adv interface | 1119 | * @soft_iface: the to-be-removed batman-adv interface |
1113 | */ | 1120 | */ |
1114 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface) | 1121 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface) |
1115 | { | 1122 | { |
1116 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 1123 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
1117 | struct batadv_softif_vlan *vlan; | 1124 | struct batadv_softif_vlan *vlan; |
1118 | 1125 | ||
1119 | ASSERT_RTNL(); | 1126 | ASSERT_RTNL(); |
1120 | 1127 | ||
1121 | /* destroy the "untagged" VLAN */ | 1128 | /* destroy the "untagged" VLAN */ |
1122 | vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); | 1129 | vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); |
1123 | if (vlan) { | 1130 | if (vlan) { |
1124 | batadv_softif_destroy_vlan(bat_priv, vlan); | 1131 | batadv_softif_destroy_vlan(bat_priv, vlan); |
1125 | batadv_softif_vlan_put(vlan); | 1132 | batadv_softif_vlan_put(vlan); |
1126 | } | 1133 | } |
1127 | 1134 | ||
1128 | batadv_sysfs_del_meshif(soft_iface); | 1135 | batadv_sysfs_del_meshif(soft_iface); |
1129 | unregister_netdevice(soft_iface); | 1136 | unregister_netdevice(soft_iface); |
1130 | } | 1137 | } |
1131 | 1138 | ||
1132 | /** | 1139 | /** |
1133 | * batadv_softif_destroy_netlink() - deletion of batadv_soft_interface via | 1140 | * batadv_softif_destroy_netlink() - deletion of batadv_soft_interface via |
1134 | * netlink | 1141 | * netlink |
1135 | * @soft_iface: the to-be-removed batman-adv interface | 1142 | * @soft_iface: the to-be-removed batman-adv interface |
1136 | * @head: list pointer | 1143 | * @head: list pointer |
1137 | */ | 1144 | */ |
1138 | static void batadv_softif_destroy_netlink(struct net_device *soft_iface, | 1145 | static void batadv_softif_destroy_netlink(struct net_device *soft_iface, |
1139 | struct list_head *head) | 1146 | struct list_head *head) |
1140 | { | 1147 | { |
1141 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 1148 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
1142 | struct batadv_hard_iface *hard_iface; | 1149 | struct batadv_hard_iface *hard_iface; |
1143 | struct batadv_softif_vlan *vlan; | 1150 | struct batadv_softif_vlan *vlan; |
1144 | 1151 | ||
1145 | list_for_each_entry(hard_iface, &batadv_hardif_list, list) { | 1152 | list_for_each_entry(hard_iface, &batadv_hardif_list, list) { |
1146 | if (hard_iface->soft_iface == soft_iface) | 1153 | if (hard_iface->soft_iface == soft_iface) |
1147 | batadv_hardif_disable_interface(hard_iface, | 1154 | batadv_hardif_disable_interface(hard_iface, |
1148 | BATADV_IF_CLEANUP_KEEP); | 1155 | BATADV_IF_CLEANUP_KEEP); |
1149 | } | 1156 | } |
1150 | 1157 | ||
1151 | /* destroy the "untagged" VLAN */ | 1158 | /* destroy the "untagged" VLAN */ |
1152 | vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); | 1159 | vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); |
1153 | if (vlan) { | 1160 | if (vlan) { |
1154 | batadv_softif_destroy_vlan(bat_priv, vlan); | 1161 | batadv_softif_destroy_vlan(bat_priv, vlan); |
1155 | batadv_softif_vlan_put(vlan); | 1162 | batadv_softif_vlan_put(vlan); |
1156 | } | 1163 | } |
1157 | 1164 | ||
1158 | batadv_sysfs_del_meshif(soft_iface); | 1165 | batadv_sysfs_del_meshif(soft_iface); |
1159 | unregister_netdevice_queue(soft_iface, head); | 1166 | unregister_netdevice_queue(soft_iface, head); |
1160 | } | 1167 | } |
1161 | 1168 | ||
1162 | /** | 1169 | /** |
1163 | * batadv_softif_is_valid() - Check whether device is a batadv soft interface | 1170 | * batadv_softif_is_valid() - Check whether device is a batadv soft interface |
1164 | * @net_dev: device which should be checked | 1171 | * @net_dev: device which should be checked |
1165 | * | 1172 | * |
1166 | * Return: true when net_dev is a batman-adv interface, false otherwise | 1173 | * Return: true when net_dev is a batman-adv interface, false otherwise |
1167 | */ | 1174 | */ |
1168 | bool batadv_softif_is_valid(const struct net_device *net_dev) | 1175 | bool batadv_softif_is_valid(const struct net_device *net_dev) |
1169 | { | 1176 | { |
1170 | if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) | 1177 | if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) |
1171 | return true; | 1178 | return true; |
1172 | 1179 | ||
1173 | return false; | 1180 | return false; |
1174 | } | 1181 | } |
1175 | 1182 | ||
1176 | struct rtnl_link_ops batadv_link_ops __read_mostly = { | 1183 | struct rtnl_link_ops batadv_link_ops __read_mostly = { |
1177 | .kind = "batadv", | 1184 | .kind = "batadv", |
1178 | .priv_size = sizeof(struct batadv_priv), | 1185 | .priv_size = sizeof(struct batadv_priv), |
1179 | .setup = batadv_softif_init_early, | 1186 | .setup = batadv_softif_init_early, |
1180 | .dellink = batadv_softif_destroy_netlink, | 1187 | .dellink = batadv_softif_destroy_netlink, |
1181 | }; | 1188 | }; |
1182 | 1189 |