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
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