1/* Copyright (C) 2010-2014 B.A.T.M.A.N. contributors: 2 * 3 * Marek Lindner 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include "main.h" 19 20#include <linux/debugfs.h> 21 22#include "debugfs.h" 23#include "translation-table.h" 24#include "originator.h" 25#include "hard-interface.h" 26#include "gateway_common.h" 27#include "gateway_client.h" 28#include "soft-interface.h" 29#include "icmp_socket.h" 30#include "bridge_loop_avoidance.h" 31#include "distributed-arp-table.h" 32#include "network-coding.h" 33 34static struct dentry *batadv_debugfs; 35 36#ifdef CONFIG_BATMAN_ADV_DEBUG 37#define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1) 38 39static const int batadv_log_buff_len = BATADV_LOG_BUF_LEN; 40 41static char *batadv_log_char_addr(struct batadv_priv_debug_log *debug_log, 42 size_t idx) 43{ 44 return &debug_log->log_buff[idx & BATADV_LOG_BUFF_MASK]; 45} 46 47static void batadv_emit_log_char(struct batadv_priv_debug_log *debug_log, 48 char c) 49{ 50 char *char_addr; 51 52 char_addr = batadv_log_char_addr(debug_log, debug_log->log_end); 53 *char_addr = c; 54 debug_log->log_end++; 55 56 if (debug_log->log_end - debug_log->log_start > batadv_log_buff_len) 57 debug_log->log_start = debug_log->log_end - batadv_log_buff_len; 58} 59 60__printf(2, 3) 61static int batadv_fdebug_log(struct batadv_priv_debug_log *debug_log, 62 const char *fmt, ...) 63{ 64 va_list args; 65 static char debug_log_buf[256]; 66 char *p; 67 68 if (!debug_log) 69 return 0; 70 71 spin_lock_bh(&debug_log->lock); 72 va_start(args, fmt); 73 vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt, args); 74 va_end(args); 75 76 for (p = debug_log_buf; *p != 0; p++) 77 batadv_emit_log_char(debug_log, *p); 78 79 spin_unlock_bh(&debug_log->lock); 80 81 wake_up(&debug_log->queue_wait); 82 83 return 0; 84} 85 86int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) 87{ 88 va_list args; 89 char tmp_log_buf[256]; 90 91 va_start(args, fmt); 92 vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); 93 batadv_fdebug_log(bat_priv->debug_log, "[%10u] %s", 94 jiffies_to_msecs(jiffies), tmp_log_buf); 95 va_end(args); 96 97 return 0; 98} 99 100static int batadv_log_open(struct inode *inode, struct file *file) 101{ 102 if (!try_module_get(THIS_MODULE)) 103 return -EBUSY; 104 105 nonseekable_open(inode, file); 106 file->private_data = inode->i_private; 107 return 0; 108} 109 110static int batadv_log_release(struct inode *inode, struct file *file) 111{ 112 module_put(THIS_MODULE); 113 return 0; 114} 115 116static int batadv_log_empty(struct batadv_priv_debug_log *debug_log) 117{ 118 return !(debug_log->log_start - debug_log->log_end); 119} 120 121static ssize_t batadv_log_read(struct file *file, char __user *buf, 122 size_t count, loff_t *ppos) 123{ 124 struct batadv_priv *bat_priv = file->private_data; 125 struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; 126 int error, i = 0; 127 char *char_addr; 128 char c; 129 130 if ((file->f_flags & O_NONBLOCK) && batadv_log_empty(debug_log)) 131 return -EAGAIN; 132 133 if (!buf) 134 return -EINVAL; 135 136 if (count == 0) 137 return 0; 138 139 if (!access_ok(VERIFY_WRITE, buf, count)) 140 return -EFAULT; 141 142 error = wait_event_interruptible(debug_log->queue_wait, 143 (!batadv_log_empty(debug_log))); 144 145 if (error) 146 return error; 147 148 spin_lock_bh(&debug_log->lock); 149 150 while ((!error) && (i < count) && 151 (debug_log->log_start != debug_log->log_end)) { 152 char_addr = batadv_log_char_addr(debug_log, 153 debug_log->log_start); 154 c = *char_addr; 155 156 debug_log->log_start++; 157 158 spin_unlock_bh(&debug_log->lock); 159 160 error = __put_user(c, buf); 161 162 spin_lock_bh(&debug_log->lock); 163 164 buf++; 165 i++; 166 } 167 168 spin_unlock_bh(&debug_log->lock); 169 170 if (!error) 171 return i; 172 173 return error; 174} 175 176static unsigned int batadv_log_poll(struct file *file, poll_table *wait) 177{ 178 struct batadv_priv *bat_priv = file->private_data; 179 struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; 180 181 poll_wait(file, &debug_log->queue_wait, wait); 182 183 if (!batadv_log_empty(debug_log)) 184 return POLLIN | POLLRDNORM; 185 186 return 0; 187} 188 189static const struct file_operations batadv_log_fops = { 190 .open = batadv_log_open, 191 .release = batadv_log_release, 192 .read = batadv_log_read, 193 .poll = batadv_log_poll, 194 .llseek = no_llseek, 195}; 196 197static int batadv_debug_log_setup(struct batadv_priv *bat_priv) 198{ 199 struct dentry *d; 200 201 if (!bat_priv->debug_dir) 202 goto err; 203 204 bat_priv->debug_log = kzalloc(sizeof(*bat_priv->debug_log), GFP_ATOMIC); 205 if (!bat_priv->debug_log) 206 goto err; 207 208 spin_lock_init(&bat_priv->debug_log->lock); 209 init_waitqueue_head(&bat_priv->debug_log->queue_wait); 210 211 d = debugfs_create_file("log", S_IFREG | S_IRUSR, 212 bat_priv->debug_dir, bat_priv, 213 &batadv_log_fops); 214 if (!d) 215 goto err; 216 217 return 0; 218 219err: 220 return -ENOMEM; 221} 222 223static void batadv_debug_log_cleanup(struct batadv_priv *bat_priv) 224{ 225 kfree(bat_priv->debug_log); 226 bat_priv->debug_log = NULL; 227} 228#else /* CONFIG_BATMAN_ADV_DEBUG */ 229static int batadv_debug_log_setup(struct batadv_priv *bat_priv) 230{ 231 return 0; 232} 233 234static void batadv_debug_log_cleanup(struct batadv_priv *bat_priv) 235{ 236} 237#endif 238 239static int batadv_algorithms_open(struct inode *inode, struct file *file) 240{ 241 return single_open(file, batadv_algo_seq_print_text, NULL); 242} 243 244static int batadv_originators_open(struct inode *inode, struct file *file) 245{ 246 struct net_device *net_dev = (struct net_device *)inode->i_private; 247 248 return single_open(file, batadv_orig_seq_print_text, net_dev); 249} 250 251/** 252 * batadv_originators_hardif_open - handles debugfs output for the 253 * originator table of an hard interface 254 * @inode: inode pointer to debugfs file 255 * @file: pointer to the seq_file 256 */ 257static int batadv_originators_hardif_open(struct inode *inode, 258 struct file *file) 259{ 260 struct net_device *net_dev = (struct net_device *)inode->i_private; 261 262 return single_open(file, batadv_orig_hardif_seq_print_text, net_dev); 263} 264 265static int batadv_gateways_open(struct inode *inode, struct file *file) 266{ 267 struct net_device *net_dev = (struct net_device *)inode->i_private; 268 269 return single_open(file, batadv_gw_client_seq_print_text, net_dev); 270} 271 272static int batadv_transtable_global_open(struct inode *inode, struct file *file) 273{ 274 struct net_device *net_dev = (struct net_device *)inode->i_private; 275 276 return single_open(file, batadv_tt_global_seq_print_text, net_dev); 277} 278 279#ifdef CONFIG_BATMAN_ADV_BLA 280static int batadv_bla_claim_table_open(struct inode *inode, struct file *file) 281{ 282 struct net_device *net_dev = (struct net_device *)inode->i_private; 283 284 return single_open(file, batadv_bla_claim_table_seq_print_text, 285 net_dev); 286} 287 288static int batadv_bla_backbone_table_open(struct inode *inode, 289 struct file *file) 290{ 291 struct net_device *net_dev = (struct net_device *)inode->i_private; 292 293 return single_open(file, batadv_bla_backbone_table_seq_print_text, 294 net_dev); 295} 296 297#endif 298 299#ifdef CONFIG_BATMAN_ADV_DAT 300/** 301 * batadv_dat_cache_open - Prepare file handler for reads from dat_chache 302 * @inode: inode which was opened 303 * @file: file handle to be initialized 304 */ 305static int batadv_dat_cache_open(struct inode *inode, struct file *file) 306{ 307 struct net_device *net_dev = (struct net_device *)inode->i_private; 308 309 return single_open(file, batadv_dat_cache_seq_print_text, net_dev); 310} 311#endif 312 313static int batadv_transtable_local_open(struct inode *inode, struct file *file) 314{ 315 struct net_device *net_dev = (struct net_device *)inode->i_private; 316 317 return single_open(file, batadv_tt_local_seq_print_text, net_dev); 318} 319 320struct batadv_debuginfo { 321 struct attribute attr; 322 const struct file_operations fops; 323}; 324 325#ifdef CONFIG_BATMAN_ADV_NC 326static int batadv_nc_nodes_open(struct inode *inode, struct file *file) 327{ 328 struct net_device *net_dev = (struct net_device *)inode->i_private; 329 330 return single_open(file, batadv_nc_nodes_seq_print_text, net_dev); 331} 332#endif 333 334#define BATADV_DEBUGINFO(_name, _mode, _open) \ 335struct batadv_debuginfo batadv_debuginfo_##_name = { \ 336 .attr = { .name = __stringify(_name), \ 337 .mode = _mode, }, \ 338 .fops = { .owner = THIS_MODULE, \ 339 .open = _open, \ 340 .read = seq_read, \ 341 .llseek = seq_lseek, \ 342 .release = single_release, \ 343 } \ 344} 345 346/* the following attributes are general and therefore they will be directly 347 * placed in the BATADV_DEBUGFS_SUBDIR subdirectory of debugfs 348 */ 349static BATADV_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open); 350 351static struct batadv_debuginfo *batadv_general_debuginfos[] = { 352 &batadv_debuginfo_routing_algos, 353 NULL, 354}; 355 356/* The following attributes are per soft interface */ 357static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open); 358static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open); 359static BATADV_DEBUGINFO(transtable_global, S_IRUGO, 360 batadv_transtable_global_open); 361#ifdef CONFIG_BATMAN_ADV_BLA 362static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); 363static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO, 364 batadv_bla_backbone_table_open); 365#endif 366#ifdef CONFIG_BATMAN_ADV_DAT 367static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open); 368#endif 369static BATADV_DEBUGINFO(transtable_local, S_IRUGO, 370 batadv_transtable_local_open); 371#ifdef CONFIG_BATMAN_ADV_NC 372static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open); 373#endif 374 375static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { 376 &batadv_debuginfo_originators, 377 &batadv_debuginfo_gateways, 378 &batadv_debuginfo_transtable_global, 379#ifdef CONFIG_BATMAN_ADV_BLA 380 &batadv_debuginfo_bla_claim_table, 381 &batadv_debuginfo_bla_backbone_table, 382#endif 383#ifdef CONFIG_BATMAN_ADV_DAT 384 &batadv_debuginfo_dat_cache, 385#endif 386 &batadv_debuginfo_transtable_local, 387#ifdef CONFIG_BATMAN_ADV_NC 388 &batadv_debuginfo_nc_nodes, 389#endif 390 NULL, 391}; 392 393#define BATADV_HARDIF_DEBUGINFO(_name, _mode, _open) \ 394struct batadv_debuginfo batadv_hardif_debuginfo_##_name = { \ 395 .attr = { \ 396 .name = __stringify(_name), \ 397 .mode = _mode, \ 398 }, \ 399 .fops = { \ 400 .owner = THIS_MODULE, \ 401 .open = _open, \ 402 .read = seq_read, \ 403 .llseek = seq_lseek, \ 404 .release = single_release, \ 405 }, \ 406} 407 408static BATADV_HARDIF_DEBUGINFO(originators, S_IRUGO, 409 batadv_originators_hardif_open); 410 411static struct batadv_debuginfo *batadv_hardif_debuginfos[] = { 412 &batadv_hardif_debuginfo_originators, 413 NULL, 414}; 415 416void batadv_debugfs_init(void) 417{ 418 struct batadv_debuginfo **bat_debug; 419 struct dentry *file; 420 421 batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL); 422 if (batadv_debugfs == ERR_PTR(-ENODEV)) 423 batadv_debugfs = NULL; 424 425 if (!batadv_debugfs) 426 goto err; 427 428 for (bat_debug = batadv_general_debuginfos; *bat_debug; ++bat_debug) { 429 file = debugfs_create_file(((*bat_debug)->attr).name, 430 S_IFREG | ((*bat_debug)->attr).mode, 431 batadv_debugfs, NULL, 432 &(*bat_debug)->fops); 433 if (!file) { 434 pr_err("Can't add general debugfs file: %s\n", 435 ((*bat_debug)->attr).name); 436 goto err; 437 } 438 } 439 440 return; 441err: 442 debugfs_remove_recursive(batadv_debugfs); 443 batadv_debugfs = NULL; 444} 445 446void batadv_debugfs_destroy(void) 447{ 448 debugfs_remove_recursive(batadv_debugfs); 449 batadv_debugfs = NULL; 450} 451 452/** 453 * batadv_debugfs_add_hardif - creates the base directory for a hard interface 454 * in debugfs. 455 * @hard_iface: hard interface which should be added. 456 */ 457int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface) 458{ 459 struct batadv_debuginfo **bat_debug; 460 struct dentry *file; 461 462 if (!batadv_debugfs) 463 goto out; 464 465 hard_iface->debug_dir = debugfs_create_dir(hard_iface->net_dev->name, 466 batadv_debugfs); 467 if (!hard_iface->debug_dir) 468 goto out; 469 470 for (bat_debug = batadv_hardif_debuginfos; *bat_debug; ++bat_debug) { 471 file = debugfs_create_file(((*bat_debug)->attr).name, 472 S_IFREG | ((*bat_debug)->attr).mode, 473 hard_iface->debug_dir, 474 hard_iface->net_dev, 475 &(*bat_debug)->fops); 476 if (!file) 477 goto rem_attr; 478 } 479 480 return 0; 481rem_attr: 482 debugfs_remove_recursive(hard_iface->debug_dir); 483 hard_iface->debug_dir = NULL; 484out: 485#ifdef CONFIG_DEBUG_FS 486 return -ENOMEM; 487#else 488 return 0; 489#endif /* CONFIG_DEBUG_FS */ 490} 491 492/** 493 * batadv_debugfs_del_hardif - delete the base directory for a hard interface 494 * in debugfs. 495 * @hard_iface: hard interface which is deleted. 496 */ 497void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface) 498{ 499 if (batadv_debugfs) { 500 debugfs_remove_recursive(hard_iface->debug_dir); 501 hard_iface->debug_dir = NULL; 502 } 503} 504 505int batadv_debugfs_add_meshif(struct net_device *dev) 506{ 507 struct batadv_priv *bat_priv = netdev_priv(dev); 508 struct batadv_debuginfo **bat_debug; 509 struct dentry *file; 510 511 if (!batadv_debugfs) 512 goto out; 513 514 bat_priv->debug_dir = debugfs_create_dir(dev->name, batadv_debugfs); 515 if (!bat_priv->debug_dir) 516 goto out; 517 518 if (batadv_socket_setup(bat_priv) < 0) 519 goto rem_attr; 520 521 if (batadv_debug_log_setup(bat_priv) < 0) 522 goto rem_attr; 523 524 for (bat_debug = batadv_mesh_debuginfos; *bat_debug; ++bat_debug) { 525 file = debugfs_create_file(((*bat_debug)->attr).name, 526 S_IFREG | ((*bat_debug)->attr).mode, 527 bat_priv->debug_dir, 528 dev, &(*bat_debug)->fops); 529 if (!file) { 530 batadv_err(dev, "Can't add debugfs file: %s/%s\n", 531 dev->name, ((*bat_debug)->attr).name); 532 goto rem_attr; 533 } 534 } 535 536 if (batadv_nc_init_debugfs(bat_priv) < 0) 537 goto rem_attr; 538 539 return 0; 540rem_attr: 541 debugfs_remove_recursive(bat_priv->debug_dir); 542 bat_priv->debug_dir = NULL; 543out: 544#ifdef CONFIG_DEBUG_FS 545 return -ENOMEM; 546#else 547 return 0; 548#endif /* CONFIG_DEBUG_FS */ 549} 550 551void batadv_debugfs_del_meshif(struct net_device *dev) 552{ 553 struct batadv_priv *bat_priv = netdev_priv(dev); 554 555 batadv_debug_log_cleanup(bat_priv); 556 557 if (batadv_debugfs) { 558 debugfs_remove_recursive(bat_priv->debug_dir); 559 bat_priv->debug_dir = NULL; 560 } 561} 562