2012-05-12 04:09:43 +04:00
/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
2010-12-13 14:19:28 +03:00
*
* Marek Lindner
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA
* 02110 - 1301 , USA
*/
# include "main.h"
# include <linux/debugfs.h>
2012-06-11 01:58:51 +04:00
# include "debugfs.h"
2010-12-13 14:19:28 +03:00
# include "translation-table.h"
# include "originator.h"
# include "hard-interface.h"
# include "gateway_common.h"
# include "gateway_client.h"
# include "soft-interface.h"
# include "vis.h"
# include "icmp_socket.h"
2012-01-22 23:00:21 +04:00
# include "bridge_loop_avoidance.h"
2010-12-13 14:19:28 +03:00
2012-05-12 20:33:50 +04:00
static struct dentry * batadv_debugfs ;
2010-12-13 14:19:28 +03:00
# ifdef CONFIG_BATMAN_ADV_DEBUG
2012-06-04 00:19:07 +04:00
# define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1)
2010-12-13 14:19:28 +03:00
2012-06-06 00:31:32 +04:00
static const int batadv_log_buff_len = BATADV_LOG_BUF_LEN ;
static char * batadv_log_char_addr ( struct batadv_debug_log * debug_log ,
size_t idx )
{
return & debug_log - > log_buff [ idx & BATADV_LOG_BUFF_MASK ] ;
}
2010-12-13 14:19:28 +03:00
2012-06-06 00:31:31 +04:00
static void batadv_emit_log_char ( struct batadv_debug_log * debug_log , char c )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:32 +04:00
char * char_addr ;
char_addr = batadv_log_char_addr ( debug_log , debug_log - > log_end ) ;
* char_addr = c ;
2010-12-13 14:19:28 +03:00
debug_log - > log_end + + ;
2012-05-12 20:33:50 +04:00
if ( debug_log - > log_end - debug_log - > log_start > batadv_log_buff_len )
debug_log - > log_start = debug_log - > log_end - batadv_log_buff_len ;
2010-12-13 14:19:28 +03:00
}
2011-05-15 01:14:46 +04:00
__printf ( 2 , 3 )
2012-06-06 00:31:31 +04:00
static int batadv_fdebug_log ( struct batadv_debug_log * debug_log ,
const char * fmt , . . . )
2010-12-13 14:19:28 +03:00
{
va_list args ;
static char debug_log_buf [ 256 ] ;
char * p ;
if ( ! debug_log )
return 0 ;
spin_lock_bh ( & debug_log - > lock ) ;
va_start ( args , fmt ) ;
2011-01-27 15:48:54 +03:00
vscnprintf ( debug_log_buf , sizeof ( debug_log_buf ) , fmt , args ) ;
2010-12-13 14:19:28 +03:00
va_end ( args ) ;
for ( p = debug_log_buf ; * p ! = 0 ; p + + )
2012-05-12 20:33:50 +04:00
batadv_emit_log_char ( debug_log , * p ) ;
2010-12-13 14:19:28 +03:00
spin_unlock_bh ( & debug_log - > lock ) ;
wake_up ( & debug_log - > queue_wait ) ;
return 0 ;
}
2012-06-06 00:31:31 +04:00
int batadv_debug_log ( struct batadv_priv * bat_priv , const char * fmt , . . . )
2010-12-13 14:19:28 +03:00
{
va_list args ;
char tmp_log_buf [ 256 ] ;
va_start ( args , fmt ) ;
vscnprintf ( tmp_log_buf , sizeof ( tmp_log_buf ) , fmt , args ) ;
2012-05-12 20:33:50 +04:00
batadv_fdebug_log ( bat_priv - > debug_log , " [%10u] %s " ,
jiffies_to_msecs ( jiffies ) , tmp_log_buf ) ;
2010-12-13 14:19:28 +03:00
va_end ( args ) ;
return 0 ;
}
2012-05-12 20:33:50 +04:00
static int batadv_log_open ( struct inode * inode , struct file * file )
2010-12-13 14:19:28 +03:00
{
nonseekable_open ( inode , file ) ;
file - > private_data = inode - > i_private ;
2012-05-12 04:09:42 +04:00
batadv_inc_module_count ( ) ;
2010-12-13 14:19:28 +03:00
return 0 ;
}
2012-05-12 20:33:50 +04:00
static int batadv_log_release ( struct inode * inode , struct file * file )
2010-12-13 14:19:28 +03:00
{
2012-05-12 04:09:42 +04:00
batadv_dec_module_count ( ) ;
2010-12-13 14:19:28 +03:00
return 0 ;
}
2012-06-19 22:26:30 +04:00
static int batadv_log_empty ( struct batadv_debug_log * debug_log )
{
return ! ( debug_log - > log_start - debug_log - > log_end ) ;
}
2012-05-12 20:33:50 +04:00
static ssize_t batadv_log_read ( struct file * file , char __user * buf ,
size_t count , loff_t * ppos )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:31 +04:00
struct batadv_priv * bat_priv = file - > private_data ;
struct batadv_debug_log * debug_log = bat_priv - > debug_log ;
2010-12-13 14:19:28 +03:00
int error , i = 0 ;
2012-06-06 00:31:32 +04:00
char * char_addr ;
2010-12-13 14:19:28 +03:00
char c ;
2012-06-19 22:26:30 +04:00
if ( ( file - > f_flags & O_NONBLOCK ) & & batadv_log_empty ( debug_log ) )
2010-12-13 14:19:28 +03:00
return - EAGAIN ;
2011-05-15 01:14:48 +04:00
if ( ! buf )
2010-12-13 14:19:28 +03:00
return - EINVAL ;
if ( count = = 0 )
return 0 ;
if ( ! access_ok ( VERIFY_WRITE , buf , count ) )
return - EFAULT ;
error = wait_event_interruptible ( debug_log - > queue_wait ,
2012-06-19 22:26:30 +04:00
( ! batadv_log_empty ( debug_log ) ) ) ;
2010-12-13 14:19:28 +03:00
if ( error )
return error ;
spin_lock_bh ( & debug_log - > lock ) ;
while ( ( ! error ) & & ( i < count ) & &
( debug_log - > log_start ! = debug_log - > log_end ) ) {
2012-06-06 00:31:32 +04:00
char_addr = batadv_log_char_addr ( debug_log ,
debug_log - > log_start ) ;
c = * char_addr ;
2010-12-13 14:19:28 +03:00
debug_log - > log_start + + ;
spin_unlock_bh ( & debug_log - > lock ) ;
error = __put_user ( c , buf ) ;
spin_lock_bh ( & debug_log - > lock ) ;
buf + + ;
i + + ;
}
spin_unlock_bh ( & debug_log - > lock ) ;
if ( ! error )
return i ;
return error ;
}
2012-05-12 20:33:50 +04:00
static unsigned int batadv_log_poll ( struct file * file , poll_table * wait )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:31 +04:00
struct batadv_priv * bat_priv = file - > private_data ;
struct batadv_debug_log * debug_log = bat_priv - > debug_log ;
2010-12-13 14:19:28 +03:00
poll_wait ( file , & debug_log - > queue_wait , wait ) ;
2012-06-19 22:26:30 +04:00
if ( ! batadv_log_empty ( debug_log ) )
2010-12-13 14:19:28 +03:00
return POLLIN | POLLRDNORM ;
return 0 ;
}
2012-05-12 20:33:50 +04:00
static const struct file_operations batadv_log_fops = {
. open = batadv_log_open ,
. release = batadv_log_release ,
. read = batadv_log_read ,
. poll = batadv_log_poll ,
2010-12-13 14:19:28 +03:00
. llseek = no_llseek ,
} ;
2012-06-06 00:31:31 +04:00
static int batadv_debug_log_setup ( struct batadv_priv * bat_priv )
2010-12-13 14:19:28 +03:00
{
struct dentry * d ;
if ( ! bat_priv - > debug_dir )
goto err ;
2011-05-15 01:14:54 +04:00
bat_priv - > debug_log = kzalloc ( sizeof ( * bat_priv - > debug_log ) , GFP_ATOMIC ) ;
2010-12-13 14:19:28 +03:00
if ( ! bat_priv - > debug_log )
goto err ;
spin_lock_init ( & bat_priv - > debug_log - > lock ) ;
init_waitqueue_head ( & bat_priv - > debug_log - > queue_wait ) ;
d = debugfs_create_file ( " log " , S_IFREG | S_IRUSR ,
2012-05-12 20:33:50 +04:00
bat_priv - > debug_dir , bat_priv ,
& batadv_log_fops ) ;
2012-05-05 15:27:28 +04:00
if ( ! d )
2010-12-13 14:19:28 +03:00
goto err ;
return 0 ;
err :
2012-05-05 15:27:28 +04:00
return - ENOMEM ;
2010-12-13 14:19:28 +03:00
}
2012-06-06 00:31:31 +04:00
static void batadv_debug_log_cleanup ( struct batadv_priv * bat_priv )
2010-12-13 14:19:28 +03:00
{
kfree ( bat_priv - > debug_log ) ;
bat_priv - > debug_log = NULL ;
}
# else /* CONFIG_BATMAN_ADV_DEBUG */
2012-06-06 00:31:31 +04:00
static int batadv_debug_log_setup ( struct batadv_priv * bat_priv )
2010-12-13 14:19:28 +03:00
{
bat_priv - > debug_log = NULL ;
return 0 ;
}
2012-06-06 00:31:31 +04:00
static void batadv_debug_log_cleanup ( struct batadv_priv * bat_priv )
2010-12-13 14:19:28 +03:00
{
return ;
}
# endif
2012-05-12 20:33:50 +04:00
static int batadv_algorithms_open ( struct inode * inode , struct file * file )
2011-11-28 13:40:17 +04:00
{
2012-05-12 04:09:42 +04:00
return single_open ( file , batadv_algo_seq_print_text , NULL ) ;
2011-11-28 13:40:17 +04:00
}
2012-05-12 20:33:50 +04:00
static int batadv_originators_open ( struct inode * inode , struct file * file )
2010-12-13 14:19:28 +03:00
{
struct net_device * net_dev = ( struct net_device * ) inode - > i_private ;
2012-05-12 04:09:34 +04:00
return single_open ( file , batadv_orig_seq_print_text , net_dev ) ;
2010-12-13 14:19:28 +03:00
}
2012-05-12 20:33:50 +04:00
static int batadv_gateways_open ( struct inode * inode , struct file * file )
2010-12-13 14:19:28 +03:00
{
struct net_device * net_dev = ( struct net_device * ) inode - > i_private ;
2012-05-12 04:09:29 +04:00
return single_open ( file , batadv_gw_client_seq_print_text , net_dev ) ;
2010-12-13 14:19:28 +03:00
}
2012-05-12 20:33:50 +04:00
static int batadv_transtable_global_open ( struct inode * inode , struct file * file )
2010-12-13 14:19:28 +03:00
{
struct net_device * net_dev = ( struct net_device * ) inode - > i_private ;
2012-05-12 04:09:39 +04:00
return single_open ( file , batadv_tt_global_seq_print_text , net_dev ) ;
2010-12-13 14:19:28 +03:00
}
2012-01-22 23:00:27 +04:00
# ifdef CONFIG_BATMAN_ADV_BLA
2012-05-12 20:33:50 +04:00
static int batadv_bla_claim_table_open ( struct inode * inode , struct file * file )
2012-01-22 23:00:21 +04:00
{
struct net_device * net_dev = ( struct net_device * ) inode - > i_private ;
2012-05-12 15:38:47 +04:00
return single_open ( file , batadv_bla_claim_table_seq_print_text ,
net_dev ) ;
2012-01-22 23:00:21 +04:00
}
2012-01-22 23:00:27 +04:00
# endif
2012-01-22 23:00:21 +04:00
2012-05-12 20:33:50 +04:00
static int batadv_transtable_local_open ( struct inode * inode , struct file * file )
2010-12-13 14:19:28 +03:00
{
struct net_device * net_dev = ( struct net_device * ) inode - > i_private ;
2012-05-12 04:09:39 +04:00
return single_open ( file , batadv_tt_local_seq_print_text , net_dev ) ;
2010-12-13 14:19:28 +03:00
}
2012-05-12 20:33:50 +04:00
static int batadv_vis_data_open ( struct inode * inode , struct file * file )
2010-12-13 14:19:28 +03:00
{
struct net_device * net_dev = ( struct net_device * ) inode - > i_private ;
2012-05-12 04:09:41 +04:00
return single_open ( file , batadv_vis_seq_print_text , net_dev ) ;
2010-12-13 14:19:28 +03:00
}
2012-06-06 00:31:27 +04:00
struct batadv_debuginfo {
2010-12-13 14:19:28 +03:00
struct attribute attr ;
const struct file_operations fops ;
} ;
2012-06-04 00:19:07 +04:00
# define BATADV_DEBUGINFO(_name, _mode, _open) \
2012-06-06 00:31:27 +04:00
struct batadv_debuginfo batadv_debuginfo_ # # _name = { \
2012-05-12 20:33:50 +04:00
. attr = { . name = __stringify ( _name ) , \
. mode = _mode , } , \
. fops = { . owner = THIS_MODULE , \
. open = _open , \
. read = seq_read , \
. llseek = seq_lseek , \
. release = single_release , \
} \
2010-12-13 14:19:28 +03:00
} ;
2012-06-04 00:19:07 +04:00
static BATADV_DEBUGINFO ( routing_algos , S_IRUGO , batadv_algorithms_open ) ;
static BATADV_DEBUGINFO ( originators , S_IRUGO , batadv_originators_open ) ;
static BATADV_DEBUGINFO ( gateways , S_IRUGO , batadv_gateways_open ) ;
static BATADV_DEBUGINFO ( transtable_global , S_IRUGO ,
batadv_transtable_global_open ) ;
2012-01-22 23:00:27 +04:00
# ifdef CONFIG_BATMAN_ADV_BLA
2012-06-04 00:19:07 +04:00
static BATADV_DEBUGINFO ( bla_claim_table , S_IRUGO , batadv_bla_claim_table_open ) ;
2012-01-22 23:00:27 +04:00
# endif
2012-06-04 00:19:07 +04:00
static BATADV_DEBUGINFO ( transtable_local , S_IRUGO ,
batadv_transtable_local_open ) ;
static BATADV_DEBUGINFO ( vis_data , S_IRUGO , batadv_vis_data_open ) ;
2010-12-13 14:19:28 +03:00
2012-06-06 00:31:27 +04:00
static struct batadv_debuginfo * batadv_mesh_debuginfos [ ] = {
2012-05-12 20:33:50 +04:00
& batadv_debuginfo_originators ,
& batadv_debuginfo_gateways ,
& batadv_debuginfo_transtable_global ,
2012-01-22 23:00:27 +04:00
# ifdef CONFIG_BATMAN_ADV_BLA
2012-05-12 20:33:50 +04:00
& batadv_debuginfo_bla_claim_table ,
2012-01-22 23:00:27 +04:00
# endif
2012-05-12 20:33:50 +04:00
& batadv_debuginfo_transtable_local ,
& batadv_debuginfo_vis_data ,
2010-12-13 14:19:28 +03:00
NULL ,
} ;
2012-05-12 04:09:23 +04:00
void batadv_debugfs_init ( void )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:27 +04:00
struct batadv_debuginfo * bat_debug ;
2011-11-28 13:40:17 +04:00
struct dentry * file ;
2012-06-04 00:19:08 +04:00
batadv_debugfs = debugfs_create_dir ( BATADV_DEBUGFS_SUBDIR , NULL ) ;
2012-05-12 20:33:50 +04:00
if ( batadv_debugfs = = ERR_PTR ( - ENODEV ) )
batadv_debugfs = NULL ;
2011-11-28 13:40:17 +04:00
2012-05-12 20:33:50 +04:00
if ( ! batadv_debugfs )
2011-11-28 13:40:17 +04:00
goto out ;
2012-05-12 20:33:50 +04:00
bat_debug = & batadv_debuginfo_routing_algos ;
2011-11-28 13:40:17 +04:00
file = debugfs_create_file ( bat_debug - > attr . name ,
S_IFREG | bat_debug - > attr . mode ,
2012-05-12 20:33:50 +04:00
batadv_debugfs , NULL , & bat_debug - > fops ) ;
2011-11-28 13:40:17 +04:00
if ( ! file )
pr_err ( " Can't add debugfs file: %s \n " , bat_debug - > attr . name ) ;
out :
return ;
2010-12-13 14:19:28 +03:00
}
2012-05-12 04:09:23 +04:00
void batadv_debugfs_destroy ( void )
2010-12-13 14:19:28 +03:00
{
2012-05-12 20:33:50 +04:00
if ( batadv_debugfs ) {
debugfs_remove_recursive ( batadv_debugfs ) ;
batadv_debugfs = NULL ;
2010-12-13 14:19:28 +03:00
}
}
2012-05-12 04:09:23 +04:00
int batadv_debugfs_add_meshif ( struct net_device * dev )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:31 +04:00
struct batadv_priv * bat_priv = netdev_priv ( dev ) ;
2012-06-06 00:31:27 +04:00
struct batadv_debuginfo * * bat_debug ;
2010-12-13 14:19:28 +03:00
struct dentry * file ;
2012-05-12 20:33:50 +04:00
if ( ! batadv_debugfs )
2010-12-13 14:19:28 +03:00
goto out ;
2012-05-12 20:33:50 +04:00
bat_priv - > debug_dir = debugfs_create_dir ( dev - > name , batadv_debugfs ) ;
2010-12-13 14:19:28 +03:00
if ( ! bat_priv - > debug_dir )
goto out ;
2012-05-12 04:09:33 +04:00
if ( batadv_socket_setup ( bat_priv ) < 0 )
2012-05-05 15:27:28 +04:00
goto rem_attr ;
2012-05-12 20:33:50 +04:00
if ( batadv_debug_log_setup ( bat_priv ) < 0 )
2012-05-05 15:27:28 +04:00
goto rem_attr ;
2010-12-13 14:19:28 +03:00
2012-05-12 20:33:50 +04:00
for ( bat_debug = batadv_mesh_debuginfos ; * bat_debug ; + + bat_debug ) {
2010-12-13 14:19:28 +03:00
file = debugfs_create_file ( ( ( * bat_debug ) - > attr ) . name ,
2012-06-19 22:26:30 +04:00
S_IFREG | ( ( * bat_debug ) - > attr ) . mode ,
bat_priv - > debug_dir ,
dev , & ( * bat_debug ) - > fops ) ;
2010-12-13 14:19:28 +03:00
if ( ! file ) {
2012-05-16 22:23:22 +04:00
batadv_err ( dev , " Can't add debugfs file: %s/%s \n " ,
dev - > name , ( ( * bat_debug ) - > attr ) . name ) ;
2010-12-13 14:19:28 +03:00
goto rem_attr ;
}
}
return 0 ;
rem_attr :
debugfs_remove_recursive ( bat_priv - > debug_dir ) ;
bat_priv - > debug_dir = NULL ;
out :
# ifdef CONFIG_DEBUG_FS
return - ENOMEM ;
# else
return 0 ;
# endif /* CONFIG_DEBUG_FS */
}
2012-05-12 04:09:23 +04:00
void batadv_debugfs_del_meshif ( struct net_device * dev )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:31 +04:00
struct batadv_priv * bat_priv = netdev_priv ( dev ) ;
2010-12-13 14:19:28 +03:00
2012-05-12 20:33:50 +04:00
batadv_debug_log_cleanup ( bat_priv ) ;
2010-12-13 14:19:28 +03:00
2012-05-12 20:33:50 +04:00
if ( batadv_debugfs ) {
2010-12-13 14:19:28 +03:00
debugfs_remove_recursive ( bat_priv - > debug_dir ) ;
bat_priv - > debug_dir = NULL ;
}
}