at v5.2 501 lines 14 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (C) 2010-2019 B.A.T.M.A.N. contributors: 3 * 4 * Marek Lindner 5 */ 6 7#include "debugfs.h" 8#include "main.h" 9 10#include <asm/current.h> 11#include <linux/dcache.h> 12#include <linux/debugfs.h> 13#include <linux/err.h> 14#include <linux/errno.h> 15#include <linux/export.h> 16#include <linux/fs.h> 17#include <linux/netdevice.h> 18#include <linux/printk.h> 19#include <linux/sched.h> 20#include <linux/seq_file.h> 21#include <linux/stat.h> 22#include <linux/stddef.h> 23#include <linux/stringify.h> 24#include <linux/sysfs.h> 25#include <net/net_namespace.h> 26 27#include "bat_algo.h" 28#include "bridge_loop_avoidance.h" 29#include "distributed-arp-table.h" 30#include "gateway_client.h" 31#include "icmp_socket.h" 32#include "log.h" 33#include "multicast.h" 34#include "network-coding.h" 35#include "originator.h" 36#include "translation-table.h" 37 38static struct dentry *batadv_debugfs; 39 40/** 41 * batadv_debugfs_deprecated() - Log use of deprecated batadv debugfs access 42 * @file: file which was accessed 43 * @alt: explanation what can be used as alternative 44 */ 45void batadv_debugfs_deprecated(struct file *file, const char *alt) 46{ 47 struct dentry *dentry = file_dentry(file); 48 const char *name = dentry->d_name.name; 49 50 pr_warn_ratelimited(DEPRECATED "%s (pid %d) Use of debugfs file \"%s\".\n%s", 51 current->comm, task_pid_nr(current), name, alt); 52} 53 54static int batadv_algorithms_open(struct inode *inode, struct file *file) 55{ 56 batadv_debugfs_deprecated(file, 57 "Use genl command BATADV_CMD_GET_ROUTING_ALGOS instead\n"); 58 return single_open(file, batadv_algo_seq_print_text, NULL); 59} 60 61static int neighbors_open(struct inode *inode, struct file *file) 62{ 63 struct net_device *net_dev = (struct net_device *)inode->i_private; 64 65 batadv_debugfs_deprecated(file, 66 "Use genl command BATADV_CMD_GET_NEIGHBORS instead\n"); 67 return single_open(file, batadv_hardif_neigh_seq_print_text, net_dev); 68} 69 70static int batadv_originators_open(struct inode *inode, struct file *file) 71{ 72 struct net_device *net_dev = (struct net_device *)inode->i_private; 73 74 batadv_debugfs_deprecated(file, 75 "Use genl command BATADV_CMD_GET_ORIGINATORS instead\n"); 76 return single_open(file, batadv_orig_seq_print_text, net_dev); 77} 78 79/** 80 * batadv_originators_hardif_open() - handles debugfs output for the originator 81 * table of an hard interface 82 * @inode: inode pointer to debugfs file 83 * @file: pointer to the seq_file 84 * 85 * Return: 0 on success or negative error number in case of failure 86 */ 87static int batadv_originators_hardif_open(struct inode *inode, 88 struct file *file) 89{ 90 struct net_device *net_dev = (struct net_device *)inode->i_private; 91 92 batadv_debugfs_deprecated(file, 93 "Use genl command BATADV_CMD_GET_HARDIFS instead\n"); 94 return single_open(file, batadv_orig_hardif_seq_print_text, net_dev); 95} 96 97static int batadv_gateways_open(struct inode *inode, struct file *file) 98{ 99 struct net_device *net_dev = (struct net_device *)inode->i_private; 100 101 batadv_debugfs_deprecated(file, 102 "Use genl command BATADV_CMD_GET_GATEWAYS instead\n"); 103 return single_open(file, batadv_gw_client_seq_print_text, net_dev); 104} 105 106static int batadv_transtable_global_open(struct inode *inode, struct file *file) 107{ 108 struct net_device *net_dev = (struct net_device *)inode->i_private; 109 110 batadv_debugfs_deprecated(file, 111 "Use genl command BATADV_CMD_GET_TRANSTABLE_GLOBAL instead\n"); 112 return single_open(file, batadv_tt_global_seq_print_text, net_dev); 113} 114 115#ifdef CONFIG_BATMAN_ADV_BLA 116static int batadv_bla_claim_table_open(struct inode *inode, struct file *file) 117{ 118 struct net_device *net_dev = (struct net_device *)inode->i_private; 119 120 batadv_debugfs_deprecated(file, 121 "Use genl command BATADV_CMD_GET_BLA_CLAIM instead\n"); 122 return single_open(file, batadv_bla_claim_table_seq_print_text, 123 net_dev); 124} 125 126static int batadv_bla_backbone_table_open(struct inode *inode, 127 struct file *file) 128{ 129 struct net_device *net_dev = (struct net_device *)inode->i_private; 130 131 batadv_debugfs_deprecated(file, 132 "Use genl command BATADV_CMD_GET_BLA_BACKBONE instead\n"); 133 return single_open(file, batadv_bla_backbone_table_seq_print_text, 134 net_dev); 135} 136 137#endif 138 139#ifdef CONFIG_BATMAN_ADV_DAT 140/** 141 * batadv_dat_cache_open() - Prepare file handler for reads from dat_cache 142 * @inode: inode which was opened 143 * @file: file handle to be initialized 144 * 145 * Return: 0 on success or negative error number in case of failure 146 */ 147static int batadv_dat_cache_open(struct inode *inode, struct file *file) 148{ 149 struct net_device *net_dev = (struct net_device *)inode->i_private; 150 151 batadv_debugfs_deprecated(file, 152 "Use genl command BATADV_CMD_GET_DAT_CACHE instead\n"); 153 return single_open(file, batadv_dat_cache_seq_print_text, net_dev); 154} 155#endif 156 157static int batadv_transtable_local_open(struct inode *inode, struct file *file) 158{ 159 struct net_device *net_dev = (struct net_device *)inode->i_private; 160 161 batadv_debugfs_deprecated(file, 162 "Use genl command BATADV_CMD_GET_TRANSTABLE_LOCAL instead\n"); 163 return single_open(file, batadv_tt_local_seq_print_text, net_dev); 164} 165 166struct batadv_debuginfo { 167 struct attribute attr; 168 const struct file_operations fops; 169}; 170 171#ifdef CONFIG_BATMAN_ADV_NC 172static int batadv_nc_nodes_open(struct inode *inode, struct file *file) 173{ 174 struct net_device *net_dev = (struct net_device *)inode->i_private; 175 176 batadv_debugfs_deprecated(file, ""); 177 return single_open(file, batadv_nc_nodes_seq_print_text, net_dev); 178} 179#endif 180 181#ifdef CONFIG_BATMAN_ADV_MCAST 182/** 183 * batadv_mcast_flags_open() - prepare file handler for reads from mcast_flags 184 * @inode: inode which was opened 185 * @file: file handle to be initialized 186 * 187 * Return: 0 on success or negative error number in case of failure 188 */ 189static int batadv_mcast_flags_open(struct inode *inode, struct file *file) 190{ 191 struct net_device *net_dev = (struct net_device *)inode->i_private; 192 193 batadv_debugfs_deprecated(file, 194 "Use genl command BATADV_CMD_GET_MCAST_FLAGS instead\n"); 195 return single_open(file, batadv_mcast_flags_seq_print_text, net_dev); 196} 197#endif 198 199#define BATADV_DEBUGINFO(_name, _mode, _open) \ 200struct batadv_debuginfo batadv_debuginfo_##_name = { \ 201 .attr = { \ 202 .name = __stringify(_name), \ 203 .mode = _mode, \ 204 }, \ 205 .fops = { \ 206 .owner = THIS_MODULE, \ 207 .open = _open, \ 208 .read = seq_read, \ 209 .llseek = seq_lseek, \ 210 .release = single_release, \ 211 }, \ 212} 213 214/* the following attributes are general and therefore they will be directly 215 * placed in the BATADV_DEBUGFS_SUBDIR subdirectory of debugfs 216 */ 217static BATADV_DEBUGINFO(routing_algos, 0444, batadv_algorithms_open); 218 219static struct batadv_debuginfo *batadv_general_debuginfos[] = { 220 &batadv_debuginfo_routing_algos, 221 NULL, 222}; 223 224/* The following attributes are per soft interface */ 225static BATADV_DEBUGINFO(neighbors, 0444, neighbors_open); 226static BATADV_DEBUGINFO(originators, 0444, batadv_originators_open); 227static BATADV_DEBUGINFO(gateways, 0444, batadv_gateways_open); 228static BATADV_DEBUGINFO(transtable_global, 0444, batadv_transtable_global_open); 229#ifdef CONFIG_BATMAN_ADV_BLA 230static BATADV_DEBUGINFO(bla_claim_table, 0444, batadv_bla_claim_table_open); 231static BATADV_DEBUGINFO(bla_backbone_table, 0444, 232 batadv_bla_backbone_table_open); 233#endif 234#ifdef CONFIG_BATMAN_ADV_DAT 235static BATADV_DEBUGINFO(dat_cache, 0444, batadv_dat_cache_open); 236#endif 237static BATADV_DEBUGINFO(transtable_local, 0444, batadv_transtable_local_open); 238#ifdef CONFIG_BATMAN_ADV_NC 239static BATADV_DEBUGINFO(nc_nodes, 0444, batadv_nc_nodes_open); 240#endif 241#ifdef CONFIG_BATMAN_ADV_MCAST 242static BATADV_DEBUGINFO(mcast_flags, 0444, batadv_mcast_flags_open); 243#endif 244 245static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { 246 &batadv_debuginfo_neighbors, 247 &batadv_debuginfo_originators, 248 &batadv_debuginfo_gateways, 249 &batadv_debuginfo_transtable_global, 250#ifdef CONFIG_BATMAN_ADV_BLA 251 &batadv_debuginfo_bla_claim_table, 252 &batadv_debuginfo_bla_backbone_table, 253#endif 254#ifdef CONFIG_BATMAN_ADV_DAT 255 &batadv_debuginfo_dat_cache, 256#endif 257 &batadv_debuginfo_transtable_local, 258#ifdef CONFIG_BATMAN_ADV_NC 259 &batadv_debuginfo_nc_nodes, 260#endif 261#ifdef CONFIG_BATMAN_ADV_MCAST 262 &batadv_debuginfo_mcast_flags, 263#endif 264 NULL, 265}; 266 267#define BATADV_HARDIF_DEBUGINFO(_name, _mode, _open) \ 268struct batadv_debuginfo batadv_hardif_debuginfo_##_name = { \ 269 .attr = { \ 270 .name = __stringify(_name), \ 271 .mode = _mode, \ 272 }, \ 273 .fops = { \ 274 .owner = THIS_MODULE, \ 275 .open = _open, \ 276 .read = seq_read, \ 277 .llseek = seq_lseek, \ 278 .release = single_release, \ 279 }, \ 280} 281 282static BATADV_HARDIF_DEBUGINFO(originators, 0444, 283 batadv_originators_hardif_open); 284 285static struct batadv_debuginfo *batadv_hardif_debuginfos[] = { 286 &batadv_hardif_debuginfo_originators, 287 NULL, 288}; 289 290/** 291 * batadv_debugfs_init() - Initialize soft interface independent debugfs entries 292 */ 293void batadv_debugfs_init(void) 294{ 295 struct batadv_debuginfo **bat_debug; 296 struct dentry *file; 297 298 batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL); 299 if (batadv_debugfs == ERR_PTR(-ENODEV)) 300 batadv_debugfs = NULL; 301 302 if (!batadv_debugfs) 303 goto err; 304 305 for (bat_debug = batadv_general_debuginfos; *bat_debug; ++bat_debug) { 306 file = debugfs_create_file(((*bat_debug)->attr).name, 307 S_IFREG | ((*bat_debug)->attr).mode, 308 batadv_debugfs, NULL, 309 &(*bat_debug)->fops); 310 if (!file) { 311 pr_err("Can't add general debugfs file: %s\n", 312 ((*bat_debug)->attr).name); 313 goto err; 314 } 315 } 316 317 return; 318err: 319 debugfs_remove_recursive(batadv_debugfs); 320 batadv_debugfs = NULL; 321} 322 323/** 324 * batadv_debugfs_destroy() - Remove all debugfs entries 325 */ 326void batadv_debugfs_destroy(void) 327{ 328 debugfs_remove_recursive(batadv_debugfs); 329 batadv_debugfs = NULL; 330} 331 332/** 333 * batadv_debugfs_add_hardif() - creates the base directory for a hard interface 334 * in debugfs. 335 * @hard_iface: hard interface which should be added. 336 * 337 * Return: 0 on success or negative error number in case of failure 338 */ 339int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface) 340{ 341 struct net *net = dev_net(hard_iface->net_dev); 342 struct batadv_debuginfo **bat_debug; 343 struct dentry *file; 344 345 if (!batadv_debugfs) 346 goto out; 347 348 if (net != &init_net) 349 return 0; 350 351 hard_iface->debug_dir = debugfs_create_dir(hard_iface->net_dev->name, 352 batadv_debugfs); 353 if (!hard_iface->debug_dir) 354 goto out; 355 356 for (bat_debug = batadv_hardif_debuginfos; *bat_debug; ++bat_debug) { 357 file = debugfs_create_file(((*bat_debug)->attr).name, 358 S_IFREG | ((*bat_debug)->attr).mode, 359 hard_iface->debug_dir, 360 hard_iface->net_dev, 361 &(*bat_debug)->fops); 362 if (!file) 363 goto rem_attr; 364 } 365 366 return 0; 367rem_attr: 368 debugfs_remove_recursive(hard_iface->debug_dir); 369 hard_iface->debug_dir = NULL; 370out: 371 return -ENOMEM; 372} 373 374/** 375 * batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif 376 * @hard_iface: hard interface which was renamed 377 */ 378void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface) 379{ 380 const char *name = hard_iface->net_dev->name; 381 struct dentry *dir; 382 struct dentry *d; 383 384 dir = hard_iface->debug_dir; 385 if (!dir) 386 return; 387 388 d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); 389 if (!d) 390 pr_err("Can't rename debugfs dir to %s\n", name); 391} 392 393/** 394 * batadv_debugfs_del_hardif() - delete the base directory for a hard interface 395 * in debugfs. 396 * @hard_iface: hard interface which is deleted. 397 */ 398void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface) 399{ 400 struct net *net = dev_net(hard_iface->net_dev); 401 402 if (net != &init_net) 403 return; 404 405 if (batadv_debugfs) { 406 debugfs_remove_recursive(hard_iface->debug_dir); 407 hard_iface->debug_dir = NULL; 408 } 409} 410 411/** 412 * batadv_debugfs_add_meshif() - Initialize interface dependent debugfs entries 413 * @dev: netdev struct of the soft interface 414 * 415 * Return: 0 on success or negative error number in case of failure 416 */ 417int batadv_debugfs_add_meshif(struct net_device *dev) 418{ 419 struct batadv_priv *bat_priv = netdev_priv(dev); 420 struct batadv_debuginfo **bat_debug; 421 struct net *net = dev_net(dev); 422 struct dentry *file; 423 424 if (!batadv_debugfs) 425 goto out; 426 427 if (net != &init_net) 428 return 0; 429 430 bat_priv->debug_dir = debugfs_create_dir(dev->name, batadv_debugfs); 431 if (!bat_priv->debug_dir) 432 goto out; 433 434 if (batadv_socket_setup(bat_priv) < 0) 435 goto rem_attr; 436 437 if (batadv_debug_log_setup(bat_priv) < 0) 438 goto rem_attr; 439 440 for (bat_debug = batadv_mesh_debuginfos; *bat_debug; ++bat_debug) { 441 file = debugfs_create_file(((*bat_debug)->attr).name, 442 S_IFREG | ((*bat_debug)->attr).mode, 443 bat_priv->debug_dir, 444 dev, &(*bat_debug)->fops); 445 if (!file) { 446 batadv_err(dev, "Can't add debugfs file: %s/%s\n", 447 dev->name, ((*bat_debug)->attr).name); 448 goto rem_attr; 449 } 450 } 451 452 if (batadv_nc_init_debugfs(bat_priv) < 0) 453 goto rem_attr; 454 455 return 0; 456rem_attr: 457 debugfs_remove_recursive(bat_priv->debug_dir); 458 bat_priv->debug_dir = NULL; 459out: 460 return -ENOMEM; 461} 462 463/** 464 * batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif 465 * @dev: net_device which was renamed 466 */ 467void batadv_debugfs_rename_meshif(struct net_device *dev) 468{ 469 struct batadv_priv *bat_priv = netdev_priv(dev); 470 const char *name = dev->name; 471 struct dentry *dir; 472 struct dentry *d; 473 474 dir = bat_priv->debug_dir; 475 if (!dir) 476 return; 477 478 d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); 479 if (!d) 480 pr_err("Can't rename debugfs dir to %s\n", name); 481} 482 483/** 484 * batadv_debugfs_del_meshif() - Remove interface dependent debugfs entries 485 * @dev: netdev struct of the soft interface 486 */ 487void batadv_debugfs_del_meshif(struct net_device *dev) 488{ 489 struct batadv_priv *bat_priv = netdev_priv(dev); 490 struct net *net = dev_net(dev); 491 492 if (net != &init_net) 493 return; 494 495 batadv_debug_log_cleanup(bat_priv); 496 497 if (batadv_debugfs) { 498 debugfs_remove_recursive(bat_priv->debug_dir); 499 bat_priv->debug_dir = NULL; 500 } 501}