Blame view
net/batman-adv/send.c
29.4 KB
ac79cbb96 batman-adv: updat... |
1 |
/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: |
c6c8fea29 net: Add batman-a... |
2 3 4 5 6 7 8 9 10 11 12 13 14 |
* * Marek Lindner, Simon Wunderlich * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License |
ebf38fb7a batman-adv: remov... |
15 |
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
c6c8fea29 net: Add batman-a... |
16 |
*/ |
1e2c2a4fe batman-adv: Add r... |
17 |
#include "send.h" |
c6c8fea29 net: Add batman-a... |
18 |
#include "main.h" |
1e2c2a4fe batman-adv: Add r... |
19 20 |
#include <linux/atomic.h> |
9b4aec647 batman-adv: fix r... |
21 |
#include <linux/bug.h> |
1e2c2a4fe batman-adv: Add r... |
22 |
#include <linux/byteorder/generic.h> |
f50ca95a6 batman-adv: retur... |
23 |
#include <linux/errno.h> |
1e2c2a4fe batman-adv: Add r... |
24 25 |
#include <linux/etherdevice.h> #include <linux/fs.h> |
1e2c2a4fe batman-adv: Add r... |
26 |
#include <linux/if.h> |
fcafa5e74 batman-adv: Keep ... |
27 |
#include <linux/if_ether.h> |
1e2c2a4fe batman-adv: Add r... |
28 29 |
#include <linux/jiffies.h> #include <linux/kernel.h> |
273534468 batman-adv: Check... |
30 |
#include <linux/kref.h> |
1e2c2a4fe batman-adv: Add r... |
31 32 33 34 35 36 37 38 39 40 |
#include <linux/list.h> #include <linux/netdevice.h> #include <linux/printk.h> #include <linux/rculist.h> #include <linux/rcupdate.h> #include <linux/skbuff.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/stddef.h> #include <linux/workqueue.h> |
c384ea3ec batman-adv: Distr... |
41 |
#include "distributed-arp-table.h" |
1e2c2a4fe batman-adv: Add r... |
42 |
#include "fragmentation.h" |
f097e25db batman-adv: Remov... |
43 |
#include "gateway_client.h" |
1e2c2a4fe batman-adv: Add r... |
44 |
#include "hard-interface.h" |
ba412080f batman-adv: Conso... |
45 |
#include "log.h" |
612d2b4fe batman-adv: netwo... |
46 |
#include "network-coding.h" |
1e2c2a4fe batman-adv: Add r... |
47 48 49 50 |
#include "originator.h" #include "routing.h" #include "soft-interface.h" #include "translation-table.h" |
af5d4f773 batman-adv: use E... |
51 |
|
bb079c82e batman-adv: Prefi... |
52 |
static void batadv_send_outstanding_bcast_packet(struct work_struct *work); |
c6c8fea29 net: Add batman-a... |
53 |
|
95d392784 batman-adv: keep ... |
54 55 56 57 58 59 60 61 62 63 64 65 |
/** * batadv_send_skb_packet - send an already prepared packet * @skb: the packet to send * @hard_iface: the interface to use to send the broadcast packet * @dst_addr: the payload destination * * Send out an already prepared packet to the given neighbor or broadcast it * using the specified interface. Either hard_iface or neigh_node must be not * NULL. * If neigh_node is NULL, then the packet is broadcasted using hard_iface, * otherwise it is sent as unicast to the given neighbor. * |
7d72d174c batman-adv: Remov... |
66 67 68 69 70 |
* Regardless of the return value, the skb is consumed. * * Return: A negative errno code is returned on a failure. A success does not * guarantee the frame will be transmitted as it may be dropped due * to congestion or traffic shaping. |
9cfc7bd60 batman-adv: Refor... |
71 |
*/ |
56303d34a batman-adv: Prefi... |
72 73 |
int batadv_send_skb_packet(struct sk_buff *skb, struct batadv_hard_iface *hard_iface, |
6b5e971a2 batman-adv: Repla... |
74 |
const u8 *dst_addr) |
c6c8fea29 net: Add batman-a... |
75 |
{ |
95d392784 batman-adv: keep ... |
76 |
struct batadv_priv *bat_priv; |
c6c8fea29 net: Add batman-a... |
77 |
struct ethhdr *ethhdr; |
7c946062b batman-adv: Fix d... |
78 |
int ret; |
c6c8fea29 net: Add batman-a... |
79 |
|
95d392784 batman-adv: keep ... |
80 |
bat_priv = netdev_priv(hard_iface->soft_iface); |
e9a4f295e batman-adv: Prefi... |
81 |
if (hard_iface->if_status != BATADV_IF_ACTIVE) |
c6c8fea29 net: Add batman-a... |
82 |
goto send_skb_err; |
e6c10f433 batman-adv: renam... |
83 |
if (unlikely(!hard_iface->net_dev)) |
c6c8fea29 net: Add batman-a... |
84 |
goto send_skb_err; |
e6c10f433 batman-adv: renam... |
85 |
if (!(hard_iface->net_dev->flags & IFF_UP)) { |
679695813 batman-adv: use s... |
86 87 88 |
pr_warn("Interface %s is not up - can't send packet via that interface! ", hard_iface->net_dev->name); |
c6c8fea29 net: Add batman-a... |
89 90 91 92 |
goto send_skb_err; } /* push to the ethernet header. */ |
04b482a21 batman-adv: Prefi... |
93 |
if (batadv_skb_head_push(skb, ETH_HLEN) < 0) |
c6c8fea29 net: Add batman-a... |
94 95 96 |
goto send_skb_err; skb_reset_mac_header(skb); |
7ed4be952 batman-adv: use e... |
97 |
ethhdr = eth_hdr(skb); |
8fdd01530 batman-adv: prefe... |
98 99 |
ether_addr_copy(ethhdr->h_source, hard_iface->net_dev->dev_addr); ether_addr_copy(ethhdr->h_dest, dst_addr); |
293e93385 batman-adv: use h... |
100 |
ethhdr->h_proto = htons(ETH_P_BATMAN); |
c6c8fea29 net: Add batman-a... |
101 102 |
skb_set_network_header(skb, ETH_HLEN); |
293e93385 batman-adv: use h... |
103 |
skb->protocol = htons(ETH_P_BATMAN); |
c6c8fea29 net: Add batman-a... |
104 |
|
e6c10f433 batman-adv: renam... |
105 |
skb->dev = hard_iface->net_dev; |
c6c8fea29 net: Add batman-a... |
106 |
|
612d2b4fe batman-adv: netwo... |
107 108 |
/* Save a clone of the skb to use when decoding coded packets */ batadv_nc_skb_store_for_decoding(bat_priv, skb); |
c6c8fea29 net: Add batman-a... |
109 110 |
/* dev_queue_xmit() returns a negative result on error. However on * congestion and traffic shaping, it drops and returns NET_XMIT_DROP |
9cfc7bd60 batman-adv: Refor... |
111 112 |
* (which is > 0). This will not be treated as an error. */ |
7c946062b batman-adv: Fix d... |
113 114 |
ret = dev_queue_xmit(skb); return net_xmit_eval(ret); |
c6c8fea29 net: Add batman-a... |
115 116 117 118 |
send_skb_err: kfree_skb(skb); return NET_XMIT_DROP; } |
95d392784 batman-adv: keep ... |
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
int batadv_send_broadcast_skb(struct sk_buff *skb, struct batadv_hard_iface *hard_iface) { return batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr); } int batadv_send_unicast_skb(struct sk_buff *skb, struct batadv_neigh_node *neigh) { #ifdef CONFIG_BATMAN_ADV_BATMAN_V struct batadv_hardif_neigh_node *hardif_neigh; #endif int ret; ret = batadv_send_skb_packet(skb, neigh->if_incoming, neigh->addr); #ifdef CONFIG_BATMAN_ADV_BATMAN_V hardif_neigh = batadv_hardif_neigh_get(neigh->if_incoming, neigh->addr); if ((hardif_neigh) && (ret != NET_XMIT_DROP)) hardif_neigh->bat_v.last_unicast_tx = jiffies; if (hardif_neigh) batadv_hardif_neigh_put(hardif_neigh); #endif return ret; } |
bb351ba0b batman-adv: Add w... |
147 148 149 150 151 152 153 154 155 156 157 |
/** * batadv_send_skb_to_orig - Lookup next-hop and transmit skb. * @skb: Packet to be transmitted. * @orig_node: Final destination of the packet. * @recv_if: Interface used when receiving the packet (can be NULL). * * Looks up the best next-hop towards the passed originator and passes the * skb on for preparation of MAC header. If the packet originated from this * host, NULL can be passed as recv_if and no interface alternating is * attempted. * |
1ad5bcb2a batman-adv: Consu... |
158 159 |
* Return: negative errno code on a failure, -EINPROGRESS if the skb is * buffered for later transmit or the NET_XMIT status returned by the |
f50ca95a6 batman-adv: retur... |
160 |
* lower routine if the packet has been passed down. |
bb351ba0b batman-adv: Add w... |
161 |
*/ |
e91ecfc64 batman-adv: Move ... |
162 163 164 |
int batadv_send_skb_to_orig(struct sk_buff *skb, struct batadv_orig_node *orig_node, struct batadv_hard_iface *recv_if) |
bb351ba0b batman-adv: Add w... |
165 166 167 |
{ struct batadv_priv *bat_priv = orig_node->bat_priv; struct batadv_neigh_node *neigh_node; |
1ad5bcb2a batman-adv: Consu... |
168 |
int ret; |
bb351ba0b batman-adv: Add w... |
169 170 171 |
/* batadv_find_router() increases neigh_nodes refcount if found. */ neigh_node = batadv_find_router(bat_priv, orig_node, recv_if); |
1ad5bcb2a batman-adv: Consu... |
172 173 174 175 |
if (!neigh_node) { ret = -EINVAL; goto free_skb; } |
ee75ed888 batman-adv: Fragm... |
176 177 178 179 180 181 182 |
/* Check if the skb is too large to send in one piece and fragment * it if needed. */ if (atomic_read(&bat_priv->fragmentation) && skb->len > neigh_node->if_incoming->net_dev->mtu) { /* Fragment and send packet. */ |
f50ca95a6 batman-adv: retur... |
183 |
ret = batadv_frag_send_packet(skb, orig_node, neigh_node); |
1ad5bcb2a batman-adv: Consu... |
184 185 |
/* skb was consumed */ skb = NULL; |
ee75ed888 batman-adv: Fragm... |
186 |
|
1ad5bcb2a batman-adv: Consu... |
187 |
goto put_neigh_node; |
ee75ed888 batman-adv: Fragm... |
188 |
} |
bb351ba0b batman-adv: Add w... |
189 |
|
e91ecfc64 batman-adv: Move ... |
190 191 192 193 |
/* try to network code the packet, if it is received on an interface * (i.e. being forwarded). If the packet originates from this node or if * network coding fails, then send the packet as usual. */ |
f50ca95a6 batman-adv: retur... |
194 |
if (recv_if && batadv_nc_skb_forward(skb, neigh_node)) |
99860208b sched: remove NET... |
195 |
ret = -EINPROGRESS; |
f50ca95a6 batman-adv: retur... |
196 197 |
else ret = batadv_send_unicast_skb(skb, neigh_node); |
bb351ba0b batman-adv: Add w... |
198 |
|
1ad5bcb2a batman-adv: Consu... |
199 200 201 202 203 204 205 |
/* skb was consumed */ skb = NULL; put_neigh_node: batadv_neigh_node_put(neigh_node); free_skb: kfree_skb(skb); |
bb351ba0b batman-adv: Add w... |
206 |
|
e91ecfc64 batman-adv: Move ... |
207 |
return ret; |
bb351ba0b batman-adv: Add w... |
208 |
} |
f097e25db batman-adv: Remov... |
209 210 211 212 213 214 215 |
/** * batadv_send_skb_push_fill_unicast - extend the buffer and initialize the * common fields for unicast packets * @skb: the skb carrying the unicast header to initialize * @hdr_size: amount of bytes to push at the beginning of the skb * @orig_node: the destination node * |
62fe710f6 batman-adv: Fix k... |
216 |
* Return: false if the buffer extension was not possible or true otherwise. |
f097e25db batman-adv: Remov... |
217 218 219 220 221 222 |
*/ static bool batadv_send_skb_push_fill_unicast(struct sk_buff *skb, int hdr_size, struct batadv_orig_node *orig_node) { struct batadv_unicast_packet *unicast_packet; |
6b5e971a2 batman-adv: Repla... |
223 |
u8 ttvn = (u8)atomic_read(&orig_node->last_ttvn); |
f097e25db batman-adv: Remov... |
224 225 226 227 228 |
if (batadv_skb_head_push(skb, hdr_size) < 0) return false; unicast_packet = (struct batadv_unicast_packet *)skb->data; |
a40d9b075 batman-adv: fix h... |
229 |
unicast_packet->version = BATADV_COMPAT_VERSION; |
f097e25db batman-adv: Remov... |
230 |
/* batman packet type: unicast */ |
a40d9b075 batman-adv: fix h... |
231 |
unicast_packet->packet_type = BATADV_UNICAST; |
f097e25db batman-adv: Remov... |
232 |
/* set unicast ttl */ |
a40d9b075 batman-adv: fix h... |
233 |
unicast_packet->ttl = BATADV_TTL; |
f097e25db batman-adv: Remov... |
234 |
/* copy the destination for faster routing */ |
8fdd01530 batman-adv: prefe... |
235 |
ether_addr_copy(unicast_packet->dest, orig_node->orig); |
f097e25db batman-adv: Remov... |
236 237 238 239 240 241 242 243 244 245 246 |
/* set the destination tt version number */ unicast_packet->ttvn = ttvn; return true; } /** * batadv_send_skb_prepare_unicast - encapsulate an skb with a unicast header * @skb: the skb containing the payload to encapsulate * @orig_node: the destination node * |
62fe710f6 batman-adv: Fix k... |
247 |
* Return: false if the payload could not be encapsulated or true otherwise. |
f097e25db batman-adv: Remov... |
248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
*/ static bool batadv_send_skb_prepare_unicast(struct sk_buff *skb, struct batadv_orig_node *orig_node) { size_t uni_size = sizeof(struct batadv_unicast_packet); return batadv_send_skb_push_fill_unicast(skb, uni_size, orig_node); } /** * batadv_send_skb_prepare_unicast_4addr - encapsulate an skb with a * unicast 4addr header * @bat_priv: the bat priv with all the soft interface information * @skb: the skb containing the payload to encapsulate |
e51f0397d batman-adv: Fix n... |
262 |
* @orig: the destination node |
f097e25db batman-adv: Remov... |
263 264 |
* @packet_subtype: the unicast 4addr packet subtype to use * |
62fe710f6 batman-adv: Fix k... |
265 |
* Return: false if the payload could not be encapsulated or true otherwise. |
f097e25db batman-adv: Remov... |
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
*/ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv, struct sk_buff *skb, struct batadv_orig_node *orig, int packet_subtype) { struct batadv_hard_iface *primary_if; struct batadv_unicast_4addr_packet *uc_4addr_packet; bool ret = false; primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; /* Pull the header space and fill the unicast_packet substructure. * We can do that because the first member of the uc_4addr_packet * is of type struct unicast_packet */ if (!batadv_send_skb_push_fill_unicast(skb, sizeof(*uc_4addr_packet), orig)) goto out; uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; |
a40d9b075 batman-adv: fix h... |
289 |
uc_4addr_packet->u.packet_type = BATADV_UNICAST_4ADDR; |
8fdd01530 batman-adv: prefe... |
290 |
ether_addr_copy(uc_4addr_packet->src, primary_if->net_dev->dev_addr); |
f097e25db batman-adv: Remov... |
291 292 293 294 295 296 |
uc_4addr_packet->subtype = packet_subtype; uc_4addr_packet->reserved = 0; ret = true; out: if (primary_if) |
82047ad7f batman-adv: Renam... |
297 |
batadv_hardif_put(primary_if); |
f097e25db batman-adv: Remov... |
298 299 300 301 |
return ret; } /** |
e300d3146 batman-adv: refin... |
302 |
* batadv_send_skb_unicast - encapsulate and send an skb via unicast |
f097e25db batman-adv: Remov... |
303 304 305 306 307 |
* @bat_priv: the bat priv with all the soft interface information * @skb: payload to send * @packet_type: the batman unicast packet type to use * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast * 4addr packets) |
e300d3146 batman-adv: refin... |
308 |
* @orig_node: the originator to send the packet to |
c018ad3de batman-adv: add t... |
309 |
* @vid: the vid to be used to search the translation table |
f097e25db batman-adv: Remov... |
310 |
* |
e300d3146 batman-adv: refin... |
311 312 |
* Wrap the given skb into a batman-adv unicast or unicast-4addr header * depending on whether BATADV_UNICAST or BATADV_UNICAST_4ADDR was supplied |
f19dc7770 batman-adv: Remov... |
313 |
* as packet_type. Then send this frame to the given orig_node. |
e300d3146 batman-adv: refin... |
314 |
* |
62fe710f6 batman-adv: Fix k... |
315 |
* Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise. |
f097e25db batman-adv: Remov... |
316 |
*/ |
1d8ab8d3c batman-adv: Modif... |
317 318 319 320 321 |
int batadv_send_skb_unicast(struct batadv_priv *bat_priv, struct sk_buff *skb, int packet_type, int packet_subtype, struct batadv_orig_node *orig_node, unsigned short vid) |
f097e25db batman-adv: Remov... |
322 |
{ |
f097e25db batman-adv: Remov... |
323 |
struct batadv_unicast_packet *unicast_packet; |
8ea64e270 batman-adv: Use c... |
324 |
struct ethhdr *ethhdr; |
1ad5bcb2a batman-adv: Consu... |
325 |
int ret = NET_XMIT_DROP; |
f097e25db batman-adv: Remov... |
326 |
|
56a5ca840 batman-adv: remov... |
327 |
if (!orig_node) |
f097e25db batman-adv: Remov... |
328 329 330 331 |
goto out; switch (packet_type) { case BATADV_UNICAST: |
33faa0454 batman-adv: check... |
332 333 |
if (!batadv_send_skb_prepare_unicast(skb, orig_node)) goto out; |
f097e25db batman-adv: Remov... |
334 335 |
break; case BATADV_UNICAST_4ADDR: |
33faa0454 batman-adv: check... |
336 337 338 339 |
if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, orig_node, packet_subtype)) goto out; |
f097e25db batman-adv: Remov... |
340 341 342 343 344 345 346 |
break; default: /* this function supports UNICAST and UNICAST_4ADDR only. It * should never be invoked with any other packet type */ goto out; } |
927c2ed7e batman-adv: use v... |
347 348 349 350 |
/* skb->data might have been reallocated by * batadv_send_skb_prepare_unicast{,_4addr}() */ ethhdr = eth_hdr(skb); |
f097e25db batman-adv: Remov... |
351 352 353 354 355 356 357 |
unicast_packet = (struct batadv_unicast_packet *)skb->data; /* inform the destination node that we are still missing a correct route * for this client. The destination will receive this packet and will * try to reroute it because the ttvn contained in the header is less * than the current one */ |
c018ad3de batman-adv: add t... |
358 |
if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) |
f097e25db batman-adv: Remov... |
359 |
unicast_packet->ttvn = unicast_packet->ttvn - 1; |
1ad5bcb2a batman-adv: Consu... |
360 361 362 |
ret = batadv_send_skb_to_orig(skb, orig_node, NULL); /* skb was consumed */ skb = NULL; |
f097e25db batman-adv: Remov... |
363 364 |
out: |
1ad5bcb2a batman-adv: Consu... |
365 |
kfree_skb(skb); |
f097e25db batman-adv: Remov... |
366 367 |
return ret; } |
e300d3146 batman-adv: refin... |
368 369 370 371 372 373 374 |
/** * batadv_send_skb_via_tt_generic - send an skb via TT lookup * @bat_priv: the bat priv with all the soft interface information * @skb: payload to send * @packet_type: the batman unicast packet type to use * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast * 4addr packets) |
c5d3a652a batman-adv: add k... |
375 |
* @dst_hint: can be used to override the destination contained in the skb |
e300d3146 batman-adv: refin... |
376 377 378 379 380 381 382 383 |
* @vid: the vid to be used to search the translation table * * Look up the recipient node for the destination address in the ethernet * header via the translation table. Wrap the given skb into a batman-adv * unicast or unicast-4addr header depending on whether BATADV_UNICAST or * BATADV_UNICAST_4ADDR was supplied as packet_type. Then send this frame * to the according destination node. * |
62fe710f6 batman-adv: Fix k... |
384 |
* Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise. |
e300d3146 batman-adv: refin... |
385 386 387 |
*/ int batadv_send_skb_via_tt_generic(struct batadv_priv *bat_priv, struct sk_buff *skb, int packet_type, |
6b5e971a2 batman-adv: Repla... |
388 |
int packet_subtype, u8 *dst_hint, |
6c413b1c2 batman-adv: send ... |
389 |
unsigned short vid) |
e300d3146 batman-adv: refin... |
390 391 392 |
{ struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct batadv_orig_node *orig_node; |
6b5e971a2 batman-adv: Repla... |
393 |
u8 *src, *dst; |
f19dc7770 batman-adv: Remov... |
394 |
int ret; |
6c413b1c2 batman-adv: send ... |
395 396 397 398 399 400 401 402 403 404 |
src = ethhdr->h_source; dst = ethhdr->h_dest; /* if we got an hint! let's send the packet to this client (if any) */ if (dst_hint) { src = NULL; dst = dst_hint; } orig_node = batadv_transtable_search(bat_priv, src, dst, vid); |
e300d3146 batman-adv: refin... |
405 |
|
f19dc7770 batman-adv: Remov... |
406 407 408 409 410 411 412 |
ret = batadv_send_skb_unicast(bat_priv, skb, packet_type, packet_subtype, orig_node, vid); if (orig_node) batadv_orig_node_put(orig_node); return ret; |
e300d3146 batman-adv: refin... |
413 414 415 416 417 418 419 420 421 422 423 |
} /** * batadv_send_skb_via_gw - send an skb via gateway lookup * @bat_priv: the bat priv with all the soft interface information * @skb: payload to send * @vid: the vid to be used to search the translation table * * Look up the currently selected gateway. Wrap the given skb into a batman-adv * unicast header and send this frame to this gateway node. * |
62fe710f6 batman-adv: Fix k... |
424 |
* Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise. |
e300d3146 batman-adv: refin... |
425 426 427 428 429 |
*/ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb, unsigned short vid) { struct batadv_orig_node *orig_node; |
f19dc7770 batman-adv: Remov... |
430 |
int ret; |
e300d3146 batman-adv: refin... |
431 432 |
orig_node = batadv_gw_get_selected_orig(bat_priv); |
f19dc7770 batman-adv: Remov... |
433 434 435 436 437 438 439 |
ret = batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST_4ADDR, BATADV_P_DATA, orig_node, vid); if (orig_node) batadv_orig_node_put(orig_node); return ret; |
e300d3146 batman-adv: refin... |
440 |
} |
a65e54813 batman-adv: Intro... |
441 442 443 |
/** * batadv_forw_packet_free - free a forwarding packet * @forw_packet: The packet to free |
bd687fe41 batman-adv: use c... |
444 |
* @dropped: whether the packet is freed because is is dropped |
a65e54813 batman-adv: Intro... |
445 446 447 448 |
* * This frees a forwarding packet and releases any resources it might * have claimed. */ |
bd687fe41 batman-adv: use c... |
449 450 |
void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet, bool dropped) |
c6c8fea29 net: Add batman-a... |
451 |
{ |
bd687fe41 batman-adv: use c... |
452 453 454 455 |
if (dropped) kfree_skb(forw_packet->skb); else consume_skb(forw_packet->skb); |
6d5808d4a batman-adv: Add m... |
456 |
if (forw_packet->if_incoming) |
82047ad7f batman-adv: Renam... |
457 |
batadv_hardif_put(forw_packet->if_incoming); |
ef0a937f7 batman-adv: consi... |
458 |
if (forw_packet->if_outgoing) |
82047ad7f batman-adv: Renam... |
459 |
batadv_hardif_put(forw_packet->if_outgoing); |
a65e54813 batman-adv: Intro... |
460 461 |
if (forw_packet->queue_left) atomic_inc(forw_packet->queue_left); |
c6c8fea29 net: Add batman-a... |
462 463 |
kfree(forw_packet); } |
a65e54813 batman-adv: Intro... |
464 465 466 467 468 469 |
/** * batadv_forw_packet_alloc - allocate a forwarding packet * @if_incoming: The (optional) if_incoming to be grabbed * @if_outgoing: The (optional) if_outgoing to be grabbed * @queue_left: The (optional) queue counter to decrease * @bat_priv: The bat_priv for the mesh of this forw_packet |
99ba18ef0 batman-adv: priva... |
470 |
* @skb: The raw packet this forwarding packet shall contain |
a65e54813 batman-adv: Intro... |
471 472 473 474 475 476 477 478 479 480 481 |
* * Allocates a forwarding packet and tries to get a reference to the * (optional) if_incoming, if_outgoing and queue_left. If queue_left * is NULL then bat_priv is optional, too. * * Return: An allocated forwarding packet on success, NULL otherwise. */ struct batadv_forw_packet * batadv_forw_packet_alloc(struct batadv_hard_iface *if_incoming, struct batadv_hard_iface *if_outgoing, atomic_t *queue_left, |
99ba18ef0 batman-adv: priva... |
482 483 |
struct batadv_priv *bat_priv, struct sk_buff *skb) |
a65e54813 batman-adv: Intro... |
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
{ struct batadv_forw_packet *forw_packet; const char *qname; if (queue_left && !batadv_atomic_dec_not_zero(queue_left)) { qname = "unknown"; if (queue_left == &bat_priv->bcast_queue_left) qname = "bcast"; if (queue_left == &bat_priv->batman_queue_left) qname = "batman"; batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "%s queue is full ", qname); return NULL; } forw_packet = kmalloc(sizeof(*forw_packet), GFP_ATOMIC); if (!forw_packet) goto err; if (if_incoming) kref_get(&if_incoming->refcount); if (if_outgoing) kref_get(&if_outgoing->refcount); |
9b4aec647 batman-adv: fix r... |
513 514 |
INIT_HLIST_NODE(&forw_packet->list); INIT_HLIST_NODE(&forw_packet->cleanup_list); |
99ba18ef0 batman-adv: priva... |
515 |
forw_packet->skb = skb; |
a65e54813 batman-adv: Intro... |
516 517 518 519 520 521 522 523 524 525 526 527 528 |
forw_packet->queue_left = queue_left; forw_packet->if_incoming = if_incoming; forw_packet->if_outgoing = if_outgoing; forw_packet->num_packets = 0; return forw_packet; err: if (queue_left) atomic_inc(queue_left); return NULL; } |
9b4aec647 batman-adv: fix r... |
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 |
/** * batadv_forw_packet_was_stolen - check whether someone stole this packet * @forw_packet: the forwarding packet to check * * This function checks whether the given forwarding packet was claimed by * someone else for free(). * * Return: True if someone stole it, false otherwise. */ static bool batadv_forw_packet_was_stolen(struct batadv_forw_packet *forw_packet) { return !hlist_unhashed(&forw_packet->cleanup_list); } /** * batadv_forw_packet_steal - claim a forw_packet for free() * @forw_packet: the forwarding packet to steal * @lock: a key to the store to steal from (e.g. forw_{bat,bcast}_list_lock) * * This function tries to steal a specific forw_packet from global * visibility for the purpose of getting it for free(). That means * the caller is *not* allowed to requeue it afterwards. * * Return: True if stealing was successful. False if someone else stole it * before us. */ bool batadv_forw_packet_steal(struct batadv_forw_packet *forw_packet, spinlock_t *lock) { /* did purging routine steal it earlier? */ spin_lock_bh(lock); if (batadv_forw_packet_was_stolen(forw_packet)) { spin_unlock_bh(lock); return false; } hlist_del_init(&forw_packet->list); /* Just to spot misuse of this function */ hlist_add_fake(&forw_packet->cleanup_list); spin_unlock_bh(lock); return true; } /** * batadv_forw_packet_list_steal - claim a list of forward packets for free() * @forw_list: the to be stolen forward packets * @cleanup_list: a backup pointer, to be able to dispose the packet later * @hard_iface: the interface to steal forward packets from * * This function claims responsibility to free any forw_packet queued on the * given hard_iface. If hard_iface is NULL forwarding packets on all hard * interfaces will be claimed. * * The packets are being moved from the forw_list to the cleanup_list and * by that allows already running threads to notice the claiming. */ |
56303d34a batman-adv: Prefi... |
588 |
static void |
9b4aec647 batman-adv: fix r... |
589 590 591 |
batadv_forw_packet_list_steal(struct hlist_head *forw_list, struct hlist_head *cleanup_list, const struct batadv_hard_iface *hard_iface) |
c6c8fea29 net: Add batman-a... |
592 |
{ |
9b4aec647 batman-adv: fix r... |
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
struct batadv_forw_packet *forw_packet; struct hlist_node *safe_tmp_node; hlist_for_each_entry_safe(forw_packet, safe_tmp_node, forw_list, list) { /* if purge_outstanding_packets() was called with an argument * we delete only packets belonging to the given interface */ if (hard_iface && (forw_packet->if_incoming != hard_iface) && (forw_packet->if_outgoing != hard_iface)) continue; hlist_del(&forw_packet->list); hlist_add_head(&forw_packet->cleanup_list, cleanup_list); } } /** * batadv_forw_packet_list_free - free a list of forward packets * @head: a list of to be freed forw_packets * * This function cancels the scheduling of any packet in the provided list, * waits for any possibly running packet forwarding thread to finish and * finally, safely frees this forward packet. * * This function might sleep. */ static void batadv_forw_packet_list_free(struct hlist_head *head) { struct batadv_forw_packet *forw_packet; struct hlist_node *safe_tmp_node; hlist_for_each_entry_safe(forw_packet, safe_tmp_node, head, cleanup_list) { cancel_delayed_work_sync(&forw_packet->delayed_work); |
c6c8fea29 net: Add batman-a... |
629 |
|
9b4aec647 batman-adv: fix r... |
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 |
hlist_del(&forw_packet->cleanup_list); batadv_forw_packet_free(forw_packet, true); } } /** * batadv_forw_packet_queue - try to queue a forwarding packet * @forw_packet: the forwarding packet to queue * @lock: a key to the store (e.g. forw_{bat,bcast}_list_lock) * @head: the shelve to queue it on (e.g. forw_{bat,bcast}_list) * @send_time: timestamp (jiffies) when the packet is to be sent * * This function tries to (re)queue a forwarding packet. Requeuing * is prevented if the according interface is shutting down * (e.g. if batadv_forw_packet_list_steal() was called for this * packet earlier). * * Calling batadv_forw_packet_queue() after a call to * batadv_forw_packet_steal() is forbidden! * * Caller needs to ensure that forw_packet->delayed_work was initialized. */ static void batadv_forw_packet_queue(struct batadv_forw_packet *forw_packet, spinlock_t *lock, struct hlist_head *head, unsigned long send_time) { spin_lock_bh(lock); /* did purging routine steal it from us? */ if (batadv_forw_packet_was_stolen(forw_packet)) { /* If you got it for free() without trouble, then * don't get back into the queue after stealing... */ WARN_ONCE(hlist_fake(&forw_packet->cleanup_list), "Requeuing after batadv_forw_packet_steal() not allowed! "); spin_unlock_bh(lock); return; } hlist_del_init(&forw_packet->list); hlist_add_head(&forw_packet->list, head); queue_delayed_work(batadv_event_workqueue, &forw_packet->delayed_work, send_time - jiffies); spin_unlock_bh(lock); } /** * batadv_forw_packet_bcast_queue - try to queue a broadcast packet * @bat_priv: the bat priv with all the soft interface information * @forw_packet: the forwarding packet to queue * @send_time: timestamp (jiffies) when the packet is to be sent * * This function tries to (re)queue a broadcast packet. * * Caller needs to ensure that forw_packet->delayed_work was initialized. */ static void batadv_forw_packet_bcast_queue(struct batadv_priv *bat_priv, struct batadv_forw_packet *forw_packet, unsigned long send_time) { batadv_forw_packet_queue(forw_packet, &bat_priv->forw_bcast_list_lock, &bat_priv->forw_bcast_list, send_time); } /** * batadv_forw_packet_ogmv1_queue - try to queue an OGMv1 packet * @bat_priv: the bat priv with all the soft interface information * @forw_packet: the forwarding packet to queue * @send_time: timestamp (jiffies) when the packet is to be sent * * This function tries to (re)queue an OGMv1 packet. * * Caller needs to ensure that forw_packet->delayed_work was initialized. */ void batadv_forw_packet_ogmv1_queue(struct batadv_priv *bat_priv, struct batadv_forw_packet *forw_packet, unsigned long send_time) { batadv_forw_packet_queue(forw_packet, &bat_priv->forw_bat_list_lock, &bat_priv->forw_bat_list, send_time); |
c6c8fea29 net: Add batman-a... |
715 |
} |
62fe710f6 batman-adv: Fix k... |
716 |
/** |
7afcbbef6 batman-adv: Fix k... |
717 718 719 720 |
* batadv_add_bcast_packet_to_list - queue broadcast packet for multiple sends * @bat_priv: the bat priv with all the soft interface information * @skb: broadcast packet to add * @delay: number of jiffies to wait before sending |
3111beed0 batman-adv: Simpl... |
721 |
* @own_packet: true if it is a self-generated broadcast packet |
c6c8fea29 net: Add batman-a... |
722 |
* |
62fe710f6 batman-adv: Fix k... |
723 724 |
* add a broadcast packet to the queue and setup timers. broadcast packets * are sent multiple times to increase probability for being received. |
c6c8fea29 net: Add batman-a... |
725 726 |
* * The skb is not consumed, so the caller should make sure that the |
9cfc7bd60 batman-adv: Refor... |
727 |
* skb is freed. |
62fe710f6 batman-adv: Fix k... |
728 729 |
* * Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY on errors. |
9cfc7bd60 batman-adv: Refor... |
730 |
*/ |
56303d34a batman-adv: Prefi... |
731 |
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, |
9455e34cb batman-adv: Prefi... |
732 |
const struct sk_buff *skb, |
3111beed0 batman-adv: Simpl... |
733 734 |
unsigned long delay, bool own_packet) |
c6c8fea29 net: Add batman-a... |
735 |
{ |
422d2f778 batman-adv: Remov... |
736 |
struct batadv_hard_iface *primary_if; |
56303d34a batman-adv: Prefi... |
737 |
struct batadv_forw_packet *forw_packet; |
964126901 batman-adv: Prefi... |
738 |
struct batadv_bcast_packet *bcast_packet; |
747e4221a batman-adv: Add c... |
739 |
struct sk_buff *newskb; |
c6c8fea29 net: Add batman-a... |
740 |
|
e5d89254b batman-adv: Prefi... |
741 |
primary_if = batadv_primary_if_get_selected(bat_priv); |
32ae9b221 batman-adv: Make ... |
742 |
if (!primary_if) |
a65e54813 batman-adv: Intro... |
743 |
goto err; |
c6c8fea29 net: Add batman-a... |
744 |
|
99ba18ef0 batman-adv: priva... |
745 746 747 748 749 |
newskb = skb_copy(skb, GFP_ATOMIC); if (!newskb) { batadv_hardif_put(primary_if); goto err; } |
a65e54813 batman-adv: Intro... |
750 751 |
forw_packet = batadv_forw_packet_alloc(primary_if, NULL, &bat_priv->bcast_queue_left, |
99ba18ef0 batman-adv: priva... |
752 |
bat_priv, newskb); |
a65e54813 batman-adv: Intro... |
753 |
batadv_hardif_put(primary_if); |
c6c8fea29 net: Add batman-a... |
754 |
if (!forw_packet) |
a65e54813 batman-adv: Intro... |
755 |
goto err_packet_free; |
c6c8fea29 net: Add batman-a... |
756 757 |
/* as we have a copy now, it is safe to decrease the TTL */ |
964126901 batman-adv: Prefi... |
758 |
bcast_packet = (struct batadv_bcast_packet *)newskb->data; |
a40d9b075 batman-adv: fix h... |
759 |
bcast_packet->ttl--; |
c6c8fea29 net: Add batman-a... |
760 |
|
3111beed0 batman-adv: Simpl... |
761 |
forw_packet->own = own_packet; |
c6c8fea29 net: Add batman-a... |
762 |
|
724144420 batman-adv: a del... |
763 764 |
INIT_DELAYED_WORK(&forw_packet->delayed_work, batadv_send_outstanding_bcast_packet); |
9b4aec647 batman-adv: fix r... |
765 |
batadv_forw_packet_bcast_queue(bat_priv, forw_packet, jiffies + delay); |
c6c8fea29 net: Add batman-a... |
766 |
return NETDEV_TX_OK; |
a65e54813 batman-adv: Intro... |
767 |
err_packet_free: |
99ba18ef0 batman-adv: priva... |
768 |
kfree_skb(newskb); |
a65e54813 batman-adv: Intro... |
769 |
err: |
c6c8fea29 net: Add batman-a... |
770 771 |
return NETDEV_TX_BUSY; } |
e2d9ba435 batman-adv: restr... |
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 |
/** * batadv_forw_packet_bcasts_left - check if a retransmission is necessary * @forw_packet: the forwarding packet to check * @hard_iface: the interface to check on * * Checks whether a given packet has any (re)transmissions left on the provided * interface. * * hard_iface may be NULL: In that case the number of transmissions this skb had * so far is compared with the maximum amount of retransmissions independent of * any interface instead. * * Return: True if (re)transmissions are left, false otherwise. */ static bool batadv_forw_packet_bcasts_left(struct batadv_forw_packet *forw_packet, struct batadv_hard_iface *hard_iface) { unsigned int max; if (hard_iface) max = hard_iface->num_bcasts; else max = BATADV_NUM_BCASTS_MAX; return BATADV_SKB_CB(forw_packet->skb)->num_bcasts < max; } /** * batadv_forw_packet_bcasts_inc - increment retransmission counter of a packet * @forw_packet: the packet to increase the counter for */ static void batadv_forw_packet_bcasts_inc(struct batadv_forw_packet *forw_packet) { BATADV_SKB_CB(forw_packet->skb)->num_bcasts++; } /** * batadv_forw_packet_is_rebroadcast - check packet for previous transmissions * @forw_packet: the packet to check * * Return: True if this packet was transmitted before, false otherwise. */ bool batadv_forw_packet_is_rebroadcast(struct batadv_forw_packet *forw_packet) { return BATADV_SKB_CB(forw_packet->skb)->num_bcasts > 0; } |
bb079c82e batman-adv: Prefi... |
820 |
static void batadv_send_outstanding_bcast_packet(struct work_struct *work) |
c6c8fea29 net: Add batman-a... |
821 |
{ |
56303d34a batman-adv: Prefi... |
822 |
struct batadv_hard_iface *hard_iface; |
3111beed0 batman-adv: Simpl... |
823 |
struct batadv_hardif_neigh_node *neigh_node; |
bbb1f90ef batman-adv: Don't... |
824 |
struct delayed_work *delayed_work; |
56303d34a batman-adv: Prefi... |
825 |
struct batadv_forw_packet *forw_packet; |
3111beed0 batman-adv: Simpl... |
826 |
struct batadv_bcast_packet *bcast_packet; |
c6c8fea29 net: Add batman-a... |
827 |
struct sk_buff *skb1; |
56303d34a batman-adv: Prefi... |
828 829 |
struct net_device *soft_iface; struct batadv_priv *bat_priv; |
9b4aec647 batman-adv: fix r... |
830 |
unsigned long send_time = jiffies + msecs_to_jiffies(5); |
bd687fe41 batman-adv: use c... |
831 |
bool dropped = false; |
3111beed0 batman-adv: Simpl... |
832 833 834 |
u8 *neigh_addr; u8 *orig_neigh; int ret = 0; |
56303d34a batman-adv: Prefi... |
835 |
|
4ba4bc0f7 batman-adv: use t... |
836 |
delayed_work = to_delayed_work(work); |
56303d34a batman-adv: Prefi... |
837 838 839 840 |
forw_packet = container_of(delayed_work, struct batadv_forw_packet, delayed_work); soft_iface = forw_packet->if_incoming->soft_iface; bat_priv = netdev_priv(soft_iface); |
c6c8fea29 net: Add batman-a... |
841 |
|
bd687fe41 batman-adv: use c... |
842 843 |
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { dropped = true; |
c6c8fea29 net: Add batman-a... |
844 |
goto out; |
bd687fe41 batman-adv: use c... |
845 |
} |
c6c8fea29 net: Add batman-a... |
846 |
|
bd687fe41 batman-adv: use c... |
847 848 |
if (batadv_dat_drop_broadcast_packet(bat_priv, forw_packet)) { dropped = true; |
c384ea3ec batman-adv: Distr... |
849 |
goto out; |
bd687fe41 batman-adv: use c... |
850 |
} |
c384ea3ec batman-adv: Distr... |
851 |
|
3111beed0 batman-adv: Simpl... |
852 |
bcast_packet = (struct batadv_bcast_packet *)forw_packet->skb->data; |
c6c8fea29 net: Add batman-a... |
853 854 |
/* rebroadcast packet */ rcu_read_lock(); |
3193e8fdf batman-adv: Prefi... |
855 |
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { |
e6c10f433 batman-adv: renam... |
856 |
if (hard_iface->soft_iface != soft_iface) |
c6c8fea29 net: Add batman-a... |
857 |
continue; |
e2d9ba435 batman-adv: restr... |
858 |
if (!batadv_forw_packet_bcasts_left(forw_packet, hard_iface)) |
caf65bfcc batman-adv: send ... |
859 |
continue; |
3111beed0 batman-adv: Simpl... |
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 |
if (forw_packet->own) { neigh_node = NULL; } else { neigh_addr = eth_hdr(forw_packet->skb)->h_source; neigh_node = batadv_hardif_neigh_get(hard_iface, neigh_addr); } orig_neigh = neigh_node ? neigh_node->orig : NULL; ret = batadv_hardif_no_broadcast(hard_iface, bcast_packet->orig, orig_neigh); if (ret) { char *type; switch (ret) { case BATADV_HARDIF_BCAST_NORECIPIENT: type = "no neighbor"; break; case BATADV_HARDIF_BCAST_DUPFWD: type = "single neighbor is source"; break; case BATADV_HARDIF_BCAST_DUPORIG: type = "single neighbor is originator"; break; default: type = "unknown"; } |
f25cbb2a6 batman-adv: fix v... |
889 890 |
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "BCAST packet from orig %pM on %s suppressed: %s ", |
3111beed0 batman-adv: Simpl... |
891 892 893 894 895 896 897 898 899 900 901 |
bcast_packet->orig, hard_iface->net_dev->name, type); if (neigh_node) batadv_hardif_neigh_put(neigh_node); continue; } if (neigh_node) batadv_hardif_neigh_put(neigh_node); |
273534468 batman-adv: Check... |
902 903 |
if (!kref_get_unless_zero(&hard_iface->refcount)) continue; |
c6c8fea29 net: Add batman-a... |
904 905 906 |
/* send a copy of the saved skb */ skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); if (skb1) |
95d392784 batman-adv: keep ... |
907 |
batadv_send_broadcast_skb(skb1, hard_iface); |
273534468 batman-adv: Check... |
908 909 |
batadv_hardif_put(hard_iface); |
c6c8fea29 net: Add batman-a... |
910 911 |
} rcu_read_unlock(); |
e2d9ba435 batman-adv: restr... |
912 |
batadv_forw_packet_bcasts_inc(forw_packet); |
c6c8fea29 net: Add batman-a... |
913 914 |
/* if we still have some more bcasts to send */ |
e2d9ba435 batman-adv: restr... |
915 |
if (batadv_forw_packet_bcasts_left(forw_packet, NULL)) { |
9b4aec647 batman-adv: fix r... |
916 917 |
batadv_forw_packet_bcast_queue(bat_priv, forw_packet, send_time); |
c6c8fea29 net: Add batman-a... |
918 919 920 921 |
return; } out: |
9b4aec647 batman-adv: fix r... |
922 923 924 925 |
/* do we get something for free()? */ if (batadv_forw_packet_steal(forw_packet, &bat_priv->forw_bcast_list_lock)) batadv_forw_packet_free(forw_packet, dropped); |
c6c8fea29 net: Add batman-a... |
926 |
} |
9b4aec647 batman-adv: fix r... |
927 928 929 930 931 932 933 934 935 936 937 |
/** * batadv_purge_outstanding_packets - stop/purge scheduled bcast/OGMv1 packets * @bat_priv: the bat priv with all the soft interface information * @hard_iface: the hard interface to cancel and purge bcast/ogm packets on * * This method cancels and purges any broadcast and OGMv1 packet on the given * hard_iface. If hard_iface is NULL, broadcast and OGMv1 packets on all hard * interfaces will be canceled and purged. * * This function might sleep. */ |
56303d34a batman-adv: Prefi... |
938 939 940 |
void batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, const struct batadv_hard_iface *hard_iface) |
c6c8fea29 net: Add batman-a... |
941 |
{ |
9b4aec647 batman-adv: fix r... |
942 |
struct hlist_head head = HLIST_HEAD_INIT; |
c6c8fea29 net: Add batman-a... |
943 |
|
e6c10f433 batman-adv: renam... |
944 |
if (hard_iface) |
39c75a51e batman-adv: Prefi... |
945 |
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
22f0502ed batman-adv: Print... |
946 947 948 |
"%s(): %s ", __func__, hard_iface->net_dev->name); |
c6c8fea29 net: Add batman-a... |
949 |
else |
39c75a51e batman-adv: Prefi... |
950 |
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
22f0502ed batman-adv: Print... |
951 952 |
"%s() ", __func__); |
c6c8fea29 net: Add batman-a... |
953 |
|
9b4aec647 batman-adv: fix r... |
954 |
/* claim bcast list for free() */ |
c6c8fea29 net: Add batman-a... |
955 |
spin_lock_bh(&bat_priv->forw_bcast_list_lock); |
9b4aec647 batman-adv: fix r... |
956 957 |
batadv_forw_packet_list_steal(&bat_priv->forw_bcast_list, &head, hard_iface); |
c6c8fea29 net: Add batman-a... |
958 |
spin_unlock_bh(&bat_priv->forw_bcast_list_lock); |
9b4aec647 batman-adv: fix r... |
959 |
/* claim batman packet list for free() */ |
c6c8fea29 net: Add batman-a... |
960 |
spin_lock_bh(&bat_priv->forw_bat_list_lock); |
9b4aec647 batman-adv: fix r... |
961 962 |
batadv_forw_packet_list_steal(&bat_priv->forw_bat_list, &head, hard_iface); |
c6c8fea29 net: Add batman-a... |
963 |
spin_unlock_bh(&bat_priv->forw_bat_list_lock); |
9b4aec647 batman-adv: fix r... |
964 965 966 |
/* then cancel or wait for packet workers to finish and free */ batadv_forw_packet_list_free(&head); |
c6c8fea29 net: Add batman-a... |
967 |
} |