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