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
Kirill Smelkov
linux
Commits
5d1931fc
Commit
5d1931fc
authored
Oct 18, 2002
by
Steven Whitehouse
Committed by
David S. Miller
Oct 18, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[DECNET]: Update to support timeouts.
parent
69dda393
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
275 additions
and
252 deletions
+275
-252
net/decnet/af_decnet.c
net/decnet/af_decnet.c
+205
-230
net/decnet/dn_dev.c
net/decnet/dn_dev.c
+70
-22
No files found.
net/decnet/af_decnet.c
View file @
5d1931fc
...
@@ -37,6 +37,9 @@
...
@@ -37,6 +37,9 @@
* when required.
* when required.
* Patrick Caulfield: /proc/net/decnet now has object name/number
* Patrick Caulfield: /proc/net/decnet now has object name/number
* Steve Whitehouse: Fixed local port allocation, hashed sk list
* Steve Whitehouse: Fixed local port allocation, hashed sk list
* Matthew Wilcox: Fixes for dn_ioctl()
* Steve Whitehouse: New connect/accept logic to allow timeouts and
* prepare for sendpage etc.
*/
*/
...
@@ -482,7 +485,7 @@ struct sock *dn_alloc_sock(struct socket *sock, int gfp)
...
@@ -482,7 +485,7 @@ struct sock *dn_alloc_sock(struct socket *sock, int gfp)
if
(
sock
)
{
if
(
sock
)
{
sock
->
ops
=
&
dn_proto_ops
;
sock
->
ops
=
&
dn_proto_ops
;
}
}
sock_init_data
(
sock
,
sk
);
sock_init_data
(
sock
,
sk
);
sk
->
backlog_rcv
=
dn_nsp_backlog_rcv
;
sk
->
backlog_rcv
=
dn_nsp_backlog_rcv
;
sk
->
destruct
=
dn_destruct
;
sk
->
destruct
=
dn_destruct
;
...
@@ -871,95 +874,177 @@ static int dn_auto_bind(struct socket *sock)
...
@@ -871,95 +874,177 @@ static int dn_auto_bind(struct socket *sock)
return
rv
;
return
rv
;
}
}
static
int
dn_confirm_accept
(
struct
sock
*
sk
,
long
*
timeo
,
int
allocation
)
{
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
DECLARE_WAITQUEUE
(
wait
,
current
);
int
err
;
if
(
scp
->
state
!=
DN_CR
)
return
-
EINVAL
;
scp
->
state
=
DN_CC
;
dn_send_conn_conf
(
sk
,
allocation
);
static
int
dn_connect
(
struct
socket
*
sock
,
struct
sockaddr
*
uaddr
,
int
addr_len
,
int
flags
)
add_wait_queue
(
sk
->
sleep
,
&
wait
);
for
(;;)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
release_sock
(
sk
);
if
(
scp
->
state
==
DN_CC
)
*
timeo
=
schedule_timeout
(
*
timeo
);
lock_sock
(
sk
);
err
=
0
;
if
(
scp
->
state
==
DN_RUN
)
break
;
err
=
sock_error
(
sk
);
if
(
err
)
break
;
err
=
sock_intr_errno
(
*
timeo
);
if
(
signal_pending
(
current
))
break
;
err
=
-
EAGAIN
;
if
(
!*
timeo
)
break
;
}
remove_wait_queue
(
sk
->
sleep
,
&
wait
);
current
->
state
=
TASK_RUNNING
;
return
err
;
}
static
int
dn_wait_run
(
struct
sock
*
sk
,
long
*
timeo
)
{
{
struct
sockaddr_dn
*
addr
=
(
struct
sockaddr_dn
*
)
uaddr
;
struct
sock
*
sk
=
sock
->
sk
;
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
int
err
=
-
EISCONN
;
DECLARE_WAITQUEUE
(
wait
,
current
);
int
err
=
0
;
if
(
scp
->
state
==
DN_RUN
)
goto
out
;
if
(
!*
timeo
)
return
-
EALREADY
;
add_wait_queue
(
sk
->
sleep
,
&
wait
);
for
(;;)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
release_sock
(
sk
);
if
(
scp
->
state
==
DN_CI
||
scp
->
state
==
DN_CC
)
*
timeo
=
schedule_timeout
(
*
timeo
);
lock_sock
(
sk
);
lock_sock
(
sk
);
err
=
0
;
if
(
scp
->
state
==
DN_RUN
)
break
;
err
=
sock_error
(
sk
);
if
(
err
)
break
;
err
=
sock_intr_errno
(
*
timeo
);
if
(
signal_pending
(
current
))
break
;
err
=
-
ETIMEDOUT
;
if
(
!*
timeo
)
break
;
}
remove_wait_queue
(
sk
->
sleep
,
&
wait
);
current
->
state
=
TASK_RUNNING
;
out:
if
(
err
==
0
)
{
sk
->
socket
->
state
=
SS_CONNECTED
;
}
return
err
;
}
static
int
__dn_connect
(
struct
sock
*
sk
,
struct
sockaddr_dn
*
addr
,
int
addrlen
,
long
*
timeo
,
int
flags
)
{
struct
socket
*
sock
=
sk
->
socket
;
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
int
err
=
-
EISCONN
;
if
(
sock
->
state
==
SS_CONNECTED
)
if
(
sock
->
state
==
SS_CONNECTED
)
goto
out
;
goto
out
;
if
(
sock
->
state
==
SS_CONNECTING
)
{
if
(
sock
->
state
==
SS_CONNECTING
)
{
err
=
0
;
err
=
0
;
if
(
sk
->
state
==
TCP_ESTABLISHED
)
if
(
scp
->
state
==
DN_RUN
)
{
sock
->
state
=
SS_CONNECTED
;
goto
out
;
goto
out
;
}
err
=
-
ECONNREFUSED
;
err
=
-
ECONNREFUSED
;
if
(
sk
->
state
==
TCP_CLOSE
)
if
(
scp
->
state
!=
DN_CI
&&
scp
->
state
!=
DN_CC
)
{
sock
->
state
=
SS_UNCONNECTED
;
goto
out
;
goto
out
;
}
}
return
dn_wait_run
(
sk
,
timeo
);
}
err
=
-
EINVAL
;
err
=
-
EINVAL
;
if
(
DN_SK
(
sk
)
->
state
!=
DN_O
)
if
(
scp
->
state
!=
DN_O
)
goto
out
;
goto
out
;
if
(
addr
_
len
!=
sizeof
(
struct
sockaddr_dn
))
if
(
addr
==
NULL
||
addr
len
!=
sizeof
(
struct
sockaddr_dn
))
goto
out
;
goto
out
;
if
(
addr
->
sdn_family
!=
AF_DECnet
)
if
(
addr
->
sdn_family
!=
AF_DECnet
)
goto
out
;
goto
out
;
if
(
addr
->
sdn_flags
&
SDF_WILD
)
if
(
addr
->
sdn_flags
&
SDF_WILD
)
goto
out
;
goto
out
;
err
=
-
EADDRNOTAVAIL
;
if
(
sk
->
zapped
)
{
if
(
sk
->
zapped
&&
(
err
=
dn_auto_bind
(
sock
)))
err
=
dn_auto_bind
(
sk
->
socket
);
if
(
err
)
goto
out
;
goto
out
;
}
memcpy
(
&
scp
->
peer
,
addr
,
addr_len
);
memcpy
(
&
scp
->
peer
,
addr
,
sizeof
(
struct
sockaddr_dn
)
);
err
=
-
EHOSTUNREACH
;
err
=
-
EHOSTUNREACH
;
if
(
dn_route_output
(
&
sk
->
dst_cache
,
dn_saddr2dn
(
&
scp
->
peer
),
dn_saddr2dn
(
&
scp
->
addr
),
0
)
<
0
)
if
(
dn_route_output
(
&
sk
->
dst_cache
,
dn_saddr2dn
(
&
scp
->
peer
),
dn_saddr2dn
(
&
scp
->
addr
),
flags
&
MSG_TRYHARD
)
<
0
)
goto
out
;
goto
out
;
sk
->
state
=
TCP_SYN_SENT
;
sock
->
state
=
SS_CONNECTING
;
sock
->
state
=
SS_CONNECTING
;
DN_SK
(
sk
)
->
state
=
DN_CI
;
scp
->
state
=
DN_CI
;
dn_nsp_send_conninit
(
sk
,
NSP_CI
);
dn_nsp_send_conninit
(
sk
,
NSP_CI
);
err
=
-
EINPROGRESS
;
err
=
-
EINPROGRESS
;
if
((
sk
->
state
==
TCP_SYN_SENT
)
&&
(
flags
&
O_NONBLOCK
))
if
(
*
timeo
)
{
goto
out
;
err
=
dn_wait_run
(
sk
,
timeo
);
while
(
sk
->
state
==
TCP_SYN_SENT
)
{
err
=
-
ERESTARTSYS
;
if
(
signal_pending
(
current
))
goto
out
;
if
((
err
=
sock_error
(
sk
))
!=
0
)
{
sock
->
state
=
SS_UNCONNECTED
;
goto
out
;
}
}
out:
return
err
;
}
SOCK_SLEEP_PRE
(
sk
);
static
int
dn_connect
(
struct
socket
*
sock
,
struct
sockaddr
*
uaddr
,
int
addrlen
,
int
flags
)
{
struct
sockaddr_dn
*
addr
=
(
struct
sockaddr_dn
*
)
uaddr
;
struct
sock
*
sk
=
sock
->
sk
;
int
err
;
long
timeo
=
sock_sndtimeo
(
sk
,
flags
&
O_NONBLOCK
);
if
(
sk
->
state
==
TCP_SYN_SENT
)
lock_sock
(
sk
);
schedule
();
err
=
__dn_connect
(
sk
,
addr
,
addrlen
,
&
timeo
,
0
);
release_sock
(
sk
);
SOCK_SLEEP_POST
(
sk
)
;
return
err
;
}
}
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
static
inline
int
dn_check_state
(
struct
sock
*
sk
,
struct
sockaddr_dn
*
addr
,
int
addrlen
,
long
*
timeo
,
int
flags
)
sock
->
state
=
SS_UNCONNECTED
;
{
err
=
sock_error
(
sk
);
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
goto
out
;
}
err
=
0
;
switch
(
scp
->
state
)
{
sock
->
state
=
SS_CONNECTED
;
case
DN_RUN
:
out:
return
0
;
release_sock
(
sk
);
case
DN_CR
:
return
dn_confirm_accept
(
sk
,
timeo
,
sk
->
allocation
);
case
DN_CI
:
case
DN_CC
:
return
dn_wait_run
(
sk
,
timeo
);
case
DN_O
:
return
__dn_connect
(
sk
,
addr
,
addrlen
,
timeo
,
flags
);
}
return
err
;
return
-
EINVAL
;
}
}
static
void
dn_access_copy
(
struct
sk_buff
*
skb
,
struct
accessdata_dn
*
acc
)
static
void
dn_access_copy
(
struct
sk_buff
*
skb
,
struct
accessdata_dn
*
acc
)
{
{
unsigned
char
*
ptr
=
skb
->
data
;
unsigned
char
*
ptr
=
skb
->
data
;
...
@@ -990,42 +1075,39 @@ static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
...
@@ -990,42 +1075,39 @@ static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
}
}
static
struct
sk_buff
*
dn_wait_for_connect
(
struct
sock
*
sk
,
long
*
timeo
)
/*
* This is here for use in the sockopt() call as well as
* in accept(). Must be called with a locked socket.
*/
static
int
dn_wait_accept
(
struct
socket
*
sock
,
int
flags
)
{
{
struct
sock
*
sk
=
sock
->
sk
;
DECLARE_WAITQUEUE
(
wait
,
current
);
struct
sk_buff
*
skb
=
NULL
;
int
err
=
0
;
while
(
sk
->
state
==
TCP_LISTEN
)
{
add_wait_queue_exclusive
(
sk
->
sleep
,
&
wait
);
if
(
flags
&
O_NONBLOCK
)
{
for
(;;)
{
return
-
EAGAIN
;
set_current_state
(
TASK_INTERRUPTIBLE
);
release_sock
(
sk
);
skb
=
skb_dequeue
(
&
sk
->
receive_queue
);
if
(
skb
==
NULL
)
{
*
timeo
=
schedule_timeout
(
*
timeo
);
skb
=
skb_dequeue
(
&
sk
->
receive_queue
);
}
}
lock_sock
(
sk
);
SOCK_SLEEP_PRE
(
sk
)
if
(
skb
!=
NULL
)
break
;
if
(
sk
->
state
==
TCP_LISTEN
)
err
=
-
EINVAL
;
schedule
();
if
(
sk
->
state
!=
TCP_LISTEN
)
break
;
SOCK_SLEEP_POST
(
sk
)
err
=
sock_intr_errno
(
*
timeo
);
if
(
signal_pending
(
current
))
if
(
signal_pending
(
current
))
return
-
ERESTARTSYS
;
/* But of course you don't! */
break
;
}
err
=
-
EAGAIN
;
if
(
!*
timeo
)
if
((
DN_SK
(
sk
)
->
state
!=
DN_RUN
)
&&
(
DN_SK
(
sk
)
->
state
!=
DN_DRC
))
{
break
;
sock
->
state
=
SS_UNCONNECTED
;
return
sock_error
(
sk
);
}
}
remove_wait_queue
(
sk
->
sleep
,
&
wait
);
sock
->
state
=
SS_CONNECTED
;
current
->
state
=
TASK_RUNNING
;
return
skb
==
NULL
?
ERR_PTR
(
err
)
:
skb
;
return
0
;
}
}
static
int
dn_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
,
int
flags
)
static
int
dn_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
,
int
flags
)
{
{
struct
sock
*
sk
=
sock
->
sk
,
*
newsk
;
struct
sock
*
sk
=
sock
->
sk
,
*
newsk
;
...
@@ -1034,52 +1116,32 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
...
@@ -1034,52 +1116,32 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
unsigned
char
menuver
;
unsigned
char
menuver
;
int
err
=
0
;
int
err
=
0
;
unsigned
char
type
;
unsigned
char
type
;
long
timeo
=
sock_rcvtimeo
(
sk
,
flags
&
O_NONBLOCK
);
lock_sock
(
sk
);
lock_sock
(
sk
);
if
(
sk
->
state
!=
TCP_LISTEN
)
{
if
(
sk
->
state
!=
TCP_LISTEN
||
DN_SK
(
sk
)
->
state
!=
DN_O
)
{
release_sock
(
sk
);
release_sock
(
sk
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
(
DN_SK
(
sk
)
->
state
!=
DN_O
)
{
skb
=
skb_dequeue
(
&
sk
->
receive_queue
);
if
(
skb
==
NULL
)
{
skb
=
dn_wait_for_connect
(
sk
,
&
timeo
);
if
(
IS_ERR
(
skb
))
{
release_sock
(
sk
);
release_sock
(
sk
);
return
-
EINVAL
;
return
PTR_ERR
(
sk
)
;
}
}
do
{
if
((
skb
=
skb_dequeue
(
&
sk
->
receive_queue
))
==
NULL
)
{
if
(
flags
&
O_NONBLOCK
)
{
release_sock
(
sk
);
return
-
EAGAIN
;
}
}
SOCK_SLEEP_PRE
(
sk
);
if
(
!
skb_peek
(
&
sk
->
receive_queue
))
schedule
();
SOCK_SLEEP_POST
(
sk
);
if
(
signal_pending
(
current
))
{
release_sock
(
sk
);
return
-
ERESTARTSYS
;
}
}
}
while
(
skb
==
NULL
);
cb
=
DN_SKB_CB
(
skb
);
cb
=
DN_SKB_CB
(
skb
);
sk
->
ack_backlog
--
;
if
((
newsk
=
dn_alloc_sock
(
newsock
,
sk
->
allocation
))
==
NULL
)
{
newsk
=
dn_alloc_sock
(
newsock
,
sk
->
allocation
);
if
(
newsk
==
NULL
)
{
release_sock
(
sk
);
release_sock
(
sk
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
ENOBUFS
;
return
-
ENOBUFS
;
}
}
sk
->
ack_backlog
--
;
release_sock
(
sk
);
release_sock
(
sk
);
dst_release
(
xchg
(
&
newsk
->
dst_cache
,
skb
->
dst
));
dst_release
(
xchg
(
&
newsk
->
dst_cache
,
skb
->
dst
));
...
@@ -1099,8 +1161,6 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
...
@@ -1099,8 +1161,6 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
DN_SK
(
newsk
)
->
max_window
=
decnet_no_fc_max_cwnd
;
DN_SK
(
newsk
)
->
max_window
=
decnet_no_fc_max_cwnd
;
newsk
->
state
=
TCP_LISTEN
;
newsk
->
state
=
TCP_LISTEN
;
newsk
->
zapped
=
0
;
memcpy
(
&
(
DN_SK
(
newsk
)
->
addr
),
&
(
DN_SK
(
sk
)
->
addr
),
sizeof
(
struct
sockaddr_dn
));
memcpy
(
&
(
DN_SK
(
newsk
)
->
addr
),
&
(
DN_SK
(
sk
)
->
addr
),
sizeof
(
struct
sockaddr_dn
));
/*
/*
...
@@ -1137,23 +1197,18 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
...
@@ -1137,23 +1197,18 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
sizeof
(
struct
optdata_dn
));
sizeof
(
struct
optdata_dn
));
lock_sock
(
newsk
);
lock_sock
(
newsk
);
/*
err
=
dn_hash_sock
(
newsk
);
* FIXME: This can fail if we've run out of local ports....
if
(
err
==
0
)
{
*/
newsk
->
zapped
=
0
;
dn_hash_sock
(
newsk
);
dn_send_conn_ack
(
newsk
);
dn_send_conn_ack
(
newsk
);
/*
/*
* Here we use sk->allocation since although the conn conf is
* Here we use sk->allocation since although the conn conf is
* for the newsk, the context is the old socket.
* for the newsk, the context is the old socket.
*/
*/
if
(
DN_SK
(
newsk
)
->
accept_mode
==
ACC_IMMED
)
{
if
(
DN_SK
(
newsk
)
->
accept_mode
==
ACC_IMMED
)
DN_SK
(
newsk
)
->
state
=
DN_CC
;
err
=
dn_confirm_accept
(
newsk
,
&
timeo
,
sk
->
allocation
);
dn_send_conn_conf
(
newsk
,
sk
->
allocation
);
err
=
dn_wait_accept
(
newsock
,
flags
);
}
}
release_sock
(
newsk
);
release_sock
(
newsk
);
return
err
;
return
err
;
}
}
...
@@ -1227,30 +1282,6 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
...
@@ -1227,30 +1282,6 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return
dn_fib_ioctl
(
sock
,
cmd
,
arg
);
return
dn_fib_ioctl
(
sock
,
cmd
,
arg
);
#endif
/* CONFIG_DECNET_ROUTER */
#endif
/* CONFIG_DECNET_ROUTER */
#if 0
case OSIOCSNETADDR:
if (!capable(CAP_NET_ADMIN)) {
err = -EPERM;
break;
}
dn_dev_devices_off();
decnet_address = (unsigned short)arg;
dn_dev_devices_on();
err = 0;
break;
case OSIOCGNETADDR:
err = put_user(decnet_address, (unsigned short *)arg);
break;
#endif
case
SIOCGIFCONF
:
case
SIOCGIFFLAGS
:
case
SIOCGIFBRDADDR
:
return
dev_ioctl
(
cmd
,(
void
*
)
arg
);
case
TIOCOUTQ
:
case
TIOCOUTQ
:
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
if
(
amount
<
0
)
if
(
amount
<
0
)
...
@@ -1274,6 +1305,10 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
...
@@ -1274,6 +1305,10 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
release_sock
(
sk
);
release_sock
(
sk
);
err
=
put_user
(
amount
,
(
int
*
)
arg
);
err
=
put_user
(
amount
,
(
int
*
)
arg
);
break
;
break
;
default:
err
=
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
}
}
return
err
;
return
err
;
...
@@ -1327,7 +1362,6 @@ static int dn_shutdown(struct socket *sock, int how)
...
@@ -1327,7 +1362,6 @@ static int dn_shutdown(struct socket *sock, int how)
if
(
how
!=
SHUTDOWN_MASK
)
if
(
how
!=
SHUTDOWN_MASK
)
goto
out
;
goto
out
;
sk
->
shutdown
=
how
;
sk
->
shutdown
=
how
;
dn_destroy_sock
(
sk
);
dn_destroy_sock
(
sk
);
err
=
0
;
err
=
0
;
...
@@ -1354,6 +1388,7 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
...
@@ -1354,6 +1388,7 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
long
timeo
;
union
{
union
{
struct
optdata_dn
opt
;
struct
optdata_dn
opt
;
struct
accessdata_dn
acc
;
struct
accessdata_dn
acc
;
...
@@ -1439,10 +1474,8 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
...
@@ -1439,10 +1474,8 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
if
(
scp
->
state
!=
DN_CR
)
if
(
scp
->
state
!=
DN_CR
)
return
-
EINVAL
;
return
-
EINVAL
;
timeo
=
sock_rcvtimeo
(
sk
,
0
);
scp
->
state
=
DN_CC
;
err
=
dn_confirm_accept
(
sk
,
&
timeo
,
sk
->
allocation
);
dn_send_conn_conf
(
sk
,
sk
->
allocation
);
err
=
dn_wait_accept
(
sock
,
sock
->
file
->
f_flags
);
return
err
;
return
err
;
case
DSO_CONREJECT
:
case
DSO_CONREJECT
:
...
@@ -1652,55 +1685,6 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt
...
@@ -1652,55 +1685,6 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt
}
}
/*
* Used by send/recvmsg to wait until the socket is connected
* before passing data.
*/
static
int
dn_wait_run
(
struct
sock
*
sk
,
int
flags
)
{
struct
dn_scp
*
scp
=
DN_SK
(
sk
);
int
err
=
0
;
switch
(
scp
->
state
)
{
case
DN_RUN
:
return
0
;
case
DN_CR
:
scp
->
state
=
DN_CC
;
dn_send_conn_conf
(
sk
,
sk
->
allocation
);
return
dn_wait_accept
(
sk
->
socket
,
(
flags
&
MSG_DONTWAIT
)
?
O_NONBLOCK
:
0
);
case
DN_CI
:
case
DN_CC
:
break
;
default:
return
-
ENOTCONN
;
}
if
(
flags
&
MSG_DONTWAIT
)
return
-
EWOULDBLOCK
;
do
{
if
((
err
=
sock_error
(
sk
))
!=
0
)
break
;
if
(
signal_pending
(
current
))
{
err
=
-
ERESTARTSYS
;
break
;
}
SOCK_SLEEP_PRE
(
sk
)
if
(
scp
->
state
!=
DN_RUN
)
schedule
();
SOCK_SLEEP_POST
(
sk
)
}
while
(
scp
->
state
!=
DN_RUN
);
return
0
;
}
static
int
dn_data_ready
(
struct
sock
*
sk
,
struct
sk_buff_head
*
q
,
int
flags
,
int
target
)
static
int
dn_data_ready
(
struct
sock
*
sk
,
struct
sk_buff_head
*
q
,
int
flags
,
int
target
)
{
{
struct
sk_buff
*
skb
=
q
->
next
;
struct
sk_buff
*
skb
=
q
->
next
;
...
@@ -1745,6 +1729,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -1745,6 +1729,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
struct
sk_buff
*
skb
,
*
nskb
;
struct
sk_buff
*
skb
,
*
nskb
;
struct
dn_skb_cb
*
cb
=
NULL
;
struct
dn_skb_cb
*
cb
=
NULL
;
unsigned
char
eor
=
0
;
unsigned
char
eor
=
0
;
long
timeo
=
sock_rcvtimeo
(
sk
,
flags
&
MSG_DONTWAIT
);
lock_sock
(
sk
);
lock_sock
(
sk
);
...
@@ -1753,16 +1738,18 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -1753,16 +1738,18 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
goto
out
;
goto
out
;
}
}
if
((
rv
=
dn_wait_run
(
sk
,
flags
))
!=
0
)
rv
=
dn_check_state
(
sk
,
NULL
,
0
,
&
timeo
,
flags
);
if
(
rv
)
goto
out
;
goto
out
;
if
(
sk
->
shutdown
&
RCV_SHUTDOWN
)
{
if
(
sk
->
shutdown
&
RCV_SHUTDOWN
)
{
if
(
!
(
flags
&
MSG_NOSIGNAL
))
send_sig
(
SIGPIPE
,
current
,
0
);
send_sig
(
SIGPIPE
,
current
,
0
);
rv
=
-
EPIPE
;
rv
=
-
EPIPE
;
goto
out
;
goto
out
;
}
}
if
(
flags
&
~
(
MSG_PEEK
|
MSG_OOB
|
MSG_WAITALL
|
MSG_DONTWAIT
))
{
if
(
flags
&
~
(
MSG_PEEK
|
MSG_OOB
|
MSG_WAITALL
|
MSG_DONTWAIT
|
MSG_NOSIGNAL
))
{
rv
=
-
EOPNOTSUPP
;
rv
=
-
EOPNOTSUPP
;
goto
out
;
goto
out
;
}
}
...
@@ -1920,34 +1907,22 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
...
@@ -1920,34 +1907,22 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
unsigned
short
ack
;
unsigned
short
ack
;
int
len
;
int
len
;
unsigned
char
fctype
;
unsigned
char
fctype
;
long
timeo
=
sock_sndtimeo
(
sk
,
flags
&
MSG_DONTWAIT
);
if
(
flags
&
~
(
MSG_TRYHARD
|
MSG_OOB
|
MSG_DONTWAIT
|
MSG_EOR
))
if
(
flags
&
~
(
MSG_TRYHARD
|
MSG_OOB
|
MSG_DONTWAIT
|
MSG_EOR
|
MSG_NOSIGNAL
))
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
if
(
addr_len
&&
(
addr_len
!=
sizeof
(
struct
sockaddr_dn
)))
if
(
addr_len
&&
(
addr_len
!=
sizeof
(
struct
sockaddr_dn
)))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
sk
->
zapped
&&
dn_auto_bind
(
sock
))
{
err
=
-
EADDRNOTAVAIL
;
goto
out
;
}
if
(
scp
->
state
==
DN_O
)
{
if
(
!
addr_len
||
!
addr
)
{
err
=
-
ENOTCONN
;
goto
out
;
}
if
((
err
=
dn_connect
(
sock
,
(
struct
sockaddr
*
)
addr
,
addr_len
,
(
flags
&
MSG_DONTWAIT
)
?
O_NONBLOCK
:
0
))
<
0
)
goto
out
;
}
lock_sock
(
sk
);
lock_sock
(
sk
);
if
((
err
=
dn_wait_run
(
sk
,
flags
))
<
0
)
err
=
dn_check_state
(
sk
,
addr
,
addr_len
,
&
timeo
,
flags
);
if
(
err
)
goto
out
;
goto
out
;
if
(
sk
->
shutdown
&
SEND_SHUTDOWN
)
{
if
(
sk
->
shutdown
&
SEND_SHUTDOWN
)
{
if
(
!
(
flags
&
MSG_NOSIGNAL
))
send_sig
(
SIGPIPE
,
current
,
0
);
send_sig
(
SIGPIPE
,
current
,
0
);
err
=
-
EPIPE
;
err
=
-
EPIPE
;
goto
out
;
goto
out
;
...
@@ -2117,7 +2092,7 @@ static int dn_device_event(struct notifier_block *this, unsigned long event,
...
@@ -2117,7 +2092,7 @@ static int dn_device_event(struct notifier_block *this, unsigned long event,
}
}
static
struct
notifier_block
dn_dev_notifier
=
{
static
struct
notifier_block
dn_dev_notifier
=
{
.
notifier_call
=
dn_device_event
,
.
notifier_call
=
dn_device_event
,
};
};
extern
int
dn_route_rcv
(
struct
sk_buff
*
,
struct
net_device
*
,
struct
packet_type
*
);
extern
int
dn_route_rcv
(
struct
sk_buff
*
,
struct
net_device
*
,
struct
packet_type
*
);
...
...
net/decnet/dn_dev.c
View file @
5d1931fc
...
@@ -181,30 +181,74 @@ static struct dn_dev_sysctl_table {
...
@@ -181,30 +181,74 @@ static struct dn_dev_sysctl_table {
}
dn_dev_sysctl
=
{
}
dn_dev_sysctl
=
{
NULL
,
NULL
,
{
{
{
NET_DECNET_CONF_DEV_FORWARDING
,
"forwarding"
,
{
(
void
*
)
DN_DEV_PARMS_OFFSET
(
forwarding
),
.
ctl_name
=
NET_DECNET_CONF_DEV_FORWARDING
,
sizeof
(
int
),
0644
,
NULL
,
.
procname
=
"forwarding"
,
dn_forwarding_proc
,
dn_forwarding_sysctl
,
.
data
=
(
void
*
)
DN_DEV_PARMS_OFFSET
(
forwarding
),
NULL
,
NULL
,
NULL
},
.
maxlen
=
sizeof
(
int
),
{
NET_DECNET_CONF_DEV_PRIORITY
,
"priority"
,
.
mode
=
0644
,
(
void
*
)
DN_DEV_PARMS_OFFSET
(
priority
),
.
proc_handler
=
dn_forwarding_proc
,
sizeof
(
int
),
0644
,
NULL
,
.
strategy
=
dn_forwarding_sysctl
,
proc_dointvec_minmax
,
sysctl_intvec
,
},
NULL
,
&
min_priority
,
&
max_priority
},
{
{
NET_DECNET_CONF_DEV_T2
,
"t2"
,
(
void
*
)
DN_DEV_PARMS_OFFSET
(
t2
),
.
ctl_name
=
NET_DECNET_CONF_DEV_PRIORITY
,
sizeof
(
int
),
0644
,
NULL
,
.
procname
=
"priority"
,
proc_dointvec_minmax
,
sysctl_intvec
,
.
data
=
(
void
*
)
DN_DEV_PARMS_OFFSET
(
priority
),
NULL
,
&
min_t2
,
&
max_t2
},
.
maxlen
=
sizeof
(
int
),
{
NET_DECNET_CONF_DEV_T3
,
"t3"
,
(
void
*
)
DN_DEV_PARMS_OFFSET
(
t3
),
.
mode
=
0644
,
sizeof
(
int
),
0644
,
NULL
,
.
proc_handler
=
proc_dointvec_minmax
,
proc_dointvec_minmax
,
sysctl_intvec
,
.
strategy
=
sysctl_intvec
,
NULL
,
&
min_t3
,
&
max_t3
},
.
extra1
=
&
min_priority
,
.
extra2
=
&
max_priority
},
{
.
ctl_name
=
NET_DECNET_CONF_DEV_T2
,
.
procname
=
"t2"
,
.
data
=
(
void
*
)
DN_DEV_PARMS_OFFSET
(
t2
),
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
proc_dointvec_minmax
,
.
strategy
=
sysctl_intvec
,
.
extra1
=
&
min_t2
,
.
extra2
=
&
max_t2
},
{
.
ctl_name
=
NET_DECNET_CONF_DEV_T3
,
.
procname
=
"t3"
,
.
data
=
(
void
*
)
DN_DEV_PARMS_OFFSET
(
t3
),
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
proc_dointvec_minmax
,
.
strategy
=
sysctl_intvec
,
.
extra1
=
&
min_t3
,
.
extra2
=
&
max_t3
},
{
0
}
{
0
}
},
},
{{
0
,
""
,
NULL
,
0
,
0555
,
dn_dev_sysctl
.
dn_dev_vars
},
{
0
}},
{{
{{
NET_DECNET_CONF
,
"conf"
,
NULL
,
0
,
0555
,
dn_dev_sysctl
.
dn_dev_dev
},
{
0
}},
.
ctl_name
=
0
,
{{
NET_DECNET
,
"decnet"
,
NULL
,
0
,
0555
,
dn_dev_sysctl
.
dn_dev_conf_dir
},
{
0
}},
.
procname
=
""
,
{{
CTL_NET
,
"net"
,
NULL
,
0
,
0555
,
dn_dev_sysctl
.
dn_dev_proto_dir
},
{
0
}}
.
mode
=
0555
,
.
child
=
dn_dev_sysctl
.
dn_dev_vars
},
{
0
}},
{{
.
ctl_name
=
NET_DECNET_CONF
,
.
procname
=
"conf"
,
.
mode
=
0555
,
.
child
=
dn_dev_sysctl
.
dn_dev_dev
},
{
0
}},
{{
.
ctl_name
=
NET_DECNET
,
.
procname
=
"decnet"
,
.
mode
=
0555
,
.
child
=
dn_dev_sysctl
.
dn_dev_conf_dir
},
{
0
}},
{{
.
ctl_name
=
CTL_NET
,
.
procname
=
"net"
,
.
mode
=
0555
,
.
child
=
dn_dev_sysctl
.
dn_dev_proto_dir
},
{
0
}}
};
};
static
void
dn_dev_sysctl_register
(
struct
net_device
*
dev
,
struct
dn_dev_parms
*
parms
)
static
void
dn_dev_sysctl_register
(
struct
net_device
*
dev
,
struct
dn_dev_parms
*
parms
)
...
@@ -1211,8 +1255,10 @@ void dn_dev_devices_off(void)
...
@@ -1211,8 +1255,10 @@ void dn_dev_devices_off(void)
{
{
struct
net_device
*
dev
;
struct
net_device
*
dev
;
rtnl_lock
();
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
dn_dev_down
(
dev
);
dn_dev_down
(
dev
);
rtnl_unlock
();
}
}
...
@@ -1220,10 +1266,12 @@ void dn_dev_devices_on(void)
...
@@ -1220,10 +1266,12 @@ void dn_dev_devices_on(void)
{
{
struct
net_device
*
dev
;
struct
net_device
*
dev
;
rtnl_lock
();
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
{
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
{
if
(
dev
->
flags
&
IFF_UP
)
if
(
dev
->
flags
&
IFF_UP
)
dn_dev_up
(
dev
);
dn_dev_up
(
dev
);
}
}
rtnl_unlock
();
}
}
...
...
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