Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/batman-adv/main.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0
2
/* Copyright (C) B.A.T.M.A.N. contributors:
3
*
4
* Marek Lindner, Simon Wunderlich
5
*/
6
7
#include "main.h"
8
9
#include <linux/array_size.h>
10
#include <linux/atomic.h>
11
#include <linux/build_bug.h>
12
#include <linux/byteorder/generic.h>
13
#include <linux/container_of.h>
14
#include <linux/device.h>
15
#include <linux/errno.h>
16
#include <linux/gfp.h>
17
#include <linux/if_ether.h>
18
#include <linux/if_vlan.h>
19
#include <linux/init.h>
20
#include <linux/ip.h>
21
#include <linux/ipv6.h>
22
#include <linux/kobject.h>
23
#include <linux/kref.h>
24
#include <linux/list.h>
25
#include <linux/minmax.h>
26
#include <linux/module.h>
27
#include <linux/netdevice.h>
28
#include <linux/printk.h>
29
#include <linux/rcupdate.h>
30
#include <linux/skbuff.h>
31
#include <linux/slab.h>
32
#include <linux/spinlock.h>
33
#include <linux/sprintf.h>
34
#include <linux/stddef.h>
35
#include <linux/string.h>
36
#include <linux/workqueue.h>
37
#include <net/dsfield.h>
38
#include <net/genetlink.h>
39
#include <net/rtnetlink.h>
40
#include <uapi/linux/batadv_packet.h>
41
#include <uapi/linux/batman_adv.h>
42
43
#include "bat_algo.h"
44
#include "bat_iv_ogm.h"
45
#include "bat_v.h"
46
#include "bridge_loop_avoidance.h"
47
#include "distributed-arp-table.h"
48
#include "gateway_client.h"
49
#include "gateway_common.h"
50
#include "hard-interface.h"
51
#include "log.h"
52
#include "mesh-interface.h"
53
#include "multicast.h"
54
#include "netlink.h"
55
#include "originator.h"
56
#include "routing.h"
57
#include "send.h"
58
#include "tp_meter.h"
59
#include "translation-table.h"
60
61
/* List manipulations on hardif_list have to be rtnl_lock()'ed,
62
* list traversals just rcu-locked
63
*/
64
struct list_head batadv_hardif_list;
65
unsigned int batadv_hardif_generation;
66
static int (*batadv_rx_handler[256])(struct sk_buff *skb,
67
struct batadv_hard_iface *recv_if);
68
69
struct workqueue_struct *batadv_event_workqueue;
70
71
static void batadv_recv_handler_init(void);
72
73
#define BATADV_UEV_TYPE_VAR "BATTYPE="
74
#define BATADV_UEV_ACTION_VAR "BATACTION="
75
#define BATADV_UEV_DATA_VAR "BATDATA="
76
77
static char *batadv_uev_action_str[] = {
78
"add",
79
"del",
80
"change",
81
"loopdetect",
82
};
83
84
static char *batadv_uev_type_str[] = {
85
"gw",
86
"bla",
87
};
88
89
static int __init batadv_init(void)
90
{
91
int ret;
92
93
ret = batadv_tt_cache_init();
94
if (ret < 0)
95
return ret;
96
97
INIT_LIST_HEAD(&batadv_hardif_list);
98
batadv_algo_init();
99
100
batadv_recv_handler_init();
101
102
batadv_v_init();
103
batadv_iv_init();
104
batadv_tp_meter_init();
105
106
batadv_event_workqueue = create_singlethread_workqueue("bat_events");
107
if (!batadv_event_workqueue)
108
goto err_create_wq;
109
110
register_netdevice_notifier(&batadv_hard_if_notifier);
111
rtnl_link_register(&batadv_link_ops);
112
batadv_netlink_register();
113
114
pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
115
BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
116
117
return 0;
118
119
err_create_wq:
120
batadv_tt_cache_destroy();
121
122
return -ENOMEM;
123
}
124
125
static void __exit batadv_exit(void)
126
{
127
batadv_netlink_unregister();
128
rtnl_link_unregister(&batadv_link_ops);
129
unregister_netdevice_notifier(&batadv_hard_if_notifier);
130
131
destroy_workqueue(batadv_event_workqueue);
132
batadv_event_workqueue = NULL;
133
134
rcu_barrier();
135
136
batadv_tt_cache_destroy();
137
}
138
139
/**
140
* batadv_mesh_init() - Initialize mesh interface
141
* @mesh_iface: netdev struct of the mesh interface
142
*
143
* Return: 0 on success or negative error number in case of failure
144
*/
145
int batadv_mesh_init(struct net_device *mesh_iface)
146
{
147
struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
148
int ret;
149
150
spin_lock_init(&bat_priv->forw_bat_list_lock);
151
spin_lock_init(&bat_priv->forw_bcast_list_lock);
152
spin_lock_init(&bat_priv->tt.changes_list_lock);
153
spin_lock_init(&bat_priv->tt.req_list_lock);
154
spin_lock_init(&bat_priv->tt.roam_list_lock);
155
spin_lock_init(&bat_priv->tt.last_changeset_lock);
156
spin_lock_init(&bat_priv->tt.commit_lock);
157
spin_lock_init(&bat_priv->gw.list_lock);
158
#ifdef CONFIG_BATMAN_ADV_MCAST
159
spin_lock_init(&bat_priv->mcast.mla_lock);
160
spin_lock_init(&bat_priv->mcast.want_lists_lock);
161
#endif
162
spin_lock_init(&bat_priv->tvlv.container_list_lock);
163
spin_lock_init(&bat_priv->tvlv.handler_list_lock);
164
spin_lock_init(&bat_priv->meshif_vlan_list_lock);
165
spin_lock_init(&bat_priv->tp_list_lock);
166
167
INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
168
INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
169
INIT_HLIST_HEAD(&bat_priv->gw.gateway_list);
170
#ifdef CONFIG_BATMAN_ADV_MCAST
171
INIT_HLIST_HEAD(&bat_priv->mcast.want_all_unsnoopables_list);
172
INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv4_list);
173
INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv6_list);
174
#endif
175
INIT_LIST_HEAD(&bat_priv->tt.changes_list);
176
INIT_HLIST_HEAD(&bat_priv->tt.req_list);
177
INIT_LIST_HEAD(&bat_priv->tt.roam_list);
178
#ifdef CONFIG_BATMAN_ADV_MCAST
179
INIT_HLIST_HEAD(&bat_priv->mcast.mla_list);
180
#endif
181
INIT_HLIST_HEAD(&bat_priv->tvlv.container_list);
182
INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list);
183
INIT_HLIST_HEAD(&bat_priv->meshif_vlan_list);
184
INIT_HLIST_HEAD(&bat_priv->tp_list);
185
186
bat_priv->gw.generation = 0;
187
188
ret = batadv_originator_init(bat_priv);
189
if (ret < 0) {
190
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
191
goto err_orig;
192
}
193
194
ret = batadv_tt_init(bat_priv);
195
if (ret < 0) {
196
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
197
goto err_tt;
198
}
199
200
ret = batadv_v_mesh_init(bat_priv);
201
if (ret < 0) {
202
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
203
goto err_v;
204
}
205
206
ret = batadv_bla_init(bat_priv);
207
if (ret < 0) {
208
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
209
goto err_bla;
210
}
211
212
ret = batadv_dat_init(bat_priv);
213
if (ret < 0) {
214
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
215
goto err_dat;
216
}
217
218
batadv_gw_init(bat_priv);
219
batadv_mcast_init(bat_priv);
220
221
atomic_set(&bat_priv->gw.reselect, 0);
222
atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
223
224
return 0;
225
226
err_dat:
227
batadv_bla_free(bat_priv);
228
err_bla:
229
batadv_v_mesh_free(bat_priv);
230
err_v:
231
batadv_tt_free(bat_priv);
232
err_tt:
233
batadv_originator_free(bat_priv);
234
err_orig:
235
batadv_purge_outstanding_packets(bat_priv, NULL);
236
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
237
238
return ret;
239
}
240
241
/**
242
* batadv_mesh_free() - Deinitialize mesh interface
243
* @mesh_iface: netdev struct of the mesh interface
244
*/
245
void batadv_mesh_free(struct net_device *mesh_iface)
246
{
247
struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
248
249
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
250
251
batadv_purge_outstanding_packets(bat_priv, NULL);
252
253
batadv_gw_node_free(bat_priv);
254
255
batadv_v_mesh_free(bat_priv);
256
batadv_dat_free(bat_priv);
257
batadv_bla_free(bat_priv);
258
259
batadv_mcast_free(bat_priv);
260
261
/* Free the TT and the originator tables only after having terminated
262
* all the other depending components which may use these structures for
263
* their purposes.
264
*/
265
batadv_tt_free(bat_priv);
266
267
/* Since the originator table clean up routine is accessing the TT
268
* tables as well, it has to be invoked after the TT tables have been
269
* freed and marked as empty. This ensures that no cleanup RCU callbacks
270
* accessing the TT data are scheduled for later execution.
271
*/
272
batadv_originator_free(bat_priv);
273
274
batadv_gw_free(bat_priv);
275
276
free_percpu(bat_priv->bat_counters);
277
bat_priv->bat_counters = NULL;
278
279
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
280
}
281
282
/**
283
* batadv_is_my_mac() - check if the given mac address belongs to any of the
284
* real interfaces in the current mesh
285
* @bat_priv: the bat priv with all the mesh interface information
286
* @addr: the address to check
287
*
288
* Return: 'true' if the mac address was found, false otherwise.
289
*/
290
bool batadv_is_my_mac(struct batadv_priv *bat_priv, const u8 *addr)
291
{
292
const struct batadv_hard_iface *hard_iface;
293
struct list_head *iter;
294
bool is_my_mac = false;
295
296
rcu_read_lock();
297
netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
298
if (hard_iface->if_status != BATADV_IF_ACTIVE)
299
continue;
300
301
if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) {
302
is_my_mac = true;
303
break;
304
}
305
}
306
rcu_read_unlock();
307
return is_my_mac;
308
}
309
310
/**
311
* batadv_max_header_len() - calculate maximum encapsulation overhead for a
312
* payload packet
313
*
314
* Return: the maximum encapsulation overhead in bytes.
315
*/
316
int batadv_max_header_len(void)
317
{
318
int header_len = 0;
319
320
header_len = max_t(int, header_len,
321
sizeof(struct batadv_unicast_packet));
322
header_len = max_t(int, header_len,
323
sizeof(struct batadv_unicast_4addr_packet));
324
header_len = max_t(int, header_len,
325
sizeof(struct batadv_bcast_packet));
326
327
return header_len + ETH_HLEN;
328
}
329
330
/**
331
* batadv_skb_set_priority() - sets skb priority according to packet content
332
* @skb: the packet to be sent
333
* @offset: offset to the packet content
334
*
335
* This function sets a value between 256 and 263 (802.1d priority), which
336
* can be interpreted by the cfg80211 or other drivers.
337
*/
338
void batadv_skb_set_priority(struct sk_buff *skb, int offset)
339
{
340
struct iphdr ip_hdr_tmp, *ip_hdr;
341
struct ipv6hdr ip6_hdr_tmp, *ip6_hdr;
342
struct ethhdr ethhdr_tmp, *ethhdr;
343
struct vlan_ethhdr *vhdr, vhdr_tmp;
344
u32 prio;
345
346
/* already set, do nothing */
347
if (skb->priority >= 256 && skb->priority <= 263)
348
return;
349
350
ethhdr = skb_header_pointer(skb, offset, sizeof(*ethhdr), &ethhdr_tmp);
351
if (!ethhdr)
352
return;
353
354
switch (ethhdr->h_proto) {
355
case htons(ETH_P_8021Q):
356
vhdr = skb_header_pointer(skb, offset + sizeof(*vhdr),
357
sizeof(*vhdr), &vhdr_tmp);
358
if (!vhdr)
359
return;
360
prio = ntohs(vhdr->h_vlan_TCI) & VLAN_PRIO_MASK;
361
prio = prio >> VLAN_PRIO_SHIFT;
362
break;
363
case htons(ETH_P_IP):
364
ip_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
365
sizeof(*ip_hdr), &ip_hdr_tmp);
366
if (!ip_hdr)
367
return;
368
prio = (ipv4_get_dsfield(ip_hdr) & 0xfc) >> 5;
369
break;
370
case htons(ETH_P_IPV6):
371
ip6_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
372
sizeof(*ip6_hdr), &ip6_hdr_tmp);
373
if (!ip6_hdr)
374
return;
375
prio = (ipv6_get_dsfield(ip6_hdr) & 0xfc) >> 5;
376
break;
377
default:
378
return;
379
}
380
381
skb->priority = prio + 256;
382
}
383
384
static int batadv_recv_unhandled_packet(struct sk_buff *skb,
385
struct batadv_hard_iface *recv_if)
386
{
387
kfree_skb(skb);
388
389
return NET_RX_DROP;
390
}
391
392
/* incoming packets with the batman ethertype received on any active hard
393
* interface
394
*/
395
396
/**
397
* batadv_batman_skb_recv() - Handle incoming message from an hard interface
398
* @skb: the received packet
399
* @dev: the net device that the packet was received on
400
* @ptype: packet type of incoming packet (ETH_P_BATMAN)
401
* @orig_dev: the original receive net device (e.g. bonded device)
402
*
403
* Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure
404
*/
405
int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
406
struct packet_type *ptype,
407
struct net_device *orig_dev)
408
{
409
struct batadv_priv *bat_priv;
410
struct batadv_ogm_packet *batadv_ogm_packet;
411
struct batadv_hard_iface *hard_iface;
412
u8 idx;
413
414
hard_iface = container_of(ptype, struct batadv_hard_iface,
415
batman_adv_ptype);
416
417
/* Prevent processing a packet received on an interface which is getting
418
* shut down otherwise the packet may trigger de-reference errors
419
* further down in the receive path.
420
*/
421
if (!kref_get_unless_zero(&hard_iface->refcount))
422
goto err_out;
423
424
skb = skb_share_check(skb, GFP_ATOMIC);
425
426
/* skb was released by skb_share_check() */
427
if (!skb)
428
goto err_put;
429
430
/* packet should hold at least type and version */
431
if (unlikely(!pskb_may_pull(skb, 2)))
432
goto err_free;
433
434
/* expect a valid ethernet header here. */
435
if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb)))
436
goto err_free;
437
438
if (!hard_iface->mesh_iface)
439
goto err_free;
440
441
bat_priv = netdev_priv(hard_iface->mesh_iface);
442
443
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
444
goto err_free;
445
446
/* discard frames on not active interfaces */
447
if (hard_iface->if_status != BATADV_IF_ACTIVE)
448
goto err_free;
449
450
batadv_ogm_packet = (struct batadv_ogm_packet *)skb->data;
451
452
if (batadv_ogm_packet->version != BATADV_COMPAT_VERSION) {
453
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
454
"Drop packet: incompatible batman version (%i)\n",
455
batadv_ogm_packet->version);
456
goto err_free;
457
}
458
459
/* reset control block to avoid left overs from previous users */
460
memset(skb->cb, 0, sizeof(struct batadv_skb_cb));
461
462
idx = batadv_ogm_packet->packet_type;
463
(*batadv_rx_handler[idx])(skb, hard_iface);
464
465
batadv_hardif_put(hard_iface);
466
467
/* return NET_RX_SUCCESS in any case as we
468
* most probably dropped the packet for
469
* routing-logical reasons.
470
*/
471
return NET_RX_SUCCESS;
472
473
err_free:
474
kfree_skb(skb);
475
err_put:
476
batadv_hardif_put(hard_iface);
477
err_out:
478
return NET_RX_DROP;
479
}
480
481
static void batadv_recv_handler_init(void)
482
{
483
int i;
484
485
for (i = 0; i < ARRAY_SIZE(batadv_rx_handler); i++)
486
batadv_rx_handler[i] = batadv_recv_unhandled_packet;
487
488
for (i = BATADV_UNICAST_MIN; i <= BATADV_UNICAST_MAX; i++)
489
batadv_rx_handler[i] = batadv_recv_unhandled_unicast_packet;
490
491
/* compile time checks for sizes */
492
BUILD_BUG_ON(sizeof(struct batadv_bla_claim_dst) != 6);
493
BUILD_BUG_ON(sizeof(struct batadv_ogm_packet) != 24);
494
BUILD_BUG_ON(sizeof(struct batadv_icmp_header) != 20);
495
BUILD_BUG_ON(sizeof(struct batadv_icmp_packet) != 20);
496
BUILD_BUG_ON(sizeof(struct batadv_icmp_packet_rr) != 116);
497
BUILD_BUG_ON(sizeof(struct batadv_unicast_packet) != 10);
498
BUILD_BUG_ON(sizeof(struct batadv_unicast_4addr_packet) != 18);
499
BUILD_BUG_ON(sizeof(struct batadv_frag_packet) != 20);
500
BUILD_BUG_ON(sizeof(struct batadv_bcast_packet) != 14);
501
BUILD_BUG_ON(sizeof(struct batadv_coded_packet) != 46);
502
BUILD_BUG_ON(sizeof(struct batadv_unicast_tvlv_packet) != 20);
503
BUILD_BUG_ON(sizeof(struct batadv_tvlv_hdr) != 4);
504
BUILD_BUG_ON(sizeof(struct batadv_tvlv_gateway_data) != 8);
505
BUILD_BUG_ON(sizeof(struct batadv_tvlv_tt_vlan_data) != 8);
506
BUILD_BUG_ON(sizeof(struct batadv_tvlv_tt_change) != 12);
507
BUILD_BUG_ON(sizeof(struct batadv_tvlv_roam_adv) != 8);
508
509
i = sizeof_field(struct sk_buff, cb);
510
BUILD_BUG_ON(sizeof(struct batadv_skb_cb) > i);
511
512
/* broadcast packet */
513
batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
514
/* multicast packet */
515
batadv_rx_handler[BATADV_MCAST] = batadv_recv_mcast_packet;
516
517
/* unicast packets ... */
518
/* unicast with 4 addresses packet */
519
batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet;
520
/* unicast packet */
521
batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
522
/* unicast tvlv packet */
523
batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv;
524
/* batman icmp packet */
525
batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet;
526
/* Fragmented packets */
527
batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_frag_packet;
528
}
529
530
/**
531
* batadv_recv_handler_register() - Register handler for batman-adv packet type
532
* @packet_type: batadv_packettype which should be handled
533
* @recv_handler: receive handler for the packet type
534
*
535
* Return: 0 on success or negative error number in case of failure
536
*/
537
int
538
batadv_recv_handler_register(u8 packet_type,
539
int (*recv_handler)(struct sk_buff *,
540
struct batadv_hard_iface *))
541
{
542
int (*curr)(struct sk_buff *skb,
543
struct batadv_hard_iface *recv_if);
544
curr = batadv_rx_handler[packet_type];
545
546
if (curr != batadv_recv_unhandled_packet &&
547
curr != batadv_recv_unhandled_unicast_packet)
548
return -EBUSY;
549
550
batadv_rx_handler[packet_type] = recv_handler;
551
return 0;
552
}
553
554
/**
555
* batadv_recv_handler_unregister() - Unregister handler for packet type
556
* @packet_type: batadv_packettype which should no longer be handled
557
*/
558
void batadv_recv_handler_unregister(u8 packet_type)
559
{
560
batadv_rx_handler[packet_type] = batadv_recv_unhandled_packet;
561
}
562
563
/**
564
* batadv_get_vid() - extract the VLAN identifier from skb if any
565
* @skb: the buffer containing the packet
566
* @header_len: length of the batman header preceding the ethernet header
567
*
568
* Return: VID with the BATADV_VLAN_HAS_TAG flag when the packet embedded in the
569
* skb is vlan tagged. Otherwise BATADV_NO_FLAGS.
570
*/
571
unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len)
572
{
573
struct ethhdr *ethhdr = (struct ethhdr *)(skb->data + header_len);
574
struct vlan_ethhdr *vhdr;
575
unsigned short vid;
576
577
if (ethhdr->h_proto != htons(ETH_P_8021Q))
578
return BATADV_NO_FLAGS;
579
580
if (!pskb_may_pull(skb, header_len + VLAN_ETH_HLEN))
581
return BATADV_NO_FLAGS;
582
583
vhdr = (struct vlan_ethhdr *)(skb->data + header_len);
584
vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
585
586
/* VID 0 is only used to indicate "priority tag" frames which only
587
* contain priority information and no VID.
588
*/
589
if (vid == 0)
590
return BATADV_NO_FLAGS;
591
592
vid |= BATADV_VLAN_HAS_TAG;
593
594
return vid;
595
}
596
597
/**
598
* batadv_vlan_ap_isola_get() - return AP isolation status for the given vlan
599
* @bat_priv: the bat priv with all the mesh interface information
600
* @vid: the VLAN identifier for which the AP isolation attributed as to be
601
* looked up
602
*
603
* Return: true if AP isolation is on for the VLAN identified by vid, false
604
* otherwise
605
*/
606
bool batadv_vlan_ap_isola_get(struct batadv_priv *bat_priv, unsigned short vid)
607
{
608
bool ap_isolation_enabled = false;
609
struct batadv_meshif_vlan *vlan;
610
611
/* if the AP isolation is requested on a VLAN, then check for its
612
* setting in the proper VLAN private data structure
613
*/
614
vlan = batadv_meshif_vlan_get(bat_priv, vid);
615
if (vlan) {
616
ap_isolation_enabled = atomic_read(&vlan->ap_isolation);
617
batadv_meshif_vlan_put(vlan);
618
}
619
620
return ap_isolation_enabled;
621
}
622
623
/**
624
* batadv_throw_uevent() - Send an uevent with batman-adv specific env data
625
* @bat_priv: the bat priv with all the mesh interface information
626
* @type: subsystem type of event. Stored in uevent's BATTYPE
627
* @action: action type of event. Stored in uevent's BATACTION
628
* @data: string with additional information to the event (ignored for
629
* BATADV_UEV_DEL). Stored in uevent's BATDATA
630
*
631
* Return: 0 on success or negative error number in case of failure
632
*/
633
int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
634
enum batadv_uev_action action, const char *data)
635
{
636
int ret = -ENOMEM;
637
struct kobject *bat_kobj;
638
char *uevent_env[4] = { NULL, NULL, NULL, NULL };
639
640
bat_kobj = &bat_priv->mesh_iface->dev.kobj;
641
642
uevent_env[0] = kasprintf(GFP_ATOMIC,
643
"%s%s", BATADV_UEV_TYPE_VAR,
644
batadv_uev_type_str[type]);
645
if (!uevent_env[0])
646
goto report_error;
647
648
uevent_env[1] = kasprintf(GFP_ATOMIC,
649
"%s%s", BATADV_UEV_ACTION_VAR,
650
batadv_uev_action_str[action]);
651
if (!uevent_env[1])
652
goto free_first_env;
653
654
/* If the event is DEL, ignore the data field */
655
if (action != BATADV_UEV_DEL) {
656
uevent_env[2] = kasprintf(GFP_ATOMIC,
657
"%s%s", BATADV_UEV_DATA_VAR, data);
658
if (!uevent_env[2])
659
goto free_second_env;
660
}
661
662
ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
663
kfree(uevent_env[2]);
664
free_second_env:
665
kfree(uevent_env[1]);
666
free_first_env:
667
kfree(uevent_env[0]);
668
669
if (ret)
670
report_error:
671
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
672
"Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
673
batadv_uev_type_str[type],
674
batadv_uev_action_str[action],
675
(action == BATADV_UEV_DEL ? "NULL" : data), ret);
676
return ret;
677
}
678
679
module_init(batadv_init);
680
module_exit(batadv_exit);
681
682
MODULE_LICENSE("GPL");
683
684
MODULE_AUTHOR(BATADV_DRIVER_AUTHOR);
685
MODULE_DESCRIPTION(BATADV_DRIVER_DESC);
686
MODULE_VERSION(BATADV_SOURCE_VERSION);
687
MODULE_ALIAS_RTNL_LINK("batadv");
688
MODULE_ALIAS_GENL_FAMILY(BATADV_NL_NAME);
689
690