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
a33b4399
Commit
a33b4399
authored
Mar 24, 2003
by
Jon Grimm
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP] Add icmpv6 handler to SCTP.
parent
d6b6fece
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1131 additions
and
1115 deletions
+1131
-1115
include/net/sctp/constants.h
include/net/sctp/constants.h
+3
-5
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+19
-19
net/sctp/input.c
net/sctp/input.c
+110
-64
net/sctp/ipv6.c
net/sctp/ipv6.c
+63
-18
net/sctp/outqueue.c
net/sctp/outqueue.c
+5
-4
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+931
-1005
No files found.
include/net/sctp/constants.h
View file @
a33b4399
...
@@ -138,12 +138,10 @@ typedef enum {
...
@@ -138,12 +138,10 @@ typedef enum {
*/
*/
typedef
union
{
typedef
union
{
sctp_cid_t
chunk
;
sctp_cid_t
chunk
;
sctp_event_timeout_t
timeout
;
sctp_event_timeout_t
timeout
;
sctp_event_other_t
other
;
sctp_event_other_t
other
;
sctp_event_primitive_t
primitive
;
sctp_event_primitive_t
primitive
;
}
sctp_subtype_t
;
}
sctp_subtype_t
;
#define SCTP_SUBTYPE_CONSTRUCTOR(_name, _type, _elt) \
#define SCTP_SUBTYPE_CONSTRUCTOR(_name, _type, _elt) \
...
@@ -421,9 +419,9 @@ typedef enum {
...
@@ -421,9 +419,9 @@ typedef enum {
/* Reasons to retransmit. */
/* Reasons to retransmit. */
typedef
enum
{
typedef
enum
{
SCTP_R
ETRANSMIT
_T3_RTX
,
SCTP_R
TXR
_T3_RTX
,
SCTP_R
ETRANSMIT
_FAST_RTX
,
SCTP_R
TXR
_FAST_RTX
,
SCTP_R
ETRANSMIT_PMTU_DISCOVERY
,
SCTP_R
TXR_PMTUD
,
}
sctp_retransmit_reason_t
;
}
sctp_retransmit_reason_t
;
/* Reasons to lower cwnd. */
/* Reasons to lower cwnd. */
...
...
include/net/sctp/sctp.h
View file @
a33b4399
...
@@ -130,7 +130,7 @@ extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
...
@@ -130,7 +130,7 @@ extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
extern
int
sctp_register_pf
(
struct
sctp_pf
*
,
sa_family_t
);
extern
int
sctp_register_pf
(
struct
sctp_pf
*
,
sa_family_t
);
/*
/*
* sctp
_
socket.c
* sctp
/
socket.c
*/
*/
extern
int
sctp_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
extern
int
sctp_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
extern
int
sctp_inet_listen
(
struct
socket
*
sock
,
int
backlog
);
extern
int
sctp_inet_listen
(
struct
socket
*
sock
,
int
backlog
);
...
@@ -139,7 +139,7 @@ extern unsigned int sctp_poll(struct file *file, struct socket *sock,
...
@@ -139,7 +139,7 @@ extern unsigned int sctp_poll(struct file *file, struct socket *sock,
poll_table
*
wait
);
poll_table
*
wait
);
/*
/*
* sctp
_
primitive.c
* sctp
/
primitive.c
*/
*/
extern
int
sctp_primitive_ASSOCIATE
(
sctp_association_t
*
,
void
*
arg
);
extern
int
sctp_primitive_ASSOCIATE
(
sctp_association_t
*
,
void
*
arg
);
extern
int
sctp_primitive_SHUTDOWN
(
sctp_association_t
*
,
void
*
arg
);
extern
int
sctp_primitive_SHUTDOWN
(
sctp_association_t
*
,
void
*
arg
);
...
@@ -148,14 +148,14 @@ extern int sctp_primitive_SEND(sctp_association_t *, void *arg);
...
@@ -148,14 +148,14 @@ extern int sctp_primitive_SEND(sctp_association_t *, void *arg);
extern
int
sctp_primitive_REQUESTHEARTBEAT
(
sctp_association_t
*
,
void
*
arg
);
extern
int
sctp_primitive_REQUESTHEARTBEAT
(
sctp_association_t
*
,
void
*
arg
);
/*
/*
* sctp
_
crc32c.c
* sctp
/
crc32c.c
*/
*/
extern
__u32
sctp_start_cksum
(
__u8
*
ptr
,
__u16
count
);
extern
__u32
sctp_start_cksum
(
__u8
*
ptr
,
__u16
count
);
extern
__u32
sctp_update_cksum
(
__u8
*
ptr
,
__u16
count
,
__u32
cksum
);
extern
__u32
sctp_update_cksum
(
__u8
*
ptr
,
__u16
count
,
__u32
cksum
);
extern
__u32
sctp_end_cksum
(
__u32
cksum
);
extern
__u32
sctp_end_cksum
(
__u32
cksum
);
/*
/*
* sctp
_
input.c
* sctp
/
input.c
*/
*/
extern
int
sctp_rcv
(
struct
sk_buff
*
skb
);
extern
int
sctp_rcv
(
struct
sk_buff
*
skb
);
extern
void
sctp_v4_err
(
struct
sk_buff
*
skb
,
u32
info
);
extern
void
sctp_v4_err
(
struct
sk_buff
*
skb
,
u32
info
);
...
@@ -170,9 +170,16 @@ extern void __sctp_unhash_endpoint(sctp_endpoint_t *);
...
@@ -170,9 +170,16 @@ extern void __sctp_unhash_endpoint(sctp_endpoint_t *);
extern
sctp_association_t
*
__sctp_lookup_association
(
const
union
sctp_addr
*
,
extern
sctp_association_t
*
__sctp_lookup_association
(
const
union
sctp_addr
*
,
const
union
sctp_addr
*
,
const
union
sctp_addr
*
,
struct
sctp_transport
**
);
struct
sctp_transport
**
);
extern
struct
sock
*
sctp_err_lookup
(
int
family
,
struct
sk_buff
*
,
struct
sctphdr
*
,
struct
sctp_endpoint
**
,
struct
sctp_association
**
,
struct
sctp_transport
**
);
extern
void
sctp_err_finish
(
struct
sock
*
,
struct
sctp_endpoint
*
,
struct
sctp_association
*
);
extern
void
sctp_icmp_frag_needed
(
struct
sock
*
,
struct
sctp_association
*
,
struct
sctp_transport
*
t
,
__u32
pmtu
);
/*
/*
* sctp
_
hashdriver.c
* sctp
/
hashdriver.c
*/
*/
extern
void
sctp_hash_digest
(
const
char
*
secret
,
const
int
secret_len
,
extern
void
sctp_hash_digest
(
const
char
*
secret
,
const
int
secret_len
,
const
char
*
text
,
const
int
text_len
,
const
char
*
text
,
const
int
text_len
,
...
@@ -184,9 +191,7 @@ extern void sctp_hash_digest(const char *secret, const int secret_len,
...
@@ -184,9 +191,7 @@ extern void sctp_hash_digest(const char *secret, const int secret_len,
#ifdef TEST_FRAME
#ifdef TEST_FRAME
#include <test_frame.h>
#include <test_frame.h>
#else
#else
/* spin lock wrappers. */
/* spin lock wrappers. */
...
@@ -312,7 +317,6 @@ static inline void sctp_sysctl_register(void) { return; }
...
@@ -312,7 +317,6 @@ static inline void sctp_sysctl_register(void) { return; }
static
inline
void
sctp_sysctl_unregister
(
void
)
{
return
;
}
static
inline
void
sctp_sysctl_unregister
(
void
)
{
return
;
}
#endif
#endif
/* Size of Supported Address Parameter for 'x' address types. */
/* Size of Supported Address Parameter for 'x' address types. */
#define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
#define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
...
@@ -320,19 +324,15 @@ static inline void sctp_sysctl_unregister(void) { return; }
...
@@ -320,19 +324,15 @@ static inline void sctp_sysctl_unregister(void) { return; }
extern
int
sctp_v6_init
(
void
);
extern
int
sctp_v6_init
(
void
);
extern
void
sctp_v6_exit
(
void
);
extern
void
sctp_v6_exit
(
void
);
static
inline
int
sctp_ipv6_addr_type
(
const
struct
in6_addr
*
addr
)
extern
void
sctp_v6_err
(
struct
sk_buff
*
skb
,
struct
inet6_skb_parm
*
opt
,
{
int
type
,
int
code
,
int
offset
,
__u32
info
);
return
ipv6_addr_type
((
struct
in6_addr
*
)
addr
);
}
#else
/* #ifdef defined(CONFIG_IPV6)
|| defined(CONFIG_IPV6_MODULE)
*/
#else
/* #ifdef defined(CONFIG_IPV6) */
#define sctp_ipv6_addr_type(a) 0
static
inline
int
sctp_v6_init
(
void
)
{
return
0
;
}
static
inline
int
sctp_v6_init
(
void
)
{
return
0
;
}
static
inline
void
sctp_v6_exit
(
void
)
{
return
;
}
static
inline
void
sctp_v6_exit
(
void
)
{
return
;
}
#endif
/* #ifdef defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
#endif
/* #if defined(CONFIG_IPV6) */
/* Map an association to an assoc_id. */
/* Map an association to an assoc_id. */
static
inline
sctp_assoc_t
sctp_assoc2id
(
const
sctp_association_t
*
asoc
)
static
inline
sctp_assoc_t
sctp_assoc2id
(
const
sctp_association_t
*
asoc
)
...
@@ -546,7 +546,7 @@ struct sctp_sock {
...
@@ -546,7 +546,7 @@ struct sctp_sock {
struct
sock
sk
;
struct
sock
sk
;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct
ipv6_pinfo
*
pinet6
;
struct
ipv6_pinfo
*
pinet6
;
#endif
/* CONFIG_IPV6
|| CONFIG_IPV6_MODULE
*/
#endif
/* CONFIG_IPV6 */
struct
inet_opt
inet
;
struct
inet_opt
inet
;
struct
sctp_opt
sctp
;
struct
sctp_opt
sctp
;
};
};
...
@@ -559,7 +559,7 @@ struct sctp6_sock {
...
@@ -559,7 +559,7 @@ struct sctp6_sock {
struct
sctp_opt
sctp
;
struct
sctp_opt
sctp
;
struct
ipv6_pinfo
inet6
;
struct
ipv6_pinfo
inet6
;
};
};
#endif
/* CONFIG_IPV6
|| CONFIG_IPV6_MODULE
*/
#endif
/* CONFIG_IPV6 */
#define sctp_sk(__sk) (&((struct sctp_sock *)__sk)->sctp)
#define sctp_sk(__sk) (&((struct sctp_sock *)__sk)->sctp)
...
...
net/sctp/input.c
View file @
a33b4399
...
@@ -205,21 +205,19 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -205,21 +205,19 @@ int sctp_rcv(struct sk_buff *skb)
*/
*/
sctp_bh_lock_sock
(
sk
);
sctp_bh_lock_sock
(
sk
);
if
(
sock_owned_by_user
(
sk
))
{
if
(
sock_owned_by_user
(
sk
))
sk_add_backlog
(
sk
,
(
struct
sk_buff
*
)
chunk
);
sk_add_backlog
(
sk
,
(
struct
sk_buff
*
)
chunk
);
}
else
{
else
sctp_backlog_rcv
(
sk
,
(
struct
sk_buff
*
)
chunk
);
sctp_backlog_rcv
(
sk
,
(
struct
sk_buff
*
)
chunk
);
}
/* Release the sock and any reference counts we took in the
/* Release the sock and any reference counts we took in the
* lookup calls.
* lookup calls.
*/
*/
sctp_bh_unlock_sock
(
sk
);
sctp_bh_unlock_sock
(
sk
);
if
(
asoc
)
{
if
(
asoc
)
sctp_association_put
(
asoc
);
sctp_association_put
(
asoc
);
}
else
{
else
sctp_endpoint_put
(
ep
);
sctp_endpoint_put
(
ep
);
}
sock_put
(
sk
);
sock_put
(
sk
);
return
ret
;
return
ret
;
...
@@ -266,10 +264,8 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
...
@@ -266,10 +264,8 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
}
}
/* Handle icmp frag needed error. */
/* Handle icmp frag needed error. */
static
inline
void
sctp_icmp_frag_needed
(
struct
sock
*
sk
,
void
sctp_icmp_frag_needed
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
,
sctp_association_t
*
asoc
,
struct
sctp_transport
*
t
,
__u32
pmtu
)
struct
sctp_transport
*
transport
,
__u32
pmtu
)
{
{
if
(
unlikely
(
pmtu
<
SCTP_DEFAULT_MINSEGMENT
))
{
if
(
unlikely
(
pmtu
<
SCTP_DEFAULT_MINSEGMENT
))
{
printk
(
KERN_WARNING
"%s: Reported pmtu %d too low, "
printk
(
KERN_WARNING
"%s: Reported pmtu %d too low, "
...
@@ -278,54 +274,38 @@ static inline void sctp_icmp_frag_needed(struct sock *sk,
...
@@ -278,54 +274,38 @@ static inline void sctp_icmp_frag_needed(struct sock *sk,
pmtu
=
SCTP_DEFAULT_MINSEGMENT
;
pmtu
=
SCTP_DEFAULT_MINSEGMENT
;
}
}
if
(
!
sock_owned_by_user
(
sk
)
&&
t
ransport
&&
(
transpor
t
->
pmtu
!=
pmtu
))
{
if
(
!
sock_owned_by_user
(
sk
)
&&
t
&&
(
t
->
pmtu
!=
pmtu
))
{
t
ransport
->
pmtu
=
pmtu
;
t
->
pmtu
=
pmtu
;
sctp_assoc_sync_pmtu
(
asoc
);
sctp_assoc_sync_pmtu
(
asoc
);
sctp_retransmit
(
&
asoc
->
outqueue
,
transport
,
sctp_retransmit
(
&
asoc
->
outqueue
,
t
,
SCTP_RTXR_PMTUD
);
SCTP_RETRANSMIT_PMTU_DISCOVERY
);
}
}
}
}
/*
/* Common lookup code for icmp/icmpv6 error handler. */
* This routine is called by the ICMP module when it gets some
struct
sock
*
sctp_err_lookup
(
int
family
,
struct
sk_buff
*
skb
,
* sort of error condition. If err < 0 then the socket should
struct
sctphdr
*
sctphdr
,
* be closed and the error returned to the user. If err > 0
struct
sctp_endpoint
**
epp
,
* it's just the icmp type << 8 | icmp code. After adjustment
struct
sctp_association
**
app
,
* header points to the first 8 bytes of the sctp header. We need
struct
sctp_transport
**
tpp
)
* to find the appropriate port.
*
* The locking strategy used here is very "optimistic". When
* someone else accesses the socket the ICMP is just dropped
* and for some paths there is no check at all.
* A more general error queue to queue errors for later handling
* is probably better.
*
*/
void
sctp_v4_err
(
struct
sk_buff
*
skb
,
__u32
info
)
{
{
struct
iphdr
*
iph
=
(
struct
iphdr
*
)
skb
->
data
;
union
sctp_addr
saddr
;
struct
sctphdr
*
sh
=
(
struct
sctphdr
*
)(
skb
->
data
+
(
iph
->
ihl
<<
2
));
union
sctp_addr
daddr
;
int
type
=
skb
->
h
.
icmph
->
type
;
struct
sctp_af
*
af
;
int
code
=
skb
->
h
.
icmph
->
code
;
union
sctp_addr
saddr
,
daddr
;
struct
inet_opt
*
inet
;
struct
sock
*
sk
=
NULL
;
struct
sock
*
sk
=
NULL
;
sctp_endpoint_t
*
ep
=
NULL
;
struct
sctp_endpoint
*
ep
=
NULL
;
sctp_association_t
*
asoc
=
NULL
;
struct
sctp_association
*
asoc
=
NULL
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
=
NULL
;
int
err
;
if
(
skb
->
len
<
((
iph
->
ihl
<<
2
)
+
8
))
{
*
app
=
NULL
;
*
epp
=
NULL
;
*
tpp
=
NULL
;
ICMP_INC_STATS_BH
(
IcmpInErrors
);
return
;
af
=
sctp_get_af_specific
(
family
);
if
(
unlikely
(
!
af
))
{
return
NULL
;
}
}
saddr
.
v4
.
sin_family
=
AF_INET
;
/* Initialize local addresses for lookups. */
saddr
.
v4
.
sin_port
=
ntohs
(
sh
->
source
);
af
->
from_skb
(
&
saddr
,
skb
,
1
);
memcpy
(
&
saddr
.
v4
.
sin_addr
.
s_addr
,
&
iph
->
saddr
,
sizeof
(
struct
in_addr
));
af
->
from_skb
(
&
daddr
,
skb
,
0
);
daddr
.
v4
.
sin_family
=
AF_INET
;
daddr
.
v4
.
sin_port
=
ntohs
(
sh
->
dest
);
memcpy
(
&
daddr
.
v4
.
sin_addr
.
s_addr
,
&
iph
->
daddr
,
sizeof
(
struct
in_addr
));
/* Look for an association that matches the incoming ICMP error
/* Look for an association that matches the incoming ICMP error
* packet.
* packet.
...
@@ -338,13 +318,12 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
...
@@ -338,13 +318,12 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
*/
*/
ep
=
__sctp_rcv_lookup_endpoint
(
&
daddr
);
ep
=
__sctp_rcv_lookup_endpoint
(
&
daddr
);
if
(
!
ep
)
{
if
(
!
ep
)
{
ICMP_INC_STATS_BH
(
IcmpInErrors
);
return
NULL
;
return
;
}
}
}
}
if
(
asoc
)
{
if
(
asoc
)
{
if
(
ntohl
(
s
h
->
vtag
)
!=
asoc
->
c
.
peer_vtag
)
{
if
(
ntohl
(
s
ctphdr
->
vtag
)
!=
asoc
->
c
.
peer_vtag
)
{
ICMP_INC_STATS_BH
(
IcmpInErrors
);
ICMP_INC_STATS_BH
(
IcmpInErrors
);
goto
out
;
goto
out
;
}
}
...
@@ -353,12 +332,90 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
...
@@ -353,12 +332,90 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
sk
=
ep
->
base
.
sk
;
sk
=
ep
->
base
.
sk
;
sctp_bh_lock_sock
(
sk
);
sctp_bh_lock_sock
(
sk
);
/* If too many ICMPs get dropped on busy
/* If too many ICMPs get dropped on busy
* servers this needs to be solved differently.
* servers this needs to be solved differently.
*/
*/
if
(
sock_owned_by_user
(
sk
))
if
(
sock_owned_by_user
(
sk
))
NET_INC_STATS_BH
(
LockDroppedIcmps
);
NET_INC_STATS_BH
(
LockDroppedIcmps
);
*
epp
=
ep
;
*
app
=
asoc
;
*
tpp
=
transport
;
return
sk
;
out:
sock_put
(
sk
);
if
(
asoc
)
sctp_association_put
(
asoc
);
if
(
ep
)
sctp_endpoint_put
(
ep
);
return
NULL
;
}
/* Common cleanup code for icmp/icmpv6 error handler. */
void
sctp_err_finish
(
struct
sock
*
sk
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
)
{
sctp_bh_unlock_sock
(
sk
);
sock_put
(
sk
);
if
(
asoc
)
sctp_association_put
(
asoc
);
if
(
ep
)
sctp_endpoint_put
(
ep
);
}
/*
* This routine is called by the ICMP module when it gets some
* sort of error condition. If err < 0 then the socket should
* be closed and the error returned to the user. If err > 0
* it's just the icmp type << 8 | icmp code. After adjustment
* header points to the first 8 bytes of the sctp header. We need
* to find the appropriate port.
*
* The locking strategy used here is very "optimistic". When
* someone else accesses the socket the ICMP is just dropped
* and for some paths there is no check at all.
* A more general error queue to queue errors for later handling
* is probably better.
*
*/
void
sctp_v4_err
(
struct
sk_buff
*
skb
,
__u32
info
)
{
struct
iphdr
*
iph
=
(
struct
iphdr
*
)
skb
->
data
;
struct
sctphdr
*
sh
=
(
struct
sctphdr
*
)(
skb
->
data
+
(
iph
->
ihl
<<
2
));
int
type
=
skb
->
h
.
icmph
->
type
;
int
code
=
skb
->
h
.
icmph
->
code
;
struct
sock
*
sk
;
sctp_endpoint_t
*
ep
;
sctp_association_t
*
asoc
;
struct
sctp_transport
*
transport
;
struct
inet_opt
*
inet
;
char
*
saveip
,
*
savesctp
;
int
err
;
if
(
skb
->
len
<
((
iph
->
ihl
<<
2
)
+
8
))
{
ICMP_INC_STATS_BH
(
IcmpInErrors
);
return
;
}
/* Fix up skb to look at the embedded net header. */
saveip
=
skb
->
nh
.
raw
;
savesctp
=
skb
->
h
.
raw
;
skb
->
nh
.
iph
=
iph
;
skb
->
h
.
raw
=
(
char
*
)
sh
;
sk
=
sctp_err_lookup
(
AF_INET
,
skb
,
sh
,
&
ep
,
&
asoc
,
&
transport
);
/* Put back, the original pointers. */
skb
->
nh
.
raw
=
saveip
;
skb
->
h
.
raw
=
savesctp
;
if
(
!
sk
)
{
ICMP_INC_STATS_BH
(
IcmpInErrors
);
return
;
}
/* Warning: The sock lock is held. Remember to call
* sctp_err_finish!
*/
switch
(
type
)
{
switch
(
type
)
{
case
ICMP_PARAMETERPROB
:
case
ICMP_PARAMETERPROB
:
err
=
EPROTO
;
err
=
EPROTO
;
...
@@ -397,13 +454,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
...
@@ -397,13 +454,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
}
}
out_unlock:
out_unlock:
sctp_bh_unlock_sock
(
sk
);
sctp_err_finish
(
sk
,
ep
,
asoc
);
out:
sock_put
(
sk
);
if
(
asoc
)
sctp_association_put
(
asoc
);
if
(
ep
)
sctp_endpoint_put
(
ep
);
}
}
/*
/*
...
@@ -780,8 +831,3 @@ sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
...
@@ -780,8 +831,3 @@ sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
return
asoc
;
return
asoc
;
}
}
net/sctp/ipv6.c
View file @
a33b4399
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
* Copyright (c) 2001 La Monte H.P. Yarroll
* Copyright (c) 2002 International Business Machines, Corp.
* Copyright (c) 2002
-2003
International Business Machines, Corp.
*
*
* This file is part of the SCTP kernel reference Implementation
* This file is part of the SCTP kernel reference Implementation
*
*
...
@@ -88,17 +88,62 @@ extern struct notifier_block sctp_inetaddr_notifier;
...
@@ -88,17 +88,62 @@ extern struct notifier_block sctp_inetaddr_notifier;
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
ntohs((addr)->s6_addr16[7])
/* FIXME: Comments. */
/* ICMP error handler. */
static
inline
void
sctp_v6_err
(
struct
sk_buff
*
skb
,
void
sctp_v6_err
(
struct
sk_buff
*
skb
,
struct
inet6_skb_parm
*
opt
,
struct
inet6_skb_parm
*
opt
,
int
type
,
int
code
,
int
offset
,
__u32
info
)
int
type
,
int
code
,
int
offset
,
__u32
info
)
{
{
/* BUG. WRITE ME. */
struct
ipv6hdr
*
iph
=
(
struct
ipv6hdr
*
)
skb
->
data
;
struct
sctphdr
*
sh
=
(
struct
sctphdr
*
)(
skb
->
data
+
offset
);
struct
sock
*
sk
;
sctp_endpoint_t
*
ep
;
sctp_association_t
*
asoc
;
struct
sctp_transport
*
transport
;
struct
ipv6_pinfo
*
np
;
char
*
saveip
,
*
savesctp
;
int
err
;
/* Fix up skb to look at the embedded net header. */
saveip
=
skb
->
nh
.
raw
;
savesctp
=
skb
->
h
.
raw
;
skb
->
nh
.
ipv6h
=
iph
;
skb
->
h
.
raw
=
(
char
*
)
sh
;
sk
=
sctp_err_lookup
(
AF_INET6
,
skb
,
sh
,
&
ep
,
&
asoc
,
&
transport
);
/* Put back, the original pointers. */
skb
->
nh
.
raw
=
saveip
;
skb
->
h
.
raw
=
savesctp
;
if
(
!
sk
)
{
ICMP6_INC_STATS_BH
(
Icmp6InErrors
);
return
;
}
/* Warning: The sock lock is held. Remember to call
* sctp_err_finish!
*/
switch
(
type
)
{
case
ICMPV6_PKT_TOOBIG
:
sctp_icmp_frag_needed
(
sk
,
asoc
,
transport
,
ntohl
(
info
));
goto
out_unlock
;
default:
break
;
}
np
=
inet6_sk
(
sk
);
icmpv6_err_convert
(
type
,
code
,
&
err
);
if
(
!
sock_owned_by_user
(
sk
)
&&
np
->
recverr
)
{
sk
->
err
=
err
;
sk
->
error_report
(
sk
);
}
else
{
/* Only an error on timeout */
sk
->
err_soft
=
err
;
}
out_unlock:
sctp_err_finish
(
sk
,
ep
,
asoc
);
}
}
/* Based on tcp_v6_xmit() in tcp_ipv6.c. */
/* Based on tcp_v6_xmit() in tcp_ipv6.c. */
static
in
line
int
sctp_v6_xmit
(
struct
sk_buff
*
skb
,
static
in
t
sctp_v6_xmit
(
struct
sk_buff
*
skb
,
struct
sctp_transport
*
transport
,
struct
sctp_transport
*
transport
,
int
ipfragok
)
int
ipfragok
)
{
{
struct
sock
*
sk
=
skb
->
sk
;
struct
sock
*
sk
=
skb
->
sk
;
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
...
@@ -110,9 +155,9 @@ static inline int sctp_v6_xmit(struct sk_buff *skb,
...
@@ -110,9 +155,9 @@ static inline int sctp_v6_xmit(struct sk_buff *skb,
/* Fill in the dest address from the route entry passed with the skb
/* Fill in the dest address from the route entry passed with the skb
* and the source address from the transport.
* and the source address from the transport.
*/
*/
fl
.
fl6_dst
=
&
rt6
->
rt6i_dst
.
addr
;
fl
.
fl6_dst
=
&
rt6
->
rt6i_dst
.
addr
;
fl
.
fl6_src
=
&
transport
->
saddr
.
v6
.
sin6_addr
;
fl
.
fl6_src
=
&
transport
->
saddr
.
v6
.
sin6_addr
;
fl
.
fl6_flowlabel
=
np
->
flow_label
;
fl
.
fl6_flowlabel
=
np
->
flow_label
;
IP6_ECN_flow_xmit
(
sk
,
fl
.
fl6_flowlabel
);
IP6_ECN_flow_xmit
(
sk
,
fl
.
fl6_flowlabel
);
...
@@ -174,7 +219,7 @@ struct dst_entry *sctp_v6_get_dst(sctp_association_t *asoc,
...
@@ -174,7 +219,7 @@ struct dst_entry *sctp_v6_get_dst(sctp_association_t *asoc,
/* Returns the number of consecutive initial bits that match in the 2 ipv6
/* Returns the number of consecutive initial bits that match in the 2 ipv6
* addresses.
* addresses.
*/
*/
static
inline
int
sctp_v6_addr_match_len
(
union
sctp_addr
*
s1
,
static
inline
int
sctp_v6_addr_match_len
(
union
sctp_addr
*
s1
,
union
sctp_addr
*
s2
)
union
sctp_addr
*
s2
)
{
{
...
@@ -186,7 +231,7 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
...
@@ -186,7 +231,7 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
__u32
a1xora2
;
__u32
a1xora2
;
a1xora2
=
a1
->
s6_addr32
[
i
]
^
a2
->
s6_addr32
[
i
];
a1xora2
=
a1
->
s6_addr32
[
i
]
^
a2
->
s6_addr32
[
i
];
if
((
j
=
fls
(
ntohl
(
a1xora2
))))
if
((
j
=
fls
(
ntohl
(
a1xora2
))))
return
(
i
*
32
+
32
-
j
);
return
(
i
*
32
+
32
-
j
);
}
}
...
@@ -196,7 +241,7 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
...
@@ -196,7 +241,7 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
/* Fills in the source address(saddr) based on the destination address(daddr)
/* Fills in the source address(saddr) based on the destination address(daddr)
* and asoc's bind address list.
* and asoc's bind address list.
*/
*/
void
sctp_v6_get_saddr
(
sctp_association_t
*
asoc
,
struct
dst_entry
*
dst
,
void
sctp_v6_get_saddr
(
sctp_association_t
*
asoc
,
struct
dst_entry
*
dst
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
{
{
...
@@ -432,7 +477,7 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
...
@@ -432,7 +477,7 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
return
retval
;
return
retval
;
}
}
/* Create and initialize a new sk for the socket to be returned by accept(). */
/* Create and initialize a new sk for the socket to be returned by accept(). */
struct
sock
*
sctp_v6_create_accept_sk
(
struct
sock
*
sk
,
struct
sock
*
sctp_v6_create_accept_sk
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
struct
sctp_association
*
asoc
)
{
{
...
@@ -469,11 +514,11 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk,
...
@@ -469,11 +514,11 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk,
memcpy
(
newnp
,
np
,
sizeof
(
struct
ipv6_pinfo
));
memcpy
(
newnp
,
np
,
sizeof
(
struct
ipv6_pinfo
));
ipv6_addr_copy
(
&
newnp
->
daddr
,
&
asoc
->
peer
.
primary_addr
.
v6
.
sin6_addr
);
ipv6_addr_copy
(
&
newnp
->
daddr
,
&
asoc
->
peer
.
primary_addr
.
v6
.
sin6_addr
);
newinet
->
sport
=
inet
->
sport
;
newinet
->
sport
=
inet
->
sport
;
newinet
->
dport
=
asoc
->
peer
.
port
;
newinet
->
dport
=
asoc
->
peer
.
port
;
#ifdef INET_REFCNT_DEBUG
#ifdef INET_REFCNT_DEBUG
atomic_inc
(
&
inet6_sock_nr
);
atomic_inc
(
&
inet6_sock_nr
);
atomic_inc
(
&
inet_sock_nr
);
atomic_inc
(
&
inet_sock_nr
);
...
@@ -623,11 +668,11 @@ static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
...
@@ -623,11 +668,11 @@ static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
/* Fill in Supported Address Type information for INIT and INIT-ACK
/* Fill in Supported Address Type information for INIT and INIT-ACK
* chunks. Note: In the future, we may want to look at sock options
* chunks. Note: In the future, we may want to look at sock options
* to determine whether a PF_INET6 socket really wants to have IPV4
* to determine whether a PF_INET6 socket really wants to have IPV4
* addresses.
* addresses.
* Returns number of addresses supported.
* Returns number of addresses supported.
*/
*/
static
int
sctp_inet6_supported_addrs
(
const
struct
sctp_opt
*
opt
,
static
int
sctp_inet6_supported_addrs
(
const
struct
sctp_opt
*
opt
,
__u16
*
types
)
__u16
*
types
)
{
{
types
[
0
]
=
SCTP_PARAM_IPV4_ADDRESS
;
types
[
0
]
=
SCTP_PARAM_IPV4_ADDRESS
;
types
[
1
]
=
SCTP_PARAM_IPV6_ADDRESS
;
types
[
1
]
=
SCTP_PARAM_IPV6_ADDRESS
;
...
...
net/sctp/outqueue.c
View file @
a33b4399
...
@@ -357,7 +357,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
...
@@ -357,7 +357,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
__u8
fast_retransmit
=
0
;
__u8
fast_retransmit
=
0
;
switch
(
reason
)
{
switch
(
reason
)
{
case
SCTP_R
ETRANSMIT
_T3_RTX
:
case
SCTP_R
TXR
_T3_RTX
:
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_T3_RTX
);
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_T3_RTX
);
/* Update the retran path if the T3-rtx timer has expired for
/* Update the retran path if the T3-rtx timer has expired for
* the current retran path.
* the current retran path.
...
@@ -365,10 +365,11 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
...
@@ -365,10 +365,11 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
if
(
transport
==
transport
->
asoc
->
peer
.
retran_path
)
if
(
transport
==
transport
->
asoc
->
peer
.
retran_path
)
sctp_assoc_update_retran_path
(
transport
->
asoc
);
sctp_assoc_update_retran_path
(
transport
->
asoc
);
break
;
break
;
case
SCTP_R
ETRANSMIT
_FAST_RTX
:
case
SCTP_R
TXR
_FAST_RTX
:
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_FAST_RTX
);
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_FAST_RTX
);
fast_retransmit
=
1
;
fast_retransmit
=
1
;
break
;
break
;
case
SCTP_RTXR_PMTUD
:
default:
default:
break
;
break
;
}
}
...
@@ -876,7 +877,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -876,7 +877,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
start_timer
=
0
;
start_timer
=
0
;
queue
=
&
q
->
out
;
queue
=
&
q
->
out
;
while
(
chunk
=
sctp_outq_dequeue_data
(
q
))
{
while
(
(
chunk
=
sctp_outq_dequeue_data
(
q
)
))
{
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
* stream identifier.
* stream identifier.
*/
*/
...
@@ -1570,7 +1571,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
...
@@ -1570,7 +1571,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
if
(
transport
)
{
if
(
transport
)
{
if
(
do_fast_retransmit
)
if
(
do_fast_retransmit
)
sctp_retransmit
(
q
,
transport
,
SCTP_R
ETRANSMIT
_FAST_RTX
);
sctp_retransmit
(
q
,
transport
,
SCTP_R
TXR
_FAST_RTX
);
SCTP_DEBUG_PRINTK
(
"%s: transport: %p, cwnd: %d, "
SCTP_DEBUG_PRINTK
(
"%s: transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, pba: %d
\n
"
,
"ssthresh: %d, flight_size: %d, pba: %d
\n
"
,
...
...
net/sctp/sm_sideeffect.c
View file @
a33b4399
This diff is collapsed.
Click to expand it.
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