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
44bb970a
Commit
44bb970a
authored
Sep 26, 2002
by
Arnaldo Carvalho de Melo
Browse files
Options
Browse Files
Download
Plain Diff
Merge hera.kernel.org:/home/acme/BK/llc-2.5.old
into hera.kernel.org:/home/acme/BK/llc-2.5
parents
02debc0e
87c9fe7c
Changes
25
Show whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
418 additions
and
974 deletions
+418
-974
include/net/llc_c_ev.h
include/net/llc_c_ev.h
+7
-31
include/net/llc_conn.h
include/net/llc_conn.h
+3
-8
include/net/llc_evnt.h
include/net/llc_evnt.h
+5
-19
include/net/llc_frame.h
include/net/llc_frame.h
+0
-98
include/net/llc_if.h
include/net/llc_if.h
+18
-62
include/net/llc_main.h
include/net/llc_main.h
+1
-2
include/net/llc_name.h
include/net/llc_name.h
+0
-7
include/net/llc_s_ev.h
include/net/llc_s_ev.h
+7
-30
include/net/llc_sap.h
include/net/llc_sap.h
+14
-17
include/net/llc_state.h
include/net/llc_state.h
+0
-4
include/net/p8022.h
include/net/p8022.h
+5
-4
net/802/p8022.c
net/802/p8022.c
+4
-2
net/802/psnap.c
net/802/psnap.c
+7
-13
net/ipx/af_ipx.c
net/ipx/af_ipx.c
+1
-17
net/llc/llc_c_ac.c
net/llc/llc_c_ac.c
+10
-39
net/llc/llc_c_ev.c
net/llc/llc_c_ev.c
+15
-15
net/llc/llc_conn.c
net/llc/llc_conn.c
+142
-117
net/llc/llc_evnt.c
net/llc/llc_evnt.c
+4
-4
net/llc/llc_if.c
net/llc/llc_if.c
+45
-76
net/llc/llc_mac.c
net/llc/llc_mac.c
+17
-3
net/llc/llc_main.c
net/llc/llc_main.c
+29
-37
net/llc/llc_s_ac.c
net/llc/llc_s_ac.c
+9
-15
net/llc/llc_s_ev.c
net/llc/llc_s_ev.c
+8
-8
net/llc/llc_sap.c
net/llc/llc_sap.c
+49
-45
net/llc/llc_sock.c
net/llc/llc_sock.c
+18
-301
No files found.
include/net/llc_c_ev.h
View file @
44bb970a
...
...
@@ -110,38 +110,14 @@
#define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11
#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12
/* Event data interface; what is sent in an event package */
/* Event LLC_CONN_EV_TYPE_SIMPLE interface */
struct
llc_conn_ev_simple_if
{
u8
ev
;
};
/* Event LLC_CONN_EV_TYPE_PRIM interface */
struct
llc_conn_ev_prim_if
{
u8
prim
;
/* connect, disconnect, reset, ... */
u8
type
;
/* request, indicate, response, conf */
struct
llc_prim_if_block
*
data
;
};
/* Event LLC_CONN_EV_TYPE_PDU interface */
struct
llc_conn_ev_pdu_if
{
u8
ev
;
};
union
llc_conn_ev_if
{
struct
llc_conn_ev_simple_if
a
;
/* 'a' for simple, easy ... */
struct
llc_conn_ev_prim_if
prim
;
struct
llc_conn_ev_pdu_if
pdu
;
};
struct
llc_conn_state_ev
{
u8
type
;
u8
prim
;
u8
prim_type
;
u8
reason
;
u8
status
;
u8
flag
;
struct
llc_prim_if_block
*
ind_prim
;
struct
llc_prim_if_block
*
cfm_prim
;
union
llc_conn_ev_if
data
;
u8
ind_prim
;
u8
cfm_prim
;
};
static
__inline__
struct
llc_conn_state_ev
*
llc_conn_ev
(
struct
sk_buff
*
skb
)
...
...
include/net/llc_conn.h
View file @
44bb970a
...
...
@@ -66,18 +66,10 @@ struct llc_opt {
u32
rx_pdu_hdr
;
/* used for saving header of last pdu
received and caused sending FRMR.
Used for resending FRMR */
#ifdef DEBUG_LLC_CONN_ALLOC
char
*
f_alloc
,
/* function that allocated this connection */
*
f_free
;
/* function that freed this connection */
int
l_alloc
,
/* line that allocated this connection */
l_free
;
/* line that freed this connection */
#endif
};
#define llc_sk(__sk) ((struct llc_opt *)(__sk)->protinfo)
struct
llc_conn_state_ev
;
extern
struct
sock
*
llc_sk_alloc
(
int
family
,
int
priority
);
extern
void
llc_sk_free
(
struct
sock
*
sk
);
...
...
@@ -100,6 +92,9 @@ extern struct sock *llc_lookup_established(struct llc_sap *sap,
struct
llc_addr
*
laddr
);
extern
struct
sock
*
llc_lookup_listener
(
struct
llc_sap
*
sap
,
struct
llc_addr
*
laddr
);
extern
struct
sock
*
llc_lookup_dgram
(
struct
llc_sap
*
sap
,
struct
llc_addr
*
laddr
);
extern
void
llc_save_primitive
(
struct
sk_buff
*
skb
,
u8
prim
);
extern
u8
llc_data_accept_state
(
u8
state
);
extern
void
llc_build_offset_table
(
void
);
#endif
/* LLC_CONN_H */
include/net/llc_evnt.h
View file @
44bb970a
...
...
@@ -31,25 +31,11 @@
#define LLC_STATION_EV_RX_NULL_DSAP_TEST_C 8
#define LLC_STATION_EV_DISABLE_REQ 9
/* Interfaces for various types of supported events */
struct
llc_stat_ev_simple_if
{
u8
ev
;
};
struct
llc_stat_ev_prim_if
{
u8
prim
;
/* connect, disconnect, reset, ... */
u8
type
;
/* request, indicate, response, confirm */
};
union
llc_stat_ev_if
{
struct
llc_stat_ev_simple_if
a
;
/* 'a' for simple, easy ... */
struct
llc_stat_ev_prim_if
prim
;
};
struct
llc_station_state_ev
{
u8
type
;
u8
prim
;
u8
prim_type
;
u8
reason
;
union
llc_stat_ev_if
data
;
struct
list_head
node
;
/* node in station->ev_q.list */
};
...
...
include/net/llc_frame.h
deleted
100644 → 0
View file @
02debc0e
/* if_ether.h needed for definition of ETH_DATA_LEN and ETH_ALEN
*/
#include "linux/if_ether.h"
/* frame layout based on par3.2 "LLC PDU format"
*/
typedef
union
{
/* pdu layout from pages 40 & 44 */
struct
{
/* general header, all pdu types */
unsigned
dsap
:
8
;
/* dest service access point */
unsigned
ssap
:
8
;
/* source service access point */
unsigned
f1
:
1
;
/* I- U- or S- format id bits */
unsigned
f2
:
1
;
unsigned
:
6
;
unsigned
:
8
;
}
pdu_hdr
;
struct
{
char
dummy1
[
2
];
/* dsap + ssap */
char
byte1
;
char
byte2
;
}
pdu_cntl
;
/* unformatted control bytes */
struct
{
/* header of an Information pdu */
unsigned
char
dummy2
[
2
];
unsigned
:
1
;
unsigned
ns
:
7
;
unsigned
i_pflag
:
1
;
/* poll/final bit */
unsigned
nr
:
7
;
/* N(R) */
unsigned
char
is_info
[
ETH_DATA_LEN
];
}
i_hdr
;
struct
{
/* header of a Supervisory pdu */
unsigned
char
dummy3
[
2
];
unsigned
:
2
;
unsigned
ss
:
2
;
/* supervisory function bits */
unsigned
:
4
;
unsigned
s_pflag
:
1
;
/* poll/final bit */
unsigned
nr
:
7
;
/* N(R) */
}
s_hdr
;
/* when accessing the P/F bit or the N(R) field there's no need to distinguish
I pdus from S pdus i_pflag and s_pflag / i_nr and s_nr map to the same
physical location.
*/
struct
{
/* header of an Unnumbered pdu */
unsigned
char
dummy4
[
2
];
unsigned
:
2
;
unsigned
mm1
:
2
;
/* modifier function part1 */
unsigned
u_pflag
:
1
;
/* P/F for U- pdus */
unsigned
mm2
:
3
;
/* modifier function part2 */
unsigned
char
u_info
[
ETH_DATA_LEN
-
1
];
}
u_hdr
;
struct
{
/* mm field in an Unnumbered pdu */
unsigned
char
dummy5
[
2
];
unsigned
:
2
;
unsigned
mm
:
6
;
/* must be masked to get ridd of P/F ! */
}
u_mm
;
}
frame_type
,
*
frameptr
;
/* frame format test macros: */
#define IS_UFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & ( (fr)->pdu_hdr.f2) )
#define IS_IFRAME( fr ) ( !( (fr)->pdu_hdr.f1) )
#define IS_SFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & !( (fr)->pdu_hdr.f2) )
#define IS_RSP( fr ) ( fr->pdu_hdr.ssap & 0x01 )
/* The transition table, the _encode tables and some tests in the
source code depend on the numeric order of these values.
Think twice before changing.
*/
/* frame names for TYPE 2 operation: */
#define I_CMD 0
#define RR_CMD 1
#define RNR_CMD 2
#define REJ_CMD 3
#define DISC_CMD 4
#define SABME_CMD 5
#define I_RSP 6
#define RR_RSP 7
#define RNR_RSP 8
#define REJ_RSP 9
#define UA_RSP 10
#define DM_RSP 11
#define FRMR_RSP 12
/* junk frame name: */
#define BAD_FRAME 13
#define NO_FRAME 13
/* frame names for TYPE 1 operation: */
#define UI_CMD 14
#define XID_CMD 15
#define TEST_CMD 16
#define XID_RSP 17
#define TEST_RSP 18
include/net/llc_if.h
View file @
44bb970a
...
...
@@ -17,17 +17,17 @@
#include <linux/if_arp.h>
#include <linux/llc.h>
#define LLC_DATAUNIT_PRIM
0
#define LLC_CONN_PRIM
1
#define LLC_DATA_PRIM
2
#define LLC_DISC_PRIM
3
#define LLC_RESET_PRIM
4
#define LLC_FLOWCONTROL_PRIM
5
/* Not supported at this time */
#define LLC_DISABLE_PRIM
6
#define LLC_XID_PRIM
7
#define LLC_TEST_PRIM
8
#define LLC_SAP_ACTIVATION
9
#define LLC_SAP_DEACTIVATION 1
0
#define LLC_DATAUNIT_PRIM
1
#define LLC_CONN_PRIM
2
#define LLC_DATA_PRIM
3
#define LLC_DISC_PRIM
4
#define LLC_RESET_PRIM
5
#define LLC_FLOWCONTROL_PRIM
6
/* Not supported at this time */
#define LLC_DISABLE_PRIM
7
#define LLC_XID_PRIM
8
#define LLC_TEST_PRIM
9
#define LLC_SAP_ACTIVATION
10
#define LLC_SAP_DEACTIVATION 1
1
#define LLC_NBR_PRIMITIVES 11
...
...
@@ -67,66 +67,22 @@ struct llc_addr {
u8
mac
[
IFHWADDRLEN
];
};
struct
llc_prim_reset
{
struct
sock
*
sk
;
u16
link
;
};
/* Sending data in conection-less mode */
struct
llc_prim_unit_data
{
struct
llc_addr
saddr
;
struct
llc_addr
daddr
;
u8
pri
;
struct
sk_buff
*
skb
;
/* pointer to frame */
u8
lfb
;
/* largest frame bit (TR) */
};
struct
llc_prim_xid
{
struct
llc_addr
saddr
;
struct
llc_addr
daddr
;
u8
pri
;
struct
sk_buff
*
skb
;
};
struct
llc_prim_test
{
struct
llc_addr
saddr
;
struct
llc_addr
daddr
;
u8
pri
;
struct
sk_buff
*
skb
;
/* pointer to frame */
};
union
llc_u_prim_data
{
struct
llc_prim_reset
res
;
struct
llc_prim_unit_data
udata
;
/* unit data */
struct
llc_prim_xid
xid
;
struct
llc_prim_test
test
;
};
struct
llc_sap
;
/* Information block passed with all called primitives */
struct
llc_prim_if_block
{
struct
llc_sap
*
sap
;
u8
prim
;
union
llc_u_prim_data
*
data
;
};
typedef
int
(
*
llc_prim_call_t
)(
struct
llc_prim_if_block
*
prim_if
);
extern
struct
llc_sap
*
llc_sap_open
(
llc_prim_call_t
network_indicate
,
llc_prim_call_t
network_confirm
,
u8
lsap
);
extern
struct
llc_sap
*
llc_sap_open
(
u8
lsap
,
int
(
*
func
)(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
));
extern
void
llc_sap_close
(
struct
llc_sap
*
sap
);
extern
int
llc_establish_connection
(
struct
sock
*
sk
,
u8
*
lmac
,
u8
*
dmac
,
u8
dsap
);
extern
int
llc_build_and_send_pkt
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
extern
void
llc_build_and_send_ui_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
extern
void
llc_build_and_send_ui_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
u8
*
dmac
,
u8
dsap
);
extern
void
llc_build_and_send_xid_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
extern
void
llc_build_and_send_xid_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
u8
*
dmac
,
u8
dsap
);
extern
void
llc_build_and_send_test_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
extern
void
llc_build_and_send_test_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
u8
*
dmac
,
u8
dsap
);
extern
int
llc_send_disc
(
struct
sock
*
sk
);
#endif
/* LLC_IF_H */
include/net/llc_main.h
View file @
44bb970a
...
...
@@ -43,7 +43,7 @@ struct llc_station {
u8
maximum_retry
;
u8
mac_sa
[
6
];
struct
{
spin
lock_t
lock
;
rw
lock_t
lock
;
struct
list_head
list
;
}
sap_list
;
struct
{
...
...
@@ -52,7 +52,6 @@ struct llc_station {
}
ev_q
;
struct
sk_buff_head
mac_pdu_q
;
};
struct
llc_station_state_ev
;
extern
struct
llc_sap
*
llc_sap_alloc
(
void
);
extern
void
llc_sap_save
(
struct
llc_sap
*
sap
);
...
...
include/net/llc_name.h
deleted
100644 → 0
View file @
02debc0e
char
*
frame_names
[]
=
{
"I_CMD"
,
"RR_CMD"
,
"RNR_CMD"
,
"REJ_CMD"
,
"DISC_CMD"
,
"SABME_CMD"
,
"I_RSP"
,
"RR_RSP"
,
"RNR_RSP"
,
"REJ_RSP"
,
"UA_RSP"
,
"DM_RSP"
,
"FRMR_RSP"
,
"BAD_FRAME"
,
"UI_CMD"
,
"XID_CMD"
,
"TEST_CMD"
,
"XID_RSP"
,
"TEST_RSP"
};
include/net/llc_s_ev.h
View file @
44bb970a
...
...
@@ -34,37 +34,14 @@
#define LLC_SAP_EV_RX_TEST_R 9
#define LLC_SAP_EV_DEACTIVATION_REQ 10
/* Interfaces for various types of supported events */
struct
llc_sap_ev_simple_if
{
u8
ev
;
};
struct
llc_prim_if_block
;
struct
llc_sap_ev_prim_if
{
u8
prim
;
/* connect, disconnect, reset, ... */
u8
type
;
/* request, indicate, response, conf */
struct
llc_prim_if_block
*
data
;
};
struct
llc_sap_ev_pdu_if
{
u8
ev
;
};
union
llc_sap_ev_if
{
struct
llc_sap_ev_simple_if
a
;
/* 'a' for simple, easy ... */
struct
llc_sap_ev_prim_if
prim
;
struct
llc_sap_ev_pdu_if
pdu
;
};
struct
llc_prim_if_block
;
struct
llc_sap_state_ev
{
u8
prim
;
u8
prim_type
;
u8
type
;
u8
reason
;
u8
ind_cfm_flag
;
struct
llc_
prim_if_block
*
prim
;
union
llc_sap_ev_if
data
;
struct
llc_
addr
saddr
;
struct
llc_addr
daddr
;
};
static
__inline__
struct
llc_sap_state_ev
*
llc_sap_ev
(
struct
sk_buff
*
skb
)
...
...
include/net/llc_sap.h
View file @
44bb970a
...
...
@@ -12,36 +12,33 @@
* See the GNU General Public License for more details.
*/
#include <linux/skbuff.h>
#include <net/llc_if.h>
/**
* struct llc_sap - Defines the SAP component
*
* @station - station this sap belongs to
* @state - sap state
* @p_bit - only lowest-order bit used
* @f_bit - only lowest-order bit used
* @ind - provided by network layer
* @conf - provided by network layer
* @laddr - SAP value in this 'lsap'
* @node - entry in station sap_list
* @sk_list - LLC sockets this one manages
* @mac_pdu_q - PDUs ready to send to MAC
*/
struct
llc_sap
{
struct
llc_station
*
parent_
station
;
struct
llc_station
*
station
;
u8
state
;
u8
p_bit
;
u8
f_bit
;
llc_prim_call_t
ind
;
llc_prim_call_t
conf
;
struct
llc_prim_if_block
llc_ind_prim
,
llc_cfm_prim
;
union
llc_u_prim_data
llc_ind_data_prim
,
llc_cfm_data_prim
;
int
(
*
rcv_func
)(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
);
struct
llc_addr
laddr
;
struct
list_head
node
;
struct
{
spinlock_t
lock
;
struct
list_head
list
;
rwlock_t
lock
;
struct
sock
*
list
;
}
sk_list
;
struct
sk_buff_head
mac_pdu_q
;
};
struct
llc_sap_state_ev
;
extern
void
llc_sap_assign_sock
(
struct
llc_sap
*
sap
,
struct
sock
*
sk
);
extern
void
llc_sap_unassign_sock
(
struct
llc_sap
*
sap
,
struct
sock
*
sk
);
...
...
include/net/llc_state.h
deleted
100644 → 0
View file @
02debc0e
char
*
state_names
[]
=
{
"ADM"
,
"CONN"
,
"RESET_WAIT"
,
"RESET_CHECK"
,
"SETUP"
,
"RESET"
,
"D_CONN"
,
"ERROR"
,
"NORMAL"
};
include/net/p8022.h
View file @
44bb970a
#ifndef _NET_P8022_H
#define _NET_P8022_H
#include <net/llc_if.h>
extern
struct
datalink_proto
*
register_8022_client
(
unsigned
char
type
,
int
(
*
indicate
)(
struct
llc_prim_if_block
*
prim
));
extern
struct
datalink_proto
*
register_8022_client
(
unsigned
char
type
,
int
(
*
func
)(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
));
extern
void
unregister_8022_client
(
struct
datalink_proto
*
proto
);
#endif
net/802/p8022.c
View file @
44bb970a
...
...
@@ -33,7 +33,9 @@ static int p8022_request(struct datalink_proto *dl, struct sk_buff *skb,
}
struct
datalink_proto
*
register_8022_client
(
unsigned
char
type
,
int
(
*
indicate
)(
struct
llc_prim_if_block
*
prim
))
int
(
*
func
)(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
))
{
struct
datalink_proto
*
proto
;
...
...
@@ -42,7 +44,7 @@ struct datalink_proto *register_8022_client(unsigned char type,
proto
->
type
[
0
]
=
type
;
proto
->
header_length
=
3
;
proto
->
request
=
p8022_request
;
proto
->
sap
=
llc_sap_open
(
indicate
,
NULL
,
type
);
proto
->
sap
=
llc_sap_open
(
type
,
func
);
if
(
!
proto
->
sap
)
{
kfree
(
proto
);
proto
=
NULL
;
...
...
net/802/psnap.c
View file @
44bb970a
...
...
@@ -51,32 +51,26 @@ static struct datalink_proto *find_snap_client(unsigned char *desc)
/*
* A SNAP packet has arrived
*/
static
int
snap_indicate
(
struct
llc_prim_if_block
*
prim
)
static
int
snap_rcv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
)
{
struct
sk_buff
*
skb
;
struct
datalink_proto
*
proto
;
int
rc
=
1
;
static
struct
packet_type
psnap_packet_type
=
{
struct
datalink_proto
*
proto
=
find_snap_client
(
skb
->
h
.
raw
);
static
struct
packet_type
snap_packet_type
=
{
.
type
=
__constant_htons
(
ETH_P_SNAP
),
};
if
(
prim
->
prim
!=
LLC_DATAUNIT_PRIM
)
goto
out
;
skb
=
prim
->
data
->
udata
.
skb
;
proto
=
find_snap_client
(
skb
->
h
.
raw
);
if
(
proto
)
{
/* Pass the frame on. */
skb
->
h
.
raw
+=
5
;
skb_pull
(
skb
,
5
);
rc
=
proto
->
rcvfunc
(
skb
,
skb
->
dev
,
&
p
snap_packet_type
);
rc
=
proto
->
rcvfunc
(
skb
,
dev
,
&
snap_packet_type
);
}
else
{
skb
->
sk
=
NULL
;
kfree_skb
(
skb
);
rc
=
1
;
}
out:
return
rc
;
}
...
...
@@ -99,7 +93,7 @@ EXPORT_SYMBOL(unregister_snap_client);
static
int
__init
snap_init
(
void
)
{
snap_sap
=
llc_sap_open
(
snap_indicate
,
NULL
,
0xAA
);
snap_sap
=
llc_sap_open
(
0xAA
,
snap_rcv
);
if
(
!
snap_sap
)
printk
(
KERN_CRIT
"SNAP - unable to register with 802.2
\n
"
);
...
...
net/ipx/af_ipx.c
View file @
44bb970a
...
...
@@ -2252,22 +2252,6 @@ drop: kfree_skb(skb);
out:
return
ret
;
}
static
int
ipx_8022_indicate
(
struct
llc_prim_if_block
*
prim
)
{
int
rc
=
1
;
static
struct
packet_type
p8022_packet_type
=
{
.
type
=
__constant_htons
(
ETH_P_802_2
),
};
if
(
prim
->
prim
==
LLC_DATAUNIT_PRIM
)
{
struct
sk_buff
*
skb
=
prim
->
data
->
udata
.
skb
;
rc
=
ipx_rcv
(
skb
,
skb
->
dev
,
&
p8022_packet_type
);
}
return
rc
;
}
static
int
ipx_sendmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
len
,
struct
scm_cookie
*
scm
)
{
...
...
@@ -2560,7 +2544,7 @@ static int __init ipx_init(void)
else
printk
(
ipx_8023_err_msg
);
p8022_datalink
=
register_8022_client
(
ipx_8022_type
,
ipx_
8022_indicate
);
p8022_datalink
=
register_8022_client
(
ipx_8022_type
,
ipx_
rcv
);
if
(
!
p8022_datalink
)
printk
(
ipx_llc_err_msg
);
...
...
net/llc/llc_c_ac.c
View file @
44bb970a
...
...
@@ -65,9 +65,7 @@ int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
llc_pdu_decode_sa
(
skb
,
llc
->
daddr
.
mac
);
llc_pdu_decode_da
(
skb
,
llc
->
laddr
.
mac
);
llc
->
dev
=
skb
->
dev
;
/* FIXME: find better way to notify upper layer */
ev
->
flag
=
LLC_CONN_PRIM
+
1
;
ev
->
ind_prim
=
(
void
*
)
1
;
ev
->
ind_prim
=
LLC_CONN_PRIM
;
rc
=
0
;
}
return
rc
;
...
...
@@ -77,8 +75,7 @@ int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
ev
->
flag
=
LLC_CONN_PRIM
+
1
;
ev
->
cfm_prim
=
(
void
*
)
1
;
ev
->
cfm_prim
=
LLC_CONN_PRIM
;
return
0
;
}
...
...
@@ -86,12 +83,7 @@ static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
/*
* FIXME: find better way to tell upper layer that the packet was
* confirmed by the other endpoint
*/
ev
->
flag
=
LLC_DATA_PRIM
+
1
;
ev
->
cfm_prim
=
(
void
*
)
1
;
ev
->
cfm_prim
=
LLC_DATA_PRIM
;
return
0
;
}
...
...
@@ -130,8 +122,7 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
}
if
(
!
rc
)
{
ev
->
reason
=
reason
;
ev
->
flag
=
LLC_DISC_PRIM
+
1
;
ev
->
ind_prim
=
(
void
*
)
1
;
ev
->
ind_prim
=
LLC_DISC_PRIM
;
}
return
rc
;
}
...
...
@@ -141,8 +132,7 @@ int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb)
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
ev
->
reason
=
ev
->
status
;
ev
->
flag
=
LLC_DISC_PRIM
+
1
;
ev
->
cfm_prim
=
(
void
*
)
1
;
ev
->
cfm_prim
=
LLC_DISC_PRIM
;
return
0
;
}
...
...
@@ -184,18 +174,8 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
break
;
}
if
(
!
rc
)
{
struct
llc_sap
*
sap
=
llc
->
sap
;
struct
llc_prim_if_block
*
prim
=
&
sap
->
llc_ind_prim
;
union
llc_u_prim_data
*
prim_data
=
prim
->
data
;
prim_data
->
res
.
sk
=
sk
;
prim_data
->
res
.
link
=
llc
->
link
;
prim
->
data
=
prim_data
;
prim
->
prim
=
LLC_RESET_PRIM
;
prim
->
sap
=
sap
;
ev
->
reason
=
reason
;
ev
->
flag
=
1
;
ev
->
ind_prim
=
prim
;
ev
->
ind_prim
=
LLC_RESET_PRIM
;
}
return
rc
;
}
...
...
@@ -203,18 +183,9 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
int
llc_conn_ac_rst_confirm
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
struct
llc_sap
*
sap
=
llc
->
sap
;
struct
llc_prim_if_block
*
prim
=
&
sap
->
llc_cfm_prim
;
union
llc_u_prim_data
*
prim_data
=
prim
->
data
;
prim_data
->
res
.
sk
=
sk
;
prim_data
->
res
.
link
=
llc
->
link
;
prim
->
data
=
prim_data
;
prim
->
prim
=
LLC_RESET_PRIM
;
prim
->
sap
=
sap
;
ev
->
flag
=
1
;
ev
->
cfm_prim
=
prim
;
ev
->
reason
=
0
;
ev
->
cfm_prim
=
LLC_RESET_PRIM
;
return
0
;
}
...
...
net/llc/llc_c_ev.c
View file @
44bb970a
...
...
@@ -101,48 +101,48 @@ int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
data
.
prim
.
prim
==
LLC_CONN_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
return
ev
->
prim
==
LLC_CONN_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
int
llc_conn_ev_conn_resp
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
data
.
prim
.
prim
==
LLC_CONN_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_RESP
?
0
:
1
;
return
ev
->
prim
==
LLC_CONN_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_RESP
?
0
:
1
;
}
int
llc_conn_ev_data_req
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
data
.
prim
.
prim
==
LLC_DATA_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
return
ev
->
prim
==
LLC_DATA_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
int
llc_conn_ev_disc_req
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
data
.
prim
.
prim
==
LLC_DISC_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
return
ev
->
prim
==
LLC_DISC_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
int
llc_conn_ev_rst_req
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
data
.
prim
.
prim
==
LLC_RESET_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
return
ev
->
prim
==
LLC_RESET_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
int
llc_conn_ev_rst_resp
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
data
.
prim
.
prim
==
LLC_RESET_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_RESP
?
0
:
1
;
return
ev
->
prim
==
LLC_RESET_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_RESP
?
0
:
1
;
}
int
llc_conn_ev_local_busy_detected
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
...
...
@@ -150,7 +150,7 @@ int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
type
==
LLC_CONN_EV_TYPE_SIMPLE
&&
ev
->
data
.
a
.
ev
==
LLC_CONN_EV_LOCAL_BUSY_DETECTED
?
0
:
1
;
ev
->
prim_type
==
LLC_CONN_EV_LOCAL_BUSY_DETECTED
?
0
:
1
;
}
int
llc_conn_ev_local_busy_cleared
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
...
...
@@ -158,7 +158,7 @@ int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
type
==
LLC_CONN_EV_TYPE_SIMPLE
&&
ev
->
data
.
a
.
ev
==
LLC_CONN_EV_LOCAL_BUSY_CLEARED
?
0
:
1
;
ev
->
prim_type
==
LLC_CONN_EV_LOCAL_BUSY_CLEARED
?
0
:
1
;
}
int
llc_conn_ev_rx_bad_pdu
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
...
...
@@ -666,7 +666,7 @@ int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
return
ev
->
type
==
LLC_CONN_EV_TYPE_SIMPLE
&&
ev
->
data
.
a
.
ev
==
LLC_CONN_EV_TX_BUFF_FULL
?
0
:
1
;
ev
->
prim_type
==
LLC_CONN_EV_TX_BUFF_FULL
?
0
:
1
;
}
/* Event qualifier functions
...
...
net/llc/llc_conn.c
View file @
44bb970a
...
...
@@ -39,12 +39,12 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
/* Offset table on connection states transition diagram */
static
int
llc_offset_table
[
NBR_CONN_STATES
][
NBR_CONN_EV
];
void
llc_save_primitive
(
struct
s
ock
*
sk
,
struct
s
k_buff
*
skb
,
u8
prim
)
void
llc_save_primitive
(
struct
sk_buff
*
skb
,
u8
prim
)
{
struct
sockaddr_llc
*
addr
=
llc_ui_skb_cb
(
skb
);
/* save primitive for use by the user. */
addr
->
sllc_family
=
sk
->
family
;
addr
->
sllc_family
=
sk
b
->
sk
->
family
;
addr
->
sllc_arphrd
=
skb
->
dev
->
type
;
addr
->
sllc_test
=
prim
==
LLC_TEST_PRIM
;
addr
->
sllc_xid
=
prim
==
LLC_XID_PRIM
;
...
...
@@ -67,48 +67,39 @@ void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
*/
int
llc_conn_state_process
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
/* sending event to state machine */
int
rc
=
llc_conn_service
(
sk
,
skb
);
int
rc
;
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
u8
flag
=
ev
->
flag
;
u8
status
=
ev
->
status
;
struct
llc_prim_if_block
*
ind_prim
=
ev
->
ind_prim
;
struct
llc_prim_if_block
*
cfm_prim
=
ev
->
cfm_prim
;
/*
* FIXME: this will vanish as soon I get rid of the last prim crap
*/
if
(
flag
!=
LLC_DATA_PRIM
+
1
&&
flag
!=
LLC_CONN_PRIM
+
1
&&
flag
!=
LLC_DISC_PRIM
+
1
)
llc_conn_free_ev
(
skb
);
else
if
(
ind_prim
&&
cfm_prim
)
skb_get
(
skb
);
if
(
!
flag
)
/* indicate or confirm not required */
ev
->
ind_prim
=
ev
->
cfm_prim
=
0
;
rc
=
llc_conn_service
(
sk
,
skb
);
/* sending event to state machine */
if
(
rc
)
{
printk
(
KERN_ERR
"%s: llc_conn_service failed
\n
"
,
__FUNCTION__
);
goto
out_kfree_skb
;
}
if
(
!
ev
->
ind_prim
&&
!
ev
->
cfm_prim
)
{
/* indicate or confirm not required */
if
(
!
skb
->
list
)
goto
out_kfree_skb
;
goto
out
;
rc
=
0
;
if
(
ind_prim
)
{
/* indication required */
/*
* FIXME: this will be saner as soon I get rid of the double
* sock crap
*/
switch
(
flag
)
{
case
LLC_DATA_PRIM
+
1
:
llc_save_primitive
(
sk
,
skb
,
LLC_DATA_PRIM
);
}
if
(
ev
->
ind_prim
&&
ev
->
cfm_prim
)
skb_get
(
skb
);
switch
(
ev
->
ind_prim
)
{
case
LLC_DATA_PRIM
:
llc_save_primitive
(
skb
,
LLC_DATA_PRIM
);
if
(
sock_queue_rcv_skb
(
sk
,
skb
))
{
/*
* FIXME: have to sync the LLC state
* machine wrt mem usage with
* sk->{r,w}mem_alloc, will do
* this soon 8)
* shouldn't happen
*/
printk
(
KERN_ERR
"%s: sock_queue_rcv_skb failed!
\n
"
,
printk
(
KERN_ERR
"%s: sock_queue_rcv_skb failed!
\n
"
,
__FUNCTION__
);
kfree_skb
(
skb
);
}
break
;
case
LLC_CONN_PRIM
+
1
:
{
case
LLC_CONN_PRIM
:
{
struct
sock
*
parent
=
skb
->
sk
;
skb
->
sk
=
sk
;
...
...
@@ -116,7 +107,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
sk
->
state_change
(
parent
);
}
break
;
case
LLC_DISC_PRIM
+
1
:
case
LLC_DISC_PRIM
:
sock_hold
(
sk
);
if
(
sk
->
type
==
SOCK_STREAM
&&
sk
->
state
==
TCP_ESTABLISHED
)
{
sk
->
shutdown
=
SHUTDOWN_MASK
;
...
...
@@ -130,25 +121,34 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
kfree_skb
(
skb
);
sock_put
(
sk
);
break
;
case
LLC_RESET_PRIM
:
/*
* FIXME:
* RESET is not being notified to upper layers for now
*/
printk
(
KERN_INFO
"%s: received a reset ind!
\n
"
,
__FUNCTION__
);
kfree_skb
(
skb
);
break
;
default:
llc
->
sap
->
ind
(
ind_prim
);
if
(
ev
->
ind_prim
)
{
printk
(
KERN_INFO
"%s: received unknown %d prim!
\n
"
,
__FUNCTION__
,
ev
->
ind_prim
);
kfree_skb
(
skb
);
}
/* No indication */
break
;
}
if
(
!
cfm_prim
)
/* confirmation not required */
goto
out
;
/* FIXME: see FIXMEs above */
switch
(
flag
)
{
case
LLC_DATA_PRIM
+
1
:
switch
(
ev
->
cfm_prim
)
{
case
LLC_DATA_PRIM
:
if
(
!
llc_data_accept_state
(
llc
->
state
))
/* In this state, we can send I pdu */
sk
->
write_space
(
sk
);
else
rc
=
llc
->
failed_data_req
=
1
;
break
;
case
LLC_CONN_PRIM
+
1
:
if
(
sk
->
type
!=
SOCK_STREAM
||
sk
->
state
!=
TCP_SYN_SENT
)
goto
out_kfree_skb
;
if
(
status
)
{
case
LLC_CONN_PRIM
:
if
(
sk
->
type
==
SOCK_STREAM
&&
sk
->
state
==
TCP_SYN_SENT
)
{
if
(
ev
->
status
)
{
sk
->
socket
->
state
=
SS_UNCONNECTED
;
sk
->
state
=
TCP_CLOSE
;
}
else
{
...
...
@@ -156,21 +156,31 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
sk
->
state
=
TCP_ESTABLISHED
;
}
sk
->
state_change
(
sk
);
}
break
;
case
LLC_DISC_PRIM
+
1
:
case
LLC_DISC_PRIM
:
sock_hold
(
sk
);
if
(
sk
->
type
!=
SOCK_STREAM
||
sk
->
state
!=
TCP_CLOSING
)
{
sock_put
(
sk
);
goto
out_kfree_skb
;
}
if
(
sk
->
type
==
SOCK_STREAM
&&
sk
->
state
==
TCP_CLOSING
)
{
sk
->
socket
->
state
=
SS_UNCONNECTED
;
sk
->
state
=
TCP_CLOSE
;
sk
->
state_change
(
sk
);
}
sock_put
(
sk
);
break
;
case
LLC_RESET_PRIM
:
/*
* FIXME:
* RESET is not being notified to upper layers for now
*/
printk
(
KERN_INFO
"%s: received a reset conf!
\n
"
,
__FUNCTION__
);
break
;
default:
llc
->
sap
->
conf
(
cfm_prim
);
goto
out
;
if
(
ev
->
cfm_prim
)
{
printk
(
KERN_INFO
"%s: received unknown %d prim!
\n
"
,
__FUNCTION__
,
ev
->
cfm_prim
);
break
;
}
goto
out
;
/* No confirmation */
}
out_kfree_skb:
kfree_skb
(
skb
);
...
...
@@ -198,9 +208,7 @@ void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
{
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
/* FIXME: indicate that we should send this to the upper layer */
ev
->
flag
=
LLC_DATA_PRIM
+
1
;
ev
->
ind_prim
=
(
void
*
)
1
;
ev
->
ind_prim
=
LLC_DATA_PRIM
;
}
/**
...
...
@@ -355,12 +363,14 @@ void llc_conn_free_ev(struct sk_buff *skb)
/* free the frame that is bound to this event */
struct
llc_pdu_sn
*
pdu
=
llc_pdu_sn_hdr
(
skb
);
if
(
LLC_PDU_TYPE_IS_I
(
pdu
)
||
!
ev
->
flag
||
!
ev
->
ind_prim
)
if
(
LLC_PDU_TYPE_IS_I
(
pdu
)
||
!
ev
->
ind_prim
)
kfree_skb
(
skb
);
}
else
if
(
ev
->
type
==
LLC_CONN_EV_TYPE_PRIM
&&
ev
->
data
.
prim
.
prim
!=
LLC_DATA_PRIM
)
ev
->
prim
!=
LLC_DATA_PRIM
)
kfree_skb
(
skb
);
else
if
(
ev
->
type
==
LLC_CONN_EV_TYPE_P_TMR
)
else
if
(
ev
->
type
==
LLC_CONN_EV_TYPE_P_TMR
||
ev
->
type
==
LLC_CONN_EV_TYPE_BUSY_TMR
||
ev
->
type
==
LLC_CONN_EV_TYPE_REJ_TMR
)
kfree_skb
(
skb
);
}
...
...
@@ -483,27 +493,21 @@ static int llc_exec_conn_trans_actions(struct sock *sk,
struct
sock
*
llc_lookup_established
(
struct
llc_sap
*
sap
,
struct
llc_addr
*
daddr
,
struct
llc_addr
*
laddr
)
{
struct
sock
*
rc
=
NULL
;
struct
list_head
*
entry
;
struct
sock
*
rc
;
spin_lock_bh
(
&
sap
->
sk_list
.
lock
);
if
(
list_empty
(
&
sap
->
sk_list
.
list
))
goto
out
;
list_for_each
(
entry
,
&
sap
->
sk_list
.
list
)
{
struct
llc_opt
*
llc
=
list_entry
(
entry
,
struct
llc_opt
,
node
);
read_lock_bh
(
&
sap
->
sk_list
.
lock
);
for
(
rc
=
sap
->
sk_list
.
list
;
rc
;
rc
=
rc
->
next
)
{
struct
llc_opt
*
llc
=
llc_sk
(
rc
);
if
(
llc
->
laddr
.
lsap
==
laddr
->
lsap
&&
llc
->
daddr
.
lsap
==
daddr
->
lsap
&&
llc_mac_match
(
llc
->
laddr
.
mac
,
laddr
->
mac
)
&&
llc_mac_match
(
llc
->
daddr
.
mac
,
daddr
->
mac
))
{
rc
=
llc
->
sk
;
llc_mac_match
(
llc
->
daddr
.
mac
,
daddr
->
mac
))
break
;
}
}
if
(
rc
)
sock_hold
(
rc
);
out:
spin_unlock_bh
(
&
sap
->
sk_list
.
lock
);
read_unlock_bh
(
&
sap
->
sk_list
.
lock
);
return
rc
;
}
...
...
@@ -518,28 +522,49 @@ struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
*/
struct
sock
*
llc_lookup_listener
(
struct
llc_sap
*
sap
,
struct
llc_addr
*
laddr
)
{
struct
sock
*
rc
=
NULL
;
struct
list_head
*
entry
;
struct
sock
*
rc
;
spin_lock_bh
(
&
sap
->
sk_list
.
lock
);
if
(
list_empty
(
&
sap
->
sk_list
.
list
))
goto
out
;
list_for_each
(
entry
,
&
sap
->
sk_list
.
list
)
{
struct
llc_opt
*
llc
=
list_entry
(
entry
,
struct
llc_opt
,
node
);
if
(
llc
->
sk
->
type
!=
SOCK_STREAM
||
llc
->
sk
->
state
!=
TCP_LISTEN
||
llc
->
laddr
.
lsap
!=
laddr
->
lsap
||
!
llc_mac_match
(
llc
->
laddr
.
mac
,
laddr
->
mac
))
continue
;
rc
=
llc
->
sk
;
read_lock_bh
(
&
sap
->
sk_list
.
lock
);
for
(
rc
=
sap
->
sk_list
.
list
;
rc
;
rc
=
rc
->
next
)
{
struct
llc_opt
*
llc
=
llc_sk
(
rc
);
if
(
rc
->
type
==
SOCK_STREAM
&&
rc
->
state
==
TCP_LISTEN
&&
llc
->
laddr
.
lsap
==
laddr
->
lsap
&&
llc_mac_match
(
llc
->
laddr
.
mac
,
laddr
->
mac
))
break
;
}
if
(
rc
)
sock_hold
(
rc
);
out:
spin_unlock_bh
(
&
sap
->
sk_list
.
lock
);
read_unlock_bh
(
&
sap
->
sk_list
.
lock
);
return
rc
;
}
/**
* llc_lookup_dgram - Finds dgram socket for the local sap/mac
* @sap: SAP
* @laddr: address of local LLC (MAC + SAP)
*
* Search socket list of the SAP and finds connection using the local
* mac, and local sap. Returns pointer for socket found, %NULL otherwise.
*/
struct
sock
*
llc_lookup_dgram
(
struct
llc_sap
*
sap
,
struct
llc_addr
*
laddr
)
{
struct
sock
*
rc
;
read_lock_bh
(
&
sap
->
sk_list
.
lock
);
for
(
rc
=
sap
->
sk_list
.
list
;
rc
;
rc
=
rc
->
next
)
{
struct
llc_opt
*
llc
=
llc_sk
(
rc
);
if
(
rc
->
type
==
SOCK_DGRAM
&&
llc
->
laddr
.
lsap
==
laddr
->
lsap
&&
llc_mac_match
(
llc
->
laddr
.
mac
,
laddr
->
mac
))
break
;
}
if
(
rc
)
sock_hold
(
rc
);
read_unlock_bh
(
&
sap
->
sk_list
.
lock
);
return
rc
;
}
/**
* llc_data_accept_state - designates if in this state data can be sent.
* @state: state of connection.
...
...
net/llc/llc_evnt.c
View file @
44bb970a
...
...
@@ -29,7 +29,7 @@ int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station,
struct
llc_station_state_ev
*
ev
=
llc_station_ev
(
skb
);
return
ev
->
type
==
LLC_STATION_EV_TYPE_SIMPLE
&&
ev
->
data
.
a
.
ev
==
ev
->
prim_type
==
LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK
?
0
:
1
;
}
...
...
@@ -39,7 +39,7 @@ int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station,
struct
llc_station_state_ev
*
ev
=
llc_station_ev
(
skb
);
return
ev
->
type
==
LLC_STATION_EV_TYPE_SIMPLE
&&
ev
->
data
.
a
.
ev
==
ev
->
prim_type
==
LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK
?
0
:
1
;
}
...
...
@@ -120,6 +120,6 @@ int llc_stat_ev_disable_req(struct llc_station *station, struct sk_buff *skb)
struct
llc_station_state_ev
*
ev
=
llc_station_ev
(
skb
);
return
ev
->
type
==
LLC_STATION_EV_TYPE_PRIM
&&
ev
->
data
.
prim
.
prim
==
LLC_DISABLE_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
ev
->
prim
==
LLC_DISABLE_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
net/llc/llc_if.c
View file @
44bb970a
...
...
@@ -30,17 +30,16 @@
/**
* llc_sap_open - open interface to the upper layers.
* @nw_indicate: pointer to indicate function of upper layer.
* @nw_confirm: pointer to confirm function of upper layer.
* @lsap: SAP number.
* @
sap: pointer to allocated SAP (output argument).
* @
func: rcv func for datalink protos
*
* Interface function to upper layer. Each one who wants to get a SAP
* (for example NetBEUI) should call this function. Returns the opened
* SAP for success, NULL for failure.
*/
struct
llc_sap
*
llc_sap_open
(
llc_prim_call_t
nw_indicate
,
llc_prim_call_t
nw_confirm
,
u8
lsap
)
struct
llc_sap
*
llc_sap_open
(
u8
lsap
,
int
(
*
func
)(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
pt
))
{
/* verify this SAP is not already open; if so, return error */
struct
llc_sap
*
sap
;
...
...
@@ -57,9 +56,8 @@ struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate,
goto
err
;
/* allocated a SAP; initialize it and clear out its memory pool */
sap
->
laddr
.
lsap
=
lsap
;
sap
->
ind
=
nw_indicate
;
sap
->
conf
=
nw_confirm
;
sap
->
parent_station
=
llc_station_get
();
sap
->
rcv_func
=
func
;
sap
->
station
=
llc_station_get
();
/* initialized SAP; add it to list of SAPs this station manages */
llc_sap_save
(
sap
);
out:
...
...
@@ -99,24 +97,16 @@ void llc_sap_close(struct llc_sap *sap)
void
llc_build_and_send_ui_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
u8
*
dmac
,
u8
dsap
)
{
union
llc_u_prim_data
prim_data
;
struct
llc_prim_if_block
prim
;
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
prim
.
data
=
&
prim_data
;
prim
.
sap
=
sap
;
prim
.
prim
=
LLC_DATAUNIT_PRIM
;
prim_data
.
udata
.
skb
=
skb
;
prim_data
.
udata
.
saddr
.
lsap
=
sap
->
laddr
.
lsap
;
prim_data
.
udata
.
daddr
.
lsap
=
dsap
;
memcpy
(
prim_data
.
udata
.
saddr
.
mac
,
skb
->
dev
->
dev_addr
,
IFHWADDRLEN
);
memcpy
(
prim_data
.
udata
.
daddr
.
mac
,
dmac
,
IFHWADDRLEN
);
ev
->
saddr
.
lsap
=
sap
->
laddr
.
lsap
;
ev
->
daddr
.
lsap
=
dsap
;
memcpy
(
ev
->
saddr
.
mac
,
skb
->
dev
->
dev_addr
,
IFHWADDRLEN
);
memcpy
(
ev
->
daddr
.
mac
,
dmac
,
IFHWADDRLEN
);
ev
->
type
=
LLC_SAP_EV_TYPE_PRIM
;
ev
->
data
.
prim
.
prim
=
LLC_DATAUNIT_PRIM
;
ev
->
data
.
prim
.
type
=
LLC_PRIM_TYPE_REQ
;
ev
->
data
.
prim
.
data
=
&
prim
;
ev
->
prim
=
LLC_DATAUNIT_PRIM
;
ev
->
prim_type
=
LLC_PRIM_TYPE_REQ
;
llc_sap_state_process
(
sap
,
skb
);
}
...
...
@@ -130,27 +120,19 @@ void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
* This function is called when upper layer wants to send a TEST pdu.
* Returns 0 for success, 1 otherwise.
*/
void
llc_build_and_send_test_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
u8
*
dmac
,
u8
dsap
)
void
llc_build_and_send_test_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
u8
*
dmac
,
u8
dsap
)
{
union
llc_u_prim_data
prim_data
;
struct
llc_prim_if_block
prim
;
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
prim
.
data
=
&
prim_data
;
prim
.
sap
=
sap
;
prim
.
prim
=
LLC_TEST_PRIM
;
prim_data
.
test
.
skb
=
skb
;
prim_data
.
test
.
saddr
.
lsap
=
sap
->
laddr
.
lsap
;
prim_data
.
test
.
daddr
.
lsap
=
dsap
;
memcpy
(
prim_data
.
test
.
saddr
.
mac
,
skb
->
dev
->
dev_addr
,
IFHWADDRLEN
);
memcpy
(
prim_data
.
test
.
daddr
.
mac
,
dmac
,
IFHWADDRLEN
);
ev
->
saddr
.
lsap
=
sap
->
laddr
.
lsap
;
ev
->
daddr
.
lsap
=
dsap
;
memcpy
(
ev
->
saddr
.
mac
,
skb
->
dev
->
dev_addr
,
IFHWADDRLEN
);
memcpy
(
ev
->
daddr
.
mac
,
dmac
,
IFHWADDRLEN
);
ev
->
type
=
LLC_SAP_EV_TYPE_PRIM
;
ev
->
data
.
prim
.
prim
=
LLC_TEST_PRIM
;
ev
->
data
.
prim
.
type
=
LLC_PRIM_TYPE_REQ
;
ev
->
data
.
prim
.
data
=
&
prim
;
ev
->
prim
=
LLC_TEST_PRIM
;
ev
->
prim_type
=
LLC_PRIM_TYPE_REQ
;
llc_sap_state_process
(
sap
,
skb
);
}
...
...
@@ -167,24 +149,16 @@ void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
void
llc_build_and_send_xid_pkt
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
,
u8
*
dmac
,
u8
dsap
)
{
union
llc_u_prim_data
prim_data
;
struct
llc_prim_if_block
prim
;
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
prim
.
data
=
&
prim_data
;
prim
.
sap
=
sap
;
prim
.
prim
=
LLC_XID_PRIM
;
prim_data
.
xid
.
skb
=
skb
;
prim_data
.
xid
.
saddr
.
lsap
=
sap
->
laddr
.
lsap
;
prim_data
.
xid
.
daddr
.
lsap
=
dsap
;
memcpy
(
prim_data
.
xid
.
saddr
.
mac
,
skb
->
dev
->
dev_addr
,
IFHWADDRLEN
);
memcpy
(
prim_data
.
xid
.
daddr
.
mac
,
dmac
,
IFHWADDRLEN
);
ev
->
saddr
.
lsap
=
sap
->
laddr
.
lsap
;
ev
->
daddr
.
lsap
=
dsap
;
memcpy
(
ev
->
saddr
.
mac
,
skb
->
dev
->
dev_addr
,
IFHWADDRLEN
);
memcpy
(
ev
->
daddr
.
mac
,
dmac
,
IFHWADDRLEN
);
ev
->
type
=
LLC_SAP_EV_TYPE_PRIM
;
ev
->
data
.
prim
.
prim
=
LLC_XID_PRIM
;
ev
->
data
.
prim
.
type
=
LLC_PRIM_TYPE_REQ
;
ev
->
data
.
prim
.
data
=
&
prim
;
ev
->
prim
=
LLC_XID_PRIM
;
ev
->
prim_type
=
LLC_PRIM_TYPE_REQ
;
llc_sap_state_process
(
sap
,
skb
);
}
...
...
@@ -220,9 +194,8 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
}
ev
=
llc_conn_ev
(
skb
);
ev
->
type
=
LLC_CONN_EV_TYPE_PRIM
;
ev
->
data
.
prim
.
prim
=
LLC_DATA_PRIM
;
ev
->
data
.
prim
.
type
=
LLC_PRIM_TYPE_REQ
;
ev
->
data
.
prim
.
data
=
NULL
;
ev
->
prim
=
LLC_DATA_PRIM
;
ev
->
prim_type
=
LLC_PRIM_TYPE_REQ
;
skb
->
dev
=
llc
->
dev
;
rc
=
llc_conn_state_process
(
sk
,
skb
);
out:
...
...
@@ -269,9 +242,8 @@ int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
ev
->
type
=
LLC_CONN_EV_TYPE_PRIM
;
ev
->
data
.
prim
.
prim
=
LLC_CONN_PRIM
;
ev
->
data
.
prim
.
type
=
LLC_PRIM_TYPE_REQ
;
ev
->
data
.
prim
.
data
=
NULL
;
ev
->
prim
=
LLC_CONN_PRIM
;
ev
->
prim_type
=
LLC_PRIM_TYPE_REQ
;
rc
=
llc_conn_state_process
(
sk
,
skb
);
}
out_put:
...
...
@@ -309,9 +281,8 @@ int llc_send_disc(struct sock *sk)
sk
->
state
=
TCP_CLOSING
;
ev
=
llc_conn_ev
(
skb
);
ev
->
type
=
LLC_CONN_EV_TYPE_PRIM
;
ev
->
data
.
prim
.
prim
=
LLC_DISC_PRIM
;
ev
->
data
.
prim
.
type
=
LLC_PRIM_TYPE_REQ
;
ev
->
data
.
prim
.
data
=
NULL
;
ev
->
prim
=
LLC_DISC_PRIM
;
ev
->
prim_type
=
LLC_PRIM_TYPE_REQ
;
rc
=
llc_conn_state_process
(
sk
,
skb
);
out:
sock_put
(
sk
);
...
...
@@ -327,8 +298,7 @@ int llc_send_disc(struct sock *sk)
* it to connection component state machine. Returns 0 for success, 1
* otherwise.
*/
int
llc_build_and_send_reset_pkt
(
struct
sock
*
sk
,
struct
llc_prim_if_block
*
prim
)
int
llc_build_and_send_reset_pkt
(
struct
sock
*
sk
)
{
int
rc
=
1
;
struct
sk_buff
*
skb
=
alloc_skb
(
0
,
GFP_ATOMIC
);
...
...
@@ -337,9 +307,8 @@ int llc_build_and_send_reset_pkt(struct sock *sk,
struct
llc_conn_state_ev
*
ev
=
llc_conn_ev
(
skb
);
ev
->
type
=
LLC_CONN_EV_TYPE_PRIM
;
ev
->
data
.
prim
.
prim
=
LLC_RESET_PRIM
;
ev
->
data
.
prim
.
type
=
LLC_PRIM_TYPE_REQ
;
ev
->
data
.
prim
.
data
=
prim
;
ev
->
prim
=
LLC_RESET_PRIM
;
ev
->
prim_type
=
LLC_PRIM_TYPE_REQ
;
rc
=
llc_conn_state_process
(
sk
,
skb
);
}
return
rc
;
...
...
net/llc/llc_mac.c
View file @
44bb970a
...
...
@@ -113,8 +113,22 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
}
llc_decode_pdu_type
(
skb
,
&
dest
);
if
(
dest
==
LLC_DEST_SAP
)
{
/* type 1 services */
dprintk
(
"%s: calling llc_sap_rcv!
\n
"
,
__FUNCTION__
);
if
(
sap
->
rcv_func
)
sap
->
rcv_func
(
skb
,
dev
,
pt
);
else
{
struct
llc_addr
laddr
;
struct
sock
*
sk
;
llc_pdu_decode_da
(
skb
,
laddr
.
mac
);
llc_pdu_decode_dsap
(
skb
,
&
laddr
.
lsap
);
sk
=
llc_lookup_dgram
(
sap
,
&
laddr
);
if
(
!
sk
)
goto
drop
;
skb
->
sk
=
sk
;
llc_sap_rcv
(
sap
,
skb
);
sock_put
(
sk
);
}
}
else
if
(
dest
==
LLC_DEST_CONN
)
{
struct
llc_addr
saddr
,
daddr
;
struct
sock
*
sk
;
...
...
net/llc/llc_main.c
View file @
44bb970a
...
...
@@ -71,10 +71,6 @@ struct llc_sap *llc_sap_alloc(void)
sap
->
state
=
LLC_SAP_STATE_ACTIVE
;
memcpy
(
sap
->
laddr
.
mac
,
llc_main_station
.
mac_sa
,
ETH_ALEN
);
spin_lock_init
(
&
sap
->
sk_list
.
lock
);
INIT_LIST_HEAD
(
&
sap
->
sk_list
.
list
);
skb_queue_head_init
(
&
sap
->
mac_pdu_q
);
sap
->
llc_ind_prim
.
data
=
&
sap
->
llc_ind_data_prim
;
sap
->
llc_cfm_prim
.
data
=
&
sap
->
llc_cfm_data_prim
;
}
return
sap
;
}
...
...
@@ -88,12 +84,10 @@ struct llc_sap *llc_sap_alloc(void)
*/
void
llc_free_sap
(
struct
llc_sap
*
sap
)
{
struct
llc_station
*
station
=
sap
->
parent_station
;
llc_rtn_all_conns
(
sap
);
spin_lock_bh
(
&
station
->
sap_list
.
lock
);
write_lock_bh
(
&
sap
->
station
->
sap_list
.
lock
);
list_del
(
&
sap
->
node
);
spin_unlock_bh
(
&
station
->
sap_list
.
lock
);
write_unlock_bh
(
&
sap
->
station
->
sap_list
.
lock
);
kfree
(
sap
);
}
...
...
@@ -105,9 +99,9 @@ void llc_free_sap(struct llc_sap *sap)
*/
void
llc_sap_save
(
struct
llc_sap
*
sap
)
{
spin
_lock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
write
_lock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
list_add_tail
(
&
sap
->
node
,
&
llc_main_station
.
sap_list
.
list
);
spin
_unlock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
write
_unlock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
}
/**
...
...
@@ -122,7 +116,7 @@ struct llc_sap *llc_sap_find(u8 sap_value)
struct
llc_sap
*
sap
=
NULL
;
struct
list_head
*
entry
;
spin
_lock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
read
_lock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
list_for_each
(
entry
,
&
llc_main_station
.
sap_list
.
list
)
{
sap
=
list_entry
(
entry
,
struct
llc_sap
,
node
);
if
(
sap
->
laddr
.
lsap
==
sap_value
)
...
...
@@ -130,7 +124,7 @@ struct llc_sap *llc_sap_find(u8 sap_value)
}
if
(
entry
==
&
llc_main_station
.
sap_list
.
list
)
/* not found */
sap
=
NULL
;
spin
_unlock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
read
_unlock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
return
sap
;
}
...
...
@@ -328,20 +322,18 @@ void llc_sk_reset(struct sock *sk)
static
int
llc_rtn_all_conns
(
struct
llc_sap
*
sap
)
{
int
rc
=
0
;
struct
list_head
*
entry
,
*
tmp
;
struct
sock
*
sk
;
spin_lock_bh
(
&
sap
->
sk_list
.
lock
);
if
(
list_empty
(
&
sap
->
sk_list
.
list
))
goto
out
;
list_for_each_safe
(
entry
,
tmp
,
&
sap
->
sk_list
.
list
)
{
struct
llc_opt
*
llc
=
list_entry
(
entry
,
struct
llc_opt
,
node
);
write_lock_bh
(
&
sap
->
sk_list
.
lock
);
llc
->
state
=
LLC_CONN_STATE_TEMP
;
if
(
llc_send_disc
(
llc
->
sk
))
for
(
sk
=
sap
->
sk_list
.
list
;
sk
;
sk
=
sk
->
next
)
{
llc_sk
(
sk
)
->
state
=
LLC_CONN_STATE_TEMP
;
if
(
llc_send_disc
(
sk
))
rc
=
1
;
}
out:
spin
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
write
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
return
rc
;
}
...
...
@@ -564,19 +556,19 @@ static char *llc_conn_state_names[] = {
static
int
llc_proc_get_info
(
char
*
bf
,
char
**
start
,
off_t
offset
,
int
length
)
{
struct
l
lc_opt
*
llc
;
struct
list_head
*
sap_entry
,
*
llc_entry
;
struct
l
ist_head
*
sap_entry
;
struct
sock
*
sk
;
off_t
begin
=
0
,
pos
=
0
;
int
len
=
0
;
spin
_lock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
read
_lock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
list_for_each
(
sap_entry
,
&
llc_main_station
.
sap_list
.
list
)
{
struct
llc_sap
*
sap
=
list_entry
(
sap_entry
,
struct
llc_sap
,
node
);
len
+=
sprintf
(
bf
+
len
,
"lsap=%02X
\n
"
,
sap
->
laddr
.
lsap
);
spin
_lock_bh
(
&
sap
->
sk_list
.
lock
);
if
(
list_empty
(
&
sap
->
sk_list
.
list
)
)
{
read
_lock_bh
(
&
sap
->
sk_list
.
lock
);
if
(
!
sap
->
sk_list
.
list
)
{
len
+=
sprintf
(
bf
+
len
,
"no connections
\n
"
);
goto
unlock
;
}
...
...
@@ -584,8 +576,9 @@ static int llc_proc_get_info(char *bf, char **start, off_t offset, int length)
"dsap state retr txw rxw "
"pf ff sf df rs cs "
"tack tpfc trs tbs blog busr
\n
"
);
list_for_each
(
llc_entry
,
&
sap
->
sk_list
.
list
)
{
llc
=
list_entry
(
llc_entry
,
struct
llc_opt
,
node
);
for
(
sk
=
sap
->
sk_list
.
list
;
sk
;
sk
=
sk
->
next
)
{
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
len
+=
sprintf
(
bf
+
len
,
" %02X %-10s %3d %3d %3d "
"%2d %2d %2d "
"%2d %2d %2d "
...
...
@@ -600,11 +593,10 @@ static int llc_proc_get_info(char *bf, char **start, off_t offset, int length)
timer_pending
(
&
llc
->
pf_cycle_timer
.
timer
),
timer_pending
(
&
llc
->
rej_sent_timer
.
timer
),
timer_pending
(
&
llc
->
busy_state_timer
.
timer
),
!!
llc
->
sk
->
backlog
.
tail
,
llc
->
sk
->
lock
.
users
);
!!
sk
->
backlog
.
tail
,
sk
->
lock
.
users
);
}
unlock:
spin
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
read
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
/* Keep dumping into the buffer start */
...
...
@@ -613,7 +605,7 @@ static int llc_proc_get_info(char *bf, char **start, off_t offset, int length)
if
(
pos
>
offset
+
length
)
/* We have dumped enough */
break
;
}
spin
_unlock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
read
_unlock_bh
(
&
llc_main_station
.
sap_list
.
lock
);
/* The data in question runs from begin to begin + len */
*
start
=
bf
+
(
offset
-
begin
);
/* Start of wanted data */
...
...
@@ -634,8 +626,8 @@ static struct packet_type llc_tr_packet_type = {
};
static
char
llc_banner
[]
__initdata
=
KERN_INFO
"LLC 2.0 by Procom, 1997, Arnaldo C. Melo, 2001
\n
"
KERN_INFO
"NET4.0 IEEE 802.2 extended support
\n
"
;
KERN_INFO
"LLC 2.0 by Procom, 1997, Arnaldo C. Melo, 2001
, 2002
\n
"
KERN_INFO
"NET
4.0 IEEE 802.2 extended support
\n
"
;
static
char
llc_error_msg
[]
__initdata
=
KERN_ERR
"LLC install NOT successful.
\n
"
;
...
...
@@ -669,7 +661,7 @@ static int __init llc_init(void)
llc_main_station
.
maximum_retry
=
1
;
llc_main_station
.
state
=
LLC_STATION_STATE_DOWN
;
ev
->
type
=
LLC_STATION_EV_TYPE_SIMPLE
;
ev
->
data
.
a
.
ev
=
LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK
;
ev
->
prim_type
=
LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK
;
rc
=
llc_station_next_state
(
&
llc_main_station
,
skb
);
proc_net_create
(
"802.2"
,
0
,
llc_proc_get_info
);
llc_ui_init
();
...
...
@@ -695,5 +687,5 @@ module_init(llc_init);
module_exit
(
llc_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001"
);
MODULE_AUTHOR
(
"Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001
, 2002
"
);
MODULE_DESCRIPTION
(
"LLC 2.0, NET4.0 IEEE 802.2 extended support"
);
net/llc/llc_s_ac.c
View file @
44bb970a
...
...
@@ -51,14 +51,12 @@ int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
int
llc_sap_action_send_ui
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
)
{
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
struct
llc_prim_if_block
*
prim
=
ev
->
data
.
prim
.
data
;
struct
llc_prim_unit_data
*
prim_data
=
&
prim
->
data
->
udata
;
int
rc
;
llc_pdu_header_init
(
skb
,
LLC_PDU_TYPE_U
,
prim_data
->
saddr
.
lsap
,
prim_data
->
daddr
.
lsap
,
LLC_PDU_CMD
);
llc_pdu_header_init
(
skb
,
LLC_PDU_TYPE_U
,
ev
->
saddr
.
lsap
,
ev
->
daddr
.
lsap
,
LLC_PDU_CMD
);
llc_pdu_init_as_ui_cmd
(
skb
);
rc
=
lan_hdrs_init
(
skb
,
prim_data
->
saddr
.
mac
,
prim_data
->
daddr
.
mac
);
rc
=
lan_hdrs_init
(
skb
,
ev
->
saddr
.
mac
,
ev
->
daddr
.
mac
);
if
(
!
rc
)
llc_sap_send_pdu
(
sap
,
skb
);
return
rc
;
...
...
@@ -76,14 +74,12 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
int
llc_sap_action_send_xid_c
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
)
{
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
struct
llc_prim_if_block
*
prim
=
ev
->
data
.
prim
.
data
;
struct
llc_prim_xid
*
prim_data
=
&
prim
->
data
->
xid
;
int
rc
;
llc_pdu_header_init
(
skb
,
LLC_PDU_TYPE_U
,
prim_data
->
saddr
.
lsap
,
prim_data
->
daddr
.
lsap
,
LLC_PDU_CMD
);
llc_pdu_header_init
(
skb
,
LLC_PDU_TYPE_U
,
ev
->
saddr
.
lsap
,
ev
->
daddr
.
lsap
,
LLC_PDU_CMD
);
llc_pdu_init_as_xid_cmd
(
skb
,
LLC_XID_NULL_CLASS_2
,
0
);
rc
=
lan_hdrs_init
(
skb
,
prim_data
->
saddr
.
mac
,
prim_data
->
daddr
.
mac
);
rc
=
lan_hdrs_init
(
skb
,
ev
->
saddr
.
mac
,
ev
->
daddr
.
mac
);
if
(
!
rc
)
llc_sap_send_pdu
(
sap
,
skb
);
return
rc
;
...
...
@@ -132,14 +128,12 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
int
llc_sap_action_send_test_c
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
)
{
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
struct
llc_prim_if_block
*
prim
=
ev
->
data
.
prim
.
data
;
struct
llc_prim_test
*
prim_data
=
&
prim
->
data
->
test
;
int
rc
;
llc_pdu_header_init
(
skb
,
LLC_PDU_TYPE_U
,
prim_data
->
saddr
.
lsap
,
prim_data
->
daddr
.
lsap
,
LLC_PDU_CMD
);
llc_pdu_header_init
(
skb
,
LLC_PDU_TYPE_U
,
ev
->
saddr
.
lsap
,
ev
->
daddr
.
lsap
,
LLC_PDU_CMD
);
llc_pdu_init_as_test_cmd
(
skb
);
rc
=
lan_hdrs_init
(
skb
,
prim_data
->
saddr
.
mac
,
prim_data
->
daddr
.
mac
);
rc
=
lan_hdrs_init
(
skb
,
ev
->
saddr
.
mac
,
ev
->
daddr
.
mac
);
if
(
!
rc
)
llc_sap_send_pdu
(
sap
,
skb
);
return
rc
;
...
...
net/llc/llc_s_ev.c
View file @
44bb970a
...
...
@@ -25,7 +25,7 @@ int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb)
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
return
ev
->
type
==
LLC_SAP_EV_TYPE_SIMPLE
&&
ev
->
data
.
a
.
ev
==
LLC_SAP_EV_ACTIVATION_REQ
?
0
:
1
;
ev
->
prim_type
==
LLC_SAP_EV_ACTIVATION_REQ
?
0
:
1
;
}
int
llc_sap_ev_rx_ui
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
)
...
...
@@ -43,8 +43,8 @@ int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb)
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
return
ev
->
type
==
LLC_SAP_EV_TYPE_PRIM
&&
ev
->
data
.
prim
.
prim
==
LLC_DATAUNIT_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
ev
->
prim
==
LLC_DATAUNIT_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
...
...
@@ -53,8 +53,8 @@ int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb)
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
return
ev
->
type
==
LLC_SAP_EV_TYPE_PRIM
&&
ev
->
data
.
prim
.
prim
==
LLC_XID_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
ev
->
prim
==
LLC_XID_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
int
llc_sap_ev_rx_xid_c
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
)
...
...
@@ -82,8 +82,8 @@ int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb)
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
return
ev
->
type
==
LLC_SAP_EV_TYPE_PRIM
&&
ev
->
data
.
prim
.
prim
==
LLC_TEST_PRIM
&&
ev
->
data
.
prim
.
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
ev
->
prim
==
LLC_TEST_PRIM
&&
ev
->
prim_
type
==
LLC_PRIM_TYPE_REQ
?
0
:
1
;
}
int
llc_sap_ev_rx_test_c
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
)
...
...
@@ -111,5 +111,5 @@ int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb)
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
return
ev
->
type
==
LLC_SAP_EV_TYPE_SIMPLE
&&
ev
->
data
.
a
.
ev
==
LLC_SAP_EV_DEACTIVATION_REQ
?
0
:
1
;
ev
->
prim_type
==
LLC_SAP_EV_DEACTIVATION_REQ
?
0
:
1
;
}
net/llc/llc_sap.c
View file @
44bb970a
...
...
@@ -18,6 +18,7 @@
#include <net/llc_s_ac.h>
#include <net/llc_s_st.h>
#include <net/sock.h>
#include <linux/tcp.h>
#include <net/llc_main.h>
#include <net/llc_mac.h>
#include <net/llc_pdu.h>
...
...
@@ -39,11 +40,15 @@ static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
*/
void
llc_sap_assign_sock
(
struct
llc_sap
*
sap
,
struct
sock
*
sk
)
{
spin
_lock_bh
(
&
sap
->
sk_list
.
lock
);
write
_lock_bh
(
&
sap
->
sk_list
.
lock
);
llc_sk
(
sk
)
->
sap
=
sap
;
list_add_tail
(
&
llc_sk
(
sk
)
->
node
,
&
sap
->
sk_list
.
list
);
sk
->
next
=
sap
->
sk_list
.
list
;
if
(
sk
->
next
)
sap
->
sk_list
.
list
->
pprev
=
&
sk
->
next
;
sap
->
sk_list
.
list
=
sk
;
sk
->
pprev
=
&
sap
->
sk_list
.
list
;
sock_hold
(
sk
);
spin
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
write
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
}
/**
...
...
@@ -55,28 +60,53 @@ void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk)
*/
void
llc_sap_unassign_sock
(
struct
llc_sap
*
sap
,
struct
sock
*
sk
)
{
spin_lock_bh
(
&
sap
->
sk_list
.
lock
);
list_del
(
&
llc_sk
(
sk
)
->
node
);
write_lock_bh
(
&
sap
->
sk_list
.
lock
);
if
(
sk
->
pprev
)
{
if
(
sk
->
next
)
sk
->
next
->
pprev
=
sk
->
pprev
;
*
sk
->
pprev
=
sk
->
next
;
sk
->
pprev
=
NULL
;
/*
* This only makes sense if the socket was inserted on the
* list, if sk->pprev is NULL it wasn't
*/
sock_put
(
sk
);
spin_unlock_bh
(
&
sap
->
sk_list
.
lock
);
}
write_unlock_bh
(
&
sap
->
sk_list
.
lock
);
}
/**
* llc_sap_state_process - sends event to SAP state machine
* @sap:
pointer to SAP
* @sap:
sap to use
* @skb: pointer to occurred event
*
* After executing actions of the event, upper layer will be indicated
* if needed(on receiving an UI frame).
* if needed(on receiving an UI frame). sk can be null for the
* datalink_proto case.
*/
void
llc_sap_state_process
(
struct
llc_sap
*
sap
,
struct
sk_buff
*
skb
)
{
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
/*
* We have to hold the skb, because llc_sap_next_state
* will kfree it in the sending path and we need to
* look at the skb->cb, where we encode llc_sap_state_ev.
*/
skb_get
(
skb
);
ev
->
ind_cfm_flag
=
0
;
llc_sap_next_state
(
sap
,
skb
);
if
(
ev
->
ind_cfm_flag
==
LLC_IND
)
sap
->
ind
(
ev
->
prim
);
else
if
(
ev
->
type
==
LLC_SAP_EV_TYPE_PDU
)
if
(
ev
->
ind_cfm_flag
==
LLC_IND
)
{
if
(
skb
->
sk
->
state
==
TCP_LISTEN
)
kfree_skb
(
skb
);
else
{
llc_save_primitive
(
skb
,
ev
->
prim
);
/* queue skb to the user. */
if
(
sock_queue_rcv_skb
(
skb
->
sk
,
skb
))
kfree_skb
(
skb
);
}
}
kfree_skb
(
skb
);
}
...
...
@@ -89,43 +119,17 @@ void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb)
{
struct
llc_pdu_un
*
pdu
;
struct
llc_sap_state_ev
*
ev
=
llc_sap_ev
(
skb
);
struct
llc_prim_if_block
*
prim
=
&
sap
->
llc_ind_prim
;
union
llc_u_prim_data
*
prim_data
=
prim
->
data
;
u8
lfb
;
llc_pdu_decode_sa
(
skb
,
prim_data
->
udata
.
saddr
.
mac
);
llc_pdu_decode_da
(
skb
,
prim_data
->
udata
.
daddr
.
mac
);
llc_pdu_decode_dsap
(
skb
,
&
prim_data
->
udata
.
daddr
.
lsap
);
llc_pdu_decode_ssap
(
skb
,
&
prim_data
->
udata
.
saddr
.
lsap
);
prim_data
->
udata
.
pri
=
0
;
prim_data
->
udata
.
skb
=
skb
;
pdu
=
llc_pdu_un_hdr
(
skb
);
switch
(
LLC_U_PDU_RSP
(
pdu
))
{
case
LLC_1_PDU_CMD_TEST
:
prim
->
prim
=
LLC_TEST_PRIM
;
break
;
ev
->
prim
=
LLC_TEST_PRIM
;
break
;
case
LLC_1_PDU_CMD_XID
:
prim
->
prim
=
LLC_XID_PRIM
;
break
;
ev
->
prim
=
LLC_XID_PRIM
;
break
;
case
LLC_1_PDU_CMD_UI
:
if
(
skb
->
protocol
==
ntohs
(
ETH_P_TR_802_2
))
{
if
(((
struct
trh_hdr
*
)
skb
->
mac
.
raw
)
->
rcf
)
{
lfb
=
ntohs
(((
struct
trh_hdr
*
)
skb
->
mac
.
raw
)
->
rcf
)
&
0x0070
;
prim_data
->
udata
.
lfb
=
lfb
>>
4
;
}
else
{
lfb
=
0xFF
;
prim_data
->
udata
.
lfb
=
0xFF
;
}
}
prim
->
prim
=
LLC_DATAUNIT_PRIM
;
break
;
ev
->
prim
=
LLC_DATAUNIT_PRIM
;
break
;
}
prim
->
data
=
prim_data
;
prim
->
sap
=
sap
;
ev
->
ind_cfm_flag
=
LLC_IND
;
ev
->
prim
=
prim
;
}
/**
...
...
net/llc/llc_sock.c
View file @
44bb970a
...
...
@@ -51,11 +51,7 @@ static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
static
u16
llc_ui_sap_link_no_max
[
256
];
static
struct
sockaddr_llc
llc_ui_addrnull
;
static
struct
proto_ops
llc_ui_ops
;
static
struct
sock
*
llc_ui_sockets
;
static
rwlock_t
llc_ui_sockets_lock
=
RW_LOCK_UNLOCKED
;
static
int
llc_ui_indicate
(
struct
llc_prim_if_block
*
prim
);
static
int
llc_ui_confirm
(
struct
llc_prim_if_block
*
prim
);
static
int
llc_ui_wait_for_conn
(
struct
sock
*
sk
,
int
timeout
);
static
int
llc_ui_wait_for_disc
(
struct
sock
*
sk
,
int
timeout
);
static
int
llc_ui_wait_for_data
(
struct
sock
*
sk
,
int
timeout
);
...
...
@@ -145,103 +141,6 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
return
rc
;
}
/**
* __llc_ui_find_sk_by_addr - return socket matching local mac + sap.
* @addr: Local address to match.
*
* Search the local socket list and return the socket which has a matching
* local (mac + sap) address (allows null mac). This search will work on
* unconnected and connected sockets, though find_by_link_no is recommend
* for connected sockets.
* Returns sock upon match, %NULL otherwise.
*/
static
struct
sock
*
__llc_ui_find_sk_by_addr
(
struct
llc_addr
*
laddr
,
struct
llc_addr
*
daddr
,
struct
net_device
*
dev
)
{
struct
sock
*
sk
;
for
(
sk
=
llc_ui_sockets
;
sk
;
sk
=
sk
->
next
)
{
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
if
(
llc
->
addr
.
sllc_ssap
!=
laddr
->
lsap
)
continue
;
if
(
llc_mac_null
(
llc
->
addr
.
sllc_smac
))
{
if
(
!
llc_mac_null
(
llc
->
addr
.
sllc_mmac
)
&&
!
llc_mac_match
(
llc
->
addr
.
sllc_mmac
,
laddr
->
mac
))
continue
;
break
;
}
if
(
dev
&&
!
llc_mac_null
(
llc
->
addr
.
sllc_mmac
)
&&
llc_mac_match
(
llc
->
addr
.
sllc_mmac
,
laddr
->
mac
)
&&
llc_mac_match
(
llc
->
addr
.
sllc_smac
,
dev
->
dev_addr
))
break
;
if
(
dev
->
flags
&
IFF_LOOPBACK
)
break
;
if
(
!
llc_mac_match
(
llc
->
addr
.
sllc_smac
,
laddr
->
mac
))
continue
;
if
(
llc_mac_null
(
llc
->
addr
.
sllc_dmac
))
break
;
}
return
sk
;
}
static
struct
sock
*
llc_ui_find_sk_by_addr
(
struct
llc_addr
*
addr
,
struct
llc_addr
*
daddr
,
struct
net_device
*
dev
)
{
struct
sock
*
sk
;
read_lock
(
&
llc_ui_sockets_lock
);
sk
=
__llc_ui_find_sk_by_addr
(
addr
,
daddr
,
dev
);
if
(
sk
)
sock_hold
(
sk
);
read_unlock
(
&
llc_ui_sockets_lock
);
return
sk
;
}
/**
* llc_ui_insert_socket - insert socket into list
* @sk: Socket to insert.
*
* Insert a socket into the local llc socket list.
*/
static
__inline__
void
llc_ui_insert_socket
(
struct
sock
*
sk
)
{
write_lock_bh
(
&
llc_ui_sockets_lock
);
sk
->
next
=
llc_ui_sockets
;
if
(
sk
->
next
)
llc_ui_sockets
->
pprev
=
&
sk
->
next
;
llc_ui_sockets
=
sk
;
sk
->
pprev
=
&
llc_ui_sockets
;
sock_hold
(
sk
);
write_unlock_bh
(
&
llc_ui_sockets_lock
);
}
/**
* llc_ui_remove_socket - remove socket from list
* @sk: Socket to remove.
*
* Remove a socket from the local llc socket list.
*/
static
__inline__
void
llc_ui_remove_socket
(
struct
sock
*
sk
)
{
write_lock_bh
(
&
llc_ui_sockets_lock
);
if
(
sk
->
pprev
)
{
if
(
sk
->
next
)
sk
->
next
->
pprev
=
sk
->
pprev
;
*
sk
->
pprev
=
sk
->
next
;
sk
->
pprev
=
NULL
;
/*
* This only makes sense if the socket was inserted on the
* list, if sk->pprev is NULL it wasn't
*/
sock_put
(
sk
);
}
write_unlock_bh
(
&
llc_ui_sockets_lock
);
}
static
void
llc_ui_sk_init
(
struct
socket
*
sock
,
struct
sock
*
sk
)
{
sk
->
type
=
sock
->
type
;
...
...
@@ -296,12 +195,10 @@ static int llc_ui_release(struct socket *sock)
llc
->
laddr
.
lsap
,
llc
->
daddr
.
lsap
);
if
(
!
llc_send_disc
(
sk
))
llc_ui_wait_for_disc
(
sk
,
sk
->
rcvtimeo
);
if
(
!
sk
->
zapped
)
{
if
(
!
sk
->
zapped
)
llc_sap_unassign_sock
(
llc
->
sap
,
sk
);
llc_ui_remove_socket
(
sk
);
}
release_sock
(
sk
);
if
(
llc
->
sap
&&
list_empty
(
&
llc
->
sap
->
sk_list
.
list
)
)
if
(
llc
->
sap
&&
!
llc
->
sap
->
sk_list
.
list
)
llc_sap_close
(
llc
->
sap
);
sock_put
(
sk
);
llc_sk_free
(
sk
);
...
...
@@ -384,8 +281,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
}
sap
=
llc_sap_find
(
addr
->
sllc_ssap
);
if
(
!
sap
)
{
sap
=
llc_sap_open
(
llc_ui_indicate
,
llc_ui_confirm
,
addr
->
sllc_ssap
);
sap
=
llc_sap_open
(
addr
->
sllc_ssap
,
NULL
);
rc
=
-
EBUSY
;
/* some other network layer is using the sap */
if
(
!
sap
)
goto
out
;
...
...
@@ -420,7 +316,6 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
llc
->
daddr
.
lsap
=
addr
->
sllc_dsap
;
memcpy
(
llc
->
daddr
.
mac
,
addr
->
sllc_dmac
,
IFHWADDRLEN
);
memcpy
(
&
llc
->
addr
,
addr
,
sizeof
(
llc
->
addr
));
llc_ui_insert_socket
(
sk
);
/* assign new connection to it's SAP */
llc_sap_assign_sock
(
sap
,
sk
);
rc
=
sk
->
zapped
=
0
;
...
...
@@ -769,7 +664,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
/* put original socket back into a clean listen state. */
sk
->
state
=
TCP_LISTEN
;
sk
->
ack_backlog
--
;
llc_ui_insert_socket
(
newsk
);
skb
->
sk
=
NULL
;
dprintk
(
"%s: ok success on %02X, client on %02X
\n
"
,
__FUNCTION__
,
llc_sk
(
sk
)
->
addr
.
sllc_ssap
,
newllc
->
addr
.
sllc_dsap
);
...
...
@@ -1126,178 +1020,6 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
return
rc
;
}
/**
* llc_ui_ind_test - handle TEST indication
* @prim: Primitive block provided by the llc layer.
*
* handle TEST indication.
*/
static
void
llc_ui_ind_test
(
struct
llc_prim_if_block
*
prim
)
{
struct
llc_prim_test
*
prim_data
=
&
prim
->
data
->
test
;
struct
sk_buff
*
skb
=
prim_data
->
skb
;
struct
sockaddr_llc
*
addr
=
llc_ui_skb_cb
(
skb
);
struct
sock
*
sk
=
llc_ui_find_sk_by_addr
(
&
prim_data
->
daddr
,
&
prim_data
->
saddr
,
skb
->
dev
);
if
(
!
sk
)
goto
out
;
if
(
sk
->
state
==
TCP_LISTEN
)
goto
out_put
;
/* save primitive for use by the user. */
addr
->
sllc_family
=
AF_LLC
;
addr
->
sllc_arphrd
=
skb
->
dev
->
type
;
addr
->
sllc_test
=
1
;
addr
->
sllc_xid
=
0
;
addr
->
sllc_ua
=
0
;
addr
->
sllc_dsap
=
prim_data
->
daddr
.
lsap
;
memcpy
(
addr
->
sllc_dmac
,
prim_data
->
daddr
.
mac
,
IFHWADDRLEN
);
addr
->
sllc_ssap
=
prim_data
->
saddr
.
lsap
;
memcpy
(
addr
->
sllc_smac
,
prim_data
->
saddr
.
mac
,
IFHWADDRLEN
);
/* queue skb to the user. */
if
(
sock_queue_rcv_skb
(
sk
,
skb
))
kfree_skb
(
skb
);
out_put:
sock_put
(
sk
);
out:
;
}
/**
* llc_ui_ind_xid - handle XID indication
* @prim: Primitive block provided by the llc layer.
*
* handle XID indication.
*/
static
void
llc_ui_ind_xid
(
struct
llc_prim_if_block
*
prim
)
{
struct
llc_prim_xid
*
prim_data
=
&
prim
->
data
->
xid
;
struct
sk_buff
*
skb
=
prim_data
->
skb
;
struct
sockaddr_llc
*
addr
=
llc_ui_skb_cb
(
skb
);
struct
sock
*
sk
=
llc_ui_find_sk_by_addr
(
&
prim_data
->
daddr
,
&
prim_data
->
saddr
,
skb
->
dev
);
if
(
!
sk
)
goto
out
;
if
(
sk
->
state
==
TCP_LISTEN
)
goto
out_put
;
/* save primitive for use by the user. */
addr
->
sllc_family
=
AF_LLC
;
addr
->
sllc_arphrd
=
0
;
addr
->
sllc_test
=
0
;
addr
->
sllc_xid
=
1
;
addr
->
sllc_ua
=
0
;
addr
->
sllc_dsap
=
prim_data
->
daddr
.
lsap
;
memcpy
(
addr
->
sllc_dmac
,
prim_data
->
daddr
.
mac
,
IFHWADDRLEN
);
addr
->
sllc_ssap
=
prim_data
->
saddr
.
lsap
;
memcpy
(
addr
->
sllc_smac
,
prim_data
->
saddr
.
mac
,
IFHWADDRLEN
);
/* queue skb to the user. */
if
(
sock_queue_rcv_skb
(
sk
,
skb
))
kfree_skb
(
skb
);
out_put:
sock_put
(
sk
);
out:
;
}
/**
* llc_ui_ind_dataunit - handle DATAUNIT indication
* @prim: Primitive block provided by the llc layer.
*
* handle DATAUNIT indication.
*/
static
void
llc_ui_ind_dataunit
(
struct
llc_prim_if_block
*
prim
)
{
struct
llc_prim_unit_data
*
prim_data
=
&
prim
->
data
->
udata
;
struct
sk_buff
*
skb
=
prim_data
->
skb
;
struct
sockaddr_llc
*
addr
=
llc_ui_skb_cb
(
skb
);
struct
sock
*
sk
=
llc_ui_find_sk_by_addr
(
&
prim_data
->
daddr
,
&
prim_data
->
saddr
,
skb
->
dev
);
if
(
!
sk
)
goto
out
;
if
(
sk
->
state
==
TCP_LISTEN
)
goto
out_put
;
/* save primitive for use by the user. */
addr
->
sllc_family
=
AF_LLC
;
addr
->
sllc_arphrd
=
skb
->
dev
->
type
;
addr
->
sllc_test
=
0
;
addr
->
sllc_xid
=
0
;
addr
->
sllc_ua
=
1
;
addr
->
sllc_dsap
=
prim_data
->
daddr
.
lsap
;
memcpy
(
addr
->
sllc_dmac
,
prim_data
->
daddr
.
mac
,
IFHWADDRLEN
);
addr
->
sllc_ssap
=
prim_data
->
saddr
.
lsap
;
memcpy
(
addr
->
sllc_smac
,
prim_data
->
saddr
.
mac
,
IFHWADDRLEN
);
/* queue skb to the user. */
if
(
sock_queue_rcv_skb
(
sk
,
skb
))
kfree_skb
(
skb
);
out_put:
sock_put
(
sk
);
out:
;
}
/**
* llc_ui_indicate - LLC user interface hook into the LLC layer.
* @prim: Primitive block provided by the llc layer.
*
* LLC user interface hook into the LLC layer, every llc_ui sap references
* this function as its indicate handler.
* Always returns 0 to indicate reception of primitive.
*/
static
int
llc_ui_indicate
(
struct
llc_prim_if_block
*
prim
)
{
switch
(
prim
->
prim
)
{
case
LLC_TEST_PRIM
:
llc_ui_ind_test
(
prim
);
break
;
case
LLC_XID_PRIM
:
llc_ui_ind_xid
(
prim
);
break
;
case
LLC_DATAUNIT_PRIM
:
llc_ui_ind_dataunit
(
prim
);
break
;
case
LLC_CONN_PRIM
:
dprintk
(
"%s: shouldn't happen, LLC_CONN_PRIM "
"is gone for ->ind()...
\n
"
,
__FUNCTION__
);
break
;
case
LLC_DATA_PRIM
:
dprintk
(
"%s: shouldn't happen, LLC_DATA_PRIM "
"is gone for ->ind()...
\n
"
,
__FUNCTION__
);
break
;
case
LLC_DISC_PRIM
:
dprintk
(
"%s: shouldn't happen, LLC_DISC_PRIM "
"is gone for ->ind()...
\n
"
,
__FUNCTION__
);
break
;
case
LLC_RESET_PRIM
:
default:
break
;
}
return
0
;
}
/**
* llc_ui_confirm - LLC user interface hook into the LLC layer
* @prim: Primitive block provided by the llc layer.
*
* LLC user interface hook into the LLC layer, every llc_ui sap references
* this function as its confirm handler.
* Always returns 0 to indicate reception of primitive.
*/
static
int
llc_ui_confirm
(
struct
llc_prim_if_block
*
prim
)
{
switch
(
prim
->
prim
)
{
case
LLC_CONN_PRIM
:
dprintk
(
"%s: shouldn't happen, LLC_CONN_PRIM "
"is gone for ->conf()...
\n
"
,
__FUNCTION__
);
break
;
case
LLC_DATA_PRIM
:
dprintk
(
"%s: shouldn't happen, LLC_DATA_PRIM "
"is gone for ->conf()...
\n
"
,
__FUNCTION__
);
break
;
case
LLC_DISC_PRIM
:
dprintk
(
"%s: shouldn't happen, LLC_DISC_PRIM "
"is gone for ->conf()...
\n
"
,
__FUNCTION__
);
break
;
case
LLC_RESET_PRIM
:
break
;
default:
printk
(
KERN_ERR
"%s: prim not supported%d
\n
"
,
__FUNCTION__
,
prim
->
prim
);
break
;
}
return
0
;
}
#ifdef CONFIG_PROC_FS
#define MAC_FORMATTED_SIZE 17
static
void
llc_ui_format_mac
(
char
*
bf
,
unsigned
char
*
mac
)
...
...
@@ -1320,25 +1042,24 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
{
off_t
pos
=
0
;
off_t
begin
=
0
;
struct
llc_opt
*
llc
;
struct
llc_sap
*
sap
;
struct
list_head
*
sap_entry
,
*
llc_entry
;
struct
sock
*
sk
;
struct
list_head
*
sap_entry
;
struct
llc_station
*
station
=
llc_station_get
();
int
len
=
sprintf
(
buffer
,
"SKt Mc local_mac_sap "
"remote_mac_sap tx_queue rx_queue st uid "
"link
\n
"
);
/* Output the LLC socket data for the /proc filesystem */
spin
_lock_bh
(
&
station
->
sap_list
.
lock
);
read
_lock_bh
(
&
station
->
sap_list
.
lock
);
list_for_each
(
sap_entry
,
&
station
->
sap_list
.
list
)
{
sap
=
list_entry
(
sap_entry
,
struct
llc_sap
,
node
);
spin
_lock_bh
(
&
sap
->
sk_list
.
lock
);
list_for_each
(
llc_entry
,
&
sap
->
sk_list
.
lis
t
)
{
llc
=
list_entry
(
llc_entry
,
struct
llc_opt
,
node
);
read
_lock_bh
(
&
sap
->
sk_list
.
lock
);
for
(
sk
=
sap
->
sk_list
.
list
;
sk
;
sk
=
sk
->
nex
t
)
{
struct
llc_opt
*
llc
=
llc_sk
(
sk
);
len
+=
sprintf
(
buffer
+
len
,
"%2X %2X "
,
llc
->
sk
->
type
,
len
+=
sprintf
(
buffer
+
len
,
"%2X %2X "
,
sk
->
type
,
!
llc_mac_null
(
llc
->
addr
.
sllc_mmac
));
if
(
llc
->
dev
&&
llc_mac_null
(
llc
->
addr
.
sllc_mmac
))
llc_ui_format_mac
(
buffer
+
len
,
...
...
@@ -1358,12 +1079,11 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
len
+=
sprintf
(
buffer
+
len
,
"@%02X %8d %8d %2d %3d "
,
llc
->
addr
.
sllc_dsap
,
atomic_read
(
&
llc
->
sk
->
wmem_alloc
),
atomic_read
(
&
llc
->
sk
->
rmem_alloc
),
llc
->
sk
->
state
,
llc
->
sk
->
socket
?
SOCK_INODE
(
llc
->
sk
->
socket
)
->
i_uid
:
-
1
);
atomic_read
(
&
sk
->
wmem_alloc
),
atomic_read
(
&
sk
->
rmem_alloc
),
sk
->
state
,
sk
->
socket
?
SOCK_INODE
(
sk
->
socket
)
->
i_uid
:
-
1
);
len
+=
sprintf
(
buffer
+
len
,
"%4d
\n
"
,
llc
->
link
);
/* Are we still dumping unwanted data then discard the record */
pos
=
begin
+
len
;
...
...
@@ -1375,9 +1095,9 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
if
(
pos
>
offset
+
length
)
/* We have dumped enough */
break
;
}
spin
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
read
_unlock_bh
(
&
sap
->
sk_list
.
lock
);
}
spin
_unlock_bh
(
&
station
->
sap_list
.
lock
);
read
_unlock_bh
(
&
station
->
sap_list
.
lock
);
/* The data in question runs from begin to begin + len */
*
start
=
buffer
+
offset
-
begin
;
/* Start of wanted data */
...
...
@@ -1393,7 +1113,7 @@ static struct net_proto_family llc_ui_family_ops = {
.
create
=
llc_ui_create
,
};
static
struct
proto_ops
SOCKOPS_WRAPPED
(
llc_ui_ops
)
=
{
static
struct
proto_ops
llc_ui_ops
=
{
.
family
=
PF_LLC
,
.
release
=
llc_ui_release
,
.
bind
=
llc_ui_bind
,
...
...
@@ -1413,9 +1133,6 @@ static struct proto_ops SOCKOPS_WRAPPED(llc_ui_ops) = {
.
sendpage
=
sock_no_sendpage
,
};
#include <linux/smp_lock.h>
SOCKOPS_WRAP
(
llc_ui
,
PF_LLC
);
static
char
llc_ui_banner
[]
__initdata
=
KERN_INFO
"NET4.0 IEEE 802.2 BSD sockets, Jay Schulist, 2001, Arnaldo C. Melo, 2002
\n
"
;
...
...
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