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
2520f0dc
Commit
2520f0dc
authored
Nov 13, 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
af18c093
c5124639
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
200 additions
and
241 deletions
+200
-241
include/net/sctp/structs.h
include/net/sctp/structs.h
+12
-7
net/sctp/associola.c
net/sctp/associola.c
+27
-121
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+21
-81
net/sctp/endpointola.c
net/sctp/endpointola.c
+2
-1
net/sctp/ipv6.c
net/sctp/ipv6.c
+59
-7
net/sctp/output.c
net/sctp/output.c
+1
-1
net/sctp/protocol.c
net/sctp/protocol.c
+63
-12
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+2
-1
net/sctp/socket.c
net/sctp/socket.c
+7
-6
net/sctp/transport.c
net/sctp/transport.c
+6
-4
No files found.
include/net/sctp/structs.h
View file @
2520f0dc
...
...
@@ -250,8 +250,10 @@ typedef struct sctp_func {
union
sctp_addr
*
saddr
);
void
(
*
copy_addrlist
)
(
struct
list_head
*
,
struct
net_device
*
);
int
(
*
cmp_saddr
)
(
struct
dst_entry
*
dst
,
union
sctp_addr
*
saddr
);
void
(
*
dst_saddr
)
(
union
sctp_addr
*
saddr
,
struct
dst_entry
*
dst
);
int
(
*
cmp_addr
)
(
const
union
sctp_addr
*
addr1
,
const
union
sctp_addr
*
addr2
);
void
(
*
addr_copy
)
(
union
sctp_addr
*
dst
,
union
sctp_addr
*
src
);
void
(
*
from_skb
)
(
union
sctp_addr
*
,
...
...
@@ -260,6 +262,7 @@ typedef struct sctp_func {
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
*
);
__u16
net_header_len
;
int
sockaddr_len
;
sa_family_t
sa_family
;
...
...
@@ -273,6 +276,9 @@ 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
);
int
(
*
cmp_addr
)
(
const
union
sctp_addr
*
,
const
union
sctp_addr
*
,
struct
sctp_opt
*
);
struct
sctp_func
*
af
;
}
sctp_pf_t
;
...
...
@@ -758,7 +764,8 @@ extern sctp_transport_t *sctp_transport_new(const union sctp_addr *, int);
extern
sctp_transport_t
*
sctp_transport_init
(
sctp_transport_t
*
,
const
union
sctp_addr
*
,
int
);
extern
void
sctp_transport_set_owner
(
sctp_transport_t
*
,
sctp_association_t
*
);
extern
void
sctp_transport_route
(
sctp_transport_t
*
,
union
sctp_addr
*
);
extern
void
sctp_transport_route
(
sctp_transport_t
*
,
union
sctp_addr
*
,
struct
sctp_opt
*
);
extern
void
sctp_transport_free
(
sctp_transport_t
*
);
extern
void
sctp_transport_destroy
(
sctp_transport_t
*
);
extern
void
sctp_transport_reset_timers
(
sctp_transport_t
*
);
...
...
@@ -908,7 +915,8 @@ int sctp_bind_addr_copy(sctp_bind_addr_t *dest, const sctp_bind_addr_t *src,
int
sctp_add_bind_addr
(
sctp_bind_addr_t
*
,
union
sctp_addr
*
,
int
priority
);
int
sctp_del_bind_addr
(
sctp_bind_addr_t
*
,
union
sctp_addr
*
);
int
sctp_bind_addr_has_addr
(
sctp_bind_addr_t
*
,
const
union
sctp_addr
*
);
int
sctp_bind_addr_match
(
sctp_bind_addr_t
*
,
const
union
sctp_addr
*
,
struct
sctp_opt
*
);
union
sctp_params
sctp_bind_addrs_to_raw
(
const
sctp_bind_addr_t
*
bp
,
int
*
addrs_len
,
int
priority
);
...
...
@@ -1565,14 +1573,11 @@ __u32 __sctp_association_get_next_tsn(sctp_association_t *);
__u32
__sctp_association_get_tsn_block
(
sctp_association_t
*
,
int
);
__u16
__sctp_association_get_next_ssn
(
sctp_association_t
*
,
__u16
sid
);
int
sctp_cmp_addr
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
);
int
sctp_cmp_addr_exact
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
);
sctp_chunk_t
*
sctp_get_ecne_prepend
(
sctp_association_t
*
asoc
);
sctp_chunk_t
*
sctp_get_no_prepend
(
sctp_association_t
*
asoc
);
/* A convenience structure to parse out SCTP specific CMSGs. */
typedef
struct
sctp_cmsgs
{
struct
sctp_initmsg
*
init
;
...
...
net/sctp/associola.c
View file @
2520f0dc
...
...
@@ -4,36 +4,36 @@
* Copyright (c) 2001-2002 International Business Machines Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* This module provides the abstraction for an SCTP association.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@us.ibm.com>
...
...
@@ -41,7 +41,7 @@
* Hui Huang <hui.huang@nokia.com>
* Sridhar Samudrala <sri@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -92,7 +92,7 @@ sctp_association_t *sctp_association_new(const sctp_endpoint_t *ep,
sctp_association_t
*
sctp_association_init
(
sctp_association_t
*
asoc
,
const
sctp_endpoint_t
*
ep
,
const
struct
sock
*
sk
,
sctp_scope_t
scope
,
sctp_scope_t
scope
,
int
priority
)
{
sctp_opt_t
*
sp
;
...
...
@@ -368,43 +368,29 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
{
sctp_transport_t
*
peer
;
sctp_opt_t
*
sp
;
const
__u16
*
port
;
switch
(
addr
->
sa
.
sa_family
)
{
case
AF_INET
:
port
=
&
addr
->
v4
.
sin_port
;
break
;
case
AF_INET6
:
SCTP_V6
(
port
=
&
addr
->
v6
.
sin6_port
;
break
;
);
unsigned
short
port
;
default:
return
NULL
;
};
/* AF_INET and AF_INET6 share common port field. */
port
=
addr
->
v4
.
sin_port
;
/* Set the port if it has not been set yet. */
if
(
0
==
asoc
->
peer
.
port
)
{
asoc
->
peer
.
port
=
*
port
;
asoc
->
peer
.
port
=
port
;
}
SCTP_ASSERT
(
*
port
==
asoc
->
peer
.
port
,
":Invalid port
\n
"
,
return
NULL
);
/* Check to see if this is a duplicate. */
peer
=
sctp_assoc_lookup_paddr
(
asoc
,
addr
);
if
(
peer
)
return
peer
;
peer
=
sctp_transport_new
(
addr
,
priority
);
if
(
NULL
==
peer
)
if
(
!
peer
)
return
NULL
;
sctp_transport_set_owner
(
peer
,
asoc
);
/* Cache a route for the transport. */
sctp_transport_route
(
peer
,
NULL
);
sctp_transport_route
(
peer
,
NULL
,
sctp_sk
(
asoc
->
base
.
sk
)
);
/* If this is the first transport addr on this association,
* initialize the association PMTU to the peer's PMTU.
...
...
@@ -648,62 +634,6 @@ __u16 __sctp_association_get_next_ssn(sctp_association_t *asoc, __u16 sid)
return
asoc
->
ssn
[
sid
]
++
;
}
/* Compare two addresses to see if they match. Wildcard addresses
* always match within their address family.
*
* FIXME: We do not match address scopes correctly.
*/
int
sctp_cmp_addr
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
)
{
int
len
;
const
void
*
base1
;
const
void
*
base2
;
if
(
ss1
->
sa
.
sa_family
!=
ss2
->
sa
.
sa_family
)
return
0
;
if
(
ss1
->
v4
.
sin_port
!=
ss2
->
v4
.
sin_port
)
return
0
;
switch
(
ss1
->
sa
.
sa_family
)
{
case
AF_INET
:
if
(
INADDR_ANY
==
ss1
->
v4
.
sin_addr
.
s_addr
||
INADDR_ANY
==
ss2
->
v4
.
sin_addr
.
s_addr
)
goto
match
;
len
=
sizeof
(
struct
in_addr
);
base1
=
&
ss1
->
v4
.
sin_addr
;
base2
=
&
ss2
->
v4
.
sin_addr
;
break
;
case
AF_INET6
:
SCTP_V6
(
if
(
IPV6_ADDR_ANY
==
sctp_ipv6_addr_type
(
&
ss1
->
v6
.
sin6_addr
))
goto
match
;
if
(
IPV6_ADDR_ANY
==
sctp_ipv6_addr_type
(
&
ss2
->
v6
.
sin6_addr
))
goto
match
;
len
=
sizeof
(
struct
in6_addr
);
base1
=
&
ss1
->
v6
.
sin6_addr
;
base2
=
&
ss2
->
v6
.
sin6_addr
;
break
;
)
default:
printk
(
KERN_WARNING
"WARNING, bogus socket address family %d
\n
"
,
ss1
->
sa
.
sa_family
);
return
0
;
};
return
(
0
==
memcmp
(
base1
,
base2
,
len
));
match:
return
1
;
}
/* Compare two addresses to see if they match. Wildcard addresses
* only match themselves.
*
...
...
@@ -712,38 +642,13 @@ int sctp_cmp_addr(const union sctp_addr *ss1, const union sctp_addr *ss2)
int
sctp_cmp_addr_exact
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
)
{
int
len
;
const
void
*
base1
;
const
void
*
base2
;
if
(
ss1
->
sa
.
sa_family
!=
ss2
->
sa
.
sa_family
)
return
0
;
if
(
ss1
->
v4
.
sin_port
!=
ss2
->
v4
.
sin_port
)
return
0
;
struct
sctp_func
*
af
;
switch
(
ss1
->
sa
.
sa_family
)
{
case
AF_INET
:
len
=
sizeof
(
struct
in_addr
);
base1
=
&
ss1
->
v4
.
sin_addr
;
base2
=
&
ss2
->
v4
.
sin_addr
;
break
;
case
AF_INET6
:
SCTP_V6
(
len
=
sizeof
(
struct
in6_addr
);
base1
=
&
ss1
->
v6
.
sin6_addr
;
base2
=
&
ss2
->
v6
.
sin6_addr
;
break
;
)
default:
printk
(
KERN_WARNING
"WARNING, bogus socket address family %d
\n
"
,
ss1
->
sa
.
sa_family
);
af
=
sctp_get_af_specific
(
ss1
->
sa
.
sa_family
);
if
(
!
af
)
return
0
;
};
return
(
0
==
memcmp
(
base1
,
base2
,
len
)
);
return
af
->
cmp_addr
(
ss1
,
ss2
);
}
/* Return an ecne chunk to get prepended to a packet.
...
...
@@ -858,7 +763,8 @@ sctp_transport_t *sctp_assoc_is_match(sctp_association_t *asoc,
if
(
!
transport
)
goto
out
;
if
(
sctp_bind_addr_has_addr
(
&
asoc
->
base
.
bind_addr
,
laddr
))
if
(
sctp_bind_addr_match
(
&
asoc
->
base
.
bind_addr
,
laddr
,
sctp_sk
(
asoc
->
base
.
sk
)))
goto
out
;
}
transport
=
NULL
;
...
...
@@ -901,7 +807,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc)
error
=
sctp_do_sm
(
SCTP_EVENT_T_CHUNK
,
SCTP_ST_CHUNK
(
subtype
),
state
,
ep
,
asoc
,
chunk
,
GFP_ATOMIC
);
/* Check to see if the association is freed in response to
/* Check to see if the association is freed in response to
* the incoming chunk. If so, get out of the while loop.
*/
if
(
!
sctp_id2assoc
(
sk
,
associd
))
...
...
net/sctp/bind_addr.c
View file @
2520f0dc
...
...
@@ -282,15 +282,16 @@ int sctp_raw_to_bind_addrs(sctp_bind_addr_t *bp, __u8 *raw_addr_list,
* 2nd Level Abstractions
********************************************************************/
/* Does this contain a specified address? */
int
sctp_bind_addr_has_addr
(
sctp_bind_addr_t
*
bp
,
const
union
sctp_addr
*
addr
)
/* Does this contain a specified address? Allow wildcarding. */
int
sctp_bind_addr_match
(
sctp_bind_addr_t
*
bp
,
const
union
sctp_addr
*
addr
,
struct
sctp_opt
*
opt
)
{
struct
sockaddr_storage_list
*
laddr
;
struct
list_head
*
pos
;
list_for_each
(
pos
,
&
bp
->
address_list
)
{
laddr
=
list_entry
(
pos
,
struct
sockaddr_storage_list
,
list
);
if
(
sctp_cmp_addr
(
&
laddr
->
a
,
addr
))
if
(
opt
->
pf
->
cmp_addr
(
&
laddr
->
a
,
addr
,
opt
))
return
1
;
}
...
...
@@ -323,30 +324,13 @@ static int sctp_copy_one_addr(sctp_bind_addr_t *dest, union sctp_addr *addr,
return
error
;
}
/* Is
addr one of the wildcard
s? */
/* Is
this a wildcard addres
s? */
int
sctp_is_any
(
const
union
sctp_addr
*
addr
)
{
int
retval
=
0
;
switch
(
addr
->
sa
.
sa_family
)
{
case
AF_INET
:
if
(
INADDR_ANY
==
addr
->
v4
.
sin_addr
.
s_addr
)
retval
=
1
;
break
;
case
AF_INET6
:
SCTP_V6
(
if
(
IPV6_ADDR_ANY
==
sctp_ipv6_addr_type
(
&
addr
->
v6
.
sin6_addr
))
retval
=
1
;
);
break
;
default:
break
;
};
return
retval
;
struct
sctp_func
*
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
if
(
!
af
)
return
0
;
return
af
->
is_any
(
addr
);
}
/* Is 'addr' valid for 'scope'? */
...
...
@@ -354,63 +338,19 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
{
sctp_scope_t
addr_scope
=
sctp_scope
(
addr
);
switch
(
addr
->
sa
.
sa_family
)
{
case
AF_INET
:
/* According to the SCTP IPv4 address scoping document -
* <draft-stewart-tsvwg-sctp-ipv4-00.txt>, the scope has
* a heirarchy of 5 levels:
* Level 0 - unusable SCTP addresses
* Level 1 - loopback address
* Level 2 - link-local addresses
* Level 3 - private addresses.
* Level 4 - global addresses
* For INIT and INIT-ACK address list, let L be the level of
* of requested destination address, sender and receiver
* SHOULD include all of its addresses with level greater
* than or equal to L.
*/
/* The unusable SCTP addresses will not be considered with
* any defined scopes.
*/
if
(
SCTP_SCOPE_UNUSABLE
==
addr_scope
)
return
0
;
/* Note that we are assuming that the scoping are the same
* for both IPv4 addresses and IPv6 addresses, i.e., if the
* scope is link local, both IPv4 link local addresses and
* IPv6 link local addresses would be treated as in the
* scope. There is no filtering for IPv4 vs. IPv6 addresses
* based on scoping alone.
*/
if
(
addr_scope
<=
scope
)
return
1
;
break
;
case
AF_INET6
:
/* FIXME:
* This is almost certainly wrong since scopes have an
* heirarchy. I don't know what RFC to look at.
* There may be some guidance in the SCTP implementors
* guide (an Internet Draft as of October 2001).
*
* Further verification on the correctness of the IPv6
* scoping is needed. According to the IPv6 scoping draft,
* the link local and site local address may require
* further scoping.
*
* Is the heirachy of the IPv6 scoping the same as what's
* defined for IPv4?
* If the same heirarchy indeed applies to both famiies,
* this function can be simplified with one set of code.
* (see the comments for IPv4 above)
*/
if
(
addr_scope
<=
scope
)
return
1
;
break
;
default:
/* The unusable SCTP addresses will not be considered with
* any defined scopes.
*/
if
(
SCTP_SCOPE_UNUSABLE
==
addr_scope
)
return
0
;
};
/*
* For INIT and INIT-ACK address list, let L be the level of
* of requested destination address, sender and receiver
* SHOULD include all of its addresses with level greater
* than or equal to L.
*/
if
(
addr_scope
<=
scope
)
return
1
;
return
0
;
}
...
...
net/sctp/endpointola.c
View file @
2520f0dc
...
...
@@ -243,7 +243,8 @@ sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *ep,
sctp_read_lock
(
&
ep
->
base
.
addr_lock
);
if
(
ep
->
base
.
bind_addr
.
port
==
laddr
->
v4
.
sin_port
)
{
if
(
sctp_bind_addr_has_addr
(
&
ep
->
base
.
bind_addr
,
laddr
))
{
if
(
sctp_bind_addr_match
(
&
ep
->
base
.
bind_addr
,
laddr
,
sctp_sk
(
ep
->
base
.
sk
)))
{
retval
=
ep
;
goto
out
;
}
...
...
net/sctp/ipv6.c
View file @
2520f0dc
...
...
@@ -176,8 +176,8 @@ struct dst_entry *sctp_v6_get_dst(union sctp_addr *daddr,
union
sctp_addr
*
saddr
)
{
struct
dst_entry
*
dst
;
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip6_u
=
{
.
daddr
=
&
daddr
->
v6
.
sin6_addr
,
}
}
};
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip6_u
=
{
.
daddr
=
&
daddr
->
v6
.
sin6_addr
,
}
}
};
SCTP_DEBUG_PRINTK
(
"%s: DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
,
...
...
@@ -261,22 +261,45 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
ipv6_addr_copy
(
&
addr
->
v6
.
sin6_addr
,
from
);
}
/*
Check if the dst entry's source addr matches the given source addr
. */
static
int
sctp_v6_cmp_saddr
(
struct
dst_entry
*
dst
,
union
sctp_addr
*
saddr
)
/*
Initialize a sctp_addr from a dst_entry
. */
static
void
sctp_v6_dst_saddr
(
union
sctp_addr
*
addr
,
struct
dst_entry
*
dst
)
{
struct
rt6_info
*
rt
=
(
struct
rt6_info
*
)
dst
;
addr
->
sa
.
sa_family
=
AF_INET6
;
ipv6_addr_copy
(
&
addr
->
v6
.
sin6_addr
,
&
rt
->
rt6i_src
.
addr
);
}
/* Compare addresses exactly. Well.. almost exactly; ignore scope_id
* for now. FIXME.
*/
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
,
(
struct
in6_addr
*
)
&
addr2
->
v6
.
sin6_addr
);
return
ipv6_addr_cmp
(
&
rt
->
rt6i_src
.
addr
,
&
saddr
->
v6
.
sin6_addr
)
;
return
match
;
}
/* Initialize addr struct to INADDR_ANY. */
void
sctp_v6_inaddr_any
(
union
sctp_addr
*
addr
,
unsigned
short
port
)
static
void
sctp_v6_inaddr_any
(
union
sctp_addr
*
addr
,
unsigned
short
port
)
{
memset
(
addr
,
0x00
,
sizeof
(
union
sctp_addr
));
addr
->
v6
.
sin6_family
=
AF_INET6
;
addr
->
v6
.
sin6_port
=
port
;
}
/* Is this a wildcard address? */
static
int
sctp_v6_is_any
(
const
union
sctp_addr
*
addr
)
{
int
type
;
type
=
ipv6_addr_type
((
struct
in6_addr
*
)
&
addr
->
v6
.
sin6_addr
);
return
IPV6_ADDR_ANY
==
type
;
}
/* This function checks if the address is a valid address to be used for
* SCTP.
*
...
...
@@ -417,6 +440,32 @@ 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.
*/
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
;
af1
=
sctp_get_af_specific
(
addr1
->
sa
.
sa_family
);
af2
=
sctp_get_af_specific
(
addr2
->
sa
.
sa_family
);
if
(
!
af1
||
!
af2
)
return
0
;
/* Today, wildcard AF_INET/AF_INET6. */
if
(
sctp_is_any
(
addr1
)
||
sctp_is_any
(
addr2
))
return
1
;
if
(
addr1
->
sa
.
sa_family
!=
addr2
->
sa
.
sa_family
)
return
0
;
return
af1
->
cmp_addr
(
addr1
,
addr2
);
}
static
struct
proto_ops
inet6_seqpacket_ops
=
{
.
family
=
PF_INET6
,
...
...
@@ -459,10 +508,12 @@ static sctp_func_t sctp_ipv6_specific = {
.
get_dst
=
sctp_v6_get_dst
,
.
copy_addrlist
=
sctp_v6_copy_addrlist
,
.
from_skb
=
sctp_v6_from_skb
,
.
cmp_saddr
=
sctp_v6_cmp_saddr
,
.
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
,
.
net_header_len
=
sizeof
(
struct
ipv6hdr
),
.
sockaddr_len
=
sizeof
(
struct
sockaddr_in6
),
.
sa_family
=
AF_INET6
,
...
...
@@ -472,6 +523,7 @@ static sctp_pf_t 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
,
.
af
=
&
sctp_ipv6_specific
,
};
...
...
net/sctp/output.c
View file @
2520f0dc
...
...
@@ -425,7 +425,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
dst
=
transport
->
dst
;
if
(
!
dst
||
dst
->
obsolete
)
{
sctp_transport_route
(
transport
,
NULL
);
sctp_transport_route
(
transport
,
NULL
,
sctp_sk
(
sk
)
);
}
nskb
->
dst
=
dst_clone
(
transport
->
dst
);
...
...
net/sctp/protocol.c
View file @
2520f0dc
...
...
@@ -227,12 +227,11 @@ struct dst_entry *sctp_v4_get_dst(union sctp_addr *daddr,
union
sctp_addr
*
saddr
)
{
struct
rtable
*
rt
;
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
daddr
->
v4
.
sin_addr
.
s_addr
,
}},
.
proto
=
IPPROTO_SCTP
,
};
struct
flowi
fl
;
memset
(
&
fl
,
0x0
,
sizeof
(
struct
flowi
));
fl
.
fl4_dst
=
daddr
->
v4
.
sin_addr
.
s_addr
;
fl
.
proto
=
IPPROTO_SCTP
;
if
(
saddr
)
fl
.
fl4_src
=
saddr
->
v4
.
sin_addr
.
s_addr
;
...
...
@@ -275,22 +274,42 @@ 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
));
}
/*
Check if the dst entry's source addr matches the given source addr
. */
int
sctp_v4_cmp_saddr
(
struct
dst_entry
*
dst
,
union
sctp_addr
*
saddr
)
/*
Initialize a sctp_addr from a dst_entry
. */
static
void
sctp_v4_dst_saddr
(
union
sctp_addr
*
saddr
,
struct
dst_entry
*
dst
)
{
struct
rtable
*
rt
=
(
struct
rtable
*
)
dst
;
saddr
->
v4
.
sin_family
=
AF_INET
;
saddr
->
v4
.
sin_addr
.
s_addr
=
rt
->
rt_src
;
}
/* Compare two addresses exactly. */
static
int
sctp_v4_cmp_addr
(
const
union
sctp_addr
*
addr1
,
const
union
sctp_addr
*
addr2
)
{
if
(
addr1
->
sa
.
sa_family
!=
addr2
->
sa
.
sa_family
)
return
0
;
if
(
addr1
->
v4
.
sin_port
!=
addr2
->
v4
.
sin_port
)
return
0
;
if
(
addr1
->
v4
.
sin_addr
.
s_addr
!=
addr2
->
v4
.
sin_addr
.
s_addr
)
return
0
;
return
(
rt
->
rt_src
==
saddr
->
v4
.
sin_addr
.
s_addr
)
;
return
1
;
}
/* Initialize addr struct to INADDR_ANY. */
void
sctp_v4_inaddr_any
(
union
sctp_addr
*
addr
,
unsigned
short
port
)
static
void
sctp_v4_inaddr_any
(
union
sctp_addr
*
addr
,
unsigned
short
port
)
{
addr
->
v4
.
sin_family
=
AF_INET
;
addr
->
v4
.
sin_addr
.
s_addr
=
INADDR_ANY
;
addr
->
v4
.
sin_port
=
port
;
}
/* Is this a wildcard address? */
static
int
sctp_v4_is_any
(
const
union
sctp_addr
*
addr
)
{
return
INADDR_ANY
==
addr
->
v4
.
sin_addr
.
s_addr
;
}
/* This function checks if the address is a valid address to be used for
* SCTP.
*
...
...
@@ -310,6 +329,16 @@ static int sctp_v4_addr_valid(union sctp_addr *addr)
/* 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>.
*
* Level 0 - unusable SCTP addresses
* Level 1 - loopback address
* Level 2 - link-local addresses
* Level 3 - private addresses.
* Level 4 - global addresses
* For INIT and INIT-ACK address list, let L be the level of
* of requested destination address, sender and receiver
* SHOULD include all of its addresses with level greater
* than or equal to L.
*/
static
sctp_scope_t
sctp_v4_scope
(
union
sctp_addr
*
addr
)
{
...
...
@@ -413,7 +442,8 @@ static void sctp_inet_msgname(char *msgname, int *addr_len)
}
/* Copy the primary address of the peer primary address as the msg_name. */
static
void
sctp_inet_event_msgname
(
sctp_ulpevent_t
*
event
,
char
*
msgname
,
int
*
addr_len
)
static
void
sctp_inet_event_msgname
(
sctp_ulpevent_t
*
event
,
char
*
msgname
,
int
*
addr_len
)
{
struct
sockaddr_in
*
sin
,
*
sinfrom
;
...
...
@@ -448,12 +478,31 @@ static int sctp_inet_af_supported(sa_family_t family)
return
(
AF_INET
==
family
);
}
/* Address matching with wildcards allowed. */
static
int
sctp_inet_cmp_addr
(
const
union
sctp_addr
*
addr1
,
const
union
sctp_addr
*
addr2
,
struct
sctp_opt
*
opt
)
{
/* PF_INET only supports AF_INET addresses. */
if
(
addr1
->
sa
.
sa_family
!=
addr2
->
sa
.
sa_family
)
return
0
;
if
(
INADDR_ANY
==
addr1
->
v4
.
sin_addr
.
s_addr
||
INADDR_ANY
==
addr2
->
v4
.
sin_addr
.
s_addr
)
return
1
;
if
(
addr1
->
v4
.
sin_addr
.
s_addr
==
addr2
->
v4
.
sin_addr
.
s_addr
)
return
1
;
return
0
;
}
struct
sctp_func
sctp_ipv4_specific
;
static
sctp_pf_t
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
,
.
af
=
&
sctp_ipv4_specific
,
};
...
...
@@ -509,9 +558,11 @@ struct sctp_func sctp_ipv4_specific = {
.
get_dst
=
sctp_v4_get_dst
,
.
copy_addrlist
=
sctp_v4_copy_addrlist
,
.
from_skb
=
sctp_v4_from_skb
,
.
cmp_saddr
=
sctp_v4_cmp_saddr
,
.
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
,
.
scope
=
sctp_v4_scope
,
.
net_header_len
=
sizeof
(
struct
iphdr
),
.
sockaddr_len
=
sizeof
(
struct
sockaddr_in
),
...
...
net/sctp/sm_statefuns.c
View file @
2520f0dc
...
...
@@ -4314,7 +4314,8 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
/* Cache a route for the transport with the chunk's destination as
* the source address.
*/
sctp_transport_route
(
transport
,
(
union
sctp_addr
*
)
&
chunk
->
dest
);
sctp_transport_route
(
transport
,
(
union
sctp_addr
*
)
&
chunk
->
dest
,
sctp_sk
(
sctp_get_ctl_sock
()));
packet
=
sctp_packet_init
(
packet
,
transport
,
sport
,
dport
);
packet
=
sctp_packet_config
(
packet
,
vtag
,
0
,
NULL
);
...
...
net/sctp/socket.c
View file @
2520f0dc
...
...
@@ -2117,12 +2117,13 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
sctp_endpoint_t
*
ep2
;
ep2
=
sctp_sk
(
sk2
)
->
ep
;
if
(
!
sk_reuse
||
!
sk2
->
reuse
)
{
if
(
sctp_bind_addr_has_addr
(
&
ep2
->
base
.
bind_addr
,
&
tmpaddr
))
{
goto
found
;
}
}
if
(
sk_reuse
&&
sk2
->
reuse
)
continue
;
if
(
sctp_bind_addr_match
(
&
ep2
->
base
.
bind_addr
,
&
tmpaddr
,
sctp_sk
(
sk
)))
goto
found
;
}
found:
...
...
net/sctp/transport.c
View file @
2520f0dc
...
...
@@ -203,17 +203,18 @@ void sctp_transport_set_owner(sctp_transport_t *transport,
/* Caches the dst entry for a transport's destination address and an optional
* souce address.
*/
void
sctp_transport_route
(
sctp_transport_t
*
transport
,
union
sctp_addr
*
saddr
)
void
sctp_transport_route
(
sctp_transport_t
*
transport
,
union
sctp_addr
*
saddr
,
struct
sctp_opt
*
opt
)
{
sctp_association_t
*
asoc
=
transport
->
asoc
;
s
ctp_func_t
*
af
=
transport
->
af_specific
;
s
truct
sctp_func
*
af
=
transport
->
af_specific
;
union
sctp_addr
*
daddr
=
&
transport
->
ipaddr
;
sctp_bind_addr_t
*
bp
;
rwlock_t
*
addr_lock
;
struct
sockaddr_storage_list
*
laddr
;
struct
list_head
*
pos
;
struct
dst_entry
*
dst
;
union
sctp_addr
dst_saddr
;
dst
=
af
->
get_dst
(
daddr
,
saddr
);
...
...
@@ -239,7 +240,8 @@ void sctp_transport_route(sctp_transport_t *transport,
list_for_each
(
pos
,
&
bp
->
address_list
)
{
laddr
=
list_entry
(
pos
,
struct
sockaddr_storage_list
,
list
);
if
(
af
->
cmp_saddr
(
dst
,
&
laddr
->
a
))
af
->
dst_saddr
(
&
dst_saddr
,
dst
);
if
(
opt
->
pf
->
cmp_addr
(
&
dst_saddr
,
&
laddr
->
a
,
opt
))
goto
out_unlock
;
}
sctp_read_unlock
(
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