1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2016-2020 B.A.T.M.A.N. contributors:
10 #include <linux/atomic.h>
11 #include <linux/bitops.h>
12 #include <linux/bug.h>
13 #include <linux/byteorder/generic.h>
14 #include <linux/cache.h>
15 #include <linux/err.h>
16 #include <linux/errno.h>
17 #include <linux/export.h>
18 #include <linux/genetlink.h>
19 #include <linux/gfp.h>
20 #include <linux/if_ether.h>
21 #include <linux/if_vlan.h>
22 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/limits.h>
25 #include <linux/list.h>
26 #include <linux/netdevice.h>
27 #include <linux/netlink.h>
28 #include <linux/printk.h>
29 #include <linux/rtnetlink.h>
30 #include <linux/skbuff.h>
31 #include <linux/stddef.h>
32 #include <linux/types.h>
33 #include <net/genetlink.h>
34 #include <net/net_namespace.h>
35 #include <net/netlink.h>
37 #include <uapi/linux/batadv_packet.h>
38 #include <uapi/linux/batman_adv.h>
41 #include "bridge_loop_avoidance.h"
42 #include "distributed-arp-table.h"
43 #include "gateway_client.h"
44 #include "gateway_common.h"
45 #include "hard-interface.h"
47 #include "multicast.h"
48 #include "network-coding.h"
49 #include "originator.h"
50 #include "soft-interface.h"
52 #include "translation-table.h"
54 struct genl_family batadv_netlink_family
;
56 /* multicast groups */
57 enum batadv_netlink_multicast_groups
{
58 BATADV_NL_MCGRP_CONFIG
,
59 BATADV_NL_MCGRP_TPMETER
,
63 * enum batadv_genl_ops_flags - flags for genl_ops's internal_flags
65 enum batadv_genl_ops_flags
{
67 * @BATADV_FLAG_NEED_MESH: request requires valid soft interface in
68 * attribute BATADV_ATTR_MESH_IFINDEX and expects a pointer to it to be
69 * saved in info->user_ptr[0]
71 BATADV_FLAG_NEED_MESH
= BIT(0),
74 * @BATADV_FLAG_NEED_HARDIF: request requires valid hard interface in
75 * attribute BATADV_ATTR_HARD_IFINDEX and expects a pointer to it to be
76 * saved in info->user_ptr[1]
78 BATADV_FLAG_NEED_HARDIF
= BIT(1),
81 * @BATADV_FLAG_NEED_VLAN: request requires valid vlan in
82 * attribute BATADV_ATTR_VLANID and expects a pointer to it to be
83 * saved in info->user_ptr[1]
85 BATADV_FLAG_NEED_VLAN
= BIT(2),
88 static const struct genl_multicast_group batadv_netlink_mcgrps
[] = {
89 [BATADV_NL_MCGRP_CONFIG
] = { .name
= BATADV_NL_MCAST_GROUP_CONFIG
},
90 [BATADV_NL_MCGRP_TPMETER
] = { .name
= BATADV_NL_MCAST_GROUP_TPMETER
},
93 static const struct nla_policy batadv_netlink_policy
[NUM_BATADV_ATTR
] = {
94 [BATADV_ATTR_VERSION
] = { .type
= NLA_STRING
},
95 [BATADV_ATTR_ALGO_NAME
] = { .type
= NLA_STRING
},
96 [BATADV_ATTR_MESH_IFINDEX
] = { .type
= NLA_U32
},
97 [BATADV_ATTR_MESH_IFNAME
] = { .type
= NLA_STRING
},
98 [BATADV_ATTR_MESH_ADDRESS
] = { .len
= ETH_ALEN
},
99 [BATADV_ATTR_HARD_IFINDEX
] = { .type
= NLA_U32
},
100 [BATADV_ATTR_HARD_IFNAME
] = { .type
= NLA_STRING
},
101 [BATADV_ATTR_HARD_ADDRESS
] = { .len
= ETH_ALEN
},
102 [BATADV_ATTR_ORIG_ADDRESS
] = { .len
= ETH_ALEN
},
103 [BATADV_ATTR_TPMETER_RESULT
] = { .type
= NLA_U8
},
104 [BATADV_ATTR_TPMETER_TEST_TIME
] = { .type
= NLA_U32
},
105 [BATADV_ATTR_TPMETER_BYTES
] = { .type
= NLA_U64
},
106 [BATADV_ATTR_TPMETER_COOKIE
] = { .type
= NLA_U32
},
107 [BATADV_ATTR_ACTIVE
] = { .type
= NLA_FLAG
},
108 [BATADV_ATTR_TT_ADDRESS
] = { .len
= ETH_ALEN
},
109 [BATADV_ATTR_TT_TTVN
] = { .type
= NLA_U8
},
110 [BATADV_ATTR_TT_LAST_TTVN
] = { .type
= NLA_U8
},
111 [BATADV_ATTR_TT_CRC32
] = { .type
= NLA_U32
},
112 [BATADV_ATTR_TT_VID
] = { .type
= NLA_U16
},
113 [BATADV_ATTR_TT_FLAGS
] = { .type
= NLA_U32
},
114 [BATADV_ATTR_FLAG_BEST
] = { .type
= NLA_FLAG
},
115 [BATADV_ATTR_LAST_SEEN_MSECS
] = { .type
= NLA_U32
},
116 [BATADV_ATTR_NEIGH_ADDRESS
] = { .len
= ETH_ALEN
},
117 [BATADV_ATTR_TQ
] = { .type
= NLA_U8
},
118 [BATADV_ATTR_THROUGHPUT
] = { .type
= NLA_U32
},
119 [BATADV_ATTR_BANDWIDTH_UP
] = { .type
= NLA_U32
},
120 [BATADV_ATTR_BANDWIDTH_DOWN
] = { .type
= NLA_U32
},
121 [BATADV_ATTR_ROUTER
] = { .len
= ETH_ALEN
},
122 [BATADV_ATTR_BLA_OWN
] = { .type
= NLA_FLAG
},
123 [BATADV_ATTR_BLA_ADDRESS
] = { .len
= ETH_ALEN
},
124 [BATADV_ATTR_BLA_VID
] = { .type
= NLA_U16
},
125 [BATADV_ATTR_BLA_BACKBONE
] = { .len
= ETH_ALEN
},
126 [BATADV_ATTR_BLA_CRC
] = { .type
= NLA_U16
},
127 [BATADV_ATTR_DAT_CACHE_IP4ADDRESS
] = { .type
= NLA_U32
},
128 [BATADV_ATTR_DAT_CACHE_HWADDRESS
] = { .len
= ETH_ALEN
},
129 [BATADV_ATTR_DAT_CACHE_VID
] = { .type
= NLA_U16
},
130 [BATADV_ATTR_MCAST_FLAGS
] = { .type
= NLA_U32
},
131 [BATADV_ATTR_MCAST_FLAGS_PRIV
] = { .type
= NLA_U32
},
132 [BATADV_ATTR_VLANID
] = { .type
= NLA_U16
},
133 [BATADV_ATTR_AGGREGATED_OGMS_ENABLED
] = { .type
= NLA_U8
},
134 [BATADV_ATTR_AP_ISOLATION_ENABLED
] = { .type
= NLA_U8
},
135 [BATADV_ATTR_ISOLATION_MARK
] = { .type
= NLA_U32
},
136 [BATADV_ATTR_ISOLATION_MASK
] = { .type
= NLA_U32
},
137 [BATADV_ATTR_BONDING_ENABLED
] = { .type
= NLA_U8
},
138 [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED
] = { .type
= NLA_U8
},
139 [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED
] = { .type
= NLA_U8
},
140 [BATADV_ATTR_FRAGMENTATION_ENABLED
] = { .type
= NLA_U8
},
141 [BATADV_ATTR_GW_BANDWIDTH_DOWN
] = { .type
= NLA_U32
},
142 [BATADV_ATTR_GW_BANDWIDTH_UP
] = { .type
= NLA_U32
},
143 [BATADV_ATTR_GW_MODE
] = { .type
= NLA_U8
},
144 [BATADV_ATTR_GW_SEL_CLASS
] = { .type
= NLA_U32
},
145 [BATADV_ATTR_HOP_PENALTY
] = { .type
= NLA_U8
},
146 [BATADV_ATTR_LOG_LEVEL
] = { .type
= NLA_U32
},
147 [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED
] = { .type
= NLA_U8
},
148 [BATADV_ATTR_MULTICAST_FANOUT
] = { .type
= NLA_U32
},
149 [BATADV_ATTR_NETWORK_CODING_ENABLED
] = { .type
= NLA_U8
},
150 [BATADV_ATTR_ORIG_INTERVAL
] = { .type
= NLA_U32
},
151 [BATADV_ATTR_ELP_INTERVAL
] = { .type
= NLA_U32
},
152 [BATADV_ATTR_THROUGHPUT_OVERRIDE
] = { .type
= NLA_U32
},
156 * batadv_netlink_get_ifindex() - Extract an interface index from a message
157 * @nlh: Message header
158 * @attrtype: Attribute which holds an interface index
160 * Return: interface index, or 0.
163 batadv_netlink_get_ifindex(const struct nlmsghdr
*nlh
, int attrtype
)
165 struct nlattr
*attr
= nlmsg_find_attr(nlh
, GENL_HDRLEN
, attrtype
);
167 return (attr
&& nla_len(attr
) == sizeof(u32
)) ? nla_get_u32(attr
) : 0;
171 * batadv_netlink_mesh_fill_ap_isolation() - Add ap_isolation softif attribute
172 * @msg: Netlink message to dump into
173 * @bat_priv: the bat priv with all the soft interface information
175 * Return: 0 on success or negative error number in case of failure
177 static int batadv_netlink_mesh_fill_ap_isolation(struct sk_buff
*msg
,
178 struct batadv_priv
*bat_priv
)
180 struct batadv_softif_vlan
*vlan
;
183 vlan
= batadv_softif_vlan_get(bat_priv
, BATADV_NO_FLAGS
);
187 ap_isolation
= atomic_read(&vlan
->ap_isolation
);
188 batadv_softif_vlan_put(vlan
);
190 return nla_put_u8(msg
, BATADV_ATTR_AP_ISOLATION_ENABLED
,
195 * batadv_option_set_ap_isolation() - Set ap_isolation from genl msg
196 * @attr: parsed BATADV_ATTR_AP_ISOLATION_ENABLED attribute
197 * @bat_priv: the bat priv with all the soft interface information
199 * Return: 0 on success or negative error number in case of failure
201 static int batadv_netlink_set_mesh_ap_isolation(struct nlattr
*attr
,
202 struct batadv_priv
*bat_priv
)
204 struct batadv_softif_vlan
*vlan
;
206 vlan
= batadv_softif_vlan_get(bat_priv
, BATADV_NO_FLAGS
);
210 atomic_set(&vlan
->ap_isolation
, !!nla_get_u8(attr
));
211 batadv_softif_vlan_put(vlan
);
217 * batadv_netlink_mesh_fill() - Fill message with mesh attributes
218 * @msg: Netlink message to dump into
219 * @bat_priv: the bat priv with all the soft interface information
220 * @cmd: type of message to generate
221 * @portid: Port making netlink request
222 * @seq: sequence number for message
223 * @flags: Additional flags for message
225 * Return: 0 on success or negative error number in case of failure
227 static int batadv_netlink_mesh_fill(struct sk_buff
*msg
,
228 struct batadv_priv
*bat_priv
,
229 enum batadv_nl_commands cmd
,
230 u32 portid
, u32 seq
, int flags
)
232 struct net_device
*soft_iface
= bat_priv
->soft_iface
;
233 struct batadv_hard_iface
*primary_if
= NULL
;
234 struct net_device
*hard_iface
;
237 hdr
= genlmsg_put(msg
, portid
, seq
, &batadv_netlink_family
, flags
, cmd
);
241 if (nla_put_string(msg
, BATADV_ATTR_VERSION
, BATADV_SOURCE_VERSION
) ||
242 nla_put_string(msg
, BATADV_ATTR_ALGO_NAME
,
243 bat_priv
->algo_ops
->name
) ||
244 nla_put_u32(msg
, BATADV_ATTR_MESH_IFINDEX
, soft_iface
->ifindex
) ||
245 nla_put_string(msg
, BATADV_ATTR_MESH_IFNAME
, soft_iface
->name
) ||
246 nla_put(msg
, BATADV_ATTR_MESH_ADDRESS
, ETH_ALEN
,
247 soft_iface
->dev_addr
) ||
248 nla_put_u8(msg
, BATADV_ATTR_TT_TTVN
,
249 (u8
)atomic_read(&bat_priv
->tt
.vn
)))
250 goto nla_put_failure
;
252 #ifdef CONFIG_BATMAN_ADV_BLA
253 if (nla_put_u16(msg
, BATADV_ATTR_BLA_CRC
,
254 ntohs(bat_priv
->bla
.claim_dest
.group
)))
255 goto nla_put_failure
;
258 if (batadv_mcast_mesh_info_put(msg
, bat_priv
))
259 goto nla_put_failure
;
261 primary_if
= batadv_primary_if_get_selected(bat_priv
);
262 if (primary_if
&& primary_if
->if_status
== BATADV_IF_ACTIVE
) {
263 hard_iface
= primary_if
->net_dev
;
265 if (nla_put_u32(msg
, BATADV_ATTR_HARD_IFINDEX
,
266 hard_iface
->ifindex
) ||
267 nla_put_string(msg
, BATADV_ATTR_HARD_IFNAME
,
269 nla_put(msg
, BATADV_ATTR_HARD_ADDRESS
, ETH_ALEN
,
270 hard_iface
->dev_addr
))
271 goto nla_put_failure
;
274 if (nla_put_u8(msg
, BATADV_ATTR_AGGREGATED_OGMS_ENABLED
,
275 !!atomic_read(&bat_priv
->aggregated_ogms
)))
276 goto nla_put_failure
;
278 if (batadv_netlink_mesh_fill_ap_isolation(msg
, bat_priv
))
279 goto nla_put_failure
;
281 if (nla_put_u32(msg
, BATADV_ATTR_ISOLATION_MARK
,
282 bat_priv
->isolation_mark
))
283 goto nla_put_failure
;
285 if (nla_put_u32(msg
, BATADV_ATTR_ISOLATION_MASK
,
286 bat_priv
->isolation_mark_mask
))
287 goto nla_put_failure
;
289 if (nla_put_u8(msg
, BATADV_ATTR_BONDING_ENABLED
,
290 !!atomic_read(&bat_priv
->bonding
)))
291 goto nla_put_failure
;
293 #ifdef CONFIG_BATMAN_ADV_BLA
294 if (nla_put_u8(msg
, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED
,
295 !!atomic_read(&bat_priv
->bridge_loop_avoidance
)))
296 goto nla_put_failure
;
297 #endif /* CONFIG_BATMAN_ADV_BLA */
299 #ifdef CONFIG_BATMAN_ADV_DAT
300 if (nla_put_u8(msg
, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED
,
301 !!atomic_read(&bat_priv
->distributed_arp_table
)))
302 goto nla_put_failure
;
303 #endif /* CONFIG_BATMAN_ADV_DAT */
305 if (nla_put_u8(msg
, BATADV_ATTR_FRAGMENTATION_ENABLED
,
306 !!atomic_read(&bat_priv
->fragmentation
)))
307 goto nla_put_failure
;
309 if (nla_put_u32(msg
, BATADV_ATTR_GW_BANDWIDTH_DOWN
,
310 atomic_read(&bat_priv
->gw
.bandwidth_down
)))
311 goto nla_put_failure
;
313 if (nla_put_u32(msg
, BATADV_ATTR_GW_BANDWIDTH_UP
,
314 atomic_read(&bat_priv
->gw
.bandwidth_up
)))
315 goto nla_put_failure
;
317 if (nla_put_u8(msg
, BATADV_ATTR_GW_MODE
,
318 atomic_read(&bat_priv
->gw
.mode
)))
319 goto nla_put_failure
;
321 if (bat_priv
->algo_ops
->gw
.get_best_gw_node
&&
322 bat_priv
->algo_ops
->gw
.is_eligible
) {
323 /* GW selection class is not available if the routing algorithm
324 * in use does not implement the GW API
326 if (nla_put_u32(msg
, BATADV_ATTR_GW_SEL_CLASS
,
327 atomic_read(&bat_priv
->gw
.sel_class
)))
328 goto nla_put_failure
;
331 if (nla_put_u8(msg
, BATADV_ATTR_HOP_PENALTY
,
332 atomic_read(&bat_priv
->hop_penalty
)))
333 goto nla_put_failure
;
335 #ifdef CONFIG_BATMAN_ADV_DEBUG
336 if (nla_put_u32(msg
, BATADV_ATTR_LOG_LEVEL
,
337 atomic_read(&bat_priv
->log_level
)))
338 goto nla_put_failure
;
339 #endif /* CONFIG_BATMAN_ADV_DEBUG */
341 #ifdef CONFIG_BATMAN_ADV_MCAST
342 if (nla_put_u8(msg
, BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED
,
343 !atomic_read(&bat_priv
->multicast_mode
)))
344 goto nla_put_failure
;
346 if (nla_put_u32(msg
, BATADV_ATTR_MULTICAST_FANOUT
,
347 atomic_read(&bat_priv
->multicast_fanout
)))
348 goto nla_put_failure
;
349 #endif /* CONFIG_BATMAN_ADV_MCAST */
351 #ifdef CONFIG_BATMAN_ADV_NC
352 if (nla_put_u8(msg
, BATADV_ATTR_NETWORK_CODING_ENABLED
,
353 !!atomic_read(&bat_priv
->network_coding
)))
354 goto nla_put_failure
;
355 #endif /* CONFIG_BATMAN_ADV_NC */
357 if (nla_put_u32(msg
, BATADV_ATTR_ORIG_INTERVAL
,
358 atomic_read(&bat_priv
->orig_interval
)))
359 goto nla_put_failure
;
362 batadv_hardif_put(primary_if
);
364 genlmsg_end(msg
, hdr
);
369 batadv_hardif_put(primary_if
);
371 genlmsg_cancel(msg
, hdr
);
376 * batadv_netlink_notify_mesh() - send softif attributes to listener
377 * @bat_priv: the bat priv with all the soft interface information
379 * Return: 0 on success, < 0 on error
381 int batadv_netlink_notify_mesh(struct batadv_priv
*bat_priv
)
386 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
390 ret
= batadv_netlink_mesh_fill(msg
, bat_priv
, BATADV_CMD_SET_MESH
,
397 genlmsg_multicast_netns(&batadv_netlink_family
,
398 dev_net(bat_priv
->soft_iface
), msg
, 0,
399 BATADV_NL_MCGRP_CONFIG
, GFP_KERNEL
);
405 * batadv_netlink_get_mesh() - Get softif attributes
406 * @skb: Netlink message with request data
407 * @info: receiver information
409 * Return: 0 on success or negative error number in case of failure
411 static int batadv_netlink_get_mesh(struct sk_buff
*skb
, struct genl_info
*info
)
413 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
417 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
421 ret
= batadv_netlink_mesh_fill(msg
, bat_priv
, BATADV_CMD_GET_MESH
,
422 info
->snd_portid
, info
->snd_seq
, 0);
428 ret
= genlmsg_reply(msg
, info
);
434 * batadv_netlink_set_mesh() - Set softif attributes
435 * @skb: Netlink message with request data
436 * @info: receiver information
438 * Return: 0 on success or negative error number in case of failure
440 static int batadv_netlink_set_mesh(struct sk_buff
*skb
, struct genl_info
*info
)
442 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
445 if (info
->attrs
[BATADV_ATTR_AGGREGATED_OGMS_ENABLED
]) {
446 attr
= info
->attrs
[BATADV_ATTR_AGGREGATED_OGMS_ENABLED
];
448 atomic_set(&bat_priv
->aggregated_ogms
, !!nla_get_u8(attr
));
451 if (info
->attrs
[BATADV_ATTR_AP_ISOLATION_ENABLED
]) {
452 attr
= info
->attrs
[BATADV_ATTR_AP_ISOLATION_ENABLED
];
454 batadv_netlink_set_mesh_ap_isolation(attr
, bat_priv
);
457 if (info
->attrs
[BATADV_ATTR_ISOLATION_MARK
]) {
458 attr
= info
->attrs
[BATADV_ATTR_ISOLATION_MARK
];
460 bat_priv
->isolation_mark
= nla_get_u32(attr
);
463 if (info
->attrs
[BATADV_ATTR_ISOLATION_MASK
]) {
464 attr
= info
->attrs
[BATADV_ATTR_ISOLATION_MASK
];
466 bat_priv
->isolation_mark_mask
= nla_get_u32(attr
);
469 if (info
->attrs
[BATADV_ATTR_BONDING_ENABLED
]) {
470 attr
= info
->attrs
[BATADV_ATTR_BONDING_ENABLED
];
472 atomic_set(&bat_priv
->bonding
, !!nla_get_u8(attr
));
475 #ifdef CONFIG_BATMAN_ADV_BLA
476 if (info
->attrs
[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED
]) {
477 attr
= info
->attrs
[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED
];
479 atomic_set(&bat_priv
->bridge_loop_avoidance
,
481 batadv_bla_status_update(bat_priv
->soft_iface
);
483 #endif /* CONFIG_BATMAN_ADV_BLA */
485 #ifdef CONFIG_BATMAN_ADV_DAT
486 if (info
->attrs
[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED
]) {
487 attr
= info
->attrs
[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED
];
489 atomic_set(&bat_priv
->distributed_arp_table
,
491 batadv_dat_status_update(bat_priv
->soft_iface
);
493 #endif /* CONFIG_BATMAN_ADV_DAT */
495 if (info
->attrs
[BATADV_ATTR_FRAGMENTATION_ENABLED
]) {
496 attr
= info
->attrs
[BATADV_ATTR_FRAGMENTATION_ENABLED
];
498 atomic_set(&bat_priv
->fragmentation
, !!nla_get_u8(attr
));
499 batadv_update_min_mtu(bat_priv
->soft_iface
);
502 if (info
->attrs
[BATADV_ATTR_GW_BANDWIDTH_DOWN
]) {
503 attr
= info
->attrs
[BATADV_ATTR_GW_BANDWIDTH_DOWN
];
505 atomic_set(&bat_priv
->gw
.bandwidth_down
, nla_get_u32(attr
));
506 batadv_gw_tvlv_container_update(bat_priv
);
509 if (info
->attrs
[BATADV_ATTR_GW_BANDWIDTH_UP
]) {
510 attr
= info
->attrs
[BATADV_ATTR_GW_BANDWIDTH_UP
];
512 atomic_set(&bat_priv
->gw
.bandwidth_up
, nla_get_u32(attr
));
513 batadv_gw_tvlv_container_update(bat_priv
);
516 if (info
->attrs
[BATADV_ATTR_GW_MODE
]) {
519 attr
= info
->attrs
[BATADV_ATTR_GW_MODE
];
520 gw_mode
= nla_get_u8(attr
);
522 if (gw_mode
<= BATADV_GW_MODE_SERVER
) {
523 /* Invoking batadv_gw_reselect() is not enough to really
524 * de-select the current GW. It will only instruct the
525 * gateway client code to perform a re-election the next
526 * time that this is needed.
528 * When gw client mode is being switched off the current
529 * GW must be de-selected explicitly otherwise no GW_ADD
530 * uevent is thrown on client mode re-activation. This
531 * is operation is performed in
532 * batadv_gw_check_client_stop().
534 batadv_gw_reselect(bat_priv
);
536 /* always call batadv_gw_check_client_stop() before
537 * changing the gateway state
539 batadv_gw_check_client_stop(bat_priv
);
540 atomic_set(&bat_priv
->gw
.mode
, gw_mode
);
541 batadv_gw_tvlv_container_update(bat_priv
);
545 if (info
->attrs
[BATADV_ATTR_GW_SEL_CLASS
] &&
546 bat_priv
->algo_ops
->gw
.get_best_gw_node
&&
547 bat_priv
->algo_ops
->gw
.is_eligible
) {
548 /* setting the GW selection class is allowed only if the routing
549 * algorithm in use implements the GW API
552 u32 sel_class_max
= 0xffffffffu
;
555 attr
= info
->attrs
[BATADV_ATTR_GW_SEL_CLASS
];
556 sel_class
= nla_get_u32(attr
);
558 if (!bat_priv
->algo_ops
->gw
.store_sel_class
)
559 sel_class_max
= BATADV_TQ_MAX_VALUE
;
561 if (sel_class
>= 1 && sel_class
<= sel_class_max
) {
562 atomic_set(&bat_priv
->gw
.sel_class
, sel_class
);
563 batadv_gw_reselect(bat_priv
);
567 if (info
->attrs
[BATADV_ATTR_HOP_PENALTY
]) {
568 attr
= info
->attrs
[BATADV_ATTR_HOP_PENALTY
];
570 atomic_set(&bat_priv
->hop_penalty
, nla_get_u8(attr
));
573 #ifdef CONFIG_BATMAN_ADV_DEBUG
574 if (info
->attrs
[BATADV_ATTR_LOG_LEVEL
]) {
575 attr
= info
->attrs
[BATADV_ATTR_LOG_LEVEL
];
577 atomic_set(&bat_priv
->log_level
,
578 nla_get_u32(attr
) & BATADV_DBG_ALL
);
580 #endif /* CONFIG_BATMAN_ADV_DEBUG */
582 #ifdef CONFIG_BATMAN_ADV_MCAST
583 if (info
->attrs
[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED
]) {
584 attr
= info
->attrs
[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED
];
586 atomic_set(&bat_priv
->multicast_mode
, !nla_get_u8(attr
));
589 if (info
->attrs
[BATADV_ATTR_MULTICAST_FANOUT
]) {
590 attr
= info
->attrs
[BATADV_ATTR_MULTICAST_FANOUT
];
592 atomic_set(&bat_priv
->multicast_fanout
, nla_get_u32(attr
));
594 #endif /* CONFIG_BATMAN_ADV_MCAST */
596 #ifdef CONFIG_BATMAN_ADV_NC
597 if (info
->attrs
[BATADV_ATTR_NETWORK_CODING_ENABLED
]) {
598 attr
= info
->attrs
[BATADV_ATTR_NETWORK_CODING_ENABLED
];
600 atomic_set(&bat_priv
->network_coding
, !!nla_get_u8(attr
));
601 batadv_nc_status_update(bat_priv
->soft_iface
);
603 #endif /* CONFIG_BATMAN_ADV_NC */
605 if (info
->attrs
[BATADV_ATTR_ORIG_INTERVAL
]) {
608 attr
= info
->attrs
[BATADV_ATTR_ORIG_INTERVAL
];
609 orig_interval
= nla_get_u32(attr
);
611 orig_interval
= min_t(u32
, orig_interval
, INT_MAX
);
612 orig_interval
= max_t(u32
, orig_interval
, 2 * BATADV_JITTER
);
614 atomic_set(&bat_priv
->orig_interval
, orig_interval
);
617 batadv_netlink_notify_mesh(bat_priv
);
623 * batadv_netlink_tp_meter_put() - Fill information of started tp_meter session
624 * @msg: netlink message to be sent back
625 * @cookie: tp meter session cookie
627 * Return: 0 on success, < 0 on error
630 batadv_netlink_tp_meter_put(struct sk_buff
*msg
, u32 cookie
)
632 if (nla_put_u32(msg
, BATADV_ATTR_TPMETER_COOKIE
, cookie
))
639 * batadv_netlink_tpmeter_notify() - send tp_meter result via netlink to client
640 * @bat_priv: the bat priv with all the soft interface information
641 * @dst: destination of tp_meter session
642 * @result: reason for tp meter session stop
643 * @test_time: total time ot the tp_meter session
644 * @total_bytes: bytes acked to the receiver
645 * @cookie: cookie of tp_meter session
647 * Return: 0 on success, < 0 on error
649 int batadv_netlink_tpmeter_notify(struct batadv_priv
*bat_priv
, const u8
*dst
,
650 u8 result
, u32 test_time
, u64 total_bytes
,
657 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
661 hdr
= genlmsg_put(msg
, 0, 0, &batadv_netlink_family
, 0,
662 BATADV_CMD_TP_METER
);
668 if (nla_put_u32(msg
, BATADV_ATTR_TPMETER_COOKIE
, cookie
))
669 goto nla_put_failure
;
671 if (nla_put_u32(msg
, BATADV_ATTR_TPMETER_TEST_TIME
, test_time
))
672 goto nla_put_failure
;
674 if (nla_put_u64_64bit(msg
, BATADV_ATTR_TPMETER_BYTES
, total_bytes
,
676 goto nla_put_failure
;
678 if (nla_put_u8(msg
, BATADV_ATTR_TPMETER_RESULT
, result
))
679 goto nla_put_failure
;
681 if (nla_put(msg
, BATADV_ATTR_ORIG_ADDRESS
, ETH_ALEN
, dst
))
682 goto nla_put_failure
;
684 genlmsg_end(msg
, hdr
);
686 genlmsg_multicast_netns(&batadv_netlink_family
,
687 dev_net(bat_priv
->soft_iface
), msg
, 0,
688 BATADV_NL_MCGRP_TPMETER
, GFP_KERNEL
);
693 genlmsg_cancel(msg
, hdr
);
702 * batadv_netlink_tp_meter_start() - Start a new tp_meter session
703 * @skb: received netlink message
704 * @info: receiver information
706 * Return: 0 on success, < 0 on error
709 batadv_netlink_tp_meter_start(struct sk_buff
*skb
, struct genl_info
*info
)
711 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
712 struct sk_buff
*msg
= NULL
;
719 if (!info
->attrs
[BATADV_ATTR_ORIG_ADDRESS
])
722 if (!info
->attrs
[BATADV_ATTR_TPMETER_TEST_TIME
])
725 dst
= nla_data(info
->attrs
[BATADV_ATTR_ORIG_ADDRESS
]);
727 test_length
= nla_get_u32(info
->attrs
[BATADV_ATTR_TPMETER_TEST_TIME
]);
729 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
735 msg_head
= genlmsg_put(msg
, info
->snd_portid
, info
->snd_seq
,
736 &batadv_netlink_family
, 0,
737 BATADV_CMD_TP_METER
);
743 batadv_tp_start(bat_priv
, dst
, test_length
, &cookie
);
745 ret
= batadv_netlink_tp_meter_put(msg
, cookie
);
754 genlmsg_end(msg
, msg_head
);
755 return genlmsg_reply(msg
, info
);
759 * batadv_netlink_tp_meter_start() - Cancel a running tp_meter session
760 * @skb: received netlink message
761 * @info: receiver information
763 * Return: 0 on success, < 0 on error
766 batadv_netlink_tp_meter_cancel(struct sk_buff
*skb
, struct genl_info
*info
)
768 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
772 if (!info
->attrs
[BATADV_ATTR_ORIG_ADDRESS
])
775 dst
= nla_data(info
->attrs
[BATADV_ATTR_ORIG_ADDRESS
]);
777 batadv_tp_stop(bat_priv
, dst
, BATADV_TP_REASON_CANCEL
);
783 * batadv_netlink_hardif_fill() - Fill message with hardif attributes
784 * @msg: Netlink message to dump into
785 * @bat_priv: the bat priv with all the soft interface information
786 * @hard_iface: hard interface which was modified
787 * @cmd: type of message to generate
788 * @portid: Port making netlink request
789 * @seq: sequence number for message
790 * @flags: Additional flags for message
791 * @cb: Control block containing additional options
793 * Return: 0 on success or negative error number in case of failure
795 static int batadv_netlink_hardif_fill(struct sk_buff
*msg
,
796 struct batadv_priv
*bat_priv
,
797 struct batadv_hard_iface
*hard_iface
,
798 enum batadv_nl_commands cmd
,
799 u32 portid
, u32 seq
, int flags
,
800 struct netlink_callback
*cb
)
802 struct net_device
*net_dev
= hard_iface
->net_dev
;
805 hdr
= genlmsg_put(msg
, portid
, seq
, &batadv_netlink_family
, flags
, cmd
);
810 genl_dump_check_consistent(cb
, hdr
);
812 if (nla_put_u32(msg
, BATADV_ATTR_MESH_IFINDEX
,
813 bat_priv
->soft_iface
->ifindex
))
814 goto nla_put_failure
;
816 if (nla_put_u32(msg
, BATADV_ATTR_HARD_IFINDEX
,
818 nla_put_string(msg
, BATADV_ATTR_HARD_IFNAME
,
820 nla_put(msg
, BATADV_ATTR_HARD_ADDRESS
, ETH_ALEN
,
822 goto nla_put_failure
;
824 if (hard_iface
->if_status
== BATADV_IF_ACTIVE
) {
825 if (nla_put_flag(msg
, BATADV_ATTR_ACTIVE
))
826 goto nla_put_failure
;
829 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
830 if (nla_put_u32(msg
, BATADV_ATTR_ELP_INTERVAL
,
831 atomic_read(&hard_iface
->bat_v
.elp_interval
)))
832 goto nla_put_failure
;
834 if (nla_put_u32(msg
, BATADV_ATTR_THROUGHPUT_OVERRIDE
,
835 atomic_read(&hard_iface
->bat_v
.throughput_override
)))
836 goto nla_put_failure
;
837 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */
839 genlmsg_end(msg
, hdr
);
843 genlmsg_cancel(msg
, hdr
);
848 * batadv_netlink_notify_hardif() - send hardif attributes to listener
849 * @bat_priv: the bat priv with all the soft interface information
850 * @hard_iface: hard interface which was modified
852 * Return: 0 on success, < 0 on error
854 int batadv_netlink_notify_hardif(struct batadv_priv
*bat_priv
,
855 struct batadv_hard_iface
*hard_iface
)
860 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
864 ret
= batadv_netlink_hardif_fill(msg
, bat_priv
, hard_iface
,
865 BATADV_CMD_SET_HARDIF
, 0, 0, 0, NULL
);
871 genlmsg_multicast_netns(&batadv_netlink_family
,
872 dev_net(bat_priv
->soft_iface
), msg
, 0,
873 BATADV_NL_MCGRP_CONFIG
, GFP_KERNEL
);
879 * batadv_netlink_get_hardif() - Get hardif attributes
880 * @skb: Netlink message with request data
881 * @info: receiver information
883 * Return: 0 on success or negative error number in case of failure
885 static int batadv_netlink_get_hardif(struct sk_buff
*skb
,
886 struct genl_info
*info
)
888 struct batadv_hard_iface
*hard_iface
= info
->user_ptr
[1];
889 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
893 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
897 ret
= batadv_netlink_hardif_fill(msg
, bat_priv
, hard_iface
,
898 BATADV_CMD_GET_HARDIF
,
899 info
->snd_portid
, info
->snd_seq
, 0,
906 ret
= genlmsg_reply(msg
, info
);
912 * batadv_netlink_set_hardif() - Set hardif attributes
913 * @skb: Netlink message with request data
914 * @info: receiver information
916 * Return: 0 on success or negative error number in case of failure
918 static int batadv_netlink_set_hardif(struct sk_buff
*skb
,
919 struct genl_info
*info
)
921 struct batadv_hard_iface
*hard_iface
= info
->user_ptr
[1];
922 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
924 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
927 if (info
->attrs
[BATADV_ATTR_ELP_INTERVAL
]) {
928 attr
= info
->attrs
[BATADV_ATTR_ELP_INTERVAL
];
930 atomic_set(&hard_iface
->bat_v
.elp_interval
, nla_get_u32(attr
));
933 if (info
->attrs
[BATADV_ATTR_THROUGHPUT_OVERRIDE
]) {
934 attr
= info
->attrs
[BATADV_ATTR_THROUGHPUT_OVERRIDE
];
936 atomic_set(&hard_iface
->bat_v
.throughput_override
,
939 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */
941 batadv_netlink_notify_hardif(bat_priv
, hard_iface
);
947 * batadv_netlink_dump_hardif() - Dump all hard interface into a messages
948 * @msg: Netlink message to dump into
949 * @cb: Parameters from query
951 * Return: error code, or length of reply message on success
954 batadv_netlink_dump_hardif(struct sk_buff
*msg
, struct netlink_callback
*cb
)
956 struct net
*net
= sock_net(cb
->skb
->sk
);
957 struct net_device
*soft_iface
;
958 struct batadv_hard_iface
*hard_iface
;
959 struct batadv_priv
*bat_priv
;
961 int portid
= NETLINK_CB(cb
->skb
).portid
;
962 int skip
= cb
->args
[0];
965 ifindex
= batadv_netlink_get_ifindex(cb
->nlh
,
966 BATADV_ATTR_MESH_IFINDEX
);
970 soft_iface
= dev_get_by_index(net
, ifindex
);
974 if (!batadv_softif_is_valid(soft_iface
)) {
979 bat_priv
= netdev_priv(soft_iface
);
982 cb
->seq
= batadv_hardif_generation
<< 1 | 1;
984 list_for_each_entry(hard_iface
, &batadv_hardif_list
, list
) {
985 if (hard_iface
->soft_iface
!= soft_iface
)
991 if (batadv_netlink_hardif_fill(msg
, bat_priv
, hard_iface
,
992 BATADV_CMD_GET_HARDIF
,
993 portid
, cb
->nlh
->nlmsg_seq
,
1002 dev_put(soft_iface
);
1010 * batadv_netlink_vlan_fill() - Fill message with vlan attributes
1011 * @msg: Netlink message to dump into
1012 * @bat_priv: the bat priv with all the soft interface information
1013 * @vlan: vlan which was modified
1014 * @cmd: type of message to generate
1015 * @portid: Port making netlink request
1016 * @seq: sequence number for message
1017 * @flags: Additional flags for message
1019 * Return: 0 on success or negative error number in case of failure
1021 static int batadv_netlink_vlan_fill(struct sk_buff
*msg
,
1022 struct batadv_priv
*bat_priv
,
1023 struct batadv_softif_vlan
*vlan
,
1024 enum batadv_nl_commands cmd
,
1025 u32 portid
, u32 seq
, int flags
)
1029 hdr
= genlmsg_put(msg
, portid
, seq
, &batadv_netlink_family
, flags
, cmd
);
1033 if (nla_put_u32(msg
, BATADV_ATTR_MESH_IFINDEX
,
1034 bat_priv
->soft_iface
->ifindex
))
1035 goto nla_put_failure
;
1037 if (nla_put_u32(msg
, BATADV_ATTR_VLANID
, vlan
->vid
& VLAN_VID_MASK
))
1038 goto nla_put_failure
;
1040 if (nla_put_u8(msg
, BATADV_ATTR_AP_ISOLATION_ENABLED
,
1041 !!atomic_read(&vlan
->ap_isolation
)))
1042 goto nla_put_failure
;
1044 genlmsg_end(msg
, hdr
);
1048 genlmsg_cancel(msg
, hdr
);
1053 * batadv_netlink_notify_vlan() - send vlan attributes to listener
1054 * @bat_priv: the bat priv with all the soft interface information
1055 * @vlan: vlan which was modified
1057 * Return: 0 on success, < 0 on error
1059 int batadv_netlink_notify_vlan(struct batadv_priv
*bat_priv
,
1060 struct batadv_softif_vlan
*vlan
)
1062 struct sk_buff
*msg
;
1065 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1069 ret
= batadv_netlink_vlan_fill(msg
, bat_priv
, vlan
,
1070 BATADV_CMD_SET_VLAN
, 0, 0, 0);
1076 genlmsg_multicast_netns(&batadv_netlink_family
,
1077 dev_net(bat_priv
->soft_iface
), msg
, 0,
1078 BATADV_NL_MCGRP_CONFIG
, GFP_KERNEL
);
1084 * batadv_netlink_get_vlan() - Get vlan attributes
1085 * @skb: Netlink message with request data
1086 * @info: receiver information
1088 * Return: 0 on success or negative error number in case of failure
1090 static int batadv_netlink_get_vlan(struct sk_buff
*skb
, struct genl_info
*info
)
1092 struct batadv_softif_vlan
*vlan
= info
->user_ptr
[1];
1093 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
1094 struct sk_buff
*msg
;
1097 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1101 ret
= batadv_netlink_vlan_fill(msg
, bat_priv
, vlan
, BATADV_CMD_GET_VLAN
,
1102 info
->snd_portid
, info
->snd_seq
, 0);
1108 ret
= genlmsg_reply(msg
, info
);
1114 * batadv_netlink_set_vlan() - Get vlan attributes
1115 * @skb: Netlink message with request data
1116 * @info: receiver information
1118 * Return: 0 on success or negative error number in case of failure
1120 static int batadv_netlink_set_vlan(struct sk_buff
*skb
, struct genl_info
*info
)
1122 struct batadv_softif_vlan
*vlan
= info
->user_ptr
[1];
1123 struct batadv_priv
*bat_priv
= info
->user_ptr
[0];
1124 struct nlattr
*attr
;
1126 if (info
->attrs
[BATADV_ATTR_AP_ISOLATION_ENABLED
]) {
1127 attr
= info
->attrs
[BATADV_ATTR_AP_ISOLATION_ENABLED
];
1129 atomic_set(&vlan
->ap_isolation
, !!nla_get_u8(attr
));
1132 batadv_netlink_notify_vlan(bat_priv
, vlan
);
1138 * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes
1139 * @net: the applicable net namespace
1140 * @info: receiver information
1142 * Return: Pointer to soft interface (with increased refcnt) on success, error
1145 static struct net_device
*
1146 batadv_get_softif_from_info(struct net
*net
, struct genl_info
*info
)
1148 struct net_device
*soft_iface
;
1151 if (!info
->attrs
[BATADV_ATTR_MESH_IFINDEX
])
1152 return ERR_PTR(-EINVAL
);
1154 ifindex
= nla_get_u32(info
->attrs
[BATADV_ATTR_MESH_IFINDEX
]);
1156 soft_iface
= dev_get_by_index(net
, ifindex
);
1158 return ERR_PTR(-ENODEV
);
1160 if (!batadv_softif_is_valid(soft_iface
))
1161 goto err_put_softif
;
1166 dev_put(soft_iface
);
1168 return ERR_PTR(-EINVAL
);
1172 * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes
1173 * @bat_priv: the bat priv with all the soft interface information
1174 * @net: the applicable net namespace
1175 * @info: receiver information
1177 * Return: Pointer to hard interface (with increased refcnt) on success, error
1180 static struct batadv_hard_iface
*
1181 batadv_get_hardif_from_info(struct batadv_priv
*bat_priv
, struct net
*net
,
1182 struct genl_info
*info
)
1184 struct batadv_hard_iface
*hard_iface
;
1185 struct net_device
*hard_dev
;
1186 unsigned int hardif_index
;
1188 if (!info
->attrs
[BATADV_ATTR_HARD_IFINDEX
])
1189 return ERR_PTR(-EINVAL
);
1191 hardif_index
= nla_get_u32(info
->attrs
[BATADV_ATTR_HARD_IFINDEX
]);
1193 hard_dev
= dev_get_by_index(net
, hardif_index
);
1195 return ERR_PTR(-ENODEV
);
1197 hard_iface
= batadv_hardif_get_by_netdev(hard_dev
);
1199 goto err_put_harddev
;
1201 if (hard_iface
->soft_iface
!= bat_priv
->soft_iface
)
1202 goto err_put_hardif
;
1204 /* hard_dev is referenced by hard_iface and not needed here */
1210 batadv_hardif_put(hard_iface
);
1214 return ERR_PTR(-EINVAL
);
1218 * batadv_get_vlan_from_info() - Retrieve vlan from genl attributes
1219 * @bat_priv: the bat priv with all the soft interface information
1220 * @net: the applicable net namespace
1221 * @info: receiver information
1223 * Return: Pointer to vlan on success (with increased refcnt), error pointer
1226 static struct batadv_softif_vlan
*
1227 batadv_get_vlan_from_info(struct batadv_priv
*bat_priv
, struct net
*net
,
1228 struct genl_info
*info
)
1230 struct batadv_softif_vlan
*vlan
;
1233 if (!info
->attrs
[BATADV_ATTR_VLANID
])
1234 return ERR_PTR(-EINVAL
);
1236 vid
= nla_get_u16(info
->attrs
[BATADV_ATTR_VLANID
]);
1238 vlan
= batadv_softif_vlan_get(bat_priv
, vid
| BATADV_VLAN_HAS_TAG
);
1240 return ERR_PTR(-ENOENT
);
1246 * batadv_pre_doit() - Prepare batman-adv genl doit request
1247 * @ops: requested netlink operation
1248 * @skb: Netlink message with request data
1249 * @info: receiver information
1251 * Return: 0 on success or negative error number in case of failure
1253 static int batadv_pre_doit(const struct genl_ops
*ops
, struct sk_buff
*skb
,
1254 struct genl_info
*info
)
1256 struct net
*net
= genl_info_net(info
);
1257 struct batadv_hard_iface
*hard_iface
;
1258 struct batadv_priv
*bat_priv
= NULL
;
1259 struct batadv_softif_vlan
*vlan
;
1260 struct net_device
*soft_iface
;
1265 user_ptr1_flags
= BATADV_FLAG_NEED_HARDIF
| BATADV_FLAG_NEED_VLAN
;
1266 if (WARN_ON(hweight8(ops
->internal_flags
& user_ptr1_flags
) > 1))
1269 mesh_dep_flags
= BATADV_FLAG_NEED_HARDIF
| BATADV_FLAG_NEED_VLAN
;
1270 if (WARN_ON((ops
->internal_flags
& mesh_dep_flags
) &&
1271 (~ops
->internal_flags
& BATADV_FLAG_NEED_MESH
)))
1274 if (ops
->internal_flags
& BATADV_FLAG_NEED_MESH
) {
1275 soft_iface
= batadv_get_softif_from_info(net
, info
);
1276 if (IS_ERR(soft_iface
))
1277 return PTR_ERR(soft_iface
);
1279 bat_priv
= netdev_priv(soft_iface
);
1280 info
->user_ptr
[0] = bat_priv
;
1283 if (ops
->internal_flags
& BATADV_FLAG_NEED_HARDIF
) {
1284 hard_iface
= batadv_get_hardif_from_info(bat_priv
, net
, info
);
1285 if (IS_ERR(hard_iface
)) {
1286 ret
= PTR_ERR(hard_iface
);
1287 goto err_put_softif
;
1290 info
->user_ptr
[1] = hard_iface
;
1293 if (ops
->internal_flags
& BATADV_FLAG_NEED_VLAN
) {
1294 vlan
= batadv_get_vlan_from_info(bat_priv
, net
, info
);
1296 ret
= PTR_ERR(vlan
);
1297 goto err_put_softif
;
1300 info
->user_ptr
[1] = vlan
;
1307 dev_put(bat_priv
->soft_iface
);
1313 * batadv_post_doit() - End batman-adv genl doit request
1314 * @ops: requested netlink operation
1315 * @skb: Netlink message with request data
1316 * @info: receiver information
1318 static void batadv_post_doit(const struct genl_ops
*ops
, struct sk_buff
*skb
,
1319 struct genl_info
*info
)
1321 struct batadv_hard_iface
*hard_iface
;
1322 struct batadv_softif_vlan
*vlan
;
1323 struct batadv_priv
*bat_priv
;
1325 if (ops
->internal_flags
& BATADV_FLAG_NEED_HARDIF
&&
1326 info
->user_ptr
[1]) {
1327 hard_iface
= info
->user_ptr
[1];
1329 batadv_hardif_put(hard_iface
);
1332 if (ops
->internal_flags
& BATADV_FLAG_NEED_VLAN
&& info
->user_ptr
[1]) {
1333 vlan
= info
->user_ptr
[1];
1334 batadv_softif_vlan_put(vlan
);
1337 if (ops
->internal_flags
& BATADV_FLAG_NEED_MESH
&& info
->user_ptr
[0]) {
1338 bat_priv
= info
->user_ptr
[0];
1339 dev_put(bat_priv
->soft_iface
);
1343 static const struct genl_ops batadv_netlink_ops
[] = {
1345 .cmd
= BATADV_CMD_GET_MESH
,
1346 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1347 /* can be retrieved by unprivileged users */
1348 .doit
= batadv_netlink_get_mesh
,
1349 .internal_flags
= BATADV_FLAG_NEED_MESH
,
1352 .cmd
= BATADV_CMD_TP_METER
,
1353 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1354 .flags
= GENL_ADMIN_PERM
,
1355 .doit
= batadv_netlink_tp_meter_start
,
1356 .internal_flags
= BATADV_FLAG_NEED_MESH
,
1359 .cmd
= BATADV_CMD_TP_METER_CANCEL
,
1360 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1361 .flags
= GENL_ADMIN_PERM
,
1362 .doit
= batadv_netlink_tp_meter_cancel
,
1363 .internal_flags
= BATADV_FLAG_NEED_MESH
,
1366 .cmd
= BATADV_CMD_GET_ROUTING_ALGOS
,
1367 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1368 .flags
= GENL_ADMIN_PERM
,
1369 .dumpit
= batadv_algo_dump
,
1372 .cmd
= BATADV_CMD_GET_HARDIF
,
1373 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1374 /* can be retrieved by unprivileged users */
1375 .dumpit
= batadv_netlink_dump_hardif
,
1376 .doit
= batadv_netlink_get_hardif
,
1377 .internal_flags
= BATADV_FLAG_NEED_MESH
|
1378 BATADV_FLAG_NEED_HARDIF
,
1381 .cmd
= BATADV_CMD_GET_TRANSTABLE_LOCAL
,
1382 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1383 .flags
= GENL_ADMIN_PERM
,
1384 .dumpit
= batadv_tt_local_dump
,
1387 .cmd
= BATADV_CMD_GET_TRANSTABLE_GLOBAL
,
1388 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1389 .flags
= GENL_ADMIN_PERM
,
1390 .dumpit
= batadv_tt_global_dump
,
1393 .cmd
= BATADV_CMD_GET_ORIGINATORS
,
1394 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1395 .flags
= GENL_ADMIN_PERM
,
1396 .dumpit
= batadv_orig_dump
,
1399 .cmd
= BATADV_CMD_GET_NEIGHBORS
,
1400 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1401 .flags
= GENL_ADMIN_PERM
,
1402 .dumpit
= batadv_hardif_neigh_dump
,
1405 .cmd
= BATADV_CMD_GET_GATEWAYS
,
1406 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1407 .flags
= GENL_ADMIN_PERM
,
1408 .dumpit
= batadv_gw_dump
,
1411 .cmd
= BATADV_CMD_GET_BLA_CLAIM
,
1412 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1413 .flags
= GENL_ADMIN_PERM
,
1414 .dumpit
= batadv_bla_claim_dump
,
1417 .cmd
= BATADV_CMD_GET_BLA_BACKBONE
,
1418 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1419 .flags
= GENL_ADMIN_PERM
,
1420 .dumpit
= batadv_bla_backbone_dump
,
1423 .cmd
= BATADV_CMD_GET_DAT_CACHE
,
1424 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1425 .flags
= GENL_ADMIN_PERM
,
1426 .dumpit
= batadv_dat_cache_dump
,
1429 .cmd
= BATADV_CMD_GET_MCAST_FLAGS
,
1430 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1431 .flags
= GENL_ADMIN_PERM
,
1432 .dumpit
= batadv_mcast_flags_dump
,
1435 .cmd
= BATADV_CMD_SET_MESH
,
1436 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1437 .flags
= GENL_ADMIN_PERM
,
1438 .doit
= batadv_netlink_set_mesh
,
1439 .internal_flags
= BATADV_FLAG_NEED_MESH
,
1442 .cmd
= BATADV_CMD_SET_HARDIF
,
1443 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1444 .flags
= GENL_ADMIN_PERM
,
1445 .doit
= batadv_netlink_set_hardif
,
1446 .internal_flags
= BATADV_FLAG_NEED_MESH
|
1447 BATADV_FLAG_NEED_HARDIF
,
1450 .cmd
= BATADV_CMD_GET_VLAN
,
1451 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1452 /* can be retrieved by unprivileged users */
1453 .doit
= batadv_netlink_get_vlan
,
1454 .internal_flags
= BATADV_FLAG_NEED_MESH
|
1455 BATADV_FLAG_NEED_VLAN
,
1458 .cmd
= BATADV_CMD_SET_VLAN
,
1459 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1460 .flags
= GENL_ADMIN_PERM
,
1461 .doit
= batadv_netlink_set_vlan
,
1462 .internal_flags
= BATADV_FLAG_NEED_MESH
|
1463 BATADV_FLAG_NEED_VLAN
,
1467 struct genl_family batadv_netlink_family __ro_after_init
= {
1469 .name
= BATADV_NL_NAME
,
1471 .maxattr
= BATADV_ATTR_MAX
,
1472 .policy
= batadv_netlink_policy
,
1474 .pre_doit
= batadv_pre_doit
,
1475 .post_doit
= batadv_post_doit
,
1476 .module
= THIS_MODULE
,
1477 .ops
= batadv_netlink_ops
,
1478 .n_ops
= ARRAY_SIZE(batadv_netlink_ops
),
1479 .mcgrps
= batadv_netlink_mcgrps
,
1480 .n_mcgrps
= ARRAY_SIZE(batadv_netlink_mcgrps
),
1484 * batadv_netlink_register() - register batadv genl netlink family
1486 void __init
batadv_netlink_register(void)
1490 ret
= genl_register_family(&batadv_netlink_family
);
1492 pr_warn("unable to register netlink family");
1496 * batadv_netlink_unregister() - unregister batadv genl netlink family
1498 void batadv_netlink_unregister(void)
1500 genl_unregister_family(&batadv_netlink_family
);