Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
6244be2f
Commit
6244be2f
authored
Jul 30, 2002
by
Ralf Bächle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert ax25_route_list by a rw_lock, no longer an interrup-save
spinlock. Reformat switch statements.
parent
be0eacc3
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1383 additions
and
1379 deletions
+1383
-1379
net/ax25/af_ax25.c
net/ax25/af_ax25.c
+427
-425
net/ax25/ax25_dev.c
net/ax25/ax25_dev.c
+14
-14
net/ax25/ax25_ds_in.c
net/ax25/ax25_ds_in.c
+194
-192
net/ax25/ax25_ds_timer.c
net/ax25/ax25_ds_timer.c
+56
-57
net/ax25/ax25_iface.c
net/ax25/ax25_iface.c
+12
-16
net/ax25/ax25_in.c
net/ax25/ax25_in.c
+47
-47
net/ax25/ax25_ip.c
net/ax25/ax25_ip.c
+10
-10
net/ax25/ax25_out.c
net/ax25/ax25_out.c
+28
-28
net/ax25/ax25_route.c
net/ax25/ax25_route.c
+120
-112
net/ax25/ax25_std_in.c
net/ax25/ax25_std_in.c
+292
-290
net/ax25/ax25_std_timer.c
net/ax25/ax25_std_timer.c
+64
-65
net/ax25/ax25_subr.c
net/ax25/ax25_subr.c
+12
-12
net/ax25/ax25_timer.c
net/ax25/ax25_timer.c
+46
-46
net/ax25/ax25_uid.c
net/ax25/ax25_uid.c
+61
-65
No files found.
net/ax25/af_ax25.c
View file @
6244be2f
...
...
@@ -231,16 +231,16 @@ static int ax25_device_event(struct notifier_block *this,unsigned long event, vo
return
NOTIFY_DONE
;
switch
(
event
)
{
case
NETDEV_UP
:
ax25_dev_device_up
(
dev
);
break
;
case
NETDEV_DOWN
:
ax25_kill_by_device
(
dev
);
ax25_rt_device_down
(
dev
);
ax25_dev_device_down
(
dev
);
break
;
default:
break
;
case
NETDEV_UP
:
ax25_dev_device_up
(
dev
);
break
;
case
NETDEV_DOWN
:
ax25_kill_by_device
(
dev
);
ax25_rt_device_down
(
dev
);
ax25_dev_device_down
(
dev
);
break
;
default:
break
;
}
return
NOTIFY_DONE
;
...
...
@@ -479,66 +479,66 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void *arg)
return
-
ENOTCONN
;
switch
(
ax25_ctl
.
cmd
)
{
case
AX25_KILL
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
case
AX25_KILL
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
#ifdef CONFIG_AX25_DAMA_SLAVE
if
(
ax25_dev
->
dama
.
slave
&&
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
]
==
AX25_PROTO_DAMA_SLAVE
)
ax25_dama_off
(
ax25
);
if
(
ax25_dev
->
dama
.
slave
&&
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
]
==
AX25_PROTO_DAMA_SLAVE
)
ax25_dama_off
(
ax25
);
#endif
ax25_disconnect
(
ax25
,
ENETRESET
);
break
;
ax25_disconnect
(
ax25
,
ENETRESET
);
break
;
case
AX25_WINDOW
:
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
if
(
ax25_ctl
.
arg
<
1
||
ax25_ctl
.
arg
>
7
)
return
-
EINVAL
;
}
else
{
if
(
ax25_ctl
.
arg
<
1
||
ax25_ctl
.
arg
>
63
)
return
-
EINVAL
;
}
ax25
->
window
=
ax25_ctl
.
arg
;
break
;
case
AX25_T1
:
if
(
ax25_ctl
.
arg
<
1
)
case
AX25_WINDOW
:
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
if
(
ax25_ctl
.
arg
<
1
||
ax25_ctl
.
arg
>
7
)
return
-
EINVAL
;
ax25
->
rtt
=
(
ax25_ctl
.
arg
*
HZ
)
/
2
;
ax25
->
t1
=
ax25_ctl
.
arg
*
HZ
;
break
;
case
AX25_T2
:
if
(
ax25_ctl
.
arg
<
1
)
return
-
EINVAL
;
ax25
->
t2
=
ax25_ctl
.
arg
*
HZ
;
break
;
case
AX25_N2
:
if
(
ax25_ctl
.
arg
<
1
||
ax25_ctl
.
arg
>
31
)
return
-
EINVAL
;
ax25
->
n2count
=
0
;
ax25
->
n2
=
ax25_ctl
.
arg
;
break
;
case
AX25_T3
:
if
(
ax25_ctl
.
arg
<
0
)
return
-
EINVAL
;
ax25
->
t3
=
ax25_ctl
.
arg
*
HZ
;
break
;
case
AX25_IDLE
:
if
(
ax25_ctl
.
arg
<
0
)
return
-
EINVAL
;
ax25
->
idle
=
ax25_ctl
.
arg
*
60
*
HZ
;
break
;
case
AX25_PACLEN
:
if
(
ax25_ctl
.
arg
<
16
||
ax25_ctl
.
arg
>
65535
)
return
-
EINVAL
;
ax25
->
paclen
=
ax25_ctl
.
arg
;
break
;
default:
return
-
EINVAL
;
}
else
{
if
(
ax25_ctl
.
arg
<
1
||
ax25_ctl
.
arg
>
63
)
return
-
EINVAL
;
}
ax25
->
window
=
ax25_ctl
.
arg
;
break
;
case
AX25_T1
:
if
(
ax25_ctl
.
arg
<
1
)
return
-
EINVAL
;
ax25
->
rtt
=
(
ax25_ctl
.
arg
*
HZ
)
/
2
;
ax25
->
t1
=
ax25_ctl
.
arg
*
HZ
;
break
;
case
AX25_T2
:
if
(
ax25_ctl
.
arg
<
1
)
return
-
EINVAL
;
ax25
->
t2
=
ax25_ctl
.
arg
*
HZ
;
break
;
case
AX25_N2
:
if
(
ax25_ctl
.
arg
<
1
||
ax25_ctl
.
arg
>
31
)
return
-
EINVAL
;
ax25
->
n2count
=
0
;
ax25
->
n2
=
ax25_ctl
.
arg
;
break
;
case
AX25_T3
:
if
(
ax25_ctl
.
arg
<
0
)
return
-
EINVAL
;
ax25
->
t3
=
ax25_ctl
.
arg
*
HZ
;
break
;
case
AX25_IDLE
:
if
(
ax25_ctl
.
arg
<
0
)
return
-
EINVAL
;
ax25
->
idle
=
ax25_ctl
.
arg
*
60
*
HZ
;
break
;
case
AX25_PACLEN
:
if
(
ax25_ctl
.
arg
<
16
||
ax25_ctl
.
arg
>
65535
)
return
-
EINVAL
;
ax25
->
paclen
=
ax25_ctl
.
arg
;
break
;
default:
return
-
EINVAL
;
}
return
0
;
...
...
@@ -647,115 +647,116 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, char *op
ax25
=
ax25_sk
(
sk
);
switch
(
optname
)
{
case
AX25_WINDOW
:
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
if
(
opt
<
1
||
opt
>
7
)
{
res
=
-
EINVAL
;
break
;
}
}
else
{
if
(
opt
<
1
||
opt
>
63
)
{
res
=
-
EINVAL
;
break
;
}
}
ax25
->
window
=
opt
;
break
;
case
AX25_T1
:
if
(
opt
<
1
)
{
case
AX25_WINDOW
:
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
if
(
opt
<
1
||
opt
>
7
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
rtt
=
(
opt
*
HZ
)
/
2
;
ax25
->
t1
=
opt
*
HZ
;
break
;
case
AX25_T2
:
if
(
opt
<
1
)
{
}
else
{
if
(
opt
<
1
||
opt
>
63
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
t2
=
opt
*
HZ
;
break
;
}
ax25
->
window
=
opt
;
break
;
case
AX25_N2
:
if
(
opt
<
1
||
opt
>
31
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
n2
=
opt
;
case
AX25_T1
:
if
(
opt
<
1
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
rtt
=
(
opt
*
HZ
)
/
2
;
ax25
->
t1
=
opt
*
HZ
;
break
;
case
AX25_T3
:
if
(
opt
<
1
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
t3
=
opt
*
HZ
;
case
AX25_T2
:
if
(
opt
<
1
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
t2
=
opt
*
HZ
;
break
;
case
AX25_IDLE
:
if
(
opt
<
0
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
idle
=
opt
*
60
*
HZ
;
case
AX25_N2
:
if
(
opt
<
1
||
opt
>
31
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
n2
=
opt
;
break
;
case
AX25_BACKOFF
:
if
(
opt
<
0
||
opt
>
2
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
backoff
=
opt
;
case
AX25_T3
:
if
(
opt
<
1
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
t3
=
opt
*
HZ
;
break
;
case
AX25_EXTSEQ
:
ax25
->
modulus
=
opt
?
AX25_EMODULUS
:
AX25_MODULUS
;
case
AX25_IDLE
:
if
(
opt
<
0
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
idle
=
opt
*
60
*
HZ
;
break
;
case
AX25_PIDINCL
:
ax25
->
pidincl
=
opt
?
1
:
0
;
case
AX25_BACKOFF
:
if
(
opt
<
0
||
opt
>
2
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
backoff
=
opt
;
break
;
case
AX25_IAMDIGI
:
ax25
->
iamdigi
=
opt
?
1
:
0
;
break
;
case
AX25_EXTSEQ
:
ax25
->
modulus
=
opt
?
AX25_EMODULUS
:
AX25_MODULUS
;
break
;
case
AX25_PACLEN
:
if
(
opt
<
16
||
opt
>
65535
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
paclen
=
opt
;
break
;
case
AX25_PIDINCL
:
ax25
->
pidincl
=
opt
?
1
:
0
;
break
;
case
SO_BINDTODEVICE
:
if
(
optlen
>
IFNAMSIZ
)
optlen
=
IFNAMSIZ
;
if
(
copy_from_user
(
devname
,
optval
,
optlen
))
{
res
=
-
EFAULT
;
break
;
}
case
AX25_IAMDIGI
:
ax25
->
iamdigi
=
opt
?
1
:
0
;
break
;
dev
=
dev_get_by_name
(
devname
);
if
(
dev
==
NULL
)
{
res
=
-
ENODEV
;
break
;
}
case
AX25_PACLEN
:
if
(
opt
<
16
||
opt
>
65535
)
{
res
=
-
EINVAL
;
break
;
}
ax25
->
paclen
=
opt
;
break
;
case
SO_BINDTODEVICE
:
if
(
optlen
>
IFNAMSIZ
)
optlen
=
IFNAMSIZ
;
if
(
copy_from_user
(
devname
,
optval
,
optlen
))
{
res
=
-
EFAULT
;
break
;
}
if
(
sk
->
type
==
SOCK_SEQPACKET
&&
(
sock
->
state
!=
SS_UNCONNECTED
||
sk
->
state
==
TCP_LISTEN
))
{
res
=
-
EADDRNOTAVAIL
;
break
;
}
ax25
->
ax25_dev
=
ax25_dev_ax25dev
(
dev
);
ax25_fillin_cb
(
ax25
,
ax25
->
ax25_dev
);
dev
=
dev_get_by_name
(
devname
);
if
(
dev
==
NULL
)
{
res
=
-
ENODEV
;
break
;
}
default:
res
=
-
ENOPROTOOPT
;
if
(
sk
->
type
==
SOCK_SEQPACKET
&&
(
sock
->
state
!=
SS_UNCONNECTED
||
sk
->
state
==
TCP_LISTEN
))
{
res
=
-
EADDRNOTAVAIL
;
break
;
}
ax25
->
ax25_dev
=
ax25_dev_ax25dev
(
dev
);
ax25_fillin_cb
(
ax25
,
ax25
->
ax25_dev
);
break
;
default:
res
=
-
ENOPROTOOPT
;
}
unlock_kernel
();
...
...
@@ -788,68 +789,68 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname, char *op
ax25
=
ax25_sk
(
sk
);
switch
(
optname
)
{
case
AX25_WINDOW
:
val
=
ax25
->
window
;
break
;
case
AX25_WINDOW
:
val
=
ax25
->
window
;
break
;
case
AX25_T1
:
val
=
ax25
->
t1
/
HZ
;
break
;
case
AX25_T1
:
val
=
ax25
->
t1
/
HZ
;
break
;
case
AX25_T2
:
val
=
ax25
->
t2
/
HZ
;
break
;
case
AX25_T2
:
val
=
ax25
->
t2
/
HZ
;
break
;
case
AX25_N2
:
val
=
ax25
->
n2
;
break
;
case
AX25_N2
:
val
=
ax25
->
n2
;
break
;
case
AX25_T3
:
val
=
ax25
->
t3
/
HZ
;
break
;
case
AX25_T3
:
val
=
ax25
->
t3
/
HZ
;
break
;
case
AX25_IDLE
:
val
=
ax25
->
idle
/
(
60
*
HZ
);
break
;
case
AX25_IDLE
:
val
=
ax25
->
idle
/
(
60
*
HZ
);
break
;
case
AX25_BACKOFF
:
val
=
ax25
->
backoff
;
break
;
case
AX25_BACKOFF
:
val
=
ax25
->
backoff
;
break
;
case
AX25_EXTSEQ
:
val
=
(
ax25
->
modulus
==
AX25_EMODULUS
);
break
;
case
AX25_EXTSEQ
:
val
=
(
ax25
->
modulus
==
AX25_EMODULUS
);
break
;
case
AX25_PIDINCL
:
val
=
ax25
->
pidincl
;
break
;
case
AX25_PIDINCL
:
val
=
ax25
->
pidincl
;
break
;
case
AX25_IAMDIGI
:
val
=
ax25
->
iamdigi
;
break
;
case
AX25_IAMDIGI
:
val
=
ax25
->
iamdigi
;
break
;
case
AX25_PACLEN
:
val
=
ax25
->
paclen
;
break
;
case
SO_BINDTODEVICE
:
ax25_dev
=
ax25
->
ax25_dev
;
if
(
ax25_dev
!=
NULL
&&
ax25_dev
->
dev
!=
NULL
)
{
strncpy
(
devname
,
ax25_dev
->
dev
->
name
,
IFNAMSIZ
);
length
=
min_t
(
unsigned
int
,
strlen
(
ax25_dev
->
dev
->
name
)
+
1
,
maxlen
);
devname
[
length
-
1
]
=
'\0'
;
}
else
{
*
devname
=
'\0'
;
length
=
1
;
}
case
AX25_PACLEN
:
val
=
ax25
->
paclen
;
break
;
valptr
=
(
void
*
)
devname
;
break
;
case
SO_BINDTODEVICE
:
ax25_dev
=
ax25
->
ax25_dev
;
default:
unlock_kernel
();
return
-
ENOPROTOOPT
;
if
(
ax25_dev
!=
NULL
&&
ax25_dev
->
dev
!=
NULL
)
{
strncpy
(
devname
,
ax25_dev
->
dev
->
name
,
IFNAMSIZ
);
length
=
min_t
(
unsigned
int
,
strlen
(
ax25_dev
->
dev
->
name
)
+
1
,
maxlen
);
devname
[
length
-
1
]
=
'\0'
;
}
else
{
*
devname
=
'\0'
;
length
=
1
;
}
valptr
=
(
void
*
)
devname
;
break
;
default:
unlock_kernel
();
return
-
ENOPROTOOPT
;
}
unlock_kernel
();
...
...
@@ -881,46 +882,48 @@ int ax25_create(struct socket *sock, int protocol)
ax25_cb
*
ax25
;
switch
(
sock
->
type
)
{
case
SOCK_DGRAM
:
if
(
protocol
==
0
||
protocol
==
PF_AX25
)
protocol
=
AX25_P_TEXT
;
case
SOCK_DGRAM
:
if
(
protocol
==
0
||
protocol
==
PF_AX25
)
protocol
=
AX25_P_TEXT
;
break
;
case
SOCK_SEQPACKET
:
switch
(
protocol
)
{
case
0
:
case
PF_AX25
:
/* For CLX */
protocol
=
AX25_P_TEXT
;
break
;
case
SOCK_SEQPACKET
:
switch
(
protocol
)
{
case
0
:
case
PF_AX25
:
/* For CLX */
protocol
=
AX25_P_TEXT
;
break
;
case
AX25_P_SEGMENT
:
case
AX25_P_SEGMENT
:
#ifdef CONFIG_INET
case
AX25_P_ARP
:
case
AX25_P_IP
:
case
AX25_P_ARP
:
case
AX25_P_IP
:
#endif
#ifdef CONFIG_NETROM
case
AX25_P_NETROM
:
case
AX25_P_NETROM
:
#endif
#ifdef CONFIG_ROSE
case
AX25_P_ROSE
:
case
AX25_P_ROSE
:
#endif
return
-
ESOCKTNOSUPPORT
;
return
-
ESOCKTNOSUPPORT
;
#ifdef CONFIG_NETROM_MODULE
case
AX25_P_NETROM
:
if
(
ax25_protocol_is_registered
(
AX25_P_NETROM
))
return
-
ESOCKTNOSUPPORT
;
case
AX25_P_NETROM
:
if
(
ax25_protocol_is_registered
(
AX25_P_NETROM
))
return
-
ESOCKTNOSUPPORT
;
#endif
#ifdef CONFIG_ROSE_MODULE
case
AX25_P_ROSE
:
if
(
ax25_protocol_is_registered
(
AX25_P_ROSE
))
return
-
ESOCKTNOSUPPORT
;
case
AX25_P_ROSE
:
if
(
ax25_protocol_is_registered
(
AX25_P_ROSE
))
return
-
ESOCKTNOSUPPORT
;
#endif
default:
break
;
}
break
;
case
SOCK_RAW
:
break
;
default:
return
-
ESOCKTNOSUPPORT
;
break
;
}
break
;
case
SOCK_RAW
:
break
;
default:
return
-
ESOCKTNOSUPPORT
;
}
if
((
sk
=
sk_alloc
(
PF_AX25
,
GFP_ATOMIC
,
1
,
NULL
))
==
NULL
)
...
...
@@ -957,14 +960,14 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
}
switch
(
osk
->
type
)
{
case
SOCK_DGRAM
:
break
;
case
SOCK_SEQPACKET
:
break
;
default:
sk_free
(
sk
);
ax25_free_cb
(
ax25
);
return
NULL
;
case
SOCK_DGRAM
:
break
;
case
SOCK_SEQPACKET
:
break
;
default:
sk_free
(
sk
);
ax25_free_cb
(
ax25
);
return
NULL
;
}
sock_init_data
(
NULL
,
sk
);
...
...
@@ -1029,52 +1032,52 @@ static int ax25_release(struct socket *sock)
if
(
sk
->
type
==
SOCK_SEQPACKET
)
{
switch
(
ax25
->
state
)
{
case
AX25_STATE_0
:
ax25_disconnect
(
ax25
,
0
);
ax25_destroy_socket
(
ax25
);
break
;
case
AX25_STATE_0
:
ax25_disconnect
(
ax25
,
0
);
ax25_destroy_socket
(
ax25
);
break
;
case
AX25_STATE_1
:
case
AX25_STATE_2
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_disconnect
(
ax25
,
0
);
ax25_destroy_socket
(
ax25
);
break
;
case
AX25_STATE_1
:
case
AX25_STATE_2
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_disconnect
(
ax25
,
0
);
ax25_destroy_socket
(
ax25
);
break
;
case
AX25_STATE_3
:
case
AX25_STATE_4
:
ax25_clear_queues
(
ax25
);
ax25
->
n2count
=
0
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_stop_t2timer
(
ax25
);
ax25_stop_t3timer
(
ax25
);
ax25_stop_idletimer
(
ax25
);
break
;
case
AX25_STATE_3
:
case
AX25_STATE_4
:
ax25_clear_queues
(
ax25
);
ax25
->
n2count
=
0
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_stop_t2timer
(
ax25
);
ax25_stop_t3timer
(
ax25
);
ax25_stop_idletimer
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
ax25_stop_t3timer
(
ax25
);
ax25_stop_idletimer
(
ax25
);
break
;
#endif
}
ax25_calculate_t1
(
ax25
);
ax25_start_t1timer
(
ax25
);
ax25
->
state
=
AX25_STATE_2
;
sk
->
state
=
TCP_CLOSE
;
sk
->
shutdown
|=
SEND_SHUTDOWN
;
sk
->
state_change
(
sk
);
sk
->
dead
=
1
;
sk
->
destroy
=
1
;
case
AX25_PROTO_DAMA_SLAVE
:
ax25_stop_t3timer
(
ax25
);
ax25_stop_idletimer
(
ax25
);
break
;
#endif
}
ax25_calculate_t1
(
ax25
);
ax25_start_t1timer
(
ax25
);
ax25
->
state
=
AX25_STATE_2
;
sk
->
state
=
TCP_CLOSE
;
sk
->
shutdown
|=
SEND_SHUTDOWN
;
sk
->
state_change
(
sk
);
sk
->
dead
=
1
;
sk
->
destroy
=
1
;
break
;
default:
break
;
default:
break
;
}
}
else
{
sk
->
state
=
TCP_CLOSE
;
...
...
@@ -1317,21 +1320,20 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
sk
->
state
=
TCP_SYN_SENT
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_establish_data_link
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_establish_data_link
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_establish_data_link
(
ax25
);
else
ax25_std_establish_data_link
(
ax25
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_establish_data_link
(
ax25
);
else
ax25_std_establish_data_link
(
ax25
);
break
;
#endif
}
...
...
@@ -1740,165 +1742,165 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
lock_kernel
();
switch
(
cmd
)
{
case
TIOCOUTQ
:
{
long
amount
;
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
if
(
amount
<
0
)
amount
=
0
;
res
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
}
case
TIOCINQ
:
{
struct
sk_buff
*
skb
;
long
amount
=
0L
;
/* These two are safe on a single CPU system as only user tasks fiddle here */
if
((
skb
=
skb_peek
(
&
sk
->
receive_queue
))
!=
NULL
)
amount
=
skb
->
len
;
res
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
}
case
TIOCOUTQ
:
{
long
amount
;
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
if
(
amount
<
0
)
amount
=
0
;
res
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
}
case
SIOCGSTAMP
:
if
(
sk
!=
NULL
)
{
if
(
sk
->
stamp
.
tv_sec
==
0
)
{
res
=
-
ENOENT
;
break
;
}
res
=
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
break
;
}
res
=
-
EINVAL
;
break
;
case
TIOCINQ
:
{
struct
sk_buff
*
skb
;
long
amount
=
0L
;
/* These two are safe on a single CPU system as only user tasks fiddle here */
if
((
skb
=
skb_peek
(
&
sk
->
receive_queue
))
!=
NULL
)
amount
=
skb
->
len
;
res
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
}
case
SIOCAX25ADDUID
:
/* Add a uid to the uid/call map table */
case
SIOCAX25DELUID
:
/* Delete a uid from the uid/call map table */
case
SIOCAX25GETUID
:
{
struct
sockaddr_ax25
sax25
;
if
(
copy_from_user
(
&
sax25
,
(
void
*
)
arg
,
sizeof
(
sax25
)))
{
res
=
-
EFAULT
;
case
SIOCGSTAMP
:
if
(
sk
!=
NULL
)
{
if
(
sk
->
stamp
.
tv_sec
==
0
)
{
res
=
-
ENOENT
;
break
;
}
res
=
ax25_uid_ioctl
(
cmd
,
&
sax25
);
res
=
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
break
;
}
res
=
-
EINVAL
;
break
;
case
SIOCAX25ADDUID
:
/* Add a uid to the uid/call map table */
case
SIOCAX25DELUID
:
/* Delete a uid from the uid/call map table */
case
SIOCAX25GETUID
:
{
struct
sockaddr_ax25
sax25
;
if
(
copy_from_user
(
&
sax25
,
(
void
*
)
arg
,
sizeof
(
sax25
)))
{
res
=
-
EFAULT
;
break
;
}
res
=
ax25_uid_ioctl
(
cmd
,
&
sax25
);
break
;
}
case
SIOCAX25NOUID
:
{
/* Set the default policy (default/bar) */
long
amount
;
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
break
;
}
if
(
get_user
(
amount
,
(
long
*
)
arg
))
{
res
=
-
EFAULT
;
break
;
}
if
(
amount
>
AX25_NOUID_BLOCK
)
{
res
=
-
EINVAL
;
break
;
}
ax25_uid_policy
=
amount
;
res
=
0
;
case
SIOCAX25NOUID
:
{
/* Set the default policy (default/bar) */
long
amount
;
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
break
;
}
case
SIOCADDRT
:
case
SIOCDELRT
:
case
SIOCAX25OPTRT
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
break
;
}
res
=
ax25_rt_ioctl
(
cmd
,
(
void
*
)
arg
);
if
(
get_user
(
amount
,
(
long
*
)
arg
))
{
res
=
-
EFAULT
;
break
;
}
if
(
amount
>
AX25_NOUID_BLOCK
)
{
res
=
-
EINVAL
;
break
;
}
ax25_uid_policy
=
amount
;
res
=
0
;
break
;
}
case
SIOCAX25CTLCON
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
break
;
}
res
=
ax25_ctl_ioctl
(
cmd
,
(
void
*
)
arg
);
case
SIOCADDRT
:
case
SIOCDELRT
:
case
SIOCAX25OPTRT
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
break
;
}
res
=
ax25_rt_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
case
SIOCAX25GETINFO
:
case
SIOCAX25GETINFOOLD
:
{
ax25_cb
*
ax25
=
ax25_sk
(
sk
);
struct
ax25_info_struct
ax25_info
;
ax25_info
.
t1
=
ax25
->
t1
/
HZ
;
ax25_info
.
t2
=
ax25
->
t2
/
HZ
;
ax25_info
.
t3
=
ax25
->
t3
/
HZ
;
ax25_info
.
idle
=
ax25
->
idle
/
(
60
*
HZ
);
ax25_info
.
n2
=
ax25
->
n2
;
ax25_info
.
t1timer
=
ax25_display_timer
(
&
ax25
->
t1timer
)
/
HZ
;
ax25_info
.
t2timer
=
ax25_display_timer
(
&
ax25
->
t2timer
)
/
HZ
;
ax25_info
.
t3timer
=
ax25_display_timer
(
&
ax25
->
t3timer
)
/
HZ
;
ax25_info
.
idletimer
=
ax25_display_timer
(
&
ax25
->
idletimer
)
/
(
60
*
HZ
);
ax25_info
.
n2count
=
ax25
->
n2count
;
ax25_info
.
state
=
ax25
->
state
;
ax25_info
.
rcv_q
=
atomic_read
(
&
sk
->
rmem_alloc
);
ax25_info
.
snd_q
=
atomic_read
(
&
sk
->
wmem_alloc
);
ax25_info
.
vs
=
ax25
->
vs
;
ax25_info
.
vr
=
ax25
->
vr
;
ax25_info
.
va
=
ax25
->
va
;
ax25_info
.
vs_max
=
ax25
->
vs
;
/* reserved */
ax25_info
.
paclen
=
ax25
->
paclen
;
ax25_info
.
window
=
ax25
->
window
;
/* old structure? */
if
(
cmd
==
SIOCAX25GETINFOOLD
)
{
static
int
warned
=
0
;
if
(
!
warned
)
{
printk
(
KERN_INFO
"%s uses old SIOCAX25GETINFO
\n
"
,
current
->
comm
);
warned
=
1
;
}
if
(
copy_to_user
((
void
*
)
arg
,
&
ax25_info
,
sizeof
(
struct
ax25_info_struct_depreciated
)))
{
res
=
-
EFAULT
;
break
;
}
}
else
{
if
(
copy_to_user
((
void
*
)
arg
,
&
ax25_info
,
sizeof
(
struct
ax25_info_struct
)))
{
res
=
-
EINVAL
;
break
;
}
}
res
=
0
;
case
SIOCAX25CTLCON
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
break
;
}
res
=
ax25_ctl_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
case
SIOCAX25GETINFO
:
case
SIOCAX25GETINFOOLD
:
{
ax25_cb
*
ax25
=
ax25_sk
(
sk
);
struct
ax25_info_struct
ax25_info
;
ax25_info
.
t1
=
ax25
->
t1
/
HZ
;
ax25_info
.
t2
=
ax25
->
t2
/
HZ
;
ax25_info
.
t3
=
ax25
->
t3
/
HZ
;
ax25_info
.
idle
=
ax25
->
idle
/
(
60
*
HZ
);
ax25_info
.
n2
=
ax25
->
n2
;
ax25_info
.
t1timer
=
ax25_display_timer
(
&
ax25
->
t1timer
)
/
HZ
;
ax25_info
.
t2timer
=
ax25_display_timer
(
&
ax25
->
t2timer
)
/
HZ
;
ax25_info
.
t3timer
=
ax25_display_timer
(
&
ax25
->
t3timer
)
/
HZ
;
ax25_info
.
idletimer
=
ax25_display_timer
(
&
ax25
->
idletimer
)
/
(
60
*
HZ
);
ax25_info
.
n2count
=
ax25
->
n2count
;
ax25_info
.
state
=
ax25
->
state
;
ax25_info
.
rcv_q
=
atomic_read
(
&
sk
->
rmem_alloc
);
ax25_info
.
snd_q
=
atomic_read
(
&
sk
->
wmem_alloc
);
ax25_info
.
vs
=
ax25
->
vs
;
ax25_info
.
vr
=
ax25
->
vr
;
ax25_info
.
va
=
ax25
->
va
;
ax25_info
.
vs_max
=
ax25
->
vs
;
/* reserved */
ax25_info
.
paclen
=
ax25
->
paclen
;
ax25_info
.
window
=
ax25
->
window
;
/* old structure? */
if
(
cmd
==
SIOCAX25GETINFOOLD
)
{
static
int
warned
=
0
;
if
(
!
warned
)
{
printk
(
KERN_INFO
"%s uses old SIOCAX25GETINFO
\n
"
,
current
->
comm
);
warned
=
1
;
}
case
SIOCAX25ADDFWD
:
case
SIOCAX25DELFWD
:
{
struct
ax25_fwd_struct
ax25_fwd
;
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
if
(
copy_to_user
((
void
*
)
arg
,
&
ax25_info
,
sizeof
(
struct
ax25_info_struct_depreciated
)))
{
res
=
-
EFAULT
;
break
;
}
if
(
copy_from_user
(
&
ax25_fwd
,
(
void
*
)
arg
,
sizeof
(
ax25_fwd
)))
{
res
=
-
EFAULT
;
}
else
{
if
(
copy_to_user
((
void
*
)
arg
,
&
ax25_info
,
sizeof
(
struct
ax25_info_struct
)))
{
res
=
-
EINVAL
;
break
;
}
res
=
ax25_fwd_ioctl
(
cmd
,
&
ax25_fwd
);
}
res
=
0
;
break
;
}
case
SIOCAX25ADDFWD
:
case
SIOCAX25DELFWD
:
{
struct
ax25_fwd_struct
ax25_fwd
;
if
(
!
capable
(
CAP_NET_ADMIN
))
{
res
=
-
EPERM
;
break
;
}
case
SIOCGIFADDR
:
case
SIOCSIFADDR
:
case
SIOCGIFDSTADDR
:
case
SIOCSIFDSTADDR
:
case
SIOCGIFBRDADDR
:
case
SIOCSIFBRDADDR
:
case
SIOCGIFNETMASK
:
case
SIOCSIFNETMASK
:
case
SIOCGIFMETRIC
:
case
SIOCSIFMETRIC
:
res
=
-
EINVAL
;
if
(
copy_from_user
(
&
ax25_fwd
,
(
void
*
)
arg
,
sizeof
(
ax25_fwd
)))
{
res
=
-
EFAULT
;
break
;
}
res
=
ax25_fwd_ioctl
(
cmd
,
&
ax25_fwd
);
break
;
}
default:
res
=
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
case
SIOCGIFADDR
:
case
SIOCSIFADDR
:
case
SIOCGIFDSTADDR
:
case
SIOCSIFDSTADDR
:
case
SIOCGIFBRDADDR
:
case
SIOCSIFBRDADDR
:
case
SIOCGIFNETMASK
:
case
SIOCSIFNETMASK
:
case
SIOCGIFMETRIC
:
case
SIOCSIFMETRIC
:
res
=
-
EINVAL
;
break
;
default:
res
=
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
}
unlock_kernel
();
...
...
net/ax25/ax25_dev.c
View file @
6244be2f
...
...
@@ -174,22 +174,22 @@ int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
return
-
EINVAL
;
switch
(
cmd
)
{
case
SIOCAX25ADDFWD
:
if
((
fwd_dev
=
ax25_addr_ax25dev
(
&
fwd
->
port_to
))
==
NULL
)
return
-
EINVAL
;
if
(
ax25_dev
->
forward
!=
NULL
)
return
-
EINVAL
;
ax25_dev
->
forward
=
fwd_dev
->
dev
;
break
;
case
SIOCAX25DELFWD
:
if
(
ax25_dev
->
forward
==
NULL
)
return
-
EINVAL
;
ax25_dev
->
forward
=
NULL
;
break
;
case
SIOCAX25ADDFWD
:
if
((
fwd_dev
=
ax25_addr_ax25dev
(
&
fwd
->
port_to
))
==
NULL
)
return
-
EINVAL
;
if
(
ax25_dev
->
forward
!=
NULL
)
return
-
EINVAL
;
ax25_dev
->
forward
=
fwd_dev
->
dev
;
break
;
default:
case
SIOCAX25DELFWD
:
if
(
ax25_dev
->
forward
==
NULL
)
return
-
EINVAL
;
ax25_dev
->
forward
=
NULL
;
break
;
default:
return
-
EINVAL
;
}
return
0
;
...
...
net/ax25/ax25_ds_in.c
View file @
6244be2f
...
...
@@ -53,54 +53,56 @@
static
int
ax25_ds_state1_machine
(
ax25_cb
*
ax25
,
struct
sk_buff
*
skb
,
int
frametype
,
int
pf
,
int
type
)
{
switch
(
frametype
)
{
case
AX25_SABM
:
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_SABM
:
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_SABME
:
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_DM
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_UA
:
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25
->
state
=
AX25_STATE_3
;
ax25
->
n2count
=
0
;
if
(
ax25
->
sk
!=
NULL
)
{
ax25
->
sk
->
state
=
TCP_ESTABLISHED
;
/* For WAIT_SABM connections we will produce an accept ready socket here */
if
(
!
ax25
->
sk
->
dead
)
ax25
->
sk
->
state_change
(
ax25
->
sk
);
}
ax25_dama_on
(
ax25
);
/* according to DK4EGs spec we are required to
* send a RR RESPONSE FINAL NR=0.
*/
ax25_std_enquiry_response
(
ax25
);
break
;
case
AX25_DM
:
if
(
pf
)
ax25_disconnect
(
ax25
,
ECONNREFUSED
);
break
;
default:
if
(
pf
)
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLON
,
AX25_COMMAND
);
break
;
case
AX25_SABME
:
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_DM
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_UA
:
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25
->
state
=
AX25_STATE_3
;
ax25
->
n2count
=
0
;
if
(
ax25
->
sk
!=
NULL
)
{
ax25
->
sk
->
state
=
TCP_ESTABLISHED
;
/* For WAIT_SABM connections we will produce an accept ready socket here */
if
(
!
ax25
->
sk
->
dead
)
ax25
->
sk
->
state_change
(
ax25
->
sk
);
}
ax25_dama_on
(
ax25
);
/* according to DK4EGs spec we are required to
* send a RR RESPONSE FINAL NR=0.
*/
ax25_std_enquiry_response
(
ax25
);
break
;
case
AX25_DM
:
if
(
pf
)
ax25_disconnect
(
ax25
,
ECONNREFUSED
);
break
;
default:
if
(
pf
)
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLON
,
AX25_COMMAND
);
break
;
}
return
0
;
...
...
@@ -114,38 +116,38 @@ static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int framet
static
int
ax25_ds_state2_machine
(
ax25_cb
*
ax25
,
struct
sk_buff
*
skb
,
int
frametype
,
int
pf
,
int
type
)
{
switch
(
frametype
)
{
case
AX25_SABM
:
case
AX25_SABME
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_dama_off
(
ax25
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
case
AX25_SABM
:
case
AX25_SABME
:
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_dama_off
(
ax25
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_dama_off
(
ax25
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_DM
:
case
AX25_UA
:
if
(
pf
)
{
ax25_dama_off
(
ax25
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_DM
:
case
AX25_UA
:
if
(
pf
)
{
ax25_dama_off
(
ax25
);
ax25_disconnect
(
ax25
,
0
);
}
break
;
case
AX25_I
:
case
AX25_REJ
:
case
AX25_RNR
:
case
AX25_RR
:
if
(
pf
)
{
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_dama_off
(
ax25
);
}
break
;
}
break
;
case
AX25_I
:
case
AX25_REJ
:
case
AX25_RNR
:
case
AX25_RR
:
if
(
pf
)
{
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_dama_off
(
ax25
);
}
break
;
default:
break
;
default:
break
;
}
return
0
;
...
...
@@ -161,127 +163,127 @@ static int ax25_ds_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int framet
int
queued
=
0
;
switch
(
frametype
)
{
case
AX25_SABM
:
case
AX25_SABME
:
if
(
frametype
==
AX25_SABM
)
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
else
{
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
}
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
condition
=
0x00
;
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25_requeue_frames
(
ax25
);
ax25_dama_on
(
ax25
);
break
;
case
AX25_SABM
:
case
AX25_SABME
:
if
(
frametype
==
AX25_SABM
)
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
else
{
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
}
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
condition
=
0x00
;
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25_requeue_frames
(
ax25
);
ax25_dama_on
(
ax25
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_dama_off
(
ax25
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_DM
:
ax25_dama_off
(
ax25
);
ax25_disconnect
(
ax25
,
ECONNRESET
);
break
;
case
AX25_RR
:
case
AX25_RNR
:
if
(
frametype
==
AX25_RR
)
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
else
ax25
->
condition
|=
AX25_COND_PEER_RX_BUSY
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
if
(
ax25_check_iframes_acked
(
ax25
,
nr
))
ax25
->
n2count
=
0
;
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_ds_enquiry_response
(
ax25
);
}
else
{
ax25_ds_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_dama_off
(
ax25
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_REJ
:
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
case
AX25_DM
:
ax25_dama_off
(
ax25
);
ax25_disconnect
(
ax25
,
ECONNRESET
);
break
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
if
(
ax25
->
va
!=
nr
)
ax25
->
n2count
=
0
;
case
AX25_RR
:
case
AX25_RNR
:
if
(
frametype
==
AX25_RR
)
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
else
ax25
->
condition
|=
AX25_COND_PEER_RX_BUSY
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
if
(
ax25_check_iframes_acked
(
ax25
,
nr
))
ax25
->
n2count
=
0
;
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_ds_enquiry_response
(
ax25
);
}
else
{
ax25_ds_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
case
AX25_REJ
:
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
if
(
ax25
->
va
!=
nr
)
ax25
->
n2count
=
0
;
ax25_frames_acked
(
ax25
,
nr
);
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_requeue_frames
(
ax25
);
ax25_frames_acked
(
ax25
,
nr
);
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_requeue_frames
(
ax25
);
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_ds_enquiry_response
(
ax25
);
}
else
{
ax25_ds_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_ds_enquiry_response
(
ax25
);
}
else
{
ax25_ds_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
case
AX25_I
:
if
(
!
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_ds_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
case
AX25_I
:
if
(
!
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_ds_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
}
if
(
ax25
->
condition
&
AX25_COND_PEER_RX_BUSY
)
{
ax25_frames_acked
(
ax25
,
nr
);
}
if
(
ax25
->
condition
&
AX25_COND_PEER_RX_BUSY
)
{
ax25_frames_acked
(
ax25
,
nr
);
ax25
->
n2count
=
0
;
}
else
{
if
(
ax25_check_iframes_acked
(
ax25
,
nr
))
ax25
->
n2count
=
0
;
}
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
{
if
(
pf
)
ax25_ds_enquiry_response
(
ax25
);
break
;
}
if
(
ns
==
ax25
->
vr
)
{
ax25
->
vr
=
(
ax25
->
vr
+
1
)
%
ax25
->
modulus
;
queued
=
ax25_rx_iframe
(
ax25
,
skb
);
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
ax25
->
vr
=
ns
;
/* ax25->vr - 1 */
ax25
->
condition
&=
~
AX25_COND_REJECT
;
if
(
pf
)
{
ax25_ds_enquiry_response
(
ax25
);
}
else
{
if
(
ax25_check_iframes_acked
(
ax25
,
nr
))
ax25
->
n2count
=
0
;
if
(
!
(
ax25
->
condition
&
AX25_COND_ACK_PENDING
))
{
ax25
->
condition
|=
AX25_COND_ACK_PENDING
;
ax25_start_t2timer
(
ax25
);
}
}
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
{
}
else
{
if
(
ax25
->
condition
&
AX25_COND_REJECT
)
{
if
(
pf
)
ax25_ds_enquiry_response
(
ax25
);
break
;
}
if
(
ns
==
ax25
->
vr
)
{
ax25
->
vr
=
(
ax25
->
vr
+
1
)
%
ax25
->
modulus
;
queued
=
ax25_rx_iframe
(
ax25
,
skb
);
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
ax25
->
vr
=
ns
;
/* ax25->vr - 1 */
ax25
->
condition
&=
~
AX25_COND_REJECT
;
if
(
pf
)
{
ax25_ds_enquiry_response
(
ax25
);
}
else
{
if
(
!
(
ax25
->
condition
&
AX25_COND_ACK_PENDING
))
{
ax25
->
condition
|=
AX25_COND_ACK_PENDING
;
ax25_start_t2timer
(
ax25
);
}
}
}
else
{
if
(
ax25
->
condition
&
AX25_COND_REJECT
)
{
if
(
pf
)
ax25_ds_enquiry_response
(
ax25
);
}
else
{
ax25
->
condition
|=
AX25_COND_REJECT
;
ax25_ds_enquiry_response
(
ax25
);
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
}
ax25
->
condition
|=
AX25_COND_REJECT
;
ax25_ds_enquiry_response
(
ax25
);
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
}
break
;
}
break
;
case
AX25_FRMR
:
case
AX25_ILLEGAL
:
ax25_ds_establish_data_link
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
case
AX25_FRMR
:
case
AX25_ILLEGAL
:
ax25_ds_establish_data_link
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
default:
break
;
default:
break
;
}
return
queued
;
...
...
@@ -297,15 +299,15 @@ int ax25_ds_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
frametype
=
ax25_decode
(
ax25
,
skb
,
&
ns
,
&
nr
,
&
pf
);
switch
(
ax25
->
state
)
{
case
AX25_STATE_1
:
queued
=
ax25_ds_state1_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_2
:
queued
=
ax25_ds_state2_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_3
:
queued
=
ax25_ds_state3_machine
(
ax25
,
skb
,
frametype
,
ns
,
nr
,
pf
,
type
);
break
;
case
AX25_STATE_1
:
queued
=
ax25_ds_state1_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_2
:
queued
=
ax25_ds_state2_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_3
:
queued
=
ax25_ds_state3_machine
(
ax25
,
skb
,
frametype
,
ns
,
nr
,
pf
,
type
);
break
;
}
return
queued
;
...
...
net/ax25/ax25_ds_timer.c
View file @
6244be2f
...
...
@@ -108,28 +108,28 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
{
switch
(
ax25
->
state
)
{
case
AX25_STATE_0
:
/* Magic here: If we listen() and a new link dies before it
is accepted() it isn't 'dead' so doesn't get removed. */
if
(
ax25
->
sk
==
NULL
||
ax25
->
sk
->
destroy
||
(
ax25
->
sk
->
state
==
TCP_LISTEN
&&
ax25
->
sk
->
dead
))
{
ax25_destroy_socket
(
ax25
);
return
;
}
break
;
case
AX25_STATE_3
:
/*
* Check the state of the receive buffer.
*/
if
(
ax25
->
sk
!=
NULL
)
{
if
(
atomic_read
(
&
ax25
->
sk
->
rmem_alloc
)
<
(
ax25
->
sk
->
rcvbuf
/
2
)
&&
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
))
{
ax25
->
condition
&=
~
AX25_COND_OWN_RX_BUSY
;
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
break
;
}
case
AX25_STATE_0
:
/* Magic here: If we listen() and a new link dies before it
is accepted() it isn't 'dead' so doesn't get removed. */
if
(
ax25
->
sk
==
NULL
||
ax25
->
sk
->
destroy
||
(
ax25
->
sk
->
state
==
TCP_LISTEN
&&
ax25
->
sk
->
dead
))
{
ax25_destroy_socket
(
ax25
);
return
;
}
break
;
case
AX25_STATE_3
:
/*
* Check the state of the receive buffer.
*/
if
(
ax25
->
sk
!=
NULL
)
{
if
(
atomic_read
(
&
ax25
->
sk
->
rmem_alloc
)
<
(
ax25
->
sk
->
rcvbuf
/
2
)
&&
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
))
{
ax25
->
condition
&=
~
AX25_COND_OWN_RX_BUSY
;
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
break
;
}
break
;
}
break
;
}
ax25_start_heartbeat
(
ax25
);
...
...
@@ -182,46 +182,45 @@ void ax25_ds_idletimer_expiry(ax25_cb *ax25)
void
ax25_ds_t1_timeout
(
ax25_cb
*
ax25
)
{
switch
(
ax25
->
state
)
{
case
AX25_STATE_1
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25
->
n2count
=
0
;
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLOFF
,
AX25_COMMAND
);
}
}
else
{
ax25
->
n2count
++
;
if
(
ax25
->
modulus
==
AX25_MODULUS
)
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLOFF
,
AX25_COMMAND
);
else
ax25_send_control
(
ax25
,
AX25_SABME
,
AX25_POLLOFF
,
AX25_COMMAND
);
}
break
;
case
AX25_STATE_2
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
}
break
;
case
AX25_STATE_3
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DM
,
AX25_POLLON
,
AX25_RESPONSE
);
case
AX25_STATE_1
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25
->
n2count
=
0
;
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLOFF
,
AX25_COMMAND
);
}
break
;
}
else
{
ax25
->
n2count
++
;
if
(
ax25
->
modulus
==
AX25_MODULUS
)
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLOFF
,
AX25_COMMAND
);
else
ax25_send_control
(
ax25
,
AX25_SABME
,
AX25_POLLOFF
,
AX25_COMMAND
);
}
break
;
case
AX25_STATE_2
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
}
break
;
case
AX25_STATE_3
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DM
,
AX25_POLLON
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
}
break
;
}
ax25_calculate_t1
(
ax25
);
...
...
net/ax25/ax25_iface.c
View file @
6244be2f
...
...
@@ -41,7 +41,7 @@ static struct protocol_struct {
unsigned
int
pid
;
int
(
*
func
)(
struct
sk_buff
*
,
ax25_cb
*
);
}
*
protocol_list
;
static
spinlock_t
protocol_list_lock
=
SPIN
_LOCK_UNLOCKED
;
static
rwlock_t
protocol_list_lock
=
RW
_LOCK_UNLOCKED
;
static
struct
linkfail_struct
{
struct
linkfail_struct
*
next
;
...
...
@@ -59,7 +59,6 @@ static spinlock_t listen_lock = SPIN_LOCK_UNLOCKED;
int
ax25_protocol_register
(
unsigned
int
pid
,
int
(
*
func
)(
struct
sk_buff
*
,
ax25_cb
*
))
{
struct
protocol_struct
*
protocol
;
unsigned
long
flags
;
if
(
pid
==
AX25_P_TEXT
||
pid
==
AX25_P_SEGMENT
)
return
0
;
...
...
@@ -73,10 +72,10 @@ int ax25_protocol_register(unsigned int pid, int (*func)(struct sk_buff *, ax25_
protocol
->
pid
=
pid
;
protocol
->
func
=
func
;
spin_lock_irqsave
(
&
protocol_list_lock
,
flags
);
write_lock
(
&
protocol_list_lock
);
protocol
->
next
=
protocol_list
;
protocol_list
=
protocol
;
spin_unlock_irqrestore
(
&
protocol_list_lock
,
flags
);
write_unlock
(
&
protocol_list_lock
);
return
1
;
}
...
...
@@ -84,18 +83,17 @@ int ax25_protocol_register(unsigned int pid, int (*func)(struct sk_buff *, ax25_
void
ax25_protocol_release
(
unsigned
int
pid
)
{
struct
protocol_struct
*
s
,
*
protocol
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
protocol_list_lock
,
flags
);
write_lock
(
&
protocol_list_lock
);
protocol
=
protocol_list
;
if
(
protocol
==
NULL
)
{
spin_unlock_irqrestore
(
&
protocol_list_lock
,
flags
);
write_unlock
(
&
protocol_list_lock
);
return
;
}
if
(
protocol
->
pid
==
pid
)
{
protocol_list
=
protocol
->
next
;
spin_unlock_irqrestore
(
&
protocol_list_lock
,
flags
);
write_unlock
(
&
protocol_list_lock
);
kfree
(
protocol
);
return
;
}
...
...
@@ -104,14 +102,14 @@ void ax25_protocol_release(unsigned int pid)
if
(
protocol
->
next
->
pid
==
pid
)
{
s
=
protocol
->
next
;
protocol
->
next
=
protocol
->
next
->
next
;
spin_unlock_irqrestore
(
&
protocol_list_lock
,
flags
);
write_unlock
(
&
protocol_list_lock
);
kfree
(
s
);
return
;
}
protocol
=
protocol
->
next
;
}
spin_unlock_irqrestore
(
&
protocol_list_lock
,
flags
);
write_unlock
(
&
protocol_list_lock
);
}
int
ax25_linkfail_register
(
void
(
*
func
)(
ax25_cb
*
,
int
))
...
...
@@ -220,15 +218,14 @@ int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
{
int
(
*
res
)(
struct
sk_buff
*
,
ax25_cb
*
)
=
NULL
;
struct
protocol_struct
*
protocol
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
protocol_list_lock
,
flags
);
read_lock
(
&
protocol_list_lock
);
for
(
protocol
=
protocol_list
;
protocol
!=
NULL
;
protocol
=
protocol
->
next
)
if
(
protocol
->
pid
==
pid
)
{
res
=
protocol
->
func
;
break
;
}
spin_unlock_irqrestore
(
&
protocol_list_lock
,
flags
);
read_unlock
(
&
protocol_list_lock
);
return
res
;
}
...
...
@@ -261,16 +258,15 @@ void ax25_link_failed(ax25_cb *ax25, int reason)
int
ax25_protocol_is_registered
(
unsigned
int
pid
)
{
struct
protocol_struct
*
protocol
;
unsigned
long
flags
;
int
res
=
0
;
spin_lock_irqsave
(
&
protocol_list_lock
,
flags
);
read_lock
(
&
protocol_list_lock
);
for
(
protocol
=
protocol_list
;
protocol
!=
NULL
;
protocol
=
protocol
->
next
)
if
(
protocol
->
pid
==
pid
)
{
res
=
1
;
break
;
}
spin_unlock_irqrestore
(
&
protocol_list_lock
,
flags
);
read_unlock
(
&
protocol_list_lock
);
return
res
;
}
net/ax25/ax25_in.c
View file @
6244be2f
...
...
@@ -199,18 +199,18 @@ static int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, i
return
0
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
queued
=
ax25_std_frame_in
(
ax25
,
skb
,
type
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
queued
=
ax25_std_frame_in
(
ax25
,
skb
,
type
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
if
(
dama
||
ax25
->
ax25_dev
->
dama
.
slave
)
queued
=
ax25_ds_frame_in
(
ax25
,
skb
,
type
);
else
queued
=
ax25_std_frame_in
(
ax25
,
skb
,
type
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
if
(
dama
||
ax25
->
ax25_dev
->
dama
.
slave
)
queued
=
ax25_ds_frame_in
(
ax25
,
skb
,
type
);
else
queued
=
ax25_std_frame_in
(
ax25
,
skb
,
type
);
break
;
#endif
}
...
...
@@ -285,47 +285,47 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *d
/* Now we are pointing at the pid byte */
switch
(
skb
->
data
[
1
])
{
#ifdef CONFIG_INET
case
AX25_P_IP
:
skb_pull
(
skb
,
2
);
/* drop PID/CTRL */
skb
->
h
.
raw
=
skb
->
data
;
skb
->
nh
.
raw
=
skb
->
data
;
skb
->
dev
=
dev
;
skb
->
pkt_type
=
PACKET_HOST
;
skb
->
protocol
=
htons
(
ETH_P_IP
);
ip_rcv
(
skb
,
dev
,
ptype
);
/* Note ptype here is the wrong one, fix me later */
break
;
case
AX25_P_ARP
:
skb_pull
(
skb
,
2
);
skb
->
h
.
raw
=
skb
->
data
;
skb
->
nh
.
raw
=
skb
->
data
;
skb
->
dev
=
dev
;
skb
->
pkt_type
=
PACKET_HOST
;
skb
->
protocol
=
htons
(
ETH_P_ARP
);
arp_rcv
(
skb
,
dev
,
ptype
);
/* Note ptype here is wrong... */
break
;
case
AX25_P_IP
:
skb_pull
(
skb
,
2
);
/* drop PID/CTRL */
skb
->
h
.
raw
=
skb
->
data
;
skb
->
nh
.
raw
=
skb
->
data
;
skb
->
dev
=
dev
;
skb
->
pkt_type
=
PACKET_HOST
;
skb
->
protocol
=
htons
(
ETH_P_IP
);
ip_rcv
(
skb
,
dev
,
ptype
);
/* Note ptype here is the wrong one, fix me later */
break
;
case
AX25_P_ARP
:
skb_pull
(
skb
,
2
);
skb
->
h
.
raw
=
skb
->
data
;
skb
->
nh
.
raw
=
skb
->
data
;
skb
->
dev
=
dev
;
skb
->
pkt_type
=
PACKET_HOST
;
skb
->
protocol
=
htons
(
ETH_P_ARP
);
arp_rcv
(
skb
,
dev
,
ptype
);
/* Note ptype here is wrong... */
break
;
#endif
case
AX25_P_TEXT
:
/* Now find a suitable dgram socket */
if
((
sk
=
ax25_find_socket
(
&
dest
,
&
src
,
SOCK_DGRAM
))
!=
NULL
)
{
if
(
atomic_read
(
&
sk
->
rmem_alloc
)
>=
sk
->
rcvbuf
)
{
kfree_skb
(
skb
);
}
else
{
/*
* Remove the control and PID.
*/
skb_pull
(
skb
,
2
);
if
(
sock_queue_rcv_skb
(
sk
,
skb
)
!=
0
)
kfree_skb
(
skb
);
}
}
else
{
case
AX25_P_TEXT
:
/* Now find a suitable dgram socket */
if
((
sk
=
ax25_find_socket
(
&
dest
,
&
src
,
SOCK_DGRAM
))
!=
NULL
)
{
if
(
atomic_read
(
&
sk
->
rmem_alloc
)
>=
sk
->
rcvbuf
)
{
kfree_skb
(
skb
);
}
else
{
/*
* Remove the control and PID.
*/
skb_pull
(
skb
,
2
);
if
(
sock_queue_rcv_skb
(
sk
,
skb
)
!=
0
)
kfree_skb
(
skb
);
}
break
;
}
else
{
kfree_skb
(
skb
);
}
break
;
default:
kfree_skb
(
skb
);
/* Will scan SOCK_AX25 RAW sockets */
break
;
default:
kfree_skb
(
skb
);
/* Will scan SOCK_AX25 RAW sockets */
break
;
}
return
0
;
...
...
net/ax25/ax25_ip.c
View file @
6244be2f
...
...
@@ -88,16 +88,16 @@ int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short
/* Append a suitable AX.25 PID */
switch
(
type
)
{
case
ETH_P_IP
:
*
buff
++
=
AX25_P_IP
;
break
;
case
ETH_P_ARP
:
*
buff
++
=
AX25_P_ARP
;
break
;
default:
printk
(
KERN_ERR
"AX.25: ax25_encapsulate - wrong protocol type 0x%2.2x
\n
"
,
type
);
*
buff
++
=
0
;
break
;
case
ETH_P_IP
:
*
buff
++
=
AX25_P_IP
;
break
;
case
ETH_P_ARP
:
*
buff
++
=
AX25_P_ARP
;
break
;
default:
printk
(
KERN_ERR
"AX.25: ax25_encapsulate - wrong protocol type 0x%2.2x
\n
"
,
type
);
*
buff
++
=
0
;
break
;
}
if
(
daddr
!=
NULL
)
...
...
net/ax25/ax25_out.c
View file @
6244be2f
...
...
@@ -104,18 +104,18 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax2
}
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_establish_data_link
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_establish_data_link
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25_dev
->
dama
.
slave
)
ax25_ds_establish_data_link
(
ax25
);
else
ax25_std_establish_data_link
(
ax25
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25_dev
->
dama
.
slave
)
ax25_ds_establish_data_link
(
ax25
);
else
ax25_std_establish_data_link
(
ax25
);
break
;
#endif
}
...
...
@@ -203,19 +203,19 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
}
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_kick
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_kick
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
/*
* A DAMA slave is _required_ to work as normal AX.25L2V2
* if no DAMA master is available.
*/
case
AX25_PROTO_DAMA_SLAVE
:
if
(
!
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_kick
(
ax25
);
break
;
/*
* A DAMA slave is _required_ to work as normal AX.25L2V2
* if no DAMA master is available.
*/
case
AX25_PROTO_DAMA_SLAVE
:
if
(
!
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_kick
(
ax25
);
break
;
#endif
}
}
...
...
@@ -306,15 +306,15 @@ void ax25_kick(ax25_cb *ax25)
* in DAMA mode.
*/
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_send_iframe
(
ax25
,
skbn
,
(
last
)
?
AX25_POLLON
:
AX25_POLLOFF
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_send_iframe
(
ax25
,
skbn
,
(
last
)
?
AX25_POLLON
:
AX25_POLLOFF
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
ax25_send_iframe
(
ax25
,
skbn
,
AX25_POLLOFF
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
ax25_send_iframe
(
ax25
,
skbn
,
AX25_POLLOFF
);
break
;
#endif
}
...
...
net/ax25/ax25_route.c
View file @
6244be2f
...
...
@@ -66,7 +66,7 @@
#include <linux/init.h>
static
ax25_route
*
ax25_route_list
;
static
spinlock_t
ax25_route_lock
=
SPIN
_LOCK_UNLOCKED
;
static
rwlock_t
ax25_route_lock
=
RW
_LOCK_UNLOCKED
;
static
ax25_route
*
ax25_find_route
(
ax25_address
*
,
struct
net_device
*
);
...
...
@@ -89,9 +89,8 @@ static inline void ax25_route_invert(ax25_digi *in, ax25_digi *out)
void
ax25_rt_device_down
(
struct
net_device
*
dev
)
{
ax25_route
*
s
,
*
t
,
*
ax25_rt
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
ax25_route_lock
,
flags
);
write_lock
(
&
ax25_route_lock
);
ax25_rt
=
ax25_route_list
;
while
(
ax25_rt
!=
NULL
)
{
s
=
ax25_rt
;
...
...
@@ -116,12 +115,11 @@ void ax25_rt_device_down(struct net_device *dev)
}
}
}
spin_unlock_irqrestore
(
&
ax25_route_lock
,
flags
);
write_unlock
(
&
ax25_route_lock
);
}
int
ax25_rt_ioctl
(
unsigned
int
cmd
,
void
*
arg
)
{
unsigned
long
flags
;
ax25_route
*
s
,
*
t
,
*
ax25_rt
;
struct
ax25_routes_struct
route
;
struct
ax25_route_opt_struct
rt_option
;
...
...
@@ -129,115 +127,122 @@ int ax25_rt_ioctl(unsigned int cmd, void *arg)
int
i
;
switch
(
cmd
)
{
case
SIOCADDRT
:
if
(
copy_from_user
(
&
route
,
arg
,
sizeof
(
route
)))
return
-
EFAULT
;
if
((
ax25_dev
=
ax25_addr_ax25dev
(
&
route
.
port_addr
))
==
NULL
)
return
-
EINVAL
;
if
(
route
.
digi_count
>
AX25_MAX_DIGIS
)
return
-
EINVAL
;
for
(
ax25_rt
=
ax25_route_list
;
ax25_rt
!=
NULL
;
ax25_rt
=
ax25_rt
->
next
)
{
if
(
ax25cmp
(
&
ax25_rt
->
callsign
,
&
route
.
dest_addr
)
==
0
&&
ax25_rt
->
dev
==
ax25_dev
->
dev
)
{
if
(
ax25_rt
->
digipeat
!=
NULL
)
{
kfree
(
ax25_rt
->
digipeat
);
ax25_rt
->
digipeat
=
NULL
;
case
SIOCADDRT
:
if
(
copy_from_user
(
&
route
,
arg
,
sizeof
(
route
)))
return
-
EFAULT
;
if
((
ax25_dev
=
ax25_addr_ax25dev
(
&
route
.
port_addr
))
==
NULL
)
return
-
EINVAL
;
if
(
route
.
digi_count
>
AX25_MAX_DIGIS
)
return
-
EINVAL
;
write_lock
(
ax25_route_lock
);
for
(
ax25_rt
=
ax25_route_list
;
ax25_rt
!=
NULL
;
ax25_rt
=
ax25_rt
->
next
)
{
if
(
ax25cmp
(
&
ax25_rt
->
callsign
,
&
route
.
dest_addr
)
==
0
&&
ax25_rt
->
dev
==
ax25_dev
->
dev
)
{
if
(
ax25_rt
->
digipeat
!=
NULL
)
{
kfree
(
ax25_rt
->
digipeat
);
ax25_rt
->
digipeat
=
NULL
;
}
if
(
route
.
digi_count
!=
0
)
{
if
((
ax25_rt
->
digipeat
=
kmalloc
(
sizeof
(
ax25_digi
),
GFP_ATOMIC
))
==
NULL
)
{
write_unlock
(
ax25_route_lock
);
return
-
ENOMEM
;
}
if
(
route
.
digi_count
!=
0
)
{
if
((
ax25_rt
->
digipeat
=
kmalloc
(
sizeof
(
ax25_digi
),
GFP_ATOMIC
))
==
NULL
)
return
-
ENOMEM
;
ax25_rt
->
digipeat
->
lastrepeat
=
-
1
;
ax25_rt
->
digipeat
->
ndigi
=
route
.
digi_count
;
for
(
i
=
0
;
i
<
route
.
digi_count
;
i
++
)
{
ax25_rt
->
digipeat
->
repeated
[
i
]
=
0
;
ax25_rt
->
digipeat
->
calls
[
i
]
=
route
.
digi_addr
[
i
];
}
ax25_rt
->
digipeat
->
lastrepeat
=
-
1
;
ax25_rt
->
digipeat
->
ndigi
=
route
.
digi_count
;
for
(
i
=
0
;
i
<
route
.
digi_count
;
i
++
)
{
ax25_rt
->
digipeat
->
repeated
[
i
]
=
0
;
ax25_rt
->
digipeat
->
calls
[
i
]
=
route
.
digi_addr
[
i
];
}
return
0
;
}
return
0
;
}
if
((
ax25_rt
=
kmalloc
(
sizeof
(
ax25_route
),
GFP_ATOMIC
))
==
NULL
)
}
if
((
ax25_rt
=
kmalloc
(
sizeof
(
ax25_route
),
GFP_ATOMIC
))
==
NULL
)
{
write_unlock
(
ax25_route_lock
);
return
-
ENOMEM
;
}
ax25_rt
->
callsign
=
route
.
dest_addr
;
ax25_rt
->
dev
=
ax25_dev
->
dev
;
ax25_rt
->
digipeat
=
NULL
;
ax25_rt
->
ip_mode
=
' '
;
if
(
route
.
digi_count
!=
0
)
{
if
((
ax25_rt
->
digipeat
=
kmalloc
(
sizeof
(
ax25_digi
),
GFP_ATOMIC
))
==
NULL
)
{
write_unlock
(
ax25_route_lock
);
kfree
(
ax25_rt
);
return
-
ENOMEM
;
ax25_rt
->
callsign
=
route
.
dest_addr
;
ax25_rt
->
dev
=
ax25_dev
->
dev
;
ax25_rt
->
digipeat
=
NULL
;
ax25_rt
->
ip_mode
=
' '
;
if
(
route
.
digi_count
!=
0
)
{
if
((
ax25_rt
->
digipeat
=
kmalloc
(
sizeof
(
ax25_digi
),
GFP_ATOMIC
))
==
NULL
)
{
kfree
(
ax25_rt
);
return
-
ENOMEM
;
}
ax25_rt
->
digipeat
->
lastrepeat
=
-
1
;
ax25_rt
->
digipeat
->
ndigi
=
route
.
digi_count
;
for
(
i
=
0
;
i
<
route
.
digi_count
;
i
++
)
{
ax25_rt
->
digipeat
->
repeated
[
i
]
=
0
;
ax25_rt
->
digipeat
->
calls
[
i
]
=
route
.
digi_addr
[
i
];
}
}
spin_lock_irqsave
(
&
ax25_route_lock
,
flags
);
ax25_rt
->
next
=
ax25_route_list
;
ax25_route_list
=
ax25_rt
;
spin_unlock_irqrestore
(
&
ax25_route_lock
,
flags
);
ax25_rt
->
digipeat
->
lastrepeat
=
-
1
;
ax25_rt
->
digipeat
->
ndigi
=
route
.
digi_count
;
for
(
i
=
0
;
i
<
route
.
digi_count
;
i
++
)
{
ax25_rt
->
digipeat
->
repeated
[
i
]
=
0
;
ax25_rt
->
digipeat
->
calls
[
i
]
=
route
.
digi_addr
[
i
];
}
}
ax25_rt
->
next
=
ax25_route_list
;
ax25_route_list
=
ax25_rt
;
write_unlock
(
ax25_route_lock
);
break
;
break
;
case
SIOCDELRT
:
if
(
copy_from_user
(
&
route
,
arg
,
sizeof
(
route
)))
return
-
EFAULT
;
if
((
ax25_dev
=
ax25_addr_ax25dev
(
&
route
.
port_addr
))
==
NULL
)
return
-
EINVAL
;
ax25_rt
=
ax25_route_list
;
while
(
ax25_rt
!=
NULL
)
{
s
=
ax25_rt
;
ax25_rt
=
ax25_rt
->
next
;
if
(
s
->
dev
==
ax25_dev
->
dev
&&
ax25cmp
(
&
route
.
dest_addr
,
&
s
->
callsign
)
==
0
)
{
if
(
ax25_route_list
==
s
)
{
ax25_route_list
=
s
->
next
;
if
(
s
->
digipeat
!=
NULL
)
kfree
(
s
->
digipeat
);
kfree
(
s
);
}
else
{
for
(
t
=
ax25_route_list
;
t
!=
NULL
;
t
=
t
->
next
)
{
if
(
t
->
next
==
s
)
{
t
->
next
=
s
->
next
;
if
(
s
->
digipeat
!=
NULL
)
kfree
(
s
->
digipeat
);
kfree
(
s
);
break
;
}
}
}
case
SIOCDELRT
:
if
(
copy_from_user
(
&
route
,
arg
,
sizeof
(
route
)))
return
-
EFAULT
;
if
((
ax25_dev
=
ax25_addr_ax25dev
(
&
route
.
port_addr
))
==
NULL
)
return
-
EINVAL
;
ax25_rt
=
ax25_route_list
;
while
(
ax25_rt
!=
NULL
)
{
s
=
ax25_rt
;
ax25_rt
=
ax25_rt
->
next
;
if
(
s
->
dev
==
ax25_dev
->
dev
&&
ax25cmp
(
&
route
.
dest_addr
,
&
s
->
callsign
)
==
0
)
{
if
(
ax25_route_list
==
s
)
{
ax25_route_list
=
s
->
next
;
if
(
s
->
digipeat
!=
NULL
)
kfree
(
s
->
digipeat
);
kfree
(
s
);
}
else
{
for
(
t
=
ax25_route_list
;
t
!=
NULL
;
t
=
t
->
next
)
{
if
(
t
->
next
==
s
)
{
t
->
next
=
s
->
next
;
if
(
s
->
digipeat
!=
NULL
)
kfree
(
s
->
digipeat
);
kfree
(
s
);
break
;
}
}
}
}
break
;
}
break
;
case
SIOCAX25OPTRT
:
if
(
copy_from_user
(
&
rt_option
,
arg
,
sizeof
(
rt_option
)))
return
-
EFAULT
;
if
((
ax25_dev
=
ax25_addr_ax25dev
(
&
rt_option
.
port_addr
))
==
NULL
)
return
-
EINVAL
;
for
(
ax25_rt
=
ax25_route_list
;
ax25_rt
!=
NULL
;
ax25_rt
=
ax25_rt
->
next
)
{
if
(
ax25_rt
->
dev
==
ax25_dev
->
dev
&&
ax25cmp
(
&
rt_option
.
dest_addr
,
&
ax25_rt
->
callsign
)
==
0
)
{
switch
(
rt_option
.
cmd
)
{
case
AX25_SET_RT_IPMODE
:
switch
(
rt_option
.
arg
)
{
case
' '
:
case
'D
'
:
case
'V
'
:
ax25_rt
->
ip_mode
=
rt_option
.
arg
;
break
;
default:
return
-
EINVAL
;
}
break
;
default:
return
-
EINVAL
;
}
case
SIOCAX25OPTRT
:
if
(
copy_from_user
(
&
rt_option
,
arg
,
sizeof
(
rt_option
)))
return
-
EFAULT
;
if
((
ax25_dev
=
ax25_addr_ax25dev
(
&
rt_option
.
port_addr
))
==
NULL
)
return
-
EINVAL
;
write_lock
(
ax25_route_lock
);
for
(
ax25_rt
=
ax25_route_list
;
ax25_rt
!=
NULL
;
ax25_rt
=
ax25_rt
->
next
)
{
if
(
ax25_rt
->
dev
==
ax25_dev
->
dev
&&
ax25cmp
(
&
rt_option
.
dest_addr
,
&
ax25_rt
->
callsign
)
==
0
)
{
switch
(
rt_option
.
cmd
)
{
case
AX25_SET_RT_IPMODE
:
switch
(
rt_option
.
arg
)
{
case
'
'
:
case
'D
'
:
case
'V'
:
ax25_rt
->
ip_mode
=
rt_option
.
arg
;
break
;
default:
return
-
EINVAL
;
}
break
;
default:
return
-
EINVAL
;
}
}
break
;
}
write_unlock
(
ax25_route_lock
);
break
;
default:
return
-
EINVAL
;
default:
return
-
EINVAL
;
}
return
0
;
...
...
@@ -246,14 +251,13 @@ int ax25_rt_ioctl(unsigned int cmd, void *arg)
int
ax25_rt_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
{
ax25_route
*
ax25_rt
;
unsigned
long
flags
;
int
len
=
0
;
off_t
pos
=
0
;
off_t
begin
=
0
;
char
*
callsign
;
int
i
;
spin_lock_irqsave
(
&
ax25_route_lock
,
flags
);
read_lock
(
&
ax25_route_lock
);
len
+=
sprintf
(
buffer
,
"callsign dev mode digipeaters
\n
"
);
...
...
@@ -267,15 +271,15 @@ int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length)
ax25_rt
->
dev
?
ax25_rt
->
dev
->
name
:
"???"
);
switch
(
ax25_rt
->
ip_mode
)
{
case
'V'
:
len
+=
sprintf
(
buffer
+
len
,
" vc"
);
break
;
case
'D'
:
len
+=
sprintf
(
buffer
+
len
,
" dg"
);
break
;
default:
len
+=
sprintf
(
buffer
+
len
,
" *"
);
break
;
case
'V'
:
len
+=
sprintf
(
buffer
+
len
,
" vc"
);
break
;
case
'D'
:
len
+=
sprintf
(
buffer
+
len
,
" dg"
);
break
;
default:
len
+=
sprintf
(
buffer
+
len
,
" *"
);
break
;
}
if
(
ax25_rt
->
digipeat
!=
NULL
)
...
...
@@ -294,7 +298,7 @@ int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length)
if
(
pos
>
offset
+
length
)
break
;
}
spin_unlock_irqrestore
(
&
ax25_route_lock
,
flags
);
read_unlock
(
&
ax25_route_lock
);
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
...
...
@@ -314,6 +318,7 @@ static ax25_route *ax25_find_route(ax25_address *addr, struct net_device *dev)
ax25_route
*
ax25_def_rt
=
NULL
;
ax25_route
*
ax25_rt
;
read_lock
(
&
ax25_route_lock
);
/*
* Bind to the physical interface we heard them on, or the default
* route if none is found;
...
...
@@ -331,6 +336,7 @@ static ax25_route *ax25_find_route(ax25_address *addr, struct net_device *dev)
ax25_def_rt
=
ax25_rt
;
}
}
read_unlock
(
&
ax25_route_lock
);
if
(
ax25_spe_rt
!=
NULL
)
return
ax25_spe_rt
;
...
...
@@ -448,6 +454,7 @@ void __exit ax25_rt_free(void)
{
ax25_route
*
s
,
*
ax25_rt
=
ax25_route_list
;
write_unlock
(
&
ax25_route_lock
);
while
(
ax25_rt
!=
NULL
)
{
s
=
ax25_rt
;
ax25_rt
=
ax25_rt
->
next
;
...
...
@@ -457,4 +464,5 @@ void __exit ax25_rt_free(void)
kfree
(
s
);
}
write_unlock
(
&
ax25_route_lock
);
}
net/ax25/ax25_std_in.c
View file @
6244be2f
...
...
@@ -68,55 +68,55 @@
static
int
ax25_std_state1_machine
(
ax25_cb
*
ax25
,
struct
sk_buff
*
skb
,
int
frametype
,
int
pf
,
int
type
)
{
switch
(
frametype
)
{
case
AX25_SABM
:
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_SABME
:
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_DM
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_UA
:
if
(
pf
)
{
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25
->
state
=
AX25_STATE_3
;
ax25
->
n2count
=
0
;
if
(
ax25
->
sk
!=
NULL
)
{
ax25
->
sk
->
state
=
TCP_ESTABLISHED
;
/* For WAIT_SABM connections we will produce an accept ready socket here */
if
(
!
ax25
->
sk
->
dead
)
ax25
->
sk
->
state_change
(
ax25
->
sk
);
}
case
AX25_SABM
:
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_SABME
:
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_DM
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_UA
:
if
(
pf
)
{
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25
->
state
=
AX25_STATE_3
;
ax25
->
n2count
=
0
;
if
(
ax25
->
sk
!=
NULL
)
{
ax25
->
sk
->
state
=
TCP_ESTABLISHED
;
/* For WAIT_SABM connections we will produce an accept ready socket here */
if
(
!
ax25
->
sk
->
dead
)
ax25
->
sk
->
state_change
(
ax25
->
sk
);
}
break
;
}
break
;
case
AX25_DM
:
if
(
pf
)
{
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
ax25_disconnect
(
ax25
,
ECONNREFUSED
);
}
else
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
case
AX25_DM
:
if
(
pf
)
{
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
ax25_disconnect
(
ax25
,
ECONNREFUSED
);
}
else
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
break
;
}
break
;
default:
break
;
default:
break
;
}
return
0
;
...
...
@@ -130,30 +130,31 @@ static int ax25_std_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frame
static
int
ax25_std_state2_machine
(
ax25_cb
*
ax25
,
struct
sk_buff
*
skb
,
int
frametype
,
int
pf
,
int
type
)
{
switch
(
frametype
)
{
case
AX25_SABM
:
case
AX25_SABME
:
ax25_send_control
(
ax25
,
AX25_DM
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
case
AX25_SABM
:
case
AX25_SABME
:
ax25_send_control
(
ax25
,
AX25_DM
,
pf
,
AX25_RESPONSE
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_DM
:
case
AX25_UA
:
if
(
pf
)
ax25_disconnect
(
ax25
,
0
);
break
;
break
;
case
AX25_DM
:
case
AX25_UA
:
if
(
pf
)
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_I
:
case
AX25_REJ
:
case
AX25_RNR
:
case
AX25_RR
:
if
(
pf
)
ax25_send_control
(
ax25
,
AX25_DM
,
AX25_POLLON
,
AX25_RESPONSE
);
break
;
case
AX25_I
:
case
AX25_REJ
:
case
AX25_RNR
:
case
AX25_RR
:
if
(
pf
)
ax25_send_control
(
ax25
,
AX25_DM
,
AX25_POLLON
,
AX25_RESPONSE
);
break
;
default:
break
;
default:
break
;
}
return
0
;
...
...
@@ -169,116 +170,116 @@ static int ax25_std_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frame
int
queued
=
0
;
switch
(
frametype
)
{
case
AX25_SABM
:
case
AX25_SABME
:
if
(
frametype
==
AX25_SABM
)
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
else
{
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
}
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
case
AX25_SABM
:
case
AX25_SABME
:
if
(
frametype
==
AX25_SABM
)
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
else
{
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
}
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_stop_t1timer
(
ax25
);
ax25_stop_t2timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
condition
=
0x00
;
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25_requeue_frames
(
ax25
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_DM
:
ax25_disconnect
(
ax25
,
ECONNRESET
);
break
;
case
AX25_RR
:
case
AX25_RNR
:
if
(
frametype
==
AX25_RR
)
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
else
ax25
->
condition
|=
AX25_COND_PEER_RX_BUSY
;
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_std_enquiry_response
(
ax25
);
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_check_iframes_acked
(
ax25
,
nr
);
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
case
AX25_REJ
:
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_std_enquiry_response
(
ax25
);
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_stop_t2timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
condition
=
0x00
;
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25_requeue_frames
(
ax25
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
0
);
break
;
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
case
AX25_DM
:
ax25_disconnect
(
ax25
,
ECONNRESET
);
case
AX25_I
:
if
(
!
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
case
AX25_RR
:
case
AX25_RNR
:
if
(
frametype
==
AX25_RR
)
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
else
ax25
->
condition
|=
AX25_COND_PEER_RX_BUSY
;
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_std_enquiry_response
(
ax25
);
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_check_iframes_acked
(
ax25
,
nr
);
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
}
if
(
ax25
->
condition
&
AX25_COND_PEER_RX_BUSY
)
{
ax25_frames_acked
(
ax25
,
nr
);
}
else
{
ax25_check_iframes_acked
(
ax25
,
nr
);
}
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
{
if
(
pf
)
ax25_std_enquiry_response
(
ax25
);
break
;
case
AX25_REJ
:
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
if
(
type
==
AX25_COMMAND
&&
pf
)
}
if
(
ns
==
ax25
->
vr
)
{
ax25
->
vr
=
(
ax25
->
vr
+
1
)
%
ax25
->
modulus
;
queued
=
ax25_rx_iframe
(
ax25
,
skb
);
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
ax25
->
vr
=
ns
;
/* ax25->vr - 1 */
ax25
->
condition
&=
~
AX25_COND_REJECT
;
if
(
pf
)
{
ax25_std_enquiry_response
(
ax25
);
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
ax25_calculate_rtt
(
ax25
);
ax25_stop_t1timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_requeue_frames
(
ax25
);
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
case
AX25_I
:
if
(
!
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
}
if
(
ax25
->
condition
&
AX25_COND_PEER_RX_BUSY
)
{
ax25_frames_acked
(
ax25
,
nr
);
}
else
{
ax25_check_iframes_acked
(
ax25
,
nr
);
if
(
!
(
ax25
->
condition
&
AX25_COND_ACK_PENDING
))
{
ax25
->
condition
|=
AX25_COND_ACK_PENDING
;
ax25_start_t2timer
(
ax25
);
}
}
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
{
}
else
{
if
(
ax25
->
condition
&
AX25_COND_REJECT
)
{
if
(
pf
)
ax25_std_enquiry_response
(
ax25
);
break
;
}
if
(
ns
==
ax25
->
vr
)
{
ax25
->
vr
=
(
ax25
->
vr
+
1
)
%
ax25
->
modulus
;
queued
=
ax25_rx_iframe
(
ax25
,
skb
);
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
ax25
->
vr
=
ns
;
/* ax25->vr - 1 */
ax25
->
condition
&=
~
AX25_COND_REJECT
;
if
(
pf
)
{
ax25_std_enquiry_response
(
ax25
);
}
else
{
if
(
!
(
ax25
->
condition
&
AX25_COND_ACK_PENDING
))
{
ax25
->
condition
|=
AX25_COND_ACK_PENDING
;
ax25_start_t2timer
(
ax25
);
}
}
}
else
{
if
(
ax25
->
condition
&
AX25_COND_REJECT
)
{
if
(
pf
)
ax25_std_enquiry_response
(
ax25
);
}
else
{
ax25
->
condition
|=
AX25_COND_REJECT
;
ax25_send_control
(
ax25
,
AX25_REJ
,
pf
,
AX25_RESPONSE
);
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
}
ax25
->
condition
|=
AX25_COND_REJECT
;
ax25_send_control
(
ax25
,
AX25_REJ
,
pf
,
AX25_RESPONSE
);
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
}
break
;
}
break
;
case
AX25_FRMR
:
case
AX25_ILLEGAL
:
ax25_std_establish_data_link
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
case
AX25_FRMR
:
case
AX25_ILLEGAL
:
ax25_std_establish_data_link
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
default:
break
;
default:
break
;
}
return
queued
;
...
...
@@ -294,145 +295,146 @@ static int ax25_std_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frame
int
queued
=
0
;
switch
(
frametype
)
{
case
AX25_SABM
:
case
AX25_SABME
:
if
(
frametype
==
AX25_SABM
)
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
else
{
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
}
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
case
AX25_SABM
:
case
AX25_SABME
:
if
(
frametype
==
AX25_SABM
)
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
}
else
{
ax25
->
modulus
=
AX25_EMODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_EWINDOW
];
}
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_stop_t1timer
(
ax25
);
ax25_stop_t2timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
condition
=
0x00
;
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25
->
state
=
AX25_STATE_3
;
ax25
->
n2count
=
0
;
ax25_requeue_frames
(
ax25
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_DM
:
ax25_disconnect
(
ax25
,
ECONNRESET
);
break
;
case
AX25_RR
:
case
AX25_RNR
:
if
(
frametype
==
AX25_RR
)
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
else
ax25
->
condition
|=
AX25_COND_PEER_RX_BUSY
;
if
(
type
==
AX25_RESPONSE
&&
pf
)
{
ax25_stop_t1timer
(
ax25
);
ax25_stop_t2timer
(
ax25
);
ax25_start_t3timer
(
ax25
);
ax25_start_idletimer
(
ax25
);
ax25
->
condition
=
0x00
;
ax25
->
vs
=
0
;
ax25
->
va
=
0
;
ax25
->
vr
=
0
;
ax25
->
state
=
AX25_STATE_3
;
ax25
->
n2count
=
0
;
ax25_requeue_frames
(
ax25
);
break
;
case
AX25_DISC
:
ax25_send_control
(
ax25
,
AX25_UA
,
pf
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
0
);
break
;
case
AX25_DM
:
ax25_disconnect
(
ax25
,
ECONNRESET
);
break
;
case
AX25_RR
:
case
AX25_RNR
:
if
(
frametype
==
AX25_RR
)
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
else
ax25
->
condition
|=
AX25_COND_PEER_RX_BUSY
;
if
(
type
==
AX25_RESPONSE
&&
pf
)
{
ax25_stop_t1timer
(
ax25
);
ax25
->
n2count
=
0
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
if
(
ax25
->
vs
==
ax25
->
va
)
{
ax25_start_t3timer
(
ax25
);
ax25
->
state
=
AX25_STATE_3
;
}
else
{
ax25_requeue_frames
(
ax25
);
}
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
}
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_std_enquiry_response
(
ax25
);
ax25
->
n2count
=
0
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
if
(
ax25
->
vs
==
ax25
->
va
)
{
ax25_start_t3timer
(
ax25
);
ax25
->
state
=
AX25_STATE_3
;
}
else
{
ax25_requeue_frames
(
ax25
);
}
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
}
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_std_enquiry_response
(
ax25
);
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
case
AX25_REJ
:
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
if
(
pf
&&
type
==
AX25_RESPONSE
)
{
ax25_stop_t1timer
(
ax25
);
ax25
->
n2count
=
0
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
if
(
ax25
->
vs
==
ax25
->
va
)
{
ax25_start_t3timer
(
ax25
);
ax25
->
state
=
AX25_STATE_3
;
}
else
{
ax25_requeue_frames
(
ax25
);
}
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
}
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_std_enquiry_response
(
ax25
);
case
AX25_REJ
:
ax25
->
condition
&=
~
AX25_COND_PEER_RX_BUSY
;
if
(
pf
&&
type
==
AX25_RESPONSE
)
{
ax25_stop_t1timer
(
ax25
);
ax25
->
n2count
=
0
;
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
ax25_requeue_frames
(
ax25
);
if
(
ax25
->
vs
==
ax25
->
va
)
{
ax25_start_t3timer
(
ax25
);
ax25
->
state
=
AX25_STATE_3
;
}
else
{
ax25_requeue_frames
(
ax25
);
}
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
}
if
(
type
==
AX25_COMMAND
&&
pf
)
ax25_std_enquiry_response
(
ax25
);
if
(
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_frames_acked
(
ax25
,
nr
);
ax25_requeue_frames
(
ax25
);
}
else
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
}
break
;
case
AX25_I
:
if
(
!
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
case
AX25_I
:
if
(
!
ax25_validate_nr
(
ax25
,
nr
))
{
ax25_std_nr_error_recovery
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
}
ax25_frames_acked
(
ax25
,
nr
);
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
{
if
(
pf
)
ax25_std_enquiry_response
(
ax25
);
break
;
}
if
(
ns
==
ax25
->
vr
)
{
ax25
->
vr
=
(
ax25
->
vr
+
1
)
%
ax25
->
modulus
;
queued
=
ax25_rx_iframe
(
ax25
,
skb
);
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
ax25
->
vr
=
ns
;
/* ax25->vr - 1 */
ax25
->
condition
&=
~
AX25_COND_REJECT
;
if
(
pf
)
{
ax25_std_enquiry_response
(
ax25
);
}
else
{
if
(
!
(
ax25
->
condition
&
AX25_COND_ACK_PENDING
))
{
ax25
->
condition
|=
AX25_COND_ACK_PENDING
;
ax25_start_t2timer
(
ax25
);
}
}
ax25_frames_acked
(
ax25
,
nr
);
if
(
ax25
->
condition
&
AX25_COND_
OWN_RX_BUSY
)
{
}
else
{
if
(
ax25
->
condition
&
AX25_COND_
REJECT
)
{
if
(
pf
)
ax25_std_enquiry_response
(
ax25
);
break
;
}
if
(
ns
==
ax25
->
vr
)
{
ax25
->
vr
=
(
ax25
->
vr
+
1
)
%
ax25
->
modulus
;
queued
=
ax25_rx_iframe
(
ax25
,
skb
);
if
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
)
ax25
->
vr
=
ns
;
/* ax25->vr - 1 */
ax25
->
condition
&=
~
AX25_COND_REJECT
;
if
(
pf
)
{
ax25_std_enquiry_response
(
ax25
);
}
else
{
if
(
!
(
ax25
->
condition
&
AX25_COND_ACK_PENDING
))
{
ax25
->
condition
|=
AX25_COND_ACK_PENDING
;
ax25_start_t2timer
(
ax25
);
}
}
}
else
{
if
(
ax25
->
condition
&
AX25_COND_REJECT
)
{
if
(
pf
)
ax25_std_enquiry_response
(
ax25
);
}
else
{
ax25
->
condition
|=
AX25_COND_REJECT
;
ax25_send_control
(
ax25
,
AX25_REJ
,
pf
,
AX25_RESPONSE
);
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
}
ax25
->
condition
|=
AX25_COND_REJECT
;
ax25_send_control
(
ax25
,
AX25_REJ
,
pf
,
AX25_RESPONSE
);
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
}
break
;
}
break
;
case
AX25_FRMR
:
case
AX25_ILLEGAL
:
ax25_std_establish_data_link
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
case
AX25_FRMR
:
case
AX25_ILLEGAL
:
ax25_std_establish_data_link
(
ax25
);
ax25
->
state
=
AX25_STATE_1
;
break
;
default:
break
;
default:
break
;
}
return
queued
;
...
...
@@ -448,18 +450,18 @@ int ax25_std_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
frametype
=
ax25_decode
(
ax25
,
skb
,
&
ns
,
&
nr
,
&
pf
);
switch
(
ax25
->
state
)
{
case
AX25_STATE_1
:
queued
=
ax25_std_state1_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_2
:
queued
=
ax25_std_state2_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_3
:
queued
=
ax25_std_state3_machine
(
ax25
,
skb
,
frametype
,
ns
,
nr
,
pf
,
type
);
break
;
case
AX25_STATE_4
:
queued
=
ax25_std_state4_machine
(
ax25
,
skb
,
frametype
,
ns
,
nr
,
pf
,
type
);
break
;
case
AX25_STATE_1
:
queued
=
ax25_std_state1_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_2
:
queued
=
ax25_std_state2_machine
(
ax25
,
skb
,
frametype
,
pf
,
type
);
break
;
case
AX25_STATE_3
:
queued
=
ax25_std_state3_machine
(
ax25
,
skb
,
frametype
,
ns
,
nr
,
pf
,
type
);
break
;
case
AX25_STATE_4
:
queued
=
ax25_std_state4_machine
(
ax25
,
skb
,
frametype
,
ns
,
nr
,
pf
,
type
);
break
;
}
ax25_kick
(
ax25
);
...
...
net/ax25/ax25_std_timer.c
View file @
6244be2f
...
...
@@ -47,30 +47,29 @@
void
ax25_std_heartbeat_expiry
(
ax25_cb
*
ax25
)
{
switch
(
ax25
->
state
)
{
case
AX25_STATE_0
:
/* Magic here: If we listen() and a new link dies before it
is accepted() it isn't 'dead' so doesn't get removed. */
if
(
ax25
->
sk
==
NULL
||
ax25
->
sk
->
destroy
||
(
ax25
->
sk
->
state
==
TCP_LISTEN
&&
ax25
->
sk
->
dead
))
{
ax25_destroy_socket
(
ax25
);
return
;
}
break
;
case
AX25_STATE_3
:
case
AX25_STATE_4
:
/*
* Check the state of the receive buffer.
*/
if
(
ax25
->
sk
!=
NULL
)
{
if
(
atomic_read
(
&
ax25
->
sk
->
rmem_alloc
)
<
(
ax25
->
sk
->
rcvbuf
/
2
)
&&
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
))
{
ax25
->
condition
&=
~
AX25_COND_OWN_RX_BUSY
;
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
ax25_send_control
(
ax25
,
AX25_RR
,
AX25_POLLOFF
,
AX25_RESPONSE
);
break
;
}
case
AX25_STATE_0
:
/* Magic here: If we listen() and a new link dies before it
is accepted() it isn't 'dead' so doesn't get removed. */
if
(
ax25
->
sk
==
NULL
||
ax25
->
sk
->
destroy
||
(
ax25
->
sk
->
state
==
TCP_LISTEN
&&
ax25
->
sk
->
dead
))
{
ax25_destroy_socket
(
ax25
);
return
;
}
break
;
case
AX25_STATE_3
:
case
AX25_STATE_4
:
/*
* Check the state of the receive buffer.
*/
if
(
ax25
->
sk
!=
NULL
)
{
if
(
atomic_read
(
&
ax25
->
sk
->
rmem_alloc
)
<
(
ax25
->
sk
->
rcvbuf
/
2
)
&&
(
ax25
->
condition
&
AX25_COND_OWN_RX_BUSY
))
{
ax25
->
condition
&=
~
AX25_COND_OWN_RX_BUSY
;
ax25
->
condition
&=
~
AX25_COND_ACK_PENDING
;
ax25_send_control
(
ax25
,
AX25_RR
,
AX25_POLLOFF
,
AX25_RESPONSE
);
break
;
}
}
}
ax25_start_heartbeat
(
ax25
);
...
...
@@ -117,53 +116,53 @@ void ax25_std_idletimer_expiry(ax25_cb *ax25)
void
ax25_std_t1timer_expiry
(
ax25_cb
*
ax25
)
{
switch
(
ax25
->
state
)
{
case
AX25_STATE_1
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25
->
n2count
=
0
;
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLON
,
AX25_COMMAND
);
}
}
else
{
ax25
->
n2count
++
;
if
(
ax25
->
modulus
==
AX25_MODULUS
)
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLON
,
AX25_COMMAND
);
else
ax25_send_control
(
ax25
,
AX25_SABME
,
AX25_POLLON
,
AX25_COMMAND
);
}
break
;
case
AX25_STATE_2
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
case
AX25_STATE_1
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
if
(
ax25
->
modulus
==
AX25_MODULUS
)
{
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25
->
modulus
=
AX25_MODULUS
;
ax25
->
window
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_WINDOW
];
ax25
->
n2count
=
0
;
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLON
,
AX25_COMMAND
);
}
break
;
case
AX25_STATE_3
:
ax25
->
n2count
=
1
;
}
else
{
ax25
->
n2count
++
;
if
(
ax25
->
modulus
==
AX25_MODULUS
)
ax25_send_control
(
ax25
,
AX25_SABM
,
AX25_POLLON
,
AX25_COMMAND
);
else
ax25_send_control
(
ax25
,
AX25_SABME
,
AX25_POLLON
,
AX25_COMMAND
);
}
break
;
case
AX25_STATE_2
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
ax25_send_control
(
ax25
,
AX25_DISC
,
AX25_POLLON
,
AX25_COMMAND
);
}
break
;
case
AX25_STATE_3
:
ax25
->
n2count
=
1
;
ax25_std_transmit_enquiry
(
ax25
);
ax25
->
state
=
AX25_STATE_4
;
break
;
case
AX25_STATE_4
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DM
,
AX25_POLLON
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
ax25_std_transmit_enquiry
(
ax25
);
ax25
->
state
=
AX25_STATE_4
;
break
;
case
AX25_STATE_4
:
if
(
ax25
->
n2count
==
ax25
->
n2
)
{
ax25_send_control
(
ax25
,
AX25_DM
,
AX25_POLLON
,
AX25_RESPONSE
);
ax25_disconnect
(
ax25
,
ETIMEDOUT
);
return
;
}
else
{
ax25
->
n2count
++
;
ax25_std_transmit_enquiry
(
ax25
);
}
break
;
}
break
;
}
ax25_calculate_t1
(
ax25
);
...
...
net/ax25/ax25_subr.c
View file @
6244be2f
...
...
@@ -257,18 +257,18 @@ void ax25_calculate_t1(ax25_cb *ax25)
int
n
,
t
=
2
;
switch
(
ax25
->
backoff
)
{
case
0
:
break
;
case
1
:
t
+=
2
*
ax25
->
n2count
;
break
;
case
2
:
for
(
n
=
0
;
n
<
ax25
->
n2count
;
n
++
)
t
*=
2
;
if
(
t
>
8
)
t
=
8
;
break
;
case
0
:
break
;
case
1
:
t
+=
2
*
ax25
->
n2count
;
break
;
case
2
:
for
(
n
=
0
;
n
<
ax25
->
n2count
;
n
++
)
t
*=
2
;
if
(
t
>
8
)
t
=
8
;
break
;
}
ax25
->
t1
=
t
*
ax25
->
rtt
;
...
...
net/ax25/ax25_timer.c
View file @
6244be2f
...
...
@@ -159,18 +159,18 @@ static void ax25_heartbeat_expiry(unsigned long param)
proto
=
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
];
switch
(
proto
)
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_heartbeat_expiry
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_heartbeat_expiry
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_heartbeat_expiry
(
ax25
);
else
ax25_std_heartbeat_expiry
(
ax25
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_heartbeat_expiry
(
ax25
);
else
ax25_std_heartbeat_expiry
(
ax25
);
break
;
#endif
}
}
...
...
@@ -180,16 +180,16 @@ static void ax25_t1timer_expiry(unsigned long param)
ax25_cb
*
ax25
=
(
ax25_cb
*
)
param
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_t1timer_expiry
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_t1timer_expiry
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
if
(
!
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_std_t1timer_expiry
(
ax25
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
if
(
!
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_std_t1timer_expiry
(
ax25
);
break
;
#endif
}
}
...
...
@@ -199,16 +199,16 @@ static void ax25_t2timer_expiry(unsigned long param)
ax25_cb
*
ax25
=
(
ax25_cb
*
)
param
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_t2timer_expiry
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_t2timer_expiry
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
if
(
!
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_std_t2timer_expiry
(
ax25
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
if
(
!
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_std_t2timer_expiry
(
ax25
);
break
;
#endif
}
}
...
...
@@ -218,18 +218,18 @@ static void ax25_t3timer_expiry(unsigned long param)
ax25_cb
*
ax25
=
(
ax25_cb
*
)
param
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_t3timer_expiry
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_t3timer_expiry
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_t3timer_expiry
(
ax25
);
else
ax25_std_t3timer_expiry
(
ax25
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_t3timer_expiry
(
ax25
);
else
ax25_std_t3timer_expiry
(
ax25
);
break
;
#endif
}
}
...
...
@@ -239,18 +239,18 @@ static void ax25_idletimer_expiry(unsigned long param)
ax25_cb
*
ax25
=
(
ax25_cb
*
)
param
;
switch
(
ax25
->
ax25_dev
->
values
[
AX25_VALUES_PROTOCOL
])
{
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_idletimer_expiry
(
ax25
);
break
;
case
AX25_PROTO_STD_SIMPLEX
:
case
AX25_PROTO_STD_DUPLEX
:
ax25_std_idletimer_expiry
(
ax25
);
break
;
#ifdef CONFIG_AX25_DAMA_SLAVE
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_idletimer_expiry
(
ax25
);
else
ax25_std_idletimer_expiry
(
ax25
);
break
;
case
AX25_PROTO_DAMA_SLAVE
:
if
(
ax25
->
ax25_dev
->
dama
.
slave
)
ax25_ds_idletimer_expiry
(
ax25
);
else
ax25_std_idletimer_expiry
(
ax25
);
break
;
#endif
}
}
net/ax25/ax25_uid.c
View file @
6244be2f
...
...
@@ -48,7 +48,7 @@
*/
static
ax25_uid_assoc
*
ax25_uid_list
;
static
spinlock_t
ax25_uid_lock
=
SPIN
_LOCK_UNLOCKED
;
static
rwlock_t
ax25_uid_lock
=
RW
_LOCK_UNLOCKED
;
int
ax25_uid_policy
=
0
;
...
...
@@ -56,16 +56,15 @@ ax25_address *ax25_findbyuid(uid_t uid)
{
ax25_uid_assoc
*
ax25_uid
;
ax25_address
*
res
=
NULL
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
read_lock
(
&
ax25_uid_lock
);
for
(
ax25_uid
=
ax25_uid_list
;
ax25_uid
!=
NULL
;
ax25_uid
=
ax25_uid
->
next
)
{
if
(
ax25_uid
->
uid
==
uid
)
{
res
=
&
ax25_uid
->
call
;
break
;
}
}
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
read_unlock
(
&
ax25_uid_lock
);
return
NULL
;
}
...
...
@@ -73,78 +72,77 @@ ax25_address *ax25_findbyuid(uid_t uid)
int
ax25_uid_ioctl
(
int
cmd
,
struct
sockaddr_ax25
*
sax
)
{
ax25_uid_assoc
*
s
,
*
ax25_uid
;
unsigned
long
flags
;
unsigned
long
res
;
switch
(
cmd
)
{
case
SIOCAX25GETUID
:
res
=
-
ENOENT
;
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
for
(
ax25_uid
=
ax25_uid_list
;
ax25_uid
!=
NULL
;
ax25_uid
=
ax25_uid
->
next
)
{
if
(
ax25cmp
(
&
sax
->
sax25_call
,
&
ax25_uid
->
call
)
==
0
)
{
res
=
ax25_uid
->
uid
;
break
;
}
case
SIOCAX25GETUID
:
res
=
-
ENOENT
;
read_lock
(
&
ax25_uid_lock
);
for
(
ax25_uid
=
ax25_uid_list
;
ax25_uid
!=
NULL
;
ax25_uid
=
ax25_uid
->
next
)
{
if
(
ax25cmp
(
&
sax
->
sax25_call
,
&
ax25_uid
->
call
)
==
0
)
{
res
=
ax25_uid
->
uid
;
break
;
}
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
}
read_unlock
(
&
ax25_uid_lock
);
return
res
;
return
res
;
case
SIOCAX25ADDUID
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
ax25_findbyuid
(
sax
->
sax25_uid
))
return
-
EEXIST
;
if
(
sax
->
sax25_uid
==
0
)
return
-
EINVAL
;
if
((
ax25_uid
=
kmalloc
(
sizeof
(
*
ax25_uid
),
GFP_KERNEL
))
==
NULL
)
return
-
ENOMEM
;
case
SIOCAX25ADDUID
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
ax25_findbyuid
(
sax
->
sax25_uid
))
return
-
EEXIST
;
if
(
sax
->
sax25_uid
==
0
)
return
-
EINVAL
;
if
((
ax25_uid
=
kmalloc
(
sizeof
(
*
ax25_uid
),
GFP_KERNEL
))
==
NULL
)
return
-
ENOMEM
;
ax25_uid
->
uid
=
sax
->
sax25_uid
;
ax25_uid
->
call
=
sax
->
sax25_call
;
ax25_uid
->
uid
=
sax
->
sax25_uid
;
ax25_uid
->
call
=
sax
->
sax25_call
;
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
ax25_uid
->
next
=
ax25_uid_list
;
ax25_uid_list
=
ax25_uid
;
spin_unlock_irqrestore
(
&
ax25_uid_lock
,
flags
);
write_lock
(
&
ax25_uid_lock
);
ax25_uid
->
next
=
ax25_uid_list
;
ax25_uid_list
=
ax25_uid
;
write_unlock
(
&
ax25_uid_lock
);
return
0
;
return
0
;
case
SIOCAX25DELUID
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
case
SIOCAX25DELUID
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
for
(
ax25_uid
=
ax25_uid_list
;
ax25_uid
!=
NULL
;
ax25_uid
=
ax25_uid
->
next
)
{
if
(
ax25cmp
(
&
sax
->
sax25_call
,
&
ax25_uid
->
call
)
==
0
)
{
break
;
}
}
if
(
ax25_uid
==
NULL
)
{
spin_unlock_irqrestore
(
&
ax25_uid_lock
,
flags
);
return
-
ENOENT
;
write_lock
(
&
ax25_uid_lock
);
for
(
ax25_uid
=
ax25_uid_list
;
ax25_uid
!=
NULL
;
ax25_uid
=
ax25_uid
->
next
)
{
if
(
ax25cmp
(
&
sax
->
sax25_call
,
&
ax25_uid
->
call
)
==
0
)
{
break
;
}
if
((
s
=
ax25_uid_list
)
==
ax25_uid
)
{
ax25_uid_list
=
s
->
next
;
spin_unlock_irqrestore
(
&
ax25_uid_lock
,
flags
);
}
if
(
ax25_uid
==
NULL
)
{
write_unlock
(
&
ax25_uid_lock
);
return
-
ENOENT
;
}
if
((
s
=
ax25_uid_list
)
==
ax25_uid
)
{
ax25_uid_list
=
s
->
next
;
write_unlock
(
&
ax25_uid_lock
);
kfree
(
ax25_uid
);
return
0
;
}
while
(
s
!=
NULL
&&
s
->
next
!=
NULL
)
{
if
(
s
->
next
==
ax25_uid
)
{
s
->
next
=
ax25_uid
->
next
;
write_unlock
(
&
ax25_uid_lock
);
kfree
(
ax25_uid
);
return
0
;
}
while
(
s
!=
NULL
&&
s
->
next
!=
NULL
)
{
if
(
s
->
next
==
ax25_uid
)
{
s
->
next
=
ax25_uid
->
next
;
spin_unlock_irqrestore
(
&
ax25_uid_lock
,
flags
);
kfree
(
ax25_uid
);
return
0
;
}
s
=
s
->
next
;
}
spin_unlock_irqrestore
(
&
ax25_uid_lock
,
flags
);
s
=
s
->
next
;
}
write_unlock
(
&
ax25_uid_lock
);
return
-
ENOENT
;
return
-
ENOENT
;
default:
return
-
EINVAL
;
default:
return
-
EINVAL
;
}
return
-
EINVAL
;
/*NOTREACHED */
...
...
@@ -152,13 +150,12 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
int
ax25_uid_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
{
unsigned
long
flags
;
ax25_uid_assoc
*
pt
;
int
len
=
0
;
off_t
pos
=
0
;
off_t
begin
=
0
;
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
read_lock
(
&
ax25_uid_lock
);
len
+=
sprintf
(
buffer
,
"Policy: %d
\n
"
,
ax25_uid_policy
);
for
(
pt
=
ax25_uid_list
;
pt
!=
NULL
;
pt
=
pt
->
next
)
{
...
...
@@ -174,7 +171,7 @@ int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length)
if
(
pos
>
offset
+
length
)
break
;
}
spin_unlock_irqrestore
(
&
ax25_uid_lock
,
flags
);
read_unlock
(
&
ax25_uid_lock
);
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
offset
-
begin
;
...
...
@@ -191,9 +188,8 @@ int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length)
void
__exit
ax25_uid_free
(
void
)
{
ax25_uid_assoc
*
s
,
*
ax25_uid
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
ax25_uid_lock
,
flags
);
write_lock
(
&
ax25_uid_lock
);
ax25_uid
=
ax25_uid_list
;
while
(
ax25_uid
!=
NULL
)
{
s
=
ax25_uid
;
...
...
@@ -202,5 +198,5 @@ void __exit ax25_uid_free(void)
kfree
(
s
);
}
ax25_uid_list
=
NULL
;
spin_unlock_irqrestore
(
&
ax25_uid_lock
,
flags
);
write_unlock
(
&
ax25_uid_lock
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment