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