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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      X.25 Packet Layer release 002
3
 *
4
 *      This is ALPHA test software. This code may break your machine, randomly fail to work with new
5
 *      releases, misbehave and/or generally screw up. It might even work.
6
 *
7
 *      This code REQUIRES 2.1.15 or higher
8
 *
9
 *      This module:
10
 *              This module 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
 *      History
16
 *      X.25 001        Jonathan Naylor Started coding.
17
 */
18
 
19
#include <linux/config.h>
20
#include <linux/errno.h>
21
#include <linux/types.h>
22
#include <linux/socket.h>
23
#include <linux/in.h>
24
#include <linux/kernel.h>
25
#include <linux/sched.h>
26
#include <linux/timer.h>
27
#include <linux/string.h>
28
#include <linux/sockios.h>
29
#include <linux/net.h>
30
#include <linux/inet.h>
31
#include <linux/netdevice.h>
32
#include <net/arp.h>
33
#include <linux/if_arp.h>
34
#include <linux/skbuff.h>
35
#include <net/sock.h>
36
#include <asm/segment.h>
37
#include <asm/system.h>
38
#include <asm/uaccess.h>
39
#include <linux/fcntl.h>
40
#include <linux/termios.h>      /* For TIOCINQ/OUTQ */
41
#include <linux/mm.h>
42
#include <linux/interrupt.h>
43
#include <linux/notifier.h>
44
#include <linux/init.h>
45
#include <net/x25.h>
46
 
47
static struct x25_route *x25_route_list /* = NULL initially */;
48
 
49
/*
50
 *      Add a new route.
51
 */
52
static int x25_add_route(x25_address *address, unsigned int sigdigits, struct net_device *dev)
53
{
54
        struct x25_route *x25_route;
55
        unsigned long flags;
56
 
57
        for (x25_route = x25_route_list; x25_route != NULL; x25_route = x25_route->next)
58
                if (memcmp(&x25_route->address, address, sigdigits) == 0 && x25_route->sigdigits == sigdigits)
59
                        return -EINVAL;
60
 
61
        if ((x25_route = kmalloc(sizeof(*x25_route), GFP_ATOMIC)) == NULL)
62
                return -ENOMEM;
63
 
64
        strcpy(x25_route->address.x25_addr, "000000000000000");
65
        memcpy(x25_route->address.x25_addr, address->x25_addr, sigdigits);
66
 
67
        x25_route->sigdigits = sigdigits;
68
        x25_route->dev       = dev;
69
 
70
        save_flags(flags); cli();
71
        x25_route->next = x25_route_list;
72
        x25_route_list  = x25_route;
73
        restore_flags(flags);
74
 
75
        return 0;
76
}
77
 
78
static void x25_remove_route(struct x25_route *x25_route)
79
{
80
        struct x25_route *s;
81
        unsigned long flags;
82
 
83
        save_flags(flags);
84
        cli();
85
 
86
        if ((s = x25_route_list) == x25_route) {
87
                x25_route_list = x25_route->next;
88
                restore_flags(flags);
89
                kfree(x25_route);
90
                return;
91
        }
92
 
93
        while (s != NULL && s->next != NULL) {
94
                if (s->next == x25_route) {
95
                        s->next = x25_route->next;
96
                        restore_flags(flags);
97
                        kfree(x25_route);
98
                        return;
99
                }
100
 
101
                s = s->next;
102
        }
103
 
104
        restore_flags(flags);
105
}
106
 
107
static int x25_del_route(x25_address *address, unsigned int sigdigits, struct net_device *dev)
108
{
109
        struct x25_route *x25_route;
110
 
111
        for (x25_route = x25_route_list; x25_route != NULL; x25_route = x25_route->next) {
112
                if (memcmp(&x25_route->address, address, sigdigits) == 0 && x25_route->sigdigits == sigdigits && x25_route->dev == dev) {
113
                        x25_remove_route(x25_route);
114
                        return 0;
115
                }
116
        }
117
 
118
        return -EINVAL;
119
}
120
 
121
/*
122
 *      A device has been removed, remove its routes.
123
 */
124
void x25_route_device_down(struct net_device *dev)
125
{
126
        struct x25_route *route, *x25_route = x25_route_list;
127
 
128
        while (x25_route != NULL) {
129
                route     = x25_route;
130
                x25_route = x25_route->next;
131
 
132
                if (route->dev == dev)
133
                        x25_remove_route(route);
134
        }
135
}
136
 
137
/*
138
 *      Check that the device given is a valid X.25 interface that is "up".
139
 */
140
struct net_device *x25_dev_get(char *devname)
141
{
142
        struct net_device *dev;
143
 
144
        if ((dev = dev_get_by_name(devname)) == NULL)
145
                return NULL;
146
 
147
        if ((dev->flags & IFF_UP) && (dev->type == ARPHRD_X25
148
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
149
           || dev->type == ARPHRD_ETHER
150
#endif
151
           ))
152
                return dev;
153
 
154
        dev_put(dev);
155
 
156
        return NULL;
157
}
158
 
159
/*
160
 *      Find a device given an X.25 address.
161
 */
162
struct net_device *x25_get_route(x25_address *addr)
163
{
164
        struct x25_route *route, *use = NULL;
165
 
166
        for (route = x25_route_list; route != NULL; route = route->next) {
167
                if (memcmp(&route->address, addr, route->sigdigits) == 0) {
168
                        if (use == NULL) {
169
                                use = route;
170
                        } else {
171
                                if (route->sigdigits > use->sigdigits)
172
                                        use = route;
173
                        }
174
                }
175
        }
176
 
177
        return (use != NULL) ? use->dev : NULL;
178
}
179
 
180
/*
181
 *      Handle the ioctls that control the routing functions.
182
 */
183
int x25_route_ioctl(unsigned int cmd, void *arg)
184
{
185
        struct x25_route_struct x25_route;
186
        struct net_device *dev;
187
        int err;
188
 
189
        switch (cmd) {
190
 
191
                case SIOCADDRT:
192
                        if (copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct)))
193
                                return -EFAULT;
194
                        if (x25_route.sigdigits < 0 || x25_route.sigdigits > 15)
195
                                return -EINVAL;
196
                        if ((dev = x25_dev_get(x25_route.device)) == NULL)
197
                                return -EINVAL;
198
                        err = x25_add_route(&x25_route.address, x25_route.sigdigits, dev);
199
                        dev_put(dev);
200
                        return err;
201
 
202
                case SIOCDELRT:
203
                        if (copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct)))
204
                                return -EFAULT;
205
                        if (x25_route.sigdigits < 0 || x25_route.sigdigits > 15)
206
                                return -EINVAL;
207
                        if ((dev = x25_dev_get(x25_route.device)) == NULL)
208
                                return -EINVAL;
209
                        err = x25_del_route(&x25_route.address, x25_route.sigdigits, dev);
210
                        dev_put(dev);
211
                        return err;
212
 
213
                default:
214
                        return -EINVAL;
215
        }
216
 
217
        return 0;
218
}
219
 
220
int x25_routes_get_info(char *buffer, char **start, off_t offset, int length)
221
{
222
        struct x25_route *x25_route;
223
        int len     = 0;
224
        off_t pos   = 0;
225
        off_t begin = 0;
226
 
227
        cli();
228
 
229
        len += sprintf(buffer, "address          digits  device\n");
230
 
231
        for (x25_route = x25_route_list; x25_route != NULL; x25_route = x25_route->next) {
232
                len += sprintf(buffer + len, "%-15s  %-6d  %-5s\n",
233
                        x25_route->address.x25_addr,
234
                        x25_route->sigdigits,
235
                        (x25_route->dev != NULL) ? x25_route->dev->name : "???");
236
 
237
                pos = begin + len;
238
 
239
                if (pos < offset) {
240
                        len   = 0;
241
                        begin = pos;
242
                }
243
 
244
                if (pos > offset + length)
245
                        break;
246
        }
247
 
248
        sti();
249
 
250
        *start = buffer + (offset - begin);
251
        len   -= (offset - begin);
252
 
253
        if (len > length) len = length;
254
 
255
        return len;
256
}
257
 
258
/*
259
 *      Release all memory associated with X.25 routing structures.
260
 */
261
void __exit x25_route_free(void)
262
{
263
        struct x25_route *route, *x25_route = x25_route_list;
264
 
265
        while (x25_route != NULL) {
266
                route     = x25_route;
267
                x25_route = x25_route->next;
268
 
269
                x25_remove_route(route);
270
        }
271
}

powered by: WebSVN 2.1.0

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