Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
fc129116
Commit
fc129116
authored
Nov 21, 2002
by
Jon Grimm
Browse files
Options
Browse Files
Download
Plain Diff
Merge touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5
into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work
parents
4354abee
d8367696
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
274 additions
and
271 deletions
+274
-271
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+2
-2
include/net/sctp/structs.h
include/net/sctp/structs.h
+14
-7
net/ipv6/ipv6_syms.c
net/ipv6/ipv6_syms.c
+1
-0
net/sctp/associola.c
net/sctp/associola.c
+1
-1
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+2
-2
net/sctp/input.c
net/sctp/input.c
+1
-1
net/sctp/ipv6.c
net/sctp/ipv6.c
+66
-19
net/sctp/protocol.c
net/sctp/protocol.c
+90
-36
net/sctp/socket.c
net/sctp/socket.c
+96
-202
net/sctp/transport.c
net/sctp/transport.c
+1
-1
No files found.
include/net/sctp/sctp.h
View file @
fc129116
...
...
@@ -123,8 +123,8 @@ extern sctp_protocol_t sctp_proto;
extern
struct
sock
*
sctp_get_ctl_sock
(
void
);
extern
int
sctp_copy_local_addr_list
(
sctp_protocol_t
*
,
sctp_bind_addr_t
*
,
sctp_scope_t
,
int
priority
,
int
flags
);
extern
s
ctp_pf_t
*
sctp_get_pf_specific
(
in
t
family
);
extern
void
sctp_set_pf_specific
(
int
family
,
sctp_pf_t
*
);
extern
s
truct
sctp_pf
*
sctp_get_pf_specific
(
sa_family_
t
family
);
extern
int
sctp_register_pf
(
struct
sctp_pf
*
,
sa_family_t
);
/*
* sctp_socket.c
...
...
include/net/sctp/structs.h
View file @
fc129116
...
...
@@ -234,7 +234,7 @@ struct SCTP_protocol {
* Pointers to address related SCTP functions.
* (i.e. things that depend on the address family.)
*/
typedef
struct
sctp_func
{
struct
sctp_af
{
int
(
*
queue_xmit
)
(
struct
sk_buff
*
skb
);
int
(
*
setsockopt
)
(
struct
sock
*
sk
,
int
level
,
...
...
@@ -259,27 +259,34 @@ typedef struct sctp_func {
void
(
*
from_skb
)
(
union
sctp_addr
*
,
struct
sk_buff
*
skb
,
int
saddr
);
void
(
*
from_sk
)
(
union
sctp_addr
*
,
struct
sock
*
sk
);
void
(
*
to_sk
)
(
union
sctp_addr
*
,
struct
sock
*
sk
);
int
(
*
addr_valid
)
(
union
sctp_addr
*
);
sctp_scope_t
(
*
scope
)
(
union
sctp_addr
*
);
void
(
*
inaddr_any
)
(
union
sctp_addr
*
,
unsigned
short
);
int
(
*
is_any
)
(
const
union
sctp_addr
*
);
int
(
*
available
)
(
const
union
sctp_addr
*
);
__u16
net_header_len
;
int
sockaddr_len
;
sa_family_t
sa_family
;
struct
list_head
list
;
}
sctp_func_t
;
};
sctp_func_t
*
sctp_get_af_specific
(
sa_family_t
);
struct
sctp_af
*
sctp_get_af_specific
(
sa_family_t
);
int
sctp_register_af
(
struct
sctp_af
*
);
/* Protocol family functions. */
typedef
struct
sctp_pf
{
void
(
*
event_msgname
)(
sctp_ulpevent_t
*
,
char
*
,
int
*
);
void
(
*
skb_msgname
)(
struct
sk_buff
*
,
char
*
,
int
*
);
int
(
*
af_supported
)(
sa_family_t
);
void
(
*
skb_msgname
)
(
struct
sk_buff
*
,
char
*
,
int
*
);
int
(
*
af_supported
)
(
sa_family_t
);
int
(
*
cmp_addr
)
(
const
union
sctp_addr
*
,
const
union
sctp_addr
*
,
struct
sctp_opt
*
);
struct
sctp_func
*
af
;
int
(
*
bind_verify
)
(
struct
sctp_opt
*
,
union
sctp_addr
*
);
struct
sctp_af
*
af
;
}
sctp_pf_t
;
/* SCTP Socket type: UDP or TCP style. */
...
...
@@ -623,7 +630,7 @@ struct SCTP_transport {
union
sctp_addr
ipaddr
;
/* These are the functions we call to handle LLP stuff. */
s
ctp_func_t
*
af_specific
;
s
truct
sctp_af
*
af_specific
;
/* Which association do we belong to? */
sctp_association_t
*
asoc
;
...
...
net/ipv6/ipv6_syms.c
View file @
fc129116
...
...
@@ -24,3 +24,4 @@ EXPORT_SYMBOL(inet6_bind);
EXPORT_SYMBOL
(
inet6_getname
);
EXPORT_SYMBOL
(
inet6_ioctl
);
EXPORT_SYMBOL
(
ipv6_get_saddr
);
EXPORT_SYMBOL
(
ipv6_chk_addr
);
net/sctp/associola.c
View file @
fc129116
...
...
@@ -642,7 +642,7 @@ __u16 __sctp_association_get_next_ssn(sctp_association_t *asoc, __u16 sid)
int
sctp_cmp_addr_exact
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
)
{
struct
sctp_
func
*
af
;
struct
sctp_
af
*
af
;
af
=
sctp_get_af_specific
(
ss1
->
sa
.
sa_family
);
if
(
!
af
)
...
...
net/sctp/bind_addr.c
View file @
fc129116
...
...
@@ -327,7 +327,7 @@ static int sctp_copy_one_addr(sctp_bind_addr_t *dest, union sctp_addr *addr,
/* Is this a wildcard address? */
int
sctp_is_any
(
const
union
sctp_addr
*
addr
)
{
struct
sctp_
func
*
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
struct
sctp_
af
*
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
if
(
!
af
)
return
0
;
return
af
->
is_any
(
addr
);
...
...
@@ -362,7 +362,7 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
/* What is the scope of 'addr'? */
sctp_scope_t
sctp_scope
(
const
union
sctp_addr
*
addr
)
{
struct
sctp_
func
*
af
;
struct
sctp_
af
*
af
;
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
if
(
!
af
)
...
...
net/sctp/input.c
View file @
fc129116
...
...
@@ -96,7 +96,7 @@ int sctp_rcv(struct sk_buff *skb)
struct
sctphdr
*
sh
;
union
sctp_addr
src
;
union
sctp_addr
dest
;
struct
sctp_
func
*
af
;
struct
sctp_
af
*
af
;
int
ret
=
0
;
if
(
skb
->
pkt_type
!=
PACKET_HOST
)
...
...
net/sctp/ipv6.c
View file @
fc129116
...
...
@@ -140,8 +140,8 @@ static inline int sctp_v6_xmit(struct sk_buff *skb)
* to disallow loopback when the scoping rules have
* not bound loopback to the endpoint.
*/
if
(
sctp_
ipv6_addr_type
(
&
saddr
)
&
IPV6_ADDR_LOOPBACK
)
{
if
(
!
(
sctp_
ipv6_addr_type
(
&
np
->
daddr
)
&
if
(
ipv6_addr_type
(
&
saddr
)
&
IPV6_ADDR_LOOPBACK
)
{
if
(
!
(
ipv6_addr_type
(
&
np
->
daddr
)
&
IPV6_ADDR_LOOPBACK
))
{
ipv6_addr_copy
(
&
saddr
,
&
np
->
daddr
);
}
...
...
@@ -176,7 +176,7 @@ struct dst_entry *sctp_v6_get_dst(union sctp_addr *daddr,
union
sctp_addr
*
saddr
)
{
struct
dst_entry
*
dst
;
struct
flowi
fl
=
{
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip6_u
=
{
.
daddr
=
&
daddr
->
v6
.
sin6_addr
,
}
}
};
...
...
@@ -261,6 +261,20 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
ipv6_addr_copy
(
&
addr
->
v6
.
sin6_addr
,
from
);
}
/* Initialize an sctp_addr from a socket. */
static
void
sctp_v6_from_sk
(
union
sctp_addr
*
addr
,
struct
sock
*
sk
)
{
addr
->
v6
.
sin6_family
=
AF_INET6
;
addr
->
v6
.
sin6_port
=
inet_sk
(
sk
)
->
num
;
addr
->
v6
.
sin6_addr
=
inet6_sk
(
sk
)
->
rcv_saddr
;
}
/* Initialize sk->rcv_saddr from sctp_addr. */
static
void
sctp_v6_to_sk
(
union
sctp_addr
*
addr
,
struct
sock
*
sk
)
{
inet6_sk
(
sk
)
->
rcv_saddr
=
addr
->
v6
.
sin6_addr
;
}
/* Initialize a sctp_addr from a dst_entry. */
static
void
sctp_v6_dst_saddr
(
union
sctp_addr
*
addr
,
struct
dst_entry
*
dst
)
{
...
...
@@ -270,15 +284,15 @@ static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst)
}
/* Compare addresses exactly. Well.. almost exactly; ignore scope_id
* for now. FIXME.
* for now. FIXME
: v4-mapped-v6
.
*/
static
int
sctp_v6_cmp_addr
(
const
union
sctp_addr
*
addr1
,
static
int
sctp_v6_cmp_addr
(
const
union
sctp_addr
*
addr1
,
const
union
sctp_addr
*
addr2
)
{
int
match
;
if
(
addr1
->
sa
.
sa_family
!=
addr2
->
sa
.
sa_family
)
return
0
;
match
=
!
ipv6_addr_cmp
((
struct
in6_addr
*
)
&
addr1
->
v6
.
sin6_addr
,
match
=
!
ipv6_addr_cmp
((
struct
in6_addr
*
)
&
addr1
->
v6
.
sin6_addr
,
(
struct
in6_addr
*
)
&
addr2
->
v6
.
sin6_addr
);
return
match
;
...
...
@@ -300,6 +314,22 @@ static int sctp_v6_is_any(const union sctp_addr *addr)
return
IPV6_ADDR_ANY
==
type
;
}
/* Should this be available for binding? */
static
int
sctp_v6_available
(
const
union
sctp_addr
*
addr
)
{
int
type
;
struct
in6_addr
*
in6
=
(
struct
in6_addr
*
)
&
addr
->
v6
.
sin6_addr
;
type
=
ipv6_addr_type
(
in6
);
if
(
IPV6_ADDR_ANY
==
type
)
return
1
;
if
(
!
(
type
&
IPV6_ADDR_UNICAST
))
return
0
;
return
ipv6_chk_addr
(
in6
,
NULL
);
}
/* This function checks if the address is a valid address to be used for
* SCTP.
*
...
...
@@ -309,7 +339,7 @@ static int sctp_v6_is_any(const union sctp_addr *addr)
*/
static
int
sctp_v6_addr_valid
(
union
sctp_addr
*
addr
)
{
int
ret
=
sctp_
ipv6_addr_type
(
&
addr
->
v6
.
sin6_addr
);
int
ret
=
ipv6_addr_type
(
&
addr
->
v6
.
sin6_addr
);
/* FIXME: v4-mapped-v6 address support. */
...
...
@@ -442,14 +472,14 @@ static int sctp_inet6_af_supported(sa_family_t family)
/* Address matching with wildcards allowed. This extra level
* of indirection lets us choose whether a PF_INET6 should
* disallow any v4 addresses if we so choose.
* disallow any v4 addresses if we so choose.
*/
static
int
sctp_inet6_cmp_addr
(
const
union
sctp_addr
*
addr1
,
static
int
sctp_inet6_cmp_addr
(
const
union
sctp_addr
*
addr1
,
const
union
sctp_addr
*
addr2
,
struct
sctp_opt
*
opt
)
{
struct
sctp_
func
*
af1
,
*
af2
;
struct
sctp_
af
*
af1
,
*
af2
;
af1
=
sctp_get_af_specific
(
addr1
->
sa
.
sa_family
);
af2
=
sctp_get_af_specific
(
addr2
->
sa
.
sa_family
);
...
...
@@ -461,11 +491,25 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
if
(
addr1
->
sa
.
sa_family
!=
addr2
->
sa
.
sa_family
)
return
0
;
return
af1
->
cmp_addr
(
addr1
,
addr2
);
}
/* Verify that the provided sockaddr looks bindable. Common verification,
* has already been taken care of.
*/
static
int
sctp_inet6_bind_verify
(
struct
sctp_opt
*
opt
,
union
sctp_addr
*
addr
)
{
struct
sctp_af
*
af
;
/* ASSERT: address family has already been verified. */
if
(
addr
->
sa
.
sa_family
!=
AF_INET6
)
{
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
}
else
af
=
opt
->
pf
->
af
;
return
af
->
available
(
addr
);
}
static
struct
proto_ops
inet6_seqpacket_ops
=
{
.
family
=
PF_INET6
,
...
...
@@ -501,29 +545,33 @@ static struct inet6_protocol sctpv6_protocol = {
.
err_handler
=
sctp_v6_err
,
};
static
s
ctp_func_t
sctp_ipv6_specific
=
{
static
s
truct
sctp_af
sctp_ipv6_specific
=
{
.
queue_xmit
=
sctp_v6_xmit
,
.
setsockopt
=
ipv6_setsockopt
,
.
setsockopt
=
ipv6_setsockopt
,
.
getsockopt
=
ipv6_getsockopt
,
.
get_dst
=
sctp_v6_get_dst
,
.
copy_addrlist
=
sctp_v6_copy_addrlist
,
.
from_skb
=
sctp_v6_from_skb
,
.
from_sk
=
sctp_v6_from_sk
,
.
to_sk
=
sctp_v6_to_sk
,
.
dst_saddr
=
sctp_v6_dst_saddr
,
.
cmp_addr
=
sctp_v6_cmp_addr
,
.
scope
=
sctp_v6_scope
,
.
addr_valid
=
sctp_v6_addr_valid
,
.
inaddr_any
=
sctp_v6_inaddr_any
,
.
is_any
=
sctp_v6_is_any
,
.
available
=
sctp_v6_available
,
.
net_header_len
=
sizeof
(
struct
ipv6hdr
),
.
sockaddr_len
=
sizeof
(
struct
sockaddr_in6
),
.
sa_family
=
AF_INET6
,
};
static
s
ctp_pf_t
sctp_pf_inet6_specific
=
{
static
s
truct
sctp_pf
sctp_pf_inet6_specific
=
{
.
event_msgname
=
sctp_inet6_event_msgname
,
.
skb_msgname
=
sctp_inet6_skb_msgname
,
.
af_supported
=
sctp_inet6_af_supported
,
.
cmp_addr
=
sctp_inet6_cmp_addr
,
.
bind_verify
=
sctp_inet6_bind_verify
,
.
af
=
&
sctp_ipv6_specific
,
};
...
...
@@ -538,11 +586,10 @@ int sctp_v6_init(void)
inet6_register_protosw
(
&
sctpv6_protosw
);
/* Register the SCTP specfic PF_INET6 functions. */
sctp_
set_pf_specific
(
PF_INET6
,
&
sctp_pf_inet6_specific
);
sctp_
register_pf
(
&
sctp_pf_inet6_specific
,
PF_INET6
);
/* Fill in address family info. */
INIT_LIST_HEAD
(
&
sctp_ipv6_specific
.
list
);
list_add_tail
(
&
sctp_ipv6_specific
.
list
,
&
sctp_proto
.
address_families
);
/* Register the SCTP specfic AF_INET6 functions. */
sctp_register_af
(
&
sctp_ipv6_specific
);
return
0
;
}
...
...
net/sctp/protocol.c
View file @
fc129116
...
...
@@ -67,8 +67,10 @@ struct sctp_mib sctp_statistics[NR_CPUS * 2];
*/
static
struct
socket
*
sctp_ctl_socket
;
static
sctp_pf_t
*
sctp_pf_inet6_specific
;
static
sctp_pf_t
*
sctp_pf_inet_specific
;
static
struct
sctp_pf
*
sctp_pf_inet6_specific
;
static
struct
sctp_pf
*
sctp_pf_inet_specific
;
static
struct
sctp_af
*
sctp_af_v4_specific
;
static
struct
sctp_af
*
sctp_af_v6_specific
;
extern
struct
net_proto_family
inet_family_ops
;
...
...
@@ -140,12 +142,12 @@ static void __sctp_get_local_addr_list(sctp_protocol_t *proto)
{
struct
net_device
*
dev
;
struct
list_head
*
pos
;
struct
sctp_
func
*
af
;
struct
sctp_
af
*
af
;
read_lock
(
&
dev_base_lock
);
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
{
list_for_each
(
pos
,
&
proto
->
address_families
)
{
af
=
list_entry
(
pos
,
s
ctp_func_t
,
list
);
af
=
list_entry
(
pos
,
s
truct
sctp_af
,
list
);
af
->
copy_addrlist
(
&
proto
->
local_addr_list
,
dev
);
}
}
...
...
@@ -251,7 +253,6 @@ struct dst_entry *sctp_v4_get_dst(union sctp_addr *daddr,
return
&
rt
->
u
.
dst
;
}
/* Initialize a sctp_addr from in incoming skb. */
static
void
sctp_v4_from_skb
(
union
sctp_addr
*
addr
,
struct
sk_buff
*
skb
,
int
is_saddr
)
...
...
@@ -274,6 +275,21 @@ static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
memcpy
(
&
addr
->
v4
.
sin_addr
.
s_addr
,
from
,
sizeof
(
struct
in_addr
));
}
/* Initialize an sctp_addr from a socket. */
static
void
sctp_v4_from_sk
(
union
sctp_addr
*
addr
,
struct
sock
*
sk
)
{
addr
->
v4
.
sin_family
=
AF_INET
;
addr
->
v4
.
sin_port
=
inet_sk
(
sk
)
->
num
;
addr
->
v4
.
sin_addr
.
s_addr
=
inet_sk
(
sk
)
->
rcv_saddr
;
}
/* Initialize sk->rcv_saddr from sctp_addr. */
static
void
sctp_v4_to_sk
(
union
sctp_addr
*
addr
,
struct
sock
*
sk
)
{
inet_sk
(
sk
)
->
rcv_saddr
=
addr
->
v4
.
sin_addr
.
s_addr
;
}
/* Initialize a sctp_addr from a dst_entry. */
static
void
sctp_v4_dst_saddr
(
union
sctp_addr
*
saddr
,
struct
dst_entry
*
dst
)
{
...
...
@@ -311,7 +327,7 @@ static int sctp_v4_is_any(const union sctp_addr *addr)
}
/* This function checks if the address is a valid address to be used for
* SCTP.
* SCTP
binding
.
*
* Output:
* Return 0 - If the address is a non-unicast or an illegal address.
...
...
@@ -326,6 +342,18 @@ static int sctp_v4_addr_valid(union sctp_addr *addr)
return
1
;
}
/* Should this be available for binding? */
static
int
sctp_v4_available
(
const
union
sctp_addr
*
addr
)
{
int
ret
=
inet_addr_type
(
addr
->
v4
.
sin_addr
.
s_addr
);
/* FIXME: ip_nonlocal_bind sysctl support. */
if
(
addr
->
v4
.
sin_addr
.
s_addr
!=
INADDR_ANY
&&
ret
!=
RTN_LOCAL
)
return
0
;
return
1
;
}
/* Checking the loopback, private and other address scopes as defined in
* RFC 1918. The IPv4 scoping is based on the draft for SCTP IPv4
* scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>.
...
...
@@ -405,29 +433,42 @@ int sctp_ctl_sock_init(void)
return
0
;
}
/* Register address family specific functions. */
int
sctp_register_af
(
struct
sctp_af
*
af
)
{
switch
(
af
->
sa_family
)
{
case
AF_INET
:
if
(
sctp_af_v4_specific
)
return
0
;
sctp_af_v4_specific
=
sctp_af_v4_specific
=
af
;
break
;
case
AF_INET6
:
if
(
sctp_af_v6_specific
)
return
0
;
sctp_af_v6_specific
=
sctp_af_v6_specific
=
af
;
break
;
default:
return
0
;
}
INIT_LIST_HEAD
(
&
af
->
list
);
list_add_tail
(
&
af
->
list
,
&
sctp_proto
.
address_families
);
return
1
;
}
/* Get the table of functions for manipulating a particular address
* family.
*/
s
ctp_func_t
*
sctp_get_af_specific
(
sa_family_t
family
)
s
truct
sctp_af
*
sctp_get_af_specific
(
sa_family_t
family
)
{
struct
list_head
*
pos
;
sctp_protocol_t
*
proto
=
sctp_get_protocol
();
struct
sctp_func
*
retval
,
*
af
;
retval
=
NULL
;
/* Cycle through all AF specific functions looking for a
* match.
*/
list_for_each
(
pos
,
&
proto
->
address_families
)
{
af
=
list_entry
(
pos
,
sctp_func_t
,
list
);
if
(
family
==
af
->
sa_family
)
{
retval
=
af
;
break
;
}
switch
(
family
)
{
case
AF_INET
:
return
sctp_af_v4_specific
;
case
AF_INET6
:
return
sctp_af_v6_specific
;
default:
return
NULL
;
}
return
retval
;
}
/* Common code to initialize a AF_INET msg_name. */
...
...
@@ -495,18 +536,25 @@ static int sctp_inet_cmp_addr(const union sctp_addr *addr1,
return
0
;
}
/* Verify that provided sockaddr looks bindable. Common verification has
* already been taken care of.
*/
static
int
sctp_inet_bind_verify
(
struct
sctp_opt
*
opt
,
union
sctp_addr
*
addr
)
{
return
sctp_v4_available
(
addr
);
}
struct
sctp_
func
sctp_ipv4_specific
;
struct
sctp_
af
sctp_ipv4_specific
;
static
s
ctp_pf_t
sctp_pf_inet
=
{
static
s
truct
sctp_pf
sctp_pf_inet
=
{
.
event_msgname
=
sctp_inet_event_msgname
,
.
skb_msgname
=
sctp_inet_skb_msgname
,
.
af_supported
=
sctp_inet_af_supported
,
.
cmp_addr
=
sctp_inet_cmp_addr
,
.
bind_verify
=
sctp_inet_bind_verify
,
.
af
=
&
sctp_ipv4_specific
,
};
/* Registration for netdev events. */
struct
notifier_block
sctp_netdev_notifier
=
{
.
notifier_call
=
sctp_netdev_event
,
...
...
@@ -551,25 +599,28 @@ static struct inet_protocol sctp_protocol = {
};
/* IPv4 address related functions. */
struct
sctp_
func
sctp_ipv4_specific
=
{
struct
sctp_
af
sctp_ipv4_specific
=
{
.
queue_xmit
=
ip_queue_xmit
,
.
setsockopt
=
ip_setsockopt
,
.
getsockopt
=
ip_getsockopt
,
.
get_dst
=
sctp_v4_get_dst
,
.
copy_addrlist
=
sctp_v4_copy_addrlist
,
.
from_skb
=
sctp_v4_from_skb
,
.
from_sk
=
sctp_v4_from_sk
,
.
to_sk
=
sctp_v4_to_sk
,
.
dst_saddr
=
sctp_v4_dst_saddr
,
.
cmp_addr
=
sctp_v4_cmp_addr
,
.
addr_valid
=
sctp_v4_addr_valid
,
.
inaddr_any
=
sctp_v4_inaddr_any
,
.
is_any
=
sctp_v4_is_any
,
.
available
=
sctp_v4_available
,
.
scope
=
sctp_v4_scope
,
.
net_header_len
=
sizeof
(
struct
iphdr
),
.
sockaddr_len
=
sizeof
(
struct
sockaddr_in
),
.
sa_family
=
AF_INET
,
};
s
ctp_pf_t
*
sctp_get_pf_specific
(
in
t
family
)
{
s
truct
sctp_pf
*
sctp_get_pf_specific
(
sa_family_
t
family
)
{
switch
(
family
)
{
case
PF_INET
:
...
...
@@ -581,20 +632,24 @@ sctp_pf_t *sctp_get_pf_specific(int family) {
}
}
/*
Set
the PF specific function table. */
void
sctp_set_pf_specific
(
int
family
,
sctp_pf_t
*
pf
)
/*
Register
the PF specific function table. */
int
sctp_register_pf
(
struct
sctp_pf
*
pf
,
sa_family_t
family
)
{
switch
(
family
)
{
case
PF_INET
:
if
(
sctp_pf_inet_specific
)
return
0
;
sctp_pf_inet_specific
=
pf
;
break
;
case
PF_INET6
:
if
(
sctp_pf_inet6_specific
)
return
0
;
sctp_pf_inet6_specific
=
pf
;
break
;
default:
BUG
();
break
;
return
0
;
}
return
1
;
}
/* Initialize the universe into something sensible. */
...
...
@@ -617,7 +672,7 @@ int sctp_init(void)
sctp_dbg_objcnt_init
();
/* Initialize the SCTP specific PF functions. */
sctp_
set_pf_specific
(
PF_INET
,
&
sctp_pf_inet
);
sctp_
register_pf
(
&
sctp_pf_inet
,
PF_INET
);
/*
* 14. Suggested SCTP Protocol Parameter Values
*/
...
...
@@ -709,8 +764,7 @@ int sctp_init(void)
sctp_sysctl_register
();
INIT_LIST_HEAD
(
&
sctp_proto
.
address_families
);
INIT_LIST_HEAD
(
&
sctp_ipv4_specific
.
list
);
list_add_tail
(
&
sctp_ipv4_specific
.
list
,
&
sctp_proto
.
address_families
);
sctp_register_af
(
&
sctp_ipv4_specific
);
status
=
sctp_v6_init
();
if
(
status
)
...
...
net/sctp/socket.c
View file @
fc129116
...
...
@@ -87,12 +87,7 @@ static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p,
int
msg_len
);
static
int
sctp_wait_for_packet
(
struct
sock
*
sk
,
int
*
err
,
long
*
timeo_p
);
static
int
sctp_wait_for_connect
(
sctp_association_t
*
asoc
,
long
*
timeo_p
);
static
inline
void
sctp_sk_addr_set
(
struct
sock
*
,
const
union
sctp_addr
*
newaddr
,
union
sctp_addr
*
saveaddr
);
static
inline
void
sctp_sk_addr_restore
(
struct
sock
*
,
const
union
sctp_addr
*
);
static
inline
int
sctp_verify_addr
(
struct
sock
*
,
struct
sockaddr
*
,
int
);
static
inline
int
sctp_verify_addr
(
struct
sock
*
,
union
sctp_addr
*
,
int
);
static
int
sctp_bindx_add
(
struct
sock
*
,
struct
sockaddr_storage
*
,
int
);
static
int
sctp_bindx_rem
(
struct
sock
*
,
struct
sockaddr_storage
*
,
int
);
static
int
sctp_do_bind
(
struct
sock
*
,
union
sctp_addr
*
,
int
);
...
...
@@ -133,101 +128,75 @@ int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return
retval
;
}
static
long
sctp_get_port_local
(
struct
sock
*
,
un
signed
short
);
static
long
sctp_get_port_local
(
struct
sock
*
,
un
ion
sctp_addr
*
);
/*
Bind a local address either to an endpoint or to an association.
*/
SCTP_STATIC
int
sctp_do_bind
(
struct
sock
*
sk
,
union
sctp_addr
*
newaddr
,
int
addr_
len
)
/*
Verify this is a valid sockaddr.
*/
static
struct
sctp_af
*
sctp_sockaddr_af
(
struct
sctp_opt
*
opt
,
union
sctp_addr
*
addr
,
int
len
)
{
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
sctp_endpoint_t
*
ep
=
sp
->
ep
;
sctp_bind_addr_t
*
bp
=
&
ep
->
base
.
bind_addr
;
unsigned
short
sa_family
=
newaddr
->
sa
.
sa_family
;
union
sctp_addr
tmpaddr
,
saveaddr
;
unsigned
short
*
snum
;
int
ret
=
0
;
struct
sctp_af
*
af
;
SCTP_DEBUG_PRINTK
(
"sctp_do_bind(sk: %p, newaddr: %p, addr_len: %d)
\n
"
,
sk
,
newaddr
,
addr_len
);
/* FIXME: This function needs to handle v4-mapped-on-v6
* addresses!
*/
if
(
PF_INET
==
sk
->
family
)
{
if
(
sa_family
!=
AF_INET
)
return
-
EINVAL
;
}
/* Check minimum size. */
if
(
len
<
sizeof
(
struct
sockaddr
))
return
NULL
;
/* Make a local copy of the new address. */
tmpaddr
=
*
newaddr
;
/* Does this PF support this AF? */
if
(
!
opt
->
pf
->
af_supported
(
addr
->
sa
.
sa_family
))
return
NULL
;
switch
(
sa_family
)
{
case
AF_INET
:
if
(
addr_len
<
sizeof
(
struct
sockaddr_in
))
return
-
EINVAL
;
/* If we get this far, af is valid. */
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
ret
=
inet_addr_type
(
newaddr
->
v4
.
sin_addr
.
s_addr
);
if
(
len
<
af
->
sockaddr_len
)
return
NULL
;
/* FIXME:
* Should we allow apps to bind to non-local addresses by
* checking the IP sysctl parameter "ip_nonlocal_bind"?
*/
if
(
newaddr
->
v4
.
sin_addr
.
s_addr
!=
INADDR_ANY
&&
ret
!=
RTN_LOCAL
)
return
-
EADDRNOTAVAIL
;
return
af
;
}
tmpaddr
.
v4
.
sin_port
=
htons
(
tmpaddr
.
v4
.
sin_port
);
snum
=
&
tmpaddr
.
v4
.
sin_port
;
break
;
case
AF_INET6
:
SCTP_V6
(
/* FIXME: Hui, please verify this. Looking at
* the ipv6 code I see a SIN6_LEN_RFC2133 check.
* I'm guessing that scope_id is a newer addition.
*/
if
(
addr_len
<
sizeof
(
struct
sockaddr_in6
))
return
-
EINVAL
;
/* Bind a local address either to an endpoint or to an association. */
SCTP_STATIC
int
sctp_do_bind
(
struct
sock
*
sk
,
union
sctp_addr
*
addr
,
int
len
)
{
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
sctp_endpoint_t
*
ep
=
sp
->
ep
;
sctp_bind_addr_t
*
bp
=
&
ep
->
base
.
bind_addr
;
struct
sctp_af
*
af
;
unsigned
short
snum
;
int
ret
=
0
;
/* FIXME - The support for IPv6 multiple types
* of addresses need to be added later.
*/
ret
=
sctp_ipv6_addr_type
(
&
newaddr
->
v6
.
sin6_addr
);
tmpaddr
.
v6
.
sin6_port
=
htons
(
tmpaddr
.
v6
.
sin6_port
);
snum
=
&
tmpaddr
.
v6
.
sin6_port
;
break
;
)
SCTP_DEBUG_PRINTK
(
"sctp_do_bind(sk: %p, newaddr: %p, len: %d)
\n
"
,
sk
,
addr
,
len
);
default:
/* Common sockaddr verification. */
af
=
sctp_sockaddr_af
(
sp
,
addr
,
len
);
if
(
!
af
)
return
-
EINVAL
;
};
/* 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
);
bp
->
port
,
snum
);
/* We must either be unbound, or bind to the same port. */
if
(
bp
->
port
&&
(
*
snum
!=
bp
->
port
))
{
if
(
bp
->
port
&&
(
snum
!=
bp
->
port
))
{
SCTP_DEBUG_PRINTK
(
"sctp_do_bind:"
" New port %d does not match existing port "
"%d.
\n
"
,
*
snum
,
bp
->
port
);
"%d.
\n
"
,
snum
,
bp
->
port
);
return
-
EINVAL
;
}
if
(
*
snum
&&
*
snum
<
PROT_SOCK
&&
!
capable
(
CAP_NET_BIND_SERVICE
))
if
(
snum
&&
snum
<
PROT_SOCK
&&
!
capable
(
CAP_NET_BIND_SERVICE
))
return
-
EACCES
;
/* FIXME - Make socket understand that there might be multiple bind
* addresses and there will be multiple source addresses involved in
* routing and failover decisions.
*/
sctp_sk_addr_set
(
sk
,
&
tmpaddr
,
&
saveaddr
);
/* Make sure we are allowed to bind here.
* The function sctp_get_port_local() does duplicate address
* detection.
*/
if
((
ret
=
sctp_get_port_local
(
sk
,
*
snum
)))
{
sctp_sk_addr_restore
(
sk
,
&
saveaddr
);
if
((
ret
=
sctp_get_port_local
(
sk
,
addr
)))
{
if
(
ret
==
(
long
)
sk
)
{
/* This endpoint has a conflicting address. */
return
-
EINVAL
;
...
...
@@ -237,25 +206,32 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *newaddr,
}
/* Refresh ephemeral port. */
if
(
!*
snum
)
*
snum
=
inet_sk
(
sk
)
->
num
;
if
(
!
snum
)
snum
=
inet_sk
(
sk
)
->
num
;
/* The getsockname() API depends on 'sport' being set. */
inet_sk
(
sk
)
->
sport
=
htons
(
inet_sk
(
sk
)
->
num
);
/* Add the address to the bind address list. */
sctp_local_bh_disable
();
sctp_write_lock
(
&
ep
->
base
.
addr_lock
);
/* Use GFP_ATOMIC since BHs are disabled. */
if
((
ret
=
sctp_add_bind_addr
(
bp
,
&
tmpaddr
,
GFP_ATOMIC
)))
{
sctp_sk_addr_restore
(
sk
,
&
saveaddr
);
}
else
if
(
!
bp
->
port
)
{
bp
->
port
=
*
snum
;
}
addr
->
v4
.
sin_port
=
ntohs
(
addr
->
v4
.
sin_port
);
ret
=
sctp_add_bind_addr
(
bp
,
addr
,
GFP_ATOMIC
);
addr
->
v4
.
sin_port
=
htons
(
addr
->
v4
.
sin_port
);
if
(
!
ret
&&
!
bp
->
port
)
bp
->
port
=
snum
;
sctp_write_unlock
(
&
ep
->
base
.
addr_lock
);
sctp_local_bh_enable
();
/* Copy back into socket for getsockname() use. */
if
(
!
ret
)
{
inet_sk
(
sk
)
->
sport
=
htons
(
inet_sk
(
sk
)
->
num
);
af
->
to_sk
(
addr
,
sk
);
}
return
ret
;
}
...
...
@@ -778,7 +754,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
* For a peeled-off socket, msg_name is ignored.
*/
if
((
SCTP_SOCKET_UDP_HIGH_BANDWIDTH
!=
sp
->
type
)
&&
msg
->
msg_name
)
{
err
=
sctp_verify_addr
(
sk
,
(
struct
sockaddr
*
)
msg
->
msg_name
,
err
=
sctp_verify_addr
(
sk
,
(
union
sctp_addr
*
)
msg
->
msg_name
,
msg
->
msg_namelen
);
if
(
err
)
return
err
;
...
...
@@ -1357,13 +1333,10 @@ static inline int sctp_setsockopt_set_peer_addr_params(struct sock *sk,
* optlen - the size of the buffer.
*/
SCTP_STATIC
int
sctp_setsockopt
(
struct
sock
*
sk
,
int
level
,
int
optname
,
char
*
optval
,
int
optlen
)
char
*
optval
,
int
optlen
)
{
int
retval
=
0
;
char
*
tmp
;
sctp_protocol_t
*
proto
=
sctp_get_protocol
();
struct
list_head
*
pos
;
sctp_func_t
*
af
;
SCTP_DEBUG_PRINTK
(
"sctp_setsockopt(sk: %p... optname: %d)
\n
"
,
sk
,
optname
);
...
...
@@ -1375,14 +1348,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
* are at all well-founded.
*/
if
(
level
!=
SOL_SCTP
)
{
list_for_each
(
pos
,
&
proto
->
address_families
)
{
af
=
list_entry
(
pos
,
sctp_func_t
,
list
);
retval
=
af
->
setsockopt
(
sk
,
level
,
optname
,
optval
,
optlen
);
if
(
retval
<
0
)
goto
out_nounlock
;
}
struct
sctp_af
*
af
=
sctp_sk
(
sk
)
->
pf
->
af
;
retval
=
af
->
setsockopt
(
sk
,
level
,
optname
,
optval
,
optlen
);
goto
out_nounlock
;
}
sctp_lock_sock
(
sk
);
...
...
@@ -1486,7 +1454,7 @@ SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *uaddr,
goto
out_unlock
;
}
err
=
sctp_verify_addr
(
sk
,
uaddr
,
addr_len
);
err
=
sctp_verify_addr
(
sk
,
(
union
sctp_addr
*
)
uaddr
,
addr_len
);
if
(
err
)
goto
out_unlock
;
...
...
@@ -1944,9 +1912,6 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
char
*
optval
,
int
*
optlen
)
{
int
retval
=
0
;
sctp_protocol_t
*
proto
=
sctp_get_protocol
();
sctp_func_t
*
af
;
struct
list_head
*
pos
;
int
len
;
SCTP_DEBUG_PRINTK
(
"sctp_getsockopt(sk: %p, ...)
\n
"
,
sk
);
...
...
@@ -1958,13 +1923,10 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
* are at all well-founded.
*/
if
(
level
!=
SOL_SCTP
)
{
list_for_each
(
pos
,
&
proto
->
address_families
)
{
af
=
list_entry
(
pos
,
sctp_func_t
,
list
);
retval
=
af
->
getsockopt
(
sk
,
level
,
optname
,
optval
,
optlen
);
if
(
retval
<
0
)
return
retval
;
}
struct
sctp_af
*
af
=
sctp_sk
(
sk
)
->
pf
->
af
;
retval
=
af
->
getsockopt
(
sk
,
level
,
optname
,
optval
,
optlen
);
return
retval
;
}
if
(
get_user
(
len
,
optlen
))
...
...
@@ -2032,12 +1994,17 @@ static void sctp_unhash(struct sock *sk)
*/
static
sctp_bind_bucket_t
*
sctp_bucket_create
(
sctp_bind_hashbucket_t
*
head
,
unsigned
short
snum
);
static
long
sctp_get_port_local
(
struct
sock
*
sk
,
un
signed
short
snum
)
static
long
sctp_get_port_local
(
struct
sock
*
sk
,
un
ion
sctp_addr
*
addr
)
{
sctp_bind_hashbucket_t
*
head
;
/* hash list */
sctp_bind_bucket_t
*
pp
;
/* hash list port iterator */
sctp_protocol_t
*
sctp
=
sctp_get_protocol
();
unsigned
short
snum
;
int
ret
;
/* NOTE: Remember to put this back to net order. */
addr
->
v4
.
sin_port
=
ntohs
(
addr
->
v4
.
sin_port
);
snum
=
addr
->
v4
.
sin_port
;
SCTP_DEBUG_PRINTK
(
"sctp_get_port() begins, snum=%d
\n
"
,
snum
);
...
...
@@ -2103,6 +2070,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
}
}
if
(
pp
!=
NULL
&&
pp
->
sk
!=
NULL
)
{
/* We had a port hash table hit - there is an
* available port (pp != NULL) and it is being
...
...
@@ -2110,7 +2078,6 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
* socket is going to be sk2.
*/
int
sk_reuse
=
sk
->
reuse
;
union
sctp_addr
tmpaddr
;
struct
sock
*
sk2
=
pp
->
sk
;
SCTP_DEBUG_PRINTK
(
"sctp_get_port() found a "
...
...
@@ -2118,27 +2085,6 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
if
(
pp
->
fastreuse
!=
0
&&
sk
->
reuse
!=
0
)
goto
success
;
/* FIXME - multiple addresses need to be supported
* later.
*/
switch
(
sk
->
family
)
{
case
PF_INET
:
tmpaddr
.
v4
.
sin_family
=
AF_INET
;
tmpaddr
.
v4
.
sin_port
=
snum
;
tmpaddr
.
v4
.
sin_addr
.
s_addr
=
inet_sk
(
sk
)
->
rcv_saddr
;
break
;
case
PF_INET6
:
SCTP_V6
(
tmpaddr
.
v6
.
sin6_family
=
AF_INET6
;
tmpaddr
.
v6
.
sin6_port
=
snum
;
tmpaddr
.
v6
.
sin6_addr
=
inet6_sk
(
sk
)
->
rcv_saddr
;
)
break
;
default:
break
;
};
/* Run through the list of sockets bound to the port
* (pp->port) [via the pointers bind_next and
* bind_pprev in the struct sock *sk2 (pp->sk)]. On each one,
...
...
@@ -2156,8 +2102,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
if
(
sk_reuse
&&
sk2
->
reuse
)
continue
;
if
(
sctp_bind_addr_match
(
&
ep2
->
base
.
bind_addr
,
&
tmpaddr
,
if
(
sctp_bind_addr_match
(
&
ep2
->
base
.
bind_addr
,
addr
,
sctp_sk
(
sk
)))
goto
found
;
}
...
...
@@ -2209,12 +2154,25 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
sctp_local_bh_enable
();
SCTP_DEBUG_PRINTK
(
"sctp_get_port() ends, ret=%d
\n
"
,
ret
);
addr
->
v4
.
sin_port
=
htons
(
addr
->
v4
.
sin_port
);
return
ret
;
}
/* Assign a 'snum' port to the socket. If snum == 0, an ephemeral
* port is requested.
*/
static
int
sctp_get_port
(
struct
sock
*
sk
,
unsigned
short
snum
)
{
long
ret
=
sctp_get_port_local
(
sk
,
snum
);
long
ret
;
union
sctp_addr
addr
;
struct
sctp_af
*
af
=
sctp_sk
(
sk
)
->
pf
->
af
;
/* Set up a dummy address struct from the sk. */
af
->
from_sk
(
&
addr
,
sk
);
addr
.
v4
.
sin_port
=
htons
(
snum
);
/* Note: sk->num gets filled in if ephemeral port request. */
ret
=
sctp_get_port_local
(
sk
,
&
addr
);
return
(
ret
?
1
:
0
);
}
...
...
@@ -2415,7 +2373,7 @@ void sctp_put_port(struct sock *sk)
static
int
sctp_autobind
(
struct
sock
*
sk
)
{
union
sctp_addr
autoaddr
;
struct
sctp_
func
*
af
;
struct
sctp_
af
*
af
;
unsigned
short
port
;
/* Initialize a local sockaddr structure to INADDR_ANY. */
...
...
@@ -2539,58 +2497,6 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg,
return
0
;
}
/* Setup sk->rcv_saddr before calling get_port(). */
static
inline
void
sctp_sk_addr_set
(
struct
sock
*
sk
,
const
union
sctp_addr
*
newaddr
,
union
sctp_addr
*
saveaddr
)
{
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
saveaddr
->
sa
.
sa_family
=
newaddr
->
sa
.
sa_family
;
switch
(
newaddr
->
sa
.
sa_family
)
{
case
AF_INET
:
saveaddr
->
v4
.
sin_addr
.
s_addr
=
inet
->
rcv_saddr
;
inet
->
rcv_saddr
=
inet
->
saddr
=
newaddr
->
v4
.
sin_addr
.
s_addr
;
break
;
case
AF_INET6
:
SCTP_V6
({
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
saveaddr
->
v6
.
sin6_addr
=
np
->
rcv_saddr
;
np
->
rcv_saddr
=
np
->
saddr
=
newaddr
->
v6
.
sin6_addr
;
break
;
})
default:
break
;
};
}
/* Restore sk->rcv_saddr after failing get_port(). */
static
inline
void
sctp_sk_addr_restore
(
struct
sock
*
sk
,
const
union
sctp_addr
*
addr
)
{
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
switch
(
addr
->
sa
.
sa_family
)
{
case
AF_INET
:
inet
->
rcv_saddr
=
inet
->
saddr
=
addr
->
v4
.
sin_addr
.
s_addr
;
break
;
case
AF_INET6
:
SCTP_V6
({
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
np
->
rcv_saddr
=
np
->
saddr
=
addr
->
v6
.
sin6_addr
;
break
;
})
default:
break
;
};
}
/*
* Wait for a packet..
* Note: This function is the same function as in core/datagram.c
...
...
@@ -2713,27 +2619,15 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no
}
/* Verify that this is a valid address. */
static
int
sctp_verify_addr
(
struct
sock
*
sk
,
struct
sock
addr
*
addr
,
int
len
)
static
int
sctp_verify_addr
(
struct
sock
*
sk
,
union
sctp_
addr
*
addr
,
int
len
)
{
struct
sctp_func
*
af
;
/* Check minimum size. */
if
(
len
<
sizeof
(
struct
sockaddr
))
return
-
EINVAL
;
struct
sctp_af
*
af
;
/*
Do we support this address family in general?
*/
af
=
sctp_
get_af_specific
(
addr
->
sa_family
);
/*
Verify basic sockaddr.
*/
af
=
sctp_
sockaddr_af
(
sctp_sk
(
sk
),
addr
,
len
);
if
(
!
af
)
return
-
EINVAL
;
/* Does this PF support this AF? */
if
(
!
sctp_sk
(
sk
)
->
pf
->
af_supported
(
addr
->
sa_family
))
return
-
EINVAL
;
/* Verify the minimum for this AF sockaddr. */
if
(
len
<
af
->
sockaddr_len
)
return
-
EINVAL
;
/* Is this a valid SCTP address? */
if
(
!
af
->
addr_valid
((
union
sctp_addr
*
)
addr
))
return
-
EINVAL
;
...
...
net/sctp/transport.c
View file @
fc129116
...
...
@@ -207,7 +207,7 @@ void sctp_transport_route(sctp_transport_t *transport, union sctp_addr *saddr,
struct
sctp_opt
*
opt
)
{
sctp_association_t
*
asoc
=
transport
->
asoc
;
struct
sctp_
func
*
af
=
transport
->
af_specific
;
struct
sctp_
af
*
af
=
transport
->
af_specific
;
union
sctp_addr
*
daddr
=
&
transport
->
ipaddr
;
sctp_bind_addr_t
*
bp
;
rwlock_t
*
addr_lock
;
...
...
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