Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
fb395884
Commit
fb395884
authored
Jun 20, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
parents
91b90475
246955fe
Changes
40
Show whitespace changes
Inline
Side-by-side
Showing
40 changed files
with
839 additions
and
318 deletions
+839
-318
include/linux/atalk.h
include/linux/atalk.h
+13
-13
include/linux/netlink.h
include/linux/netlink.h
+1
-0
include/linux/pfkeyv2.h
include/linux/pfkeyv2.h
+1
-0
include/linux/xfrm.h
include/linux/xfrm.h
+1
-0
include/net/ax25.h
include/net/ax25.h
+1
-1
include/net/ip_fib.h
include/net/ip_fib.h
+14
-0
include/net/sctp/command.h
include/net/sctp/command.h
+4
-4
include/net/sctp/constants.h
include/net/sctp/constants.h
+0
-7
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+17
-0
include/net/sctp/sm.h
include/net/sctp/sm.h
+6
-2
include/net/sctp/structs.h
include/net/sctp/structs.h
+32
-9
include/net/sctp/user.h
include/net/sctp/user.h
+3
-0
include/net/xfrm.h
include/net/xfrm.h
+3
-1
net/appletalk/aarp.c
net/appletalk/aarp.c
+1
-1
net/appletalk/ddp.c
net/appletalk/ddp.c
+1
-1
net/ipv4/ah4.c
net/ipv4/ah4.c
+1
-1
net/ipv4/esp4.c
net/ipv4/esp4.c
+1
-1
net/ipv4/fib_frontend.c
net/ipv4/fib_frontend.c
+55
-0
net/ipv4/ipcomp.c
net/ipv4/ipcomp.c
+3
-8
net/ipv4/xfrm4_output.c
net/ipv4/xfrm4_output.c
+6
-2
net/ipv4/xfrm4_state.c
net/ipv4/xfrm4_state.c
+9
-0
net/ipv4/xfrm4_tunnel.c
net/ipv4/xfrm4_tunnel.c
+1
-1
net/ipv6/ah6.c
net/ipv6/ah6.c
+1
-1
net/ipv6/esp6.c
net/ipv6/esp6.c
+1
-1
net/ipv6/ipcomp6.c
net/ipv6/ipcomp6.c
+2
-7
net/ipv6/xfrm6_tunnel.c
net/ipv6/xfrm6_tunnel.c
+1
-1
net/key/af_key.c
net/key/af_key.c
+7
-9
net/sctp/associola.c
net/sctp/associola.c
+114
-37
net/sctp/endpointola.c
net/sctp/endpointola.c
+0
-1
net/sctp/input.c
net/sctp/input.c
+1
-1
net/sctp/outqueue.c
net/sctp/outqueue.c
+6
-5
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+16
-4
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+85
-20
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+98
-50
net/sctp/sm_statetable.c
net/sctp/sm_statetable.c
+4
-2
net/sctp/socket.c
net/sctp/socket.c
+288
-117
net/sctp/transport.c
net/sctp/transport.c
+3
-1
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_policy.c
+0
-1
net/xfrm/xfrm_state.c
net/xfrm/xfrm_state.c
+37
-0
net/xfrm/xfrm_user.c
net/xfrm/xfrm_user.c
+1
-8
No files found.
include/linux/atalk.h
View file @
fb395884
...
...
@@ -20,7 +20,7 @@
#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
struct
atalk_addr
{
__
u
16
s_net
;
__
be
16
s_net
;
__u8
s_node
;
};
...
...
@@ -33,8 +33,8 @@ struct sockaddr_at {
struct
atalk_netrange
{
__u8
nr_phase
;
__
u
16
nr_firstnet
;
__
u
16
nr_lastnet
;
__
be
16
nr_firstnet
;
__
be
16
nr_lastnet
;
};
#ifdef __KERNEL__
...
...
@@ -70,8 +70,8 @@ struct atalk_iface {
struct
atalk_sock
{
/* struct sock has to be the first member of atalk_sock */
struct
sock
sk
;
unsigned
short
dest_net
;
unsigned
short
src_net
;
__be16
dest_net
;
__be16
src_net
;
unsigned
char
dest_node
;
unsigned
char
src_node
;
unsigned
char
dest_port
;
...
...
@@ -95,9 +95,9 @@ struct ddpehdr {
deh_hops:
4
,
deh_len:
10
;
#endif
__
u
16
deh_sum
;
__
u
16
deh_dnet
;
__
u
16
deh_snet
;
__
be
16
deh_sum
;
__
be
16
deh_dnet
;
__
be
16
deh_snet
;
__u8
deh_dnode
;
__u8
deh_snode
;
__u8
deh_dport
;
...
...
@@ -142,24 +142,24 @@ struct ddpshdr {
/* AppleTalk AARP headers */
struct
elapaarp
{
__
u
16
hw_type
;
__
be
16
hw_type
;
#define AARP_HW_TYPE_ETHERNET 1
#define AARP_HW_TYPE_TOKENRING 2
__
u
16
pa_type
;
__
be
16
pa_type
;
__u8
hw_len
;
__u8
pa_len
;
#define AARP_PA_ALEN 4
__
u
16
function
;
__
be
16
function
;
#define AARP_REQUEST 1
#define AARP_REPLY 2
#define AARP_PROBE 3
__u8
hw_src
[
ETH_ALEN
]
__attribute__
((
packed
));
__u8
pa_src_zero
__attribute__
((
packed
));
__
u
16
pa_src_net
__attribute__
((
packed
));
__
be
16
pa_src_net
__attribute__
((
packed
));
__u8
pa_src_node
__attribute__
((
packed
));
__u8
hw_dst
[
ETH_ALEN
]
__attribute__
((
packed
));
__u8
pa_dst_zero
__attribute__
((
packed
));
__
u
16
pa_dst_net
__attribute__
((
packed
));
__
be
16
pa_dst_net
__attribute__
((
packed
));
__u8
pa_dst_node
__attribute__
((
packed
));
};
...
...
include/linux/netlink.h
View file @
fb395884
...
...
@@ -14,6 +14,7 @@
#define NETLINK_SELINUX 7
/* SELinux event notifications */
#define NETLINK_ARPD 8
#define NETLINK_AUDIT 9
/* auditing */
#define NETLINK_FIB_LOOKUP 10
#define NETLINK_ROUTE6 11
/* af_inet6 route comm channel */
#define NETLINK_IP6_FW 13
#define NETLINK_DNRTMSG 14
/* DECnet routing messages */
...
...
include/linux/pfkeyv2.h
View file @
fb395884
...
...
@@ -245,6 +245,7 @@ struct sadb_x_nat_t_port {
/* Security Association flags */
#define SADB_SAFLAGS_PFS 1
#define SADB_SAFLAGS_NOPMTUDISC 0x20000000
#define SADB_SAFLAGS_DECAP_DSCP 0x40000000
#define SADB_SAFLAGS_NOECN 0x80000000
...
...
include/linux/xfrm.h
View file @
fb395884
...
...
@@ -196,6 +196,7 @@ struct xfrm_usersa_info {
__u8
flags
;
#define XFRM_STATE_NOECN 1
#define XFRM_STATE_DECAP_DSCP 2
#define XFRM_STATE_NOPMTUDISC 4
};
struct
xfrm_usersa_id
{
...
...
include/net/ax25.h
View file @
fb395884
...
...
@@ -220,7 +220,7 @@ static __inline__ void ax25_cb_put(ax25_cb *ax25)
}
}
static
inline
unsigned
short
ax25_type_trans
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
static
inline
__be16
ax25_type_trans
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
skb
->
dev
=
dev
;
skb
->
pkt_type
=
PACKET_HOST
;
...
...
include/net/ip_fib.h
View file @
fb395884
...
...
@@ -109,6 +109,20 @@ struct fib_result {
#endif
};
struct
fib_result_nl
{
u32
fl_addr
;
/* To be looked up*/
u32
fl_fwmark
;
unsigned
char
fl_tos
;
unsigned
char
fl_scope
;
unsigned
char
tb_id_in
;
unsigned
char
tb_id
;
/* Results */
unsigned
char
prefixlen
;
unsigned
char
nh_sel
;
unsigned
char
type
;
unsigned
char
scope
;
int
err
;
};
#ifdef CONFIG_IP_ROUTE_MULTIPATH
...
...
include/net/sctp/command.h
View file @
fb395884
...
...
@@ -65,9 +65,11 @@ typedef enum {
SCTP_CMD_TIMER_START
,
/* Start a timer. */
SCTP_CMD_TIMER_RESTART
,
/* Restart a timer. */
SCTP_CMD_TIMER_STOP
,
/* Stop a timer. */
SCTP_CMD_COUNTER_RESET
,
/* Reset a counter. */
SCTP_CMD_COUNTER_INC
,
/* Increment a counter. */
SCTP_CMD_INIT_CHOOSE_TRANSPORT
,
/* Choose transport for an INIT. */
SCTP_CMD_INIT_COUNTER_RESET
,
/* Reset init counter. */
SCTP_CMD_INIT_COUNTER_INC
,
/* Increment init counter. */
SCTP_CMD_INIT_RESTART
,
/* High level, do init timer work. */
SCTP_CMD_COOKIEECHO_RESTART
,
/* High level, do cookie-echo timer work. */
SCTP_CMD_INIT_FAILED
,
/* High level, do init failure work. */
SCTP_CMD_REPORT_DUP
,
/* Report a duplicate TSN. */
SCTP_CMD_STRIKE
,
/* Mark a strike against a transport. */
...
...
@@ -118,7 +120,6 @@ typedef union {
int
error
;
sctp_state_t
state
;
sctp_event_timeout_t
to
;
sctp_counter_t
counter
;
void
*
ptr
;
struct
sctp_chunk
*
chunk
;
struct
sctp_association
*
asoc
;
...
...
@@ -165,7 +166,6 @@ SCTP_ARG_CONSTRUCTOR(U16, __u16, u16)
SCTP_ARG_CONSTRUCTOR
(
U8
,
__u8
,
u8
)
SCTP_ARG_CONSTRUCTOR
(
ERROR
,
int
,
error
)
SCTP_ARG_CONSTRUCTOR
(
STATE
,
sctp_state_t
,
state
)
SCTP_ARG_CONSTRUCTOR
(
COUNTER
,
sctp_counter_t
,
counter
)
SCTP_ARG_CONSTRUCTOR
(
TO
,
sctp_event_timeout_t
,
to
)
SCTP_ARG_CONSTRUCTOR
(
PTR
,
void
*
,
ptr
)
SCTP_ARG_CONSTRUCTOR
(
CHUNK
,
struct
sctp_chunk
*
,
chunk
)
...
...
include/net/sctp/constants.h
View file @
fb395884
...
...
@@ -263,13 +263,6 @@ enum { SCTP_MIN_PMTU = 576 };
enum
{
SCTP_MAX_DUP_TSNS
=
16
};
enum
{
SCTP_MAX_GABS
=
16
};
typedef
enum
{
SCTP_COUNTER_INIT_ERROR
,
}
sctp_counter_t
;
/* How many counters does an association need? */
#define SCTP_NUMBER_COUNTERS 5
/* Here we define the default timers. */
/* cookie timer def = ? seconds */
...
...
include/net/sctp/sctp.h
View file @
fb395884
...
...
@@ -223,6 +223,22 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics);
extern
int
sctp_debug_flag
;
#define SCTP_DEBUG_PRINTK(whatever...) \
((void) (sctp_debug_flag && printk(KERN_DEBUG whatever)))
#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \
if (sctp_debug_flag) { \
if (saddr->sa.sa_family == AF_INET6) { \
printk(KERN_DEBUG \
lead "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" trail, \
leadparm, \
NIP6(saddr->v6.sin6_addr), \
otherparms); \
} else { \
printk(KERN_DEBUG \
lead "%u.%u.%u.%u" trail, \
leadparm, \
NIPQUAD(saddr->v4.sin_addr.s_addr), \
otherparms); \
} \
}
#define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; }
#define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; }
...
...
@@ -236,6 +252,7 @@ extern int sctp_debug_flag;
#else
/* SCTP_DEBUG */
#define SCTP_DEBUG_PRINTK(whatever...)
#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
#define SCTP_ENABLE_DEBUG
#define SCTP_DISABLE_DEBUG
#define SCTP_ASSERT(expr, str, func)
...
...
include/net/sctp/sm.h
View file @
fb395884
...
...
@@ -116,7 +116,8 @@ sctp_state_fn_t sctp_sf_eat_data_fast_4_4;
sctp_state_fn_t
sctp_sf_eat_sack_6_2
;
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_t1_init_timer_expire
;
sctp_state_fn_t
sctp_sf_t1_cookie_timer_expire
;
sctp_state_fn_t
sctp_sf_t2_timer_expire
;
sctp_state_fn_t
sctp_sf_t4_timer_expire
;
sctp_state_fn_t
sctp_sf_t5_timer_expire
;
...
...
@@ -258,7 +259,10 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
void
sctp_chunk_assign_tsn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_ssn
(
struct
sctp_chunk
*
);
void
sctp_stop_t1_and_abort
(
sctp_cmd_seq_t
*
commands
,
__u16
error
);
sctp_disposition_t
sctp_stop_t1_and_abort
(
sctp_cmd_seq_t
*
commands
,
__u16
error
,
const
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
transport
);
/* Prototypes for statetable processing. */
...
...
include/net/sctp/structs.h
View file @
fb395884
...
...
@@ -867,10 +867,13 @@ struct sctp_transport {
*/
unsigned
long
last_time_ecne_reduced
;
/* active : The current active state of this destination,
* : i.e. DOWN, UP, etc.
/* The number of times INIT has been sent on this transport. */
int
init_sent_count
;
/* state : The current state of this destination,
* : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN.
*/
int
activ
e
;
int
stat
e
;
/* hb_allowed : The current heartbeat state of this destination,
* : i.e. ALLOW-HB, NO-HEARTBEAT, etc.
...
...
@@ -1222,9 +1225,6 @@ struct sctp_endpoint {
/* sendbuf acct. policy. */
__u32
sndbuf_policy
;
/* Name for debugging output... */
char
*
debug_name
;
};
/* Recover the outter endpoint structure. */
...
...
@@ -1314,11 +1314,23 @@ struct sctp_association {
* : association. Normally this information is
* : hashed or keyed for quick lookup and access
* : of the TCB.
* : The list is also initialized with the list
* : of addresses passed with the sctp_connectx()
* : call.
*
* It is a list of SCTP_transport's.
*/
struct
list_head
transport_addr_list
;
/* transport_count
*
* Peer : A count of the number of peer addresses
* Transport : in the Peer Transport Address List.
* Address :
* Count :
*/
__u16
transport_count
;
/* port
* The transport layer port number.
*/
...
...
@@ -1486,6 +1498,9 @@ struct sctp_association {
/* Transport to which SHUTDOWN chunk was last sent. */
struct
sctp_transport
*
shutdown_last_sent_to
;
/* Transport to which INIT chunk was last sent. */
struct
sctp_transport
*
init_last_sent_to
;
/* Next TSN : The next TSN number to be assigned to a new
* : DATA chunk. This is sent in the INIT or INIT
* : ACK chunk to the peer and incremented each
...
...
@@ -1549,8 +1564,11 @@ struct sctp_association {
/* The message size at which SCTP fragmentation will occur. */
__u32
frag_point
;
/* Currently only one counter is used to count INIT errors. */
int
counters
[
SCTP_NUMBER_COUNTERS
];
/* Counter used to count INIT errors. */
int
init_err_counter
;
/* Count the number of INIT cycles (for doubling timeout). */
int
init_cycle
;
/* Default send parameters. */
__u16
default_stream
;
...
...
@@ -1708,6 +1726,8 @@ void sctp_association_free(struct sctp_association *);
void
sctp_association_put
(
struct
sctp_association
*
);
void
sctp_association_hold
(
struct
sctp_association
*
);
struct
sctp_transport
*
sctp_assoc_choose_init_transport
(
struct
sctp_association
*
);
struct
sctp_transport
*
sctp_assoc_choose_shutdown_transport
(
struct
sctp_association
*
);
void
sctp_assoc_update_retran_path
(
struct
sctp_association
*
);
...
...
@@ -1717,9 +1737,12 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
const
union
sctp_addr
*
laddr
);
struct
sctp_transport
*
sctp_assoc_add_peer
(
struct
sctp_association
*
,
const
union
sctp_addr
*
address
,
const
int
gfp
);
const
int
gfp
,
const
int
peer_state
);
void
sctp_assoc_del_peer
(
struct
sctp_association
*
asoc
,
const
union
sctp_addr
*
addr
);
void
sctp_assoc_rm_peer
(
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
peer
);
void
sctp_assoc_control_transport
(
struct
sctp_association
*
,
struct
sctp_transport
*
,
sctp_transport_cmd_t
,
sctp_sn_error_t
);
...
...
include/net/sctp/user.h
View file @
fb395884
...
...
@@ -111,6 +111,8 @@ enum sctp_optname {
#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM
SCTP_GET_LOCAL_ADDRS
,
/* Get all local addresss. */
#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS
SCTP_SOCKOPT_CONNECTX
,
/* CONNECTX requests. */
#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX
};
/*
...
...
@@ -527,6 +529,7 @@ struct sctp_paddrinfo {
enum
sctp_spinfo_state
{
SCTP_INACTIVE
,
SCTP_ACTIVE
,
SCTP_UNKNOWN
=
0xffff
/* Value used for transport state unknown */
};
/*
...
...
include/net/xfrm.h
View file @
fb395884
...
...
@@ -204,6 +204,7 @@ struct xfrm_state_afinfo {
rwlock_t
lock
;
struct
list_head
*
state_bydst
;
struct
list_head
*
state_byspi
;
int
(
*
init_flags
)(
struct
xfrm_state
*
x
);
void
(
*
init_tempsel
)(
struct
xfrm_state
*
x
,
struct
flowi
*
fl
,
struct
xfrm_tmpl
*
tmpl
,
xfrm_address_t
*
daddr
,
xfrm_address_t
*
saddr
);
...
...
@@ -225,7 +226,7 @@ struct xfrm_type
struct
module
*
owner
;
__u8
proto
;
int
(
*
init_state
)(
struct
xfrm_state
*
x
,
void
*
args
);
int
(
*
init_state
)(
struct
xfrm_state
*
x
);
void
(
*
destructor
)(
struct
xfrm_state
*
);
int
(
*
input
)(
struct
xfrm_state
*
,
struct
xfrm_decap_state
*
,
struct
sk_buff
*
skb
);
int
(
*
post_input
)(
struct
xfrm_state
*
,
struct
xfrm_decap_state
*
,
struct
sk_buff
*
skb
);
...
...
@@ -839,6 +840,7 @@ extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
extern
void
xfrm_replay_advance
(
struct
xfrm_state
*
x
,
u32
seq
);
extern
int
xfrm_state_check
(
struct
xfrm_state
*
x
,
struct
sk_buff
*
skb
);
extern
int
xfrm_state_mtu
(
struct
xfrm_state
*
x
,
int
mtu
);
extern
int
xfrm_init_state
(
struct
xfrm_state
*
x
);
extern
int
xfrm4_rcv
(
struct
sk_buff
*
skb
);
extern
int
xfrm4_output
(
struct
sk_buff
*
skb
);
extern
int
xfrm4_tunnel_register
(
struct
xfrm_tunnel
*
handler
);
...
...
net/appletalk/aarp.c
View file @
fb395884
...
...
@@ -565,7 +565,7 @@ int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb,
* numbers we just happen to need. Now put the
* length in the lower two.
*/
*
((
__
u
16
*
)
skb
->
data
)
=
htons
(
skb
->
len
);
*
((
__
be
16
*
)
skb
->
data
)
=
htons
(
skb
->
len
);
ft
=
1
;
}
/*
...
...
net/appletalk/ddp.c
View file @
fb395884
...
...
@@ -401,7 +401,7 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
}
/* Find a match for a specific network:node pair */
static
struct
atalk_iface
*
atalk_find_interface
(
int
net
,
int
node
)
static
struct
atalk_iface
*
atalk_find_interface
(
__be16
net
,
int
node
)
{
struct
atalk_iface
*
iface
;
...
...
net/ipv4/ah4.c
View file @
fb395884
...
...
@@ -200,7 +200,7 @@ static void ah4_err(struct sk_buff *skb, u32 info)
xfrm_state_put
(
x
);
}
static
int
ah_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
ah_init_state
(
struct
xfrm_state
*
x
)
{
struct
ah_data
*
ahp
=
NULL
;
struct
xfrm_algo_desc
*
aalg_desc
;
...
...
net/ipv4/esp4.c
View file @
fb395884
...
...
@@ -362,7 +362,7 @@ static void esp_destroy(struct xfrm_state *x)
kfree
(
esp
);
}
static
int
esp_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
esp_init_state
(
struct
xfrm_state
*
x
)
{
struct
esp_data
*
esp
=
NULL
;
...
...
net/ipv4/fib_frontend.c
View file @
fb395884
...
...
@@ -516,6 +516,60 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
#undef BRD1_OK
}
static
void
nl_fib_lookup
(
struct
fib_result_nl
*
frn
,
struct
fib_table
*
tb
)
{
struct
fib_result
res
;
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
frn
->
fl_addr
,
.
fwmark
=
frn
->
fl_fwmark
,
.
tos
=
frn
->
fl_tos
,
.
scope
=
frn
->
fl_scope
}
}
};
if
(
tb
)
{
local_bh_disable
();
frn
->
tb_id
=
tb
->
tb_id
;
frn
->
err
=
tb
->
tb_lookup
(
tb
,
&
fl
,
&
res
);
if
(
!
frn
->
err
)
{
frn
->
prefixlen
=
res
.
prefixlen
;
frn
->
nh_sel
=
res
.
nh_sel
;
frn
->
type
=
res
.
type
;
frn
->
scope
=
res
.
scope
;
}
local_bh_enable
();
}
}
static
void
nl_fib_input
(
struct
sock
*
sk
,
int
len
)
{
struct
sk_buff
*
skb
=
NULL
;
struct
nlmsghdr
*
nlh
=
NULL
;
struct
fib_result_nl
*
frn
;
int
err
;
u32
pid
;
struct
fib_table
*
tb
;
skb
=
skb_recv_datagram
(
sk
,
0
,
0
,
&
err
);
nlh
=
(
struct
nlmsghdr
*
)
skb
->
data
;
frn
=
(
struct
fib_result_nl
*
)
NLMSG_DATA
(
nlh
);
tb
=
fib_get_table
(
frn
->
tb_id_in
);
nl_fib_lookup
(
frn
,
tb
);
pid
=
nlh
->
nlmsg_pid
;
/*pid of sending process */
NETLINK_CB
(
skb
).
groups
=
0
;
/* not in mcast group */
NETLINK_CB
(
skb
).
pid
=
0
;
/* from kernel */
NETLINK_CB
(
skb
).
dst_pid
=
pid
;
NETLINK_CB
(
skb
).
dst_groups
=
0
;
/* unicast */
netlink_unicast
(
sk
,
skb
,
pid
,
MSG_DONTWAIT
);
}
static
void
nl_fib_lookup_init
(
void
)
{
netlink_kernel_create
(
NETLINK_FIB_LOOKUP
,
nl_fib_input
);
}
static
void
fib_disable_ip
(
struct
net_device
*
dev
,
int
force
)
{
if
(
fib_sync_down
(
0
,
dev
,
force
))
...
...
@@ -604,6 +658,7 @@ void __init ip_fib_init(void)
register_netdevice_notifier
(
&
fib_netdev_notifier
);
register_inetaddr_notifier
(
&
fib_inetaddr_notifier
);
nl_fib_lookup_init
();
}
EXPORT_SYMBOL
(
inet_addr_type
);
...
...
net/ipv4/ipcomp.c
View file @
fb395884
...
...
@@ -237,14 +237,9 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t
->
props
.
saddr
.
a4
=
x
->
props
.
saddr
.
a4
;
t
->
props
.
flags
=
x
->
props
.
flags
;
t
->
type
=
xfrm_get_type
(
IPPROTO_IPIP
,
t
->
props
.
family
);
if
(
t
->
type
==
NULL
)
if
(
xfrm_init_state
(
t
))
goto
error
;
if
(
t
->
type
->
init_state
(
t
,
NULL
))
goto
error
;
t
->
km
.
state
=
XFRM_STATE_VALID
;
atomic_set
(
&
t
->
tunnel_users
,
1
);
out:
return
t
;
...
...
@@ -422,7 +417,7 @@ static void ipcomp_destroy(struct xfrm_state *x)
kfree
(
ipcd
);
}
static
int
ipcomp_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
ipcomp_init_state
(
struct
xfrm_state
*
x
)
{
int
err
;
struct
ipcomp_data
*
ipcd
;
...
...
net/ipv4/xfrm4_output.c
View file @
fb395884
...
...
@@ -33,6 +33,7 @@ static void xfrm4_encap(struct sk_buff *skb)
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
xfrm_state
*
x
=
dst
->
xfrm
;
struct
iphdr
*
iph
,
*
top_iph
;
int
flags
;
iph
=
skb
->
nh
.
iph
;
skb
->
h
.
ipiph
=
iph
;
...
...
@@ -51,10 +52,13 @@ static void xfrm4_encap(struct sk_buff *skb)
/* DS disclosed */
top_iph
->
tos
=
INET_ECN_encapsulate
(
iph
->
tos
,
iph
->
tos
);
if
(
x
->
props
.
flags
&
XFRM_STATE_NOECN
)
flags
=
x
->
props
.
flags
;
if
(
flags
&
XFRM_STATE_NOECN
)
IP_ECN_clear
(
top_iph
);
top_iph
->
frag_off
=
iph
->
frag_off
&
htons
(
IP_DF
);
top_iph
->
frag_off
=
(
flags
&
XFRM_STATE_NOPMTUDISC
)
?
0
:
(
iph
->
frag_off
&
htons
(
IP_DF
));
if
(
!
top_iph
->
frag_off
)
__ip_select_ident
(
top_iph
,
dst
,
0
);
...
...
net/ipv4/xfrm4_state.c
View file @
fb395884
...
...
@@ -7,12 +7,20 @@
*
*/
#include <net/ip.h>
#include <net/xfrm.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>
static
struct
xfrm_state_afinfo
xfrm4_state_afinfo
;
static
int
xfrm4_init_flags
(
struct
xfrm_state
*
x
)
{
if
(
ipv4_config
.
no_pmtu_disc
)
x
->
props
.
flags
|=
XFRM_STATE_NOPMTUDISC
;
return
0
;
}
static
void
__xfrm4_init_tempsel
(
struct
xfrm_state
*
x
,
struct
flowi
*
fl
,
struct
xfrm_tmpl
*
tmpl
,
...
...
@@ -109,6 +117,7 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto,
static
struct
xfrm_state_afinfo
xfrm4_state_afinfo
=
{
.
family
=
AF_INET
,
.
lock
=
RW_LOCK_UNLOCKED
,
.
init_flags
=
xfrm4_init_flags
,
.
init_tempsel
=
__xfrm4_init_tempsel
,
.
state_lookup
=
__xfrm4_state_lookup
,
.
find_acq
=
__xfrm4_find_acq
,
...
...
net/ipv4/xfrm4_tunnel.c
View file @
fb395884
...
...
@@ -84,7 +84,7 @@ static void ipip_err(struct sk_buff *skb, u32 info)
handler
->
err_handler
(
skb
,
&
arg
);
}
static
int
ipip_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
ipip_init_state
(
struct
xfrm_state
*
x
)
{
if
(
!
x
->
props
.
mode
)
return
-
EINVAL
;
...
...
net/ipv6/ah6.c
View file @
fb395884
...
...
@@ -339,7 +339,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
xfrm_state_put
(
x
);
}
static
int
ah6_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
ah6_init_state
(
struct
xfrm_state
*
x
)
{
struct
ah_data
*
ahp
=
NULL
;
struct
xfrm_algo_desc
*
aalg_desc
;
...
...
net/ipv6/esp6.c
View file @
fb395884
...
...
@@ -296,7 +296,7 @@ static void esp6_destroy(struct xfrm_state *x)
kfree
(
esp
);
}
static
int
esp6_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
esp6_init_state
(
struct
xfrm_state
*
x
)
{
struct
esp_data
*
esp
=
NULL
;
...
...
net/ipv6/ipcomp6.c
View file @
fb395884
...
...
@@ -234,14 +234,9 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
t
->
props
.
mode
=
1
;
memcpy
(
t
->
props
.
saddr
.
a6
,
x
->
props
.
saddr
.
a6
,
sizeof
(
struct
in6_addr
));
t
->
type
=
xfrm_get_type
(
IPPROTO_IPV6
,
t
->
props
.
family
);
if
(
t
->
type
==
NULL
)
if
(
xfrm_init_state
(
t
))
goto
error
;
if
(
t
->
type
->
init_state
(
t
,
NULL
))
goto
error
;
t
->
km
.
state
=
XFRM_STATE_VALID
;
atomic_set
(
&
t
->
tunnel_users
,
1
);
out:
...
...
@@ -420,7 +415,7 @@ static void ipcomp6_destroy(struct xfrm_state *x)
xfrm6_tunnel_free_spi
((
xfrm_address_t
*
)
&
x
->
props
.
saddr
);
}
static
int
ipcomp6_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
ipcomp6_init_state
(
struct
xfrm_state
*
x
)
{
int
err
;
struct
ipcomp_data
*
ipcd
;
...
...
net/ipv6/xfrm6_tunnel.c
View file @
fb395884
...
...
@@ -466,7 +466,7 @@ static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return
;
}
static
int
xfrm6_tunnel_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
xfrm6_tunnel_init_state
(
struct
xfrm_state
*
x
)
{
if
(
!
x
->
props
.
mode
)
return
-
EINVAL
;
...
...
net/key/af_key.c
View file @
fb395884
...
...
@@ -690,6 +690,8 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
sa
->
sadb_sa_flags
|=
SADB_SAFLAGS_NOECN
;
if
(
x
->
props
.
flags
&
XFRM_STATE_DECAP_DSCP
)
sa
->
sadb_sa_flags
|=
SADB_SAFLAGS_DECAP_DSCP
;
if
(
x
->
props
.
flags
&
XFRM_STATE_NOPMTUDISC
)
sa
->
sadb_sa_flags
|=
SADB_SAFLAGS_NOPMTUDISC
;
/* hard time */
if
(
hsc
&
2
)
{
...
...
@@ -974,6 +976,8 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
x
->
props
.
flags
|=
XFRM_STATE_NOECN
;
if
(
sa
->
sadb_sa_flags
&
SADB_SAFLAGS_DECAP_DSCP
)
x
->
props
.
flags
|=
XFRM_STATE_DECAP_DSCP
;
if
(
sa
->
sadb_sa_flags
&
SADB_SAFLAGS_NOPMTUDISC
)
x
->
props
.
flags
|=
XFRM_STATE_NOPMTUDISC
;
lifetime
=
(
struct
sadb_lifetime
*
)
ext_hdrs
[
SADB_EXT_LIFETIME_HARD
-
1
];
if
(
lifetime
!=
NULL
)
{
...
...
@@ -1096,17 +1100,11 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
}
}
x
->
type
=
xfrm_get_type
(
proto
,
x
->
props
.
family
);
if
(
x
->
type
==
NULL
)
{
err
=
-
ENOPROTOOPT
;
goto
out
;
}
if
(
x
->
type
->
init_state
(
x
,
NULL
))
{
err
=
-
EINVAL
;
err
=
xfrm_init_state
(
x
);
if
(
err
)
goto
out
;
}
x
->
km
.
seq
=
hdr
->
sadb_msg_seq
;
x
->
km
.
state
=
XFRM_STATE_VALID
;
return
x
;
out:
...
...
net/sctp/associola.c
View file @
fb395884
...
...
@@ -191,10 +191,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc
->
last_cwr_tsn
=
asoc
->
ctsn_ack_point
;
asoc
->
unack_data
=
0
;
SCTP_DEBUG_PRINTK
(
"myctsnap for %s INIT as 0x%x.
\n
"
,
asoc
->
ep
->
debug_name
,
asoc
->
ctsn_ack_point
);
/* ADDIP Section 4.1 Asconf Chunk Procedures
*
* When an endpoint has an ASCONF signaled change to be sent to the
...
...
@@ -211,6 +207,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
/* Make an empty list of remote transport addresses. */
INIT_LIST_HEAD
(
&
asoc
->
peer
.
transport_addr_list
);
asoc
->
peer
.
transport_count
=
0
;
/* RFC 2960 5.1 Normal Establishment of an Association
*
...
...
@@ -288,6 +285,7 @@ struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
asoc
->
base
.
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
assoc
);
SCTP_DEBUG_PRINTK
(
"Created asoc %p
\n
"
,
asoc
);
return
asoc
;
...
...
@@ -356,6 +354,8 @@ void sctp_association_free(struct sctp_association *asoc)
sctp_transport_free
(
transport
);
}
asoc
->
peer
.
transport_count
=
0
;
/* Free any cached ASCONF_ACK chunk. */
if
(
asoc
->
addip_last_asconf_ack
)
sctp_chunk_free
(
asoc
->
addip_last_asconf_ack
);
...
...
@@ -400,7 +400,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
/* If the primary path is changing, assume that the
* user wants to use this new path.
*/
if
(
transport
->
active
)
if
(
transport
->
state
!=
SCTP_INACTIVE
)
asoc
->
peer
.
active_path
=
transport
;
/*
...
...
@@ -428,10 +428,58 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
transport
->
cacc
.
next_tsn_at_change
=
asoc
->
next_tsn
;
}
/* Remove a transport from an association. */
void
sctp_assoc_rm_peer
(
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
peer
)
{
struct
list_head
*
pos
;
struct
sctp_transport
*
transport
;
SCTP_DEBUG_PRINTK_IPADDR
(
"sctp_assoc_rm_peer:association %p addr: "
,
" port: %d
\n
"
,
asoc
,
(
&
peer
->
ipaddr
),
peer
->
ipaddr
.
v4
.
sin_port
);
/* If we are to remove the current retran_path, update it
* to the next peer before removing this peer from the list.
*/
if
(
asoc
->
peer
.
retran_path
==
peer
)
sctp_assoc_update_retran_path
(
asoc
);
/* Remove this peer from the list. */
list_del
(
&
peer
->
transports
);
/* Get the first transport of asoc. */
pos
=
asoc
->
peer
.
transport_addr_list
.
next
;
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
/* Update any entries that match the peer to be deleted. */
if
(
asoc
->
peer
.
primary_path
==
peer
)
sctp_assoc_set_primary
(
asoc
,
transport
);
if
(
asoc
->
peer
.
active_path
==
peer
)
asoc
->
peer
.
active_path
=
transport
;
if
(
asoc
->
peer
.
last_data_from
==
peer
)
asoc
->
peer
.
last_data_from
=
transport
;
/* If we remove the transport an INIT was last sent to, set it to
* NULL. Combined with the update of the retran path above, this
* will cause the next INIT to be sent to the next available
* transport, maintaining the cycle.
*/
if
(
asoc
->
init_last_sent_to
==
peer
)
asoc
->
init_last_sent_to
=
NULL
;
asoc
->
peer
.
transport_count
--
;
sctp_transport_free
(
peer
);
}
/* Add a transport address to an association. */
struct
sctp_transport
*
sctp_assoc_add_peer
(
struct
sctp_association
*
asoc
,
const
union
sctp_addr
*
addr
,
int
gfp
)
const
int
gfp
,
const
int
peer_state
)
{
struct
sctp_transport
*
peer
;
struct
sctp_sock
*
sp
;
...
...
@@ -442,14 +490,25 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
/* AF_INET and AF_INET6 share common port field. */
port
=
addr
->
v4
.
sin_port
;
SCTP_DEBUG_PRINTK_IPADDR
(
"sctp_assoc_add_peer:association %p addr: "
,
" port: %d state:%s
\n
"
,
asoc
,
addr
,
addr
->
v4
.
sin_port
,
peer_state
==
SCTP_UNKNOWN
?
"UNKNOWN"
:
"ACTIVE"
);
/* Set the port if it has not been set yet. */
if
(
0
==
asoc
->
peer
.
port
)
asoc
->
peer
.
port
=
port
;
/* Check to see if this is a duplicate. */
peer
=
sctp_assoc_lookup_paddr
(
asoc
,
addr
);
if
(
peer
)
if
(
peer
)
{
if
(
peer_state
==
SCTP_ACTIVE
&&
peer
->
state
==
SCTP_UNKNOWN
)
peer
->
state
=
SCTP_ACTIVE
;
return
peer
;
}
peer
=
sctp_transport_new
(
addr
,
gfp
);
if
(
!
peer
)
...
...
@@ -516,8 +575,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
/* Set the transport's RTO.initial value */
peer
->
rto
=
asoc
->
rto_initial
;
/* Set the peer's active state. */
peer
->
state
=
peer_state
;
/* Attach the remote transport to our asoc. */
list_add_tail
(
&
peer
->
transports
,
&
asoc
->
peer
.
transport_addr_list
);
asoc
->
peer
.
transport_count
++
;
/* If we do not yet have a primary path, set one. */
if
(
!
asoc
->
peer
.
primary_path
)
{
...
...
@@ -525,8 +588,9 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
asoc
->
peer
.
retran_path
=
peer
;
}
if
(
asoc
->
peer
.
active_path
==
asoc
->
peer
.
retran_path
)
if
(
asoc
->
peer
.
active_path
==
asoc
->
peer
.
retran_path
)
{
asoc
->
peer
.
retran_path
=
peer
;
}
return
peer
;
}
...
...
@@ -537,37 +601,16 @@ void sctp_assoc_del_peer(struct sctp_association *asoc,
{
struct
list_head
*
pos
;
struct
list_head
*
temp
;
struct
sctp_transport
*
peer
=
NULL
;
struct
sctp_transport
*
transport
;
list_for_each_safe
(
pos
,
temp
,
&
asoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
if
(
sctp_cmp_addr_exact
(
addr
,
&
transport
->
ipaddr
))
{
peer
=
transport
;
list_del
(
pos
);
/* Do book keeping for removing the peer and free it. */
sctp_assoc_rm_peer
(
asoc
,
transport
);
break
;
}
}
/* The address we want delete is not in the association. */
if
(
!
peer
)
return
;
/* Get the first transport of asoc. */
pos
=
asoc
->
peer
.
transport_addr_list
.
next
;
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
/* Update any entries that match the peer to be deleted. */
if
(
asoc
->
peer
.
primary_path
==
peer
)
sctp_assoc_set_primary
(
asoc
,
transport
);
if
(
asoc
->
peer
.
active_path
==
peer
)
asoc
->
peer
.
active_path
=
transport
;
if
(
asoc
->
peer
.
retran_path
==
peer
)
asoc
->
peer
.
retran_path
=
transport
;
if
(
asoc
->
peer
.
last_data_from
==
peer
)
asoc
->
peer
.
last_data_from
=
transport
;
sctp_transport_free
(
peer
);
}
/* Lookup a transport by address. */
...
...
@@ -608,12 +651,12 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
/* Record the transition on the transport. */
switch
(
command
)
{
case
SCTP_TRANSPORT_UP
:
transport
->
activ
e
=
SCTP_ACTIVE
;
transport
->
stat
e
=
SCTP_ACTIVE
;
spc_state
=
SCTP_ADDR_AVAILABLE
;
break
;
case
SCTP_TRANSPORT_DOWN
:
transport
->
activ
e
=
SCTP_INACTIVE
;
transport
->
stat
e
=
SCTP_INACTIVE
;
spc_state
=
SCTP_ADDR_UNREACHABLE
;
break
;
...
...
@@ -643,7 +686,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
list_for_each
(
pos
,
&
asoc
->
peer
.
transport_addr_list
)
{
t
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
if
(
!
t
->
active
)
if
(
t
->
state
==
SCTP_INACTIVE
)
continue
;
if
(
!
first
||
t
->
last_time_heard
>
first
->
last_time_heard
)
{
second
=
first
;
...
...
@@ -663,7 +706,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
* [If the primary is active but not most recent, bump the most
* recently used transport.]
*/
if
(
asoc
->
peer
.
primary_path
->
active
&&
if
(
asoc
->
peer
.
primary_path
->
state
!=
SCTP_INACTIVE
&&
first
!=
asoc
->
peer
.
primary_path
)
{
second
=
first
;
first
=
asoc
->
peer
.
primary_path
;
...
...
@@ -958,7 +1001,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
transports
);
if
(
!
sctp_assoc_lookup_paddr
(
asoc
,
&
trans
->
ipaddr
))
sctp_assoc_add_peer
(
asoc
,
&
trans
->
ipaddr
,
GFP_ATOMIC
);
GFP_ATOMIC
,
SCTP_ACTIVE
);
}
asoc
->
ctsn_ack_point
=
asoc
->
next_tsn
-
1
;
...
...
@@ -998,7 +1041,7 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
/* Try to find an active transport. */
if
(
t
->
active
)
{
if
(
t
->
state
!=
SCTP_INACTIVE
)
{
break
;
}
else
{
/* Keep track of the next transport in case
...
...
@@ -1019,6 +1062,40 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
}
asoc
->
peer
.
retran_path
=
t
;
SCTP_DEBUG_PRINTK_IPADDR
(
"sctp_assoc_update_retran_path:association"
" %p addr: "
,
" port: %d
\n
"
,
asoc
,
(
&
t
->
ipaddr
),
t
->
ipaddr
.
v4
.
sin_port
);
}
/* Choose the transport for sending a INIT packet. */
struct
sctp_transport
*
sctp_assoc_choose_init_transport
(
struct
sctp_association
*
asoc
)
{
struct
sctp_transport
*
t
;
/* Use the retran path. If the last INIT was sent over the
* retran path, update the retran path and use it.
*/
if
(
!
asoc
->
init_last_sent_to
)
{
t
=
asoc
->
peer
.
active_path
;
}
else
{
if
(
asoc
->
init_last_sent_to
==
asoc
->
peer
.
retran_path
)
sctp_assoc_update_retran_path
(
asoc
);
t
=
asoc
->
peer
.
retran_path
;
}
SCTP_DEBUG_PRINTK_IPADDR
(
"sctp_assoc_update_retran_path:association"
" %p addr: "
,
" port: %d
\n
"
,
asoc
,
(
&
t
->
ipaddr
),
t
->
ipaddr
.
v4
.
sin_port
);
return
t
;
}
/* Choose the transport for sending a SHUTDOWN packet. */
...
...
net/sctp/endpointola.c
View file @
fb395884
...
...
@@ -134,7 +134,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
ep
->
last_key
=
ep
->
current_key
=
0
;
ep
->
key_changed_at
=
jiffies
;
ep
->
debug_name
=
"unnamedEndpoint"
;
return
ep
;
}
...
...
net/sctp/input.c
View file @
fb395884
...
...
@@ -353,7 +353,7 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
sctp_do_sm
(
SCTP_EVENT_T_OTHER
,
SCTP_ST_OTHER
(
SCTP_EVENT_ICMP_PROTO_UNREACH
),
asoc
->
state
,
asoc
->
ep
,
asoc
,
NULL
,
asoc
->
state
,
asoc
->
ep
,
asoc
,
t
,
GFP_ATOMIC
);
}
...
...
net/sctp/outqueue.c
View file @
fb395884
...
...
@@ -682,7 +682,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
if
(
!
new_transport
)
{
new_transport
=
asoc
->
peer
.
active_path
;
}
else
if
(
!
new_transport
->
active
)
{
}
else
if
(
new_transport
->
state
==
SCTP_INACTIVE
)
{
/* If the chunk is Heartbeat or Heartbeat Ack,
* send it to chunk->transport, even if it's
* inactive.
...
...
@@ -840,7 +840,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
* Otherwise, we want to use the active path.
*/
new_transport
=
chunk
->
transport
;
if
(
!
new_transport
||
!
new_transport
->
active
)
if
(
!
new_transport
||
new_transport
->
state
==
SCTP_INACTIVE
)
new_transport
=
asoc
->
peer
.
active_path
;
/* Change packets if necessary. */
...
...
@@ -1454,7 +1455,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
/* Mark the destination transport address as
* active if it is not so marked.
*/
if
(
!
transport
->
active
)
{
if
(
transport
->
state
==
SCTP_INACTIVE
)
{
sctp_assoc_control_transport
(
transport
->
asoc
,
transport
,
...
...
net/sctp/sm_make_chunk.c
View file @
fb395884
...
...
@@ -1830,7 +1830,7 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* be a a better choice than any of the embedded addresses.
*/
if
(
peer_addr
)
if
(
!
sctp_assoc_add_peer
(
asoc
,
peer_addr
,
gfp
))
if
(
!
sctp_assoc_add_peer
(
asoc
,
peer_addr
,
gfp
,
SCTP_ACTIVE
))
goto
nomem
;
/* Process the initialization parameters. */
...
...
@@ -1841,6 +1841,14 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
goto
clean_up
;
}
/* Walk list of transports, removing transports in the UNKNOWN state. */
list_for_each_safe
(
pos
,
temp
,
&
asoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
if
(
transport
->
state
==
SCTP_UNKNOWN
)
{
sctp_assoc_rm_peer
(
asoc
,
transport
);
}
}
/* The fixed INIT headers are always in network byte
* order.
*/
...
...
@@ -1906,7 +1914,8 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* stream sequence number shall be set to 0.
*/
/* Allocate storage for the negotiated streams if it is not a temporary * association.
/* Allocate storage for the negotiated streams if it is not a temporary
* association.
*/
if
(
!
asoc
->
temp
)
{
int
assoc_id
;
...
...
@@ -1952,6 +1961,9 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
list_del_init
(
pos
);
sctp_transport_free
(
transport
);
}
asoc
->
peer
.
transport_count
=
0
;
nomem:
return
0
;
}
...
...
@@ -1995,7 +2007,7 @@ static int sctp_process_param(struct sctp_association *asoc,
af
->
from_addr_param
(
&
addr
,
param
.
addr
,
asoc
->
peer
.
port
,
0
);
scope
=
sctp_scope
(
peer_addr
);
if
(
sctp_in_scope
(
&
addr
,
scope
))
if
(
!
sctp_assoc_add_peer
(
asoc
,
&
addr
,
gfp
))
if
(
!
sctp_assoc_add_peer
(
asoc
,
&
addr
,
gfp
,
SCTP_ACTIVE
))
return
0
;
break
;
...
...
@@ -2396,7 +2408,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc,
* Due to Resource Shortage'.
*/
peer
=
sctp_assoc_add_peer
(
asoc
,
&
addr
,
GFP_ATOMIC
);
peer
=
sctp_assoc_add_peer
(
asoc
,
&
addr
,
GFP_ATOMIC
,
SCTP_ACTIVE
);
if
(
!
peer
)
return
SCTP_ERROR_RSRC_LOW
;
...
...
net/sctp/sm_sideeffect.c
View file @
fb395884
...
...
@@ -414,11 +414,13 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
*/
asoc
->
overall_error_count
++
;
if
(
transport
->
active
&&
if
(
transport
->
state
!=
SCTP_INACTIVE
&&
(
transport
->
error_count
++
>=
transport
->
max_retrans
))
{
SCTP_DEBUG_PRINTK
(
"transport_strike: transport "
"IP:%d.%d.%d.%d failed.
\n
"
,
NIPQUAD
(
transport
->
ipaddr
.
v4
.
sin_addr
));
SCTP_DEBUG_PRINTK_IPADDR
(
"transport_strike:association %p"
,
" transport IP: port:%d failed.
\n
"
,
asoc
,
(
&
transport
->
ipaddr
),
transport
->
ipaddr
.
v4
.
sin_port
);
sctp_assoc_control_transport
(
asoc
,
transport
,
SCTP_TRANSPORT_DOWN
,
SCTP_FAILED_THRESHOLD
);
...
...
@@ -593,7 +595,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
/* Mark the destination transport address as active if it is not so
* marked.
*/
if
(
!
t
->
active
)
if
(
t
->
state
==
SCTP_INACTIVE
)
sctp_assoc_control_transport
(
asoc
,
t
,
SCTP_TRANSPORT_UP
,
SCTP_HEARTBEAT_SUCCESS
);
...
...
@@ -665,6 +667,9 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
asoc
->
state
=
state
;
SCTP_DEBUG_PRINTK
(
"sctp_cmd_new_state: asoc %p[%s]
\n
"
,
asoc
,
sctp_state_tbl
[
state
]);
if
(
sctp_style
(
sk
,
TCP
))
{
/* Change the sk->sk_state of a TCP-style socket that has
* sucessfully completed a connect() call.
...
...
@@ -678,6 +683,16 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
sk
->
sk_shutdown
|=
RCV_SHUTDOWN
;
}
if
(
sctp_state
(
asoc
,
COOKIE_WAIT
))
{
/* Reset init timeouts since they may have been
* increased due to timer expirations.
*/
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
asoc
->
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
];
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
asoc
->
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
];
}
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
||
sctp_state
(
asoc
,
CLOSED
)
||
sctp_state
(
asoc
,
SHUTDOWN_RECEIVED
))
{
...
...
@@ -1122,7 +1137,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
*/
if
((
asoc
->
peer
.
retran_path
!=
asoc
->
peer
.
primary_path
)
&&
(
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
>
0
))
{
(
asoc
->
init_err_counter
>
0
))
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_FORCE_PRIM_RETRAN
,
SCTP_NULL
());
...
...
@@ -1237,18 +1252,67 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_association_put
(
asoc
);
break
;
case
SCTP_CMD_INIT_CHOOSE_TRANSPORT
:
chunk
=
cmd
->
obj
.
ptr
;
t
=
sctp_assoc_choose_init_transport
(
asoc
);
asoc
->
init_last_sent_to
=
t
;
chunk
->
transport
=
t
;
t
->
init_sent_count
++
;
break
;
case
SCTP_CMD_INIT_RESTART
:
/* Do the needed accounting and updates
* associated with restarting an initialization
* timer.
* timer. Only multiply the timeout by two if
* all transports have been tried at the current
* timeout.
*/
t
=
asoc
->
init_last_sent_to
;
asoc
->
init_err_counter
++
;
if
(
t
->
init_sent_count
>
(
asoc
->
init_cycle
+
1
))
{
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
*=
2
;
if
(
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
>
asoc
->
max_init_timeo
)
{
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
asoc
->
max_init_timeo
;
}
asoc
->
init_cycle
++
;
SCTP_DEBUG_PRINTK
(
"T1 INIT Timeout adjustment"
" init_err_counter: %d"
" cycle: %d"
" timeout: %d
\n
"
,
asoc
->
init_err_counter
,
asoc
->
init_cycle
,
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]);
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_INIT
));
break
;
case
SCTP_CMD_COOKIEECHO_RESTART
:
/* Do the needed accounting and updates
* associated with restarting an initialization
* timer. Only multiply the timeout by two if
* all transports have been tried at the current
* timeout.
*/
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
++
;
asoc
->
timeouts
[
cmd
->
obj
.
to
]
*=
2
;
if
(
asoc
->
timeouts
[
cmd
->
obj
.
to
]
>
asoc
->
init_err_counter
++
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
*=
2
;
if
(
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
>
asoc
->
max_init_timeo
)
{
asoc
->
timeouts
[
cmd
->
obj
.
to
]
=
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
asoc
->
max_init_timeo
;
}
SCTP_DEBUG_PRINTK
(
"T1 COOKIE Timeout adjustment"
" init_err_counter: %d"
" timeout: %d
\n
"
,
asoc
->
init_err_counter
,
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]);
/* If we've sent any data bundled with
* COOKIE-ECHO we need to resend.
...
...
@@ -1261,7 +1325,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
cmd
->
obj
.
to
));
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_COOKIE
));
break
;
case
SCTP_CMD_INIT_FAILED
:
...
...
@@ -1273,12 +1337,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
subtype
,
chunk
,
cmd
->
obj
.
u32
);
break
;
case
SCTP_CMD_COUNTER_INC
:
asoc
->
counters
[
cmd
->
obj
.
counter
]
++
;
case
SCTP_CMD_
INIT_
COUNTER_INC
:
asoc
->
init_err_counter
++
;
break
;
case
SCTP_CMD_COUNTER_RESET
:
asoc
->
counters
[
cmd
->
obj
.
counter
]
=
0
;
case
SCTP_CMD_INIT_COUNTER_RESET
:
asoc
->
init_err_counter
=
0
;
asoc
->
init_cycle
=
0
;
break
;
case
SCTP_CMD_REPORT_DUP
:
...
...
net/sctp/sm_statefuns.c
View file @
fb395884
...
...
@@ -533,6 +533,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_PEER_INIT
,
SCTP_PEER_INIT
(
initchunk
));
/* Reset init error count upon receipt of INIT-ACK. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_COUNTER_RESET
,
SCTP_NULL
());
/* 5.1 C) "A" shall stop the T1-init timer and leave
* COOKIE-WAIT state. "A" shall then ... start the T1-cookie
* timer, and enter the COOKIE-ECHOED state.
...
...
@@ -775,8 +778,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
* from the COOKIE-ECHOED state to the COOKIE-WAIT
* state is performed.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_COUNTER_RESET
,
SCTP_COUNTER
(
SCTP_COUNTER_INIT_ERROR
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_COUNTER_RESET
,
SCTP_NULL
());
/* RFC 2960 5.1 Normal Establishment of an Association
*
...
...
@@ -1019,10 +1021,22 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
link
=
sctp_assoc_lookup_paddr
(
asoc
,
&
from_addr
);
/* This should never happen, but lets log it if so. */
if
(
!
link
)
{
if
(
unlikely
(
!
link
))
{
if
(
from_addr
.
sa
.
sa_family
==
AF_INET6
)
{
printk
(
KERN_WARNING
"%s association %p could not find address "
"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x
\n
"
,
__FUNCTION__
,
asoc
,
NIP6
(
from_addr
.
v6
.
sin6_addr
));
}
else
{
printk
(
KERN_WARNING
"%s: Could not find address %d.%d.%d.%d
\n
"
,
__FUNCTION__
,
NIPQUAD
(
from_addr
.
v4
.
sin_addr
));
"%s association %p could not find address "
"%u.%u.%u.%u
\n
"
,
__FUNCTION__
,
asoc
,
NIPQUAD
(
from_addr
.
v4
.
sin_addr
.
s_addr
));
}
return
SCTP_DISPOSITION_DISCARD
;
}
...
...
@@ -2095,9 +2109,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
sctp_errhdr_t
*
err
;
struct
sctp_chunk
*
reply
;
struct
sctp_bind_addr
*
bp
;
int
attempts
;
attempts
=
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
+
1
;
int
attempts
=
asoc
->
init_err_counter
+
1
;
if
(
attempts
>=
asoc
->
max_init_attempts
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
...
...
@@ -2157,8 +2169,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
/* Cast away the const modifier, as we want to just
* rerun it through as a sideffect.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_COUNTER_INC
,
SCTP_COUNTER
(
SCTP_COUNTER_INIT_ERROR
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_COUNTER_INC
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_COOKIE
));
...
...
@@ -2281,8 +2292,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
if
(
len
>=
sizeof
(
struct
sctp_chunkhdr
)
+
sizeof
(
struct
sctp_errhdr
))
error
=
((
sctp_errhdr_t
*
)
chunk
->
skb
->
data
)
->
cause
;
sctp_stop_t1_and_abort
(
commands
,
error
);
return
SCTP_DISPOSITION_ABORT
;
return
sctp_stop_t1_and_abort
(
commands
,
error
,
asoc
,
chunk
->
transport
);
}
/*
...
...
@@ -2294,8 +2304,8 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_stop_t1_and_abort
(
commands
,
SCTP_ERROR_NO_ERROR
);
return
SCTP_DISPOSITION_ABORT
;
return
sctp_stop_t1_and_abort
(
commands
,
SCTP_ERROR_NO_ERROR
,
asoc
,
(
struct
sctp_transport
*
)
arg
)
;
}
/*
...
...
@@ -2318,8 +2328,12 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
*
* This is common code called by several sctp_sf_*_abort() functions above.
*/
void
sctp_stop_t1_and_abort
(
sctp_cmd_seq_t
*
commands
,
__u16
error
)
sctp_disposition_t
sctp_stop_t1_and_abort
(
sctp_cmd_seq_t
*
commands
,
__u16
error
,
const
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
transport
)
{
SCTP_DEBUG_PRINTK
(
"ABORT received (INIT).
\n
"
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
SCTP_INC_STATS
(
SCTP_MIB_ABORTEDS
);
...
...
@@ -2328,6 +2342,7 @@ void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error)
/* CMD_INIT_FAILED will DELETE_TCB. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_U32
(
error
));
return
SCTP_DISPOSITION_ABORT
;
}
/*
...
...
@@ -3805,6 +3820,10 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_ASOC
,
SCTP_ASOC
((
struct
sctp_association
*
)
asoc
));
/* Choose transport for INIT. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_CHOOSE_TRANSPORT
,
SCTP_CHUNK
(
repl
));
/* After sending the INIT, "A" starts the T1-init timer and
* enters the COOKIE-WAIT state.
*/
...
...
@@ -4589,7 +4608,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
}
/*
* sctp_sf_t1_timer_expire
* sctp_sf_t1_
init_
timer_expire
*
* Section: 4 Note: 2
* Verification Tag:
...
...
@@ -4603,6 +4622,58 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
* endpoint MUST abort the initialization process and report the
* error to SCTP user.
*
* Outputs
* (timers, events)
*
*/
sctp_disposition_t
sctp_sf_t1_init_timer_expire
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
struct
sctp_chunk
*
repl
=
NULL
;
struct
sctp_bind_addr
*
bp
;
int
attempts
=
asoc
->
init_err_counter
+
1
;
SCTP_DEBUG_PRINTK
(
"Timer T1 expired (INIT).
\n
"
);
if
(
attempts
<
asoc
->
max_init_attempts
)
{
bp
=
(
struct
sctp_bind_addr
*
)
&
asoc
->
base
.
bind_addr
;
repl
=
sctp_make_init
(
asoc
,
bp
,
GFP_ATOMIC
,
0
);
if
(
!
repl
)
return
SCTP_DISPOSITION_NOMEM
;
/* Choose transport for INIT. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_CHOOSE_TRANSPORT
,
SCTP_CHUNK
(
repl
));
/* Issue a sideeffect to do the needed accounting. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_INIT
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
}
else
{
SCTP_DEBUG_PRINTK
(
"Giving up on INIT, attempts: %d"
" max_init_attempts: %d
\n
"
,
attempts
,
asoc
->
max_init_attempts
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_U32
(
SCTP_ERROR_NO_ERROR
));
return
SCTP_DISPOSITION_DELETE_TCB
;
}
return
SCTP_DISPOSITION_CONSUME
;
}
/*
* sctp_sf_t1_cookie_timer_expire
*
* Section: 4 Note: 2
* Verification Tag:
* Inputs
* (endpoint, asoc)
*
* RFC 2960 Section 4 Notes
* 3) If the T1-cookie timer expires, the endpoint MUST retransmit
* COOKIE ECHO and re-start the T1-cookie timer without changing
* state. This MUST be repeated up to 'Max.Init.Retransmits' times.
...
...
@@ -4613,46 +4684,26 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
* (timers, events)
*
*/
sctp_disposition_t
sctp_sf_t1_timer_expire
(
const
struct
sctp_endpoint
*
ep
,
sctp_disposition_t
sctp_sf_t1_
cookie_
timer_expire
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
struct
sctp_chunk
*
repl
;
struct
sctp_bind_addr
*
bp
;
sctp_event_timeout_t
timer
=
(
sctp_event_timeout_t
)
arg
;
int
timeout
;
int
attempts
;
struct
sctp_chunk
*
repl
=
NULL
;
int
attempts
=
asoc
->
init_err_counter
+
1
;
timeout
=
asoc
->
timeouts
[
timer
];
attempts
=
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
+
1
;
repl
=
NULL
;
SCTP_DEBUG_PRINTK
(
"Timer T1 expired.
\n
"
);
SCTP_DEBUG_PRINTK
(
"Timer T1 expired (COOKIE-ECHO).
\n
"
);
if
(
attempts
<
asoc
->
max_init_attempts
)
{
switch
(
timer
)
{
case
SCTP_EVENT_TIMEOUT_T1_INIT
:
bp
=
(
struct
sctp_bind_addr
*
)
&
asoc
->
base
.
bind_addr
;
repl
=
sctp_make_init
(
asoc
,
bp
,
GFP_ATOMIC
,
0
);
break
;
case
SCTP_EVENT_TIMEOUT_T1_COOKIE
:
repl
=
sctp_make_cookie_echo
(
asoc
,
NULL
);
break
;
default:
BUG
();
break
;
};
if
(
!
repl
)
goto
nomem
;
return
SCTP_DISPOSITION_NOMEM
;
/* 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_COOKIEECHO_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_COOKIE
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
}
else
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
...
...
@@ -4661,9 +4712,6 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
}
return
SCTP_DISPOSITION_CONSUME
;
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
/* RFC2960 9.2 If the timer expires, the endpoint must re-send the SHUTDOWN
...
...
net/sctp/sm_statetable.c
View file @
fb395884
...
...
@@ -783,7 +783,8 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
/* SCTP_STATE_COOKIE_WAIT */
\
{.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_cookie_timer_expire, \
.name = "sctp_sf_t1_cookie_timer_expire"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
...
...
@@ -802,7 +803,8 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
/* SCTP_STATE_CLOSED */
\
{.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_init_timer_expire, \
.name = "sctp_sf_t1_init_timer_expire"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
...
...
net/sctp/socket.c
View file @
fb395884
...
...
@@ -262,18 +262,18 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
* sockaddr_in6 [RFC 2553]),
* addr_len - the size of the address structure.
*/
SCTP_STATIC
int
sctp_bind
(
struct
sock
*
sk
,
struct
sockaddr
*
u
addr
,
int
addr_len
)
SCTP_STATIC
int
sctp_bind
(
struct
sock
*
sk
,
struct
sockaddr
*
addr
,
int
addr_len
)
{
int
retval
=
0
;
sctp_lock_sock
(
sk
);
SCTP_DEBUG_PRINTK
(
"sctp_bind(sk: %p,
u
addr: %p, addr_len: %d)
\n
"
,
sk
,
u
addr
,
addr_len
);
SCTP_DEBUG_PRINTK
(
"sctp_bind(sk: %p, addr: %p, addr_len: %d)
\n
"
,
sk
,
addr
,
addr_len
);
/* Disallow binding twice. */
if
(
!
sctp_sk
(
sk
)
->
ep
->
base
.
bind_addr
.
port
)
retval
=
sctp_do_bind
(
sk
,
(
union
sctp_addr
*
)
u
addr
,
retval
=
sctp_do_bind
(
sk
,
(
union
sctp_addr
*
)
addr
,
addr_len
);
else
retval
=
-
EINVAL
;
...
...
@@ -318,23 +318,27 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
unsigned
short
snum
;
int
ret
=
0
;
SCTP_DEBUG_PRINTK
(
"sctp_do_bind(sk: %p, newaddr: %p, len: %d)
\n
"
,
sk
,
addr
,
len
);
/* Common sockaddr verification. */
af
=
sctp_sockaddr_af
(
sp
,
addr
,
len
);
if
(
!
af
)
if
(
!
af
)
{
SCTP_DEBUG_PRINTK
(
"sctp_do_bind(sk: %p, newaddr: %p, len: %d) EINVAL
\n
"
,
sk
,
addr
,
len
);
return
-
EINVAL
;
}
snum
=
ntohs
(
addr
->
v4
.
sin_port
);
SCTP_DEBUG_PRINTK_IPADDR
(
"sctp_do_bind(sk: %p, new addr: "
,
", port: %d, new port: %d, len: %d)
\n
"
,
sk
,
addr
,
bp
->
port
,
snum
,
len
);
/* PF specific bind() address verification. */
if
(
!
sp
->
pf
->
bind_verify
(
sp
,
addr
))
return
-
EADDRNOTAVAIL
;
snum
=
ntohs
(
addr
->
v4
.
sin_port
);
SCTP_DEBUG_PRINTK
(
"sctp_do_bind: port: %d, new port: %d
\n
"
,
bp
->
port
,
snum
);
/* We must either be unbound, or bind to the same port. */
if
(
bp
->
port
&&
(
snum
!=
bp
->
port
))
{
SCTP_DEBUG_PRINTK
(
"sctp_do_bind:"
...
...
@@ -816,7 +820,8 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
*
* Basically do nothing but copying the addresses from user to kernel
* land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk.
* This is used for tunneling the sctp_bindx() request through sctp_setsockopt() * from userspace.
* This is used for tunneling the sctp_bindx() request through sctp_setsockopt()
* from userspace.
*
* We don't use copy_from_user() for optimization: we first do the
* sanity checks (buffer size -fast- and access check-healthy
...
...
@@ -913,6 +918,243 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
return
err
;
}
/* __sctp_connect(struct sock* sk, struct sockaddr *kaddrs, int addrs_size)
*
* Common routine for handling connect() and sctp_connectx().
* Connect will come in with just a single address.
*/
static
int
__sctp_connect
(
struct
sock
*
sk
,
struct
sockaddr
*
kaddrs
,
int
addrs_size
)
{
struct
sctp_sock
*
sp
;
struct
sctp_endpoint
*
ep
;
struct
sctp_association
*
asoc
=
NULL
;
struct
sctp_association
*
asoc2
;
struct
sctp_transport
*
transport
;
union
sctp_addr
to
;
struct
sctp_af
*
af
;
sctp_scope_t
scope
;
long
timeo
;
int
err
=
0
;
int
addrcnt
=
0
;
int
walk_size
=
0
;
struct
sockaddr
*
sa_addr
;
void
*
addr_buf
;
sp
=
sctp_sk
(
sk
);
ep
=
sp
->
ep
;
/* connect() cannot be done on a socket that is already in ESTABLISHED
* state - UDP-style peeled off socket or a TCP-style socket that
* is already connected.
* It cannot be done even on a TCP-style listening socket.
*/
if
(
sctp_sstate
(
sk
,
ESTABLISHED
)
||
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
)))
{
err
=
-
EISCONN
;
goto
out_free
;
}
/* Walk through the addrs buffer and count the number of addresses. */
addr_buf
=
kaddrs
;
while
(
walk_size
<
addrs_size
)
{
sa_addr
=
(
struct
sockaddr
*
)
addr_buf
;
af
=
sctp_get_af_specific
(
sa_addr
->
sa_family
);
/* If the address family is not supported or if this address
* causes the address buffer to overflow return EINVAL.
*/
if
(
!
af
||
(
walk_size
+
af
->
sockaddr_len
)
>
addrs_size
)
{
err
=
-
EINVAL
;
goto
out_free
;
}
err
=
sctp_verify_addr
(
sk
,
(
union
sctp_addr
*
)
sa_addr
,
af
->
sockaddr_len
);
if
(
err
)
goto
out_free
;
memcpy
(
&
to
,
sa_addr
,
af
->
sockaddr_len
);
to
.
v4
.
sin_port
=
ntohs
(
to
.
v4
.
sin_port
);
/* Check if there already is a matching association on the
* endpoint (other than the one created here).
*/
asoc2
=
sctp_endpoint_lookup_assoc
(
ep
,
&
to
,
&
transport
);
if
(
asoc2
&&
asoc2
!=
asoc
)
{
if
(
asoc2
->
state
>=
SCTP_STATE_ESTABLISHED
)
err
=
-
EISCONN
;
else
err
=
-
EALREADY
;
goto
out_free
;
}
/* If we could not find a matching association on the endpoint,
* make sure that there is no peeled-off association matching
* the peer address even on another socket.
*/
if
(
sctp_endpoint_is_peeled_off
(
ep
,
&
to
))
{
err
=
-
EADDRNOTAVAIL
;
goto
out_free
;
}
if
(
!
asoc
)
{
/* If a bind() or sctp_bindx() is not called prior to
* an sctp_connectx() call, the system picks an
* ephemeral port and will choose an address set
* equivalent to binding with a wildcard address.
*/
if
(
!
ep
->
base
.
bind_addr
.
port
)
{
if
(
sctp_autobind
(
sk
))
{
err
=
-
EAGAIN
;
goto
out_free
;
}
}
scope
=
sctp_scope
(
&
to
);
asoc
=
sctp_association_new
(
ep
,
sk
,
scope
,
GFP_KERNEL
);
if
(
!
asoc
)
{
err
=
-
ENOMEM
;
goto
out_free
;
}
}
/* Prime the peer's transport structures. */
transport
=
sctp_assoc_add_peer
(
asoc
,
&
to
,
GFP_KERNEL
,
SCTP_UNKNOWN
);
if
(
!
transport
)
{
err
=
-
ENOMEM
;
goto
out_free
;
}
addrcnt
++
;
addr_buf
+=
af
->
sockaddr_len
;
walk_size
+=
af
->
sockaddr_len
;
}
err
=
sctp_assoc_set_bind_addr_from_ep
(
asoc
,
GFP_KERNEL
);
if
(
err
<
0
)
{
goto
out_free
;
}
err
=
sctp_primitive_ASSOCIATE
(
asoc
,
NULL
);
if
(
err
<
0
)
{
goto
out_free
;
}
/* Initialize sk's dport and daddr for getpeername() */
inet_sk
(
sk
)
->
dport
=
htons
(
asoc
->
peer
.
port
);
af
=
sctp_get_af_specific
(
to
.
sa
.
sa_family
);
af
->
to_sk_daddr
(
&
to
,
sk
);
timeo
=
sock_sndtimeo
(
sk
,
sk
->
sk_socket
->
file
->
f_flags
&
O_NONBLOCK
);
err
=
sctp_wait_for_connect
(
asoc
,
&
timeo
);
/* Don't free association on exit. */
asoc
=
NULL
;
out_free:
SCTP_DEBUG_PRINTK
(
"About to exit __sctp_connect() free asoc: %p"
" kaddrs: %p err: %d
\n
"
,
asoc
,
kaddrs
,
err
);
if
(
asoc
)
sctp_association_free
(
asoc
);
return
err
;
}
/* Helper for tunneling sctp_connectx() requests through sctp_setsockopt()
*
* API 8.9
* int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt);
*
* If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
* If the sd is an IPv6 socket, the addresses passed can either be IPv4
* or IPv6 addresses.
*
* A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see
* Section 3.1.2 for this usage.
*
* addrs is a pointer to an array of one or more socket addresses. Each
* address is contained in its appropriate structure (i.e. struct
* sockaddr_in or struct sockaddr_in6) the family of the address type
* must be used to distengish the address length (note that this
* representation is termed a "packed array" of addresses). The caller
* specifies the number of addresses in the array with addrcnt.
*
* On success, sctp_connectx() returns 0. On failure, sctp_connectx() returns
* -1, and sets errno to the appropriate error code.
*
* For SCTP, the port given in each socket address must be the same, or
* sctp_connectx() will fail, setting errno to EINVAL.
*
* An application can use sctp_connectx to initiate an association with
* an endpoint that is multi-homed. Much like sctp_bindx() this call
* allows a caller to specify multiple addresses at which a peer can be
* reached. The way the SCTP stack uses the list of addresses to set up
* the association is implementation dependant. This function only
* specifies that the stack will try to make use of all the addresses in
* the list when needed.
*
* Note that the list of addresses passed in is only used for setting up
* the association. It does not necessarily equal the set of addresses
* the peer uses for the resulting association. If the caller wants to
* find out the set of peer addresses, it must use sctp_getpaddrs() to
* retrieve them after the association has been set up.
*
* Basically do nothing but copying the addresses from user to kernel
* land and invoking either sctp_connectx(). This is used for tunneling
* the sctp_connectx() request through sctp_setsockopt() from userspace.
*
* We don't use copy_from_user() for optimization: we first do the
* sanity checks (buffer size -fast- and access check-healthy
* pointer); if all of those succeed, then we can alloc the memory
* (expensive operation) needed to copy the data to kernel. Then we do
* the copying without checking the user space area
* (__copy_from_user()).
*
* On exit there is no need to do sockfd_put(), sys_setsockopt() does
* it.
*
* sk The sk of the socket
* addrs The pointer to the addresses in user land
* addrssize Size of the addrs buffer
*
* Returns 0 if ok, <0 errno code on error.
*/
SCTP_STATIC
int
sctp_setsockopt_connectx
(
struct
sock
*
sk
,
struct
sockaddr
__user
*
addrs
,
int
addrs_size
)
{
int
err
=
0
;
struct
sockaddr
*
kaddrs
;
SCTP_DEBUG_PRINTK
(
"%s - sk %p addrs %p addrs_size %d
\n
"
,
__FUNCTION__
,
sk
,
addrs
,
addrs_size
);
if
(
unlikely
(
addrs_size
<=
0
))
return
-
EINVAL
;
/* Check the user passed a healthy pointer. */
if
(
unlikely
(
!
access_ok
(
VERIFY_READ
,
addrs
,
addrs_size
)))
return
-
EFAULT
;
/* Alloc space for the address array in kernel memory. */
kaddrs
=
(
struct
sockaddr
*
)
kmalloc
(
addrs_size
,
GFP_KERNEL
);
if
(
unlikely
(
!
kaddrs
))
return
-
ENOMEM
;
if
(
__copy_from_user
(
kaddrs
,
addrs
,
addrs_size
))
{
err
=
-
EFAULT
;
}
else
{
err
=
__sctp_connect
(
sk
,
kaddrs
,
addrs_size
);
}
kfree
(
kaddrs
);
return
err
;
}
/* API 3.1.4 close() - UDP Style Syntax
* Applications use close() to perform graceful shutdown (as described in
* Section 10.1 of [SCTP]) on ALL the associations currently represented
...
...
@@ -1095,7 +1337,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
sp
=
sctp_sk
(
sk
);
ep
=
sp
->
ep
;
SCTP_DEBUG_PRINTK
(
"Using endpoint: %
s.
\n
"
,
ep
->
debug_name
);
SCTP_DEBUG_PRINTK
(
"Using endpoint: %
p.
\n
"
,
ep
);
/* We cannot send a message over a TCP-style listening socket. */
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
))
{
...
...
@@ -1306,7 +1548,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
/* Prime the peer's transport structures. */
transport
=
sctp_assoc_add_peer
(
asoc
,
&
to
,
GFP_KERNEL
);
transport
=
sctp_assoc_add_peer
(
asoc
,
&
to
,
GFP_KERNEL
,
SCTP_UNKNOWN
);
if
(
!
transport
)
{
err
=
-
ENOMEM
;
goto
out_free
;
...
...
@@ -2208,6 +2450,12 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
optlen
,
SCTP_BINDX_REM_ADDR
);
break
;
case
SCTP_SOCKOPT_CONNECTX
:
/* 'optlen' is the size of the addresses buffer. */
retval
=
sctp_setsockopt_connectx
(
sk
,
(
struct
sockaddr
__user
*
)
optval
,
optlen
);
break
;
case
SCTP_DISABLE_FRAGMENTS
:
retval
=
sctp_setsockopt_disable_fragments
(
sk
,
optval
,
optlen
);
break
;
...
...
@@ -2283,112 +2531,29 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
*
* len: the size of the address.
*/
SCTP_STATIC
int
sctp_connect
(
struct
sock
*
sk
,
struct
sockaddr
*
u
addr
,
SCTP_STATIC
int
sctp_connect
(
struct
sock
*
sk
,
struct
sockaddr
*
addr
,
int
addr_len
)
{
struct
sctp_sock
*
sp
;
struct
sctp_endpoint
*
ep
;
struct
sctp_association
*
asoc
;
struct
sctp_transport
*
transport
;
union
sctp_addr
to
;
struct
sctp_af
*
af
;
sctp_scope_t
scope
;
long
timeo
;
int
err
=
0
;
struct
sctp_af
*
af
;
sctp_lock_sock
(
sk
);
SCTP_DEBUG_PRINTK
(
"%s - sk: %p, sockaddr: %p, addr_len: %d)
\n
"
,
__FUNCTION__
,
sk
,
uaddr
,
addr_len
);
sp
=
sctp_sk
(
sk
);
ep
=
sp
->
ep
;
/* connect() cannot be done on a socket that is already in ESTABLISHED
* state - UDP-style peeled off socket or a TCP-style socket that
* is already connected.
* It cannot be done even on a TCP-style listening socket.
*/
if
(
sctp_sstate
(
sk
,
ESTABLISHED
)
||
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
)))
{
err
=
-
EISCONN
;
goto
out_unlock
;
}
err
=
sctp_verify_addr
(
sk
,
(
union
sctp_addr
*
)
uaddr
,
addr_len
);
if
(
err
)
goto
out_unlock
;
if
(
addr_len
>
sizeof
(
to
))
addr_len
=
sizeof
(
to
);
memcpy
(
&
to
,
uaddr
,
addr_len
);
to
.
v4
.
sin_port
=
ntohs
(
to
.
v4
.
sin_port
);
asoc
=
sctp_endpoint_lookup_assoc
(
ep
,
&
to
,
&
transport
);
if
(
asoc
)
{
if
(
asoc
->
state
>=
SCTP_STATE_ESTABLISHED
)
err
=
-
EISCONN
;
else
err
=
-
EALREADY
;
goto
out_unlock
;
}
/* If we could not find a matching association on the endpoint,
* make sure that there is no peeled-off association matching the
* peer address even on another socket.
*/
if
(
sctp_endpoint_is_peeled_off
(
ep
,
&
to
))
{
err
=
-
EADDRNOTAVAIL
;
goto
out_unlock
;
}
SCTP_DEBUG_PRINTK
(
"%s - sk: %p, sockaddr: %p, addr_len: %d
\n
"
,
__FUNCTION__
,
sk
,
addr
,
addr_len
);
/* If a bind() or sctp_bindx() is not called prior to a connect()
* call, the system picks an ephemeral port and will choose an address
* set equivalent to binding with a wildcard address.
/* Validate addr_len before calling common connect/connectx routine. */
af
=
sctp_get_af_specific
(
addr
->
sa_family
);
if
(
!
af
||
addr_len
<
af
->
sockaddr_len
)
{
err
=
-
EINVAL
;
}
else
{
/* Pass correct addr len to common routine (so it knows there
* is only one address being passed.
*/
if
(
!
ep
->
base
.
bind_addr
.
port
)
{
if
(
sctp_autobind
(
sk
))
{
err
=
-
EAGAIN
;
goto
out_unlock
;
}
err
=
__sctp_connect
(
sk
,
addr
,
af
->
sockaddr_len
);
}
scope
=
sctp_scope
(
&
to
);
asoc
=
sctp_association_new
(
ep
,
sk
,
scope
,
GFP_KERNEL
);
if
(
!
asoc
)
{
err
=
-
ENOMEM
;
goto
out_unlock
;
}
/* Prime the peer's transport structures. */
transport
=
sctp_assoc_add_peer
(
asoc
,
&
to
,
GFP_KERNEL
);
if
(
!
transport
)
{
sctp_association_free
(
asoc
);
goto
out_unlock
;
}
err
=
sctp_assoc_set_bind_addr_from_ep
(
asoc
,
GFP_KERNEL
);
if
(
err
<
0
)
{
sctp_association_free
(
asoc
);
goto
out_unlock
;
}
err
=
sctp_primitive_ASSOCIATE
(
asoc
,
NULL
);
if
(
err
<
0
)
{
sctp_association_free
(
asoc
);
goto
out_unlock
;
}
/* Initialize sk's dport and daddr for getpeername() */
inet_sk
(
sk
)
->
dport
=
htons
(
asoc
->
peer
.
port
);
af
=
sctp_get_af_specific
(
to
.
sa
.
sa_family
);
af
->
to_sk_daddr
(
&
to
,
sk
);
timeo
=
sock_sndtimeo
(
sk
,
sk
->
sk_socket
->
file
->
f_flags
&
O_NONBLOCK
);
err
=
sctp_wait_for_connect
(
asoc
,
&
timeo
);
out_unlock:
sctp_release_sock
(
sk
);
return
err
;
}
...
...
@@ -2677,12 +2842,15 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
/* Map ipv4 address into v4-mapped-on-v6 address. */
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sctp_sk
(
sk
),
(
union
sctp_addr
*
)
&
status
.
sstat_primary
.
spinfo_address
);
status
.
sstat_primary
.
spinfo_state
=
transport
->
activ
e
;
status
.
sstat_primary
.
spinfo_state
=
transport
->
stat
e
;
status
.
sstat_primary
.
spinfo_cwnd
=
transport
->
cwnd
;
status
.
sstat_primary
.
spinfo_srtt
=
transport
->
srtt
;
status
.
sstat_primary
.
spinfo_rto
=
jiffies_to_msecs
(
transport
->
rto
);
status
.
sstat_primary
.
spinfo_mtu
=
transport
->
pmtu
;
if
(
status
.
sstat_primary
.
spinfo_state
==
SCTP_UNKNOWN
)
status
.
sstat_primary
.
spinfo_state
=
SCTP_ACTIVE
;
if
(
put_user
(
len
,
optlen
))
{
retval
=
-
EFAULT
;
goto
out
;
...
...
@@ -2733,12 +2901,15 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len,
return
-
EINVAL
;
pinfo
.
spinfo_assoc_id
=
sctp_assoc2id
(
transport
->
asoc
);
pinfo
.
spinfo_state
=
transport
->
activ
e
;
pinfo
.
spinfo_state
=
transport
->
stat
e
;
pinfo
.
spinfo_cwnd
=
transport
->
cwnd
;
pinfo
.
spinfo_srtt
=
transport
->
srtt
;
pinfo
.
spinfo_rto
=
jiffies_to_msecs
(
transport
->
rto
);
pinfo
.
spinfo_mtu
=
transport
->
pmtu
;
if
(
pinfo
.
spinfo_state
==
SCTP_UNKNOWN
)
pinfo
.
spinfo_state
=
SCTP_ACTIVE
;
if
(
put_user
(
len
,
optlen
))
{
retval
=
-
EFAULT
;
goto
out
;
...
...
@@ -3591,7 +3762,8 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
int
retval
=
0
;
int
len
;
SCTP_DEBUG_PRINTK
(
"sctp_getsockopt(sk: %p, ...)
\n
"
,
sk
);
SCTP_DEBUG_PRINTK
(
"sctp_getsockopt(sk: %p... optname: %d)
\n
"
,
sk
,
optname
);
/* I can hardly begin to describe how wrong this is. This is
* so broken as to be worse than useless. The API draft
...
...
@@ -4596,8 +4768,7 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
return
err
;
do_error:
if
(
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
+
1
>=
asoc
->
max_init_attempts
)
if
(
asoc
->
init_err_counter
+
1
>=
asoc
->
max_init_attempts
)
err
=
-
ETIMEDOUT
;
else
err
=
-
ECONNREFUSED
;
...
...
net/sctp/transport.c
View file @
fb395884
...
...
@@ -83,7 +83,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
peer
->
last_time_used
=
jiffies
;
peer
->
last_time_ecne_reduced
=
jiffies
;
peer
->
active
=
SCTP_ACTIVE
;
peer
->
init_sent_count
=
0
;
peer
->
state
=
SCTP_ACTIVE
;
peer
->
hb_allowed
=
0
;
/* Initialize the default path max_retrans. */
...
...
net/xfrm/xfrm_policy.c
View file @
fb395884
...
...
@@ -118,7 +118,6 @@ struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
xfrm_policy_put_afinfo
(
afinfo
);
return
type
;
}
EXPORT_SYMBOL
(
xfrm_get_type
);
int
xfrm_dst_lookup
(
struct
xfrm_dst
**
dst
,
struct
flowi
*
fl
,
unsigned
short
family
)
...
...
net/xfrm/xfrm_state.c
View file @
fb395884
...
...
@@ -1056,6 +1056,43 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
EXPORT_SYMBOL
(
xfrm_state_mtu
);
int
xfrm_init_state
(
struct
xfrm_state
*
x
)
{
struct
xfrm_state_afinfo
*
afinfo
;
int
family
=
x
->
props
.
family
;
int
err
;
err
=
-
EAFNOSUPPORT
;
afinfo
=
xfrm_state_get_afinfo
(
family
);
if
(
!
afinfo
)
goto
error
;
err
=
0
;
if
(
afinfo
->
init_flags
)
err
=
afinfo
->
init_flags
(
x
);
xfrm_state_put_afinfo
(
afinfo
);
if
(
err
)
goto
error
;
err
=
-
EPROTONOSUPPORT
;
x
->
type
=
xfrm_get_type
(
x
->
id
.
proto
,
family
);
if
(
x
->
type
==
NULL
)
goto
error
;
err
=
x
->
type
->
init_state
(
x
);
if
(
err
)
goto
error
;
x
->
km
.
state
=
XFRM_STATE_VALID
;
error:
return
err
;
}
EXPORT_SYMBOL
(
xfrm_init_state
);
void
__init
xfrm_state_init
(
void
)
{
int
i
;
...
...
net/xfrm/xfrm_user.c
View file @
fb395884
...
...
@@ -249,17 +249,10 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
if
((
err
=
attach_encap_tmpl
(
&
x
->
encap
,
xfrma
[
XFRMA_ENCAP
-
1
])))
goto
error
;
err
=
-
ENOENT
;
x
->
type
=
xfrm_get_type
(
x
->
id
.
proto
,
x
->
props
.
family
);
if
(
x
->
type
==
NULL
)
goto
error
;
err
=
x
->
type
->
init_state
(
x
,
NULL
);
err
=
xfrm_init_state
(
x
);
if
(
err
)
goto
error
;
x
->
curlft
.
add_time
=
(
unsigned
long
)
xtime
.
tv_sec
;
x
->
km
.
state
=
XFRM_STATE_VALID
;
x
->
km
.
seq
=
p
->
seq
;
return
x
;
...
...
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