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
229e0840
Commit
229e0840
authored
Sep 26, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge nuts.ninka.net:/home/davem/src/BK/network-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
02debc0e
10880106
Changes
58
Show whitespace changes
Inline
Side-by-side
Showing
58 changed files
with
2647 additions
and
2540 deletions
+2647
-2540
include/linux/x25.h
include/linux/x25.h
+8
-8
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/ndisc.h
include/net/ndisc.h
+19
-0
include/net/p8022.h
include/net/p8022.h
+5
-4
include/net/sctp/constants.h
include/net/sctp/constants.h
+1
-0
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+2
-1
include/net/sctp/sm.h
include/net/sctp/sm.h
+8
-0
include/net/sctp/structs.h
include/net/sctp/structs.h
+14
-1
include/net/x25.h
include/net/x25.h
+8
-6
net/802/p8022.c
net/802/p8022.c
+4
-2
net/802/psnap.c
net/802/psnap.c
+7
-13
net/ipv4/netfilter/ipchains_core.c
net/ipv4/netfilter/ipchains_core.c
+1
-1
net/ipv6/ndisc.c
net/ipv6/ndisc.c
+189
-111
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
net/sched/sch_htb.c
net/sched/sch_htb.c
+6
-0
net/sctp/adler32.c
net/sctp/adler32.c
+1
-1
net/sctp/associola.c
net/sctp/associola.c
+32
-20
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+17
-17
net/sctp/command.c
net/sctp/command.c
+13
-13
net/sctp/debug.c
net/sctp/debug.c
+1
-0
net/sctp/endpointola.c
net/sctp/endpointola.c
+47
-42
net/sctp/input.c
net/sctp/input.c
+16
-16
net/sctp/ipv6.c
net/sctp/ipv6.c
+98
-17
net/sctp/output.c
net/sctp/output.c
+37
-40
net/sctp/outqueue.c
net/sctp/outqueue.c
+88
-63
net/sctp/primitive.c
net/sctp/primitive.c
+14
-14
net/sctp/protocol.c
net/sctp/protocol.c
+94
-14
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+30
-21
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+43
-21
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+501
-247
net/sctp/sm_statetable.c
net/sctp/sm_statetable.c
+492
-451
net/sctp/socket.c
net/sctp/socket.c
+54
-93
net/sctp/transport.c
net/sctp/transport.c
+20
-20
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+48
-42
net/sctp/ulpqueue.c
net/sctp/ulpqueue.c
+15
-15
net/x25/af_x25.c
net/x25/af_x25.c
+306
-267
net/x25/x25_in.c
net/x25/x25_in.c
+1
-1
net/x25/x25_route.c
net/x25/x25_route.c
+5
-3
No files found.
include/linux/x25.h
View file @
229e0840
...
...
@@ -39,16 +39,16 @@
* An X.121 address, it is held as ASCII text, null terminated, up to 15
* digits and a null terminator.
*/
typedef
struct
{
struct
x25_address
{
char
x25_addr
[
16
];
}
x25_address
;
};
/*
* Linux X.25 Address structure, used for bind, and connect mostly.
*/
struct
sockaddr_x25
{
sa_family_t
sx25_family
;
/* Must be AF_X25 */
x25_address
sx25_addr
;
/* X.121 Address */
struct
x25_address
sx25_addr
;
/* X.121 Address */
};
/*
...
...
@@ -78,7 +78,7 @@ struct x25_subscrip_struct {
* Routing table control structure.
*/
struct
x25_route_struct
{
x25_address
address
;
struct
x25_address
address
;
unsigned
int
sigdigits
;
char
device
[
200
];
};
...
...
include/net/llc_c_ev.h
View file @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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/ndisc.h
View file @
229e0840
...
...
@@ -51,6 +51,25 @@ struct ra_msg {
__u32
retrans_timer
;
};
struct
nd_opt_hdr
{
__u8
nd_opt_type
;
__u8
nd_opt_len
;
}
__attribute__
((
__packed__
));
struct
ndisc_options
{
struct
nd_opt_hdr
*
nd_opt_array
[
7
];
struct
nd_opt_hdr
*
nd_opt_piend
;
};
#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
#define nd_opts_pi_end nd_opt_piend
#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
#define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
extern
struct
nd_opt_hdr
*
ndisc_next_option
(
struct
nd_opt_hdr
*
cur
,
struct
nd_opt_hdr
*
end
);
extern
struct
ndisc_options
*
ndisc_parse_options
(
u8
*
opt
,
int
opt_len
,
struct
ndisc_options
*
ndopts
);
extern
int
ndisc_init
(
struct
net_proto_family
*
ops
);
...
...
include/net/p8022.h
View file @
229e0840
#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
include/net/sctp/constants.h
View file @
229e0840
...
...
@@ -112,6 +112,7 @@ typedef enum {
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
SCTP_EVENT_TIMEOUT_T3_RTX
,
SCTP_EVENT_TIMEOUT_T4_RTO
,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
SCTP_EVENT_TIMEOUT_HEARTBEAT
,
SCTP_EVENT_TIMEOUT_SACK
,
SCTP_EVENT_TIMEOUT_AUTOCLOSE
,
...
...
include/net/sctp/sctp.h
View file @
229e0840
...
...
@@ -114,7 +114,8 @@ extern sctp_protocol_t sctp_proto;
extern
struct
sock
*
sctp_get_ctl_sock
(
void
);
extern
int
sctp_copy_local_addr_list
(
sctp_protocol_t
*
,
sctp_bind_addr_t
*
,
sctp_scope_t
,
int
priority
,
int
flags
);
extern
sctp_pf_t
*
sctp_get_pf_specific
(
int
family
);
extern
void
sctp_set_pf_specific
(
int
family
,
sctp_pf_t
*
);
/*
* sctp_socket.c
...
...
include/net/sctp/sm.h
View file @
229e0840
...
...
@@ -107,6 +107,9 @@ sctp_state_fn_t sctp_sf_timer_ignore;
sctp_state_fn_t
sctp_sf_do_9_1_abort
;
sctp_state_fn_t
sctp_sf_cookie_wait_abort
;
sctp_state_fn_t
sctp_sf_cookie_echoed_abort
;
sctp_state_fn_t
sctp_sf_shutdown_pending_abort
;
sctp_state_fn_t
sctp_sf_shutdown_sent_abort
;
sctp_state_fn_t
sctp_sf_shutdown_ack_sent_abort
;
sctp_state_fn_t
sctp_sf_do_5_1B_init
;
sctp_state_fn_t
sctp_sf_do_5_1C_ack
;
sctp_state_fn_t
sctp_sf_do_5_1D_ce
;
...
...
@@ -119,6 +122,7 @@ sctp_state_fn_t sctp_sf_tabort_8_4_8;
sctp_state_fn_t
sctp_sf_operr_notify
;
sctp_state_fn_t
sctp_sf_t1_timer_expire
;
sctp_state_fn_t
sctp_sf_t2_timer_expire
;
sctp_state_fn_t
sctp_sf_t5_timer_expire
;
sctp_state_fn_t
sctp_sf_sendbeat_8_3
;
sctp_state_fn_t
sctp_sf_beat_8_3
;
sctp_state_fn_t
sctp_sf_backbeat_8_3
;
...
...
@@ -134,6 +138,7 @@ sctp_state_fn_t sctp_sf_discard_chunk;
sctp_state_fn_t
sctp_sf_do_5_2_1_siminit
;
sctp_state_fn_t
sctp_sf_do_5_2_2_dupinit
;
sctp_state_fn_t
sctp_sf_do_5_2_4_dupcook
;
sctp_state_fn_t
sctp_sf_unk_chunk
;
/* Prototypes for primitive event state functions. */
sctp_state_fn_t
sctp_sf_do_prm_asoc
;
...
...
@@ -144,6 +149,9 @@ sctp_state_fn_t sctp_sf_cookie_echoed_prm_shutdown;
sctp_state_fn_t
sctp_sf_do_9_1_prm_abort
;
sctp_state_fn_t
sctp_sf_cookie_wait_prm_abort
;
sctp_state_fn_t
sctp_sf_cookie_echoed_prm_abort
;
sctp_state_fn_t
sctp_sf_shutdown_pending_prm_abort
;
sctp_state_fn_t
sctp_sf_shutdown_sent_prm_abort
;
sctp_state_fn_t
sctp_sf_shutdown_ack_sent_prm_abort
;
sctp_state_fn_t
sctp_sf_error_closed
;
sctp_state_fn_t
sctp_sf_error_shutdown
;
sctp_state_fn_t
sctp_sf_ignore_primitive
;
...
...
include/net/sctp/structs.h
View file @
229e0840
...
...
@@ -255,6 +255,12 @@ typedef struct sctp_func {
sctp_func_t
*
sctp_get_af_specific
(
const
sockaddr_storage_t
*
address
);
/* Protocol family functions. */
typedef
struct
sctp_pf
{
void
(
*
event_msgname
)(
sctp_ulpevent_t
*
,
char
*
,
int
*
);
void
(
*
skb_msgname
)(
struct
sk_buff
*
,
char
*
,
int
*
);
}
sctp_pf_t
;
/* SCTP Socket type: UDP or TCP style. */
typedef
enum
{
SCTP_SOCKET_UDP
=
0
,
...
...
@@ -280,6 +286,7 @@ struct sctp_opt {
__u32
autoclose
;
__u8
nodelay
;
__u8
disable_fragments
;
sctp_pf_t
*
pf
;
};
...
...
@@ -845,6 +852,7 @@ int sctp_outqueue_set_output_handlers(sctp_outqueue_t *,
sctp_outqueue_ohandler_force_t
force
);
void
sctp_outqueue_restart
(
sctp_outqueue_t
*
);
void
sctp_retransmit
(
sctp_outqueue_t
*
,
sctp_transport_t
*
,
__u8
);
void
sctp_retransmit_mark
(
sctp_outqueue_t
*
,
sctp_transport_t
*
,
__u8
);
/* These bind address data fields common between endpoints and associations */
...
...
@@ -1128,6 +1136,11 @@ struct SCTP_association {
*/
sctp_transport_t
*
primary_path
;
/* Cache the primary path address here, when we
* need a an address for msg_name.
*/
sockaddr_storage_t
primary_addr
;
/* active_path
* The path that we are currently using to
* transmit new data and most control chunks.
...
...
@@ -1183,7 +1196,7 @@ struct SCTP_association {
int
next_dup_tsn
;
/* Do we need to sack the peer? */
in
t
sack_needed
;
uint8_
t
sack_needed
;
/* These are capabilities which our peer advertised. */
__u8
ecn_capable
;
/* Can peer do ECN? */
...
...
include/net/x25.h
View file @
229e0840
...
...
@@ -103,7 +103,7 @@ enum {
struct
x25_route
{
struct
x25_route
*
next
;
x25_address
address
;
/* Start of address range */
struct
x25_address
address
;
/* Start of address range */
unsigned
int
sigdigits
;
/* Number of sig digits */
struct
net_device
*
dev
;
/* More than one for MLP */
};
...
...
@@ -120,7 +120,7 @@ struct x25_neigh {
};
typedef
struct
{
x25_address
source_addr
,
dest_addr
;
struct
x25_address
source_addr
,
dest_addr
;
struct
x25_neigh
*
neighbour
;
unsigned
int
lci
;
unsigned
char
state
,
condition
,
qbitincl
,
intflag
;
...
...
@@ -148,8 +148,10 @@ extern int sysctl_x25_reset_request_timeout;
extern
int
sysctl_x25_clear_request_timeout
;
extern
int
sysctl_x25_ack_holdback_timeout
;
extern
int
x25_addr_ntoa
(
unsigned
char
*
,
x25_address
*
,
x25_address
*
);
extern
int
x25_addr_aton
(
unsigned
char
*
,
x25_address
*
,
x25_address
*
);
extern
int
x25_addr_ntoa
(
unsigned
char
*
,
struct
x25_address
*
,
struct
x25_address
*
);
extern
int
x25_addr_aton
(
unsigned
char
*
,
struct
x25_address
*
,
struct
x25_address
*
);
extern
unsigned
int
x25_new_lci
(
struct
x25_neigh
*
);
extern
struct
sock
*
x25_find_socket
(
unsigned
int
,
struct
x25_neigh
*
);
extern
void
x25_destroy_socket
(
struct
sock
*
);
...
...
@@ -194,7 +196,7 @@ extern void x25_kick(struct sock *);
extern
void
x25_enquiry_response
(
struct
sock
*
);
/* x25_route.c */
extern
struct
net_device
*
x25_get_route
(
x25_address
*
);
extern
struct
net_device
*
x25_get_route
(
struct
x25_address
*
);
extern
struct
net_device
*
x25_dev_get
(
char
*
);
extern
void
x25_route_device_down
(
struct
net_device
*
);
extern
int
x25_route_ioctl
(
unsigned
int
,
void
*
);
...
...
net/802/p8022.c
View file @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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/ipv4/netfilter/ipchains_core.c
View file @
229e0840
...
...
@@ -1252,7 +1252,7 @@ static struct ip_fwkernel *convert_ipfw(struct ip_fwuser *fwuser, int *errno)
return
NULL
;
}
fwkern
=
kmalloc
(
SIZEOF_STRUCT_IP_FW_KERNEL
,
GFP_
KERNEL
);
fwkern
=
kmalloc
(
SIZEOF_STRUCT_IP_FW_KERNEL
,
GFP_
ATOMIC
);
if
(
!
fwkern
)
{
duprintf
(
"convert_ipfw: kmalloc failed!
\n
"
);
*
errno
=
ENOMEM
;
...
...
net/ipv6/ndisc.c
View file @
229e0840
...
...
@@ -159,6 +159,67 @@ static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
return
opt
+
space
;
}
struct
nd_opt_hdr
*
ndisc_next_option
(
struct
nd_opt_hdr
*
cur
,
struct
nd_opt_hdr
*
end
)
{
int
type
;
if
(
!
cur
||
!
end
||
cur
>=
end
)
return
NULL
;
type
=
cur
->
nd_opt_type
;
do
{
cur
=
((
void
*
)
cur
)
+
(
cur
->
nd_opt_len
<<
3
);
}
while
(
cur
<
end
&&
cur
->
nd_opt_type
!=
type
);
return
(
cur
<=
end
&&
cur
->
nd_opt_type
==
type
?
cur
:
NULL
);
}
struct
ndisc_options
*
ndisc_parse_options
(
u8
*
opt
,
int
opt_len
,
struct
ndisc_options
*
ndopts
)
{
struct
nd_opt_hdr
*
nd_opt
=
(
struct
nd_opt_hdr
*
)
opt
;
if
(
!
nd_opt
||
opt_len
<
0
||
!
ndopts
)
return
NULL
;
memset
(
ndopts
,
0
,
sizeof
(
*
ndopts
));
while
(
opt_len
)
{
int
l
;
if
(
opt_len
<
sizeof
(
struct
nd_opt_hdr
))
return
NULL
;
l
=
nd_opt
->
nd_opt_len
<<
3
;
if
(
opt_len
<
l
||
l
==
0
)
return
NULL
;
switch
(
nd_opt
->
nd_opt_type
)
{
case
ND_OPT_SOURCE_LL_ADDR
:
case
ND_OPT_TARGET_LL_ADDR
:
case
ND_OPT_MTU
:
case
ND_OPT_REDIRECT_HDR
:
if
(
ndopts
->
nd_opt_array
[
nd_opt
->
nd_opt_type
])
{
ND_PRINTK2
((
KERN_WARNING
"ndisc_parse_options(): duplicated ND6 option found: type=%d
\n
"
,
nd_opt
->
nd_opt_type
));
}
else
{
ndopts
->
nd_opt_array
[
nd_opt
->
nd_opt_type
]
=
nd_opt
;
}
break
;
case
ND_OPT_PREFIX_INFO
:
ndopts
->
nd_opts_pi_end
=
nd_opt
;
if
(
ndopts
->
nd_opt_array
[
nd_opt
->
nd_opt_type
]
==
0
)
ndopts
->
nd_opt_array
[
nd_opt
->
nd_opt_type
]
=
nd_opt
;
break
;
default:
/*
* Unknown options must be silently ignored,
* to accomodate future extension to the protocol.
*/
ND_PRINTK2
(
KERN_WARNING
"ndisc_parse_options(): ignored unsupported option; type=%d, len=%d
\n
"
,
nd_opt
->
nd_opt_type
,
nd_opt
->
nd_opt_len
);
}
opt_len
-=
l
;
nd_opt
=
((
void
*
)
nd_opt
)
+
l
;
}
return
ndopts
;
}
int
ndisc_mc_map
(
struct
in6_addr
*
addr
,
char
*
buf
,
struct
net_device
*
dev
,
int
dir
)
{
switch
(
dev
->
type
)
{
...
...
@@ -489,27 +550,6 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
}
static
u8
*
ndisc_find_option
(
u8
*
opt
,
int
opt_len
,
int
len
,
int
option
)
{
while
(
opt_len
<=
len
)
{
int
l
=
opt
[
1
]
<<
3
;
if
(
opt
[
0
]
==
option
&&
l
>=
opt_len
)
return
opt
+
2
;
if
(
l
==
0
)
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ndisc: option has 0 len
\n
"
);
return
NULL
;
}
opt
+=
l
;
len
-=
l
;
}
return
NULL
;
}
static
void
ndisc_error_report
(
struct
neighbour
*
neigh
,
struct
sk_buff
*
skb
)
{
/*
...
...
@@ -547,13 +587,6 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
}
}
static
void
ndisc_update
(
struct
neighbour
*
neigh
,
u8
*
opt
,
int
len
,
int
type
)
{
opt
=
ndisc_find_option
(
opt
,
neigh
->
dev
->
addr_len
+
2
,
len
,
type
);
neigh_update
(
neigh
,
opt
,
NUD_STALE
,
1
,
1
);
}
static
void
ndisc_router_discovery
(
struct
sk_buff
*
skb
)
{
struct
ra_msg
*
ra_msg
=
(
struct
ra_msg
*
)
skb
->
h
.
raw
;
...
...
@@ -561,6 +594,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
struct
inet6_dev
*
in6_dev
;
struct
rt6_info
*
rt
;
int
lifetime
;
struct
ndisc_options
ndopts
;
int
optlen
;
__u8
*
opt
=
(
__u8
*
)(
ra_msg
+
1
);
...
...
@@ -592,6 +626,13 @@ static void ndisc_router_discovery(struct sk_buff *skb)
return
;
}
if
(
!
ndisc_parse_options
(
opt
,
optlen
,
&
ndopts
))
{
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 RA: invalid ND option, ignored.
\n
"
);
return
;
}
if
(
in6_dev
->
if_flags
&
IF_RS_SENT
)
{
/*
* flag that an RA was received after an RS was sent
...
...
@@ -675,40 +716,42 @@ static void ndisc_router_discovery(struct sk_buff *skb)
* Process options.
*/
while
(
optlen
>
0
)
{
int
len
=
(
opt
[
1
]
<<
3
);
if
(
len
==
0
)
{
ND_PRINTK0
(
"RA: opt has 0 len
\n
"
);
break
;
if
(
rt
&&
(
neigh
=
rt
->
rt6i_nexthop
)
!=
NULL
)
{
u8
*
lladdr
=
NULL
;
int
lladdrlen
;
if
(
ndopts
.
nd_opts_src_lladdr
)
{
lladdr
=
(
u8
*
)((
ndopts
.
nd_opts_src_lladdr
)
+
1
);
lladdrlen
=
ndopts
.
nd_opts_src_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
skb
->
dev
->
addr_len
))
{
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 RA: Invalid lladdr length.
\n
"
);
goto
out
;
}
}
neigh_update
(
neigh
,
lladdr
,
NUD_STALE
,
1
,
1
);
}
switch
(
*
opt
)
{
case
ND_OPT_SOURCE_LL_ADDR
:
if
(
rt
==
NULL
)
break
;
if
((
neigh
=
rt
->
rt6i_nexthop
)
!=
NULL
&&
skb
->
dev
->
addr_len
+
2
>=
len
)
neigh_update
(
neigh
,
opt
+
2
,
NUD_STALE
,
1
,
1
);
break
;
case
ND_OPT_PREFIX_INFO
:
addrconf_prefix_rcv
(
skb
->
dev
,
opt
,
len
);
break
;
if
(
ndopts
.
nd_opts_pi
)
{
struct
nd_opt_hdr
*
p
;
for
(
p
=
ndopts
.
nd_opts_pi
;
p
;
p
=
ndisc_next_option
(
p
,
ndopts
.
nd_opts_pi_end
))
{
addrconf_prefix_rcv
(
skb
->
dev
,
(
u8
*
)
p
,
(
p
->
nd_opt_len
)
<<
3
);
}
}
case
ND_OPT_MTU
:
{
int
mtu
;
if
(
ndopts
.
nd_opts_mtu
)
{
u32
mtu
;
mtu
=
htonl
(
*
(
__u32
*
)(
opt
+
4
));
memcpy
(
&
mtu
,
((
u8
*
)(
ndopts
.
nd_opts_mtu
+
1
))
+
2
,
sizeof
(
mtu
));
mtu
=
ntohl
(
mtu
);
if
(
mtu
<
IPV6_MIN_MTU
||
mtu
>
skb
->
dev
->
mtu
)
{
ND_PRINTK0
(
"NDISC: router "
"
announcement with mtu = %d
\n
"
,
if
(
net_ratelimit
())
{
ND_PRINTK0
(
"NDISC: router
announcement with mtu = %d
\n
"
,
mtu
);
break
;
}
}
if
(
in6_dev
->
cnf
.
mtu6
!=
mtu
)
{
...
...
@@ -720,18 +763,13 @@ static void ndisc_router_discovery(struct sk_buff *skb)
rt6_mtu_change
(
skb
->
dev
,
mtu
);
}
}
break
;
case
ND_OPT_TARGET_LL_ADDR
:
case
ND_OPT_REDIRECT_HDR
:
ND_PRINTK0
(
"got illegal option with RA"
);
break
;
default:
ND_PRINTK0
(
"unkown option in RA
\n
"
);
};
optlen
-=
len
;
opt
+=
len
;
if
(
ndopts
.
nd_opts_tgt_lladdr
||
ndopts
.
nd_opts_rh
)
{
if
(
net_ratelimit
())
ND_PRINTK0
(
KERN_WARNING
"ICMP6 RA: got illegal option with RA"
);
}
out:
if
(
rt
)
dst_release
(
&
rt
->
u
.
dst
);
in6_dev_put
(
in6_dev
);
...
...
@@ -745,7 +783,10 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
struct
in6_addr
*
target
;
/* new first hop to destination */
struct
neighbour
*
neigh
;
int
on_link
=
0
;
struct
ndisc_options
ndopts
;
int
optlen
;
u8
*
lladdr
=
NULL
;
int
lladdrlen
;
if
(
!
(
ipv6_addr_type
(
&
skb
->
nh
.
ipv6h
->
saddr
)
&
IPV6_ADDR_LINKLOCAL
))
{
if
(
net_ratelimit
())
...
...
@@ -793,6 +834,24 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
* first-hop router for the specified ICMP Destination Address.
*/
if
(
!
ndisc_parse_options
((
u8
*
)(
dest
+
1
),
optlen
,
&
ndopts
))
{
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 Redirect: invalid ND options, rejected.
\n
"
);
in6_dev_put
(
in6_dev
);
return
;
}
if
(
ndopts
.
nd_opts_tgt_lladdr
)
{
lladdr
=
(
u8
*
)(
ndopts
.
nd_opts_tgt_lladdr
+
1
);
lladdrlen
=
ndopts
.
nd_opts_tgt_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
skb
->
dev
->
addr_len
))
{
if
(
net_ratelimit
())
ND_PRINTK2
(
KERN_WARNING
"ICMP6 Redirect: invalid lladdr length.
\n
"
);
in6_dev_put
(
in6_dev
);
return
;
}
}
/* passed validation tests */
/*
...
...
@@ -801,7 +860,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
neigh
=
__neigh_lookup
(
&
nd_tbl
,
target
,
skb
->
dev
,
1
);
if
(
neigh
)
{
n
disc_update
(
neigh
,
(
u8
*
)(
dest
+
1
),
optlen
,
ND_OPT_TARGET_LL_ADDR
);
n
eigh_update
(
neigh
,
lladdr
,
NUD_STALE
,
1
,
1
);
if
(
neigh
->
nud_state
&
NUD_VALID
)
rt6_redirect
(
dest
,
&
skb
->
nh
.
ipv6h
->
saddr
,
neigh
,
on_link
);
else
...
...
@@ -927,31 +986,6 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
ICMP6_INC_STATS
(
Icmp6OutMsgs
);
}
static
__inline__
struct
neighbour
*
ndisc_recv_ns
(
struct
in6_addr
*
saddr
,
struct
sk_buff
*
skb
)
{
u8
*
opt
;
opt
=
skb
->
h
.
raw
;
opt
+=
sizeof
(
struct
nd_msg
);
opt
=
ndisc_find_option
(
opt
,
skb
->
dev
->
addr_len
+
2
,
skb
->
tail
-
opt
,
ND_OPT_SOURCE_LL_ADDR
);
return
neigh_event_ns
(
&
nd_tbl
,
opt
,
saddr
,
skb
->
dev
);
}
static
__inline__
int
ndisc_recv_na
(
struct
neighbour
*
neigh
,
struct
sk_buff
*
skb
)
{
u8
*
opt
;
struct
nd_msg
*
msg
=
(
struct
nd_msg
*
)
skb
->
h
.
raw
;
opt
=
ndisc_find_option
(
msg
->
opt
,
skb
->
dev
->
addr_len
+
2
,
skb
->
tail
-
msg
->
opt
,
ND_OPT_TARGET_LL_ADDR
);
return
neigh_update
(
neigh
,
opt
,
msg
->
icmph
.
icmp6_solicited
?
NUD_REACHABLE
:
NUD_STALE
,
msg
->
icmph
.
icmp6_override
,
1
);
}
static
void
pndisc_redo
(
struct
sk_buff
*
skb
)
{
ndisc_rcv
(
skb
);
...
...
@@ -983,13 +1017,15 @@ int ndisc_rcv(struct sk_buff *skb)
return
0
;
}
/* XXX: RFC2461 Validation of [all ndisc messages]:
* All included ndisc options MUST be of non-zero length
* (Some checking in ndisc_find_option)
*/
switch
(
msg
->
icmph
.
icmp6_type
)
{
case
NDISC_NEIGHBOUR_SOLICITATION
:
{
struct
nd_msg
*
msg
=
(
struct
nd_msg
*
)
skb
->
h
.
raw
;
u8
*
lladdr
=
NULL
;
int
lladdrlen
=
0
;
u32
ndoptlen
=
skb
->
tail
-
msg
->
opt
;
struct
ndisc_options
ndopts
;
if
(
skb
->
len
<
sizeof
(
struct
nd_msg
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: packet too short
\n
"
);
...
...
@@ -1002,6 +1038,22 @@ int ndisc_rcv(struct sk_buff *skb)
return
0
;
}
if
(
!
ndisc_parse_options
(
msg
->
opt
,
ndoptlen
,
&
ndopts
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: invalid ND option, ignored.
\n
"
);
return
0
;
}
if
(
ndopts
.
nd_opts_src_lladdr
)
{
lladdr
=
(
u8
*
)(
ndopts
.
nd_opts_src_lladdr
+
1
);
lladdrlen
=
ndopts
.
nd_opts_src_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
skb
->
dev
->
addr_len
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: bad lladdr length.
\n
"
);
return
0
;
}
}
/* XXX: RFC2461 7.1.1:
* If the IP source address is the unspecified address, there
* MUST NOT be source link-layer address option in the message.
...
...
@@ -1068,7 +1120,7 @@ int ndisc_rcv(struct sk_buff *skb)
* for the source adddress
*/
neigh
=
n
disc_recv_ns
(
saddr
,
skb
);
neigh
=
n
eigh_event_ns
(
&
nd_tbl
,
lladdr
,
saddr
,
skb
->
dev
);
if
(
neigh
||
!
dev
->
hard_header
)
{
ndisc_send_na
(
dev
,
neigh
,
saddr
,
&
ifp
->
addr
,
...
...
@@ -1098,7 +1150,8 @@ int ndisc_rcv(struct sk_buff *skb)
else
nd_tbl
.
stats
.
rcv_probes_ucast
++
;
neigh
=
ndisc_recv_ns
(
saddr
,
skb
);
neigh
=
neigh_event_ns
(
&
nd_tbl
,
lladdr
,
saddr
,
skb
->
dev
);
if
(
neigh
)
{
ndisc_send_na
(
dev
,
neigh
,
saddr
,
&
msg
->
target
,
...
...
@@ -1118,8 +1171,16 @@ int ndisc_rcv(struct sk_buff *skb)
}
return
0
;
}
case
NDISC_NEIGHBOUR_ADVERTISEMENT
:
{
struct
nd_msg
*
msg
=
(
struct
nd_msg
*
)
skb
->
h
.
raw
;
u8
*
lladdr
=
NULL
;
int
lladdrlen
=
0
;
u32
ndoptlen
=
skb
->
tail
-
msg
->
opt
;
struct
ndisc_options
ndopts
;
if
(
skb
->
len
<
sizeof
(
struct
nd_msg
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NA: packet too short
\n
"
);
...
...
@@ -1138,6 +1199,20 @@ int ndisc_rcv(struct sk_buff *skb)
return
0
;
}
if
(
!
ndisc_parse_options
(
msg
->
opt
,
ndoptlen
,
&
ndopts
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"ICMP NS: invalid ND option, ignored.
\n
"
);
return
0
;
}
if
(
ndopts
.
nd_opts_tgt_lladdr
)
{
lladdr
=
(
u8
*
)(
ndopts
.
nd_opts_tgt_lladdr
+
1
);
lladdrlen
=
ndopts
.
nd_opts_tgt_lladdr
->
nd_opt_len
<<
3
;
if
(
lladdrlen
!=
NDISC_OPT_SPACE
(
skb
->
dev
->
addr_len
))
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"NDISC NA: invalid lladdr length.
\n
"
);
return
0
;
}
}
if
((
ifp
=
ipv6_get_ifaddr
(
&
msg
->
target
,
dev
)))
{
if
(
ifp
->
flags
&
IFA_F_TENTATIVE
)
{
addrconf_dad_failure
(
ifp
);
...
...
@@ -1175,10 +1250,13 @@ int ndisc_rcv(struct sk_buff *skb)
neigh
->
flags
|=
NTF_ROUTER
;
}
ndisc_recv_na
(
neigh
,
skb
);
neigh_update
(
neigh
,
lladdr
,
msg
->
icmph
.
icmp6_solicited
?
NUD_REACHABLE
:
NUD_STALE
,
msg
->
icmph
.
icmp6_override
,
1
);
neigh_release
(
neigh
);
}
break
;
}
case
NDISC_ROUTER_ADVERTISEMENT
:
ndisc_router_discovery
(
skb
);
...
...
net/ipx/af_ipx.c
View file @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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 @
229e0840
...
...
@@ -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
"
;
...
...
net/sched/sch_htb.c
View file @
229e0840
...
...
@@ -1163,6 +1163,8 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt)
skb_queue_head_init
(
&
q
->
direct_queue
);
q
->
direct_qlen
=
sch
->
dev
->
tx_queue_len
;
if
(
q
->
direct_qlen
<
2
)
/* some devices have zero tx_queue_len */
q
->
direct_qlen
=
2
;
q
->
timer
.
function
=
htb_timer
;
q
->
timer
.
data
=
(
unsigned
long
)
sch
;
...
...
@@ -1429,6 +1431,10 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
if
(
!
rtab
||
!
ctab
)
goto
failure
;
if
(
!
cl
)
{
/* new class */
/* check for valid classid */
if
(
!
classid
||
TC_H_MAJ
(
classid
^
sch
->
handle
)
||
htb_find
(
classid
,
sch
))
goto
failure
;
/* check maximal depth */
if
(
parent
&&
parent
->
parent
&&
parent
->
parent
->
level
<
2
)
{
printk
(
KERN_ERR
"htb: tree is too deep
\n
"
);
...
...
net/sctp/adler32.c
View file @
229e0840
...
...
@@ -96,7 +96,7 @@ unsigned long update_adler32(unsigned long adler,
* one subtract at the MOST, since buf[n]
* is a max of 255.
*/
if
(
s1
>=
BASE
)
if
(
s1
>=
BASE
)
s1
-=
BASE
;
/* s2 = (s2 + s1) % BASE */
...
...
net/sctp/associola.c
View file @
229e0840
...
...
@@ -288,7 +288,6 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
return
NULL
;
}
/* Free this association if possible. There may still be users, so
* the actual deallocation may be delayed.
*/
...
...
@@ -330,6 +329,11 @@ void sctp_association_free(sctp_association_t *asoc)
sctp_association_put
(
asoc
);
}
/* Free peer's cached cookie. */
if
(
asoc
->
peer
.
cookie
)
{
kfree
(
asoc
->
peer
.
cookie
);
}
/* Release the transport structures. */
list_for_each_safe
(
pos
,
temp
,
&
asoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
sctp_transport_t
,
transports
);
...
...
@@ -342,7 +346,6 @@ void sctp_association_free(sctp_association_t *asoc)
sctp_association_put
(
asoc
);
}
/* Cleanup and free up an association. */
static
void
sctp_association_destroy
(
sctp_association_t
*
asoc
)
{
...
...
@@ -387,8 +390,7 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
asoc
->
peer
.
port
=
*
port
;
}
SCTP_ASSERT
(
*
port
==
asoc
->
peer
.
port
,
":Invalid port
\n
"
,
return
NULL
);
SCTP_ASSERT
(
*
port
==
asoc
->
peer
.
port
,
":Invalid port
\n
"
,
return
NULL
);
/* Check to see if this is a duplicate. */
peer
=
sctp_assoc_lookup_paddr
(
asoc
,
addr
);
...
...
@@ -464,6 +466,16 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
/* Attach the remote transport to our asoc. */
list_add_tail
(
&
peer
->
transports
,
&
asoc
->
peer
.
transport_addr_list
);
/* If we do not yet have a primary path, set one. */
if
(
NULL
==
asoc
->
peer
.
primary_path
)
{
asoc
->
peer
.
primary_path
=
peer
;
/* Set a default msg_name for events. */
memcpy
(
&
asoc
->
peer
.
primary_addr
,
&
peer
->
ipaddr
,
sizeof
(
sockaddr_storage_t
));
asoc
->
peer
.
active_path
=
peer
;
asoc
->
peer
.
retran_path
=
peer
;
}
/* If we do not yet have a primary path, set one. */
if
(
NULL
==
asoc
->
peer
.
primary_path
)
{
asoc
->
peer
.
primary_path
=
peer
;
...
...
net/sctp/bind_addr.c
View file @
229e0840
net/sctp/command.c
View file @
229e0840
net/sctp/debug.c
View file @
229e0840
...
...
@@ -198,6 +198,7 @@ static const char *sctp_timer_tbl[] = {
"TIMEOUT_T2_SHUTDOWN"
,
"TIMEOUT_T3_RTX"
,
"TIMEOUT_T4_RTO"
,
"TIMEOUT_T5_SHUTDOWN_GUARD"
,
"TIMEOUT_HEARTBEAT"
,
"TIMEOUT_SACK"
,
"TIMEOUT_AUTOCLOSE"
,
...
...
net/sctp/endpointola.c
View file @
229e0840
...
...
@@ -92,6 +92,7 @@ sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto,
sctp_endpoint_t
*
sctp_endpoint_init
(
sctp_endpoint_t
*
ep
,
sctp_protocol_t
*
proto
,
struct
sock
*
sk
,
int
priority
)
{
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
memset
(
ep
,
0
,
sizeof
(
sctp_endpoint_t
));
/* Initialize the base structure. */
...
...
@@ -129,22 +130,30 @@ sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
/* Set up the base timeout information. */
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_NONE
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
SCTP_DEFAULT_TIMEOUT_T1_COOKIE
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
SCTP_DEFAULT_TIMEOUT_T1_INIT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
sctp_sk
(
sk
)
->
rtoinfo
.
srto_initial
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
SCTP_DEFAULT_TIMEOUT_T1_COOKIE
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
SCTP_DEFAULT_TIMEOUT_T1_INIT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
sp
->
rtoinfo
.
srto_initial
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T3_RTX
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
SCTP_DEFAULT_TIMEOUT_HEARTBEAT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
SCTP_DEFAULT_TIMEOUT_SACK
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sctp_sk
(
sk
)
->
autoclose
*
HZ
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_PMTU_RAISE
]
=
SCTP_DEFAULT_TIMEOUT_PMTU_RAISE
;
/* sctpimpguide-05 Section 2.12.2
* If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
* recommended value of 5 times 'RTO.Max'.
*/
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
]
=
5
*
sp
->
rtoinfo
.
srto_max
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
SCTP_DEFAULT_TIMEOUT_HEARTBEAT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
SCTP_DEFAULT_TIMEOUT_SACK
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sp
->
autoclose
*
HZ
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_PMTU_RAISE
]
=
SCTP_DEFAULT_TIMEOUT_PMTU_RAISE
;
/* Set up the default send/receive buffer space. */
...
...
@@ -251,7 +260,8 @@ sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *ep,
* We do a linear search of the associations for this endpoint.
* We return the matching transport address too.
*/
sctp_association_t
*
__sctp_endpoint_lookup_assoc
(
const
sctp_endpoint_t
*
endpoint
,
sctp_association_t
*
__sctp_endpoint_lookup_assoc
(
const
sctp_endpoint_t
*
endpoint
,
const
sockaddr_storage_t
*
paddr
,
sctp_transport_t
**
transport
)
{
...
...
@@ -360,10 +370,5 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep)
/* Is this the right way to pass errors up to the ULP? */
if
(
error
)
ep
->
base
.
sk
->
err
=
-
error
;
out:
}
net/sctp/input.c
View file @
229e0840
net/sctp/ipv6.c
View file @
229e0840
...
...
@@ -189,6 +189,80 @@ int sctp_v6_get_dst_mtu(const sockaddr_storage_t *address)
return
dst_mtu
;
}
/* Initialize a PF_INET6 socket msg_name. */
static
void
sctp_inet6_msgname
(
char
*
msgname
,
int
*
addr_len
)
{
struct
sockaddr_in6
*
sin6
;
sin6
=
(
struct
sockaddr_in6
*
)
msgname
;
sin6
->
sin6_family
=
AF_INET6
;
sin6
->
sin6_flowinfo
=
0
;
sin6
->
sin6_scope_id
=
0
;
*
addr_len
=
sizeof
(
struct
sockaddr_in6
);
}
/* Initialize a PF_INET msgname from a ulpevent. */
static
void
sctp_inet6_event_msgname
(
sctp_ulpevent_t
*
event
,
char
*
msgname
,
int
*
addrlen
)
{
struct
sockaddr_in6
*
sin6
,
*
sin6from
;
if
(
msgname
)
{
sockaddr_storage_t
*
addr
;
sctp_inet6_msgname
(
msgname
,
addrlen
);
sin6
=
(
struct
sockaddr_in6
*
)
msgname
;
sin6
->
sin6_port
=
htons
(
event
->
asoc
->
peer
.
port
);
addr
=
&
event
->
asoc
->
peer
.
primary_addr
;
/* Note: If we go to a common v6 format, this code
* will change.
*/
/* Map ipv4 address into v4-mapped-on-v6 address. */
if
(
AF_INET
==
addr
->
sa
.
sa_family
)
{
/* FIXME: Easy, but there was no way to test this
* yet.
*/
return
;
}
sin6from
=
&
event
->
asoc
->
peer
.
primary_addr
.
v6
;
ipv6_addr_copy
(
&
sin6
->
sin6_addr
,
&
sin6from
->
sin6_addr
);
}
}
/* Initialize a msg_name from an inbound skb. */
static
void
sctp_inet6_skb_msgname
(
struct
sk_buff
*
skb
,
char
*
msgname
,
int
*
addr_len
)
{
struct
sctphdr
*
sh
;
struct
sockaddr_in6
*
sin6
;
if
(
msgname
)
{
sctp_inet6_msgname
(
msgname
,
addr_len
);
sin6
=
(
struct
sockaddr_in6
*
)
msgname
;
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin6
->
sin6_port
=
sh
->
source
;
/* FIXME: Map ipv4 address into v4-mapped-on-v6 address. */
if
(
__constant_htons
(
ETH_P_IP
)
==
skb
->
protocol
)
{
/* FIXME: Easy, but there was no way to test this
* yet.
*/
return
;
}
/* Otherwise, just copy the v6 address. */
ipv6_addr_copy
(
&
sin6
->
sin6_addr
,
&
skb
->
nh
.
ipv6h
->
saddr
);
if
(
ipv6_addr_type
(
&
sin6
->
sin6_addr
)
&
IPV6_ADDR_LINKLOCAL
)
{
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
sin6
->
sin6_scope_id
=
opt
->
iif
;
}
}
}
static
struct
proto_ops
inet6_seqpacket_ops
=
{
.
family
=
PF_INET6
,
.
release
=
inet6_release
,
...
...
@@ -238,15 +312,22 @@ static sctp_func_t sctp_ipv6_specific = {
.
sa_family
=
AF_INET6
,
};
static
sctp_pf_t
sctp_pf_inet6_specific
=
{
.
event_msgname
=
sctp_inet6_event_msgname
,
.
skb_msgname
=
sctp_inet6_skb_msgname
,
};
/* Initialize IPv6 support and register with inet6 stack. */
int
sctp_v6_init
(
void
)
{
/* Add SCTPv6 to inetsw6 linked list. */
inet6_register_protosw
(
&
sctpv6_protosw
);
/* Register inet6 protocol. */
inet6_add_protocol
(
&
sctpv6_protocol
);
/* Register the SCTP specfic PF_INET6 functions. */
sctp_set_pf_specific
(
PF_INET6
,
&
sctp_pf_inet6_specific
);
/* Fill in address family info. */
INIT_LIST_HEAD
(
&
sctp_ipv6_specific
.
list
);
list_add_tail
(
&
sctp_ipv6_specific
.
list
,
&
sctp_proto
.
address_families
);
...
...
net/sctp/output.c
View file @
229e0840
...
...
@@ -129,7 +129,8 @@ void sctp_packet_free(sctp_packet_t *packet)
* as it can fit in the packet, but any more data that does not fit in this
* packet can be sent only after receiving the COOKIE_ACK.
*/
sctp_xmit_t
sctp_packet_transmit_chunk
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
sctp_xmit_t
sctp_packet_transmit_chunk
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
{
sctp_xmit_t
retval
;
int
error
=
0
;
...
...
@@ -181,8 +182,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
/* Both control chunks and data chunks with TSNs are
* non-fragmentable.
*/
int
fragmentable
=
sctp_chunk_is_data
(
chunk
)
&&
(
!
chunk
->
has_tsn
);
int
fragmentable
=
sctp_chunk_is_data
(
chunk
)
&&
(
!
chunk
->
has_tsn
);
if
(
packet_empty
)
{
if
(
fragmentable
)
{
retval
=
SCTP_XMIT_MUST_FRAG
;
...
...
@@ -221,10 +222,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
}
/* It is OK to send this chunk. */
skb_queue_tail
(
&
packet
->
chunks
,
(
struct
sk_buff
*
)
chunk
);
skb_queue_tail
(
&
packet
->
chunks
,
(
struct
sk_buff
*
)
chunk
);
packet
->
size
+=
chunk_len
;
finish:
return
retval
;
}
...
...
@@ -337,7 +336,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
}
/* Build the SCTP header. */
sh
=
(
struct
sctphdr
*
)
skb_push
(
nskb
,
sizeof
(
struct
sctphdr
));
sh
=
(
struct
sctphdr
*
)
skb_push
(
nskb
,
sizeof
(
struct
sctphdr
));
sh
->
source
=
htons
(
packet
->
source_port
);
sh
->
dest
=
htons
(
packet
->
destination_port
);
...
...
@@ -467,7 +466,8 @@ static void sctp_packet_reset(sctp_packet_t *packet)
}
/* This private function handles the specifics of appending DATA chunks. */
static
sctp_xmit_t
sctp_packet_append_data
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
static
sctp_xmit_t
sctp_packet_append_data
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
{
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
size_t
datasize
,
rwnd
,
inflight
;
...
...
@@ -502,12 +502,13 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
}
}
/* sctpimpguide-05 2.14.2 D) When the time comes for the sender to
/* sctpimpguide-05 2.14.2
* D) When the time comes for the sender to
* transmit new DATA chunks, the protocol parameter Max.Burst MUST
* first be applied to limit how many new DATA chunks may be sent.
* The limit is applied by adjusting cwnd as follows:
* if
((flightsize + Max.Burst*
MTU) < cwnd)
* cwnd = flightsize + Max.Burst
*
MTU
* if
((flightsize + Max.Burst *
MTU) < cwnd)
* cwnd = flightsize + Max.Burst
*
MTU
*/
max_burst_bytes
=
transport
->
asoc
->
max_burst
*
transport
->
asoc
->
pmtu
;
if
((
transport
->
flight_size
+
max_burst_bytes
)
<
transport
->
cwnd
)
{
...
...
@@ -552,7 +553,3 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
finish:
return
retval
;
}
net/sctp/outqueue.c
View file @
229e0840
...
...
@@ -196,23 +196,14 @@ int sctp_push_outqueue(sctp_outqueue_t *q, sctp_chunk_t *chunk)
return
error
;
}
/* Mark all the eligible packets on a transport for retransmission and force
* one packet out.
*/
void
sctp_retransmit
(
sctp_outqueue_t
*
q
,
sctp_transport_t
*
transport
,
/* Mark all the eligible packets on a transport for retransmission. */
void
sctp_retransmit_mark
(
sctp_outqueue_t
*
q
,
sctp_transport_t
*
transport
,
__u8
fast_retransmit
)
{
struct
list_head
*
lchunk
;
sctp_chunk_t
*
chunk
;
int
error
=
0
;
struct
list_head
tlist
;
if
(
fast_retransmit
)
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_FAST_RTX
);
}
else
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_T3_RTX
);
}
INIT_LIST_HEAD
(
&
tlist
);
while
(
!
list_empty
(
&
transport
->
transmitted
))
{
...
...
@@ -276,7 +267,26 @@ void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
transport
->
flight_size
,
transport
->
partial_bytes_acked
);
}
/* Mark all the eligible packets on a transport for retransmission and force
* one packet out.
*/
void
sctp_retransmit
(
sctp_outqueue_t
*
q
,
sctp_transport_t
*
transport
,
__u8
fast_retransmit
)
{
int
error
=
0
;
if
(
fast_retransmit
)
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_FAST_RTX
);
}
else
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_T3_RTX
);
}
sctp_retransmit_mark
(
q
,
transport
,
fast_retransmit
);
error
=
sctp_flush_outqueue
(
q
,
/* rtx_timeout */
1
);
if
(
error
)
q
->
asoc
->
base
.
sk
->
err
=
-
error
;
}
...
...
@@ -370,8 +380,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
/* The append was successful, so add this chunk to
* the transmitted list.
*/
list_add_tail
(
lchunk
,
&
transport
->
transmitted
);
list_add_tail
(
lchunk
,
&
transport
->
transmitted
);
*
start_timer
=
1
;
q
->
empty
=
0
;
...
...
@@ -389,8 +398,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
* chunk that is currently in the process of fragmentation.
*/
void
sctp_xmit_frag
(
sctp_outqueue_t
*
q
,
struct
sk_buff
*
pos
,
sctp_packet_t
*
packet
,
sctp_chunk_t
*
frag
,
__u32
tsn
)
sctp_packet_t
*
packet
,
sctp_chunk_t
*
frag
,
__u32
tsn
)
{
sctp_transport_t
*
transport
=
packet
->
transport
;
struct
sk_buff_head
*
queue
=
&
q
->
out
;
...
...
@@ -499,7 +507,8 @@ void sctp_xmit_fragmented_chunks(sctp_outqueue_t *q, sctp_packet_t *packet,
* fragments. It returns the first fragment with the frag_list field holding
* the remaining fragments.
*/
sctp_chunk_t
*
sctp_fragment_chunk
(
sctp_chunk_t
*
chunk
,
size_t
max_frag_data_len
)
sctp_chunk_t
*
sctp_fragment_chunk
(
sctp_chunk_t
*
chunk
,
size_t
max_frag_data_len
)
{
sctp_association_t
*
asoc
=
chunk
->
asoc
;
void
*
data_ptr
=
chunk
->
subh
.
data_hdr
;
...
...
@@ -533,11 +542,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len)
/* Make the middle fragments. */
while
(
chunk_data_len
>
max_frag_data_len
)
{
frag
=
sctp_make_datafrag
(
asoc
,
sinfo
,
max_frag_data_len
,
data_ptr
,
SCTP_DATA_MIDDLE_FRAG
,
ssn
);
data_ptr
,
SCTP_DATA_MIDDLE_FRAG
,
ssn
);
if
(
!
frag
)
goto
err
;
/* Add the middle fragment to the first fragment's frag_list. */
/* Add the middle fragment to the first fragment's
* frag_list.
*/
list_add_tail
(
&
frag
->
frag_list
,
frag_list
);
chunk_data_len
-=
max_frag_data_len
;
...
...
@@ -674,7 +686,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
(
void
)
(
*
q
->
build_output
)(
&
singleton
,
chunk
);
error
=
(
*
q
->
force_output
)(
&
singleton
);
if
(
error
<
0
)
return
(
error
)
;
return
error
;
break
;
case
SCTP_CID_ABORT
:
...
...
@@ -705,10 +717,10 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
/* Is it OK to send data chunks? */
switch
(
asoc
->
state
)
{
case
SCTP_STATE_COOKIE_ECHOED
:
/* Only allow bundling
, if
this packet has a COOKIE-ECHO
/* Only allow bundling
when
this packet has a COOKIE-ECHO
* chunk.
*/
if
(
packet
&&
!
packet
->
has_cookie_echo
)
if
(
!
packet
||
!
packet
->
has_cookie_echo
)
break
;
/* fallthru */
...
...
@@ -748,6 +760,12 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
if
(
start_timer
)
sctp_transport_reset_timers
(
transport
);
/* This can happen on COOKIE-ECHO resend. Only
* one chunk can get bundled with a COOKIE-ECHO.
*/
if
(
packet
->
has_cookie_echo
)
goto
sctp_flush_out
;
}
/* Finally, transmit new packets. */
...
...
@@ -813,8 +831,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
chunk
->
skb
?
chunk
->
skb
->
head
:
0
,
chunk
->
skb
?
atomic_read
(
&
chunk
->
skb
->
users
)
:
-
1
);
atomic_read
(
&
chunk
->
skb
->
users
)
:
-
1
);
/* Add the chunk to the packet. */
status
=
(
*
q
->
build_output
)(
packet
,
chunk
);
...
...
@@ -827,7 +844,8 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
*/
SCTP_DEBUG_PRINTK
(
"sctp_flush_outqueue: could"
"not transmit TSN: 0x%x, status: %d
\n
"
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
status
);
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
status
);
skb_queue_head
(
queue
,
(
struct
sk_buff
*
)
chunk
);
goto
sctp_flush_out
;
break
;
...
...
@@ -857,7 +875,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
default:
BUG
();
}
;
}
/* BUG: We assume that the (*q->force_output())
* call below will succeed all the time and add the
...
...
@@ -875,13 +893,19 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
sctp_transport_reset_timers
(
transport
);
q
->
empty
=
0
;
/* Only let one DATA chunk get bundled with a
* COOKIE-ECHO chunk.
*/
if
(
packet
->
has_cookie_echo
)
goto
sctp_flush_out
;
}
break
;
default:
/* Do nothing. */
break
;
}
;
}
sctp_flush_out:
/* Before returning, examine all the transports touched in
...
...
@@ -986,8 +1010,7 @@ int sctp_sack_outqueue(sctp_outqueue_t *q, sctp_sackhdr_t *sack)
ctsn
=
q
->
asoc
->
ctsn_ack_point
;
SCTP_DEBUG_PRINTK
(
"%s: sack Cumulative TSN Ack is 0x%x.
\n
"
,
__FUNCTION__
,
sack_ctsn
);
__FUNCTION__
,
sack_ctsn
);
SCTP_DEBUG_PRINTK
(
"%s: Cumulative TSN Ack of association "
"%p is 0x%x.
\n
"
,
__FUNCTION__
,
q
->
asoc
,
ctsn
);
...
...
@@ -1114,8 +1137,9 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* 6.3.1 C5) Karn's algorithm: RTT measurements
* MUST NOT be made using packets that were
* retransmitted (and thus for which it is
* ambiguous whether the reply was for the first
* instance of the packet or a later instance).
* ambiguous whether the reply was for the
* first instance of the packet or a later
* instance).
*/
if
((
!
tchunk
->
tsn_gap_acked
)
&&
(
1
==
tchunk
->
num_times_sent
)
&&
...
...
@@ -1150,15 +1174,15 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* 'Stray DATA chunk(s)' record the highest TSN
* reported as newly acknowledged, call this
* value 'HighestTSNinSack'. A newly
* acknowledged DATA chunk is one not
previously
* acknowledged in a SACK.
* acknowledged DATA chunk is one not
*
previously
acknowledged in a SACK.
*
* When the SCTP sender of data receives a SACK
* chunk that acknowledges, for the first time,
* the receipt of a DATA chunk, all the still
* unacknowledged DATA chunks whose TSN is
older
*
than that newly acknowledged DATA chunk, are
* qualified as 'Stray DATA chunks'.
* unacknowledged DATA chunks whose TSN is
*
older than that newly acknowledged DATA
*
chunk, are
qualified as 'Stray DATA chunks'.
*/
if
(
!
tchunk
->
tsn_gap_acked
)
{
tchunk
->
tsn_gap_acked
=
1
;
...
...
@@ -1217,8 +1241,8 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
}
else
{
if
(
tchunk
->
tsn_gap_acked
)
{
SCTP_DEBUG_PRINTK
(
"%s: Receiver reneged on
data
"
"TSN: 0x%x
\n
"
,
SCTP_DEBUG_PRINTK
(
"%s: Receiver reneged on "
"
data
TSN: 0x%x
\n
"
,
__FUNCTION__
,
tsn
);
tchunk
->
tsn_gap_acked
=
0
;
...
...
@@ -1227,10 +1251,11 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
/* RFC 2960 6.3.2 Retransmission Timer Rules
*
* R4) Whenever a SACK is received missing a TSN
* that was previously acknowledged via a Gap Ack
* Block, start T3-rtx for the destination
* address to which the DATA chunk was originally
* R4) Whenever a SACK is received missing a
* TSN that was previously acknowledged via a
* Gap Ack Block, start T3-rtx for the
* destination address to which the DATA
* chunk was originally
* transmitted if it is not already running.
*/
restart_timer
=
1
;
...
...
@@ -1306,7 +1331,8 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* active if it is not so marked.
*/
if
(
!
transport
->
state
.
active
)
{
sctp_assoc_control_transport
(
transport
->
asoc
,
sctp_assoc_control_transport
(
transport
->
asoc
,
transport
,
SCTP_TRANSPORT_UP
,
SCTP_RECEIVED_SACK
);
...
...
@@ -1398,8 +1424,7 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
SCTP_DEBUG_PRINTK
(
"%s: transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, pba: %d
\n
"
,
__FUNCTION__
,
transport
,
transport
->
cwnd
,
__FUNCTION__
,
transport
,
transport
->
cwnd
,
transport
->
ssthresh
,
transport
->
flight_size
,
transport
->
partial_bytes_acked
);
}
...
...
net/sctp/primitive.c
View file @
229e0840
net/sctp/protocol.c
View file @
229e0840
...
...
@@ -66,6 +66,9 @@ struct proc_dir_entry *proc_net_sctp;
*/
static
struct
socket
*
sctp_ctl_socket
;
static
sctp_pf_t
*
sctp_pf_inet6_specific
;
static
sctp_pf_t
*
sctp_pf_inet_specific
;
extern
struct
net_proto_family
inet_family_ops
;
/* Return the address of the control sock. */
...
...
@@ -91,7 +94,7 @@ void sctp_proc_init(void)
void
sctp_proc_exit
(
void
)
{
if
(
proc_net_sctp
)
{
proc_net_sctp
=
NULL
;
proc_net_sctp
=
NULL
;
remove_proc_entry
(
"net/sctp"
,
0
);
}
}
...
...
@@ -135,7 +138,8 @@ static inline void sctp_v4_get_local_addr_list(sctp_protocol_t *proto,
* the protocol structure.
* FIXME: Make this an address family function.
*/
static
inline
void
sctp_v6_get_local_addr_list
(
sctp_protocol_t
*
proto
,
struct
net_device
*
dev
)
static
inline
void
sctp_v6_get_local_addr_list
(
sctp_protocol_t
*
proto
,
struct
net_device
*
dev
)
{
#ifdef SCTP_V6_SUPPORT
/* FIXME: The testframe doesn't support this function. */
...
...
@@ -239,8 +243,7 @@ int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp,
(((
AF_INET6
==
addr
->
a
.
sa
.
sa_family
)
&&
(
copy_flags
&
SCTP_ADDR6_ALLOWED
)
&&
(
copy_flags
&
SCTP_ADDR6_PEERSUPP
))))
{
error
=
sctp_add_bind_addr
(
bp
,
&
addr
->
a
,
error
=
sctp_add_bind_addr
(
bp
,
&
addr
->
a
,
priority
);
if
(
error
)
goto
end_copy
;
...
...
@@ -286,7 +289,8 @@ int sctp_v4_get_dst_mtu(const sockaddr_storage_t *address)
/* Event handler for inet device events.
* Basically, whenever there is an event, we re-build our local address list.
*/
static
int
sctp_netdev_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
static
int
sctp_netdev_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
long
flags
__attribute__
((
unused
));
...
...
@@ -347,6 +351,52 @@ sctp_func_t *sctp_get_af_specific(const sockaddr_storage_t *address)
return
retval
;
}
/* Common code to initialize a AF_INET msg_name. */
static
void
sctp_inet_msgname
(
char
*
msgname
,
int
*
addr_len
)
{
struct
sockaddr_in
*
sin
;
sin
=
(
struct
sockaddr_in
*
)
msgname
;
*
addr_len
=
sizeof
(
struct
sockaddr_in
);
sin
->
sin_family
=
AF_INET
;
memset
(
sin
->
sin_zero
,
0
,
sizeof
(
sin
->
sin_zero
));
}
/* Copy the primary address of the peer primary address as the msg_name. */
static
void
sctp_inet_event_msgname
(
sctp_ulpevent_t
*
event
,
char
*
msgname
,
int
*
addr_len
)
{
struct
sockaddr_in
*
sin
,
*
sinfrom
;
if
(
msgname
)
{
sctp_inet_msgname
(
msgname
,
addr_len
);
sin
=
(
struct
sockaddr_in
*
)
msgname
;
sinfrom
=
&
event
->
asoc
->
peer
.
primary_addr
.
v4
;
sin
->
sin_port
=
htons
(
event
->
asoc
->
peer
.
port
);
sin
->
sin_addr
.
s_addr
=
sinfrom
->
sin_addr
.
s_addr
;
}
}
/* Initialize and copy out a msgname from an inbound skb. */
static
void
sctp_inet_skb_msgname
(
struct
sk_buff
*
skb
,
char
*
msgname
,
int
*
addr_len
)
{
struct
sctphdr
*
sh
;
struct
sockaddr_in
*
sin
;
if
(
msgname
)
{
sctp_inet_msgname
(
msgname
,
addr_len
);
sin
=
(
struct
sockaddr_in
*
)
msgname
;
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin
->
sin_port
=
sh
->
source
;
sin
->
sin_addr
.
s_addr
=
skb
->
nh
.
iph
->
saddr
;
}
}
static
sctp_pf_t
sctp_pf_inet
=
{
.
event_msgname
=
sctp_inet_event_msgname
,
.
skb_msgname
=
sctp_inet_skb_msgname
,
};
/* Registration for netdev events. */
struct
notifier_block
sctp_netdev_notifier
=
{
.
notifier_call
=
sctp_netdev_event
,
...
...
@@ -403,6 +453,34 @@ sctp_func_t sctp_ipv4_specific = {
.
sa_family
=
AF_INET
,
};
sctp_pf_t
*
sctp_get_pf_specific
(
int
family
)
{
switch
(
family
)
{
case
PF_INET
:
return
sctp_pf_inet_specific
;
case
PF_INET6
:
return
sctp_pf_inet6_specific
;
default:
return
NULL
;
}
}
/* Set the PF specific function table. */
void
sctp_set_pf_specific
(
int
family
,
sctp_pf_t
*
pf
)
{
switch
(
family
)
{
case
PF_INET
:
sctp_pf_inet_specific
=
pf
;
break
;
case
PF_INET6
:
sctp_pf_inet6_specific
=
pf
;
break
;
default:
BUG
();
break
;
}
}
/* Initialize the universe into something sensible. */
int
sctp_init
(
void
)
{
...
...
@@ -421,6 +499,8 @@ int sctp_init(void)
/* Initialize object count debugging. */
sctp_dbg_objcnt_init
();
/* Initialize the SCTP specific PF functions. */
sctp_set_pf_specific
(
PF_INET
,
&
sctp_pf_inet
);
/*
* 14. Suggested SCTP Protocol Parameter Values
*/
...
...
@@ -468,7 +548,7 @@ int sctp_init(void)
sctp_proto
.
assoc_hashbucket
=
(
sctp_hashbucket_t
*
)
kmalloc
(
4096
*
sizeof
(
sctp_hashbucket_t
),
GFP_KERNEL
);
if
(
!
sctp_proto
.
assoc_hashbucket
)
{
printk
(
KERN_ERR
"SCTP: Failed association hash alloc.
\n
"
);
printk
(
KERN_ERR
"SCTP: Failed association hash alloc.
\n
"
);
status
=
-
ENOMEM
;
goto
err_ahash_alloc
;
}
...
...
@@ -482,7 +562,7 @@ int sctp_init(void)
sctp_proto
.
ep_hashbucket
=
(
sctp_hashbucket_t
*
)
kmalloc
(
64
*
sizeof
(
sctp_hashbucket_t
),
GFP_KERNEL
);
if
(
!
sctp_proto
.
ep_hashbucket
)
{
printk
(
KERN_ERR
"SCTP: Failed endpoint_hash alloc.
\n
"
);
printk
(
KERN_ERR
"SCTP: Failed endpoint_hash alloc.
\n
"
);
status
=
-
ENOMEM
;
goto
err_ehash_alloc
;
}
...
...
@@ -497,7 +577,7 @@ int sctp_init(void)
sctp_proto
.
port_hashtable
=
(
sctp_bind_hashbucket_t
*
)
kmalloc
(
4096
*
sizeof
(
sctp_bind_hashbucket_t
),
GFP_KERNEL
);
if
(
!
sctp_proto
.
port_hashtable
)
{
printk
(
KERN_ERR
"SCTP: Failed bind hash alloc."
);
printk
(
KERN_ERR
"SCTP: Failed bind hash alloc."
);
status
=
-
ENOMEM
;
goto
err_bhash_alloc
;
}
...
...
net/sctp/sm_make_chunk.c
View file @
229e0840
...
...
@@ -1418,6 +1418,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
__u8
*
end
;
sctp_transport_t
*
transport
;
struct
list_head
*
pos
,
*
temp
;
char
*
cookie
;
/* We must include the address that the INIT packet came from.
* This is the only address that matters for an INIT packet.
...
...
@@ -1471,6 +1472,15 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
/* Peer Rwnd : Current calculated value of the peer's rwnd. */
asoc
->
peer
.
rwnd
=
asoc
->
peer
.
i
.
a_rwnd
;
/* Copy cookie in case we need to resend COOKIE-ECHO. */
cookie
=
asoc
->
peer
.
cookie
;
if
(
cookie
)
{
asoc
->
peer
.
cookie
=
kmalloc
(
asoc
->
peer
.
cookie_len
,
priority
);
if
(
!
asoc
->
peer
.
cookie
)
goto
clean_up
;
memcpy
(
asoc
->
peer
.
cookie
,
cookie
,
asoc
->
peer
.
cookie_len
);
}
/* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily
* high (for example, implementations MAY use the size of the receiver
* advertised window).
...
...
@@ -1560,7 +1570,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
break
;
case
SCTP_PARAM_HOST_NAME_ADDRESS
:
SCTP_DEBUG_PRINTK
(
"unimplmented SCTP_HOST_NAME_ADDRESS
\n
"
);
SCTP_DEBUG_PRINTK
(
"unimpl
e
mented SCTP_HOST_NAME_ADDRESS
\n
"
);
break
;
case
SCTP_PARAM_SUPPORTED_ADDRESS_TYPES
:
...
...
@@ -1595,13 +1605,12 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
case
SCTP_PARAM_STATE_COOKIE
:
asoc
->
peer
.
cookie_len
=
ntohs
(
param
.
p
->
length
)
-
sizeof
(
sctp_paramhdr_t
);
ntohs
(
param
.
p
->
length
)
-
sizeof
(
sctp_paramhdr_t
);
asoc
->
peer
.
cookie
=
param
.
cookie
->
body
;
break
;
case
SCTP_PARAM_HEATBEAT_INFO
:
SCTP_DEBUG_PRINTK
(
"unimplmented "
SCTP_DEBUG_PRINTK
(
"unimpl
e
mented "
"SCTP_PARAM_HEATBEAT_INFO
\n
"
);
break
;
...
...
net/sctp/sm_sideeffect.c
View file @
229e0840
...
...
@@ -253,6 +253,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
sctp_chunk_t
*
new_obj
;
sctp_chunk_t
*
chunk
;
sctp_packet_t
*
packet
;
struct
list_head
*
pos
;
struct
timer_list
*
timer
;
unsigned
long
timeout
;
sctp_transport_t
*
t
;
...
...
@@ -336,9 +337,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
case
SCTP_CMD_PEER_INIT
:
/* Process a unified INIT from the peer. */
sctp_cmd_process_init
(
commands
,
asoc
,
chunk
,
command
->
obj
.
ptr
,
priority
);
sctp_cmd_process_init
(
commands
,
asoc
,
chunk
,
command
->
obj
.
ptr
,
priority
);
break
;
case
SCTP_CMD_GEN_COOKIE_ECHO
:
...
...
@@ -462,6 +462,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
break
;
case
SCTP_CMD_INIT_RESTART
:
/* Do the needed accounting and updates
* associated with restarting an initialization
* timer.
...
...
@@ -474,6 +475,15 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
asoc
->
max_init_timeo
;
}
/* If we've sent any data bundled with
* COOKIE-ECHO we need to resend.
*/
list_for_each
(
pos
,
&
asoc
->
peer
.
transport_addr_list
)
{
t
=
list_entry
(
pos
,
sctp_transport_t
,
transports
);
sctp_retransmit_mark
(
&
asoc
->
outqueue
,
t
,
0
);
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
command
->
obj
.
to
));
...
...
@@ -867,6 +877,14 @@ void sctp_generate_t2_shutdown_event(unsigned long data)
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
);
}
void
sctp_generate_t5_shutdown_guard_event
(
unsigned
long
data
)
{
sctp_association_t
*
asoc
=
(
sctp_association_t
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
);
}
/* sctp_generate_t5_shutdown_guard_event() */
void
sctp_generate_autoclose_event
(
unsigned
long
data
)
{
sctp_association_t
*
asoc
=
(
sctp_association_t
*
)
data
;
...
...
@@ -932,6 +950,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
sctp_generate_t2_shutdown_event
,
NULL
,
NULL
,
sctp_generate_t5_shutdown_guard_event
,
sctp_generate_heartbeat_event
,
sctp_generate_sack_event
,
sctp_generate_autoclose_event
,
...
...
@@ -1023,6 +1042,9 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
event
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
/* FIXME: We need to handle data that could not be sent or was not
* acked, if the user has enabled SEND_FAILED notifications.
*/
...
...
net/sctp/sm_statefuns.c
View file @
229e0840
...
...
@@ -149,6 +149,9 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
...
...
@@ -160,35 +163,6 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* Discard the whole packet.
*
* Section: 8.4 2)
*
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action.
* Otherwise,
*
* Verification Tag: No verification necessary
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_pdiscard
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
/*
* Respond to a normal INIT chunk.
* We are the side that is being asked for an association.
...
...
@@ -338,20 +312,17 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
if
(
!
reply
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
}
/* Tag the variable length paramters. Note that we never
* convert the parameters in an INIT chunk.
*/
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
initchunk
=
(
sctp_init_chunk_t
*
)
chunk
->
chunk_hdr
;
...
...
@@ -460,8 +431,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const sctp_endpoint_t *ep,
case
-
SCTP_IERROR_BAD_SIG
:
default:
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
};
}
...
...
@@ -625,8 +595,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const sctp_endpoint_t *ep,
if
(
!
reply
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
/* Set transport error counter and association error counter
* when sending heartbeat.
...
...
@@ -779,8 +748,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep,
* sent and mark the destination transport address as active if
* it is not so marked.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_ON
,
SCTP_TRANSPORT
(
link
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_ON
,
SCTP_TRANSPORT
(
link
));
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -875,8 +843,10 @@ static char sctp_tietags_compare(sctp_association_t *new_asoc,
/* Common helper routine for both duplicate and simulataneous INIT
* chunk handling.
*/
static
sctp_disposition_t
sctp_sf_do_unexpected_init
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
static
sctp_disposition_t
sctp_sf_do_unexpected_init
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
chunk
=
arg
;
...
...
@@ -894,8 +864,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
chunk
->
subh
.
init_hdr
=
(
sctp_inithdr_t
*
)
chunk
->
skb
->
data
;
/* Tag the variable length parameters. */
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
/*
* Other parameters for the endpoint SHOULD be copied from the
...
...
@@ -912,10 +881,9 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
* Verification Tag and Peers Verification tag into a reserved
* place (local tie-tag and per tie-tag) within the state cookie.
*/
sctp_process_init
(
new_asoc
,
chunk
->
chunk_hdr
->
type
,
sctp_source
(
chunk
),
(
sctp_init_chunk_t
*
)
chunk
->
chunk_hdr
,
GFP_ATOMIC
);
sctp_process_init
(
new_asoc
,
chunk
->
chunk_hdr
->
type
,
sctp_source
(
chunk
),
(
sctp_init_chunk_t
*
)
chunk
->
chunk_hdr
,
GFP_ATOMIC
);
sctp_tietags_populate
(
new_asoc
,
asoc
);
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
...
...
@@ -1323,10 +1291,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
/* "Decode" the chunk. We have no optional parameters so we
* are in good shape.
*/
chunk
->
subh
.
cookie_hdr
=
(
sctp_signed_cookie_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
ntohs
(
chunk
->
chunk_hdr
->
length
)
-
sizeof
(
sctp_chunkhdr_t
));
chunk
->
subh
.
cookie_hdr
=
(
sctp_signed_cookie_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
ntohs
(
chunk
->
chunk_hdr
->
length
)
-
sizeof
(
sctp_chunkhdr_t
));
/* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
* of a duplicate COOKIE ECHO match the Verification Tags of the
...
...
@@ -1351,8 +1318,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
case
-
SCTP_IERROR_BAD_SIG
:
default:
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
};
}
...
...
@@ -1398,6 +1364,65 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* Process an ABORT. (SHUTDOWN-PENDING state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t
sctp_sf_shutdown_pending_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* Process an ABORT. (SHUTDOWN-SENT state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t
sctp_sf_shutdown_sent_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* Process an ABORT. (SHUTDOWN-ACK-SENT state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t
sctp_sf_shutdown_ack_sent_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
return
sctp_sf_shutdown_sent_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
#if 0
/*
* Handle a Stale COOKIE Error
...
...
@@ -1540,11 +1565,8 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Check the verification tag. */
/* BUG: WRITE ME. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
/* ASSOC_FAILED will DELETE_TCB. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
/* BUG? This does not look complete... */
return
SCTP_DISPOSITION_ABORT
;
...
...
@@ -1561,15 +1583,19 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Check the verification tag. */
/* BUG: WRITE ME. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_INIT
));
/* CMD_INIT_FAILED will DELETE_TCB. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
/* BUG? This does not look complete... */
return
SCTP_DISPOSITION_ABORT
;
}
/*
...
...
@@ -1589,67 +1615,6 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const sctp_endpoint_t *ep,
return
sctp_sf_cookie_wait_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
#if 0
/*
* Handle a shutdown timeout or INIT during a shutdown phase.
*
* Section: 9.2
* If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
* (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
* transport addresses (either in the IP addresses or in the INIT chunk)
* that belong to this association, it should discard the INIT chunk and
* retransmit the SHUTDOWN ACK chunk.
*...
* While in SHUTDOWN-SENT state ... If the timer expires, the endpoint
* must re-send the SHUTDOWN ACK.
*
* Verification Tag: Neither the INIT nor the timeout will have a
* valid verification tag, so it is safe to ignore.
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t sctp_do_9_2_reshutack(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_chunk_t *chunk = arg;
/* If this was a timeout (not an INIT), then do the counter
* work. We might need to just dump the association.
*/
if (!chunk) {
if (1 + asoc->counters[SctpCounterRetran] >
asoc->maxRetrans) {
sctp_add_cmd(commands, SCTP_CMD_DELETE_TCB,
SCTP_NULL());
return SCTP_DISPOSITION_DELETE_TCB;
}
retval->counters[0] = SCTP_COUNTER_INCR;
retval->counters[0] = SctpCounterRetran;
retval->counters[1] = 0;
retval->counters[1] = 0;
}
reply = sctp_make_shutdown_ack(asoc, chunk);
if (!reply)
goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
return SCTP_DISPOSITION_CONSUME;
nomem:
return SCTP_DISPOSITION_NOMEM;
}
#endif /* 0 */
/*
* sctp_sf_do_9_2_shut
*
...
...
@@ -1694,7 +1659,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
sctp_disposition_t
disposition
;
/* Convert the elaborate header. */
sdh
=
(
sctp_shutdownhdr_t
*
)
chunk
->
skb
->
data
;
sdh
=
(
sctp_shutdownhdr_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_shutdownhdr_t
));
chunk
->
subh
.
shutdown_hdr
=
sdh
;
...
...
@@ -1718,8 +1683,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
disposition
=
SCTP_DISPOSITION_CONSUME
;
if
(
sctp_outqueue_is_empty
(
&
asoc
->
outqueue
))
{
disposition
=
sctp_sf_do_9_2_shutdown_ack
(
ep
,
asoc
,
type
,
disposition
=
sctp_sf_do_9_2_shutdown_ack
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
...
...
@@ -1732,6 +1696,42 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
return
disposition
;
}
/* RFC 2960 9.2
* If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
* (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
* transport addresses (either in the IP addresses or in the INIT chunk)
* that belong to this association, it should discard the INIT chunk and
* retransmit the SHUTDOWN ACK chunk.
*/
sctp_disposition_t
sctp_sf_do_9_2_reshutack
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
chunk
=
(
sctp_chunk_t
*
)
arg
;
sctp_chunk_t
*
reply
;
reply
=
sctp_make_shutdown_ack
(
asoc
,
chunk
);
if
(
NULL
==
reply
)
goto
nomem
;
/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
* the T2-SHUTDOWN timer.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SETUP_T2
,
SCTP_CHUNK
(
reply
));
/* and restart the T2-shutdown timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
return
SCTP_DISPOSITION_CONSUME
;
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* sctp_sf_do_ecn_cwr
*
...
...
@@ -1979,9 +1979,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep,
* processing the rest of the chunks in the packet.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -2185,9 +2183,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const sctp_endpoint_t *ep,
* processing the rest of the chunks in the packet.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -2296,14 +2292,12 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const sctp_endpoint_t *ep,
*/
if
(
TSN_lt
(
ctsn
,
asoc
->
ctsn_ack_point
))
{
SCTP_DEBUG_PRINTK
(
"ctsn %x
\n
"
,
ctsn
);
SCTP_DEBUG_PRINTK
(
"ctsn_ack_point %x
\n
"
,
asoc
->
ctsn_ack_point
);
SCTP_DEBUG_PRINTK
(
"ctsn_ack_point %x
\n
"
,
asoc
->
ctsn_ack_point
);
return
SCTP_DISPOSITION_DISCARD
;
}
/* Return this SACK for further processing. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_PROCESS_SACK
,
SCTP_SACKH
(
sackh
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_PROCESS_SACK
,
SCTP_SACKH
(
sackh
));
/* Note: We do the rest of the work on the PROCESS_SACK
* sideeffect.
...
...
@@ -2410,7 +2404,8 @@ sctp_disposition_t sctp_sf_operr_notify(const sctp_endpoint_t *ep,
sctp_ulpevent_t
*
ev
;
while
(
chunk
->
chunk_end
>
chunk
->
skb
->
data
)
{
ev
=
sctp_ulpevent_make_remote_error
(
asoc
,
chunk
,
0
,
GFP_ATOMIC
);
ev
=
sctp_ulpevent_make_remote_error
(
asoc
,
chunk
,
0
,
GFP_ATOMIC
);
if
(
!
ev
)
goto
nomem
;
...
...
@@ -2464,6 +2459,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
/* ...send a SHUTDOWN COMPLETE chunk to its peer, */
reply
=
sctp_make_shutdown_complete
(
asoc
,
chunk
);
if
(
!
reply
)
...
...
@@ -2616,6 +2614,148 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const sctp_endpoint_t *ep,
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* Process an unknown chunk.
*
* Section: 3.2. Also, 2.1 in the implementor's guide.
*
* Chunk Types are encoded such that the highest-order two bits specify
* the action that must be taken if the processing endpoint does not
* recognize the Chunk Type.
*
* 00 - Stop processing this SCTP packet and discard it, do not process
* any further chunks within it.
*
* 01 - Stop processing this SCTP packet and discard it, do not process
* any further chunks within it, and report the unrecognized
* chunk in an 'Unrecognized Chunk Type'.
*
* 10 - Skip this chunk and continue processing.
*
* 11 - Skip this chunk and continue processing, but report in an ERROR
* Chunk using the 'Unrecognized Chunk Type' cause of error.
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_unk_chunk
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
unk_chunk
=
arg
;
sctp_chunk_t
*
err_chunk
;
sctp_chunkhdr_t
*
hdr
;
SCTP_DEBUG_PRINTK
(
"Processing the unknown chunk id %d.
\n
"
,
type
.
chunk
);
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet.
*/
if
(
ntohl
(
unk_chunk
->
sctp_hdr
->
vtag
)
!=
asoc
->
c
.
my_vtag
)
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
switch
(
type
.
chunk
&
SCTP_CID_ACTION_MASK
)
{
case
SCTP_CID_ACTION_DISCARD
:
/* Discard the packet. */
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
break
;
case
SCTP_CID_ACTION_DISCARD_ERR
:
/* Discard the packet. */
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
/* Generate an ERROR chunk as response. */
hdr
=
unk_chunk
->
chunk_hdr
;
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
WORD_ROUND
(
ntohs
(
hdr
->
length
)));
if
(
err_chunk
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err_chunk
));
}
return
SCTP_DISPOSITION_CONSUME
;
break
;
case
SCTP_CID_ACTION_SKIP
:
/* Skip the chunk. */
return
SCTP_DISPOSITION_DISCARD
;
break
;
case
SCTP_CID_ACTION_SKIP_ERR
:
/* Generate an ERROR chunk as response. */
hdr
=
unk_chunk
->
chunk_hdr
;
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
WORD_ROUND
(
ntohs
(
hdr
->
length
)));
if
(
err_chunk
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err_chunk
));
}
/* Skip the chunk. */
return
SCTP_DISPOSITION_CONSUME
;
break
;
default:
break
;
}
return
SCTP_DISPOSITION_DISCARD
;
}
/*
* Discard the chunk.
*
* Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
* [Too numerous to mention...]
* Verification Tag: No verification needed.
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_discard_chunk
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
SCTP_DEBUG_PRINTK
(
"Chunk %d is discarded
\n
"
,
type
.
chunk
);
return
SCTP_DISPOSITION_DISCARD
;
}
/*
* Discard the whole packet.
*
* Section: 8.4 2)
*
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action.
* Otherwise,
*
* Verification Tag: No verification necessary
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_pdiscard
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
#if 0
/*
...
...
@@ -2976,10 +3116,16 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_SHUTDOWN_PENDING
));
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_START
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
disposition
=
SCTP_DISPOSITION_CONSUME
;
if
(
sctp_outqueue_is_empty
(
&
asoc
->
outqueue
))
{
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
return
disposition
;
...
...
@@ -3042,12 +3188,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(const sctp_endpoint_t *ep,
* TCB. This is a departure from our typical NOMEM handling.
*/
/* Change to CLOSED state. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
/* Delete the established association. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_
DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_
ASSOC_FAILED
,
SCTP_NULL
());
return
retval
;
}
...
...
@@ -3090,7 +3232,8 @@ sctp_disposition_t sctp_sf_error_shutdown(const sctp_endpoint_t *ep,
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_cookie_wait_prm_shutdown
(
const
sctp_endpoint_t
*
ep
,
sctp_disposition_t
sctp_sf_cookie_wait_prm_shutdown
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
...
...
@@ -3134,7 +3277,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
}
/*
* sctp_cookie_wait_prm_abort
* sctp_
sf_
cookie_wait_prm_abort
*
* Section: 4 Note: 2
* Verification Tag:
...
...
@@ -3153,14 +3296,36 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
abort
;
sctp_disposition_t
retval
;
/* Stop T1-init timer */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_INIT
));
return
sctp_sf_do_9_1_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
retval
=
SCTP_DISPOSITION_CONSUME
;
/* Generate ABORT chunk to send the peer */
abort
=
sctp_make_abort
(
asoc
,
NULL
,
0
);
if
(
!
abort
)
retval
=
SCTP_DISPOSITION_NOMEM
;
else
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
abort
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
/* Even if we can't send the ABORT due to low memory delete the
* TCB. This is a departure from our typical NOMEM handling.
*/
/* Delete the established association. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
return
retval
;
}
/*
* sctp_cookie_echoed_prm_abort
* sctp_
sf_
cookie_echoed_prm_abort
*
* Section: 4 Note: 3
* Verification Tag:
...
...
@@ -3185,6 +3350,87 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(const sctp_endpoint_t *ep,
return
sctp_sf_cookie_wait_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* sctp_sf_shutdown_pending_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explicitly address this issue, but is the route through the
* state table when someone issues an abort while in SHUTDOWN-PENDING state.
*
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_shutdown_pending_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* sctp_sf_shutdown_sent_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explicitly address this issue, but is the route through the
* state table when someone issues an abort while in SHUTDOWN-SENT state.
*
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_shutdown_sent_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* sctp_sf_cookie_echoed_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explcitly address this issue, but is the route through the
* state table when someone issues an abort while in COOKIE_ECHOED state.
*
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_shutdown_ack_sent_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
return
sctp_sf_shutdown_sent_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* Ignore the primitive event
*
...
...
@@ -3322,8 +3568,7 @@ sctp_disposition_t sctp_sf_ignore_other(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
SCTP_DEBUG_PRINTK
(
"The event other type %d is ignored
\n
"
,
type
.
other
);
SCTP_DEBUG_PRINTK
(
"The event other type %d is ignored
\n
"
,
type
.
other
);
return
SCTP_DISPOSITION_DISCARD
;
}
...
...
@@ -3479,11 +3724,11 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const sctp_endpoint_t *ep,
if
(
!
repl
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
/* Issue a sideeffect to do the needed accounting. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_RESTART
,
SCTP_TO
(
timer
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
}
else
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
...
...
@@ -3559,6 +3804,34 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_NOMEM
;
}
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
* At the expiration of this timer the sender SHOULD abort the association
* by sending an ABORT chunk.
*/
sctp_disposition_t
sctp_sf_t5_timer_expire
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
reply
=
NULL
;
SCTP_DEBUG_PRINTK
(
"Timer T5 expired.
\n
"
);
reply
=
sctp_make_abort
(
asoc
,
NULL
,
0
);
if
(
!
reply
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
/* Handle expiration of AUTOCLOSE timer. When the autoclose timer expires,
* the association is automatically closed by starting the shutdown process.
* The work that needs to be done is same as when SHUTDOWN is initiated by
...
...
@@ -3583,10 +3856,15 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_SHUTDOWN_PENDING
));
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_START
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
disposition
=
SCTP_DISPOSITION_CONSUME
;
if
(
sctp_outqueue_is_empty
(
&
asoc
->
outqueue
))
{
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
return
disposition
;
...
...
@@ -3651,30 +3929,6 @@ sctp_disposition_t sctp_sf_timer_ignore(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_CONSUME
;
}
/*
* Discard the chunk.
*
* Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
* [Too numerous to mention...]
* Verification Tag: No verification needed.
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_discard_chunk
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
SCTP_DEBUG_PRINTK
(
"Chunk %d is discarded
\n
"
,
type
.
chunk
);
return
SCTP_DISPOSITION_DISCARD
;
}
/********************************************************************
* 2nd Level Abstractions
********************************************************************/
...
...
net/sctp/sm_statetable.c
View file @
229e0840
...
...
@@ -48,9 +48,10 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
sctp_sm_table_entry_t
nop
=
{
fn
:
sctp_sf_discard_chunk
,
name:
"sctp_sf_discard_chunk"
};
sctp_sm_table_entry_t
bug
=
{
fn
:
sctp_sf_bug
,
name
:
"sctp_sf_bug"
};
sctp_sm_table_entry_t
bug
=
{
.
fn
=
sctp_sf_bug
,
.
name
=
"sctp_sf_bug"
};
#define DO_LOOKUP(_max, _type, _table) \
if ((event_subtype._type > (_max))) { \
...
...
@@ -58,9 +59,9 @@ sctp_sm_table_entry_t bug = {fn: sctp_sf_bug, name: "sctp_sf_bug"};
"sctp table %p possible attack:" \
" event %d exceeds max %d\n", \
_table, event_subtype._type, _max); \
return
(&bug)
; \
return
&bug
; \
} \
return
(&_table[event_subtype._type][(int)state])
;
return
&_table[event_subtype._type][(int)state]
;
sctp_sm_table_entry_t
*
sctp_sm_lookup_event
(
sctp_event_t
event_type
,
sctp_state_t
state
,
...
...
@@ -92,320 +93,323 @@ sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
#define TYPE_SCTP_DATA { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_eat_data_6_2, name:
"sctp_sf_eat_data_6_2"}, \
{
.fn = sctp_sf_eat_data_6_2, .name =
"sctp_sf_eat_data_6_2"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_eat_data_6_2, name:
"sctp_sf_eat_data_6_2"}, \
{
.fn = sctp_sf_eat_data_6_2, .name =
"sctp_sf_eat_data_6_2"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_eat_data_fast_4_4, name:
"sctp_sf_eat_data_fast_4_4"}, \
{
.fn = sctp_sf_eat_data_fast_4_4, .name =
"sctp_sf_eat_data_fast_4_4"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_DATA */
#define TYPE_SCTP_INIT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_do_5_1B_init, name:
"sctp_sf_do_5_1B_init"}, \
{
.fn = sctp_sf_do_5_1B_init, .name =
"sctp_sf_do_5_1B_init"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_5_2_1_siminit, name:
"sctp_sf_do_5_2_1_siminit"}, \
{
.fn = sctp_sf_do_5_2_1_siminit, .name =
"sctp_sf_do_5_2_1_siminit"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_5_2_1_siminit, name:
"sctp_sf_do_5_2_1_siminit"}, \
{
.fn = sctp_sf_do_5_2_1_siminit, .name =
"sctp_sf_do_5_2_1_siminit"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_do_9_2_reshutack, .name = "sctp_sf_do_9_2_reshutack
"}, \
}
/* TYPE_SCTP_INIT */
#define TYPE_SCTP_INIT_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_5_1C_ack, name:
"sctp_sf_do_5_1C_ack"}, \
{
.fn = sctp_sf_do_5_1C_ack, .name =
"sctp_sf_do_5_1C_ack"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_INIT_ACK */
#define TYPE_SCTP_SACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_SACK */
#define TYPE_SCTP_HEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
/* This should not happen, but we are nice. */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
}
/* TYPE_SCTP_HEARTBEAT */
#define TYPE_SCTP_HEARTBEAT_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_HEARTBEAT_ACK */
#define TYPE_SCTP_ABORT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_pdiscard, name:
"sctp_sf_pdiscard"}, \
{
.fn = sctp_sf_pdiscard, .name =
"sctp_sf_pdiscard"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_cookie_wait_abort, name:
"sctp_sf_cookie_wait_abort"}, \
{
.fn = sctp_sf_cookie_wait_abort, .name =
"sctp_sf_cookie_wait_abort"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn:
sctp_sf_cookie_echoed_abort, \
name:
"sctp_sf_cookie_echoed_abort"}, \
{
.fn =
sctp_sf_cookie_echoed_abort, \
.name =
"sctp_sf_cookie_echoed_abort"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_9_1_abort, name:
"sctp_sf_do_9_1_abort"}, \
{
.fn = sctp_sf_do_9_1_abort, .name =
"sctp_sf_do_9_1_abort"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
{.fn = sctp_sf_shutdown_pending_abort, \
.name = "sctp_sf_shutdown_pending_abort"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
{.fn = sctp_sf_shutdown_sent_abort, \
.name = "sctp_sf_shutdown_sent_abort"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_9_1_abort, name:
"sctp_sf_do_9_1_abort"}, \
{
.fn = sctp_sf_do_9_1_abort, .name =
"sctp_sf_do_9_1_abort"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
{.fn = sctp_sf_shutdown_ack_sent_abort, \
.name = "sctp_sf_shutdown_ack_sent_abort"}, \
}
/* TYPE_SCTP_ABORT */
#define TYPE_SCTP_SHUTDOWN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_9_2_shutdown, name:
"sctp_sf_do_9_2_shutdown"}, \
{
.fn = sctp_sf_do_9_2_shutdown, .name =
"sctp_sf_do_9_2_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn:
sctp_sf_do_9_2_shutdown_ack, \
name:
"sctp_sf_do_9_2_shutdown_ack"}, \
{
.fn =
sctp_sf_do_9_2_shutdown_ack, \
.name =
"sctp_sf_do_9_2_shutdown_ack"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_SHUTDOWN */
#define TYPE_SCTP_SHUTDOWN_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_ootb, .name = "sctp_sf_ootb
"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_ootb, .name = "sctp_sf_ootb
"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_9_2_final, name:
"sctp_sf_do_9_2_final"}, \
{
.fn = sctp_sf_do_9_2_final, .name =
"sctp_sf_do_9_2_final"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_9_2_final, name:
"sctp_sf_do_9_2_final"}, \
{
.fn = sctp_sf_do_9_2_final, .name =
"sctp_sf_do_9_2_final"}, \
}
/* TYPE_SCTP_SHUTDOWN_ACK */
#define TYPE_SCTP_ERROR { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_operr_notify, name:
"sctp_sf_operr_notify"}, \
{
.fn = sctp_sf_operr_notify, .name =
"sctp_sf_operr_notify"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_ERROR */
#define TYPE_SCTP_COOKIE_ECHO { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_do_5_1D_ce, name:
"sctp_sf_do_5_1D_ce"}, \
{
.fn = sctp_sf_do_5_1D_ce, .name =
"sctp_sf_do_5_1D_ce"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
}
/* TYPE_SCTP_COOKIE_ECHO */
#define TYPE_SCTP_COOKIE_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_5_1E_ca, name:
"sctp_sf_do_5_1E_ca"}, \
{
.fn = sctp_sf_do_5_1E_ca, .name =
"sctp_sf_do_5_1E_ca"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_COOKIE_ACK */
#define TYPE_SCTP_ECN_ECNE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
}
/* TYPE_SCTP_ECN_ECNE */
#define TYPE_SCTP_ECN_CWR { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_ecn_cwr, name:
"sctp_sf_do_ecn_cwr"}, \
{
.fn = sctp_sf_do_ecn_cwr, .name =
"sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_ecn_cwr, name:
"sctp_sf_do_ecn_cwr"}, \
{
.fn = sctp_sf_do_ecn_cwr, .name =
"sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_ecn_cwr, name:
"sctp_sf_do_ecn_cwr"}, \
{
.fn = sctp_sf_do_ecn_cwr, .name =
"sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
}
/* TYPE_SCTP_ECN_CWR */
#define TYPE_SCTP_SHUTDOWN_COMPLETE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_4_C, name:
"sctp_sf_do_4_C"}, \
{
.fn = sctp_sf_do_4_C, .name =
"sctp_sf_do_4_C"}, \
}
/* TYPE_SCTP_SHUTDOWN_COMPLETE */
/* The primary index for this table is the chunk type.
...
...
@@ -434,397 +438,415 @@ sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NU
static
sctp_sm_table_entry_t
chunk_event_table_asconf
[
SCTP_STATE_NUM_STATES
]
=
{
/* SCTP_STATE_EMPTY */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_CLOSED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_WAIT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{
fn
:
sctp_sf_discard_chunk
,
name:
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"
},
/* SCTP_STATE_SHUTDOWN_PENDING */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
};
/* chunk asconf */
static
sctp_sm_table_entry_t
chunk_event_table_asconf_ack
[
SCTP_STATE_NUM_STATES
]
=
{
/* SCTP_STATE_EMPTY */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_CLOSED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_WAIT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{
fn
:
sctp_sf_discard_chunk
,
name:
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"
},
/* SCTP_STATE_SHUTDOWN_PENDING */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
};
/* chunk asconf_ack */
static
sctp_sm_table_entry_t
chunk_event_table_unknown
[
SCTP_STATE_NUM_STATES
]
=
{
/* SCTP_STATE_EMPTY */
{.
fn
=
sctp_sf_ootb
,
.
name
=
"sctp_sf_ootb"
},
/* SCTP_STATE_CLOSED */
{.
fn
=
sctp_sf_tabort_8_4_8
,
.
name
=
"sctp_sf_tabort_8_4_8"
},
/* SCTP_STATE_COOKIE_WAIT */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_PENDING */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
};
/* chunk unknown */
#define TYPE_SCTP_PRIMITIVE_INITIALIZE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_INITIALIZE */
#define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_do_prm_asoc, name:
"sctp_sf_do_prm_asoc"}, \
{
.fn = sctp_sf_do_prm_asoc, .name =
"sctp_sf_do_prm_asoc"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_ASSOCIATE */
#define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_error_closed, name:
"sctp_sf_error_closed"}, \
{
.fn = sctp_sf_error_closed, .name =
"sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn:
sctp_sf_cookie_wait_prm_shutdown, \
name:
"sctp_sf_cookie_wait_prm_shutdown"}, \
{
.fn =
sctp_sf_cookie_wait_prm_shutdown, \
.name =
"sctp_sf_cookie_wait_prm_shutdown"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn:
sctp_sf_cookie_echoed_prm_shutdown, \
{
.fn =
sctp_sf_cookie_echoed_prm_shutdown, \
name:"sctp_sf_cookie_echoed_prm_shutdown"},\
/* SCTP_STATE_ESTABLISHED */
\
{
fn:
sctp_sf_do_9_2_prm_shutdown, \
name:
"sctp_sf_do_9_2_prm_shutdown"}, \
{
.fn =
sctp_sf_do_9_2_prm_shutdown, \
.name =
"sctp_sf_do_9_2_prm_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
}
/* TYPE_SCTP_PRIMITIVE_SHUTDOWN */
#define TYPE_SCTP_PRIMITIVE_ABORT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_error_closed, name:
"sctp_sf_error_closed"}, \
{
.fn = sctp_sf_error_closed, .name =
"sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn:
sctp_sf_cookie_wait_prm_abort, \
name:
"sctp_sf_cookie_wait_prm_abort"}, \
{
.fn =
sctp_sf_cookie_wait_prm_abort, \
.name =
"sctp_sf_cookie_wait_prm_abort"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn:
sctp_sf_cookie_echoed_prm_abort, \
name:
"sctp_sf_cookie_echoed_prm_abort"}, \
{
.fn =
sctp_sf_cookie_echoed_prm_abort, \
.name =
"sctp_sf_cookie_echoed_prm_abort"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn:
sctp_sf_do_9_1_prm_abort, \
name:
"sctp_sf_do_9_1_prm_abort"}, \
{
.fn =
sctp_sf_do_9_1_prm_abort, \
.name =
"sctp_sf_do_9_1_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_9_1
_prm_abort, \
name: "sctp_sf_do_9_1
_prm_abort"}, \
{
.fn = sctp_sf_shutdown_pending
_prm_abort, \
.name = "sctp_sf_shutdown_pending
_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_9_1
_prm_abort, \
name: "sctp_sf_do_9_1
_prm_abort"}, \
{
.fn = sctp_sf_shutdown_sent
_prm_abort, \
.name = "sctp_sf_shutdown_sent
_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn:
sctp_sf_do_9_1_prm_abort, \
name:
"sctp_sf_do_9_1_prm_abort"}, \
{
.fn =
sctp_sf_do_9_1_prm_abort, \
.name =
"sctp_sf_do_9_1_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_9_1
_prm_abort, \
name: "sctp_sf_do_9_1
_prm_abort"}, \
{
.fn = sctp_sf_shutdown_ack_sent
_prm_abort, \
.name = "sctp_sf_shutdown_ack_sent
_prm_abort"}, \
}
/* TYPE_SCTP_PRIMITIVE_ABORT */
#define TYPE_SCTP_PRIMITIVE_SEND { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_error_closed, name:
"sctp_sf_error_closed"}, \
{
.fn = sctp_sf_error_closed, .name =
"sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_prm_send, name:
"sctp_sf_do_prm_send"}, \
{
.fn = sctp_sf_do_prm_send, .name =
"sctp_sf_do_prm_send"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_prm_send, name:
"sctp_sf_do_prm_send"}, \
{
.fn = sctp_sf_do_prm_send, .name =
"sctp_sf_do_prm_send"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_prm_send, name:
"sctp_sf_do_prm_send"}, \
{
.fn = sctp_sf_do_prm_send, .name =
"sctp_sf_do_prm_send"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_error_shutdown, name:
"sctp_sf_error_shutdown"}, \
{
.fn = sctp_sf_error_shutdown, .name =
"sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_error_shutdown, name:
"sctp_sf_error_shutdown"}, \
{
.fn = sctp_sf_error_shutdown, .name =
"sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_error_shutdown, name:
"sctp_sf_error_shutdown"}, \
{
.fn = sctp_sf_error_shutdown, .name =
"sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_error_shutdown, name:
"sctp_sf_error_shutdown"}, \
{
.fn = sctp_sf_error_shutdown, .name =
"sctp_sf_error_shutdown"}, \
}
/* TYPE_SCTP_PRIMITIVE_SEND */
#define TYPE_SCTP_PRIMITIVE_SETPRIMARY { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_SETPRIMARY */
#define TYPE_SCTP_PRIMITIVE_RECEIVE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_RECEIVE */
#define TYPE_SCTP_PRIMITIVE_STATUS { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_STATUS */
#define TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_GETSRTTREPORT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_GETSRTTREPORT */
#define TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD */
#define TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS */
#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT */
#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED */
#define TYPE_SCTP_PRIMITIVE_DESTROY { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_DESTROY */
/* The primary index for this table is the primitive type.
...
...
@@ -851,46 +873,46 @@ sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE
#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn:
sctp_sf_do_9_2_start_shutdown, \
name:
"sctp_do_9_2_start_shutdown"}, \
{
.fn =
sctp_sf_do_9_2_start_shutdown, \
.name =
"sctp_do_9_2_start_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn:
sctp_sf_do_9_2_shutdown_ack, \
name:
"sctp_sf_do_9_2_shutdown_ack"}, \
{
.fn =
sctp_sf_do_9_2_shutdown_ack, \
.name =
"sctp_sf_do_9_2_shutdown_ack"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
}
#define TYPE_SCTP_OTHER_ICMP_UNREACHFRAG { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
sctp_sm_table_entry_t
other_event_table
[
SCTP_NUM_OTHER_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
...
...
@@ -900,213 +922,234 @@ sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STA
#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_t1_timer_expire, name:
"sctp_sf_t1_timer_expire"}, \
{
.fn = sctp_sf_t1_timer_expire, .name =
"sctp_sf_t1_timer_expire"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_t1_timer_expire, name:
"sctp_sf_t1_timer_expire"}, \
{
.fn = sctp_sf_t1_timer_expire, .name =
"sctp_sf_t1_timer_expire"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_t2_timer_expire, name:
"sctp_sf_t2_timer_expire"}, \
{
.fn = sctp_sf_t2_timer_expire, .name =
"sctp_sf_t2_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_t2_timer_expire, name:
"sctp_sf_t2_timer_expire"}, \
{
.fn = sctp_sf_t2_timer_expire, .name =
"sctp_sf_t2_timer_expire"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
/* SCTP_STATE_EMPTY */
\
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_sendbeat_8_3, name:
"sctp_sf_sendbeat_8_3"}, \
{
.fn = sctp_sf_sendbeat_8_3, .name =
"sctp_sf_sendbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_sendbeat_8_3, name:
"sctp_sf_sendbeat_8_3"}, \
{
.fn = sctp_sf_sendbeat_8_3, .name =
"sctp_sf_sendbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_6_2_sack, name:
"sctp_sf_do_6_2_sack"}, \
{
.fn = sctp_sf_do_6_2_sack, .name =
"sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_6_2_sack, name:
"sctp_sf_do_6_2_sack"}, \
{
.fn = sctp_sf_do_6_2_sack, .name =
"sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_6_2_sack, name:
"sctp_sf_do_6_2_sack"}, \
{
.fn = sctp_sf_do_6_2_sack, .name =
"sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn:
sctp_sf_autoclose_timer_expire, \
name:
"sctp_sf_autoclose_timer_expire"}, \
{
.fn =
sctp_sf_autoclose_timer_expire, \
.name =
"sctp_sf_autoclose_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
sctp_sm_table_entry_t
timeout_event_table
[
SCTP_NUM_TIMEOUT_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
...
...
@@ -1116,6 +1159,7 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM
TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
TYPE_SCTP_EVENT_TIMEOUT_T3_RTX
,
TYPE_SCTP_EVENT_TIMEOUT_T4_RTO
,
TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT
,
TYPE_SCTP_EVENT_TIMEOUT_SACK
,
TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE
,
...
...
@@ -1125,12 +1169,11 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM
sctp_sm_table_entry_t
*
sctp_chunk_event_lookup
(
sctp_cid_t
cid
,
sctp_state_t
state
)
{
if
(
state
>
SCTP_STATE_MAX
)
BUG
();
if
(
cid
<
0
)
return
&
nop
;
return
&
bug
;
if
(
cid
<=
SCTP_CID_BASE_MAX
)
if
(
cid
>=
0
&&
cid
<=
SCTP_CID_BASE_MAX
)
{
return
&
chunk_event_table
[
cid
][
state
];
}
switch
(
cid
)
{
case
SCTP_CID_ASCONF
:
...
...
@@ -1139,8 +1182,6 @@ sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t stat
case
SCTP_CID_ASCONF_ACK
:
return
&
chunk_event_table_asconf_ack
[
state
];
default:
return
&
nop
;
};
return
&
nop
;
return
&
chunk_event_table_unknown
[
state
];
}
}
net/sctp/socket.c
View file @
229e0840
/* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001
-2002
International Business Machines, Corp.
* Copyright (c) 2001
-2002
Intel Corp.
* Copyright (c) 2001
-2002
Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
* This file is part of the SCTP kernel reference Implementation
...
...
@@ -82,8 +82,6 @@ static void sctp_wfree(struct sk_buff *skb);
static
int
sctp_wait_for_sndbuf
(
sctp_association_t
*
asoc
,
long
*
timeo_p
,
int
msg_len
);
static
int
sctp_wait_for_packet
(
struct
sock
*
sk
,
int
*
err
,
long
*
timeo_p
);
static
inline
void
sctp_sk_memcpy_msgname
(
struct
sock
*
sk
,
char
*
msgname
,
int
*
addr_len
,
struct
sk_buff
*
skb
);
static
inline
void
sctp_sk_addr_set
(
struct
sock
*
,
const
sockaddr_storage_t
*
newaddr
,
sockaddr_storage_t
*
saveaddr
);
...
...
@@ -326,8 +324,8 @@ static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
SCTP_DEBUG_PRINTK
(
"__sctp_bindx(sk: %p, addrs: %p, addrcnt: %d, "
"flags: %s)
\n
"
,
sk
,
addrs
,
addrcnt
,
(
BINDX_ADD_ADDR
==
flags
)
?
"ADD"
:
((
BINDX_REM_ADDR
==
flags
)
?
"REM"
:
"BOGUS"
));
(
BINDX_ADD_ADDR
==
flags
)
?
"ADD"
:
((
BINDX_REM_ADDR
==
flags
)
?
"REM"
:
"BOGUS"
));
switch
(
flags
)
{
case
BINDX_ADD_ADDR
:
...
...
@@ -500,9 +498,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
case
AF_INET
:
saveaddr
=
*
((
sockaddr_storage_t
*
)
&
addrs
[
cnt
]);
saveaddr
.
v4
.
sin_port
=
ntohs
(
saveaddr
.
v4
.
sin_port
);
/* verify the port */
saveaddr
.
v4
.
sin_port
=
ntohs
(
saveaddr
.
v4
.
sin_port
);
/* Verify the port. */
if
(
saveaddr
.
v4
.
sin_port
!=
bp
->
port
)
{
retval
=
-
EINVAL
;
goto
err_bindx_rem
;
...
...
@@ -606,7 +603,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
*
* Returns 0 if ok, <0 errno code on error.
*/
static
int
sctp_setsockopt_bindx
(
struct
sock
*
sk
,
struct
sockaddr_storage
*
addrs
,
static
int
sctp_setsockopt_bindx
(
struct
sock
*
sk
,
struct
sockaddr_storage
*
addrs
,
int
addrssize
,
int
op
)
{
struct
sockaddr_storage
*
kaddrs
;
...
...
@@ -614,8 +612,7 @@ static int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr_storage *addrs
size_t
addrcnt
;
SCTP_DEBUG_PRINTK
(
"sctp_do_setsocktopt_bindx: sk %p addrs %p"
" addrssize %d opt %d
\n
"
,
sk
,
addrs
,
addrssize
,
op
);
" addrssize %d opt %d
\n
"
,
sk
,
addrs
,
addrssize
,
op
);
/* Do we have an integer number of structs sockaddr_storage? */
if
(
unlikely
(
addrssize
<=
0
||
...
...
@@ -851,7 +848,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
goto
out_unlock
;
}
if
(
sinfo_flags
&
MSG_ABORT
)
{
SCTP_DEBUG_PRINTK
(
"Aborting association: %p
\n
"
,
asoc
);
SCTP_DEBUG_PRINTK
(
"Aborting association: %p
\n
"
,
asoc
);
sctp_primitive_ABORT
(
asoc
,
NULL
);
err
=
0
;
goto
out_unlock
;
...
...
@@ -866,8 +863,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
* either the default or the user specified stream counts.
*/
if
(
sinfo
)
{
if
(
!
sinit
||
(
sinit
&&
!
sinit
->
sinit_num_ostreams
))
{
if
(
!
sinit
||
(
sinit
&&
!
sinit
->
sinit_num_ostreams
))
{
/* Check against the defaults. */
if
(
sinfo
->
sinfo_stream
>=
sp
->
initmsg
.
sinit_num_ostreams
)
{
...
...
@@ -1096,12 +1092,13 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
* flags - flags sent or received with the user message, see Section
* 5 for complete description of the flags.
*/
static
struct
sk_buff
*
sctp_skb_recv_datagram
(
struct
sock
*
,
int
,
int
,
int
*
);
static
struct
sk_buff
*
sctp_skb_recv_datagram
(
struct
sock
*
,
int
,
int
,
int
*
);
static
int
sctp_recvmsg
(
struct
sock
*
sk
,
struct
msghdr
*
msg
,
int
len
,
int
noblock
,
int
flags
,
int
*
addr_len
)
{
sctp_ulpevent_t
*
event
=
NULL
;
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
struct
sk_buff
*
skb
;
int
copied
;
int
err
=
0
;
...
...
@@ -1147,19 +1144,16 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
sock_recv_timestamp
(
msg
,
sk
,
skb
);
if
(
sctp_ulpevent_is_notification
(
event
))
{
msg
->
msg_flags
|=
MSG_NOTIFICATION
;
sp
->
pf
->
event_msgname
(
event
,
msg
->
msg_name
,
addr_len
);
}
else
{
/* Copy the address. */
if
(
addr_len
&&
msg
->
msg_name
)
sctp_sk_memcpy_msgname
(
sk
,
msg
->
msg_name
,
addr_len
,
skb
);
sp
->
pf
->
skb_msgname
(
skb
,
msg
->
msg_name
,
addr_len
);
}
/* Check if we allow SCTP_SNDRCVINFO. */
if
(
s
ctp_sk
(
sk
)
->
subscribe
.
sctp_data_io_event
)
if
(
s
p
->
subscribe
.
sctp_data_io_event
)
sctp_ulpevent_read_sndrcvinfo
(
event
,
msg
);
#if 0
/* FIXME: we should be calling IP
layer too
. */
/* FIXME: we should be calling IP
/IPv6 layers
. */
if (sk->protinfo.af_inet.cmsg_flags)
ip_cmsg_recv(msg, skb);
#endif
...
...
@@ -1176,7 +1170,8 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
return
err
;
}
static
inline
int
sctp_setsockopt_disable_fragments
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
static
inline
int
sctp_setsockopt_disable_fragments
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
int
val
;
...
...
@@ -1191,7 +1186,8 @@ static inline int sctp_setsockopt_disable_fragments(struct sock *sk, char *optva
return
0
;
}
static
inline
int
sctp_setsockopt_set_events
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
static
inline
int
sctp_setsockopt_set_events
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
if
(
optlen
!=
sizeof
(
struct
sctp_event_subscribe
))
return
-
EINVAL
;
...
...
@@ -1200,7 +1196,8 @@ static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval, int
return
0
;
}
static
inline
int
sctp_setsockopt_autoclose
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
static
inline
int
sctp_setsockopt_autoclose
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
...
...
@@ -1236,7 +1233,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
char
*
optval
,
int
optlen
)
{
int
retval
=
0
;
char
*
tmp
;
char
*
tmp
;
sctp_protocol_t
*
proto
=
sctp_get_protocol
();
struct
list_head
*
pos
;
sctp_func_t
*
af
;
...
...
@@ -1356,19 +1353,9 @@ static int sctp_init_sock(struct sock *sk)
proto
=
sctp_get_protocol
();
/* Create a per socket endpoint structure. Even if we
* change the data structure relationships, this may still
* be useful for storing pre-connect address information.
*/
ep
=
sctp_endpoint_new
(
proto
,
sk
,
GFP_KERNEL
);
if
(
!
ep
)
return
-
ENOMEM
;
sp
=
sctp_sk
(
sk
);
/* Initialize the SCTP per socket area. */
sp
->
ep
=
ep
;
sp
->
type
=
SCTP_SOCKET_UDP
;
/* FIXME: The next draft (04) of the SCTP Sockets Extensions
...
...
@@ -1425,6 +1412,16 @@ static int sctp_init_sock(struct sock *sk)
* for UDP-style sockets only.
*/
sp
->
autoclose
=
0
;
sp
->
pf
=
sctp_get_pf_specific
(
sk
->
family
);
/* Create a per socket endpoint structure. Even if we
* change the data structure relationships, this may still
* be useful for storing pre-connect address information.
*/
ep
=
sctp_endpoint_new
(
proto
,
sk
,
GFP_KERNEL
);
if
(
NULL
==
ep
)
return
-
ENOMEM
;
sp
->
ep
=
ep
;
SCTP_DBG_OBJCNT_INC
(
sock
);
return
0
;
...
...
@@ -1836,8 +1833,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
case
PF_INET6
:
SCTP_V6
(
tmpaddr
.
v6
.
sin6_family
=
AF_INET6
;
tmpaddr
.
v6
.
sin6_port
=
snum
;
tmpaddr
.
v6
.
sin6_addr
=
inet6_sk
(
sk
)
->
rcv_saddr
;
tmpaddr
.
v6
.
sin6_addr
=
inet6_sk
(
sk
)
->
rcv_saddr
;
)
break
;
...
...
@@ -1855,7 +1851,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
* that this port/socket (sk) combination are already
* in an endpoint.
*/
for
(
;
sk2
!=
NULL
;
sk2
=
sk2
->
bind_next
)
{
for
(
;
sk2
!=
NULL
;
sk2
=
sk2
->
bind_next
)
{
sctp_endpoint_t
*
ep2
;
ep2
=
sctp_sk
(
sk2
)
->
ep
;
...
...
@@ -1887,7 +1883,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
* SO_REUSEADDR on this socket -sk-).
*/
if
(
pp
->
sk
==
NULL
)
{
pp
->
fastreuse
=
sk
->
reuse
?
1
:
0
;
pp
->
fastreuse
=
sk
->
reuse
?
1
:
0
;
}
else
if
(
pp
->
fastreuse
&&
sk
->
reuse
==
0
)
{
pp
->
fastreuse
=
0
;
}
...
...
@@ -2073,7 +2069,7 @@ static sctp_bind_bucket_t *sctp_bucket_create(sctp_bind_hashbucket_t *head, unsi
pp
->
sk
=
NULL
;
if
((
pp
->
next
=
head
->
chain
)
!=
NULL
)
pp
->
next
->
pprev
=
&
pp
->
next
;
head
->
chain
=
pp
;
head
->
chain
=
pp
;
pp
->
pprev
=
&
head
->
chain
;
}
SCTP_DEBUG_PRINTK
(
"sctp_bucket_create() ends, pp=%p
\n
"
,
pp
);
...
...
@@ -2433,41 +2429,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no
return
NULL
;
}
/* Copy an approriately formatted address for msg_name. */
static
inline
void
sctp_sk_memcpy_msgname
(
struct
sock
*
sk
,
char
*
msgname
,
int
*
addr_len
,
struct
sk_buff
*
skb
)
{
struct
sockaddr_in
*
sin
;
struct
sockaddr_in6
*
sin6
__attribute__
((
unused
));
struct
sctphdr
*
sh
;
/* The sockets layer handles copying this out to user space. */
switch
(
sk
->
family
)
{
case
PF_INET
:
sin
=
(
struct
sockaddr_in
*
)
msgname
;
if
(
addr_len
)
*
addr_len
=
sizeof
(
struct
sockaddr_in
);
sin
->
sin_family
=
AF_INET
;
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin
->
sin_port
=
sh
->
source
;
sin
->
sin_addr
.
s_addr
=
skb
->
nh
.
iph
->
saddr
;
memset
(
sin
->
sin_zero
,
0
,
sizeof
(
sin
->
sin_zero
));
break
;
case
PF_INET6
:
SCTP_V6
(
/* FIXME: Need v6 code here. We should convert
* V4 addresses to PF_INET6 format. See ipv6/udp.c
* for an example. --jgrimm
*/
);
break
;
default:
/* Should not get here. */
break
;
};
}
static
inline
int
sctp_sendmsg_verify_name
(
struct
sock
*
sk
,
struct
msghdr
*
msg
)
{
sockaddr_storage_t
*
sa
;
...
...
net/sctp/transport.c
View file @
229e0840
net/sctp/ulpevent.c
View file @
229e0840
...
...
@@ -46,9 +46,10 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
static
void
sctp_rcvmsg_rfree
(
struct
sk_buff
*
skb
);
static
void
sctp_ulpevent_set_owner_r
(
struct
sk_buff
*
skb
,
sctp_association_t
*
asoc
);
static
void
sctp_ulpevent_set_owner
(
struct
sk_buff
*
skb
,
const
sctp_association_t
*
asoc
);
/* Create a new sctp_ulpevent. */
sctp_ulpevent_t
*
sctp_ulpevent_new
(
int
size
,
int
msg_flags
,
int
priority
)
...
...
@@ -123,14 +124,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
struct
sctp_assoc_change
*
sac
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_assoc_change
),
MSG_NOTIFICATION
,
priority
);
MSG_NOTIFICATION
,
priority
);
if
(
!
event
)
goto
fail
;
sac
=
(
struct
sctp_assoc_change
*
)
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_assoc_change
));
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_assoc_change
));
/* Socket Extensions for SCTP
* 5.3.1.1 SCTP_ASSOC_CHANGE
...
...
@@ -199,6 +198,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
sac
->
sac_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
...
...
@@ -227,14 +227,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
struct
sctp_paddr_change
*
spc
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_paddr_change
),
MSG_NOTIFICATION
,
priority
);
MSG_NOTIFICATION
,
priority
);
if
(
!
event
)
goto
fail
;
spc
=
(
struct
sctp_paddr_change
*
)
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_paddr_change
));
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_paddr_change
));
/* Sockets API Extensions for SCTP
* Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
...
...
@@ -287,12 +285,13 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
/* Socket Extensions for SCTP
* 5.3.1.1 SCTP_ASSOC_CHANGE
*
* s
a
c_assoc_id: sizeof (sctp_assoc_t)
* s
p
c_assoc_id: sizeof (sctp_assoc_t)
*
* The association id field, holds the identifier for the association.
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
spc
->
spc_assoc_id
=
sctp_assoc2id
(
asoc
);
/* Sockets API Extensions for SCTP
...
...
@@ -360,9 +359,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
/* Embed the event fields inside the cloned skb. */
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
event
=
sctp_ulpevent_init
(
event
,
skb
,
MSG_NOTIFICATION
);
event
=
sctp_ulpevent_init
(
event
,
skb
,
MSG_NOTIFICATION
);
if
(
!
event
)
goto
fail
;
...
...
@@ -418,6 +416,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
sre
->
sre_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
...
...
@@ -515,9 +514,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* The original send information associated with the undelivered
* message.
*/
memcpy
(
&
ssf
->
ssf_info
,
&
chunk
->
sinfo
,
sizeof
(
struct
sctp_sndrcvinfo
));
memcpy
(
&
ssf
->
ssf_info
,
&
chunk
->
sinfo
,
sizeof
(
struct
sctp_sndrcvinfo
));
/* Socket Extensions for SCTP
* 5.3.1.4 SCTP_SEND_FAILED
...
...
@@ -528,8 +525,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* same association identifier. For TCP style socket, this field is
* ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
ssf
->
ssf_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
fail:
...
...
@@ -541,7 +538,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* Socket Extensions for SCTP - draft-01
* 5.3.1.5 SCTP_SHUTDOWN_EVENT
*/
sctp_ulpevent_t
*
sctp_ulpevent_make_shutdown_event
(
const
sctp_association_t
*
asoc
,
sctp_ulpevent_t
*
sctp_ulpevent_make_shutdown_event
(
const
sctp_association_t
*
asoc
,
__u16
flags
,
int
priority
)
{
...
...
@@ -549,14 +547,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
struct
sctp_shutdown_event
*
sse
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_assoc_change
),
MSG_NOTIFICATION
,
priority
);
MSG_NOTIFICATION
,
priority
);
if
(
!
event
)
goto
fail
;
sse
=
(
struct
sctp_shutdown_event
*
)
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_shutdown_event
));
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_shutdown_event
));
/* Socket Extensions for SCTP
* 5.3.1.5 SCTP_SHUTDOWN_EVENT
...
...
@@ -591,6 +587,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
sse
->
sse_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
...
...
@@ -607,8 +604,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
* 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
*/
sctp_ulpevent_t
*
sctp_ulpevent_make_rcvmsg
(
sctp_association_t
*
asoc
,
sctp_chunk_t
*
chunk
,
int
priority
)
sctp_chunk_t
*
chunk
,
int
priority
)
{
sctp_ulpevent_t
*
event
;
struct
sctp_sndrcvinfo
*
info
;
...
...
@@ -818,23 +814,33 @@ static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, sctp_association_t *a
asoc
->
rwnd_over
=
skb
->
len
-
asoc
->
rwnd
;
asoc
->
rwnd
=
0
;
}
SCTP_DEBUG_PRINTK
(
"rwnd decreased by %d to (%u, %u)
\n
"
,
skb
->
len
,
asoc
->
rwnd
,
asoc
->
rwnd_over
);
}
/* A simple destructor to give up the reference to the association. */
static
void
sctp_ulpevent_rfree
(
struct
sk_buff
*
skb
)
{
sctp_ulpevent_t
*
event
;
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
sctp_association_put
(
event
->
asoc
);
}
/* Hold the association in case the msg_name needs read out of
* the association.
*/
static
void
sctp_ulpevent_set_owner
(
struct
sk_buff
*
skb
,
const
sctp_association_t
*
asoc
)
{
sctp_ulpevent_t
*
event
;
/* Cast away the const, as we are just wanting to
* bump the reference count.
*/
sctp_association_hold
((
sctp_association_t
*
)
asoc
);
skb
->
sk
=
asoc
->
base
.
sk
;
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
event
->
asoc
=
(
sctp_association_t
*
)
asoc
;
skb
->
destructor
=
sctp_ulpevent_rfree
;
}
net/sctp/ulpqueue.c
View file @
229e0840
net/x25/af_x25.c
View file @
229e0840
/*
* X.25 Packet Layer release 002
*
* This is ALPHA test software. This code may break your machine, randomly fail to work with new
* releases, misbehave and/or generally screw up. It might even work.
* This is ALPHA test software. This code may break your machine,
* randomly fail to work with new releases, misbehave and/or generally
* screw up. It might even work.
*
* This code REQUIRES 2.1.15 or higher
*
...
...
@@ -68,9 +69,10 @@ static struct sock *volatile x25_list /* = NULL initially */;
static
struct
proto_ops
x25_proto_ops
;
static
x25_address
null_x25_address
=
{
" "
};
static
struct
x25_address
null_x25_address
=
{
" "
};
int
x25_addr_ntoa
(
unsigned
char
*
p
,
x25_address
*
called_addr
,
x25_address
*
calling_addr
)
int
x25_addr_ntoa
(
unsigned
char
*
p
,
struct
x25_address
*
called_addr
,
struct
x25_address
*
calling_addr
)
{
int
called_len
,
calling_len
;
char
*
called
,
*
calling
;
...
...
@@ -101,13 +103,13 @@ int x25_addr_ntoa(unsigned char *p, x25_address *called_addr, x25_address *calli
}
}
*
called
=
'\0'
;
*
calling
=
'\0'
;
*
called
=
*
calling
=
'\0'
;
return
1
+
(
called_len
+
calling_len
+
1
)
/
2
;
}
int
x25_addr_aton
(
unsigned
char
*
p
,
x25_address
*
called_addr
,
x25_address
*
calling_addr
)
int
x25_addr_aton
(
unsigned
char
*
p
,
struct
x25_address
*
called_addr
,
struct
x25_address
*
calling_addr
)
{
unsigned
int
called_len
,
calling_len
;
char
*
called
,
*
calling
;
...
...
@@ -155,22 +157,16 @@ static void x25_remove_socket(struct sock *sk)
save_flags
(
flags
);
cli
();
if
((
s
=
x25_list
)
==
sk
)
{
if
((
s
=
x25_list
)
==
sk
)
x25_list
=
s
->
next
;
restore_flags
(
flags
);
return
;
}
while
(
s
!=
NULL
&&
s
->
next
!=
NULL
)
{
else
while
(
s
&&
s
->
next
)
{
if
(
s
->
next
==
sk
)
{
s
->
next
=
sk
->
next
;
restore_flags
(
flags
);
return
;
break
;
}
s
=
s
->
next
;
}
restore_flags
(
flags
);
}
...
...
@@ -181,7 +177,7 @@ static void x25_kill_by_device(struct net_device *dev)
{
struct
sock
*
s
;
for
(
s
=
x25_list
;
s
!=
NULL
;
s
=
s
->
next
)
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
);
}
...
...
@@ -191,7 +187,7 @@ static void x25_kill_by_device(struct net_device *dev)
*/
static
int
x25_device_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
ptr
;
struct
net_device
*
dev
=
ptr
;
struct
x25_neigh
*
neigh
;
if
(
dev
->
type
==
ARPHRD_X25
...
...
@@ -238,7 +234,7 @@ static void x25_insert_socket(struct sock *sk)
* Find a socket that wants to accept the Call Request we just
* received.
*/
static
struct
sock
*
x25_find_listener
(
x25_address
*
addr
)
static
struct
sock
*
x25_find_listener
(
struct
x25_address
*
addr
)
{
unsigned
long
flags
;
struct
sock
*
s
;
...
...
@@ -246,17 +242,14 @@ static struct sock *x25_find_listener(x25_address *addr)
save_flags
(
flags
);
cli
();
for
(
s
=
x25_list
;
s
!=
NULL
;
s
=
s
->
next
)
{
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
((
!
strcmp
(
addr
->
x25_addr
,
x25_sk
(
s
)
->
source_addr
.
x25_addr
)
||
strcmp
(
addr
->
x25_addr
,
null_x25_address
.
x25_addr
)
==
0
)
&&
s
->
state
==
TCP_LISTEN
)
{
restore_flags
(
flags
);
return
s
;
}
}
!
strcmp
(
addr
->
x25_addr
,
null_x25_address
.
x25_addr
))
&&
s
->
state
==
TCP_LISTEN
)
break
;
restore_flags
(
flags
);
return
NULL
;
return
s
;
}
/*
...
...
@@ -270,15 +263,12 @@ struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *neigh)
save_flags
(
flags
);
cli
();
for
(
s
=
x25_list
;
s
!=
NULL
;
s
=
s
->
next
)
{
if
(
x25_sk
(
s
)
->
lci
==
lci
&&
x25_sk
(
s
)
->
neighbour
==
neigh
)
{
restore_flags
(
flags
);
return
s
;
}
}
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
lci
==
lci
&&
x25_sk
(
s
)
->
neighbour
==
neigh
)
break
;
restore_flags
(
flags
);
return
NULL
;
return
s
;
}
/*
...
...
@@ -288,9 +278,10 @@ unsigned int x25_new_lci(struct x25_neigh *neigh)
{
unsigned
int
lci
=
1
;
while
(
x25_find_socket
(
lci
,
neigh
)
!=
NULL
)
{
lci
++
;
if
(
lci
==
4096
)
return
0
;
while
(
x25_find_socket
(
lci
,
neigh
))
if
(
++
lci
==
4096
)
{
lci
=
0
;
break
;
}
return
lci
;
...
...
@@ -339,7 +330,7 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
kfree_skb
(
skb
);
}
if
(
atomic_read
(
&
sk
->
wmem_alloc
)
!=
0
||
atomic_read
(
&
sk
->
rmem_alloc
)
!=
0
)
{
if
(
atomic_read
(
&
sk
->
wmem_alloc
)
||
atomic_read
(
&
sk
->
rmem_alloc
)
)
{
/* Defer: outstanding buffers */
init_timer
(
&
sk
->
timer
);
sk
->
timer
.
expires
=
jiffies
+
10
*
HZ
;
...
...
@@ -362,73 +353,69 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
static
int
x25_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
opt
;
struct
sock
*
sk
=
sock
->
sk
;
int
rc
=
-
ENOPROTOOPT
;
if
(
level
!=
SOL_X25
)
return
-
ENOPROTOOPT
;
if
(
level
!=
SOL_X25
||
optname
!=
X25_QBITINCL
)
goto
out
;
rc
=
-
EINVAL
;
if
(
optlen
<
sizeof
(
int
))
return
-
EINVAL
;
goto
out
;
rc
=
-
EFAULT
;
if
(
get_user
(
opt
,
(
int
*
)
optval
))
return
-
EFAULT
;
switch
(
optname
)
{
case
X25_QBITINCL
:
x25_sk
(
sk
)
->
qbitincl
=
opt
?
1
:
0
;
return
0
;
goto
out
;
default:
return
-
ENOPROTOOPT
;
}
x25_sk
(
sk
)
->
qbitincl
=
!!
opt
;
rc
=
0
;
out:
return
rc
;
}
static
int
x25_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
*
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
val
=
0
;
int
len
;
int
val
,
len
,
rc
=
-
ENOPROTOOPT
;
if
(
level
!=
SOL_X25
)
return
-
ENOPROTOOPT
;
if
(
level
!=
SOL_X25
||
optname
!=
X25_QBITINCL
)
goto
out
;
rc
=
-
EFAULT
;
if
(
get_user
(
len
,
optlen
))
return
-
EFAULT
;
switch
(
optname
)
{
case
X25_QBITINCL
:
val
=
x25_sk
(
sk
)
->
qbitincl
;
break
;
default:
return
-
ENOPROTOOPT
;
}
goto
out
;
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
int
));
rc
=
-
EINVAL
;
if
(
len
<
0
)
return
-
EINVAL
;
goto
out
;
rc
=
-
EFAULT
;
if
(
put_user
(
len
,
optlen
))
return
-
EFAULT
;
goto
out
;
return
copy_to_user
(
optval
,
&
val
,
len
)
?
-
EFAULT
:
0
;
val
=
x25_sk
(
sk
)
->
qbitincl
;
rc
=
copy_to_user
(
optval
,
&
val
,
len
)
?
-
EFAULT
:
0
;
out:
return
rc
;
}
static
int
x25_listen
(
struct
socket
*
sock
,
int
backlog
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
rc
=
-
EOPNOTSUPP
;
if
(
sk
->
state
!=
TCP_LISTEN
)
{
memset
(
&
x25_sk
(
sk
)
->
dest_addr
,
0
,
X25_ADDR_LEN
);
sk
->
max_ack_backlog
=
backlog
;
sk
->
state
=
TCP_LISTEN
;
r
eturn
0
;
r
c
=
0
;
}
return
-
EOPNOTSUPP
;
return
rc
;
}
static
struct
sock
*
x25_alloc_socket
(
void
)
...
...
@@ -445,7 +432,7 @@ static struct sock *x25_alloc_socket(void)
if
(
!
x25
)
goto
frees
;
memset
(
x25
,
0
x00
,
sizeof
(
*
x25
));
memset
(
x25
,
0
,
sizeof
(
*
x25
));
x25
->
sk
=
sk
;
...
...
@@ -455,10 +442,13 @@ static struct sock *x25_alloc_socket(void)
skb_queue_head_init
(
&
x25
->
fragment_queue
);
skb_queue_head_init
(
&
x25
->
interrupt_in_queue
);
skb_queue_head_init
(
&
x25
->
interrupt_out_queue
);
out:
return
sk
;
frees:
sk_free
(
sk
);
out:
return
sk
;
frees:
sk_free
(
sk
);
sk
=
NULL
;
decmod:
MOD_DEC_USE_COUNT
;
decmod:
MOD_DEC_USE_COUNT
;
goto
out
;
}
...
...
@@ -466,12 +456,14 @@ static int x25_create(struct socket *sock, int protocol)
{
struct
sock
*
sk
;
x25_cb
*
x25
;
int
rc
=
-
ESOCKTNOSUPPORT
;
if
(
sock
->
type
!=
SOCK_SEQPACKET
||
protocol
!=
0
)
return
-
ESOCKTNOSUPPORT
;
if
(
sock
->
type
!=
SOCK_SEQPACKET
||
protocol
)
goto
out
;
rc
=
-
ENOMEM
;
if
((
sk
=
x25_alloc_socket
())
==
NULL
)
return
-
ENOMEM
;
goto
out
;
x25
=
x25_sk
(
sk
);
...
...
@@ -495,20 +487,21 @@ static int x25_create(struct socket *sock, int protocol)
x25
->
facilities
.
pacsize_out
=
X25_DEFAULT_PACKET_SIZE
;
x25
->
facilities
.
throughput
=
X25_DEFAULT_THROUGHPUT
;
x25
->
facilities
.
reverse
=
X25_DEFAULT_REVERSE
;
return
0
;
rc
=
0
;
out:
return
rc
;
}
static
struct
sock
*
x25_make_new
(
struct
sock
*
osk
)
{
struct
sock
*
sk
;
struct
sock
*
sk
=
NULL
;
x25_cb
*
x25
,
*
ox25
;
if
(
osk
->
type
!=
SOCK_SEQPACKET
)
return
NULL
;
goto
out
;
if
((
sk
=
x25_alloc_socket
())
==
NULL
)
return
NULL
;
goto
out
;
x25
=
x25_sk
(
sk
);
...
...
@@ -533,7 +526,7 @@ static struct sock *x25_make_new(struct sock *osk)
x25
->
qbitincl
=
ox25
->
qbitincl
;
init_timer
(
&
x25
->
timer
);
out:
return
sk
;
}
...
...
@@ -542,7 +535,8 @@ static int x25_release(struct socket *sock)
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
;
if
(
sk
==
NULL
)
return
0
;
if
(
!
sk
)
goto
out
;
x25
=
x25_sk
(
sk
);
...
...
@@ -567,14 +561,11 @@ static int x25_release(struct socket *sock)
sk
->
dead
=
1
;
sk
->
destroy
=
1
;
break
;
default:
break
;
}
sock
->
sk
=
NULL
;
sk
->
socket
=
NULL
;
/* Not used, but we should do this */
out:
return
0
;
}
...
...
@@ -583,21 +574,14 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct
sock
*
sk
=
sock
->
sk
;
struct
sockaddr_x25
*
addr
=
(
struct
sockaddr_x25
*
)
uaddr
;
if
(
sk
->
zapped
==
0
)
return
-
EINVAL
;
if
(
addr_len
!=
sizeof
(
struct
sockaddr_x25
))
return
-
EINVAL
;
if
(
addr
->
sx25_family
!=
AF_X25
)
if
(
!
sk
->
zapped
||
addr_len
!=
sizeof
(
struct
sockaddr_x25
)
||
addr
->
sx25_family
!=
AF_X25
)
return
-
EINVAL
;
x25_sk
(
sk
)
->
source_addr
=
addr
->
sx25_addr
;
x25_insert_socket
(
sk
);
sk
->
zapped
=
0
;
SOCK_DEBUG
(
sk
,
"x25_bind: socket is bound
\n
"
);
return
0
;
...
...
@@ -609,42 +593,49 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
x25_cb
*
x25
=
x25_sk
(
sk
);
struct
sockaddr_x25
*
addr
=
(
struct
sockaddr_x25
*
)
uaddr
;
struct
net_device
*
dev
;
int
rc
=
0
;
if
(
sk
->
state
==
TCP_ESTABLISHED
&&
sock
->
state
==
SS_CONNECTING
)
{
sock
->
state
=
SS_CONNECTED
;
return
0
;
/* Connect completed during a ERESTARTSYS event */
goto
out
;
/* Connect completed during a ERESTARTSYS event */
}
rc
=
-
ECONNREFUSED
;
if
(
sk
->
state
==
TCP_CLOSE
&&
sock
->
state
==
SS_CONNECTING
)
{
sock
->
state
=
SS_UNCONNECTED
;
return
-
ECONNREFUSED
;
goto
out
;
}
rc
=
-
EISCONN
;
/* No reconnect on a seqpacket socket */
if
(
sk
->
state
==
TCP_ESTABLISHED
)
return
-
EISCONN
;
/* No reconnect on a seqpacket socket */
goto
out
;
sk
->
state
=
TCP_CLOSE
;
sock
->
state
=
SS_UNCONNECTED
;
if
(
addr_len
!=
sizeof
(
struct
sockaddr_x25
))
return
-
EINVAL
;
if
(
addr
->
sx25_family
!=
AF_X25
)
return
-
EINVAL
;
rc
=
-
EINVAL
;
if
(
addr_len
!=
sizeof
(
struct
sockaddr_x25
)
||
addr
->
sx25_family
!=
AF_X25
)
goto
out
;
if
((
dev
=
x25_get_route
(
&
addr
->
sx25_addr
))
==
NULL
)
return
-
ENETUNREACH
;
rc
=
-
ENETUNREACH
;
dev
=
x25_get_route
(
&
addr
->
sx25_addr
);
if
(
!
dev
)
goto
out
;
if
((
x25
->
neighbour
=
x25_get_neigh
(
dev
))
==
NULL
)
return
-
ENETUNREACH
;
x25
->
neighbour
=
x25_get_neigh
(
dev
);
if
(
!
x25
->
neighbour
)
goto
out
;
x25_limit_facilities
(
&
x25
->
facilities
,
x25
->
neighbour
);
if
((
x25
->
lci
=
x25_new_lci
(
x25
->
neighbour
))
==
0
)
return
-
ENETUNREACH
;
x25
->
lci
=
x25_new_lci
(
x25
->
neighbour
);
if
(
!
x25
->
lci
)
goto
out
;
rc
=
-
EINVAL
;
if
(
sk
->
zapped
)
/* Must bind first - autobinding does not work */
return
-
EINVAL
;
goto
out
;
if
(
!
strcmp
(
x25
->
source_addr
.
x25_addr
,
null_x25_address
.
x25_addr
))
memset
(
&
x25
->
source_addr
,
'\0'
,
X25_ADDR_LEN
);
...
...
@@ -663,49 +654,50 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
x25_start_t21timer
(
sk
);
/* Now the loop */
rc
=
-
EINPROGRESS
;
if
(
sk
->
state
!=
TCP_ESTABLISHED
&&
(
flags
&
O_NONBLOCK
))
return
-
EINPROGRESS
;
goto
out
;
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
))
{
sti
();
return
-
ERESTARTSYS
;
}
if
(
signal_pending
(
current
))
goto
out_unlock
;
}
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
sti
();
sock
->
state
=
SS_UNCONNECTED
;
return
sock_error
(
sk
);
/* Always set at this point */
rc
=
sock_error
(
sk
);
/* Always set at this point */
goto
out_unlock
;
}
sock
->
state
=
SS_CONNECTED
;
rc
=
0
;
out_unlock:
sti
();
return
0
;
out:
return
rc
;
}
static
int
x25_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
,
int
flags
)
{
struct
sock
*
sk
;
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
newsk
;
struct
sk_buff
*
skb
;
int
rc
=
-
EINVAL
;
if
(
(
sk
=
sock
->
sk
)
==
NULL
)
return
-
EINVAL
;
if
(
!
sk
||
sk
->
state
!=
TCP_LISTEN
)
goto
out
;
rc
=
-
EOPNOTSUPP
;
if
(
sk
->
type
!=
SOCK_SEQPACKET
)
return
-
EOPNOTSUPP
;
if
(
sk
->
state
!=
TCP_LISTEN
)
return
-
EINVAL
;
goto
out
;
/*
* The write queue this time is holding sockets ready to use
...
...
@@ -714,17 +706,16 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
do
{
cli
();
if
((
skb
=
skb_dequeue
(
&
sk
->
receive_queue
))
==
NULL
)
{
if
(
flags
&
O_NONBLOCK
)
{
sti
();
return
-
EWOULDBLOCK
;
}
rc
=
-
EWOULDBLOCK
;
if
(
flags
&
O_NONBLOCK
)
goto
out_unlock
;
/* FIXME: going to sleep with interrupts disabled */
interruptible_sleep_on
(
sk
->
sleep
);
if
(
signal_pending
(
current
))
{
sti
();
return
-
ERESTARTSYS
;
}
rc
=
-
ERESTARTSYS
;
if
(
signal_pending
(
current
))
goto
out_unlock
;
}
}
while
(
skb
==
NULL
);
}
while
(
!
skb
);
newsk
=
skb
->
sk
;
newsk
->
pair
=
NULL
;
...
...
@@ -738,8 +729,12 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
sk
->
ack_backlog
--
;
newsock
->
sk
=
newsk
;
newsock
->
state
=
SS_CONNECTED
;
return
0
;
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
)
...
...
@@ -748,16 +743,15 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_l
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
=
x25_sk
(
sk
);
if
(
peer
!=
0
)
{
if
(
peer
)
{
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
return
-
ENOTCONN
;
sx25
->
sx25_addr
=
x25
->
dest_addr
;
}
else
{
}
else
sx25
->
sx25_addr
=
x25
->
source_addr
;
}
sx25
->
sx25_family
=
AF_X25
;
*
uaddr_len
=
sizeof
(
struct
sockaddr_
x25
);
*
uaddr_len
=
sizeof
(
*
s
x25
);
return
0
;
}
...
...
@@ -767,9 +761,9 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
struct
sock
*
sk
;
struct
sock
*
make
;
x25_cb
*
makex25
;
x25_address
source_addr
,
dest_addr
;
struct
x25_address
source_addr
,
dest_addr
;
struct
x25_facilities
facilities
;
int
len
;
int
len
,
rc
;
/*
* Remove the LCI and frame type.
...
...
@@ -790,18 +784,14 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
/*
* We can't accept the Call Request.
*/
if
(
sk
==
NULL
||
sk
->
ack_backlog
==
sk
->
max_ack_backlog
)
{
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
return
0
;
}
if
(
!
sk
||
sk
->
ack_backlog
==
sk
->
max_ack_backlog
)
goto
out_clear_request
;
/*
* Try to reach a compromise on the requested facilities.
*/
if
((
len
=
x25_negotiate_facilities
(
skb
,
sk
,
&
facilities
))
==
-
1
)
{
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
return
0
;
}
if
((
len
=
x25_negotiate_facilities
(
skb
,
sk
,
&
facilities
))
==
-
1
)
goto
out_clear_request
;
/*
* current neighbour/link might impose additional limits
...
...
@@ -813,10 +803,9 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
/*
* Try to create a new socket.
*/
if
((
make
=
x25_make_new
(
sk
))
==
NULL
)
{
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
return
0
;
}
make
=
x25_make_new
(
sk
);
if
(
!
make
)
goto
out_clear_request
;
/*
* Remove the facilities, leaving any Call User Data.
...
...
@@ -857,8 +846,13 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
if
(
!
sk
->
dead
)
sk
->
data_ready
(
sk
,
skb
->
len
);
return
1
;
rc
=
1
;
out:
return
rc
;
out_clear_request:
rc
=
0
;
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
goto
out
;
}
static
int
x25_sendmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
len
,
struct
scm_cookie
*
scm
)
...
...
@@ -866,46 +860,53 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
=
x25_sk
(
sk
);
struct
sockaddr_x25
*
usx25
=
(
struct
sockaddr_x25
*
)
msg
->
msg_name
;
int
err
;
struct
sockaddr_x25
sx25
;
struct
sk_buff
*
skb
;
unsigned
char
*
asmptr
;
int
size
,
qbit
=
0
;
int
noblock
=
msg
->
msg_flags
&
MSG_DONTWAIT
;
int
size
,
qbit
=
0
,
rc
=
-
EINVAL
;
if
(
msg
->
msg_flags
&
~
(
MSG_DONTWAIT
|
MSG_OOB
|
MSG_EOR
))
return
-
EINVAL
;
goto
out
;
/* we currently don't support segmented records at the user interface */
if
(
!
(
msg
->
msg_flags
&
(
MSG_EOR
|
MSG_OOB
)))
return
-
EINVAL
;
goto
out
;
rc
=
-
EADDRNOTAVAIL
;
if
(
sk
->
zapped
)
return
-
EADDRNOTAVAIL
;
goto
out
;
rc
=
-
EPIPE
;
if
(
sk
->
shutdown
&
SEND_SHUTDOWN
)
{
send_sig
(
SIGPIPE
,
current
,
0
);
return
-
EPIPE
;
goto
out
;
}
if
(
x25
->
neighbour
==
NULL
)
return
-
ENETUNREACH
;
rc
=
-
ENETUNREACH
;
if
(
!
x25
->
neighbour
)
goto
out
;
if
(
usx25
!=
NULL
)
{
if
(
usx25
)
{
rc
=
-
EINVAL
;
if
(
msg
->
msg_namelen
<
sizeof
(
sx25
))
return
-
EINVAL
;
sx25
=
*
usx25
;
goto
out
;
memcpy
(
&
sx25
,
usx25
,
sizeof
(
sx25
));
rc
=
-
EISCONN
;
if
(
strcmp
(
x25
->
dest_addr
.
x25_addr
,
sx25
.
sx25_addr
.
x25_addr
))
return
-
EISCONN
;
goto
out
;
rc
=
-
EINVAL
;
if
(
sx25
.
sx25_family
!=
AF_X25
)
return
-
EINVAL
;
goto
out
;
}
else
{
/*
* FIXME 1003.1g - if the socket is like this because
* it has become closed (not started closed) we ought
* to SIGPIPE, EPIPE;
*/
rc
=
-
ENOTCONN
;
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
return
-
ENOTCONN
;
goto
out
;
sx25
.
sx25_family
=
AF_X25
;
sx25
.
sx25_addr
=
x25
->
dest_addr
;
...
...
@@ -921,8 +922,9 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
size
=
len
+
X25_MAX_L2_LEN
+
X25_EXT_MIN_LEN
;
if
((
skb
=
sock_alloc_send_skb
(
sk
,
size
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
))
==
NULL
)
return
err
;
skb
=
sock_alloc_send_skb
(
sk
,
size
,
noblock
,
&
rc
);
if
(
!
skb
)
goto
out
;
X25_SKB_CB
(
skb
)
->
flags
=
msg
->
msg_flags
;
skb_reserve
(
skb
,
X25_MAX_L2_LEN
+
X25_EXT_MIN_LEN
);
...
...
@@ -934,7 +936,9 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
asmptr
=
skb
->
h
.
raw
=
skb_put
(
skb
,
len
);
memcpy_fromiovec
(
asmptr
,
msg
->
msg_iov
,
len
);
rc
=
memcpy_fromiovec
(
asmptr
,
msg
->
msg_iov
,
len
);
if
(
rc
)
goto
out_kfree_skb
;
/*
* If the Q BIT Include socket option is in force, the first
...
...
@@ -985,22 +989,19 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
SOCK_DEBUG
(
sk
,
"x25_sendmsg: Built header.
\n
"
);
SOCK_DEBUG
(
sk
,
"x25_sendmsg: Transmitting buffer
\n
"
);
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
kfree_skb
(
skb
);
return
-
ENOTCONN
;
}
rc
=
-
ENOTCONN
;
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
goto
out_kfree_skb
;
if
(
msg
->
msg_flags
&
MSG_OOB
)
{
if
(
msg
->
msg_flags
&
MSG_OOB
)
skb_queue_tail
(
&
x25
->
interrupt_out_queue
,
skb
);
}
else
{
else
{
len
=
x25_output
(
sk
,
skb
);
if
(
len
<
0
){
if
(
len
<
0
)
kfree_skb
(
skb
);
}
else
{
if
(
x25
->
qbitincl
)
else
if
(
x25
->
qbitincl
)
len
++
;
}
}
/*
* lock_sock() is currently only used to serialize this x25_kick()
...
...
@@ -1019,12 +1020,17 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
lock_sock
(
sk
);
x25_kick
(
sk
);
release_sock
(
sk
);
return
len
;
rc
=
len
;
out:
return
rc
;
out_kfree_skb:
kfree_skb
(
skb
);
goto
out
;
}
static
int
x25_recvmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
size
,
int
flags
,
struct
scm_cookie
*
scm
)
static
int
x25_recvmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
size
,
int
flags
,
struct
scm_cookie
*
scm
)
{
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
=
x25_sk
(
sk
);
...
...
@@ -1032,18 +1038,19 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
int
copied
,
qbit
;
struct
sk_buff
*
skb
;
unsigned
char
*
asmptr
;
int
er
;
int
rc
=
-
ENOTCONN
;
/*
* This works for seqpacket too. The receiver has ordered the queue for
* us! We do one quick check first though
*/
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
return
-
ENOTCONN
;
goto
out
;
if
(
flags
&
MSG_OOB
)
{
rc
=
-
EINVAL
;
if
(
sk
->
urginline
||
!
skb_peek
(
&
x25
->
interrupt_in_queue
))
return
-
EINVAL
;
goto
out
;
skb
=
skb_dequeue
(
&
x25
->
interrupt_in_queue
);
...
...
@@ -1060,8 +1067,9 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
msg
->
msg_flags
|=
MSG_OOB
;
}
else
{
/* Now we can treat all alike */
if
((
skb
=
skb_recv_datagram
(
sk
,
flags
&
~
MSG_DONTWAIT
,
flags
&
MSG_DONTWAIT
,
&
er
))
==
NULL
)
return
er
;
skb
=
skb_recv_datagram
(
sk
,
flags
&
~
MSG_DONTWAIT
,
flags
&
MSG_DONTWAIT
,
&
rc
);
if
(
!
skb
)
goto
out
;
qbit
=
(
skb
->
data
[
0
]
&
X25_Q_BIT
)
==
X25_Q_BIT
;
...
...
@@ -1086,21 +1094,25 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
/* Currently, each datagram always contains a complete record */
msg
->
msg_flags
|=
MSG_EOR
;
skb_copy_datagram_iovec
(
skb
,
0
,
msg
->
msg_iov
,
copied
);
rc
=
skb_copy_datagram_iovec
(
skb
,
0
,
msg
->
msg_iov
,
copied
);
if
(
rc
)
goto
out_free_dgram
;
if
(
sx25
!=
NULL
)
{
if
(
sx25
)
{
sx25
->
sx25_family
=
AF_X25
;
sx25
->
sx25_addr
=
x25
->
dest_addr
;
}
msg
->
msg_namelen
=
sizeof
(
struct
sockaddr_x25
);
skb_free_datagram
(
sk
,
skb
);
lock_sock
(
sk
);
x25_check_rbuf
(
sk
);
release_sock
(
sk
);
return
copied
;
rc
=
copied
;
out_free_dgram:
skb_free_datagram
(
sk
,
skb
);
out:
return
rc
;
}
...
...
@@ -1108,6 +1120,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
=
x25_sk
(
sk
);
int
rc
;
switch
(
cmd
)
{
case
TIOCOUTQ
:
{
...
...
@@ -1115,26 +1128,33 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
amount
=
sk
->
sndbuf
-
atomic_read
(
&
sk
->
wmem_alloc
);
if
(
amount
<
0
)
amount
=
0
;
return
put_user
(
amount
,
(
unsigned
int
*
)
arg
);
rc
=
put_user
(
amount
,
(
unsigned
int
*
)
arg
);
break
;
}
case
TIOCINQ
:
{
struct
sk_buff
*
skb
;
int
amount
=
0
;
/* These two are safe on a single CPU system as only user tasks fiddle here */
/*
* These two are safe on a single CPU system as
* only user tasks fiddle here
*/
if
((
skb
=
skb_peek
(
&
sk
->
receive_queue
))
!=
NULL
)
amount
=
skb
->
len
;
return
put_user
(
amount
,
(
unsigned
int
*
)
arg
);
rc
=
put_user
(
amount
,
(
unsigned
int
*
)
arg
);
break
;
}
case
SIOCGSTAMP
:
if
(
sk
!=
NULL
)
{
if
(
sk
->
stamp
.
tv_sec
==
0
)
return
-
ENOENT
;
return
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
if
(
sk
)
{
rc
=
-
ENOENT
;
if
(
!
sk
->
stamp
.
tv_sec
)
break
;
rc
=
copy_to_user
((
void
*
)
arg
,
&
sk
->
stamp
,
sizeof
(
struct
timeval
))
?
-
EFAULT
:
0
;
}
r
eturn
-
EINVAL
;
r
c
=
-
EINVAL
;
break
;
case
SIOCGIFADDR
:
case
SIOCSIFADDR
:
case
SIOCGIFDSTADDR
:
...
...
@@ -1145,74 +1165,90 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case
SIOCSIFNETMASK
:
case
SIOCGIFMETRIC
:
case
SIOCSIFMETRIC
:
r
eturn
-
EINVAL
;
r
c
=
-
EINVAL
;
break
;
case
SIOCADDRT
:
case
SIOCDELRT
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
return
x25_route_ioctl
(
cmd
,
(
void
*
)
arg
);
rc
=
-
EPERM
;
if
(
!
capable
(
CAP_NET_ADMIN
))
break
;
rc
=
x25_route_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
case
SIOCX25GSUBSCRIP
:
r
eturn
x25_subscr_ioctl
(
cmd
,
(
void
*
)
arg
);
r
c
=
x25_subscr_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
case
SIOCX25SSUBSCRIP
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
return
x25_subscr_ioctl
(
cmd
,
(
void
*
)
arg
);
rc
=
-
EPERM
;
if
(
!
capable
(
CAP_NET_ADMIN
))
break
;
rc
=
x25_subscr_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
case
SIOCX25GFACILITIES
:
{
struct
x25_facilities
facilities
;
facilities
=
x25
->
facilities
;
return
copy_to_user
((
void
*
)
arg
,
&
facilities
,
sizeof
(
facilities
))
?
-
EFAULT
:
0
;
struct
x25_facilities
fac
=
x25
->
fac
ilities
;
rc
=
copy_to_user
((
void
*
)
arg
,
&
fac
,
sizeof
(
fac
))
?
-
EFAULT
:
0
;
break
;
}
case
SIOCX25SFACILITIES
:
{
struct
x25_facilities
facilities
;
rc
=
-
EFAULT
;
if
(
copy_from_user
(
&
facilities
,
(
void
*
)
arg
,
sizeof
(
facilities
)))
return
-
EFAULT
;
break
;
rc
=
-
EINVAL
;
if
(
sk
->
state
!=
TCP_LISTEN
&&
sk
->
state
!=
TCP_CLOSE
)
return
-
EINVAL
;
if
(
facilities
.
pacsize_in
<
X25_PS16
||
facilities
.
pacsize_in
>
X25_PS4096
)
return
-
EINVAL
;
if
(
facilities
.
pacsize_out
<
X25_PS16
||
facilities
.
pacsize_out
>
X25_PS4096
)
return
-
EINVAL
;
if
(
facilities
.
winsize_in
<
1
||
facilities
.
winsize_in
>
127
)
return
-
EINVAL
;
if
(
facilities
.
throughput
<
0x03
||
facilities
.
throughput
>
0xDD
)
return
-
EINVAL
;
if
(
facilities
.
reverse
!=
0
&&
facilities
.
reverse
!=
1
)
return
-
EINVAL
;
break
;
if
(
facilities
.
pacsize_in
<
X25_PS16
||
facilities
.
pacsize_in
>
X25_PS4096
)
break
;
if
(
facilities
.
pacsize_out
<
X25_PS16
||
facilities
.
pacsize_out
>
X25_PS4096
)
break
;
if
(
facilities
.
winsize_in
<
1
||
facilities
.
winsize_in
>
127
)
break
;
if
(
facilities
.
throughput
<
0x03
||
facilities
.
throughput
>
0xDD
)
break
;
if
(
facilities
.
reverse
&&
facilities
.
reverse
!=
1
)
break
;
x25
->
facilities
=
facilities
;
return
0
;
rc
=
0
;
break
;
}
case
SIOCX25GCALLUSERDATA
:
{
struct
x25_calluserdata
calluserdata
;
calluserdata
=
x25
->
calluserdata
;
return
copy_to_user
((
void
*
)
arg
,
&
calluserdata
,
sizeof
(
calluserdata
))
?
-
EFAULT
:
0
;
struct
x25_calluserdata
c
ud
=
x25
->
c
alluserdata
;
rc
=
copy_to_user
((
void
*
)
arg
,
&
cud
,
sizeof
(
cud
))
?
-
EFAULT
:
0
;
break
;
}
case
SIOCX25SCALLUSERDATA
:
{
struct
x25_calluserdata
calluserdata
;
rc
=
-
EFAULT
;
if
(
copy_from_user
(
&
calluserdata
,
(
void
*
)
arg
,
sizeof
(
calluserdata
)))
return
-
EFAULT
;
break
;
rc
=
-
EINVAL
;
if
(
calluserdata
.
cudlength
>
X25_MAX_CUD_LEN
)
return
-
EINVAL
;
break
;
x25
->
calluserdata
=
calluserdata
;
return
0
;
rc
=
0
;
break
;
}
case
SIOCX25GCAUSEDIAG
:
{
struct
x25_causediag
causediag
;
causediag
=
x25
->
causediag
;
return
copy_to_user
((
void
*
)
arg
,
&
causediag
,
sizeof
(
causediag
))
?
-
EFAULT
:
0
;
rc
=
copy_to_user
((
void
*
)
arg
,
&
causediag
,
sizeof
(
causediag
))
?
-
EFAULT
:
0
;
break
;
}
default:
return
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
rc
=
dev_ioctl
(
cmd
,
(
void
*
)
arg
);
break
;
}
/*NOTREACHED*/
return
0
;
return
rc
;
}
static
int
x25_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
...
...
@@ -1220,15 +1256,16 @@ 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
=
0
;
int
len
;
off_t
pos
=
0
;
off_t
begin
=
0
;
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
"
);
len
=
sprintf
(
buffer
,
"dest_addr src_addr dev lci st vs vr va "
"t t2 t21 t22 t23 Snd-Q Rcv-Q inode
\n
"
);
for
(
s
=
x25_list
;
s
!=
NULL
;
s
=
s
->
next
)
{
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
{
x25_cb
*
x25
=
x25_sk
(
s
);
if
(
!
x25
->
neighbour
||
(
dev
=
x25
->
neighbour
->
dev
)
==
NULL
)
...
...
@@ -1236,7 +1273,9 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
else
devname
=
x25
->
neighbour
->
dev
->
name
;
len
+=
sprintf
(
buffer
+
len
,
"%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu %3lu %3lu %3lu %5d %5d %ld
\n
"
,
len
+=
sprintf
(
buffer
+
len
,
"%-10s %-10s %-5s %3.3X %d %d "
"%d %d %3lu %3lu %3lu %3lu %3lu "
"%5d %5d %ld
\n
"
,
!
x25
->
dest_addr
.
x25_addr
[
0
]
?
"*"
:
x25
->
dest_addr
.
x25_addr
,
!
x25
->
source_addr
.
x25_addr
[
0
]
?
"*"
:
...
...
@@ -1254,7 +1293,7 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
x25
->
t23
/
HZ
,
atomic_read
(
&
s
->
wmem_alloc
),
atomic_read
(
&
s
->
rmem_alloc
),
s
->
socket
!=
NULL
?
SOCK_INODE
(
s
->
socket
)
->
i_ino
:
0L
);
s
->
socket
?
SOCK_INODE
(
s
->
socket
)
->
i_ino
:
0L
);
pos
=
begin
+
len
;
...
...
@@ -1272,9 +1311,10 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
if
(
len
>
length
)
len
=
length
;
if
(
len
>
length
)
len
=
length
;
return
(
len
)
;
return
len
;
}
struct
net_proto_family
x25_family_ops
=
{
...
...
@@ -1313,17 +1353,16 @@ static struct packet_type x25_packet_type = {
};
struct
notifier_block
x25_dev_notifier
=
{
.
notifier_call
=
x25_device_event
,
.
notifier_call
=
x25_device_event
,
};
void
x25_kill_by_neigh
(
struct
x25_neigh
*
neigh
)
{
struct
sock
*
s
;
for
(
s
=
x25_list
;
s
!=
NULL
;
s
=
s
->
next
){
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
neighbour
==
neigh
)
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
}
}
static
int
__init
x25_init
(
void
)
...
...
@@ -1351,7 +1390,7 @@ static int __init x25_init(void)
* Register any pre existing devices.
*/
read_lock
(
&
dev_base_lock
);
for
(
dev
=
dev_base
;
dev
!=
NULL
;
dev
=
dev
->
next
)
{
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
{
if
((
dev
->
flags
&
IFF_UP
)
&&
(
dev
->
type
==
ARPHRD_X25
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
||
dev
->
type
==
ARPHRD_ETHER
...
...
net/x25/x25_in.c
View file @
229e0840
...
...
@@ -98,7 +98,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
*/
static
int
x25_state1_machine
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
int
frametype
)
{
x25_address
source_addr
,
dest_addr
;
struct
x25_address
source_addr
,
dest_addr
;
switch
(
frametype
)
{
case
X25_CALL_ACCEPTED
:
{
...
...
net/x25/x25_route.c
View file @
229e0840
...
...
@@ -48,7 +48,8 @@ static struct x25_route *x25_route_list /* = NULL initially */;
/*
* Add a new route.
*/
static
int
x25_add_route
(
x25_address
*
address
,
unsigned
int
sigdigits
,
struct
net_device
*
dev
)
static
int
x25_add_route
(
struct
x25_address
*
address
,
unsigned
int
sigdigits
,
struct
net_device
*
dev
)
{
struct
x25_route
*
x25_route
;
unsigned
long
flags
;
...
...
@@ -103,7 +104,8 @@ static void x25_remove_route(struct x25_route *x25_route)
restore_flags
(
flags
);
}
static
int
x25_del_route
(
x25_address
*
address
,
unsigned
int
sigdigits
,
struct
net_device
*
dev
)
static
int
x25_del_route
(
struct
x25_address
*
address
,
unsigned
int
sigdigits
,
struct
net_device
*
dev
)
{
struct
x25_route
*
x25_route
;
...
...
@@ -158,7 +160,7 @@ struct net_device *x25_dev_get(char *devname)
/*
* Find a device given an X.25 address.
*/
struct
net_device
*
x25_get_route
(
x25_address
*
addr
)
struct
net_device
*
x25_get_route
(
struct
x25_address
*
addr
)
{
struct
x25_route
*
route
,
*
use
=
NULL
;
...
...
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