OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [bridge/] [br_ioctl.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      Ioctl handler
3
 *      Linux ethernet bridge
4
 *
5
 *      Authors:
6
 *      Lennert Buytenhek               <buytenh@gnu.org>
7
 *
8
 *      $Id: br_ioctl.c,v 1.1.1.1 2004-04-15 01:16:26 phoenix Exp $
9
 *
10
 *      This program is free software; you can redistribute it and/or
11
 *      modify it under the terms of the GNU General Public License
12
 *      as published by the Free Software Foundation; either version
13
 *      2 of the License, or (at your option) any later version.
14
 */
15
 
16
#include <linux/kernel.h>
17
#include <linux/if_bridge.h>
18
#include <linux/inetdevice.h>
19
#include <asm/uaccess.h>
20
#include "br_private.h"
21
 
22
static int br_ioctl_device(struct net_bridge *br,
23
                           unsigned int cmd,
24
                           unsigned long arg0,
25
                           unsigned long arg1,
26
                           unsigned long arg2)
27
{
28
        if (br == NULL)
29
                return -EINVAL;
30
 
31
        switch (cmd)
32
        {
33
        case BRCTL_ADD_IF:
34
        case BRCTL_DEL_IF:
35
        {
36
                struct net_device *dev;
37
                int ret;
38
 
39
                dev = dev_get_by_index(arg0);
40
                if (dev == NULL)
41
                        return -EINVAL;
42
 
43
                if (cmd == BRCTL_ADD_IF)
44
                        ret = br_add_if(br, dev);
45
                else
46
                        ret = br_del_if(br, dev);
47
 
48
                dev_put(dev);
49
                return ret;
50
        }
51
 
52
        case BRCTL_GET_BRIDGE_INFO:
53
        {
54
                struct __bridge_info b;
55
 
56
                memset(&b, 0, sizeof(struct __bridge_info));
57
                memcpy(&b.designated_root, &br->designated_root, 8);
58
                memcpy(&b.bridge_id, &br->bridge_id, 8);
59
                b.root_path_cost = br->root_path_cost;
60
                b.max_age = br->max_age;
61
                b.hello_time = br->hello_time;
62
                b.forward_delay = br->forward_delay;
63
                b.bridge_max_age = br->bridge_max_age;
64
                b.bridge_hello_time = br->bridge_hello_time;
65
                b.bridge_forward_delay = br->bridge_forward_delay;
66
                b.topology_change = br->topology_change;
67
                b.topology_change_detected = br->topology_change_detected;
68
                b.root_port = br->root_port;
69
                b.stp_enabled = br->stp_enabled;
70
                b.ageing_time = br->ageing_time;
71
                b.gc_interval = br->gc_interval;
72
                b.hello_timer_value = br_timer_get_residue(&br->hello_timer);
73
                b.tcn_timer_value = br_timer_get_residue(&br->tcn_timer);
74
                b.topology_change_timer_value = br_timer_get_residue(&br->topology_change_timer);
75
                b.gc_timer_value = br_timer_get_residue(&br->gc_timer);
76
 
77
                if (copy_to_user((void *)arg0, &b, sizeof(b)))
78
                        return -EFAULT;
79
 
80
                return 0;
81
        }
82
 
83
        case BRCTL_GET_PORT_LIST:
84
        {
85
                int i;
86
                int indices[256];
87
 
88
                for (i=0;i<256;i++)
89
                        indices[i] = 0;
90
 
91
                br_get_port_ifindices(br, indices);
92
                if (copy_to_user((void *)arg0, indices, 256*sizeof(int)))
93
                        return -EFAULT;
94
 
95
                return 0;
96
        }
97
 
98
        case BRCTL_SET_BRIDGE_FORWARD_DELAY:
99
                br->bridge_forward_delay = arg0;
100
                if (br_is_root_bridge(br))
101
                        br->forward_delay = arg0;
102
                return 0;
103
 
104
        case BRCTL_SET_BRIDGE_HELLO_TIME:
105
                br->bridge_hello_time = arg0;
106
                if (br_is_root_bridge(br))
107
                        br->hello_time = arg0;
108
                return 0;
109
 
110
        case BRCTL_SET_BRIDGE_MAX_AGE:
111
                br->bridge_max_age = arg0;
112
                if (br_is_root_bridge(br))
113
                        br->max_age = arg0;
114
                return 0;
115
 
116
        case BRCTL_SET_AGEING_TIME:
117
                br->ageing_time = arg0;
118
                return 0;
119
 
120
        case BRCTL_SET_GC_INTERVAL:
121
                br->gc_interval = arg0;
122
                return 0;
123
 
124
        case BRCTL_GET_PORT_INFO:
125
        {
126
                struct __port_info p;
127
                struct net_bridge_port *pt;
128
 
129
                if ((pt = br_get_port(br, arg1)) == NULL)
130
                        return -EINVAL;
131
 
132
                memset(&p, 0, sizeof(struct __port_info));
133
                memcpy(&p.designated_root, &pt->designated_root, 8);
134
                memcpy(&p.designated_bridge, &pt->designated_bridge, 8);
135
                p.port_id = pt->port_id;
136
                p.designated_port = pt->designated_port;
137
                p.path_cost = pt->path_cost;
138
                p.designated_cost = pt->designated_cost;
139
                p.state = pt->state;
140
                p.top_change_ack = pt->topology_change_ack;
141
                p.config_pending = pt->config_pending;
142
                p.message_age_timer_value = br_timer_get_residue(&pt->message_age_timer);
143
                p.forward_delay_timer_value = br_timer_get_residue(&pt->forward_delay_timer);
144
                p.hold_timer_value = br_timer_get_residue(&pt->hold_timer);
145
 
146
                if (copy_to_user((void *)arg0, &p, sizeof(p)))
147
                        return -EFAULT;
148
 
149
                return 0;
150
        }
151
 
152
        case BRCTL_SET_BRIDGE_STP_STATE:
153
                br->stp_enabled = arg0?1:0;
154
                return 0;
155
 
156
        case BRCTL_SET_BRIDGE_PRIORITY:
157
                br_stp_set_bridge_priority(br, arg0);
158
                return 0;
159
 
160
        case BRCTL_SET_PORT_PRIORITY:
161
        {
162
                struct net_bridge_port *p;
163
 
164
                if ((p = br_get_port(br, arg0)) == NULL)
165
                        return -EINVAL;
166
                br_stp_set_port_priority(p, arg1);
167
                return 0;
168
        }
169
 
170
        case BRCTL_SET_PATH_COST:
171
        {
172
                struct net_bridge_port *p;
173
 
174
                if ((p = br_get_port(br, arg0)) == NULL)
175
                        return -EINVAL;
176
                br_stp_set_path_cost(p, arg1);
177
                return 0;
178
        }
179
 
180
        case BRCTL_GET_FDB_ENTRIES:
181
                return br_fdb_get_entries(br, (void *)arg0, arg1, arg2);
182
        }
183
 
184
        return -EOPNOTSUPP;
185
}
186
 
187
static int br_ioctl_deviceless(unsigned int cmd,
188
                               unsigned long arg0,
189
                               unsigned long arg1)
190
{
191
        switch (cmd)
192
        {
193
        case BRCTL_GET_VERSION:
194
                return BRCTL_VERSION;
195
 
196
        case BRCTL_GET_BRIDGES:
197
        {
198
                int i;
199
                int indices[64];
200
 
201
                for (i=0;i<64;i++)
202
                        indices[i] = 0;
203
 
204
                if (arg1 > 64)
205
                        arg1 = 64;
206
                arg1 = br_get_bridge_ifindices(indices, arg1);
207
                if (copy_to_user((void *)arg0, indices, arg1*sizeof(int)))
208
                        return -EFAULT;
209
 
210
                return arg1;
211
        }
212
 
213
        case BRCTL_ADD_BRIDGE:
214
        case BRCTL_DEL_BRIDGE:
215
        {
216
                char buf[IFNAMSIZ];
217
 
218
                if (copy_from_user(buf, (void *)arg0, IFNAMSIZ))
219
                        return -EFAULT;
220
 
221
                buf[IFNAMSIZ-1] = 0;
222
 
223
                if (cmd == BRCTL_ADD_BRIDGE)
224
                        return br_add_bridge(buf);
225
 
226
                return br_del_bridge(buf);
227
        }
228
        }
229
 
230
        return -EOPNOTSUPP;
231
}
232
 
233
static DECLARE_MUTEX(ioctl_mutex);
234
 
235
int br_ioctl_deviceless_stub(unsigned long arg)
236
{
237
        int err;
238
        unsigned long i[3];
239
 
240
        if (!capable(CAP_NET_ADMIN))
241
                return -EPERM;
242
 
243
        if (copy_from_user(i, (void *)arg, 3*sizeof(unsigned long)))
244
                return -EFAULT;
245
 
246
        down(&ioctl_mutex);
247
        err = br_ioctl_deviceless(i[0], i[1], i[2]);
248
        up(&ioctl_mutex);
249
 
250
        return err;
251
}
252
 
253
int br_ioctl(struct net_bridge *br, unsigned int cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2)
254
{
255
        int err;
256
 
257
        if (!capable(CAP_NET_ADMIN))
258
                return -EPERM;
259
 
260
        down(&ioctl_mutex);
261
        err = br_ioctl_deviceless(cmd, arg0, arg1);
262
        if (err == -EOPNOTSUPP)
263
                err = br_ioctl_device(br, cmd, arg0, arg1, arg2);
264
        up(&ioctl_mutex);
265
 
266
        return err;
267
}
268
 
269
void br_call_ioctl_atomic(void (*fn)(void))
270
{
271
        down(&ioctl_mutex);
272
        fn();
273
        up(&ioctl_mutex);
274
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.