Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
ax25
ax25_dev.c
Go to the documentation of this file.
1
/*
2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
*
7
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
8
*/
9
#include <linux/errno.h>
10
#include <linux/types.h>
11
#include <linux/socket.h>
12
#include <linux/slab.h>
13
#include <linux/in.h>
14
#include <linux/kernel.h>
15
#include <
linux/timer.h
>
16
#include <linux/string.h>
17
#include <
linux/sockios.h
>
18
#include <linux/net.h>
19
#include <
linux/spinlock.h
>
20
#include <
net/ax25.h
>
21
#include <
linux/inet.h
>
22
#include <linux/netdevice.h>
23
#include <linux/if_arp.h>
24
#include <
linux/skbuff.h
>
25
#include <
net/sock.h
>
26
#include <asm/uaccess.h>
27
#include <linux/fcntl.h>
28
#include <
linux/mm.h
>
29
#include <
linux/interrupt.h
>
30
#include <
linux/init.h
>
31
32
ax25_dev
*
ax25_dev_list
;
33
DEFINE_SPINLOCK
(ax25_dev_lock);
34
35
ax25_dev
*
ax25_addr_ax25dev
(
ax25_address
*
addr
)
36
{
37
ax25_dev
*
ax25_dev
, *
res
=
NULL
;
38
39
spin_lock_bh(&
ax25_dev_lock
);
40
for
(ax25_dev = ax25_dev_list; ax25_dev !=
NULL
; ax25_dev = ax25_dev->
next
)
41
if
(
ax25cmp
(addr, (
ax25_address
*)ax25_dev->
dev
->dev_addr) == 0) {
42
res =
ax25_dev
;
43
}
44
spin_unlock_bh(&
ax25_dev_lock
);
45
46
return
res
;
47
}
48
49
/*
50
* This is called when an interface is brought up. These are
51
* reasonable defaults.
52
*/
53
void
ax25_dev_device_up
(
struct
net_device
*
dev
)
54
{
55
ax25_dev
*
ax25_dev
;
56
57
if
((ax25_dev = kzalloc(
sizeof
(*ax25_dev),
GFP_ATOMIC
)) ==
NULL
) {
58
printk
(
KERN_ERR
"AX.25: ax25_dev_device_up - out of memory\n"
);
59
return
;
60
}
61
62
dev->
ax25_ptr
=
ax25_dev
;
63
ax25_dev->
dev
=
dev
;
64
dev_hold(dev);
65
ax25_dev->
forward
=
NULL
;
66
67
ax25_dev->
values
[
AX25_VALUES_IPDEFMODE
] =
AX25_DEF_IPDEFMODE
;
68
ax25_dev->
values
[
AX25_VALUES_AXDEFMODE
] =
AX25_DEF_AXDEFMODE
;
69
ax25_dev->
values
[
AX25_VALUES_BACKOFF
] =
AX25_DEF_BACKOFF
;
70
ax25_dev->
values
[
AX25_VALUES_CONMODE
] =
AX25_DEF_CONMODE
;
71
ax25_dev->
values
[
AX25_VALUES_WINDOW
] =
AX25_DEF_WINDOW
;
72
ax25_dev->
values
[
AX25_VALUES_EWINDOW
] =
AX25_DEF_EWINDOW
;
73
ax25_dev->
values
[
AX25_VALUES_T1
] =
AX25_DEF_T1
;
74
ax25_dev->
values
[
AX25_VALUES_T2
] =
AX25_DEF_T2
;
75
ax25_dev->
values
[
AX25_VALUES_T3
] =
AX25_DEF_T3
;
76
ax25_dev->
values
[
AX25_VALUES_IDLE
] =
AX25_DEF_IDLE
;
77
ax25_dev->
values
[
AX25_VALUES_N2
] =
AX25_DEF_N2
;
78
ax25_dev->
values
[
AX25_VALUES_PACLEN
] =
AX25_DEF_PACLEN
;
79
ax25_dev->
values
[
AX25_VALUES_PROTOCOL
] =
AX25_DEF_PROTOCOL
;
80
ax25_dev->
values
[
AX25_VALUES_DS_TIMEOUT
]=
AX25_DEF_DS_TIMEOUT
;
81
82
#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
83
ax25_ds_setup_timer
(ax25_dev);
84
#endif
85
86
spin_lock_bh(&
ax25_dev_lock
);
87
ax25_dev->
next
=
ax25_dev_list
;
88
ax25_dev_list =
ax25_dev
;
89
spin_unlock_bh(&
ax25_dev_lock
);
90
91
ax25_register_dev_sysctl
(ax25_dev);
92
}
93
94
void
ax25_dev_device_down
(
struct
net_device
*
dev
)
95
{
96
ax25_dev
*
s
, *
ax25_dev
;
97
98
if
((ax25_dev = ax25_dev_ax25dev(dev)) ==
NULL
)
99
return
;
100
101
ax25_unregister_dev_sysctl
(ax25_dev);
102
103
spin_lock_bh(&
ax25_dev_lock
);
104
105
#ifdef CONFIG_AX25_DAMA_SLAVE
106
ax25_ds_del_timer
(ax25_dev);
107
#endif
108
109
/*
110
* Remove any packet forwarding that points to this device.
111
*/
112
for
(s = ax25_dev_list; s !=
NULL
; s = s->
next
)
113
if
(s->
forward
== dev)
114
s->
forward
=
NULL
;
115
116
if
((s = ax25_dev_list) == ax25_dev) {
117
ax25_dev_list = s->
next
;
118
spin_unlock_bh(&
ax25_dev_lock
);
119
dev_put(dev);
120
kfree
(ax25_dev);
121
return
;
122
}
123
124
while
(s !=
NULL
&& s->
next
!=
NULL
) {
125
if
(s->
next
== ax25_dev) {
126
s->
next
= ax25_dev->
next
;
127
spin_unlock_bh(&
ax25_dev_lock
);
128
dev_put(dev);
129
kfree
(ax25_dev);
130
return
;
131
}
132
133
s = s->
next
;
134
}
135
spin_unlock_bh(&
ax25_dev_lock
);
136
dev->
ax25_ptr
=
NULL
;
137
}
138
139
int
ax25_fwd_ioctl
(
unsigned
int
cmd
,
struct
ax25_fwd_struct
*fwd)
140
{
141
ax25_dev
*
ax25_dev
, *fwd_dev;
142
143
if
((ax25_dev =
ax25_addr_ax25dev
(&fwd->
port_from
)) ==
NULL
)
144
return
-
EINVAL
;
145
146
switch
(cmd) {
147
case
SIOCAX25ADDFWD
:
148
if
((fwd_dev =
ax25_addr_ax25dev
(&fwd->
port_to
)) ==
NULL
)
149
return
-
EINVAL
;
150
if
(ax25_dev->
forward
!=
NULL
)
151
return
-
EINVAL
;
152
ax25_dev->
forward
= fwd_dev->
dev
;
153
break
;
154
155
case
SIOCAX25DELFWD
:
156
if
(ax25_dev->
forward
==
NULL
)
157
return
-
EINVAL
;
158
ax25_dev->
forward
=
NULL
;
159
break
;
160
161
default
:
162
return
-
EINVAL
;
163
}
164
165
return
0;
166
}
167
168
struct
net_device
*
ax25_fwd_dev
(
struct
net_device
*
dev
)
169
{
170
ax25_dev
*
ax25_dev
;
171
172
if
((ax25_dev = ax25_dev_ax25dev(dev)) ==
NULL
)
173
return
dev
;
174
175
if
(ax25_dev->
forward
==
NULL
)
176
return
dev
;
177
178
return
ax25_dev->
forward
;
179
}
180
181
/*
182
* Free all memory associated with device structures.
183
*/
184
void
__exit
ax25_dev_free
(
void
)
185
{
186
ax25_dev
*
s
, *
ax25_dev
;
187
188
spin_lock_bh(&
ax25_dev_lock
);
189
ax25_dev =
ax25_dev_list
;
190
while
(ax25_dev !=
NULL
) {
191
s =
ax25_dev
;
192
dev_put(ax25_dev->
dev
);
193
ax25_dev = ax25_dev->
next
;
194
kfree
(s);
195
}
196
ax25_dev_list =
NULL
;
197
spin_unlock_bh(&
ax25_dev_lock
);
198
}
Generated on Thu Jan 10 2013 14:56:49 for Linux Kernel by
1.8.2