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
94ca866c
Commit
94ca866c
authored
Aug 14, 2003
by
Jeroen Vreeken
Committed by
David S. Miller
Aug 14, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[NETROM]: Lock sockets while doing protocol processing.
parent
af8a45cb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
168 additions
and
52 deletions
+168
-52
net/netrom/af_netrom.c
net/netrom/af_netrom.c
+156
-52
net/netrom/nr_in.c
net/netrom/nr_in.c
+6
-0
net/netrom/nr_timer.c
net/netrom/nr_timer.c
+6
-0
No files found.
net/netrom/af_netrom.c
View file @
94ca866c
...
@@ -147,8 +147,10 @@ static struct sock *nr_find_listener(ax25_address *addr)
...
@@ -147,8 +147,10 @@ static struct sock *nr_find_listener(ax25_address *addr)
spin_lock_bh
(
&
nr_list_lock
);
spin_lock_bh
(
&
nr_list_lock
);
sk_for_each
(
s
,
node
,
&
nr_list
)
sk_for_each
(
s
,
node
,
&
nr_list
)
if
(
!
ax25cmp
(
&
nr_sk
(
s
)
->
source_addr
,
addr
)
&&
if
(
!
ax25cmp
(
&
nr_sk
(
s
)
->
source_addr
,
addr
)
&&
s
->
sk_state
==
TCP_LISTEN
)
s
->
sk_state
==
TCP_LISTEN
)
{
bh_lock_sock
(
s
);
goto
found
;
goto
found
;
}
s
=
NULL
;
s
=
NULL
;
found:
found:
spin_unlock_bh
(
&
nr_list_lock
);
spin_unlock_bh
(
&
nr_list_lock
);
...
@@ -167,8 +169,10 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id)
...
@@ -167,8 +169,10 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id)
sk_for_each
(
s
,
node
,
&
nr_list
)
{
sk_for_each
(
s
,
node
,
&
nr_list
)
{
nr_cb
*
nr
=
nr_sk
(
s
);
nr_cb
*
nr
=
nr_sk
(
s
);
if
(
nr
->
my_index
==
index
&&
nr
->
my_id
==
id
)
if
(
nr
->
my_index
==
index
&&
nr
->
my_id
==
id
)
{
bh_lock_sock
(
s
);
goto
found
;
goto
found
;
}
}
}
s
=
NULL
;
s
=
NULL
;
found:
found:
...
@@ -190,8 +194,10 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id,
...
@@ -190,8 +194,10 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id,
nr_cb
*
nr
=
nr_sk
(
s
);
nr_cb
*
nr
=
nr_sk
(
s
);
if
(
nr
->
your_index
==
index
&&
nr
->
your_id
==
id
&&
if
(
nr
->
your_index
==
index
&&
nr
->
your_id
==
id
&&
!
ax25cmp
(
&
nr
->
dest_addr
,
dest
))
!
ax25cmp
(
&
nr
->
dest_addr
,
dest
))
{
bh_lock_sock
(
s
);
goto
found
;
goto
found
;
}
}
}
s
=
NULL
;
s
=
NULL
;
found:
found:
...
@@ -206,14 +212,17 @@ static unsigned short nr_find_next_circuit(void)
...
@@ -206,14 +212,17 @@ static unsigned short nr_find_next_circuit(void)
{
{
unsigned
short
id
=
circuit
;
unsigned
short
id
=
circuit
;
unsigned
char
i
,
j
;
unsigned
char
i
,
j
;
struct
sock
*
sk
;
for
(;;)
{
for
(;;)
{
i
=
id
/
256
;
i
=
id
/
256
;
j
=
id
%
256
;
j
=
id
%
256
;
if
(
i
!=
0
&&
j
!=
0
)
if
(
i
!=
0
&&
j
!=
0
)
{
if
(
nr_find_socket
(
i
,
j
)
==
NULL
)
if
(
(
sk
=
nr_find_socket
(
i
,
j
)
)
==
NULL
)
break
;
break
;
bh_unlock_sock
(
sk
);
}
id
++
;
id
++
;
}
}
...
@@ -231,7 +240,12 @@ void nr_destroy_socket(struct sock *);
...
@@ -231,7 +240,12 @@ void nr_destroy_socket(struct sock *);
*/
*/
static
void
nr_destroy_timer
(
unsigned
long
data
)
static
void
nr_destroy_timer
(
unsigned
long
data
)
{
{
nr_destroy_socket
((
struct
sock
*
)
data
);
struct
sock
*
sk
=
(
struct
sock
*
)
data
;
bh_lock_sock
(
sk
);
sock_hold
(
sk
);
nr_destroy_socket
(
sk
);
bh_unlock_sock
(
sk
);
sock_put
(
sk
);
}
}
/*
/*
...
@@ -277,7 +291,7 @@ void nr_destroy_socket(struct sock *sk)
...
@@ -277,7 +291,7 @@ void nr_destroy_socket(struct sock *sk)
sk
->
sk_timer
.
data
=
(
unsigned
long
)
sk
;
sk
->
sk_timer
.
data
=
(
unsigned
long
)
sk
;
add_timer
(
&
sk
->
sk_timer
);
add_timer
(
&
sk
->
sk_timer
);
}
else
}
else
s
k_free
(
sk
);
s
ock_put
(
sk
);
}
}
/*
/*
...
@@ -391,12 +405,15 @@ static int nr_listen(struct socket *sock, int backlog)
...
@@ -391,12 +405,15 @@ static int nr_listen(struct socket *sock, int backlog)
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
lock_sock
(
sk
);
if
(
sk
->
sk_state
!=
TCP_LISTEN
)
{
if
(
sk
->
sk_state
!=
TCP_LISTEN
)
{
memset
(
&
nr_sk
(
sk
)
->
user_addr
,
0
,
AX25_ADDR_LEN
);
memset
(
&
nr_sk
(
sk
)
->
user_addr
,
0
,
AX25_ADDR_LEN
);
sk
->
sk_max_ack_backlog
=
backlog
;
sk
->
sk_max_ack_backlog
=
backlog
;
sk
->
sk_state
=
TCP_LISTEN
;
sk
->
sk_state
=
TCP_LISTEN
;
release_sock
(
sk
);
return
0
;
return
0
;
}
}
release_sock
(
sk
);
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
...
@@ -498,6 +515,7 @@ static int nr_release(struct socket *sock)
...
@@ -498,6 +515,7 @@ static int nr_release(struct socket *sock)
if
(
sk
==
NULL
)
return
0
;
if
(
sk
==
NULL
)
return
0
;
lock_sock
(
sk
);
nr
=
nr_sk
(
sk
);
nr
=
nr_sk
(
sk
);
switch
(
nr
->
state
)
{
switch
(
nr
->
state
)
{
...
@@ -531,6 +549,7 @@ static int nr_release(struct socket *sock)
...
@@ -531,6 +549,7 @@ static int nr_release(struct socket *sock)
}
}
sock
->
sk
=
NULL
;
sock
->
sk
=
NULL
;
release_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -543,21 +562,26 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
...
@@ -543,21 +562,26 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct
net_device
*
dev
;
struct
net_device
*
dev
;
ax25_address
*
user
,
*
source
;
ax25_address
*
user
,
*
source
;
if
(
!
sk
->
sk_zapped
)
lock_sock
(
sk
);
if
(
!
sk
->
sk_zapped
)
{
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
}
if
(
addr_len
<
sizeof
(
struct
sockaddr_ax25
)
||
addr_len
>
sizeof
(
struct
if
(
addr_len
<
sizeof
(
struct
sockaddr_ax25
)
||
addr_len
>
sizeof
(
struct
full_sockaddr_ax25
))
{
full_sockaddr_ax25
))
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
}
if
(
addr_len
<
(
addr
->
fsa_ax25
.
sax25_ndigis
*
sizeof
(
ax25_address
)
+
sizeof
(
struct
sockaddr_ax25
)))
if
(
addr_len
<
(
addr
->
fsa_ax25
.
sax25_ndigis
*
sizeof
(
ax25_address
)
+
sizeof
(
struct
sockaddr_ax25
)))
{
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
}
if
(
addr
->
fsa_ax25
.
sax25_family
!=
AF_NETROM
)
if
(
addr
->
fsa_ax25
.
sax25_family
!=
AF_NETROM
)
{
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
}
if
((
dev
=
nr_dev_get
(
&
addr
->
fsa_ax25
.
sax25_call
))
==
NULL
)
{
if
((
dev
=
nr_dev_get
(
&
addr
->
fsa_ax25
.
sax25_call
))
==
NULL
)
{
SOCK_DEBUG
(
sk
,
"NET/ROM: bind failed: invalid node callsign
\n
"
);
SOCK_DEBUG
(
sk
,
"NET/ROM: bind failed: invalid node callsign
\n
"
);
release_sock
(
sk
);
return
-
EADDRNOTAVAIL
;
return
-
EADDRNOTAVAIL
;
}
}
...
@@ -565,16 +589,22 @@ full_sockaddr_ax25))
...
@@ -565,16 +589,22 @@ full_sockaddr_ax25))
* Only the super user can set an arbitrary user callsign.
* Only the super user can set an arbitrary user callsign.
*/
*/
if
(
addr
->
fsa_ax25
.
sax25_ndigis
==
1
)
{
if
(
addr
->
fsa_ax25
.
sax25_ndigis
==
1
)
{
if
(
!
capable
(
CAP_NET_BIND_SERVICE
))
if
(
!
capable
(
CAP_NET_BIND_SERVICE
))
{
dev_put
(
dev
);
release_sock
(
sk
);
return
-
EACCES
;
return
-
EACCES
;
}
nr
->
user_addr
=
addr
->
fsa_digipeater
[
0
];
nr
->
user_addr
=
addr
->
fsa_digipeater
[
0
];
nr
->
source_addr
=
addr
->
fsa_ax25
.
sax25_call
;
nr
->
source_addr
=
addr
->
fsa_ax25
.
sax25_call
;
}
else
{
}
else
{
source
=
&
addr
->
fsa_ax25
.
sax25_call
;
source
=
&
addr
->
fsa_ax25
.
sax25_call
;
if
((
user
=
ax25_findbyuid
(
current
->
euid
))
==
NULL
)
{
if
((
user
=
ax25_findbyuid
(
current
->
euid
))
==
NULL
)
{
if
(
ax25_uid_policy
&&
!
capable
(
CAP_NET_BIND_SERVICE
))
if
(
ax25_uid_policy
&&
!
capable
(
CAP_NET_BIND_SERVICE
))
{
release_sock
(
sk
);
dev_put
(
dev
);
return
-
EPERM
;
return
-
EPERM
;
}
user
=
source
;
user
=
source
;
}
}
...
@@ -586,6 +616,8 @@ full_sockaddr_ax25))
...
@@ -586,6 +616,8 @@ full_sockaddr_ax25))
nr_insert_socket
(
sk
);
nr_insert_socket
(
sk
);
sk
->
sk_zapped
=
0
;
sk
->
sk_zapped
=
0
;
dev_put
(
dev
);
release_sock
(
sk
);
SOCK_DEBUG
(
sk
,
"NET/ROM: socket is bound
\n
"
);
SOCK_DEBUG
(
sk
,
"NET/ROM: socket is bound
\n
"
);
return
0
;
return
0
;
}
}
...
@@ -599,39 +631,50 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
...
@@ -599,39 +631,50 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
ax25_address
*
user
,
*
source
=
NULL
;
ax25_address
*
user
,
*
source
=
NULL
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
lock_sock
(
sk
);
if
(
sk
->
sk_state
==
TCP_ESTABLISHED
&&
sock
->
state
==
SS_CONNECTING
)
{
if
(
sk
->
sk_state
==
TCP_ESTABLISHED
&&
sock
->
state
==
SS_CONNECTING
)
{
sock
->
state
=
SS_CONNECTED
;
sock
->
state
=
SS_CONNECTED
;
release_sock
(
sk
);
return
0
;
/* Connect completed during a ERESTARTSYS event */
return
0
;
/* Connect completed during a ERESTARTSYS event */
}
}
if
(
sk
->
sk_state
==
TCP_CLOSE
&&
sock
->
state
==
SS_CONNECTING
)
{
if
(
sk
->
sk_state
==
TCP_CLOSE
&&
sock
->
state
==
SS_CONNECTING
)
{
sock
->
state
=
SS_UNCONNECTED
;
sock
->
state
=
SS_UNCONNECTED
;
release_sock
(
sk
);
return
-
ECONNREFUSED
;
return
-
ECONNREFUSED
;
}
}
if
(
sk
->
sk_state
==
TCP_ESTABLISHED
)
if
(
sk
->
sk_state
==
TCP_ESTABLISHED
)
{
release_sock
(
sk
);
return
-
EISCONN
;
/* No reconnect on a seqpacket socket */
return
-
EISCONN
;
/* No reconnect on a seqpacket socket */
}
sk
->
sk_state
=
TCP_CLOSE
;
sk
->
sk_state
=
TCP_CLOSE
;
sock
->
state
=
SS_UNCONNECTED
;
sock
->
state
=
SS_UNCONNECTED
;
if
(
addr_len
!=
sizeof
(
struct
sockaddr_ax25
)
&&
addr_len
!=
sizeof
(
struct
full_sockaddr_ax25
))
if
(
addr_len
!=
sizeof
(
struct
sockaddr_ax25
)
&&
addr_len
!=
sizeof
(
struct
full_sockaddr_ax25
))
{
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
}
if
(
addr
->
sax25_family
!=
AF_NETROM
)
if
(
addr
->
sax25_family
!=
AF_NETROM
)
{
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
}
if
(
sk
->
sk_zapped
)
{
/* Must bind first - autobinding in this may or may not work */
if
(
sk
->
sk_zapped
)
{
/* Must bind first - autobinding in this may or may not work */
sk
->
sk_zapped
=
0
;
sk
->
sk_zapped
=
0
;
if
((
dev
=
nr_dev_first
())
==
NULL
)
if
((
dev
=
nr_dev_first
())
==
NULL
)
{
release_sock
(
sk
);
return
-
ENETUNREACH
;
return
-
ENETUNREACH
;
}
source
=
(
ax25_address
*
)
dev
->
dev_addr
;
source
=
(
ax25_address
*
)
dev
->
dev_addr
;
if
((
user
=
ax25_findbyuid
(
current
->
euid
))
==
NULL
)
{
if
((
user
=
ax25_findbyuid
(
current
->
euid
))
==
NULL
)
{
if
(
ax25_uid_policy
&&
!
capable
(
CAP_NET_ADMIN
))
if
(
ax25_uid_policy
&&
!
capable
(
CAP_NET_ADMIN
))
{
dev_put
(
dev
);
release_sock
(
sk
);
return
-
EPERM
;
return
-
EPERM
;
}
user
=
source
;
user
=
source
;
}
}
...
@@ -639,12 +682,15 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
...
@@ -639,12 +682,15 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
nr
->
source_addr
=
*
source
;
nr
->
source_addr
=
*
source
;
nr
->
device
=
dev
;
nr
->
device
=
dev
;
dev_put
(
dev
);
nr_insert_socket
(
sk
);
/* Finish the bind */
nr_insert_socket
(
sk
);
/* Finish the bind */
}
}
nr
->
dest_addr
=
addr
->
sax25_call
;
nr
->
dest_addr
=
addr
->
sax25_call
;
release_sock
(
sk
);
circuit
=
nr_find_next_circuit
();
circuit
=
nr_find_next_circuit
();
lock_sock
(
sk
);
nr
->
my_index
=
circuit
/
256
;
nr
->
my_index
=
circuit
/
256
;
nr
->
my_id
=
circuit
%
256
;
nr
->
my_id
=
circuit
%
256
;
...
@@ -662,8 +708,10 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
...
@@ -662,8 +708,10 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
nr_start_heartbeat
(
sk
);
nr_start_heartbeat
(
sk
);
/* Now the loop */
/* Now the loop */
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
&&
(
flags
&
O_NONBLOCK
))
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
&&
(
flags
&
O_NONBLOCK
))
{
release_sock
(
sk
);
return
-
EINPROGRESS
;
return
-
EINPROGRESS
;
}
/*
/*
* A Connect Ack with Choke or timeout or failed routing will go to
* A Connect Ack with Choke or timeout or failed routing will go to
...
@@ -678,8 +726,10 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
...
@@ -678,8 +726,10 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
set_current_state
(
TASK_INTERRUPTIBLE
);
set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
sk
->
sk_state
!=
TCP_SYN_SENT
)
if
(
sk
->
sk_state
!=
TCP_SYN_SENT
)
break
;
break
;
release_sock
(
sk
);
if
(
!
signal_pending
(
tsk
))
{
if
(
!
signal_pending
(
tsk
))
{
schedule
();
schedule
();
lock_sock
(
sk
);
continue
;
continue
;
}
}
return
-
ERESTARTSYS
;
return
-
ERESTARTSYS
;
...
@@ -690,10 +740,12 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
...
@@ -690,10 +740,12 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
{
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
{
sock
->
state
=
SS_UNCONNECTED
;
sock
->
state
=
SS_UNCONNECTED
;
release_sock
(
sk
);
return
sock_error
(
sk
);
/* Always set at this point */
return
sock_error
(
sk
);
/* Always set at this point */
}
}
sock
->
state
=
SS_CONNECTED
;
sock
->
state
=
SS_CONNECTED
;
release_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -756,6 +808,7 @@ static int nr_accept(struct socket *sock, struct socket *newsock, int flags)
...
@@ -756,6 +808,7 @@ static int nr_accept(struct socket *sock, struct socket *newsock, int flags)
newsock
->
sk
=
newsk
;
newsock
->
sk
=
newsk
;
out:
out:
release_sock
(
sk
);
return
err
;
return
err
;
}
}
...
@@ -766,9 +819,12 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
...
@@ -766,9 +819,12 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
nr_cb
*
nr
=
nr_sk
(
sk
);
nr_cb
*
nr
=
nr_sk
(
sk
);
lock_sock
(
sk
);
if
(
peer
!=
0
)
{
if
(
peer
!=
0
)
{
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
{
release_sock
(
sk
);
return
-
ENOTCONN
;
return
-
ENOTCONN
;
}
sax
->
fsa_ax25
.
sax25_family
=
AF_NETROM
;
sax
->
fsa_ax25
.
sax25_family
=
AF_NETROM
;
sax
->
fsa_ax25
.
sax25_ndigis
=
1
;
sax
->
fsa_ax25
.
sax25_ndigis
=
1
;
sax
->
fsa_ax25
.
sax25_call
=
nr
->
user_addr
;
sax
->
fsa_ax25
.
sax25_call
=
nr
->
user_addr
;
...
@@ -780,6 +836,7 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
...
@@ -780,6 +836,7 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
sax
->
fsa_ax25
.
sax25_call
=
nr
->
source_addr
;
sax
->
fsa_ax25
.
sax25_call
=
nr
->
source_addr
;
*
uaddr_len
=
sizeof
(
struct
sockaddr_ax25
);
*
uaddr_len
=
sizeof
(
struct
sockaddr_ax25
);
}
}
release_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -793,6 +850,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -793,6 +850,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
unsigned
short
circuit_index
,
circuit_id
;
unsigned
short
circuit_index
,
circuit_id
;
unsigned
short
peer_circuit_index
,
peer_circuit_id
;
unsigned
short
peer_circuit_index
,
peer_circuit_id
;
unsigned
short
frametype
,
flags
,
window
,
timeout
;
unsigned
short
frametype
,
flags
,
window
,
timeout
;
int
ret
;
skb
->
sk
=
NULL
;
/* Initially we don't know who it's for */
skb
->
sk
=
NULL
;
/* Initially we don't know who it's for */
...
@@ -850,7 +908,9 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -850,7 +908,9 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
else
else
nr_sk
(
sk
)
->
bpqext
=
0
;
nr_sk
(
sk
)
->
bpqext
=
0
;
return
nr_process_rx_frame
(
sk
,
skb
);
ret
=
nr_process_rx_frame
(
sk
,
skb
);
bh_unlock_sock
(
sk
);
return
ret
;
}
}
/*
/*
...
@@ -880,6 +940,8 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -880,6 +940,8 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
if
(
!
sk
||
sk
->
sk_ack_backlog
==
sk
->
sk_max_ack_backlog
||
if
(
!
sk
||
sk
->
sk_ack_backlog
==
sk
->
sk_max_ack_backlog
||
(
make
=
nr_make_new
(
sk
))
==
NULL
)
{
(
make
=
nr_make_new
(
sk
))
==
NULL
)
{
nr_transmit_refusal
(
skb
,
0
);
nr_transmit_refusal
(
skb
,
0
);
if
(
sk
)
bh_unlock_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -897,7 +959,9 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -897,7 +959,9 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
nr_make
->
your_index
=
circuit_index
;
nr_make
->
your_index
=
circuit_index
;
nr_make
->
your_id
=
circuit_id
;
nr_make
->
your_id
=
circuit_id
;
bh_unlock_sock
(
sk
);
circuit
=
nr_find_next_circuit
();
circuit
=
nr_find_next_circuit
();
bh_lock_sock
(
sk
);
nr_make
->
my_index
=
circuit
/
256
;
nr_make
->
my_index
=
circuit
/
256
;
nr_make
->
my_id
=
circuit
%
256
;
nr_make
->
my_id
=
circuit
%
256
;
...
@@ -939,6 +1003,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -939,6 +1003,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
if
(
!
sock_flag
(
sk
,
SOCK_DEAD
))
if
(
!
sock_flag
(
sk
,
SOCK_DEAD
))
sk
->
sk_data_ready
(
sk
,
skb
->
len
);
sk
->
sk_data_ready
(
sk
,
skb
->
len
);
bh_unlock_sock
(
sk
);
return
1
;
return
1
;
}
}
...
@@ -957,28 +1022,42 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -957,28 +1022,42 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
if
(
msg
->
msg_flags
&
~
(
MSG_DONTWAIT
|
MSG_EOR
))
if
(
msg
->
msg_flags
&
~
(
MSG_DONTWAIT
|
MSG_EOR
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
sk
->
sk_zapped
)
lock_sock
(
sk
);
return
-
EADDRNOTAVAIL
;
if
(
sk
->
sk_zapped
)
{
err
=
-
EADDRNOTAVAIL
;
goto
out
;
}
if
(
sk
->
sk_shutdown
&
SEND_SHUTDOWN
)
{
if
(
sk
->
sk_shutdown
&
SEND_SHUTDOWN
)
{
send_sig
(
SIGPIPE
,
current
,
0
);
send_sig
(
SIGPIPE
,
current
,
0
);
return
-
EPIPE
;
err
=
-
EPIPE
;
goto
out
;
}
}
if
(
nr
->
device
==
NULL
)
if
(
nr
->
device
==
NULL
)
{
return
-
ENETUNREACH
;
err
=
-
ENETUNREACH
;
goto
out
;
}
if
(
usax
)
{
if
(
usax
)
{
if
(
msg
->
msg_namelen
<
sizeof
(
sax
))
if
(
msg
->
msg_namelen
<
sizeof
(
sax
))
{
return
-
EINVAL
;
err
=
-
EINVAL
;
goto
out
;
}
sax
=
*
usax
;
sax
=
*
usax
;
if
(
ax25cmp
(
&
nr
->
dest_addr
,
&
sax
.
sax25_call
)
!=
0
)
if
(
ax25cmp
(
&
nr
->
dest_addr
,
&
sax
.
sax25_call
)
!=
0
)
{
return
-
EISCONN
;
err
=
-
EISCONN
;
if
(
sax
.
sax25_family
!=
AF_NETROM
)
goto
out
;
return
-
EINVAL
;
}
if
(
sax
.
sax25_family
!=
AF_NETROM
)
{
err
=
-
EINVAL
;
goto
out
;
}
}
else
{
}
else
{
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
{
return
-
ENOTCONN
;
err
=
-
ENOTCONN
;
goto
out
;
}
sax
.
sax25_family
=
AF_NETROM
;
sax
.
sax25_family
=
AF_NETROM
;
sax
.
sax25_call
=
nr
->
dest_addr
;
sax
.
sax25_call
=
nr
->
dest_addr
;
}
}
...
@@ -987,10 +1066,10 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -987,10 +1066,10 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
/* Build a packet */
/* Build a packet */
SOCK_DEBUG
(
sk
,
"NET/ROM: sendto: building packet.
\n
"
);
SOCK_DEBUG
(
sk
,
"NET/ROM: sendto: building packet.
\n
"
);
size
=
len
+
AX25_BPQ_HEADER_LEN
+
AX25_MAX_HEADER_LEN
+
NR_NETWORK_LEN
+
NR_TRANSPORT_LEN
;
size
=
len
+
NR_NETWORK_LEN
+
NR_TRANSPORT_LEN
;
if
((
skb
=
sock_alloc_send_skb
(
sk
,
size
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
))
==
NULL
)
if
((
skb
=
sock_alloc_send_skb
(
sk
,
size
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
))
==
NULL
)
return
err
;
goto
out
;
skb_reserve
(
skb
,
size
-
len
);
skb_reserve
(
skb
,
size
-
len
);
...
@@ -1025,12 +1104,16 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -1025,12 +1104,16 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
{
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
{
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
ENOTCONN
;
err
=
-
ENOTCONN
;
goto
out
;
}
}
nr_output
(
sk
,
skb
);
/* Shove it onto the queue */
nr_output
(
sk
,
skb
);
/* Shove it onto the queue */
return
len
;
err
=
len
;
out:
release_sock
(
sk
);
return
err
;
}
}
static
int
nr_recvmsg
(
struct
kiocb
*
iocb
,
struct
socket
*
sock
,
static
int
nr_recvmsg
(
struct
kiocb
*
iocb
,
struct
socket
*
sock
,
...
@@ -1047,12 +1130,17 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -1047,12 +1130,17 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
* us! We do one quick check first though
* us! We do one quick check first though
*/
*/
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
lock_sock
(
sk
);
if
(
sk
->
sk_state
!=
TCP_ESTABLISHED
)
{
release_sock
(
sk
);
return
-
ENOTCONN
;
return
-
ENOTCONN
;
}
/* Now we can treat all alike */
/* Now we can treat all alike */
if
((
skb
=
skb_recv_datagram
(
sk
,
flags
&
~
MSG_DONTWAIT
,
flags
&
MSG_DONTWAIT
,
&
er
))
==
NULL
)
if
((
skb
=
skb_recv_datagram
(
sk
,
flags
&
~
MSG_DONTWAIT
,
flags
&
MSG_DONTWAIT
,
&
er
))
==
NULL
)
{
release_sock
(
sk
);
return
er
;
return
er
;
}
skb
->
h
.
raw
=
skb
->
data
;
skb
->
h
.
raw
=
skb
->
data
;
copied
=
skb
->
len
;
copied
=
skb
->
len
;
...
@@ -1073,6 +1161,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -1073,6 +1161,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_free_datagram
(
sk
,
skb
);
skb_free_datagram
(
sk
,
skb
);
release_sock
(
sk
);
return
copied
;
return
copied
;
}
}
...
@@ -1080,13 +1169,16 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -1080,13 +1169,16 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
static
int
nr_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
int
nr_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
int
ret
;
lock_sock
(
sk
);
switch
(
cmd
)
{
switch
(
cmd
)
{
case
TIOCOUTQ
:
{
case
TIOCOUTQ
:
{
long
amount
;
long
amount
;
amount
=
sk
->
sk_sndbuf
-
atomic_read
(
&
sk
->
sk_wmem_alloc
);
amount
=
sk
->
sk_sndbuf
-
atomic_read
(
&
sk
->
sk_wmem_alloc
);
if
(
amount
<
0
)
if
(
amount
<
0
)
amount
=
0
;
amount
=
0
;
release_sock
(
sk
);
return
put_user
(
amount
,
(
int
*
)
arg
);
return
put_user
(
amount
,
(
int
*
)
arg
);
}
}
...
@@ -1096,15 +1188,21 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
...
@@ -1096,15 +1188,21 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
/* These two are safe on a single CPU system as only user tasks fiddle here */
/* These two are safe on a single CPU system as only user tasks fiddle here */
if
((
skb
=
skb_peek
(
&
sk
->
sk_receive_queue
))
!=
NULL
)
if
((
skb
=
skb_peek
(
&
sk
->
sk_receive_queue
))
!=
NULL
)
amount
=
skb
->
len
;
amount
=
skb
->
len
;
release_sock
(
sk
);
return
put_user
(
amount
,
(
int
*
)
arg
);
return
put_user
(
amount
,
(
int
*
)
arg
);
}
}
case
SIOCGSTAMP
:
case
SIOCGSTAMP
:
if
(
sk
!=
NULL
)
{
if
(
sk
!=
NULL
)
{
if
(
!
sk
->
sk_stamp
.
tv_sec
)
if
(
!
sk
->
sk_stamp
.
tv_sec
)
{
release_sock
(
sk
);
return
-
ENOENT
;
return
-
ENOENT
;
return
copy_to_user
((
void
*
)
arg
,
&
sk
->
sk_stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
}
ret
=
copy_to_user
((
void
*
)
arg
,
&
sk
->
sk_stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
release_sock
(
sk
);
return
ret
;
}
}
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
case
SIOCGIFADDR
:
case
SIOCGIFADDR
:
...
@@ -1117,17 +1215,21 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
...
@@ -1117,17 +1215,21 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case
SIOCSIFNETMASK
:
case
SIOCSIFNETMASK
:
case
SIOCGIFMETRIC
:
case
SIOCGIFMETRIC
:
case
SIOCSIFMETRIC
:
case
SIOCSIFMETRIC
:
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
case
SIOCADDRT
:
case
SIOCADDRT
:
case
SIOCDELRT
:
case
SIOCDELRT
:
case
SIOCNRDECOBS
:
case
SIOCNRDECOBS
:
release_sock
(
sk
);
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
return
nr_rt_ioctl
(
cmd
,
(
void
*
)
arg
);
return
nr_rt_ioctl
(
cmd
,
(
void
*
)
arg
);
default:
default:
release_sock
(
sk
);
return
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
return
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
}
}
release_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -1147,7 +1249,9 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length)
...
@@ -1147,7 +1249,9 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length)
len
+=
sprintf
(
buffer
,
"user_addr dest_node src_node dev my your st vs vr va t1 t2 t4 idle n2 wnd Snd-Q Rcv-Q inode
\n
"
);
len
+=
sprintf
(
buffer
,
"user_addr dest_node src_node dev my your st vs vr va t1 t2 t4 idle n2 wnd Snd-Q Rcv-Q inode
\n
"
);
sk_for_each
(
s
,
node
,
&
nr_list
)
{
sk_for_each
(
s
,
node
,
&
nr_list
)
{
nr_cb
*
nr
=
nr_sk
(
s
);
nr_cb
*
nr
;
bh_lock_sock
(
s
);
nr
=
nr_sk
(
s
);
if
((
dev
=
nr
->
device
)
==
NULL
)
if
((
dev
=
nr
->
device
)
==
NULL
)
devname
=
"???"
;
devname
=
"???"
;
...
@@ -1190,7 +1294,7 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length)
...
@@ -1190,7 +1294,7 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length)
len
=
0
;
len
=
0
;
begin
=
pos
;
begin
=
pos
;
}
}
bh_unlock_sock
(
s
);
if
(
pos
>
offset
+
length
)
if
(
pos
>
offset
+
length
)
break
;
break
;
}
}
...
...
net/netrom/nr_in.c
View file @
94ca866c
...
@@ -74,6 +74,7 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
...
@@ -74,6 +74,7 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
static
int
nr_state1_machine
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
static
int
nr_state1_machine
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
int
frametype
)
int
frametype
)
{
{
bh_lock_sock
(
sk
);
switch
(
frametype
)
{
switch
(
frametype
)
{
case
NR_CONNACK
:
{
case
NR_CONNACK
:
{
nr_cb
*
nr
=
nr_sk
(
sk
);
nr_cb
*
nr
=
nr_sk
(
sk
);
...
@@ -102,6 +103,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
...
@@ -102,6 +103,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
default:
default:
break
;
break
;
}
}
bh_unlock_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -114,6 +116,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
...
@@ -114,6 +116,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
static
int
nr_state2_machine
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
static
int
nr_state2_machine
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
int
frametype
)
int
frametype
)
{
{
bh_lock_sock
(
sk
);
switch
(
frametype
)
{
switch
(
frametype
)
{
case
NR_CONNACK
|
NR_CHOKE_FLAG
:
case
NR_CONNACK
|
NR_CHOKE_FLAG
:
nr_disconnect
(
sk
,
ECONNRESET
);
nr_disconnect
(
sk
,
ECONNRESET
);
...
@@ -129,6 +132,7 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
...
@@ -129,6 +132,7 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
default:
default:
break
;
break
;
}
}
bh_unlock_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -150,6 +154,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
...
@@ -150,6 +154,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
nr
=
skb
->
data
[
18
];
nr
=
skb
->
data
[
18
];
ns
=
skb
->
data
[
17
];
ns
=
skb
->
data
[
17
];
bh_lock_sock
(
sk
);
switch
(
frametype
)
{
switch
(
frametype
)
{
case
NR_CONNREQ
:
case
NR_CONNREQ
:
nr_write_internal
(
sk
,
NR_CONNACK
);
nr_write_internal
(
sk
,
NR_CONNACK
);
...
@@ -260,6 +265,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
...
@@ -260,6 +265,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
default:
default:
break
;
break
;
}
}
bh_unlock_sock
(
sk
);
return
queued
;
return
queued
;
}
}
...
...
net/netrom/nr_timer.c
View file @
94ca866c
...
@@ -143,7 +143,10 @@ static void nr_heartbeat_expiry(unsigned long param)
...
@@ -143,7 +143,10 @@ static void nr_heartbeat_expiry(unsigned long param)
is accepted() it isn't 'dead' so doesn't get removed. */
is accepted() it isn't 'dead' so doesn't get removed. */
if
(
sock_flag
(
sk
,
SOCK_DESTROY
)
||
if
(
sock_flag
(
sk
,
SOCK_DESTROY
)
||
(
sk
->
sk_state
==
TCP_LISTEN
&&
sock_flag
(
sk
,
SOCK_DEAD
)))
{
(
sk
->
sk_state
==
TCP_LISTEN
&&
sock_flag
(
sk
,
SOCK_DEAD
)))
{
sock_hold
(
sk
);
nr_destroy_socket
(
sk
);
nr_destroy_socket
(
sk
);
bh_unlock_sock
(
sk
);
sock_put
(
sk
);
return
;
return
;
}
}
break
;
break
;
...
@@ -227,6 +230,7 @@ static void nr_t1timer_expiry(unsigned long param)
...
@@ -227,6 +230,7 @@ static void nr_t1timer_expiry(unsigned long param)
case
NR_STATE_1
:
case
NR_STATE_1
:
if
(
nr
->
n2count
==
nr
->
n2
)
{
if
(
nr
->
n2count
==
nr
->
n2
)
{
nr_disconnect
(
sk
,
ETIMEDOUT
);
nr_disconnect
(
sk
,
ETIMEDOUT
);
bh_unlock_sock
(
sk
);
return
;
return
;
}
else
{
}
else
{
nr
->
n2count
++
;
nr
->
n2count
++
;
...
@@ -237,6 +241,7 @@ static void nr_t1timer_expiry(unsigned long param)
...
@@ -237,6 +241,7 @@ static void nr_t1timer_expiry(unsigned long param)
case
NR_STATE_2
:
case
NR_STATE_2
:
if
(
nr
->
n2count
==
nr
->
n2
)
{
if
(
nr
->
n2count
==
nr
->
n2
)
{
nr_disconnect
(
sk
,
ETIMEDOUT
);
nr_disconnect
(
sk
,
ETIMEDOUT
);
bh_unlock_sock
(
sk
);
return
;
return
;
}
else
{
}
else
{
nr
->
n2count
++
;
nr
->
n2count
++
;
...
@@ -247,6 +252,7 @@ static void nr_t1timer_expiry(unsigned long param)
...
@@ -247,6 +252,7 @@ static void nr_t1timer_expiry(unsigned long param)
case
NR_STATE_3
:
case
NR_STATE_3
:
if
(
nr
->
n2count
==
nr
->
n2
)
{
if
(
nr
->
n2count
==
nr
->
n2
)
{
nr_disconnect
(
sk
,
ETIMEDOUT
);
nr_disconnect
(
sk
,
ETIMEDOUT
);
bh_unlock_sock
(
sk
);
return
;
return
;
}
else
{
}
else
{
nr
->
n2count
++
;
nr
->
n2count
++
;
...
...
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