1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2016-2020 B.A.T.M.A.N. contributors: 3 * 4 * Matthias Schiffer 5 */ 6 7 #include "netlink.h" 8 #include "main.h" 9 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> 36 #include <net/sock.h> 37 #include <uapi/linux/batadv_packet.h> 38 #include <uapi/linux/batman_adv.h> 39 40 #include "bat_algo.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" 46 #include "log.h" 47 #include "multicast.h" 48 #include "network-coding.h" 49 #include "originator.h" 50 #include "soft-interface.h" 51 #include "tp_meter.h" 52 #include "translation-table.h" 53 54 struct genl_family batadv_netlink_family; 55 56 /* multicast groups */ 57 enum batadv_netlink_multicast_groups { 58 BATADV_NL_MCGRP_CONFIG, 59 BATADV_NL_MCGRP_TPMETER, 60 }; 61 62 /** 63 * enum batadv_genl_ops_flags - flags for genl_ops's internal_flags 64 */ 65 enum batadv_genl_ops_flags { 66 /** 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] 70 */ 71 BATADV_FLAG_NEED_MESH = BIT(0), 72 73 /** 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] 77 */ 78 BATADV_FLAG_NEED_HARDIF = BIT(1), 79 80 /** 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] 84 */ 85 BATADV_FLAG_NEED_VLAN = BIT(2), 86 }; 87 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 }, 91 }; 92 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 }, 153 }; 154 155 /** 156 * batadv_netlink_get_ifindex() - Extract an interface index from a message 157 * @nlh: Message header 158 * @attrtype: Attribute which holds an interface index 159 * 160 * Return: interface index, or 0. 161 */ 162 int 163 batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype) 164 { 165 struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype); 166 167 return (attr && nla_len(attr) == sizeof(u32)) ? nla_get_u32(attr) : 0; 168 } 169 170 /** 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 174 * 175 * Return: 0 on success or negative error number in case of failure 176 */ 177 static int batadv_netlink_mesh_fill_ap_isolation(struct sk_buff *msg, 178 struct batadv_priv *bat_priv) 179 { 180 struct batadv_softif_vlan *vlan; 181 u8 ap_isolation; 182 183 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); 184 if (!vlan) 185 return 0; 186 187 ap_isolation = atomic_read(&vlan->ap_isolation); 188 batadv_softif_vlan_put(vlan); 189 190 return nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, 191 !!ap_isolation); 192 } 193 194 /** 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 198 * 199 * Return: 0 on success or negative error number in case of failure 200 */ 201 static int batadv_netlink_set_mesh_ap_isolation(struct nlattr *attr, 202 struct batadv_priv *bat_priv) 203 { 204 struct batadv_softif_vlan *vlan; 205 206 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); 207 if (!vlan) 208 return -ENOENT; 209 210 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr)); 211 batadv_softif_vlan_put(vlan); 212 213 return 0; 214 } 215 216 /** 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 224 * 225 * Return: 0 on success or negative error number in case of failure 226 */ 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) 231 { 232 struct net_device *soft_iface = bat_priv->soft_iface; 233 struct batadv_hard_iface *primary_if = NULL; 234 struct net_device *hard_iface; 235 void *hdr; 236 237 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 238 if (!hdr) 239 return -ENOBUFS; 240 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; 251 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; 256 #endif 257 258 if (batadv_mcast_mesh_info_put(msg, bat_priv)) 259 goto nla_put_failure; 260 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; 264 265 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, 266 hard_iface->ifindex) || 267 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, 268 hard_iface->name) || 269 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN, 270 hard_iface->dev_addr)) 271 goto nla_put_failure; 272 } 273 274 if (nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS_ENABLED, 275 !!atomic_read(&bat_priv->aggregated_ogms))) 276 goto nla_put_failure; 277 278 if (batadv_netlink_mesh_fill_ap_isolation(msg, bat_priv)) 279 goto nla_put_failure; 280 281 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MARK, 282 bat_priv->isolation_mark)) 283 goto nla_put_failure; 284 285 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MASK, 286 bat_priv->isolation_mark_mask)) 287 goto nla_put_failure; 288 289 if (nla_put_u8(msg, BATADV_ATTR_BONDING_ENABLED, 290 !!atomic_read(&bat_priv->bonding))) 291 goto nla_put_failure; 292 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 */ 298 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 */ 304 305 if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION_ENABLED, 306 !!atomic_read(&bat_priv->fragmentation))) 307 goto nla_put_failure; 308 309 if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_DOWN, 310 atomic_read(&bat_priv->gw.bandwidth_down))) 311 goto nla_put_failure; 312 313 if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_UP, 314 atomic_read(&bat_priv->gw.bandwidth_up))) 315 goto nla_put_failure; 316 317 if (nla_put_u8(msg, BATADV_ATTR_GW_MODE, 318 atomic_read(&bat_priv->gw.mode))) 319 goto nla_put_failure; 320 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 325 */ 326 if (nla_put_u32(msg, BATADV_ATTR_GW_SEL_CLASS, 327 atomic_read(&bat_priv->gw.sel_class))) 328 goto nla_put_failure; 329 } 330 331 if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY, 332 atomic_read(&bat_priv->hop_penalty))) 333 goto nla_put_failure; 334 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 */ 340 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; 345 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 */ 350 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 */ 356 357 if (nla_put_u32(msg, BATADV_ATTR_ORIG_INTERVAL, 358 atomic_read(&bat_priv->orig_interval))) 359 goto nla_put_failure; 360 361 if (primary_if) 362 batadv_hardif_put(primary_if); 363 364 genlmsg_end(msg, hdr); 365 return 0; 366 367 nla_put_failure: 368 if (primary_if) 369 batadv_hardif_put(primary_if); 370 371 genlmsg_cancel(msg, hdr); 372 return -EMSGSIZE; 373 } 374 375 /** 376 * batadv_netlink_notify_mesh() - send softif attributes to listener 377 * @bat_priv: the bat priv with all the soft interface information 378 * 379 * Return: 0 on success, < 0 on error 380 */ 381 int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv) 382 { 383 struct sk_buff *msg; 384 int ret; 385 386 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 387 if (!msg) 388 return -ENOMEM; 389 390 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_SET_MESH, 391 0, 0, 0); 392 if (ret < 0) { 393 nlmsg_free(msg); 394 return ret; 395 } 396 397 genlmsg_multicast_netns(&batadv_netlink_family, 398 dev_net(bat_priv->soft_iface), msg, 0, 399 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 400 401 return 0; 402 } 403 404 /** 405 * batadv_netlink_get_mesh() - Get softif attributes 406 * @skb: Netlink message with request data 407 * @info: receiver information 408 * 409 * Return: 0 on success or negative error number in case of failure 410 */ 411 static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info) 412 { 413 struct batadv_priv *bat_priv = info->user_ptr[0]; 414 struct sk_buff *msg; 415 int ret; 416 417 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 418 if (!msg) 419 return -ENOMEM; 420 421 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_GET_MESH, 422 info->snd_portid, info->snd_seq, 0); 423 if (ret < 0) { 424 nlmsg_free(msg); 425 return ret; 426 } 427 428 ret = genlmsg_reply(msg, info); 429 430 return ret; 431 } 432 433 /** 434 * batadv_netlink_set_mesh() - Set softif attributes 435 * @skb: Netlink message with request data 436 * @info: receiver information 437 * 438 * Return: 0 on success or negative error number in case of failure 439 */ 440 static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info) 441 { 442 struct batadv_priv *bat_priv = info->user_ptr[0]; 443 struct nlattr *attr; 444 445 if (info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]) { 446 attr = info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]; 447 448 atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr)); 449 } 450 451 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) { 452 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]; 453 454 batadv_netlink_set_mesh_ap_isolation(attr, bat_priv); 455 } 456 457 if (info->attrs[BATADV_ATTR_ISOLATION_MARK]) { 458 attr = info->attrs[BATADV_ATTR_ISOLATION_MARK]; 459 460 bat_priv->isolation_mark = nla_get_u32(attr); 461 } 462 463 if (info->attrs[BATADV_ATTR_ISOLATION_MASK]) { 464 attr = info->attrs[BATADV_ATTR_ISOLATION_MASK]; 465 466 bat_priv->isolation_mark_mask = nla_get_u32(attr); 467 } 468 469 if (info->attrs[BATADV_ATTR_BONDING_ENABLED]) { 470 attr = info->attrs[BATADV_ATTR_BONDING_ENABLED]; 471 472 atomic_set(&bat_priv->bonding, !!nla_get_u8(attr)); 473 } 474 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]; 478 479 atomic_set(&bat_priv->bridge_loop_avoidance, 480 !!nla_get_u8(attr)); 481 batadv_bla_status_update(bat_priv->soft_iface); 482 } 483 #endif /* CONFIG_BATMAN_ADV_BLA */ 484 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]; 488 489 atomic_set(&bat_priv->distributed_arp_table, 490 !!nla_get_u8(attr)); 491 batadv_dat_status_update(bat_priv->soft_iface); 492 } 493 #endif /* CONFIG_BATMAN_ADV_DAT */ 494 495 if (info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]) { 496 attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]; 497 498 atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr)); 499 batadv_update_min_mtu(bat_priv->soft_iface); 500 } 501 502 if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) { 503 attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]; 504 505 atomic_set(&bat_priv->gw.bandwidth_down, nla_get_u32(attr)); 506 batadv_gw_tvlv_container_update(bat_priv); 507 } 508 509 if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]) { 510 attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]; 511 512 atomic_set(&bat_priv->gw.bandwidth_up, nla_get_u32(attr)); 513 batadv_gw_tvlv_container_update(bat_priv); 514 } 515 516 if (info->attrs[BATADV_ATTR_GW_MODE]) { 517 u8 gw_mode; 518 519 attr = info->attrs[BATADV_ATTR_GW_MODE]; 520 gw_mode = nla_get_u8(attr); 521 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. 527 * 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(). 533 */ 534 batadv_gw_reselect(bat_priv); 535 536 /* always call batadv_gw_check_client_stop() before 537 * changing the gateway state 538 */ 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); 542 } 543 } 544 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 550 */ 551 552 u32 sel_class_max = 0xffffffffu; 553 u32 sel_class; 554 555 attr = info->attrs[BATADV_ATTR_GW_SEL_CLASS]; 556 sel_class = nla_get_u32(attr); 557 558 if (!bat_priv->algo_ops->gw.store_sel_class) 559 sel_class_max = BATADV_TQ_MAX_VALUE; 560 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); 564 } 565 } 566 567 if (info->attrs[BATADV_ATTR_HOP_PENALTY]) { 568 attr = info->attrs[BATADV_ATTR_HOP_PENALTY]; 569 570 atomic_set(&bat_priv->hop_penalty, nla_get_u8(attr)); 571 } 572 573 #ifdef CONFIG_BATMAN_ADV_DEBUG 574 if (info->attrs[BATADV_ATTR_LOG_LEVEL]) { 575 attr = info->attrs[BATADV_ATTR_LOG_LEVEL]; 576 577 atomic_set(&bat_priv->log_level, 578 nla_get_u32(attr) & BATADV_DBG_ALL); 579 } 580 #endif /* CONFIG_BATMAN_ADV_DEBUG */ 581 582 #ifdef CONFIG_BATMAN_ADV_MCAST 583 if (info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]) { 584 attr = info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]; 585 586 atomic_set(&bat_priv->multicast_mode, !nla_get_u8(attr)); 587 } 588 589 if (info->attrs[BATADV_ATTR_MULTICAST_FANOUT]) { 590 attr = info->attrs[BATADV_ATTR_MULTICAST_FANOUT]; 591 592 atomic_set(&bat_priv->multicast_fanout, nla_get_u32(attr)); 593 } 594 #endif /* CONFIG_BATMAN_ADV_MCAST */ 595 596 #ifdef CONFIG_BATMAN_ADV_NC 597 if (info->attrs[BATADV_ATTR_NETWORK_CODING_ENABLED]) { 598 attr = info->attrs[BATADV_ATTR_NETWORK_CODING_ENABLED]; 599 600 atomic_set(&bat_priv->network_coding, !!nla_get_u8(attr)); 601 batadv_nc_status_update(bat_priv->soft_iface); 602 } 603 #endif /* CONFIG_BATMAN_ADV_NC */ 604 605 if (info->attrs[BATADV_ATTR_ORIG_INTERVAL]) { 606 u32 orig_interval; 607 608 attr = info->attrs[BATADV_ATTR_ORIG_INTERVAL]; 609 orig_interval = nla_get_u32(attr); 610 611 orig_interval = min_t(u32, orig_interval, INT_MAX); 612 orig_interval = max_t(u32, orig_interval, 2 * BATADV_JITTER); 613 614 atomic_set(&bat_priv->orig_interval, orig_interval); 615 } 616 617 batadv_netlink_notify_mesh(bat_priv); 618 619 return 0; 620 } 621 622 /** 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 626 * 627 * Return: 0 on success, < 0 on error 628 */ 629 static int 630 batadv_netlink_tp_meter_put(struct sk_buff *msg, u32 cookie) 631 { 632 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie)) 633 return -ENOBUFS; 634 635 return 0; 636 } 637 638 /** 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 of the tp_meter session 644 * @total_bytes: bytes acked to the receiver 645 * @cookie: cookie of tp_meter session 646 * 647 * Return: 0 on success, < 0 on error 648 */ 649 int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst, 650 u8 result, u32 test_time, u64 total_bytes, 651 u32 cookie) 652 { 653 struct sk_buff *msg; 654 void *hdr; 655 int ret; 656 657 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 658 if (!msg) 659 return -ENOMEM; 660 661 hdr = genlmsg_put(msg, 0, 0, &batadv_netlink_family, 0, 662 BATADV_CMD_TP_METER); 663 if (!hdr) { 664 ret = -ENOBUFS; 665 goto err_genlmsg; 666 } 667 668 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie)) 669 goto nla_put_failure; 670 671 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_TEST_TIME, test_time)) 672 goto nla_put_failure; 673 674 if (nla_put_u64_64bit(msg, BATADV_ATTR_TPMETER_BYTES, total_bytes, 675 BATADV_ATTR_PAD)) 676 goto nla_put_failure; 677 678 if (nla_put_u8(msg, BATADV_ATTR_TPMETER_RESULT, result)) 679 goto nla_put_failure; 680 681 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, dst)) 682 goto nla_put_failure; 683 684 genlmsg_end(msg, hdr); 685 686 genlmsg_multicast_netns(&batadv_netlink_family, 687 dev_net(bat_priv->soft_iface), msg, 0, 688 BATADV_NL_MCGRP_TPMETER, GFP_KERNEL); 689 690 return 0; 691 692 nla_put_failure: 693 genlmsg_cancel(msg, hdr); 694 ret = -EMSGSIZE; 695 696 err_genlmsg: 697 nlmsg_free(msg); 698 return ret; 699 } 700 701 /** 702 * batadv_netlink_tp_meter_start() - Start a new tp_meter session 703 * @skb: received netlink message 704 * @info: receiver information 705 * 706 * Return: 0 on success, < 0 on error 707 */ 708 static int 709 batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info) 710 { 711 struct batadv_priv *bat_priv = info->user_ptr[0]; 712 struct sk_buff *msg = NULL; 713 u32 test_length; 714 void *msg_head; 715 u32 cookie; 716 u8 *dst; 717 int ret; 718 719 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS]) 720 return -EINVAL; 721 722 if (!info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]) 723 return -EINVAL; 724 725 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]); 726 727 test_length = nla_get_u32(info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]); 728 729 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 730 if (!msg) { 731 ret = -ENOMEM; 732 goto out; 733 } 734 735 msg_head = genlmsg_put(msg, info->snd_portid, info->snd_seq, 736 &batadv_netlink_family, 0, 737 BATADV_CMD_TP_METER); 738 if (!msg_head) { 739 ret = -ENOBUFS; 740 goto out; 741 } 742 743 batadv_tp_start(bat_priv, dst, test_length, &cookie); 744 745 ret = batadv_netlink_tp_meter_put(msg, cookie); 746 747 out: 748 if (ret) { 749 if (msg) 750 nlmsg_free(msg); 751 return ret; 752 } 753 754 genlmsg_end(msg, msg_head); 755 return genlmsg_reply(msg, info); 756 } 757 758 /** 759 * batadv_netlink_tp_meter_start() - Cancel a running tp_meter session 760 * @skb: received netlink message 761 * @info: receiver information 762 * 763 * Return: 0 on success, < 0 on error 764 */ 765 static int 766 batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info) 767 { 768 struct batadv_priv *bat_priv = info->user_ptr[0]; 769 u8 *dst; 770 int ret = 0; 771 772 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS]) 773 return -EINVAL; 774 775 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]); 776 777 batadv_tp_stop(bat_priv, dst, BATADV_TP_REASON_CANCEL); 778 779 return ret; 780 } 781 782 /** 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 792 * 793 * Return: 0 on success or negative error number in case of failure 794 */ 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) 801 { 802 struct net_device *net_dev = hard_iface->net_dev; 803 void *hdr; 804 805 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 806 if (!hdr) 807 return -ENOBUFS; 808 809 if (cb) 810 genl_dump_check_consistent(cb, hdr); 811 812 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, 813 bat_priv->soft_iface->ifindex)) 814 goto nla_put_failure; 815 816 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, 817 net_dev->ifindex) || 818 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, 819 net_dev->name) || 820 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN, 821 net_dev->dev_addr)) 822 goto nla_put_failure; 823 824 if (hard_iface->if_status == BATADV_IF_ACTIVE) { 825 if (nla_put_flag(msg, BATADV_ATTR_ACTIVE)) 826 goto nla_put_failure; 827 } 828 829 if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY, 830 atomic_read(&hard_iface->hop_penalty))) 831 goto nla_put_failure; 832 833 #ifdef CONFIG_BATMAN_ADV_BATMAN_V 834 if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL, 835 atomic_read(&hard_iface->bat_v.elp_interval))) 836 goto nla_put_failure; 837 838 if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT_OVERRIDE, 839 atomic_read(&hard_iface->bat_v.throughput_override))) 840 goto nla_put_failure; 841 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */ 842 843 genlmsg_end(msg, hdr); 844 return 0; 845 846 nla_put_failure: 847 genlmsg_cancel(msg, hdr); 848 return -EMSGSIZE; 849 } 850 851 /** 852 * batadv_netlink_notify_hardif() - send hardif attributes to listener 853 * @bat_priv: the bat priv with all the soft interface information 854 * @hard_iface: hard interface which was modified 855 * 856 * Return: 0 on success, < 0 on error 857 */ 858 int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv, 859 struct batadv_hard_iface *hard_iface) 860 { 861 struct sk_buff *msg; 862 int ret; 863 864 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 865 if (!msg) 866 return -ENOMEM; 867 868 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 869 BATADV_CMD_SET_HARDIF, 0, 0, 0, NULL); 870 if (ret < 0) { 871 nlmsg_free(msg); 872 return ret; 873 } 874 875 genlmsg_multicast_netns(&batadv_netlink_family, 876 dev_net(bat_priv->soft_iface), msg, 0, 877 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 878 879 return 0; 880 } 881 882 /** 883 * batadv_netlink_get_hardif() - Get hardif attributes 884 * @skb: Netlink message with request data 885 * @info: receiver information 886 * 887 * Return: 0 on success or negative error number in case of failure 888 */ 889 static int batadv_netlink_get_hardif(struct sk_buff *skb, 890 struct genl_info *info) 891 { 892 struct batadv_hard_iface *hard_iface = info->user_ptr[1]; 893 struct batadv_priv *bat_priv = info->user_ptr[0]; 894 struct sk_buff *msg; 895 int ret; 896 897 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 898 if (!msg) 899 return -ENOMEM; 900 901 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 902 BATADV_CMD_GET_HARDIF, 903 info->snd_portid, info->snd_seq, 0, 904 NULL); 905 if (ret < 0) { 906 nlmsg_free(msg); 907 return ret; 908 } 909 910 ret = genlmsg_reply(msg, info); 911 912 return ret; 913 } 914 915 /** 916 * batadv_netlink_set_hardif() - Set hardif attributes 917 * @skb: Netlink message with request data 918 * @info: receiver information 919 * 920 * Return: 0 on success or negative error number in case of failure 921 */ 922 static int batadv_netlink_set_hardif(struct sk_buff *skb, 923 struct genl_info *info) 924 { 925 struct batadv_hard_iface *hard_iface = info->user_ptr[1]; 926 struct batadv_priv *bat_priv = info->user_ptr[0]; 927 struct nlattr *attr; 928 929 if (info->attrs[BATADV_ATTR_HOP_PENALTY]) { 930 attr = info->attrs[BATADV_ATTR_HOP_PENALTY]; 931 932 atomic_set(&hard_iface->hop_penalty, nla_get_u8(attr)); 933 } 934 935 #ifdef CONFIG_BATMAN_ADV_BATMAN_V 936 937 if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) { 938 attr = info->attrs[BATADV_ATTR_ELP_INTERVAL]; 939 940 atomic_set(&hard_iface->bat_v.elp_interval, nla_get_u32(attr)); 941 } 942 943 if (info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]) { 944 attr = info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]; 945 946 atomic_set(&hard_iface->bat_v.throughput_override, 947 nla_get_u32(attr)); 948 } 949 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */ 950 951 batadv_netlink_notify_hardif(bat_priv, hard_iface); 952 953 return 0; 954 } 955 956 /** 957 * batadv_netlink_dump_hardif() - Dump all hard interface into a messages 958 * @msg: Netlink message to dump into 959 * @cb: Parameters from query 960 * 961 * Return: error code, or length of reply message on success 962 */ 963 static int 964 batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb) 965 { 966 struct net *net = sock_net(cb->skb->sk); 967 struct net_device *soft_iface; 968 struct batadv_hard_iface *hard_iface; 969 struct batadv_priv *bat_priv; 970 int ifindex; 971 int portid = NETLINK_CB(cb->skb).portid; 972 int skip = cb->args[0]; 973 int i = 0; 974 975 ifindex = batadv_netlink_get_ifindex(cb->nlh, 976 BATADV_ATTR_MESH_IFINDEX); 977 if (!ifindex) 978 return -EINVAL; 979 980 soft_iface = dev_get_by_index(net, ifindex); 981 if (!soft_iface) 982 return -ENODEV; 983 984 if (!batadv_softif_is_valid(soft_iface)) { 985 dev_put(soft_iface); 986 return -ENODEV; 987 } 988 989 bat_priv = netdev_priv(soft_iface); 990 991 rtnl_lock(); 992 cb->seq = batadv_hardif_generation << 1 | 1; 993 994 list_for_each_entry(hard_iface, &batadv_hardif_list, list) { 995 if (hard_iface->soft_iface != soft_iface) 996 continue; 997 998 if (i++ < skip) 999 continue; 1000 1001 if (batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 1002 BATADV_CMD_GET_HARDIF, 1003 portid, cb->nlh->nlmsg_seq, 1004 NLM_F_MULTI, cb)) { 1005 i--; 1006 break; 1007 } 1008 } 1009 1010 rtnl_unlock(); 1011 1012 dev_put(soft_iface); 1013 1014 cb->args[0] = i; 1015 1016 return msg->len; 1017 } 1018 1019 /** 1020 * batadv_netlink_vlan_fill() - Fill message with vlan attributes 1021 * @msg: Netlink message to dump into 1022 * @bat_priv: the bat priv with all the soft interface information 1023 * @vlan: vlan which was modified 1024 * @cmd: type of message to generate 1025 * @portid: Port making netlink request 1026 * @seq: sequence number for message 1027 * @flags: Additional flags for message 1028 * 1029 * Return: 0 on success or negative error number in case of failure 1030 */ 1031 static int batadv_netlink_vlan_fill(struct sk_buff *msg, 1032 struct batadv_priv *bat_priv, 1033 struct batadv_softif_vlan *vlan, 1034 enum batadv_nl_commands cmd, 1035 u32 portid, u32 seq, int flags) 1036 { 1037 void *hdr; 1038 1039 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 1040 if (!hdr) 1041 return -ENOBUFS; 1042 1043 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, 1044 bat_priv->soft_iface->ifindex)) 1045 goto nla_put_failure; 1046 1047 if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK)) 1048 goto nla_put_failure; 1049 1050 if (nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, 1051 !!atomic_read(&vlan->ap_isolation))) 1052 goto nla_put_failure; 1053 1054 genlmsg_end(msg, hdr); 1055 return 0; 1056 1057 nla_put_failure: 1058 genlmsg_cancel(msg, hdr); 1059 return -EMSGSIZE; 1060 } 1061 1062 /** 1063 * batadv_netlink_notify_vlan() - send vlan attributes to listener 1064 * @bat_priv: the bat priv with all the soft interface information 1065 * @vlan: vlan which was modified 1066 * 1067 * Return: 0 on success, < 0 on error 1068 */ 1069 int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv, 1070 struct batadv_softif_vlan *vlan) 1071 { 1072 struct sk_buff *msg; 1073 int ret; 1074 1075 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1076 if (!msg) 1077 return -ENOMEM; 1078 1079 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, 1080 BATADV_CMD_SET_VLAN, 0, 0, 0); 1081 if (ret < 0) { 1082 nlmsg_free(msg); 1083 return ret; 1084 } 1085 1086 genlmsg_multicast_netns(&batadv_netlink_family, 1087 dev_net(bat_priv->soft_iface), msg, 0, 1088 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 1089 1090 return 0; 1091 } 1092 1093 /** 1094 * batadv_netlink_get_vlan() - Get vlan attributes 1095 * @skb: Netlink message with request data 1096 * @info: receiver information 1097 * 1098 * Return: 0 on success or negative error number in case of failure 1099 */ 1100 static int batadv_netlink_get_vlan(struct sk_buff *skb, struct genl_info *info) 1101 { 1102 struct batadv_softif_vlan *vlan = info->user_ptr[1]; 1103 struct batadv_priv *bat_priv = info->user_ptr[0]; 1104 struct sk_buff *msg; 1105 int ret; 1106 1107 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1108 if (!msg) 1109 return -ENOMEM; 1110 1111 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, BATADV_CMD_GET_VLAN, 1112 info->snd_portid, info->snd_seq, 0); 1113 if (ret < 0) { 1114 nlmsg_free(msg); 1115 return ret; 1116 } 1117 1118 ret = genlmsg_reply(msg, info); 1119 1120 return ret; 1121 } 1122 1123 /** 1124 * batadv_netlink_set_vlan() - Get vlan attributes 1125 * @skb: Netlink message with request data 1126 * @info: receiver information 1127 * 1128 * Return: 0 on success or negative error number in case of failure 1129 */ 1130 static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info) 1131 { 1132 struct batadv_softif_vlan *vlan = info->user_ptr[1]; 1133 struct batadv_priv *bat_priv = info->user_ptr[0]; 1134 struct nlattr *attr; 1135 1136 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) { 1137 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]; 1138 1139 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr)); 1140 } 1141 1142 batadv_netlink_notify_vlan(bat_priv, vlan); 1143 1144 return 0; 1145 } 1146 1147 /** 1148 * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes 1149 * @net: the applicable net namespace 1150 * @info: receiver information 1151 * 1152 * Return: Pointer to soft interface (with increased refcnt) on success, error 1153 * pointer on error 1154 */ 1155 static struct net_device * 1156 batadv_get_softif_from_info(struct net *net, struct genl_info *info) 1157 { 1158 struct net_device *soft_iface; 1159 int ifindex; 1160 1161 if (!info->attrs[BATADV_ATTR_MESH_IFINDEX]) 1162 return ERR_PTR(-EINVAL); 1163 1164 ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]); 1165 1166 soft_iface = dev_get_by_index(net, ifindex); 1167 if (!soft_iface) 1168 return ERR_PTR(-ENODEV); 1169 1170 if (!batadv_softif_is_valid(soft_iface)) 1171 goto err_put_softif; 1172 1173 return soft_iface; 1174 1175 err_put_softif: 1176 dev_put(soft_iface); 1177 1178 return ERR_PTR(-EINVAL); 1179 } 1180 1181 /** 1182 * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes 1183 * @bat_priv: the bat priv with all the soft interface information 1184 * @net: the applicable net namespace 1185 * @info: receiver information 1186 * 1187 * Return: Pointer to hard interface (with increased refcnt) on success, error 1188 * pointer on error 1189 */ 1190 static struct batadv_hard_iface * 1191 batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net *net, 1192 struct genl_info *info) 1193 { 1194 struct batadv_hard_iface *hard_iface; 1195 struct net_device *hard_dev; 1196 unsigned int hardif_index; 1197 1198 if (!info->attrs[BATADV_ATTR_HARD_IFINDEX]) 1199 return ERR_PTR(-EINVAL); 1200 1201 hardif_index = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]); 1202 1203 hard_dev = dev_get_by_index(net, hardif_index); 1204 if (!hard_dev) 1205 return ERR_PTR(-ENODEV); 1206 1207 hard_iface = batadv_hardif_get_by_netdev(hard_dev); 1208 if (!hard_iface) 1209 goto err_put_harddev; 1210 1211 if (hard_iface->soft_iface != bat_priv->soft_iface) 1212 goto err_put_hardif; 1213 1214 /* hard_dev is referenced by hard_iface and not needed here */ 1215 dev_put(hard_dev); 1216 1217 return hard_iface; 1218 1219 err_put_hardif: 1220 batadv_hardif_put(hard_iface); 1221 err_put_harddev: 1222 dev_put(hard_dev); 1223 1224 return ERR_PTR(-EINVAL); 1225 } 1226 1227 /** 1228 * batadv_get_vlan_from_info() - Retrieve vlan from genl attributes 1229 * @bat_priv: the bat priv with all the soft interface information 1230 * @net: the applicable net namespace 1231 * @info: receiver information 1232 * 1233 * Return: Pointer to vlan on success (with increased refcnt), error pointer 1234 * on error 1235 */ 1236 static struct batadv_softif_vlan * 1237 batadv_get_vlan_from_info(struct batadv_priv *bat_priv, struct net *net, 1238 struct genl_info *info) 1239 { 1240 struct batadv_softif_vlan *vlan; 1241 u16 vid; 1242 1243 if (!info->attrs[BATADV_ATTR_VLANID]) 1244 return ERR_PTR(-EINVAL); 1245 1246 vid = nla_get_u16(info->attrs[BATADV_ATTR_VLANID]); 1247 1248 vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); 1249 if (!vlan) 1250 return ERR_PTR(-ENOENT); 1251 1252 return vlan; 1253 } 1254 1255 /** 1256 * batadv_pre_doit() - Prepare batman-adv genl doit request 1257 * @ops: requested netlink operation 1258 * @skb: Netlink message with request data 1259 * @info: receiver information 1260 * 1261 * Return: 0 on success or negative error number in case of failure 1262 */ 1263 static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, 1264 struct genl_info *info) 1265 { 1266 struct net *net = genl_info_net(info); 1267 struct batadv_hard_iface *hard_iface; 1268 struct batadv_priv *bat_priv = NULL; 1269 struct batadv_softif_vlan *vlan; 1270 struct net_device *soft_iface; 1271 u8 user_ptr1_flags; 1272 u8 mesh_dep_flags; 1273 int ret; 1274 1275 user_ptr1_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN; 1276 if (WARN_ON(hweight8(ops->internal_flags & user_ptr1_flags) > 1)) 1277 return -EINVAL; 1278 1279 mesh_dep_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN; 1280 if (WARN_ON((ops->internal_flags & mesh_dep_flags) && 1281 (~ops->internal_flags & BATADV_FLAG_NEED_MESH))) 1282 return -EINVAL; 1283 1284 if (ops->internal_flags & BATADV_FLAG_NEED_MESH) { 1285 soft_iface = batadv_get_softif_from_info(net, info); 1286 if (IS_ERR(soft_iface)) 1287 return PTR_ERR(soft_iface); 1288 1289 bat_priv = netdev_priv(soft_iface); 1290 info->user_ptr[0] = bat_priv; 1291 } 1292 1293 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF) { 1294 hard_iface = batadv_get_hardif_from_info(bat_priv, net, info); 1295 if (IS_ERR(hard_iface)) { 1296 ret = PTR_ERR(hard_iface); 1297 goto err_put_softif; 1298 } 1299 1300 info->user_ptr[1] = hard_iface; 1301 } 1302 1303 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN) { 1304 vlan = batadv_get_vlan_from_info(bat_priv, net, info); 1305 if (IS_ERR(vlan)) { 1306 ret = PTR_ERR(vlan); 1307 goto err_put_softif; 1308 } 1309 1310 info->user_ptr[1] = vlan; 1311 } 1312 1313 return 0; 1314 1315 err_put_softif: 1316 if (bat_priv) 1317 dev_put(bat_priv->soft_iface); 1318 1319 return ret; 1320 } 1321 1322 /** 1323 * batadv_post_doit() - End batman-adv genl doit request 1324 * @ops: requested netlink operation 1325 * @skb: Netlink message with request data 1326 * @info: receiver information 1327 */ 1328 static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb, 1329 struct genl_info *info) 1330 { 1331 struct batadv_hard_iface *hard_iface; 1332 struct batadv_softif_vlan *vlan; 1333 struct batadv_priv *bat_priv; 1334 1335 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF && 1336 info->user_ptr[1]) { 1337 hard_iface = info->user_ptr[1]; 1338 1339 batadv_hardif_put(hard_iface); 1340 } 1341 1342 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN && info->user_ptr[1]) { 1343 vlan = info->user_ptr[1]; 1344 batadv_softif_vlan_put(vlan); 1345 } 1346 1347 if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) { 1348 bat_priv = info->user_ptr[0]; 1349 dev_put(bat_priv->soft_iface); 1350 } 1351 } 1352 1353 static const struct genl_small_ops batadv_netlink_ops[] = { 1354 { 1355 .cmd = BATADV_CMD_GET_MESH, 1356 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1357 /* can be retrieved by unprivileged users */ 1358 .doit = batadv_netlink_get_mesh, 1359 .internal_flags = BATADV_FLAG_NEED_MESH, 1360 }, 1361 { 1362 .cmd = BATADV_CMD_TP_METER, 1363 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1364 .flags = GENL_ADMIN_PERM, 1365 .doit = batadv_netlink_tp_meter_start, 1366 .internal_flags = BATADV_FLAG_NEED_MESH, 1367 }, 1368 { 1369 .cmd = BATADV_CMD_TP_METER_CANCEL, 1370 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1371 .flags = GENL_ADMIN_PERM, 1372 .doit = batadv_netlink_tp_meter_cancel, 1373 .internal_flags = BATADV_FLAG_NEED_MESH, 1374 }, 1375 { 1376 .cmd = BATADV_CMD_GET_ROUTING_ALGOS, 1377 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1378 .flags = GENL_ADMIN_PERM, 1379 .dumpit = batadv_algo_dump, 1380 }, 1381 { 1382 .cmd = BATADV_CMD_GET_HARDIF, 1383 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1384 /* can be retrieved by unprivileged users */ 1385 .dumpit = batadv_netlink_dump_hardif, 1386 .doit = batadv_netlink_get_hardif, 1387 .internal_flags = BATADV_FLAG_NEED_MESH | 1388 BATADV_FLAG_NEED_HARDIF, 1389 }, 1390 { 1391 .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL, 1392 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1393 .flags = GENL_ADMIN_PERM, 1394 .dumpit = batadv_tt_local_dump, 1395 }, 1396 { 1397 .cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL, 1398 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1399 .flags = GENL_ADMIN_PERM, 1400 .dumpit = batadv_tt_global_dump, 1401 }, 1402 { 1403 .cmd = BATADV_CMD_GET_ORIGINATORS, 1404 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1405 .flags = GENL_ADMIN_PERM, 1406 .dumpit = batadv_orig_dump, 1407 }, 1408 { 1409 .cmd = BATADV_CMD_GET_NEIGHBORS, 1410 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1411 .flags = GENL_ADMIN_PERM, 1412 .dumpit = batadv_hardif_neigh_dump, 1413 }, 1414 { 1415 .cmd = BATADV_CMD_GET_GATEWAYS, 1416 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1417 .flags = GENL_ADMIN_PERM, 1418 .dumpit = batadv_gw_dump, 1419 }, 1420 { 1421 .cmd = BATADV_CMD_GET_BLA_CLAIM, 1422 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1423 .flags = GENL_ADMIN_PERM, 1424 .dumpit = batadv_bla_claim_dump, 1425 }, 1426 { 1427 .cmd = BATADV_CMD_GET_BLA_BACKBONE, 1428 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1429 .flags = GENL_ADMIN_PERM, 1430 .dumpit = batadv_bla_backbone_dump, 1431 }, 1432 { 1433 .cmd = BATADV_CMD_GET_DAT_CACHE, 1434 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1435 .flags = GENL_ADMIN_PERM, 1436 .dumpit = batadv_dat_cache_dump, 1437 }, 1438 { 1439 .cmd = BATADV_CMD_GET_MCAST_FLAGS, 1440 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1441 .flags = GENL_ADMIN_PERM, 1442 .dumpit = batadv_mcast_flags_dump, 1443 }, 1444 { 1445 .cmd = BATADV_CMD_SET_MESH, 1446 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1447 .flags = GENL_ADMIN_PERM, 1448 .doit = batadv_netlink_set_mesh, 1449 .internal_flags = BATADV_FLAG_NEED_MESH, 1450 }, 1451 { 1452 .cmd = BATADV_CMD_SET_HARDIF, 1453 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1454 .flags = GENL_ADMIN_PERM, 1455 .doit = batadv_netlink_set_hardif, 1456 .internal_flags = BATADV_FLAG_NEED_MESH | 1457 BATADV_FLAG_NEED_HARDIF, 1458 }, 1459 { 1460 .cmd = BATADV_CMD_GET_VLAN, 1461 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1462 /* can be retrieved by unprivileged users */ 1463 .doit = batadv_netlink_get_vlan, 1464 .internal_flags = BATADV_FLAG_NEED_MESH | 1465 BATADV_FLAG_NEED_VLAN, 1466 }, 1467 { 1468 .cmd = BATADV_CMD_SET_VLAN, 1469 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1470 .flags = GENL_ADMIN_PERM, 1471 .doit = batadv_netlink_set_vlan, 1472 .internal_flags = BATADV_FLAG_NEED_MESH | 1473 BATADV_FLAG_NEED_VLAN, 1474 }, 1475 }; 1476 1477 struct genl_family batadv_netlink_family __ro_after_init = { 1478 .hdrsize = 0, 1479 .name = BATADV_NL_NAME, 1480 .version = 1, 1481 .maxattr = BATADV_ATTR_MAX, 1482 .policy = batadv_netlink_policy, 1483 .netnsok = true, 1484 .pre_doit = batadv_pre_doit, 1485 .post_doit = batadv_post_doit, 1486 .module = THIS_MODULE, 1487 .small_ops = batadv_netlink_ops, 1488 .n_small_ops = ARRAY_SIZE(batadv_netlink_ops), 1489 .mcgrps = batadv_netlink_mcgrps, 1490 .n_mcgrps = ARRAY_SIZE(batadv_netlink_mcgrps), 1491 }; 1492 1493 /** 1494 * batadv_netlink_register() - register batadv genl netlink family 1495 */ 1496 void __init batadv_netlink_register(void) 1497 { 1498 int ret; 1499 1500 ret = genl_register_family(&batadv_netlink_family); 1501 if (ret) 1502 pr_warn("unable to register netlink family"); 1503 } 1504 1505 /** 1506 * batadv_netlink_unregister() - unregister batadv genl netlink family 1507 */ 1508 void batadv_netlink_unregister(void) 1509 { 1510 genl_unregister_family(&batadv_netlink_family); 1511 } 1512