]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/batman-adv/proc.c
Staging: batman-adv: move originator interval setting from /proc to /sys
[net-next-2.6.git] / drivers / staging / batman-adv / proc.c
CommitLineData
5beef3c9 1/*
9b6d10b7 2 * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
5beef3c9
AL
3 *
4 * Marek Lindner, Simon Wunderlich
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA
19 *
20 */
21
22#include "main.h"
23#include "proc.h"
5beef3c9
AL
24#include "routing.h"
25#include "translation-table.h"
26#include "hard-interface.h"
27#include "types.h"
28#include "hash.h"
29#include "vis.h"
5beef3c9 30
5beef3c9 31static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
5beef3c9
AL
32
33static int proc_interfaces_read(struct seq_file *seq, void *offset)
34{
35 struct batman_if *batman_if;
36
37 rcu_read_lock();
38 list_for_each_entry_rcu(batman_if, &if_list, list) {
f6497e38 39 seq_printf(seq, "[%8s] %s %s\n",
5beef3c9
AL
40 (batman_if->if_active == IF_ACTIVE ?
41 "active" : "inactive"),
42 batman_if->dev,
43 (batman_if->if_active == IF_ACTIVE ?
44 batman_if->addr_str : " "));
45 }
46 rcu_read_unlock();
47
48 return 0;
49}
50
51static int proc_interfaces_open(struct inode *inode, struct file *file)
52{
53 return single_open(file, proc_interfaces_read, NULL);
54}
55
56static ssize_t proc_interfaces_write(struct file *instance,
57 const char __user *userbuffer,
58 size_t count, loff_t *data)
59{
60 char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
af71b816 61 int not_copied = 0, if_num = 0, add_success;
5beef3c9
AL
62 struct batman_if *batman_if = NULL;
63
64 if_string = kmalloc(count, GFP_KERNEL);
65
66 if (!if_string)
67 return -ENOMEM;
68
69 if (count > IFNAMSIZ - 1) {
bad2239e 70 printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n");
5beef3c9
AL
71 goto end;
72 }
73
74 not_copied = copy_from_user(if_string, userbuffer, count);
75 if_string[count - not_copied - 1] = 0;
76
77 colon_ptr = strchr(if_string, ':');
78 if (colon_ptr)
79 *colon_ptr = 0;
80
81 if (!colon_ptr) {
82 cr_ptr = strchr(if_string, '\n');
83 if (cr_ptr)
84 *cr_ptr = 0;
85 }
86
87 if (strlen(if_string) == 0) {
88 shutdown_module();
89 num_ifs = 0;
90 goto end;
91 }
92
93 /* add interface */
94 rcu_read_lock();
95 list_for_each_entry_rcu(batman_if, &if_list, list) {
96 if (strncmp(batman_if->dev, if_string, count) == 0) {
bad2239e 97 printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string);
5beef3c9
AL
98 rcu_read_unlock();
99 goto end;
100
101 }
102
103 if_num++;
104 }
105 rcu_read_unlock();
106
af71b816
ML
107 add_success = hardif_add_interface(if_string, if_num);
108 if (add_success < 0)
109 goto end;
110
111 num_ifs = if_num + 1;
5beef3c9
AL
112
113 if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
114 (hardif_get_active_if_num() > 0))
115 activate_module();
116
5beef3c9 117 return count;
5beef3c9
AL
118end:
119 kfree(if_string);
120 return count;
121}
122
5beef3c9
AL
123static const struct file_operations proc_interfaces_fops = {
124 .owner = THIS_MODULE,
125 .open = proc_interfaces_open,
126 .read = seq_read,
127 .write = proc_interfaces_write,
128 .llseek = seq_lseek,
129 .release = single_release,
130};
131
5beef3c9
AL
132void cleanup_procfs(void)
133{
5beef3c9
AL
134 if (proc_interface_file)
135 remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
136
5beef3c9
AL
137 if (proc_batman_dir)
138#ifdef __NET_NET_NAMESPACE_H
139 remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net);
140#else
141 remove_proc_entry(PROC_ROOT_DIR, proc_net);
142#endif
143}
144
145int setup_procfs(void)
146{
147#ifdef __NET_NET_NAMESPACE_H
148 proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, init_net.proc_net);
149#else
150 proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, proc_net);
151#endif
152
153 if (!proc_batman_dir) {
154 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s' folder failed\n", PROC_ROOT_DIR);
155 return -EFAULT;
156 }
157
158 proc_interface_file = create_proc_entry(PROC_FILE_INTERFACES,
159 S_IWUSR | S_IRUGO,
160 proc_batman_dir);
161 if (proc_interface_file) {
162 proc_interface_file->proc_fops = &proc_interfaces_fops;
163 } else {
164 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_INTERFACES);
165 cleanup_procfs();
166 return -EFAULT;
167 }
168
5beef3c9
AL
169 return 0;
170}