1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 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/array_size.h> 11 #include <linux/atomic.h> 12 #include <linux/bitops.h> 13 #include <linux/bug.h> 14 #include <linux/byteorder/generic.h> 15 #include <linux/cache.h> 16 #include <linux/err.h> 17 #include <linux/errno.h> 18 #include <linux/gfp.h> 19 #include <linux/if_ether.h> 20 #include <linux/if_vlan.h> 21 #include <linux/init.h> 22 #include <linux/limits.h> 23 #include <linux/minmax.h> 24 #include <linux/netdevice.h> 25 #include <linux/netlink.h> 26 #include <linux/printk.h> 27 #include <linux/rtnetlink.h> 28 #include <linux/skbuff.h> 29 #include <linux/stddef.h> 30 #include <linux/types.h> 31 #include <net/genetlink.h> 32 #include <net/net_namespace.h> 33 #include <net/netlink.h> 34 #include <net/sock.h> 35 #include <uapi/linux/batadv_packet.h> 36 #include <uapi/linux/batman_adv.h> 37 38 #include "bat_algo.h" 39 #include "bridge_loop_avoidance.h" 40 #include "distributed-arp-table.h" 41 #include "gateway_client.h" 42 #include "gateway_common.h" 43 #include "hard-interface.h" 44 #include "log.h" 45 #include "mesh-interface.h" 46 #include "multicast.h" 47 #include "network-coding.h" 48 #include "originator.h" 49 #include "tp_meter.h" 50 #include "translation-table.h" 51 52 struct genl_family batadv_netlink_family; 53 54 /* multicast groups */ 55 enum batadv_netlink_multicast_groups { 56 BATADV_NL_MCGRP_CONFIG, 57 BATADV_NL_MCGRP_TPMETER, 58 }; 59 60 /** 61 * enum batadv_genl_ops_flags - flags for genl_ops's internal_flags 62 */ 63 enum batadv_genl_ops_flags { 64 /** 65 * @BATADV_FLAG_NEED_MESH: request requires valid mesh interface in 66 * attribute BATADV_ATTR_MESH_IFINDEX and expects a pointer to it to be 67 * saved in info->user_ptr[0] 68 */ 69 BATADV_FLAG_NEED_MESH = BIT(0), 70 71 /** 72 * @BATADV_FLAG_NEED_HARDIF: request requires valid hard interface in 73 * attribute BATADV_ATTR_HARD_IFINDEX and expects a pointer to it to be 74 * saved in info->user_ptr[1] 75 */ 76 BATADV_FLAG_NEED_HARDIF = BIT(1), 77 78 /** 79 * @BATADV_FLAG_NEED_VLAN: request requires valid vlan in 80 * attribute BATADV_ATTR_VLANID and expects a pointer to it to be 81 * saved in info->user_ptr[1] 82 */ 83 BATADV_FLAG_NEED_VLAN = BIT(2), 84 }; 85 86 static const struct genl_multicast_group batadv_netlink_mcgrps[] = { 87 [BATADV_NL_MCGRP_CONFIG] = { .name = BATADV_NL_MCAST_GROUP_CONFIG }, 88 [BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER }, 89 }; 90 91 static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { 92 [BATADV_ATTR_VERSION] = { .type = NLA_STRING }, 93 [BATADV_ATTR_ALGO_NAME] = { .type = NLA_STRING }, 94 [BATADV_ATTR_MESH_IFINDEX] = { .type = NLA_U32 }, 95 [BATADV_ATTR_MESH_IFNAME] = { .type = NLA_STRING }, 96 [BATADV_ATTR_MESH_ADDRESS] = { .len = ETH_ALEN }, 97 [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, 98 [BATADV_ATTR_HARD_IFNAME] = { .type = NLA_STRING }, 99 [BATADV_ATTR_HARD_ADDRESS] = { .len = ETH_ALEN }, 100 [BATADV_ATTR_ORIG_ADDRESS] = { .len = ETH_ALEN }, 101 [BATADV_ATTR_TPMETER_RESULT] = { .type = NLA_U8 }, 102 [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NLA_U32 }, 103 [BATADV_ATTR_TPMETER_BYTES] = { .type = NLA_U64 }, 104 [BATADV_ATTR_TPMETER_COOKIE] = { .type = NLA_U32 }, 105 [BATADV_ATTR_ACTIVE] = { .type = NLA_FLAG }, 106 [BATADV_ATTR_TT_ADDRESS] = { .len = ETH_ALEN }, 107 [BATADV_ATTR_TT_TTVN] = { .type = NLA_U8 }, 108 [BATADV_ATTR_TT_LAST_TTVN] = { .type = NLA_U8 }, 109 [BATADV_ATTR_TT_CRC32] = { .type = NLA_U32 }, 110 [BATADV_ATTR_TT_VID] = { .type = NLA_U16 }, 111 [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 }, 112 [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG }, 113 [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 }, 114 [BATADV_ATTR_NEIGH_ADDRESS] = { .len = ETH_ALEN }, 115 [BATADV_ATTR_TQ] = { .type = NLA_U8 }, 116 [BATADV_ATTR_THROUGHPUT] = { .type = NLA_U32 }, 117 [BATADV_ATTR_BANDWIDTH_UP] = { .type = NLA_U32 }, 118 [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NLA_U32 }, 119 [BATADV_ATTR_ROUTER] = { .len = ETH_ALEN }, 120 [BATADV_ATTR_BLA_OWN] = { .type = NLA_FLAG }, 121 [BATADV_ATTR_BLA_ADDRESS] = { .len = ETH_ALEN }, 122 [BATADV_ATTR_BLA_VID] = { .type = NLA_U16 }, 123 [BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN }, 124 [BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 }, 125 [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NLA_U32 }, 126 [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .len = ETH_ALEN }, 127 [BATADV_ATTR_DAT_CACHE_VID] = { .type = NLA_U16 }, 128 [BATADV_ATTR_MCAST_FLAGS] = { .type = NLA_U32 }, 129 [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 }, 130 [BATADV_ATTR_VLANID] = { .type = NLA_U16 }, 131 [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NLA_U8 }, 132 [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NLA_U8 }, 133 [BATADV_ATTR_ISOLATION_MARK] = { .type = NLA_U32 }, 134 [BATADV_ATTR_ISOLATION_MASK] = { .type = NLA_U32 }, 135 [BATADV_ATTR_BONDING_ENABLED] = { .type = NLA_U8 }, 136 [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NLA_U8 }, 137 [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NLA_U8 }, 138 [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NLA_U8 }, 139 [BATADV_ATTR_GW_BANDWIDTH_DOWN] = { .type = NLA_U32 }, 140 [BATADV_ATTR_GW_BANDWIDTH_UP] = { .type = NLA_U32 }, 141 [BATADV_ATTR_GW_MODE] = { .type = NLA_U8 }, 142 [BATADV_ATTR_GW_SEL_CLASS] = { .type = NLA_U32 }, 143 [BATADV_ATTR_HOP_PENALTY] = { .type = NLA_U8 }, 144 [BATADV_ATTR_LOG_LEVEL] = { .type = NLA_U32 }, 145 [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED] = { .type = NLA_U8 }, 146 [BATADV_ATTR_MULTICAST_FANOUT] = { .type = NLA_U32 }, 147 [BATADV_ATTR_NETWORK_CODING_ENABLED] = { .type = NLA_U8 }, 148 [BATADV_ATTR_ORIG_INTERVAL] = { .type = NLA_U32 }, 149 [BATADV_ATTR_ELP_INTERVAL] = { .type = NLA_U32 }, 150 [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NLA_U32 }, 151 }; 152 153 /** 154 * batadv_netlink_get_ifindex() - Extract an interface index from a message 155 * @nlh: Message header 156 * @attrtype: Attribute which holds an interface index 157 * 158 * Return: interface index, or 0. 159 */ 160 static int batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype) 161 { 162 struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype); 163 164 return (attr && nla_len(attr) == sizeof(u32)) ? nla_get_u32(attr) : 0; 165 } 166 167 /** 168 * batadv_netlink_mesh_fill_ap_isolation() - Add ap_isolation meshif attribute 169 * @msg: Netlink message to dump into 170 * @bat_priv: the bat priv with all the mesh interface information 171 * 172 * Return: 0 on success or negative error number in case of failure 173 */ 174 static int batadv_netlink_mesh_fill_ap_isolation(struct sk_buff *msg, 175 struct batadv_priv *bat_priv) 176 { 177 struct batadv_meshif_vlan *vlan; 178 u8 ap_isolation; 179 180 vlan = batadv_meshif_vlan_get(bat_priv, BATADV_NO_FLAGS); 181 if (!vlan) 182 return 0; 183 184 ap_isolation = atomic_read(&vlan->ap_isolation); 185 batadv_meshif_vlan_put(vlan); 186 187 return nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, 188 !!ap_isolation); 189 } 190 191 /** 192 * batadv_netlink_set_mesh_ap_isolation() - Set ap_isolation from genl msg 193 * @attr: parsed BATADV_ATTR_AP_ISOLATION_ENABLED attribute 194 * @bat_priv: the bat priv with all the mesh interface information 195 * 196 * Return: 0 on success or negative error number in case of failure 197 */ 198 static int batadv_netlink_set_mesh_ap_isolation(struct nlattr *attr, 199 struct batadv_priv *bat_priv) 200 { 201 struct batadv_meshif_vlan *vlan; 202 203 vlan = batadv_meshif_vlan_get(bat_priv, BATADV_NO_FLAGS); 204 if (!vlan) 205 return -ENOENT; 206 207 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr)); 208 batadv_meshif_vlan_put(vlan); 209 210 return 0; 211 } 212 213 /** 214 * batadv_netlink_mesh_fill() - Fill message with mesh attributes 215 * @msg: Netlink message to dump into 216 * @bat_priv: the bat priv with all the mesh interface information 217 * @cmd: type of message to generate 218 * @portid: Port making netlink request 219 * @seq: sequence number for message 220 * @flags: Additional flags for message 221 * 222 * Return: 0 on success or negative error number in case of failure 223 */ 224 static int batadv_netlink_mesh_fill(struct sk_buff *msg, 225 struct batadv_priv *bat_priv, 226 enum batadv_nl_commands cmd, 227 u32 portid, u32 seq, int flags) 228 { 229 struct net_device *mesh_iface = bat_priv->mesh_iface; 230 struct batadv_hard_iface *primary_if = NULL; 231 struct net_device *hard_iface; 232 void *hdr; 233 234 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 235 if (!hdr) 236 return -ENOBUFS; 237 238 if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) || 239 nla_put_string(msg, BATADV_ATTR_ALGO_NAME, 240 bat_priv->algo_ops->name) || 241 nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, mesh_iface->ifindex) || 242 nla_put_string(msg, BATADV_ATTR_MESH_IFNAME, mesh_iface->name) || 243 nla_put(msg, BATADV_ATTR_MESH_ADDRESS, ETH_ALEN, 244 mesh_iface->dev_addr) || 245 nla_put_u8(msg, BATADV_ATTR_TT_TTVN, 246 (u8)atomic_read(&bat_priv->tt.vn))) 247 goto nla_put_failure; 248 249 #ifdef CONFIG_BATMAN_ADV_BLA 250 if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC, 251 ntohs(bat_priv->bla.claim_dest.group))) 252 goto nla_put_failure; 253 #endif 254 255 if (batadv_mcast_mesh_info_put(msg, bat_priv)) 256 goto nla_put_failure; 257 258 primary_if = batadv_primary_if_get_selected(bat_priv); 259 if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) { 260 hard_iface = primary_if->net_dev; 261 262 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, 263 hard_iface->ifindex) || 264 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, 265 hard_iface->name) || 266 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN, 267 hard_iface->dev_addr)) 268 goto nla_put_failure; 269 } 270 271 if (nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS_ENABLED, 272 !!atomic_read(&bat_priv->aggregated_ogms))) 273 goto nla_put_failure; 274 275 if (batadv_netlink_mesh_fill_ap_isolation(msg, bat_priv)) 276 goto nla_put_failure; 277 278 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MARK, 279 bat_priv->isolation_mark)) 280 goto nla_put_failure; 281 282 if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MASK, 283 bat_priv->isolation_mark_mask)) 284 goto nla_put_failure; 285 286 if (nla_put_u8(msg, BATADV_ATTR_BONDING_ENABLED, 287 !!atomic_read(&bat_priv->bonding))) 288 goto nla_put_failure; 289 290 #ifdef CONFIG_BATMAN_ADV_BLA 291 if (nla_put_u8(msg, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED, 292 !!atomic_read(&bat_priv->bridge_loop_avoidance))) 293 goto nla_put_failure; 294 #endif /* CONFIG_BATMAN_ADV_BLA */ 295 296 #ifdef CONFIG_BATMAN_ADV_DAT 297 if (nla_put_u8(msg, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED, 298 !!atomic_read(&bat_priv->distributed_arp_table))) 299 goto nla_put_failure; 300 #endif /* CONFIG_BATMAN_ADV_DAT */ 301 302 if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION_ENABLED, 303 !!atomic_read(&bat_priv->fragmentation))) 304 goto nla_put_failure; 305 306 if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_DOWN, 307 atomic_read(&bat_priv->gw.bandwidth_down))) 308 goto nla_put_failure; 309 310 if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_UP, 311 atomic_read(&bat_priv->gw.bandwidth_up))) 312 goto nla_put_failure; 313 314 if (nla_put_u8(msg, BATADV_ATTR_GW_MODE, 315 atomic_read(&bat_priv->gw.mode))) 316 goto nla_put_failure; 317 318 if (bat_priv->algo_ops->gw.get_best_gw_node && 319 bat_priv->algo_ops->gw.is_eligible) { 320 /* GW selection class is not available if the routing algorithm 321 * in use does not implement the GW API 322 */ 323 if (nla_put_u32(msg, BATADV_ATTR_GW_SEL_CLASS, 324 atomic_read(&bat_priv->gw.sel_class))) 325 goto nla_put_failure; 326 } 327 328 if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY, 329 atomic_read(&bat_priv->hop_penalty))) 330 goto nla_put_failure; 331 332 #ifdef CONFIG_BATMAN_ADV_DEBUG 333 if (nla_put_u32(msg, BATADV_ATTR_LOG_LEVEL, 334 atomic_read(&bat_priv->log_level))) 335 goto nla_put_failure; 336 #endif /* CONFIG_BATMAN_ADV_DEBUG */ 337 338 #ifdef CONFIG_BATMAN_ADV_MCAST 339 if (nla_put_u8(msg, BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED, 340 !atomic_read(&bat_priv->multicast_mode))) 341 goto nla_put_failure; 342 343 if (nla_put_u32(msg, BATADV_ATTR_MULTICAST_FANOUT, 344 atomic_read(&bat_priv->multicast_fanout))) 345 goto nla_put_failure; 346 #endif /* CONFIG_BATMAN_ADV_MCAST */ 347 348 #ifdef CONFIG_BATMAN_ADV_NC 349 if (nla_put_u8(msg, BATADV_ATTR_NETWORK_CODING_ENABLED, 350 !!atomic_read(&bat_priv->network_coding))) 351 goto nla_put_failure; 352 #endif /* CONFIG_BATMAN_ADV_NC */ 353 354 if (nla_put_u32(msg, BATADV_ATTR_ORIG_INTERVAL, 355 atomic_read(&bat_priv->orig_interval))) 356 goto nla_put_failure; 357 358 batadv_hardif_put(primary_if); 359 360 genlmsg_end(msg, hdr); 361 return 0; 362 363 nla_put_failure: 364 batadv_hardif_put(primary_if); 365 366 genlmsg_cancel(msg, hdr); 367 return -EMSGSIZE; 368 } 369 370 /** 371 * batadv_netlink_notify_mesh() - send meshif attributes to listener 372 * @bat_priv: the bat priv with all the mesh interface information 373 * 374 * Return: 0 on success, < 0 on error 375 */ 376 static int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv) 377 { 378 struct sk_buff *msg; 379 int ret; 380 381 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 382 if (!msg) 383 return -ENOMEM; 384 385 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_SET_MESH, 386 0, 0, 0); 387 if (ret < 0) { 388 nlmsg_free(msg); 389 return ret; 390 } 391 392 genlmsg_multicast_netns(&batadv_netlink_family, 393 dev_net(bat_priv->mesh_iface), msg, 0, 394 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 395 396 return 0; 397 } 398 399 /** 400 * batadv_netlink_get_mesh() - Get meshif attributes 401 * @skb: Netlink message with request data 402 * @info: receiver information 403 * 404 * Return: 0 on success or negative error number in case of failure 405 */ 406 static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info) 407 { 408 struct batadv_priv *bat_priv = info->user_ptr[0]; 409 struct sk_buff *msg; 410 int ret; 411 412 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 413 if (!msg) 414 return -ENOMEM; 415 416 ret = batadv_netlink_mesh_fill(msg, bat_priv, BATADV_CMD_GET_MESH, 417 info->snd_portid, info->snd_seq, 0); 418 if (ret < 0) { 419 nlmsg_free(msg); 420 return ret; 421 } 422 423 ret = genlmsg_reply(msg, info); 424 425 return ret; 426 } 427 428 /** 429 * batadv_netlink_set_mesh() - Set meshif attributes 430 * @skb: Netlink message with request data 431 * @info: receiver information 432 * 433 * Return: 0 on success or negative error number in case of failure 434 */ 435 static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info) 436 { 437 struct batadv_priv *bat_priv = info->user_ptr[0]; 438 struct nlattr *attr; 439 440 if (info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]) { 441 attr = info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]; 442 443 atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr)); 444 } 445 446 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) { 447 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]; 448 449 batadv_netlink_set_mesh_ap_isolation(attr, bat_priv); 450 } 451 452 if (info->attrs[BATADV_ATTR_ISOLATION_MARK]) { 453 attr = info->attrs[BATADV_ATTR_ISOLATION_MARK]; 454 455 bat_priv->isolation_mark = nla_get_u32(attr); 456 } 457 458 if (info->attrs[BATADV_ATTR_ISOLATION_MASK]) { 459 attr = info->attrs[BATADV_ATTR_ISOLATION_MASK]; 460 461 bat_priv->isolation_mark_mask = nla_get_u32(attr); 462 } 463 464 if (info->attrs[BATADV_ATTR_BONDING_ENABLED]) { 465 attr = info->attrs[BATADV_ATTR_BONDING_ENABLED]; 466 467 atomic_set(&bat_priv->bonding, !!nla_get_u8(attr)); 468 } 469 470 #ifdef CONFIG_BATMAN_ADV_BLA 471 if (info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED]) { 472 attr = info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED]; 473 474 atomic_set(&bat_priv->bridge_loop_avoidance, 475 !!nla_get_u8(attr)); 476 batadv_bla_status_update(bat_priv->mesh_iface); 477 } 478 #endif /* CONFIG_BATMAN_ADV_BLA */ 479 480 #ifdef CONFIG_BATMAN_ADV_DAT 481 if (info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED]) { 482 attr = info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED]; 483 484 atomic_set(&bat_priv->distributed_arp_table, 485 !!nla_get_u8(attr)); 486 batadv_dat_status_update(bat_priv->mesh_iface); 487 } 488 #endif /* CONFIG_BATMAN_ADV_DAT */ 489 490 if (info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]) { 491 attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]; 492 493 atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr)); 494 495 rtnl_lock(); 496 batadv_update_min_mtu(bat_priv->mesh_iface); 497 rtnl_unlock(); 498 } 499 500 if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) { 501 attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]; 502 503 atomic_set(&bat_priv->gw.bandwidth_down, nla_get_u32(attr)); 504 batadv_gw_tvlv_container_update(bat_priv); 505 } 506 507 if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]) { 508 attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]; 509 510 atomic_set(&bat_priv->gw.bandwidth_up, nla_get_u32(attr)); 511 batadv_gw_tvlv_container_update(bat_priv); 512 } 513 514 if (info->attrs[BATADV_ATTR_GW_MODE]) { 515 u8 gw_mode; 516 517 attr = info->attrs[BATADV_ATTR_GW_MODE]; 518 gw_mode = nla_get_u8(attr); 519 520 if (gw_mode <= BATADV_GW_MODE_SERVER) { 521 /* Invoking batadv_gw_reselect() is not enough to really 522 * de-select the current GW. It will only instruct the 523 * gateway client code to perform a re-election the next 524 * time that this is needed. 525 * 526 * When gw client mode is being switched off the current 527 * GW must be de-selected explicitly otherwise no GW_ADD 528 * uevent is thrown on client mode re-activation. This 529 * is operation is performed in 530 * batadv_gw_check_client_stop(). 531 */ 532 batadv_gw_reselect(bat_priv); 533 534 /* always call batadv_gw_check_client_stop() before 535 * changing the gateway state 536 */ 537 batadv_gw_check_client_stop(bat_priv); 538 atomic_set(&bat_priv->gw.mode, gw_mode); 539 batadv_gw_tvlv_container_update(bat_priv); 540 } 541 } 542 543 if (info->attrs[BATADV_ATTR_GW_SEL_CLASS] && 544 bat_priv->algo_ops->gw.get_best_gw_node && 545 bat_priv->algo_ops->gw.is_eligible) { 546 /* setting the GW selection class is allowed only if the routing 547 * algorithm in use implements the GW API 548 */ 549 550 u32 sel_class_max = bat_priv->algo_ops->gw.sel_class_max; 551 u32 sel_class; 552 553 attr = info->attrs[BATADV_ATTR_GW_SEL_CLASS]; 554 sel_class = nla_get_u32(attr); 555 556 if (sel_class >= 1 && sel_class <= sel_class_max) { 557 atomic_set(&bat_priv->gw.sel_class, sel_class); 558 batadv_gw_reselect(bat_priv); 559 } 560 } 561 562 if (info->attrs[BATADV_ATTR_HOP_PENALTY]) { 563 attr = info->attrs[BATADV_ATTR_HOP_PENALTY]; 564 565 atomic_set(&bat_priv->hop_penalty, nla_get_u8(attr)); 566 } 567 568 #ifdef CONFIG_BATMAN_ADV_DEBUG 569 if (info->attrs[BATADV_ATTR_LOG_LEVEL]) { 570 attr = info->attrs[BATADV_ATTR_LOG_LEVEL]; 571 572 atomic_set(&bat_priv->log_level, 573 nla_get_u32(attr) & BATADV_DBG_ALL); 574 } 575 #endif /* CONFIG_BATMAN_ADV_DEBUG */ 576 577 #ifdef CONFIG_BATMAN_ADV_MCAST 578 if (info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]) { 579 attr = info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]; 580 581 atomic_set(&bat_priv->multicast_mode, !nla_get_u8(attr)); 582 } 583 584 if (info->attrs[BATADV_ATTR_MULTICAST_FANOUT]) { 585 attr = info->attrs[BATADV_ATTR_MULTICAST_FANOUT]; 586 587 atomic_set(&bat_priv->multicast_fanout, nla_get_u32(attr)); 588 } 589 #endif /* CONFIG_BATMAN_ADV_MCAST */ 590 591 #ifdef CONFIG_BATMAN_ADV_NC 592 if (info->attrs[BATADV_ATTR_NETWORK_CODING_ENABLED]) { 593 attr = info->attrs[BATADV_ATTR_NETWORK_CODING_ENABLED]; 594 595 atomic_set(&bat_priv->network_coding, !!nla_get_u8(attr)); 596 batadv_nc_status_update(bat_priv->mesh_iface); 597 } 598 #endif /* CONFIG_BATMAN_ADV_NC */ 599 600 if (info->attrs[BATADV_ATTR_ORIG_INTERVAL]) { 601 u32 orig_interval; 602 603 attr = info->attrs[BATADV_ATTR_ORIG_INTERVAL]; 604 orig_interval = nla_get_u32(attr); 605 606 orig_interval = min_t(u32, orig_interval, INT_MAX); 607 orig_interval = max_t(u32, orig_interval, 2 * BATADV_JITTER); 608 609 atomic_set(&bat_priv->orig_interval, orig_interval); 610 } 611 612 batadv_netlink_notify_mesh(bat_priv); 613 614 return 0; 615 } 616 617 /** 618 * batadv_netlink_tp_meter_put() - Fill information of started tp_meter session 619 * @msg: netlink message to be sent back 620 * @cookie: tp meter session cookie 621 * 622 * Return: 0 on success, < 0 on error 623 */ 624 static int 625 batadv_netlink_tp_meter_put(struct sk_buff *msg, u32 cookie) 626 { 627 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie)) 628 return -ENOBUFS; 629 630 return 0; 631 } 632 633 /** 634 * batadv_netlink_tpmeter_notify() - send tp_meter result via netlink to client 635 * @bat_priv: the bat priv with all the mesh interface information 636 * @dst: destination of tp_meter session 637 * @result: reason for tp meter session stop 638 * @test_time: total time of the tp_meter session 639 * @total_bytes: bytes acked to the receiver 640 * @cookie: cookie of tp_meter session 641 * 642 * Return: 0 on success, < 0 on error 643 */ 644 int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst, 645 u8 result, u32 test_time, u64 total_bytes, 646 u32 cookie) 647 { 648 struct sk_buff *msg; 649 void *hdr; 650 int ret; 651 652 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 653 if (!msg) 654 return -ENOMEM; 655 656 hdr = genlmsg_put(msg, 0, 0, &batadv_netlink_family, 0, 657 BATADV_CMD_TP_METER); 658 if (!hdr) { 659 ret = -ENOBUFS; 660 goto err_genlmsg; 661 } 662 663 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_COOKIE, cookie)) 664 goto nla_put_failure; 665 666 if (nla_put_u32(msg, BATADV_ATTR_TPMETER_TEST_TIME, test_time)) 667 goto nla_put_failure; 668 669 if (nla_put_u64_64bit(msg, BATADV_ATTR_TPMETER_BYTES, total_bytes, 670 BATADV_ATTR_PAD)) 671 goto nla_put_failure; 672 673 if (nla_put_u8(msg, BATADV_ATTR_TPMETER_RESULT, result)) 674 goto nla_put_failure; 675 676 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, dst)) 677 goto nla_put_failure; 678 679 genlmsg_end(msg, hdr); 680 681 genlmsg_multicast_netns(&batadv_netlink_family, 682 dev_net(bat_priv->mesh_iface), msg, 0, 683 BATADV_NL_MCGRP_TPMETER, GFP_KERNEL); 684 685 return 0; 686 687 nla_put_failure: 688 genlmsg_cancel(msg, hdr); 689 ret = -EMSGSIZE; 690 691 err_genlmsg: 692 nlmsg_free(msg); 693 return ret; 694 } 695 696 /** 697 * batadv_netlink_tp_meter_start() - Start a new tp_meter session 698 * @skb: received netlink message 699 * @info: receiver information 700 * 701 * Return: 0 on success, < 0 on error 702 */ 703 static int 704 batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info) 705 { 706 struct batadv_priv *bat_priv = info->user_ptr[0]; 707 struct sk_buff *msg = NULL; 708 u32 test_length; 709 void *msg_head; 710 u32 cookie; 711 u8 *dst; 712 int ret; 713 714 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS]) 715 return -EINVAL; 716 717 if (!info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]) 718 return -EINVAL; 719 720 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]); 721 722 test_length = nla_get_u32(info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]); 723 724 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 725 if (!msg) { 726 ret = -ENOMEM; 727 goto out; 728 } 729 730 msg_head = genlmsg_put(msg, info->snd_portid, info->snd_seq, 731 &batadv_netlink_family, 0, 732 BATADV_CMD_TP_METER); 733 if (!msg_head) { 734 ret = -ENOBUFS; 735 goto out; 736 } 737 738 batadv_tp_start(bat_priv, dst, test_length, &cookie); 739 740 ret = batadv_netlink_tp_meter_put(msg, cookie); 741 742 out: 743 if (ret) { 744 if (msg) 745 nlmsg_free(msg); 746 return ret; 747 } 748 749 genlmsg_end(msg, msg_head); 750 return genlmsg_reply(msg, info); 751 } 752 753 /** 754 * batadv_netlink_tp_meter_cancel() - Cancel a running tp_meter session 755 * @skb: received netlink message 756 * @info: receiver information 757 * 758 * Return: 0 on success, < 0 on error 759 */ 760 static int 761 batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info) 762 { 763 struct batadv_priv *bat_priv = info->user_ptr[0]; 764 u8 *dst; 765 int ret = 0; 766 767 if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS]) 768 return -EINVAL; 769 770 dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]); 771 772 batadv_tp_stop(bat_priv, dst, BATADV_TP_REASON_CANCEL); 773 774 return ret; 775 } 776 777 /** 778 * batadv_netlink_hardif_fill() - Fill message with hardif attributes 779 * @msg: Netlink message to dump into 780 * @bat_priv: the bat priv with all the mesh interface information 781 * @hard_iface: hard interface which was modified 782 * @cmd: type of message to generate 783 * @portid: Port making netlink request 784 * @seq: sequence number for message 785 * @flags: Additional flags for message 786 * @cb: Control block containing additional options 787 * 788 * Return: 0 on success or negative error number in case of failure 789 */ 790 static int batadv_netlink_hardif_fill(struct sk_buff *msg, 791 struct batadv_priv *bat_priv, 792 struct batadv_hard_iface *hard_iface, 793 enum batadv_nl_commands cmd, 794 u32 portid, u32 seq, int flags, 795 struct netlink_callback *cb) 796 { 797 struct net_device *net_dev = hard_iface->net_dev; 798 void *hdr; 799 800 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 801 if (!hdr) 802 return -ENOBUFS; 803 804 if (cb) 805 genl_dump_check_consistent(cb, hdr); 806 807 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, 808 bat_priv->mesh_iface->ifindex)) 809 goto nla_put_failure; 810 811 if (nla_put_string(msg, BATADV_ATTR_MESH_IFNAME, 812 bat_priv->mesh_iface->name)) 813 goto nla_put_failure; 814 815 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, 816 net_dev->ifindex) || 817 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, 818 net_dev->name) || 819 nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN, 820 net_dev->dev_addr)) 821 goto nla_put_failure; 822 823 if (hard_iface->if_status == BATADV_IF_ACTIVE) { 824 if (nla_put_flag(msg, BATADV_ATTR_ACTIVE)) 825 goto nla_put_failure; 826 } 827 828 if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY, 829 atomic_read(&hard_iface->hop_penalty))) 830 goto nla_put_failure; 831 832 #ifdef CONFIG_BATMAN_ADV_BATMAN_V 833 if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL, 834 atomic_read(&hard_iface->bat_v.elp_interval))) 835 goto nla_put_failure; 836 837 if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT_OVERRIDE, 838 atomic_read(&hard_iface->bat_v.throughput_override))) 839 goto nla_put_failure; 840 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */ 841 842 genlmsg_end(msg, hdr); 843 return 0; 844 845 nla_put_failure: 846 genlmsg_cancel(msg, hdr); 847 return -EMSGSIZE; 848 } 849 850 /** 851 * batadv_netlink_notify_hardif() - send hardif attributes to listener 852 * @bat_priv: the bat priv with all the mesh interface information 853 * @hard_iface: hard interface which was modified 854 * 855 * Return: 0 on success, < 0 on error 856 */ 857 static int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv, 858 struct batadv_hard_iface *hard_iface) 859 { 860 struct sk_buff *msg; 861 int ret; 862 863 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 864 if (!msg) 865 return -ENOMEM; 866 867 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 868 BATADV_CMD_SET_HARDIF, 0, 0, 0, NULL); 869 if (ret < 0) { 870 nlmsg_free(msg); 871 return ret; 872 } 873 874 genlmsg_multicast_netns(&batadv_netlink_family, 875 dev_net(bat_priv->mesh_iface), msg, 0, 876 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 877 878 return 0; 879 } 880 881 /** 882 * batadv_netlink_cmd_get_hardif() - Get hardif attributes 883 * @skb: Netlink message with request data 884 * @info: receiver information 885 * 886 * Return: 0 on success or negative error number in case of failure 887 */ 888 static int batadv_netlink_cmd_get_hardif(struct sk_buff *skb, 889 struct genl_info *info) 890 { 891 struct batadv_hard_iface *hard_iface = info->user_ptr[1]; 892 struct batadv_priv *bat_priv = info->user_ptr[0]; 893 struct sk_buff *msg; 894 int ret; 895 896 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 897 if (!msg) 898 return -ENOMEM; 899 900 ret = batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 901 BATADV_CMD_GET_HARDIF, 902 info->snd_portid, info->snd_seq, 0, 903 NULL); 904 if (ret < 0) { 905 nlmsg_free(msg); 906 return ret; 907 } 908 909 ret = genlmsg_reply(msg, info); 910 911 return ret; 912 } 913 914 /** 915 * batadv_netlink_set_hardif() - Set hardif attributes 916 * @skb: Netlink message with request data 917 * @info: receiver information 918 * 919 * Return: 0 on success or negative error number in case of failure 920 */ 921 static int batadv_netlink_set_hardif(struct sk_buff *skb, 922 struct genl_info *info) 923 { 924 struct batadv_hard_iface *hard_iface = info->user_ptr[1]; 925 struct batadv_priv *bat_priv = info->user_ptr[0]; 926 struct nlattr *attr; 927 928 if (info->attrs[BATADV_ATTR_HOP_PENALTY]) { 929 attr = info->attrs[BATADV_ATTR_HOP_PENALTY]; 930 931 atomic_set(&hard_iface->hop_penalty, nla_get_u8(attr)); 932 } 933 934 #ifdef CONFIG_BATMAN_ADV_BATMAN_V 935 936 if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) { 937 attr = info->attrs[BATADV_ATTR_ELP_INTERVAL]; 938 939 atomic_set(&hard_iface->bat_v.elp_interval, nla_get_u32(attr)); 940 } 941 942 if (info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]) { 943 attr = info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]; 944 945 atomic_set(&hard_iface->bat_v.throughput_override, 946 nla_get_u32(attr)); 947 } 948 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */ 949 950 batadv_netlink_notify_hardif(bat_priv, hard_iface); 951 952 return 0; 953 } 954 955 /** 956 * batadv_netlink_dump_hardif() - Dump all hard interface into a messages 957 * @msg: Netlink message to dump into 958 * @cb: Parameters from query 959 * 960 * Return: error code, or length of reply message on success 961 */ 962 static int 963 batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb) 964 { 965 struct net_device *mesh_iface; 966 struct batadv_hard_iface *hard_iface; 967 struct batadv_priv *bat_priv; 968 int portid = NETLINK_CB(cb->skb).portid; 969 int skip = cb->args[0]; 970 struct list_head *iter; 971 int i = 0; 972 973 mesh_iface = batadv_netlink_get_meshif(cb); 974 if (IS_ERR(mesh_iface)) 975 return PTR_ERR(mesh_iface); 976 977 bat_priv = netdev_priv(mesh_iface); 978 979 rtnl_lock(); 980 cb->seq = batadv_hardif_generation << 1 | 1; 981 982 netdev_for_each_lower_private(mesh_iface, hard_iface, iter) { 983 if (i++ < skip) 984 continue; 985 986 if (batadv_netlink_hardif_fill(msg, bat_priv, hard_iface, 987 BATADV_CMD_GET_HARDIF, 988 portid, cb->nlh->nlmsg_seq, 989 NLM_F_MULTI, cb)) { 990 i--; 991 break; 992 } 993 } 994 995 rtnl_unlock(); 996 997 dev_put(mesh_iface); 998 999 cb->args[0] = i; 1000 1001 return msg->len; 1002 } 1003 1004 /** 1005 * batadv_netlink_vlan_fill() - Fill message with vlan attributes 1006 * @msg: Netlink message to dump into 1007 * @bat_priv: the bat priv with all the mesh interface information 1008 * @vlan: vlan which was modified 1009 * @cmd: type of message to generate 1010 * @portid: Port making netlink request 1011 * @seq: sequence number for message 1012 * @flags: Additional flags for message 1013 * 1014 * Return: 0 on success or negative error number in case of failure 1015 */ 1016 static int batadv_netlink_vlan_fill(struct sk_buff *msg, 1017 struct batadv_priv *bat_priv, 1018 struct batadv_meshif_vlan *vlan, 1019 enum batadv_nl_commands cmd, 1020 u32 portid, u32 seq, int flags) 1021 { 1022 void *hdr; 1023 1024 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd); 1025 if (!hdr) 1026 return -ENOBUFS; 1027 1028 if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, 1029 bat_priv->mesh_iface->ifindex)) 1030 goto nla_put_failure; 1031 1032 if (nla_put_string(msg, BATADV_ATTR_MESH_IFNAME, 1033 bat_priv->mesh_iface->name)) 1034 goto nla_put_failure; 1035 1036 if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK)) 1037 goto nla_put_failure; 1038 1039 if (nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, 1040 !!atomic_read(&vlan->ap_isolation))) 1041 goto nla_put_failure; 1042 1043 genlmsg_end(msg, hdr); 1044 return 0; 1045 1046 nla_put_failure: 1047 genlmsg_cancel(msg, hdr); 1048 return -EMSGSIZE; 1049 } 1050 1051 /** 1052 * batadv_netlink_notify_vlan() - send vlan attributes to listener 1053 * @bat_priv: the bat priv with all the mesh interface information 1054 * @vlan: vlan which was modified 1055 * 1056 * Return: 0 on success, < 0 on error 1057 */ 1058 static int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv, 1059 struct batadv_meshif_vlan *vlan) 1060 { 1061 struct sk_buff *msg; 1062 int ret; 1063 1064 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1065 if (!msg) 1066 return -ENOMEM; 1067 1068 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, 1069 BATADV_CMD_SET_VLAN, 0, 0, 0); 1070 if (ret < 0) { 1071 nlmsg_free(msg); 1072 return ret; 1073 } 1074 1075 genlmsg_multicast_netns(&batadv_netlink_family, 1076 dev_net(bat_priv->mesh_iface), msg, 0, 1077 BATADV_NL_MCGRP_CONFIG, GFP_KERNEL); 1078 1079 return 0; 1080 } 1081 1082 /** 1083 * batadv_netlink_get_vlan() - Get vlan attributes 1084 * @skb: Netlink message with request data 1085 * @info: receiver information 1086 * 1087 * Return: 0 on success or negative error number in case of failure 1088 */ 1089 static int batadv_netlink_get_vlan(struct sk_buff *skb, struct genl_info *info) 1090 { 1091 struct batadv_meshif_vlan *vlan = info->user_ptr[1]; 1092 struct batadv_priv *bat_priv = info->user_ptr[0]; 1093 struct sk_buff *msg; 1094 int ret; 1095 1096 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1097 if (!msg) 1098 return -ENOMEM; 1099 1100 ret = batadv_netlink_vlan_fill(msg, bat_priv, vlan, BATADV_CMD_GET_VLAN, 1101 info->snd_portid, info->snd_seq, 0); 1102 if (ret < 0) { 1103 nlmsg_free(msg); 1104 return ret; 1105 } 1106 1107 ret = genlmsg_reply(msg, info); 1108 1109 return ret; 1110 } 1111 1112 /** 1113 * batadv_netlink_set_vlan() - Get vlan attributes 1114 * @skb: Netlink message with request data 1115 * @info: receiver information 1116 * 1117 * Return: 0 on success or negative error number in case of failure 1118 */ 1119 static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info) 1120 { 1121 struct batadv_meshif_vlan *vlan = info->user_ptr[1]; 1122 struct batadv_priv *bat_priv = info->user_ptr[0]; 1123 struct nlattr *attr; 1124 1125 if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) { 1126 attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]; 1127 1128 atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr)); 1129 } 1130 1131 batadv_netlink_notify_vlan(bat_priv, vlan); 1132 1133 return 0; 1134 } 1135 1136 /** 1137 * batadv_netlink_get_meshif_from_ifindex() - Get mesh-iface from ifindex 1138 * @net: the applicable net namespace 1139 * @ifindex: index of the mesh interface 1140 * 1141 * Return: Pointer to mesh interface (with increased refcnt) on success, error 1142 * pointer on error 1143 */ 1144 static struct net_device * 1145 batadv_netlink_get_meshif_from_ifindex(struct net *net, int ifindex) 1146 { 1147 struct net_device *mesh_iface; 1148 1149 mesh_iface = dev_get_by_index(net, ifindex); 1150 if (!mesh_iface) 1151 return ERR_PTR(-ENODEV); 1152 1153 if (!batadv_meshif_is_valid(mesh_iface)) 1154 goto err_put_meshif; 1155 1156 return mesh_iface; 1157 1158 err_put_meshif: 1159 dev_put(mesh_iface); 1160 1161 return ERR_PTR(-EINVAL); 1162 } 1163 1164 /** 1165 * batadv_netlink_get_meshif_from_info() - Get mesh-iface from genl attributes 1166 * @net: the applicable net namespace 1167 * @info: receiver information 1168 * 1169 * Return: Pointer to mesh interface (with increased refcnt) on success, error 1170 * pointer on error 1171 */ 1172 static struct net_device * 1173 batadv_netlink_get_meshif_from_info(struct net *net, struct genl_info *info) 1174 { 1175 int ifindex; 1176 1177 if (!info->attrs[BATADV_ATTR_MESH_IFINDEX]) 1178 return ERR_PTR(-EINVAL); 1179 1180 ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]); 1181 1182 return batadv_netlink_get_meshif_from_ifindex(net, ifindex); 1183 } 1184 1185 /** 1186 * batadv_netlink_get_meshif() - Retrieve mesh interface from netlink callback 1187 * @cb: callback structure containing arguments 1188 * 1189 * Return: Pointer to mesh interface (with increased refcnt) on success, error 1190 * pointer on error 1191 */ 1192 struct net_device *batadv_netlink_get_meshif(struct netlink_callback *cb) 1193 { 1194 int ifindex = batadv_netlink_get_ifindex(cb->nlh, 1195 BATADV_ATTR_MESH_IFINDEX); 1196 if (!ifindex) 1197 return ERR_PTR(-ENONET); 1198 1199 return batadv_netlink_get_meshif_from_ifindex(sock_net(cb->skb->sk), 1200 ifindex); 1201 } 1202 1203 /** 1204 * batadv_netlink_get_hardif_from_ifindex() - Get hard-iface from ifindex 1205 * @bat_priv: the bat priv with all the mesh interface information 1206 * @net: the applicable net namespace 1207 * @ifindex: index of the hard interface 1208 * 1209 * Return: Pointer to hard interface (with increased refcnt) on success, error 1210 * pointer on error 1211 */ 1212 static struct batadv_hard_iface * 1213 batadv_netlink_get_hardif_from_ifindex(struct batadv_priv *bat_priv, 1214 struct net *net, int ifindex) 1215 { 1216 struct batadv_hard_iface *hard_iface; 1217 struct net_device *hard_dev; 1218 1219 hard_dev = dev_get_by_index(net, ifindex); 1220 if (!hard_dev) 1221 return ERR_PTR(-ENODEV); 1222 1223 hard_iface = batadv_hardif_get_by_netdev(hard_dev); 1224 if (!hard_iface) 1225 goto err_put_harddev; 1226 1227 if (hard_iface->mesh_iface != bat_priv->mesh_iface) 1228 goto err_put_hardif; 1229 1230 /* hard_dev is referenced by hard_iface and not needed here */ 1231 dev_put(hard_dev); 1232 1233 return hard_iface; 1234 1235 err_put_hardif: 1236 batadv_hardif_put(hard_iface); 1237 err_put_harddev: 1238 dev_put(hard_dev); 1239 1240 return ERR_PTR(-EINVAL); 1241 } 1242 1243 /** 1244 * batadv_netlink_get_hardif_from_info() - Get hard-iface from genl attributes 1245 * @bat_priv: the bat priv with all the mesh interface information 1246 * @net: the applicable net namespace 1247 * @info: receiver information 1248 * 1249 * Return: Pointer to hard interface (with increased refcnt) on success, error 1250 * pointer on error 1251 */ 1252 static struct batadv_hard_iface * 1253 batadv_netlink_get_hardif_from_info(struct batadv_priv *bat_priv, 1254 struct net *net, struct genl_info *info) 1255 { 1256 int ifindex; 1257 1258 if (!info->attrs[BATADV_ATTR_HARD_IFINDEX]) 1259 return ERR_PTR(-EINVAL); 1260 1261 ifindex = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]); 1262 1263 return batadv_netlink_get_hardif_from_ifindex(bat_priv, net, ifindex); 1264 } 1265 1266 /** 1267 * batadv_netlink_get_hardif() - Retrieve hard interface from netlink callback 1268 * @bat_priv: the bat priv with all the mesh interface information 1269 * @cb: callback structure containing arguments 1270 * 1271 * Return: Pointer to hard interface (with increased refcnt) on success, error 1272 * pointer on error 1273 */ 1274 struct batadv_hard_iface * 1275 batadv_netlink_get_hardif(struct batadv_priv *bat_priv, 1276 struct netlink_callback *cb) 1277 { 1278 int ifindex = batadv_netlink_get_ifindex(cb->nlh, 1279 BATADV_ATTR_HARD_IFINDEX); 1280 if (!ifindex) 1281 return ERR_PTR(-ENONET); 1282 1283 return batadv_netlink_get_hardif_from_ifindex(bat_priv, 1284 sock_net(cb->skb->sk), 1285 ifindex); 1286 } 1287 1288 /** 1289 * batadv_get_vlan_from_info() - Retrieve vlan from genl attributes 1290 * @bat_priv: the bat priv with all the mesh interface information 1291 * @net: the applicable net namespace 1292 * @info: receiver information 1293 * 1294 * Return: Pointer to vlan on success (with increased refcnt), error pointer 1295 * on error 1296 */ 1297 static struct batadv_meshif_vlan * 1298 batadv_get_vlan_from_info(struct batadv_priv *bat_priv, struct net *net, 1299 struct genl_info *info) 1300 { 1301 struct batadv_meshif_vlan *vlan; 1302 u16 vid; 1303 1304 if (!info->attrs[BATADV_ATTR_VLANID]) 1305 return ERR_PTR(-EINVAL); 1306 1307 vid = nla_get_u16(info->attrs[BATADV_ATTR_VLANID]); 1308 1309 vlan = batadv_meshif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); 1310 if (!vlan) 1311 return ERR_PTR(-ENOENT); 1312 1313 return vlan; 1314 } 1315 1316 /** 1317 * batadv_pre_doit() - Prepare batman-adv genl doit request 1318 * @ops: requested netlink operation 1319 * @skb: Netlink message with request data 1320 * @info: receiver information 1321 * 1322 * Return: 0 on success or negative error number in case of failure 1323 */ 1324 static int batadv_pre_doit(const struct genl_split_ops *ops, 1325 struct sk_buff *skb, 1326 struct genl_info *info) 1327 { 1328 struct net *net = genl_info_net(info); 1329 struct batadv_hard_iface *hard_iface; 1330 struct batadv_priv *bat_priv = NULL; 1331 struct batadv_meshif_vlan *vlan; 1332 struct net_device *mesh_iface; 1333 u8 user_ptr1_flags; 1334 u8 mesh_dep_flags; 1335 int ret; 1336 1337 user_ptr1_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN; 1338 if (WARN_ON(hweight8(ops->internal_flags & user_ptr1_flags) > 1)) 1339 return -EINVAL; 1340 1341 mesh_dep_flags = BATADV_FLAG_NEED_HARDIF | BATADV_FLAG_NEED_VLAN; 1342 if (WARN_ON((ops->internal_flags & mesh_dep_flags) && 1343 (~ops->internal_flags & BATADV_FLAG_NEED_MESH))) 1344 return -EINVAL; 1345 1346 if (ops->internal_flags & BATADV_FLAG_NEED_MESH) { 1347 mesh_iface = batadv_netlink_get_meshif_from_info(net, info); 1348 if (IS_ERR(mesh_iface)) 1349 return PTR_ERR(mesh_iface); 1350 1351 bat_priv = netdev_priv(mesh_iface); 1352 info->user_ptr[0] = bat_priv; 1353 } 1354 1355 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF) { 1356 hard_iface = batadv_netlink_get_hardif_from_info(bat_priv, net, 1357 info); 1358 if (IS_ERR(hard_iface)) { 1359 ret = PTR_ERR(hard_iface); 1360 goto err_put_meshif; 1361 } 1362 1363 info->user_ptr[1] = hard_iface; 1364 } 1365 1366 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN) { 1367 vlan = batadv_get_vlan_from_info(bat_priv, net, info); 1368 if (IS_ERR(vlan)) { 1369 ret = PTR_ERR(vlan); 1370 goto err_put_meshif; 1371 } 1372 1373 info->user_ptr[1] = vlan; 1374 } 1375 1376 return 0; 1377 1378 err_put_meshif: 1379 if (bat_priv) 1380 dev_put(bat_priv->mesh_iface); 1381 1382 return ret; 1383 } 1384 1385 /** 1386 * batadv_post_doit() - End batman-adv genl doit request 1387 * @ops: requested netlink operation 1388 * @skb: Netlink message with request data 1389 * @info: receiver information 1390 */ 1391 static void batadv_post_doit(const struct genl_split_ops *ops, 1392 struct sk_buff *skb, 1393 struct genl_info *info) 1394 { 1395 struct batadv_hard_iface *hard_iface; 1396 struct batadv_meshif_vlan *vlan; 1397 struct batadv_priv *bat_priv; 1398 1399 if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF && 1400 info->user_ptr[1]) { 1401 hard_iface = info->user_ptr[1]; 1402 1403 batadv_hardif_put(hard_iface); 1404 } 1405 1406 if (ops->internal_flags & BATADV_FLAG_NEED_VLAN && info->user_ptr[1]) { 1407 vlan = info->user_ptr[1]; 1408 batadv_meshif_vlan_put(vlan); 1409 } 1410 1411 if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) { 1412 bat_priv = info->user_ptr[0]; 1413 dev_put(bat_priv->mesh_iface); 1414 } 1415 } 1416 1417 static const struct genl_small_ops batadv_netlink_ops[] = { 1418 { 1419 .cmd = BATADV_CMD_GET_MESH, 1420 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1421 /* can be retrieved by unprivileged users */ 1422 .doit = batadv_netlink_get_mesh, 1423 .internal_flags = BATADV_FLAG_NEED_MESH, 1424 }, 1425 { 1426 .cmd = BATADV_CMD_TP_METER, 1427 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1428 .flags = GENL_UNS_ADMIN_PERM, 1429 .doit = batadv_netlink_tp_meter_start, 1430 .internal_flags = BATADV_FLAG_NEED_MESH, 1431 }, 1432 { 1433 .cmd = BATADV_CMD_TP_METER_CANCEL, 1434 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1435 .flags = GENL_UNS_ADMIN_PERM, 1436 .doit = batadv_netlink_tp_meter_cancel, 1437 .internal_flags = BATADV_FLAG_NEED_MESH, 1438 }, 1439 { 1440 .cmd = BATADV_CMD_GET_ROUTING_ALGOS, 1441 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1442 .flags = GENL_UNS_ADMIN_PERM, 1443 .dumpit = batadv_algo_dump, 1444 }, 1445 { 1446 .cmd = BATADV_CMD_GET_HARDIF, 1447 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1448 /* can be retrieved by unprivileged users */ 1449 .dumpit = batadv_netlink_dump_hardif, 1450 .doit = batadv_netlink_cmd_get_hardif, 1451 .internal_flags = BATADV_FLAG_NEED_MESH | 1452 BATADV_FLAG_NEED_HARDIF, 1453 }, 1454 { 1455 .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL, 1456 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1457 .flags = GENL_UNS_ADMIN_PERM, 1458 .dumpit = batadv_tt_local_dump, 1459 }, 1460 { 1461 .cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL, 1462 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1463 .flags = GENL_UNS_ADMIN_PERM, 1464 .dumpit = batadv_tt_global_dump, 1465 }, 1466 { 1467 .cmd = BATADV_CMD_GET_ORIGINATORS, 1468 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1469 .flags = GENL_UNS_ADMIN_PERM, 1470 .dumpit = batadv_orig_dump, 1471 }, 1472 { 1473 .cmd = BATADV_CMD_GET_NEIGHBORS, 1474 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1475 .flags = GENL_UNS_ADMIN_PERM, 1476 .dumpit = batadv_hardif_neigh_dump, 1477 }, 1478 { 1479 .cmd = BATADV_CMD_GET_GATEWAYS, 1480 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1481 .flags = GENL_UNS_ADMIN_PERM, 1482 .dumpit = batadv_gw_dump, 1483 }, 1484 { 1485 .cmd = BATADV_CMD_GET_BLA_CLAIM, 1486 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1487 .flags = GENL_UNS_ADMIN_PERM, 1488 .dumpit = batadv_bla_claim_dump, 1489 }, 1490 { 1491 .cmd = BATADV_CMD_GET_BLA_BACKBONE, 1492 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1493 .flags = GENL_UNS_ADMIN_PERM, 1494 .dumpit = batadv_bla_backbone_dump, 1495 }, 1496 { 1497 .cmd = BATADV_CMD_GET_DAT_CACHE, 1498 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1499 .flags = GENL_UNS_ADMIN_PERM, 1500 .dumpit = batadv_dat_cache_dump, 1501 }, 1502 { 1503 .cmd = BATADV_CMD_GET_MCAST_FLAGS, 1504 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1505 .flags = GENL_UNS_ADMIN_PERM, 1506 .dumpit = batadv_mcast_flags_dump, 1507 }, 1508 { 1509 .cmd = BATADV_CMD_SET_MESH, 1510 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1511 .flags = GENL_UNS_ADMIN_PERM, 1512 .doit = batadv_netlink_set_mesh, 1513 .internal_flags = BATADV_FLAG_NEED_MESH, 1514 }, 1515 { 1516 .cmd = BATADV_CMD_SET_HARDIF, 1517 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1518 .flags = GENL_UNS_ADMIN_PERM, 1519 .doit = batadv_netlink_set_hardif, 1520 .internal_flags = BATADV_FLAG_NEED_MESH | 1521 BATADV_FLAG_NEED_HARDIF, 1522 }, 1523 { 1524 .cmd = BATADV_CMD_GET_VLAN, 1525 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1526 /* can be retrieved by unprivileged users */ 1527 .doit = batadv_netlink_get_vlan, 1528 .internal_flags = BATADV_FLAG_NEED_MESH | 1529 BATADV_FLAG_NEED_VLAN, 1530 }, 1531 { 1532 .cmd = BATADV_CMD_SET_VLAN, 1533 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1534 .flags = GENL_UNS_ADMIN_PERM, 1535 .doit = batadv_netlink_set_vlan, 1536 .internal_flags = BATADV_FLAG_NEED_MESH | 1537 BATADV_FLAG_NEED_VLAN, 1538 }, 1539 }; 1540 1541 struct genl_family batadv_netlink_family __ro_after_init = { 1542 .hdrsize = 0, 1543 .name = BATADV_NL_NAME, 1544 .version = 1, 1545 .maxattr = BATADV_ATTR_MAX, 1546 .policy = batadv_netlink_policy, 1547 .netnsok = true, 1548 .pre_doit = batadv_pre_doit, 1549 .post_doit = batadv_post_doit, 1550 .module = THIS_MODULE, 1551 .small_ops = batadv_netlink_ops, 1552 .n_small_ops = ARRAY_SIZE(batadv_netlink_ops), 1553 .resv_start_op = BATADV_CMD_SET_VLAN + 1, 1554 .mcgrps = batadv_netlink_mcgrps, 1555 .n_mcgrps = ARRAY_SIZE(batadv_netlink_mcgrps), 1556 }; 1557 1558 /** 1559 * batadv_netlink_register() - register batadv genl netlink family 1560 */ 1561 void __init batadv_netlink_register(void) 1562 { 1563 int ret; 1564 1565 ret = genl_register_family(&batadv_netlink_family); 1566 if (ret) 1567 pr_warn("unable to register netlink family\n"); 1568 } 1569 1570 /** 1571 * batadv_netlink_unregister() - unregister batadv genl netlink family 1572 */ 1573 void batadv_netlink_unregister(void) 1574 { 1575 genl_unregister_family(&batadv_netlink_family); 1576 } 1577