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
457a6c8c
Commit
457a6c8c
authored
Sep 28, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/home/acme/BK/x25-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
1b924668
a134be24
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
638 additions
and
443 deletions
+638
-443
include/net/lapb.h
include/net/lapb.h
+31
-29
net/lapb/lapb_iface.c
net/lapb/lapb_iface.c
+175
-133
net/lapb/lapb_in.c
net/lapb/lapb_in.c
+210
-130
net/lapb/lapb_out.c
net/lapb/lapb_out.c
+35
-34
net/lapb/lapb_subr.c
net/lapb/lapb_subr.c
+55
-30
net/lapb/lapb_timer.c
net/lapb/lapb_timer.c
+7
-7
net/x25/af_x25.c
net/x25/af_x25.c
+125
-80
No files found.
include/net/lapb.h
View file @
457a6c8c
...
...
@@ -78,8 +78,8 @@ struct lapb_frame {
/*
* The per LAPB connection control structure.
*/
typedef
struct
lapb_cb
{
struct
l
apb_cb
*
next
;
struct
lapb_cb
{
struct
l
ist_head
node
;
void
*
token
;
/* Link status fields */
...
...
@@ -100,43 +100,45 @@ typedef struct lapb_cb {
/* FRMR control information */
struct
lapb_frame
frmr_data
;
unsigned
char
frmr_type
;
}
lapb_cb
;
atomic_t
refcnt
;
};
/* lapb_iface.c */
extern
void
lapb_connect_confirmation
(
lapb_cb
*
,
int
);
extern
void
lapb_connect_indication
(
lapb_cb
*
,
int
);
extern
void
lapb_disconnect_confirmation
(
lapb_cb
*
,
int
);
extern
void
lapb_disconnect_indication
(
lapb_cb
*
,
int
);
extern
int
lapb_data_indication
(
lapb_cb
*
,
struct
sk_buff
*
);
extern
int
lapb_data_transmit
(
lapb_cb
*
,
struct
sk_buff
*
);
extern
void
lapb_connect_confirmation
(
struct
lapb_cb
*
lapb
,
int
);
extern
void
lapb_connect_indication
(
struct
lapb_cb
*
lapb
,
int
);
extern
void
lapb_disconnect_confirmation
(
struct
lapb_cb
*
lapb
,
int
);
extern
void
lapb_disconnect_indication
(
struct
lapb_cb
*
lapb
,
int
);
extern
int
lapb_data_indication
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
);
extern
int
lapb_data_transmit
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
);
/* lapb_in.c */
extern
void
lapb_data_input
(
lapb_cb
*
,
struct
sk_buff
*
);
extern
void
lapb_data_input
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
);
/* lapb_out.c */
extern
void
lapb_kick
(
lapb_cb
*
);
extern
void
lapb_transmit_buffer
(
lapb_cb
*
,
struct
sk_buff
*
,
int
);
extern
void
lapb_establish_data_link
(
lapb_cb
*
);
extern
void
lapb_enquiry_response
(
lapb_cb
*
);
extern
void
lapb_timeout_response
(
lapb_cb
*
);
extern
void
lapb_check_iframes_acked
(
lapb_cb
*
,
unsigned
short
);
extern
void
lapb_check_need_response
(
lapb_cb
*
,
int
,
int
);
extern
void
lapb_kick
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_transmit_buffer
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
,
int
);
extern
void
lapb_establish_data_link
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_enquiry_response
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_timeout_response
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_check_iframes_acked
(
struct
lapb_cb
*
lapb
,
unsigned
short
);
extern
void
lapb_check_need_response
(
struct
lapb_cb
*
lapb
,
int
,
int
);
/* lapb_subr.c */
extern
void
lapb_clear_queues
(
lapb_cb
*
);
extern
void
lapb_frames_acked
(
lapb_cb
*
,
unsigned
short
);
extern
void
lapb_requeue_frames
(
lapb_cb
*
);
extern
int
lapb_validate_nr
(
lapb_cb
*
,
unsigned
short
);
extern
void
lapb_decode
(
lapb_cb
*
,
struct
sk_buff
*
,
struct
lapb_frame
*
);
extern
void
lapb_send_control
(
lapb_cb
*
,
int
,
int
,
int
);
extern
void
lapb_transmit_frmr
(
lapb_cb
*
);
extern
void
lapb_clear_queues
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_frames_acked
(
struct
lapb_cb
*
lapb
,
unsigned
short
);
extern
void
lapb_requeue_frames
(
struct
lapb_cb
*
lapb
);
extern
int
lapb_validate_nr
(
struct
lapb_cb
*
lapb
,
unsigned
short
);
extern
void
lapb_decode
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
,
struct
lapb_frame
*
);
extern
void
lapb_send_control
(
struct
lapb_cb
*
lapb
,
int
,
int
,
int
);
extern
void
lapb_transmit_frmr
(
struct
lapb_cb
*
lapb
);
/* lapb_timer.c */
extern
void
lapb_start_t1timer
(
lapb_cb
*
);
extern
void
lapb_start_t2timer
(
lapb_cb
*
);
extern
void
lapb_stop_t1timer
(
lapb_cb
*
);
extern
void
lapb_stop_t2timer
(
lapb_cb
*
);
extern
int
lapb_t1timer_running
(
lapb_cb
*
);
extern
void
lapb_start_t1timer
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_start_t2timer
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_stop_t1timer
(
struct
lapb_cb
*
lapb
);
extern
void
lapb_stop_t2timer
(
struct
lapb_cb
*
lapb
);
extern
int
lapb_t1timer_running
(
struct
lapb_cb
*
lapb
);
/*
* Debug levels.
...
...
net/lapb/lapb_iface.c
View file @
457a6c8c
...
...
@@ -39,87 +39,93 @@
#include <linux/init.h>
#include <net/lapb.h>
static
lapb_cb
*
volatile
lapb_list
/* = NULL initially */
;
static
struct
list_head
lapb_list
=
LIST_HEAD_INIT
(
lapb_list
);
static
rwlock_t
lapb_list_lock
=
RW_LOCK_UNLOCKED
;
/*
* Free an allocated lapb control block. This is done to centralise
* the MOD count code.
*/
static
void
lapb_free_cb
(
lapb_cb
*
lapb
)
static
void
lapb_free_cb
(
struct
lapb_cb
*
lapb
)
{
kfree
(
lapb
);
MOD_DEC_USE_COUNT
;
}
static
__inline__
void
lapb_hold
(
struct
lapb_cb
*
lapb
)
{
atomic_inc
(
&
lapb
->
refcnt
);
}
static
__inline__
void
lapb_put
(
struct
lapb_cb
*
lapb
)
{
if
(
atomic_dec_and_test
(
&
lapb
->
refcnt
))
lapb_free_cb
(
lapb
);
}
/*
* Socket removal during an interrupt is now safe.
*/
static
void
lapb_remove_cb
(
lapb_cb
*
lapb
)
static
void
__lapb_remove_cb
(
struct
lapb_cb
*
lapb
)
{
lapb_cb
*
s
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
if
((
s
=
lapb_list
)
==
lapb
)
{
lapb_list
=
s
->
next
;
restore_flags
(
flags
);
return
;
if
(
lapb
->
node
.
next
)
{
list_del
(
&
lapb
->
node
);
lapb_put
(
lapb
);
}
while
(
s
!=
NULL
&&
s
->
next
!=
NULL
)
{
if
(
s
->
next
==
lapb
)
{
s
->
next
=
lapb
->
next
;
restore_flags
(
flags
);
return
;
}
s
=
s
->
next
;
}
restore_flags
(
flags
);
}
/*
* Add a socket to the bound sockets list.
*/
static
void
lapb_insert_cb
(
lapb_cb
*
lapb
)
static
void
__lapb_insert_cb
(
struct
lapb_cb
*
lapb
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
lapb
->
next
=
lapb_list
;
lapb_list
=
lapb
;
restore_flags
(
flags
);
list_add
(
&
lapb
->
node
,
&
lapb_list
);
lapb_hold
(
lapb
);
}
/*
* Convert the integer token used by the device driver into a pointer
* to a LAPB control structure.
*/
static
lapb_cb
*
lapb_tokentostruct
(
void
*
token
)
static
struct
lapb_cb
*
__
lapb_tokentostruct
(
void
*
token
)
{
lapb_cb
*
lapb
;
struct
list_head
*
entry
;
struct
lapb_cb
*
lapb
,
*
use
=
NULL
;
list_for_each
(
entry
,
&
lapb_list
)
{
lapb
=
list_entry
(
entry
,
struct
lapb_cb
,
node
);
if
(
lapb
->
token
==
token
)
{
use
=
lapb
;
break
;
}
}
for
(
lapb
=
lapb_list
;
lapb
!=
NULL
;
lapb
=
lapb
->
next
)
if
(
lapb
->
token
==
token
)
return
lapb
;
if
(
use
)
lapb_hold
(
use
);
return
NULL
;
return
use
;
}
static
struct
lapb_cb
*
lapb_tokentostruct
(
void
*
token
)
{
struct
lapb_cb
*
rc
;
read_lock_bh
(
&
lapb_list_lock
);
rc
=
__lapb_tokentostruct
(
token
);
read_unlock_bh
(
&
lapb_list_lock
);
return
rc
;
}
/*
* Create an empty LAPB control block.
*/
static
lapb_cb
*
lapb_create_cb
(
void
)
static
struct
lapb_cb
*
lapb_create_cb
(
void
)
{
lapb_cb
*
lapb
;
struct
lapb_cb
*
lapb
=
kmalloc
(
sizeof
(
*
lapb
),
GFP_ATOMIC
);
if
(
(
lapb
=
kmalloc
(
sizeof
(
*
lapb
),
GFP_ATOMIC
))
==
NULL
)
return
NULL
;
if
(
!
lapb
)
goto
out
;
MOD_INC_USE_COUNT
;
...
...
@@ -137,55 +143,73 @@ static lapb_cb *lapb_create_cb(void)
lapb
->
mode
=
LAPB_DEFAULT_MODE
;
lapb
->
window
=
LAPB_DEFAULT_WINDOW
;
lapb
->
state
=
LAPB_STATE_0
;
atomic_set
(
&
lapb
->
refcnt
,
1
);
out:
return
lapb
;
}
int
lapb_register
(
void
*
token
,
struct
lapb_register_struct
*
callbacks
)
{
lapb_cb
*
lapb
;
struct
lapb_cb
*
lapb
;
int
rc
=
LAPB_BADTOKEN
;
write_lock_bh
(
&
lapb_list_lock
);
if
(
lapb_tokentostruct
(
token
)
!=
NULL
)
return
LAPB_BADTOKEN
;
lapb
=
__lapb_tokentostruct
(
token
);
if
(
lapb
)
{
lapb_put
(
lapb
);
goto
out
;
}
if
((
lapb
=
lapb_create_cb
())
==
NULL
)
return
LAPB_NOMEM
;
lapb
=
lapb_create_cb
();
rc
=
LAPB_NOMEM
;
if
(
!
lapb
)
goto
out
;
lapb
->
token
=
token
;
lapb
->
callbacks
=
*
callbacks
;
lapb_insert_cb
(
lapb
);
__
lapb_insert_cb
(
lapb
);
lapb_start_t1timer
(
lapb
);
return
LAPB_OK
;
rc
=
LAPB_OK
;
out:
write_unlock_bh
(
&
lapb_list_lock
);
return
rc
;
}
int
lapb_unregister
(
void
*
token
)
{
lapb_cb
*
lapb
;
struct
lapb_cb
*
lapb
;
int
rc
=
LAPB_BADTOKEN
;
if
((
lapb
=
lapb_tokentostruct
(
token
))
==
NULL
)
return
LAPB_BADTOKEN
;
write_unlock_bh
(
&
lapb_list_lock
);
lapb
=
__lapb_tokentostruct
(
token
);
if
(
!
lapb
)
goto
out
;
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb_clear_queues
(
lapb
);
lapb_remove_cb
(
lapb
);
__
lapb_remove_cb
(
lapb
);
lapb_free_cb
(
lapb
);
return
LAPB_OK
;
lapb_put
(
lapb
);
rc
=
LAPB_OK
;
out:
write_unlock_bh
(
&
lapb_list_lock
);
return
rc
;
}
int
lapb_getparms
(
void
*
token
,
struct
lapb_parms_struct
*
parms
)
{
lapb_cb
*
lapb
;
int
rc
=
LAPB_BADTOKEN
;
struct
lapb_cb
*
lapb
=
lapb_tokentostruct
(
token
);
if
(
(
lapb
=
lapb_tokentostruct
(
token
))
==
NULL
)
return
LAPB_BADTOKEN
;
if
(
!
lapb
)
goto
out
;
parms
->
t1
=
lapb
->
t1
/
HZ
;
parms
->
t2
=
lapb
->
t2
/
HZ
;
...
...
@@ -205,33 +229,29 @@ int lapb_getparms(void *token, struct lapb_parms_struct *parms)
else
parms
->
t2timer
=
(
lapb
->
t2timer
.
expires
-
jiffies
)
/
HZ
;
return
LAPB_OK
;
lapb_put
(
lapb
);
rc
=
LAPB_OK
;
out:
return
rc
;
}
int
lapb_setparms
(
void
*
token
,
struct
lapb_parms_struct
*
parms
)
{
lapb_cb
*
lapb
;
if
((
lapb
=
lapb_tokentostruct
(
token
))
==
NULL
)
return
LAPB_BADTOKEN
;
if
(
parms
->
t1
<
1
)
return
LAPB_INVALUE
;
int
rc
=
LAPB_BADTOKEN
;
struct
lapb_cb
*
lapb
=
lapb_tokentostruct
(
token
);
if
(
parms
->
t2
<
1
)
return
LAPB_INVALUE
;
if
(
!
lapb
)
goto
out
;
if
(
parms
->
n2
<
1
)
return
LAPB_INVALUE
;
rc
=
LAPB_INVALUE
;
if
(
parms
->
t1
<
1
||
parms
->
t2
<
1
||
parms
->
n2
<
1
)
goto
out_put
;
if
(
lapb
->
state
==
LAPB_STATE_0
)
{
if
(
parms
->
mode
&
LAPB_EXTENDED
)
{
if
(
parms
->
window
<
1
||
parms
->
window
>
127
)
return
LAPB_INVALUE
;
}
else
{
if
(
parms
->
window
<
1
||
parms
->
window
>
7
)
return
LAPB_INVALUE
;
}
if
(((
parms
->
mode
&
LAPB_EXTENDED
)
&&
(
parms
->
window
<
1
||
parms
->
window
>
127
))
||
(
parms
->
window
<
1
||
parms
->
window
>
7
))
goto
out_put
;
lapb
->
mode
=
parms
->
mode
;
lapb
->
window
=
parms
->
window
;
...
...
@@ -241,45 +261,55 @@ int lapb_setparms(void *token, struct lapb_parms_struct *parms)
lapb
->
t2
=
parms
->
t2
*
HZ
;
lapb
->
n2
=
parms
->
n2
;
return
LAPB_OK
;
rc
=
LAPB_OK
;
out_put:
lapb_put
(
lapb
);
out:
return
rc
;
}
int
lapb_connect_request
(
void
*
token
)
{
lapb_cb
*
lapb
;
struct
lapb_cb
*
lapb
=
lapb_tokentostruct
(
token
);
int
rc
=
LAPB_BADTOKEN
;
if
(
(
lapb
=
lapb_tokentostruct
(
token
))
==
NULL
)
return
LAPB_BADTOKEN
;
if
(
!
lapb
)
goto
out
;
switch
(
lapb
->
state
)
{
case
LAPB_STATE_1
:
return
LAPB_OK
;
case
LAPB_STATE_3
:
case
LAPB_STATE_4
:
return
LAPB_CONNECTED
;
}
rc
=
LAPB_OK
;
if
(
lapb
->
state
==
LAPB_STATE_1
)
goto
out_put
;
rc
=
LAPB_CONNECTED
;
if
(
lapb
->
state
==
LAPB_STATE_3
||
lapb
->
state
==
LAPB_STATE_4
)
goto
out_put
;
lapb_establish_data_link
(
lapb
);
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S0 -> S1
\n
"
,
lapb
->
token
);
#endif
lapb
->
state
=
LAPB_STATE_1
;
return
LAPB_OK
;
rc
=
LAPB_OK
;
out_put:
lapb_put
(
lapb
);
out:
return
rc
;
}
int
lapb_disconnect_request
(
void
*
token
)
{
lapb_cb
*
lapb
;
struct
lapb_cb
*
lapb
=
lapb_tokentostruct
(
token
);
int
rc
=
LAPB_BADTOKEN
;
if
(
(
lapb
=
lapb_tokentostruct
(
token
))
==
NULL
)
return
LAPB_BADTOKEN
;
if
(
!
lapb
)
goto
out
;
switch
(
lapb
->
state
)
{
case
LAPB_STATE_0
:
return
LAPB_NOTCONNECTED
;
rc
=
LAPB_NOTCONNECTED
;
goto
out_put
;
case
LAPB_STATE_1
:
#if LAPB_DEBUG > 1
...
...
@@ -291,10 +321,12 @@ int lapb_disconnect_request(void *token)
lapb_send_control
(
lapb
,
LAPB_DISC
,
LAPB_POLLON
,
LAPB_COMMAND
);
lapb
->
state
=
LAPB_STATE_0
;
lapb_start_t1timer
(
lapb
);
return
LAPB_NOTCONNECTED
;
rc
=
LAPB_NOTCONNECTED
;
goto
out_put
;
case
LAPB_STATE_2
:
return
LAPB_OK
;
rc
=
LAPB_OK
;
goto
out_put
;
}
lapb_clear_queues
(
lapb
);
...
...
@@ -311,77 +343,87 @@ int lapb_disconnect_request(void *token)
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S2
\n
"
,
lapb
->
token
);
#endif
return
LAPB_OK
;
rc
=
LAPB_OK
;
out_put:
lapb_put
(
lapb
);
out:
return
rc
;
}
int
lapb_data_request
(
void
*
token
,
struct
sk_buff
*
skb
)
{
lapb_cb
*
lapb
;
struct
lapb_cb
*
lapb
=
lapb_tokentostruct
(
token
);
int
rc
=
LAPB_BADTOKEN
;
if
(
(
lapb
=
lapb_tokentostruct
(
token
))
==
NULL
)
return
LAPB_BADTOKEN
;
if
(
!
lapb
)
goto
out
;
rc
=
LAPB_NOTCONNECTED
;
if
(
lapb
->
state
!=
LAPB_STATE_3
&&
lapb
->
state
!=
LAPB_STATE_4
)
return
LAPB_NOTCONNECTED
;
goto
out_put
;
skb_queue_tail
(
&
lapb
->
write_queue
,
skb
);
lapb_kick
(
lapb
);
return
LAPB_OK
;
rc
=
LAPB_OK
;
out_put:
lapb_put
(
lapb
);
out:
return
rc
;
}
int
lapb_data_received
(
void
*
token
,
struct
sk_buff
*
skb
)
{
lapb_cb
*
lapb
;
if
((
lapb
=
lapb_tokentostruct
(
token
))
==
NULL
)
return
LAPB_BADTOKEN
;
struct
lapb_cb
*
lapb
=
lapb_tokentostruct
(
token
);
int
rc
=
LAPB_BADTOKEN
;
lapb_data_input
(
lapb
,
skb
);
if
(
lapb
)
{
lapb_data_input
(
lapb
,
skb
);
lapb_put
(
lapb
);
rc
=
LAPB_OK
;
}
return
LAPB_OK
;
return
rc
;
}
void
lapb_connect_confirmation
(
lapb_cb
*
lapb
,
int
reason
)
void
lapb_connect_confirmation
(
struct
lapb_cb
*
lapb
,
int
reason
)
{
if
(
lapb
->
callbacks
.
connect_confirmation
!=
NULL
)
(
lapb
->
callbacks
.
connect_confirmation
)
(
lapb
->
token
,
reason
);
if
(
lapb
->
callbacks
.
connect_confirmation
)
lapb
->
callbacks
.
connect_confirmation
(
lapb
->
token
,
reason
);
}
void
lapb_connect_indication
(
lapb_cb
*
lapb
,
int
reason
)
void
lapb_connect_indication
(
struct
lapb_cb
*
lapb
,
int
reason
)
{
if
(
lapb
->
callbacks
.
connect_indication
!=
NULL
)
(
lapb
->
callbacks
.
connect_indication
)
(
lapb
->
token
,
reason
);
if
(
lapb
->
callbacks
.
connect_indication
)
lapb
->
callbacks
.
connect_indication
(
lapb
->
token
,
reason
);
}
void
lapb_disconnect_confirmation
(
lapb_cb
*
lapb
,
int
reason
)
void
lapb_disconnect_confirmation
(
struct
lapb_cb
*
lapb
,
int
reason
)
{
if
(
lapb
->
callbacks
.
disconnect_confirmation
!=
NULL
)
(
lapb
->
callbacks
.
disconnect_confirmation
)
(
lapb
->
token
,
reason
);
if
(
lapb
->
callbacks
.
disconnect_confirmation
)
lapb
->
callbacks
.
disconnect_confirmation
(
lapb
->
token
,
reason
);
}
void
lapb_disconnect_indication
(
lapb_cb
*
lapb
,
int
reason
)
void
lapb_disconnect_indication
(
struct
lapb_cb
*
lapb
,
int
reason
)
{
if
(
lapb
->
callbacks
.
disconnect_indication
!=
NULL
)
(
lapb
->
callbacks
.
disconnect_indication
)
(
lapb
->
token
,
reason
);
if
(
lapb
->
callbacks
.
disconnect_indication
)
lapb
->
callbacks
.
disconnect_indication
(
lapb
->
token
,
reason
);
}
int
lapb_data_indication
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
)
int
lapb_data_indication
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
)
{
if
(
lapb
->
callbacks
.
data_indication
!=
NULL
)
{
return
(
lapb
->
callbacks
.
data_indication
)
(
lapb
->
token
,
skb
);
}
if
(
lapb
->
callbacks
.
data_indication
)
return
lapb
->
callbacks
.
data_indication
(
lapb
->
token
,
skb
);
kfree_skb
(
skb
);
return
NET_RX_CN_HIGH
;
/* For now; must be != NET_RX_DROP */
}
int
lapb_data_transmit
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
)
int
lapb_data_transmit
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
)
{
int
used
=
0
;
if
(
lapb
->
callbacks
.
data_transmit
!=
NULL
)
{
(
lapb
->
callbacks
.
data_transmit
)
(
lapb
->
token
,
skb
);
if
(
lapb
->
callbacks
.
data_transmit
)
{
lapb
->
callbacks
.
data_transmit
(
lapb
->
token
,
skb
);
used
=
1
;
}
...
...
net/lapb/lapb_in.c
View file @
457a6c8c
...
...
@@ -40,26 +40,33 @@
* State machine for state 0, Disconnected State.
* The handling of the timer(s) is in file lapb_timer.c.
*/
static
void
lapb_state0_machine
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
static
void
lapb_state0_machine
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
{
switch
(
frame
->
type
)
{
case
LAPB_SABM
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S0 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S0 -> S3
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 -> S3
\n
"
,
lapb
->
token
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb
->
state
=
LAPB_STATE_3
;
...
...
@@ -74,16 +81,20 @@ static void lapb_state0_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_SABME
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S0 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S0 -> S3
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 -> S3
\n
"
,
lapb
->
token
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb
->
state
=
LAPB_STATE_3
;
...
...
@@ -95,18 +106,23 @@ static void lapb_state0_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb_connect_indication
(
lapb
,
LAPB_OK
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
break
;
case
LAPB_DISC
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S0 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S0 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
break
;
default:
...
...
@@ -120,58 +136,74 @@ static void lapb_state0_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
* State machine for state 1, Awaiting Connection State.
* The handling of the timer(s) is in file lapb_timer.c.
*/
static
void
lapb_state1_machine
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
static
void
lapb_state1_machine
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
{
switch
(
frame
->
type
)
{
case
LAPB_SABM
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
}
break
;
case
LAPB_SABME
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
break
;
case
LAPB_DISC
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
break
;
case
LAPB_UA
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
frame
->
pf
)
{
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S1 -> S3
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 -> S3
\n
"
,
lapb
->
token
);
#endif
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
...
...
@@ -187,11 +219,13 @@ static void lapb_state1_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_DM
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
frame
->
pf
)
{
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S1 -> S0
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S1 -> S0
\n
"
,
lapb
->
token
);
#endif
lapb_clear_queues
(
lapb
);
lapb
->
state
=
LAPB_STATE_0
;
...
...
@@ -200,9 +234,6 @@ static void lapb_state1_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb_disconnect_indication
(
lapb
,
LAPB_REFUSED
);
}
break
;
default:
break
;
}
kfree_skb
(
skb
);
...
...
@@ -212,33 +243,42 @@ static void lapb_state1_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
* State machine for state 2, Awaiting Release State.
* The handling of the timer(s) is in file lapb_timer.c
*/
static
void
lapb_state2_machine
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
static
void
lapb_state2_machine
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
{
switch
(
frame
->
type
)
{
case
LAPB_SABM
:
case
LAPB_SABME
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX {SABM,SABME}(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX {SABM,SABME}(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
break
;
case
LAPB_DISC
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
break
;
case
LAPB_UA
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
frame
->
pf
)
{
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S2 -> S0
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 -> S0
\n
"
,
lapb
->
token
);
#endif
lapb
->
state
=
LAPB_STATE_0
;
lapb_start_t1timer
(
lapb
);
...
...
@@ -249,16 +289,19 @@ static void lapb_state2_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_DM
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
frame
->
pf
)
{
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S2 -> S0
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 -> S0
\n
"
,
lapb
->
token
);
#endif
lapb
->
state
=
LAPB_STATE_0
;
lapb_start_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb_disconnect_confirmation
(
lapb
,
LAPB_NOTCONNECTED
);
lapb_disconnect_confirmation
(
lapb
,
LAPB_NOTCONNECTED
);
}
break
;
...
...
@@ -267,13 +310,14 @@ static void lapb_state2_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_RNR
:
case
LAPB_RR
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX {I,REJ,RNR,RR}(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX {I,REJ,RNR,RR}"
"(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S2 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
frame
->
pf
)
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
break
;
default:
if
(
frame
->
pf
)
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
break
;
}
...
...
@@ -284,28 +328,33 @@ static void lapb_state2_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
* State machine for state 3, Connected State.
* The handling of the timer(s) is in file lapb_timer.c
*/
static
void
lapb_state3_machine
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
static
void
lapb_state3_machine
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
{
int
queued
=
0
;
int
modulus
;
modulus
=
(
lapb
->
mode
&
LAPB_EXTENDED
)
?
LAPB_EMODULUS
:
LAPB_SMODULUS
;
int
modulus
=
(
lapb
->
mode
&
LAPB_EXTENDED
)
?
LAPB_EMODULUS
:
LAPB_SMODULUS
;
switch
(
frame
->
type
)
{
case
LAPB_SABM
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb
->
condition
=
0x00
;
...
...
@@ -319,13 +368,16 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_SABME
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb
->
condition
=
0x00
;
...
...
@@ -336,21 +388,26 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb_requeue_frames
(
lapb
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
break
;
case
LAPB_DISC
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX DISC(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S0
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S0
\n
"
,
lapb
->
token
);
#endif
lapb_clear_queues
(
lapb
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_start_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb
->
state
=
LAPB_STATE_0
;
...
...
@@ -359,10 +416,12 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_DM
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S0
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S0
\n
"
,
lapb
->
token
);
#endif
lapb_clear_queues
(
lapb
);
lapb
->
state
=
LAPB_STATE_0
;
...
...
@@ -373,7 +432,8 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_RNR
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX RNR(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
nr
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX RNR(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
nr
);
#endif
lapb
->
condition
|=
LAPB_PEER_RX_BUSY_CONDITION
;
lapb_check_need_response
(
lapb
,
frame
->
cr
,
frame
->
pf
);
...
...
@@ -384,7 +444,8 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb
->
frmr_type
=
LAPB_FRMR_Z
;
lapb_transmit_frmr
(
lapb
);
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
#endif
lapb_start_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
...
...
@@ -395,7 +456,8 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_RR
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX RR(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
nr
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX RR(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
nr
);
#endif
lapb
->
condition
&=
~
LAPB_PEER_RX_BUSY_CONDITION
;
lapb_check_need_response
(
lapb
,
frame
->
cr
,
frame
->
pf
);
...
...
@@ -406,7 +468,8 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb
->
frmr_type
=
LAPB_FRMR_Z
;
lapb_transmit_frmr
(
lapb
);
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
#endif
lapb_start_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
...
...
@@ -417,7 +480,8 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_REJ
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX REJ(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
nr
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX REJ(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
nr
);
#endif
lapb
->
condition
&=
~
LAPB_PEER_RX_BUSY_CONDITION
;
lapb_check_need_response
(
lapb
,
frame
->
cr
,
frame
->
pf
);
...
...
@@ -431,7 +495,8 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb
->
frmr_type
=
LAPB_FRMR_Z
;
lapb_transmit_frmr
(
lapb
);
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
#endif
lapb_start_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
...
...
@@ -442,14 +507,16 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_I
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX I(%d) S%d R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
ns
,
frame
->
nr
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX I(%d) S%d R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
frame
->
ns
,
frame
->
nr
);
#endif
if
(
!
lapb_validate_nr
(
lapb
,
frame
->
nr
))
{
lapb
->
frmr_data
=
*
frame
;
lapb
->
frmr_type
=
LAPB_FRMR_Z
;
lapb_transmit_frmr
(
lapb
);
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S4
\n
"
,
lapb
->
token
);
#endif
lapb_start_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
...
...
@@ -457,11 +524,11 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb
->
n2count
=
0
;
break
;
}
if
(
lapb
->
condition
&
LAPB_PEER_RX_BUSY_CONDITION
)
{
if
(
lapb
->
condition
&
LAPB_PEER_RX_BUSY_CONDITION
)
lapb_frames_acked
(
lapb
,
frame
->
nr
);
}
else
{
else
lapb_check_iframes_acked
(
lapb
,
frame
->
nr
);
}
if
(
frame
->
ns
==
lapb
->
vr
)
{
int
cn
;
cn
=
lapb_data_indication
(
lapb
,
skb
);
...
...
@@ -473,16 +540,18 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
* to re-transmit the frame later like
* a frame lost on the wire.
*/
if
(
cn
==
NET_RX_DROP
){
printk
(
KERN_DEBUG
"LAPB: rx congestion
\n
"
);
if
(
cn
==
NET_RX_DROP
)
{
printk
(
KERN_DEBUG
"LAPB: rx congestion
\n
"
);
break
;
}
lapb
->
vr
=
(
lapb
->
vr
+
1
)
%
modulus
;
lapb
->
condition
&=
~
LAPB_REJECT_CONDITION
;
if
(
frame
->
pf
)
{
if
(
frame
->
pf
)
lapb_enquiry_response
(
lapb
);
}
else
{
if
(
!
(
lapb
->
condition
&
LAPB_ACK_PENDING_CONDITION
))
{
else
{
if
(
!
(
lapb
->
condition
&
LAPB_ACK_PENDING_CONDITION
))
{
lapb
->
condition
|=
LAPB_ACK_PENDING_CONDITION
;
lapb_start_t2timer
(
lapb
);
}
...
...
@@ -493,10 +562,14 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb_enquiry_response
(
lapb
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX REJ(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
lapb
->
vr
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 TX REJ(%d) R%d
\n
"
,
lapb
->
token
,
frame
->
pf
,
lapb
->
vr
);
#endif
lapb
->
condition
|=
LAPB_REJECT_CONDITION
;
lapb_send_control
(
lapb
,
LAPB_REJ
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_REJ
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb
->
condition
&=
~
LAPB_ACK_PENDING_CONDITION
;
}
}
...
...
@@ -504,11 +577,15 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_FRMR
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX FRMR(%d) %02X %02X %02X %02X %02X
\n
"
,
lapb
->
token
,
frame
->
pf
,
skb
->
data
[
0
],
skb
->
data
[
1
],
skb
->
data
[
2
],
skb
->
data
[
3
],
skb
->
data
[
4
]);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX FRMR(%d) %02X "
"%02X %02X %02X %02X
\n
"
,
lapb
->
token
,
frame
->
pf
,
skb
->
data
[
0
],
skb
->
data
[
1
],
skb
->
data
[
2
],
skb
->
data
[
3
],
skb
->
data
[
4
]);
#endif
lapb_establish_data_link
(
lapb
);
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S1
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 -> S1
\n
"
,
lapb
->
token
);
#endif
lapb_requeue_frames
(
lapb
);
lapb
->
state
=
LAPB_STATE_1
;
...
...
@@ -516,7 +593,8 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_ILLEGAL
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX ILLEGAL(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S3 RX ILLEGAL(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb
->
frmr_data
=
*
frame
;
lapb
->
frmr_type
=
LAPB_FRMR_W
;
...
...
@@ -529,9 +607,6 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb
->
state
=
LAPB_STATE_4
;
lapb
->
n2count
=
0
;
break
;
default:
break
;
}
if
(
!
queued
)
...
...
@@ -542,26 +617,33 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
* State machine for state 4, Frame Reject State.
* The handling of the timer(s) is in file lapb_timer.c.
*/
static
void
lapb_state4_machine
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
static
void
lapb_state4_machine
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
{
switch
(
frame
->
type
)
{
case
LAPB_SABM
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S4 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 RX SABM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S4 -> S3
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 -> S3
\n
"
,
lapb
->
token
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb
->
state
=
LAPB_STATE_3
;
...
...
@@ -576,16 +658,20 @@ static void lapb_state4_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
case
LAPB_SABME
:
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S4 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 RX SABME(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX UA(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
#if LAPB_DEBUG > 0
printk
(
KERN_DEBUG
"lapb: (%p) S4 -> S3
\n
"
,
lapb
->
token
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 -> S3
\n
"
,
lapb
->
token
);
#endif
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_UA
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_stop_t1timer
(
lapb
);
lapb_stop_t2timer
(
lapb
);
lapb
->
state
=
LAPB_STATE_3
;
...
...
@@ -597,14 +683,13 @@ static void lapb_state4_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
lapb_connect_indication
(
lapb
,
LAPB_OK
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
printk
(
KERN_DEBUG
"lapb: (%p) S4 TX DM(%d)
\n
"
,
lapb
->
token
,
frame
->
pf
);
#endif
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
lapb_send_control
(
lapb
,
LAPB_DM
,
frame
->
pf
,
LAPB_RESPONSE
);
}
break
;
default:
break
;
}
kfree_skb
(
skb
);
...
...
@@ -613,28 +698,23 @@ static void lapb_state4_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_
/*
* Process an incoming LAPB frame
*/
void
lapb_data_input
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
)
void
lapb_data_input
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
)
{
struct
lapb_frame
frame
;
lapb_decode
(
lapb
,
skb
,
&
frame
);
switch
(
lapb
->
state
)
{
case
LAPB_STATE_0
:
lapb_state0_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_1
:
lapb_state1_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_2
:
lapb_state2_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_3
:
lapb_state3_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_4
:
lapb_state4_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_0
:
lapb_state0_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_1
:
lapb_state1_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_2
:
lapb_state2_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_3
:
lapb_state3_machine
(
lapb
,
skb
,
&
frame
);
break
;
case
LAPB_STATE_4
:
lapb_state4_machine
(
lapb
,
skb
,
&
frame
);
break
;
}
lapb_kick
(
lapb
);
...
...
net/lapb/lapb_out.c
View file @
457a6c8c
...
...
@@ -38,56 +38,54 @@
* This procedure is passed a buffer descriptor for an iframe. It builds
* the rest of the control part of the frame and then writes it out.
*/
static
void
lapb_send_iframe
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
int
poll_bit
)
static
void
lapb_send_iframe
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
int
poll_bit
)
{
unsigned
char
*
frame
;
if
(
skb
==
NULL
)
if
(
!
skb
)
return
;
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
frame
=
skb_push
(
skb
,
2
);
frame
[
0
]
=
LAPB_I
;
frame
[
0
]
|=
(
lapb
->
vs
<<
1
)
;
frame
[
1
]
=
(
poll_bit
)
?
LAPB_EPF
:
0
;
frame
[
1
]
|=
(
lapb
->
vr
<<
1
)
;
frame
[
0
]
|=
lapb
->
vs
<<
1
;
frame
[
1
]
=
poll_bit
?
LAPB_EPF
:
0
;
frame
[
1
]
|=
lapb
->
vr
<<
1
;
}
else
{
frame
=
skb_push
(
skb
,
1
);
*
frame
=
LAPB_I
;
*
frame
|=
(
poll_bit
)
?
LAPB_SPF
:
0
;
*
frame
|=
(
lapb
->
vr
<<
5
)
;
*
frame
|=
(
lapb
->
vs
<<
1
)
;
*
frame
|=
poll_bit
?
LAPB_SPF
:
0
;
*
frame
|=
lapb
->
vr
<<
5
;
*
frame
|=
lapb
->
vs
<<
1
;
}
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX I(%d) S%d R%d
\n
"
,
lapb
->
token
,
lapb
->
state
,
poll_bit
,
lapb
->
vs
,
lapb
->
vr
);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX I(%d) S%d R%d
\n
"
,
lapb
->
token
,
lapb
->
state
,
poll_bit
,
lapb
->
vs
,
lapb
->
vr
);
#endif
lapb_transmit_buffer
(
lapb
,
skb
,
LAPB_COMMAND
);
}
void
lapb_kick
(
lapb_cb
*
lapb
)
void
lapb_kick
(
struct
lapb_cb
*
lapb
)
{
struct
sk_buff
*
skb
,
*
skbn
;
unsigned
short
modulus
,
start
,
end
;
modulus
=
(
lapb
->
mode
&
LAPB_EXTENDED
)
?
LAPB_EMODULUS
:
LAPB_SMODULUS
;
start
=
(
skb_peek
(
&
lapb
->
ack_queue
)
==
NULL
)
?
lapb
->
va
:
lapb
->
vs
;
start
=
!
skb_peek
(
&
lapb
->
ack_queue
)
?
lapb
->
va
:
lapb
->
vs
;
end
=
(
lapb
->
va
+
lapb
->
window
)
%
modulus
;
if
(
!
(
lapb
->
condition
&
LAPB_PEER_RX_BUSY_CONDITION
)
&&
start
!=
end
&&
skb_peek
(
&
lapb
->
write_queue
)
!=
NULL
)
{
start
!=
end
&&
skb_peek
(
&
lapb
->
write_queue
))
{
lapb
->
vs
=
start
;
/*
* Dequeue the frame and copy it.
*/
skb
=
skb_dequeue
(
&
lapb
->
write_queue
);
skb
=
skb_dequeue
(
&
lapb
->
write_queue
);
do
{
if
((
skbn
=
skb_clone
(
skb
,
GFP_ATOMIC
))
==
NULL
)
{
...
...
@@ -95,7 +93,7 @@ void lapb_kick(lapb_cb *lapb)
break
;
}
if
(
skb
->
sk
!=
NULL
)
if
(
skb
->
sk
)
skb_set_owner_w
(
skbn
,
skb
->
sk
);
/*
...
...
@@ -119,7 +117,7 @@ void lapb_kick(lapb_cb *lapb)
}
}
void
lapb_transmit_buffer
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
int
type
)
void
lapb_transmit_buffer
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
int
type
)
{
unsigned
char
*
ptr
;
...
...
@@ -152,26 +150,30 @@ void lapb_transmit_buffer(lapb_cb *lapb, struct sk_buff *skb, int type)
}
#if LAPB_DEBUG > 2
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
0
],
skb
->
data
[
1
],
skb
->
data
[
2
]);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
0
],
skb
->
data
[
1
],
skb
->
data
[
2
]);
#endif
if
(
!
lapb_data_transmit
(
lapb
,
skb
))
kfree_skb
(
skb
);
}
void
lapb_establish_data_link
(
lapb_cb
*
lapb
)
void
lapb_establish_data_link
(
struct
lapb_cb
*
lapb
)
{
lapb
->
condition
=
0x00
;
lapb
->
n2count
=
0
;
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX SABME(1)
\n
"
,
lapb
->
token
,
lapb
->
state
);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX SABME(1)
\n
"
,
lapb
->
token
,
lapb
->
state
);
#endif
lapb_send_control
(
lapb
,
LAPB_SABME
,
LAPB_POLLON
,
LAPB_COMMAND
);
}
else
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX SABM(1)
\n
"
,
lapb
->
token
,
lapb
->
state
);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX SABM(1)
\n
"
,
lapb
->
token
,
lapb
->
state
);
#endif
lapb_send_control
(
lapb
,
LAPB_SABM
,
LAPB_POLLON
,
LAPB_COMMAND
);
}
...
...
@@ -180,10 +182,11 @@ void lapb_establish_data_link(lapb_cb *lapb)
lapb_stop_t2timer
(
lapb
);
}
void
lapb_enquiry_response
(
lapb_cb
*
lapb
)
void
lapb_enquiry_response
(
struct
lapb_cb
*
lapb
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX RR(1) R%d
\n
"
,
lapb
->
token
,
lapb
->
state
,
lapb
->
vr
);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX RR(1) R%d
\n
"
,
lapb
->
token
,
lapb
->
state
,
lapb
->
vr
);
#endif
lapb_send_control
(
lapb
,
LAPB_RR
,
LAPB_POLLON
,
LAPB_RESPONSE
);
...
...
@@ -191,32 +194,30 @@ void lapb_enquiry_response(lapb_cb *lapb)
lapb
->
condition
&=
~
LAPB_ACK_PENDING_CONDITION
;
}
void
lapb_timeout_response
(
lapb_cb
*
lapb
)
void
lapb_timeout_response
(
struct
lapb_cb
*
lapb
)
{
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX RR(0) R%d
\n
"
,
lapb
->
token
,
lapb
->
state
,
lapb
->
vr
);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX RR(0) R%d
\n
"
,
lapb
->
token
,
lapb
->
state
,
lapb
->
vr
);
#endif
lapb_send_control
(
lapb
,
LAPB_RR
,
LAPB_POLLOFF
,
LAPB_RESPONSE
);
lapb
->
condition
&=
~
LAPB_ACK_PENDING_CONDITION
;
}
void
lapb_check_iframes_acked
(
lapb_cb
*
lapb
,
unsigned
short
nr
)
void
lapb_check_iframes_acked
(
struct
lapb_cb
*
lapb
,
unsigned
short
nr
)
{
if
(
lapb
->
vs
==
nr
)
{
lapb_frames_acked
(
lapb
,
nr
);
lapb_stop_t1timer
(
lapb
);
lapb
->
n2count
=
0
;
}
else
{
if
(
lapb
->
va
!=
nr
)
{
lapb_frames_acked
(
lapb
,
nr
);
lapb_start_t1timer
(
lapb
);
}
}
else
if
(
lapb
->
va
!=
nr
)
{
lapb_frames_acked
(
lapb
,
nr
);
lapb_start_t1timer
(
lapb
);
}
}
void
lapb_check_need_response
(
lapb_cb
*
lapb
,
int
type
,
int
pf
)
void
lapb_check_need_response
(
struct
lapb_cb
*
lapb
,
int
type
,
int
pf
)
{
if
(
type
==
LAPB_COMMAND
&&
pf
)
lapb_enquiry_response
(
lapb
);
...
...
net/lapb/lapb_subr.c
View file @
457a6c8c
...
...
@@ -36,7 +36,7 @@
/*
* This routine purges all the queues of frames.
*/
void
lapb_clear_queues
(
lapb_cb
*
lapb
)
void
lapb_clear_queues
(
struct
lapb_cb
*
lapb
)
{
skb_queue_purge
(
&
lapb
->
write_queue
);
skb_queue_purge
(
&
lapb
->
ack_queue
);
...
...
@@ -47,7 +47,7 @@ void lapb_clear_queues(lapb_cb *lapb)
* acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
* SDL diagram.
*/
void
lapb_frames_acked
(
lapb_cb
*
lapb
,
unsigned
short
nr
)
void
lapb_frames_acked
(
struct
lapb_cb
*
lapb
,
unsigned
short
nr
)
{
struct
sk_buff
*
skb
;
int
modulus
;
...
...
@@ -57,16 +57,15 @@ void lapb_frames_acked(lapb_cb *lapb, unsigned short nr)
/*
* Remove all the ack-ed frames from the ack queue.
*/
if
(
lapb
->
va
!=
nr
)
{
while
(
skb_peek
(
&
lapb
->
ack_queue
)
!=
NULL
&&
lapb
->
va
!=
nr
)
{
if
(
lapb
->
va
!=
nr
)
while
(
skb_peek
(
&
lapb
->
ack_queue
)
&&
lapb
->
va
!=
nr
)
{
skb
=
skb_dequeue
(
&
lapb
->
ack_queue
);
kfree_skb
(
skb
);
lapb
->
va
=
(
lapb
->
va
+
1
)
%
modulus
;
}
}
}
void
lapb_requeue_frames
(
lapb_cb
*
lapb
)
void
lapb_requeue_frames
(
struct
lapb_cb
*
lapb
)
{
struct
sk_buff
*
skb
,
*
skb_prev
=
NULL
;
...
...
@@ -76,7 +75,7 @@ void lapb_requeue_frames(lapb_cb *lapb)
* possibility of an empty output queue.
*/
while
((
skb
=
skb_dequeue
(
&
lapb
->
ack_queue
))
!=
NULL
)
{
if
(
skb_prev
==
NULL
)
if
(
!
skb_prev
)
skb_queue_head
(
&
lapb
->
write_queue
,
skb
);
else
skb_append
(
skb_prev
,
skb
);
...
...
@@ -88,7 +87,7 @@ void lapb_requeue_frames(lapb_cb *lapb)
* Validate that the value of nr is between va and vs. Return true or
* false for testing.
*/
int
lapb_validate_nr
(
lapb_cb
*
lapb
,
unsigned
short
nr
)
int
lapb_validate_nr
(
struct
lapb_cb
*
lapb
,
unsigned
short
nr
)
{
unsigned
short
vc
=
lapb
->
va
;
int
modulus
;
...
...
@@ -96,25 +95,27 @@ int lapb_validate_nr(lapb_cb *lapb, unsigned short nr)
modulus
=
(
lapb
->
mode
&
LAPB_EXTENDED
)
?
LAPB_EMODULUS
:
LAPB_SMODULUS
;
while
(
vc
!=
lapb
->
vs
)
{
if
(
nr
==
vc
)
return
1
;
if
(
nr
==
vc
)
return
1
;
vc
=
(
vc
+
1
)
%
modulus
;
}
if
(
nr
==
lapb
->
vs
)
return
1
;
return
0
;
return
nr
==
lapb
->
vs
;
}
/*
* This routine is the centralised routine for parsing the control
* information for the different frame formats.
*/
void
lapb_decode
(
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
void
lapb_decode
(
struct
lapb_cb
*
lapb
,
struct
sk_buff
*
skb
,
struct
lapb_frame
*
frame
)
{
frame
->
type
=
LAPB_ILLEGAL
;
#if LAPB_DEBUG > 2
printk
(
KERN_DEBUG
"lapb: (%p) S%d RX %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
0
],
skb
->
data
[
1
],
skb
->
data
[
2
]);
printk
(
KERN_DEBUG
"lapb: (%p) S%d RX %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
0
],
skb
->
data
[
1
],
skb
->
data
[
2
]);
#endif
if
(
lapb
->
mode
&
LAPB_MLP
)
{
...
...
@@ -146,22 +147,31 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
skb_pull
(
skb
,
1
);
if
(
lapb
->
mode
&
LAPB_EXTENDED
)
{
if
((
skb
->
data
[
0
]
&
LAPB_S
)
==
0
)
{
frame
->
type
=
LAPB_I
;
/* I frame - carries NR/NS/PF */
if
(
!
(
skb
->
data
[
0
]
&
LAPB_S
))
{
/*
* I frame - carries NR/NS/PF
*/
frame
->
type
=
LAPB_I
;
frame
->
ns
=
(
skb
->
data
[
0
]
>>
1
)
&
0x7F
;
frame
->
nr
=
(
skb
->
data
[
1
]
>>
1
)
&
0x7F
;
frame
->
pf
=
skb
->
data
[
1
]
&
LAPB_EPF
;
frame
->
control
[
0
]
=
skb
->
data
[
0
];
frame
->
control
[
1
]
=
skb
->
data
[
1
];
skb_pull
(
skb
,
2
);
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
1
)
{
/* S frame - take out PF/NR */
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
1
)
{
/*
* S frame - take out PF/NR
*/
frame
->
type
=
skb
->
data
[
0
]
&
0x0F
;
frame
->
nr
=
(
skb
->
data
[
1
]
>>
1
)
&
0x7F
;
frame
->
pf
=
skb
->
data
[
1
]
&
LAPB_EPF
;
frame
->
control
[
0
]
=
skb
->
data
[
0
];
frame
->
control
[
1
]
=
skb
->
data
[
1
];
skb_pull
(
skb
,
2
);
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
3
)
{
/* U frame - take out PF */
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
3
)
{
/*
* U frame - take out PF
*/
frame
->
type
=
skb
->
data
[
0
]
&
~
LAPB_SPF
;
frame
->
pf
=
skb
->
data
[
0
]
&
LAPB_SPF
;
frame
->
control
[
0
]
=
skb
->
data
[
0
];
...
...
@@ -169,16 +179,25 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
skb_pull
(
skb
,
1
);
}
}
else
{
if
((
skb
->
data
[
0
]
&
LAPB_S
)
==
0
)
{
frame
->
type
=
LAPB_I
;
/* I frame - carries NR/NS/PF */
if
(
!
(
skb
->
data
[
0
]
&
LAPB_S
))
{
/*
* I frame - carries NR/NS/PF
*/
frame
->
type
=
LAPB_I
;
frame
->
ns
=
(
skb
->
data
[
0
]
>>
1
)
&
0x07
;
frame
->
nr
=
(
skb
->
data
[
0
]
>>
5
)
&
0x07
;
frame
->
pf
=
skb
->
data
[
0
]
&
LAPB_SPF
;
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
1
)
{
/* S frame - take out PF/NR */
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
1
)
{
/*
* S frame - take out PF/NR
*/
frame
->
type
=
skb
->
data
[
0
]
&
0x0F
;
frame
->
nr
=
(
skb
->
data
[
0
]
>>
5
)
&
0x07
;
frame
->
pf
=
skb
->
data
[
0
]
&
LAPB_SPF
;
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
3
)
{
/* U frame - take out PF */
}
else
if
((
skb
->
data
[
0
]
&
LAPB_U
)
==
3
)
{
/*
* U frame - take out PF
*/
frame
->
type
=
skb
->
data
[
0
]
&
~
LAPB_SPF
;
frame
->
pf
=
skb
->
data
[
0
]
&
LAPB_SPF
;
}
...
...
@@ -195,7 +214,8 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
* Only supervisory or unnumbered frames are processed, FRMRs are handled
* by lapb_transmit_frmr below.
*/
void
lapb_send_control
(
lapb_cb
*
lapb
,
int
frametype
,
int
poll_bit
,
int
type
)
void
lapb_send_control
(
struct
lapb_cb
*
lapb
,
int
frametype
,
int
poll_bit
,
int
type
)
{
struct
sk_buff
*
skb
;
unsigned
char
*
dptr
;
...
...
@@ -209,18 +229,18 @@ void lapb_send_control(lapb_cb *lapb, int frametype, int poll_bit, int type)
if
((
frametype
&
LAPB_U
)
==
LAPB_U
)
{
dptr
=
skb_put
(
skb
,
1
);
*
dptr
=
frametype
;
*
dptr
|=
(
poll_bit
)
?
LAPB_SPF
:
0
;
*
dptr
|=
poll_bit
?
LAPB_SPF
:
0
;
}
else
{
dptr
=
skb_put
(
skb
,
2
);
dptr
[
0
]
=
frametype
;
dptr
[
1
]
=
(
lapb
->
vr
<<
1
);
dptr
[
1
]
|=
(
poll_bit
)
?
LAPB_EPF
:
0
;
dptr
[
1
]
|=
poll_bit
?
LAPB_EPF
:
0
;
}
}
else
{
dptr
=
skb_put
(
skb
,
1
);
*
dptr
=
frametype
;
*
dptr
|=
(
poll_bit
)
?
LAPB_SPF
:
0
;
if
((
frametype
&
LAPB_U
)
==
LAPB_S
)
/* S frames carry NR */
*
dptr
|=
poll_bit
?
LAPB_SPF
:
0
;
if
((
frametype
&
LAPB_U
)
==
LAPB_S
)
/* S frames carry NR */
*
dptr
|=
(
lapb
->
vr
<<
5
);
}
...
...
@@ -231,7 +251,7 @@ void lapb_send_control(lapb_cb *lapb, int frametype, int poll_bit, int type)
* This routine generates FRMRs based on information previously stored in
* the LAPB control block.
*/
void
lapb_transmit_frmr
(
lapb_cb
*
lapb
)
void
lapb_transmit_frmr
(
struct
lapb_cb
*
lapb
)
{
struct
sk_buff
*
skb
;
unsigned
char
*
dptr
;
...
...
@@ -254,7 +274,10 @@ void lapb_transmit_frmr(lapb_cb *lapb)
*
dptr
++
=
lapb
->
frmr_type
;
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX FRMR %02X %02X %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
1
],
skb
->
data
[
2
],
skb
->
data
[
3
],
skb
->
data
[
4
],
skb
->
data
[
5
]);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX FRMR %02X %02X %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
1
],
skb
->
data
[
2
],
skb
->
data
[
3
],
skb
->
data
[
4
],
skb
->
data
[
5
]);
#endif
}
else
{
dptr
=
skb_put
(
skb
,
4
);
...
...
@@ -268,7 +291,9 @@ void lapb_transmit_frmr(lapb_cb *lapb)
*
dptr
++
=
lapb
->
frmr_type
;
#if LAPB_DEBUG > 1
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX FRMR %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
1
],
skb
->
data
[
2
],
skb
->
data
[
3
]);
printk
(
KERN_DEBUG
"lapb: (%p) S%d TX FRMR %02X %02X %02X
\n
"
,
lapb
->
token
,
lapb
->
state
,
skb
->
data
[
1
],
skb
->
data
[
2
],
skb
->
data
[
3
]);
#endif
}
...
...
net/lapb/lapb_timer.c
View file @
457a6c8c
...
...
@@ -37,7 +37,7 @@
static
void
lapb_t1timer_expiry
(
unsigned
long
);
static
void
lapb_t2timer_expiry
(
unsigned
long
);
void
lapb_start_t1timer
(
lapb_cb
*
lapb
)
void
lapb_start_t1timer
(
struct
lapb_cb
*
lapb
)
{
del_timer
(
&
lapb
->
t1timer
);
...
...
@@ -48,7 +48,7 @@ void lapb_start_t1timer(lapb_cb *lapb)
add_timer
(
&
lapb
->
t1timer
);
}
void
lapb_start_t2timer
(
lapb_cb
*
lapb
)
void
lapb_start_t2timer
(
struct
lapb_cb
*
lapb
)
{
del_timer
(
&
lapb
->
t2timer
);
...
...
@@ -59,24 +59,24 @@ void lapb_start_t2timer(lapb_cb *lapb)
add_timer
(
&
lapb
->
t2timer
);
}
void
lapb_stop_t1timer
(
lapb_cb
*
lapb
)
void
lapb_stop_t1timer
(
struct
lapb_cb
*
lapb
)
{
del_timer
(
&
lapb
->
t1timer
);
}
void
lapb_stop_t2timer
(
lapb_cb
*
lapb
)
void
lapb_stop_t2timer
(
struct
lapb_cb
*
lapb
)
{
del_timer
(
&
lapb
->
t2timer
);
}
int
lapb_t1timer_running
(
lapb_cb
*
lapb
)
int
lapb_t1timer_running
(
struct
lapb_cb
*
lapb
)
{
return
timer_pending
(
&
lapb
->
t1timer
);
}
static
void
lapb_t2timer_expiry
(
unsigned
long
param
)
{
lapb_cb
*
lapb
=
(
lapb_cb
*
)
param
;
struct
lapb_cb
*
lapb
=
(
struct
lapb_cb
*
)
param
;
if
(
lapb
->
condition
&
LAPB_ACK_PENDING_CONDITION
)
{
lapb
->
condition
&=
~
LAPB_ACK_PENDING_CONDITION
;
...
...
@@ -86,7 +86,7 @@ static void lapb_t2timer_expiry(unsigned long param)
static
void
lapb_t1timer_expiry
(
unsigned
long
param
)
{
lapb_cb
*
lapb
=
(
lapb_cb
*
)
param
;
struct
lapb_cb
*
lapb
=
(
struct
lapb_cb
*
)
param
;
switch
(
lapb
->
state
)
{
...
...
net/x25/af_x25.c
View file @
457a6c8c
...
...
@@ -65,7 +65,8 @@ int sysctl_x25_reset_request_timeout = X25_DEFAULT_T22;
int
sysctl_x25_clear_request_timeout
=
X25_DEFAULT_T23
;
int
sysctl_x25_ack_holdback_timeout
=
X25_DEFAULT_T2
;
static
struct
sock
*
volatile
x25_list
/* = NULL initially */
;
static
struct
sock
*
x25_list
;
static
rwlock_t
x25_list_lock
=
RW_LOCK_UNLOCKED
;
static
struct
proto_ops
x25_proto_ops
;
...
...
@@ -152,22 +153,22 @@ int x25_addr_aton(unsigned char *p, struct x25_address *called_addr,
static
void
x25_remove_socket
(
struct
sock
*
sk
)
{
struct
sock
*
s
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
write_lock_bh
(
&
x25_list_lock
);
if
((
s
=
x25_list
)
==
sk
)
x25_list
=
s
->
next
;
else
while
(
s
&&
s
->
next
)
{
if
(
s
->
next
==
sk
)
{
s
->
next
=
sk
->
next
;
sock_put
(
sk
);
break
;
}
s
=
s
->
next
;
}
restore_flags
(
flags
);
write_unlock_bh
(
&
x25_list_lock
);
}
/*
...
...
@@ -177,15 +178,20 @@ static void x25_kill_by_device(struct net_device *dev)
{
struct
sock
*
s
;
write_lock_bh
(
&
x25_list_lock
);
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
neighbour
&&
x25_sk
(
s
)
->
neighbour
->
dev
==
dev
)
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
write_unlock_bh
(
&
x25_list_lock
);
}
/*
* Handle device status changes.
*/
static
int
x25_device_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
static
int
x25_device_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
struct
net_device
*
dev
=
ptr
;
struct
x25_neigh
*
nb
;
...
...
@@ -222,15 +228,11 @@ static int x25_device_event(struct notifier_block *this, unsigned long event, vo
*/
static
void
x25_insert_socket
(
struct
sock
*
sk
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
write_lock_bh
(
&
x25_list_lock
);
sk
->
next
=
x25_list
;
x25_list
=
sk
;
restore_flags
(
flags
);
sock_hold
(
sk
);
write_unlock_bh
(
&
x25_list_lock
);
}
/*
...
...
@@ -239,11 +241,9 @@ static void x25_insert_socket(struct sock *sk)
*/
static
struct
sock
*
x25_find_listener
(
struct
x25_address
*
addr
)
{
unsigned
long
flags
;
struct
sock
*
s
;
save_flags
(
flags
);
cli
();
read_lock_bh
(
&
x25_list_lock
);
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
((
!
strcmp
(
addr
->
x25_addr
,
x25_sk
(
s
)
->
source_addr
.
x25_addr
)
||
...
...
@@ -251,26 +251,34 @@ static struct sock *x25_find_listener(struct x25_address *addr)
s
->
state
==
TCP_LISTEN
)
break
;
restore_flags
(
flags
);
if
(
s
)
sock_hold
(
s
);
read_unlock_bh
(
&
x25_list_lock
);
return
s
;
}
/*
* Find a connected X.25 socket given my LCI and neighbour.
*/
struct
sock
*
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
nb
)
struct
sock
*
__
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
nb
)
{
struct
sock
*
s
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
lci
==
lci
&&
x25_sk
(
s
)
->
neighbour
==
nb
)
break
;
if
(
s
)
sock_hold
(
s
);
return
s
;
}
struct
sock
*
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
nb
)
{
struct
sock
*
s
;
restore_flags
(
flags
);
read_lock_bh
(
&
x25_list_lock
);
s
=
__x25_find_socket
(
lci
,
nb
);
read_unlock_bh
(
&
x25_list_lock
);
return
s
;
}
...
...
@@ -280,13 +288,19 @@ struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *nb)
unsigned
int
x25_new_lci
(
struct
x25_neigh
*
nb
)
{
unsigned
int
lci
=
1
;
struct
sock
*
sk
;
read_lock_bh
(
&
x25_list_lock
);
while
(
x25_find_socket
(
lci
,
nb
))
while
((
sk
=
__x25_find_socket
(
lci
,
nb
))
!=
NULL
)
{
sock_put
(
sk
);
if
(
++
lci
==
4096
)
{
lci
=
0
;
break
;
}
}
read_unlock_bh
(
&
x25_list_lock
);
return
lci
;
}
...
...
@@ -312,11 +326,9 @@ static void x25_destroy_timer(unsigned long data)
void
x25_destroy_socket
(
struct
sock
*
sk
)
/* Not static as it's used by the timer */
{
struct
sk_buff
*
skb
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
sock_hold
(
sk
);
lock_sock
(
sk
);
x25_stop_heartbeat
(
sk
);
x25_stop_timer
(
sk
);
...
...
@@ -344,8 +356,8 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
sk_free
(
sk
);
MOD_DEC_USE_COUNT
;
}
restore_flags
(
flags
);
release_sock
(
sk
);
sock_put
(
sk
);
}
/*
...
...
@@ -590,6 +602,35 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return
0
;
}
static
int
x25_wait_for_connection_establishment
(
struct
sock
*
sk
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
int
rc
;
add_wait_queue_exclusive
(
sk
->
sleep
,
&
wait
);
for
(;;)
{
__set_current_state
(
TASK_INTERRUPTIBLE
);
rc
=
-
ERESTARTSYS
;
if
(
signal_pending
(
current
))
break
;
rc
=
sock_error
(
sk
);
if
(
rc
)
{
sk
->
socket
->
state
=
SS_UNCONNECTED
;
break
;
}
rc
=
0
;
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
release_sock
(
sk
);
schedule
();
lock_sock
(
sk
);
}
else
break
;
}
__set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
sk
->
sleep
,
&
wait
);
return
rc
;
}
static
int
x25_connect
(
struct
socket
*
sock
,
struct
sockaddr
*
uaddr
,
int
addr_len
,
int
flags
)
{
struct
sock
*
sk
=
sock
->
sk
;
...
...
@@ -598,6 +639,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
struct
x25_route
*
rt
;
int
rc
=
0
;
lock_sock
(
sk
);
if
(
sk
->
state
==
TCP_ESTABLISHED
&&
sock
->
state
==
SS_CONNECTING
)
{
sock
->
state
=
SS_CONNECTED
;
goto
out
;
/* Connect completed during a ERESTARTSYS event */
...
...
@@ -661,35 +703,48 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
if
(
sk
->
state
!=
TCP_ESTABLISHED
&&
(
flags
&
O_NONBLOCK
))
goto
out_put_neigh
;
cli
();
/* To avoid races on the sleep */
/*
* A Clear Request or timeout or failed routing will go to closed.
*/
rc
=
-
ERESTARTSYS
;
while
(
sk
->
state
==
TCP_SYN_SENT
)
{
/* FIXME: going to sleep with interrupts disabled */
interruptible_sleep_on
(
sk
->
sleep
);
if
(
signal_pending
(
current
))
goto
out_unlock
;
}
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
sock
->
state
=
SS_UNCONNECTED
;
rc
=
sock_error
(
sk
);
/* Always set at this point */
goto
out_unlock
;
}
rc
=
x25_wait_for_connection_establishment
(
sk
);
if
(
rc
)
goto
out_put_neigh
;
sock
->
state
=
SS_CONNECTED
;
rc
=
0
;
out_unlock:
sti
();
out_put_neigh:
if
(
rc
)
x25_neigh_put
(
x25
->
neighbour
);
out_put_route:
x25_route_put
(
rt
);
out:
release_sock
(
sk
);
return
rc
;
}
static
int
x25_wait_for_data
(
struct
sock
*
sk
,
int
timeout
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
int
rc
=
0
;
add_wait_queue_exclusive
(
sk
->
sleep
,
&
wait
);
for
(;;)
{
__set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
sk
->
shutdown
&
RCV_SHUTDOWN
)
break
;
rc
=
-
ERESTARTSYS
;
if
(
signal_pending
(
current
))
break
;
rc
=
-
EAGAIN
;
if
(
!
timeout
)
break
;
rc
=
0
;
if
(
skb_queue_empty
(
&
sk
->
receive_queue
))
{
release_sock
(
sk
);
timeout
=
schedule_timeout
(
timeout
);
lock_sock
(
sk
);
}
else
break
;
}
__set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
sk
->
sleep
,
&
wait
);
return
rc
;
}
...
...
@@ -707,29 +762,17 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
if
(
sk
->
type
!=
SOCK_SEQPACKET
)
goto
out
;
/*
* The write queue this time is holding sockets ready to use
* hooked into the CALL INDICATION we saved
*/
do
{
cli
();
if
((
skb
=
skb_dequeue
(
&
sk
->
receive_queue
))
==
NULL
)
{
rc
=
-
EWOULDBLOCK
;
if
(
flags
&
O_NONBLOCK
)
goto
out_unlock
;
/* FIXME: going to sleep with interrupts disabled */
interruptible_sleep_on
(
sk
->
sleep
);
rc
=
-
ERESTARTSYS
;
if
(
signal_pending
(
current
))
goto
out_unlock
;
}
}
while
(
!
skb
);
rc
=
x25_wait_for_data
(
sk
,
sk
->
rcvtimeo
);
if
(
rc
)
goto
out
;
skb
=
skb_dequeue
(
&
sk
->
receive_queue
);
rc
=
-
EINVAL
;
if
(
!
skb
->
sk
)
goto
out
;
newsk
=
skb
->
sk
;
newsk
->
pair
=
NULL
;
newsk
->
socket
=
newsock
;
newsk
->
sleep
=
&
newsock
->
wait
;
sti
();
/* Now attach up the new socket */
skb
->
sk
=
NULL
;
...
...
@@ -740,9 +783,6 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
rc
=
0
;
out:
return
rc
;
out_unlock:
sti
();
goto
out
;
}
static
int
x25_getname
(
struct
socket
*
sock
,
struct
sockaddr
*
uaddr
,
int
*
uaddr_len
,
int
peer
)
...
...
@@ -799,7 +839,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
* Try to reach a compromise on the requested facilities.
*/
if
((
len
=
x25_negotiate_facilities
(
skb
,
sk
,
&
facilities
))
==
-
1
)
goto
out_
clear_reques
t
;
goto
out_
sock_pu
t
;
/*
* current neighbour/link might impose additional limits
...
...
@@ -813,7 +853,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
*/
make
=
x25_make_new
(
sk
);
if
(
!
make
)
goto
out_
clear_reques
t
;
goto
out_
sock_pu
t
;
/*
* Remove the facilities, leaving any Call User Data.
...
...
@@ -855,8 +895,11 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
if
(
!
sk
->
dead
)
sk
->
data_ready
(
sk
,
skb
->
len
);
rc
=
1
;
sock_put
(
sk
);
out:
return
rc
;
out_sock_put:
sock_put
(
sk
);
out_clear_request:
rc
=
0
;
x25_transmit_clear_request
(
nb
,
lci
,
0x01
);
...
...
@@ -1264,14 +1307,12 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
struct
sock
*
s
;
struct
net_device
*
dev
;
const
char
*
devname
;
int
len
;
off_t
pos
=
0
;
off_t
begin
=
0
;
int
len
=
sprintf
(
buffer
,
"dest_addr src_addr dev lci st vs vr "
"va t t2 t21 t22 t23 Snd-Q Rcv-Q inode
\n
"
);
cli
();
len
=
sprintf
(
buffer
,
"dest_addr src_addr dev lci st vs vr va "
"t t2 t21 t22 t23 Snd-Q Rcv-Q inode
\n
"
);
read_lock_bh
(
&
x25_list_lock
);
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
{
struct
x25_opt
*
x25
=
x25_sk
(
s
);
...
...
@@ -1314,7 +1355,7 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
break
;
}
sti
(
);
read_unlock_bh
(
&
x25_list_lock
);
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
...
...
@@ -1368,9 +1409,13 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
{
struct
sock
*
s
;
write_lock_bh
(
&
x25_list_lock
);
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
neighbour
==
nb
)
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
write_unlock_bh
(
&
x25_list_lock
);
}
static
int
__init
x25_init
(
void
)
...
...
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