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 (
[email protected]
)
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