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
e58ceb07
Commit
e58ceb07
authored
Sep 16, 2003
by
Arnaldo Carvalho de Melo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
o LLC: move the connection related functions to llc_conn
parent
06f3b6fd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
237 additions
and
238 deletions
+237
-238
include/net/llc_conn.h
include/net/llc_conn.h
+10
-0
include/net/llc_mac.h
include/net/llc_mac.h
+0
-10
net/llc/llc_conn.c
net/llc/llc_conn.c
+220
-1
net/llc/llc_main.c
net/llc/llc_main.c
+7
-227
No files found.
include/net/llc_conn.h
View file @
e58ceb07
...
...
@@ -69,6 +69,16 @@ struct llc_opt {
#define llc_sk(__sk) ((struct llc_opt *)(__sk)->sk_protinfo)
static
__inline__
void
llc_set_backlog_type
(
struct
sk_buff
*
skb
,
char
type
)
{
skb
->
cb
[
sizeof
(
skb
->
cb
)
-
1
]
=
type
;
}
static
__inline__
char
llc_backlog_type
(
struct
sk_buff
*
skb
)
{
return
skb
->
cb
[
sizeof
(
skb
->
cb
)
-
1
];
}
extern
struct
sock
*
llc_sk_alloc
(
int
family
,
int
priority
);
extern
void
llc_sk_free
(
struct
sock
*
sk
);
...
...
include/net/llc_mac.h
View file @
e58ceb07
...
...
@@ -19,14 +19,4 @@
extern
int
llc_rcv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
);
extern
u16
lan_hdrs_init
(
struct
sk_buff
*
skb
,
u8
*
sa
,
u8
*
da
);
static
__inline__
void
llc_set_backlog_type
(
struct
sk_buff
*
skb
,
char
type
)
{
skb
->
cb
[
sizeof
(
skb
->
cb
)
-
1
]
=
type
;
}
static
__inline__
char
llc_backlog_type
(
struct
sk_buff
*
skb
)
{
return
skb
->
cb
[
sizeof
(
skb
->
cb
)
-
1
];
}
#endif
/* LLC_MAC_H */
net/llc/llc_conn.c
View file @
e58ceb07
...
...
@@ -665,7 +665,7 @@ static int llc_find_offset(int state, int ev_type)
*
* Sends received pdus to the connection state machine.
*/
int
llc_conn_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
static
int
llc_conn_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
...
...
@@ -729,3 +729,222 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
drop:
kfree_skb
(
skb
);
}
#undef LLC_REFCNT_DEBUG
#ifdef LLC_REFCNT_DEBUG
static
atomic_t
llc_sock_nr
;
#endif
/**
* llc_release_conns - releases all connections of a sap
* @sap: sap to release its connections
*
* Releases all connections of a sap. Returns 0 if all actions complete
* successfully, nonzero otherwise
*/
int
llc_release_connections
(
struct
llc_sap
*
sap
)
{
int
rc
=
0
;
struct
sock
*
sk
;
struct
hlist_node
*
node
;
write_lock_bh
(
&
sap
->
sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
sap
->
sk_list
.
list
)
{
llc_sk
(
sk
)
->
state
=
LLC_CONN_STATE_TEMP
;
if
(
llc_send_disc
(
sk
))
rc
=
1
;
}
write_unlock_bh
(
&
sap
->
sk_list
.
lock
);
return
rc
;
}
/**
* llc_backlog_rcv - Processes rx frames and expired timers.
* @sk: LLC sock (p8022 connection)
* @skb: queued rx frame or event
*
* This function processes frames that has received and timers that has
* expired during sending an I pdu (refer to data_req_handler). frames
* queue by llc_rcv function (llc_mac.c) and timers queue by timer
* callback functions(llc_c_ac.c).
*/
static
int
llc_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
int
rc
=
0
;
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
if
(
llc_backlog_type
(
skb
)
==
LLC_PACKET
)
{
if
(
llc
->
state
>
1
)
/* not closed */
rc
=
llc_conn_rcv
(
sk
,
skb
);
else
goto
out_kfree_skb
;
}
else
if
(
llc_backlog_type
(
skb
)
==
LLC_EVENT
)
{
/* timer expiration event */
if
(
llc
->
state
>
1
)
/* not closed */
rc
=
llc_conn_state_process
(
sk
,
skb
);
else
goto
out_kfree_skb
;
}
else
{
printk
(
KERN_ERR
"%s: invalid skb in backlog
\n
"
,
__FUNCTION__
);
goto
out_kfree_skb
;
}
out:
return
rc
;
out_kfree_skb:
kfree_skb
(
skb
);
goto
out
;
}
/**
* llc_sk_init - Initializes a socket with default llc values.
* @sk: socket to initialize.
*
* Initializes a socket with default llc values.
*/
int
llc_sk_init
(
struct
sock
*
sk
)
{
struct
llc_opt
*
llc
=
kmalloc
(
sizeof
(
*
llc
),
GFP_ATOMIC
);
int
rc
=
-
ENOMEM
;
if
(
!
llc
)
goto
out
;
memset
(
llc
,
0
,
sizeof
(
*
llc
));
rc
=
0
;
llc
->
sk
=
sk
;
llc
->
state
=
LLC_CONN_STATE_ADM
;
llc
->
inc_cntr
=
llc
->
dec_cntr
=
2
;
llc
->
dec_step
=
llc
->
connect_step
=
1
;
init_timer
(
&
llc
->
ack_timer
.
timer
);
llc
->
ack_timer
.
expire
=
LLC_ACK_TIME
;
llc
->
ack_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
ack_timer
.
timer
.
function
=
llc_conn_ack_tmr_cb
;
init_timer
(
&
llc
->
pf_cycle_timer
.
timer
);
llc
->
pf_cycle_timer
.
expire
=
LLC_P_TIME
;
llc
->
pf_cycle_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
pf_cycle_timer
.
timer
.
function
=
llc_conn_pf_cycle_tmr_cb
;
init_timer
(
&
llc
->
rej_sent_timer
.
timer
);
llc
->
rej_sent_timer
.
expire
=
LLC_REJ_TIME
;
llc
->
rej_sent_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
rej_sent_timer
.
timer
.
function
=
llc_conn_rej_tmr_cb
;
init_timer
(
&
llc
->
busy_state_timer
.
timer
);
llc
->
busy_state_timer
.
expire
=
LLC_BUSY_TIME
;
llc
->
busy_state_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
busy_state_timer
.
timer
.
function
=
llc_conn_busy_tmr_cb
;
llc
->
n2
=
2
;
/* max retransmit */
llc
->
k
=
2
;
/* tx win size, will adjust dynam */
llc
->
rw
=
128
;
/* rx win size (opt and equal to
* tx_win of remote LLC) */
skb_queue_head_init
(
&
llc
->
pdu_unack_q
);
sk
->
sk_backlog_rcv
=
llc_backlog_rcv
;
llc_sk
(
sk
)
=
llc
;
out:
return
rc
;
}
/**
* llc_sk_alloc - Allocates LLC sock
* @family: upper layer protocol family
* @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
*
* Allocates a LLC sock and initializes it. Returns the new LLC sock
* or %NULL if there's no memory available for one
*/
struct
sock
*
llc_sk_alloc
(
int
family
,
int
priority
)
{
struct
sock
*
sk
=
sk_alloc
(
family
,
priority
,
1
,
NULL
);
if
(
!
sk
)
goto
out
;
if
(
llc_sk_init
(
sk
))
goto
outsk
;
sock_init_data
(
NULL
,
sk
);
sk_set_owner
(
sk
,
THIS_MODULE
);
#ifdef LLC_REFCNT_DEBUG
atomic_inc
(
&
llc_sock_nr
);
printk
(
KERN_DEBUG
"LLC socket %p created in %s, now we have %d alive
\n
"
,
sk
,
__FUNCTION__
,
atomic_read
(
&
llc_sock_nr
));
#endif
out:
return
sk
;
outsk:
sk_free
(
sk
);
sk
=
NULL
;
goto
out
;
}
/**
* llc_sk_free - Frees a LLC socket
* @sk - socket to free
*
* Frees a LLC socket
*/
void
llc_sk_free
(
struct
sock
*
sk
)
{
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
llc
->
state
=
LLC_CONN_OUT_OF_SVC
;
/* Stop all (possibly) running timers */
llc_conn_ac_stop_all_timers
(
sk
,
NULL
);
#ifdef DEBUG_LLC_CONN_ALLOC
printk
(
KERN_INFO
"%s: unackq=%d, txq=%d
\n
"
,
__FUNCTION__
,
skb_queue_len
(
&
llc
->
pdu_unack_q
),
skb_queue_len
(
&
sk
->
sk_write_queue
));
#endif
skb_queue_purge
(
&
sk
->
sk_receive_queue
);
skb_queue_purge
(
&
sk
->
sk_write_queue
);
skb_queue_purge
(
&
llc
->
pdu_unack_q
);
#ifdef LLC_REFCNT_DEBUG
if
(
atomic_read
(
&
sk
->
sk_refcnt
)
!=
1
)
{
printk
(
KERN_DEBUG
"Destruction of LLC sock %p delayed in %s, cnt=%d
\n
"
,
sk
,
__FUNCTION__
,
atomic_read
(
&
sk
->
sk_refcnt
));
printk
(
KERN_DEBUG
"%d LLC sockets are still alive
\n
"
,
atomic_read
(
&
llc_sock_nr
));
}
else
{
atomic_dec
(
&
llc_sock_nr
);
printk
(
KERN_DEBUG
"LLC socket %p released in %s, %d are still alive
\n
"
,
sk
,
__FUNCTION__
,
atomic_read
(
&
llc_sock_nr
));
}
#endif
sock_put
(
sk
);
}
/**
* llc_sk_reset - resets a connection
* @sk: LLC socket to reset
*
* Resets a connection to the out of service state. Stops its timers
* and frees any frames in the queues of the connection.
*/
void
llc_sk_reset
(
struct
sock
*
sk
)
{
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
llc_conn_ac_stop_all_timers
(
sk
,
NULL
);
skb_queue_purge
(
&
sk
->
sk_write_queue
);
skb_queue_purge
(
&
llc
->
pdu_unack_q
);
llc
->
remote_busy_flag
=
0
;
llc
->
cause_flag
=
0
;
llc
->
retry_count
=
0
;
llc_conn_set_p_flag
(
sk
,
0
);
llc
->
f_flag
=
0
;
llc
->
s_flag
=
0
;
llc
->
ack_pf
=
0
;
llc
->
first_pdu_Ns
=
0
;
llc
->
ack_must_be_send
=
0
;
llc
->
dec_step
=
1
;
llc
->
inc_cntr
=
2
;
llc
->
dec_cntr
=
2
;
llc
->
X
=
0
;
llc
->
failed_data_req
=
0
;
llc
->
last_nr
=
0
;
}
net/llc/llc_main.c
View file @
e58ceb07
...
...
@@ -43,15 +43,8 @@ static u16 llc_exec_station_trans_actions(struct llc_station *station,
static
struct
llc_station_state_trans
*
llc_find_station_trans
(
struct
llc_station
*
station
,
struct
sk_buff
*
skb
);
static
int
llc_rtn_all_conns
(
struct
llc_sap
*
sap
);
struct
llc_station
llc_main_station
;
/* only one of its kind */
#undef LLC_REFCNT_DEBUG
#ifdef LLC_REFCNT_DEBUG
static
atomic_t
llc_sock_nr
;
#endif
/**
* llc_sap_alloc - allocates and initializes sap.
*
...
...
@@ -70,6 +63,12 @@ struct llc_sap *llc_sap_alloc(void)
return
sap
;
}
/*
* FIXME: this will go away as soon as sap->release_connections is introduced
* in the next changesets.
*/
extern
int
llc_release_connections
(
struct
llc_sap
*
sap
);
/**
* llc_free_sap - frees a sap
* @sap: Address of the sap
...
...
@@ -79,7 +78,7 @@ struct llc_sap *llc_sap_alloc(void)
*/
void
llc_free_sap
(
struct
llc_sap
*
sap
)
{
llc_r
tn_all_con
ns
(
sap
);
llc_r
elease_connectio
ns
(
sap
);
write_lock_bh
(
&
sap
->
station
->
sap_list
.
lock
);
list_del
(
&
sap
->
node
);
write_unlock_bh
(
&
sap
->
station
->
sap_list
.
lock
);
...
...
@@ -123,225 +122,6 @@ struct llc_sap *llc_sap_find(u8 sap_value)
return
sap
;
}
/*
* FIXME: this will not be needed in next changesets, when this
* will move to llc_conn
*/
extern
int
llc_conn_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
/**
* llc_backlog_rcv - Processes rx frames and expired timers.
* @sk: LLC sock (p8022 connection)
* @skb: queued rx frame or event
*
* This function processes frames that has received and timers that has
* expired during sending an I pdu (refer to data_req_handler). frames
* queue by llc_rcv function (llc_mac.c) and timers queue by timer
* callback functions(llc_c_ac.c).
*/
static
int
llc_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
int
rc
=
0
;
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
if
(
llc_backlog_type
(
skb
)
==
LLC_PACKET
)
{
if
(
llc
->
state
>
1
)
/* not closed */
rc
=
llc_conn_rcv
(
sk
,
skb
);
else
goto
out_kfree_skb
;
}
else
if
(
llc_backlog_type
(
skb
)
==
LLC_EVENT
)
{
/* timer expiration event */
if
(
llc
->
state
>
1
)
/* not closed */
rc
=
llc_conn_state_process
(
sk
,
skb
);
else
goto
out_kfree_skb
;
}
else
{
printk
(
KERN_ERR
"%s: invalid skb in backlog
\n
"
,
__FUNCTION__
);
goto
out_kfree_skb
;
}
out:
return
rc
;
out_kfree_skb:
kfree_skb
(
skb
);
goto
out
;
}
/**
* llc_sk_init - Initializes a socket with default llc values.
* @sk: socket to initialize.
*
* Initializes a socket with default llc values.
*/
int
llc_sk_init
(
struct
sock
*
sk
)
{
struct
llc_opt
*
llc
=
kmalloc
(
sizeof
(
*
llc
),
GFP_ATOMIC
);
int
rc
=
-
ENOMEM
;
if
(
!
llc
)
goto
out
;
memset
(
llc
,
0
,
sizeof
(
*
llc
));
rc
=
0
;
llc
->
sk
=
sk
;
llc
->
state
=
LLC_CONN_STATE_ADM
;
llc
->
inc_cntr
=
llc
->
dec_cntr
=
2
;
llc
->
dec_step
=
llc
->
connect_step
=
1
;
init_timer
(
&
llc
->
ack_timer
.
timer
);
llc
->
ack_timer
.
expire
=
LLC_ACK_TIME
;
llc
->
ack_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
ack_timer
.
timer
.
function
=
llc_conn_ack_tmr_cb
;
init_timer
(
&
llc
->
pf_cycle_timer
.
timer
);
llc
->
pf_cycle_timer
.
expire
=
LLC_P_TIME
;
llc
->
pf_cycle_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
pf_cycle_timer
.
timer
.
function
=
llc_conn_pf_cycle_tmr_cb
;
init_timer
(
&
llc
->
rej_sent_timer
.
timer
);
llc
->
rej_sent_timer
.
expire
=
LLC_REJ_TIME
;
llc
->
rej_sent_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
rej_sent_timer
.
timer
.
function
=
llc_conn_rej_tmr_cb
;
init_timer
(
&
llc
->
busy_state_timer
.
timer
);
llc
->
busy_state_timer
.
expire
=
LLC_BUSY_TIME
;
llc
->
busy_state_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
busy_state_timer
.
timer
.
function
=
llc_conn_busy_tmr_cb
;
llc
->
n2
=
2
;
/* max retransmit */
llc
->
k
=
2
;
/* tx win size, will adjust dynam */
llc
->
rw
=
128
;
/* rx win size (opt and equal to
* tx_win of remote LLC) */
skb_queue_head_init
(
&
llc
->
pdu_unack_q
);
sk
->
sk_backlog_rcv
=
llc_backlog_rcv
;
llc_sk
(
sk
)
=
llc
;
out:
return
rc
;
}
/**
* llc_sk_alloc - Allocates LLC sock
* @family: upper layer protocol family
* @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
*
* Allocates a LLC sock and initializes it. Returns the new LLC sock
* or %NULL if there's no memory available for one
*/
struct
sock
*
llc_sk_alloc
(
int
family
,
int
priority
)
{
struct
sock
*
sk
=
sk_alloc
(
family
,
priority
,
1
,
NULL
);
if
(
!
sk
)
goto
out
;
if
(
llc_sk_init
(
sk
))
goto
outsk
;
sock_init_data
(
NULL
,
sk
);
sk_set_owner
(
sk
,
THIS_MODULE
);
#ifdef LLC_REFCNT_DEBUG
atomic_inc
(
&
llc_sock_nr
);
printk
(
KERN_DEBUG
"LLC socket %p created in %s, now we have %d alive
\n
"
,
sk
,
__FUNCTION__
,
atomic_read
(
&
llc_sock_nr
));
#endif
out:
return
sk
;
outsk:
sk_free
(
sk
);
sk
=
NULL
;
goto
out
;
}
/**
* llc_sk_free - Frees a LLC socket
* @sk - socket to free
*
* Frees a LLC socket
*/
void
llc_sk_free
(
struct
sock
*
sk
)
{
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
llc
->
state
=
LLC_CONN_OUT_OF_SVC
;
/* Stop all (possibly) running timers */
llc_conn_ac_stop_all_timers
(
sk
,
NULL
);
#ifdef DEBUG_LLC_CONN_ALLOC
printk
(
KERN_INFO
"%s: unackq=%d, txq=%d
\n
"
,
__FUNCTION__
,
skb_queue_len
(
&
llc
->
pdu_unack_q
),
skb_queue_len
(
&
sk
->
sk_write_queue
));
#endif
skb_queue_purge
(
&
sk
->
sk_receive_queue
);
skb_queue_purge
(
&
sk
->
sk_write_queue
);
skb_queue_purge
(
&
llc
->
pdu_unack_q
);
#ifdef LLC_REFCNT_DEBUG
if
(
atomic_read
(
&
sk
->
sk_refcnt
)
!=
1
)
{
printk
(
KERN_DEBUG
"Destruction of LLC sock %p delayed in %s, cnt=%d
\n
"
,
sk
,
__FUNCTION__
,
atomic_read
(
&
sk
->
sk_refcnt
));
printk
(
KERN_DEBUG
"%d LLC sockets are still alive
\n
"
,
atomic_read
(
&
llc_sock_nr
));
}
else
{
atomic_dec
(
&
llc_sock_nr
);
printk
(
KERN_DEBUG
"LLC socket %p released in %s, %d are still alive
\n
"
,
sk
,
__FUNCTION__
,
atomic_read
(
&
llc_sock_nr
));
}
#endif
sock_put
(
sk
);
}
/**
* llc_sk_reset - resets a connection
* @sk: LLC socket to reset
*
* Resets a connection to the out of service state. Stops its timers
* and frees any frames in the queues of the connection.
*/
void
llc_sk_reset
(
struct
sock
*
sk
)
{
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
llc_conn_ac_stop_all_timers
(
sk
,
NULL
);
skb_queue_purge
(
&
sk
->
sk_write_queue
);
skb_queue_purge
(
&
llc
->
pdu_unack_q
);
llc
->
remote_busy_flag
=
0
;
llc
->
cause_flag
=
0
;
llc
->
retry_count
=
0
;
llc_conn_set_p_flag
(
sk
,
0
);
llc
->
f_flag
=
0
;
llc
->
s_flag
=
0
;
llc
->
ack_pf
=
0
;
llc
->
first_pdu_Ns
=
0
;
llc
->
ack_must_be_send
=
0
;
llc
->
dec_step
=
1
;
llc
->
inc_cntr
=
2
;
llc
->
dec_cntr
=
2
;
llc
->
X
=
0
;
llc
->
failed_data_req
=
0
;
llc
->
last_nr
=
0
;
}
/**
* llc_rtn_all_conns - Closes all connections of a sap
* @sap: sap to close its connections
*
* Closes all connections of a sap. Returns 0 if all actions complete
* successfully, nonzero otherwise
*/
static
int
llc_rtn_all_conns
(
struct
llc_sap
*
sap
)
{
int
rc
=
0
;
struct
sock
*
sk
;
struct
hlist_node
*
node
;
write_lock_bh
(
&
sap
->
sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
sap
->
sk_list
.
list
)
{
llc_sk
(
sk
)
->
state
=
LLC_CONN_STATE_TEMP
;
if
(
llc_send_disc
(
sk
))
rc
=
1
;
}
write_unlock_bh
(
&
sap
->
sk_list
.
lock
);
return
rc
;
}
/**
* llc_station_state_process: queue event and try to process queue.
* @station: Address of the station
...
...
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