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