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
845ddb44
Commit
845ddb44
authored
Jul 15, 2003
by
Jon Grimm
Committed by
Sridhar Samudrala
Jul 15, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP] Support v4-mapped-v6 addresses (Ardelle Fan)
parent
33585c7e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
165 additions
and
47 deletions
+165
-47
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+19
-0
include/net/sctp/structs.h
include/net/sctp/structs.h
+6
-3
include/net/sctp/user.h
include/net/sctp/user.h
+2
-0
net/sctp/input.c
net/sctp/input.c
+1
-1
net/sctp/ipv6.c
net/sctp/ipv6.c
+86
-30
net/sctp/protocol.c
net/sctp/protocol.c
+11
-4
net/sctp/socket.c
net/sctp/socket.c
+34
-9
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+6
-0
No files found.
include/net/sctp/sctp.h
View file @
845ddb44
...
...
@@ -611,4 +611,23 @@ int static inline __sctp_sstate(const struct sock *sk, sctp_sock_state_t state)
return
sk
->
sk_state
==
state
;
}
/* Map v4-mapped v6 address back to v4 address */
static
inline
void
sctp_v6_map_v4
(
union
sctp_addr
*
addr
)
{
addr
->
v4
.
sin_family
=
AF_INET
;
addr
->
v4
.
sin_port
=
addr
->
v6
.
sin6_port
;
addr
->
v4
.
sin_addr
.
s_addr
=
addr
->
v6
.
sin6_addr
.
s6_addr32
[
3
];
}
/* Map v4 address to v4-mapped v6 address */
static
inline
void
sctp_v4_map_v6
(
union
sctp_addr
*
addr
)
{
addr
->
v6
.
sin6_family
=
AF_INET6
;
addr
->
v6
.
sin6_port
=
addr
->
v4
.
sin_port
;
addr
->
v6
.
sin6_addr
.
s6_addr32
[
3
]
=
addr
->
v4
.
sin_addr
.
s_addr
;
addr
->
v6
.
sin6_addr
.
s6_addr32
[
0
]
=
0
;
addr
->
v6
.
sin6_addr
.
s6_addr32
[
1
]
=
0
;
addr
->
v6
.
sin6_addr
.
s6_addr32
[
2
]
=
htonl
(
0x0000ffff
);
}
#endif
/* __net_sctp_h__ */
include/net/sctp/structs.h
View file @
845ddb44
...
...
@@ -260,11 +260,13 @@ struct sctp_af {
struct
sock
*
sk
);
void
(
*
to_sk_daddr
)
(
union
sctp_addr
*
,
struct
sock
*
sk
);
int
(
*
addr_valid
)
(
union
sctp_addr
*
);
int
(
*
addr_valid
)
(
union
sctp_addr
*
,
struct
sctp_opt
*
);
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
*
);
int
(
*
available
)
(
union
sctp_addr
*
,
struct
sctp_opt
*
);
int
(
*
skb_iif
)
(
const
struct
sk_buff
*
sk
);
int
(
*
is_ce
)
(
const
struct
sk_buff
*
sk
);
void
(
*
seq_dump_addr
)(
struct
seq_file
*
seq
,
...
...
@@ -282,7 +284,7 @@ int sctp_register_af(struct sctp_af *);
struct
sctp_pf
{
void
(
*
event_msgname
)(
struct
sctp_ulpevent
*
,
char
*
,
int
*
);
void
(
*
skb_msgname
)
(
struct
sk_buff
*
,
char
*
,
int
*
);
int
(
*
af_supported
)
(
sa_family_t
);
int
(
*
af_supported
)
(
sa_family_t
,
struct
sctp_opt
*
);
int
(
*
cmp_addr
)
(
const
union
sctp_addr
*
,
const
union
sctp_addr
*
,
struct
sctp_opt
*
);
...
...
@@ -291,6 +293,7 @@ struct sctp_pf {
int
(
*
supported_addrs
)(
const
struct
sctp_opt
*
,
__u16
*
);
struct
sock
*
(
*
create_accept_sk
)
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
);
void
(
*
addr_v4map
)
(
struct
sctp_opt
*
,
union
sctp_addr
*
);
struct
sctp_af
*
af
;
};
...
...
include/net/sctp/user.h
View file @
845ddb44
...
...
@@ -2,6 +2,7 @@
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2003 International Business Machines, Corp.
* Copyright (c) 2002 Intel Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
...
...
@@ -41,6 +42,7 @@
* Jon Grimm <jgrimm@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ryan Layer <rmlayer@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
* Sridhar Samudrala <sri@us.ibm.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
...
...
net/sctp/input.c
View file @
845ddb44
...
...
@@ -150,7 +150,7 @@ int sctp_rcv(struct sk_buff *skb)
* IP broadcast addresses cannot be used in an SCTP transport
* address."
*/
if
(
!
af
->
addr_valid
(
&
src
)
||
!
af
->
addr_valid
(
&
dest
))
if
(
!
af
->
addr_valid
(
&
src
,
NULL
)
||
!
af
->
addr_valid
(
&
dest
,
NULL
))
goto
discard_it
;
asoc
=
__sctp_rcv_lookup
(
skb
,
&
src
,
&
dest
,
&
transport
);
...
...
net/sctp/ipv6.c
View file @
845ddb44
...
...
@@ -2,6 +2,7 @@
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
* Copyright (c) 2002-2003 International Business Machines, Corp.
* Copyright (c) 2002-2003 Intel Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
...
...
@@ -15,7 +16,7 @@
*
* 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.
*
...
...
@@ -32,14 +33,15 @@
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Le Yanqun
<yanqun.le@nokia.com>
* Le Yanqun
<yanqun.le@nokia.com>
* Hui Huang <hui.huang@nokia.com>
* La Monte H.P. Yarroll <piggy@acm.org>
* Sridhar Samudrala <sri@us.ibm.com>
* Jon Grimm <jgrimm@us.ibm.com>
* Jon Grimm <jgrimm@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
*
* Based on:
*
linux/net/ipv6/tcp_ipv6.c
*
linux/net/ipv6/tcp_ipv6.c
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
...
...
@@ -172,7 +174,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
SCTP_DEBUG_PRINTK
(
"%s: skb:%p, len:%d, "
"src:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
"dst:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x
\n
"
,
__FUNCTION__
,
skb
,
skb
->
len
,
__FUNCTION__
,
skb
,
skb
->
len
,
NIP6
(
fl
.
fl6_src
),
NIP6
(
fl
.
fl6_dst
));
SCTP_INC_STATS
(
SctpOutSCTPPacks
);
...
...
@@ -370,13 +372,28 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
/* Initialize sk->sk_rcv_saddr from sctp_addr. */
static
void
sctp_v6_to_sk_saddr
(
union
sctp_addr
*
addr
,
struct
sock
*
sk
)
{
inet6_sk
(
sk
)
->
rcv_saddr
=
addr
->
v6
.
sin6_addr
;
if
(
addr
->
sa
.
sa_family
==
AF_INET
&&
sctp_sk
(
sk
)
->
v4mapped
)
{
inet6_sk
(
sk
)
->
rcv_saddr
.
s6_addr32
[
0
]
=
0
;
inet6_sk
(
sk
)
->
rcv_saddr
.
s6_addr32
[
1
]
=
0
;
inet6_sk
(
sk
)
->
rcv_saddr
.
s6_addr32
[
2
]
=
htonl
(
0x0000ffff
);
inet6_sk
(
sk
)
->
rcv_saddr
.
s6_addr32
[
3
]
=
addr
->
v4
.
sin_addr
.
s_addr
;
}
else
{
inet6_sk
(
sk
)
->
rcv_saddr
=
addr
->
v6
.
sin6_addr
;
}
}
/* Initialize sk->sk_daddr from sctp_addr. */
static
void
sctp_v6_to_sk_daddr
(
union
sctp_addr
*
addr
,
struct
sock
*
sk
)
{
inet6_sk
(
sk
)
->
daddr
=
addr
->
v6
.
sin6_addr
;
if
(
addr
->
sa
.
sa_family
==
AF_INET
&&
sctp_sk
(
sk
)
->
v4mapped
)
{
inet6_sk
(
sk
)
->
daddr
.
s6_addr32
[
0
]
=
0
;
inet6_sk
(
sk
)
->
daddr
.
s6_addr32
[
1
]
=
0
;
inet6_sk
(
sk
)
->
daddr
.
s6_addr32
[
2
]
=
htonl
(
0x0000ffff
);
inet6_sk
(
sk
)
->
daddr
.
s6_addr32
[
3
]
=
addr
->
v4
.
sin_addr
.
s_addr
;
}
else
{
inet6_sk
(
sk
)
->
daddr
=
addr
->
v6
.
sin6_addr
;
}
}
/* Initialize a sctp_addr from a dst_entry. */
...
...
@@ -390,13 +407,30 @@ static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst,
}
/* Compare addresses exactly.
*
FIXME: v4-mapped-v6
.
*
v4-mapped-v6 is also in consideration
.
*/
static
int
sctp_v6_cmp_addr
(
const
union
sctp_addr
*
addr1
,
const
union
sctp_addr
*
addr2
)
{
if
(
addr1
->
sa
.
sa_family
!=
addr2
->
sa
.
sa_family
)
if
(
addr1
->
sa
.
sa_family
!=
addr2
->
sa
.
sa_family
)
{
if
(
addr1
->
sa
.
sa_family
==
AF_INET
&&
addr2
->
sa
.
sa_family
==
AF_INET6
&&
IPV6_ADDR_MAPPED
==
ipv6_addr_type
(
&
addr2
->
v6
.
sin6_addr
))
{
if
(
addr2
->
v6
.
sin6_port
==
addr1
->
v4
.
sin_port
&&
addr2
->
v6
.
sin6_addr
.
s6_addr32
[
3
]
==
addr1
->
v4
.
sin_addr
.
s_addr
)
return
1
;
}
if
(
addr2
->
sa
.
sa_family
==
AF_INET
&&
addr1
->
sa
.
sa_family
==
AF_INET6
&&
IPV6_ADDR_MAPPED
==
ipv6_addr_type
(
&
addr1
->
v6
.
sin6_addr
))
{
if
(
addr1
->
v6
.
sin6_port
==
addr2
->
v4
.
sin_port
&&
addr1
->
v6
.
sin6_addr
.
s6_addr32
[
3
]
==
addr2
->
v4
.
sin_addr
.
s_addr
)
return
1
;
}
return
0
;
}
if
(
ipv6_addr_cmp
(
&
addr1
->
v6
.
sin6_addr
,
&
addr2
->
v6
.
sin6_addr
))
return
0
;
/* If this is a linklocal address, compare the scope_id. */
...
...
@@ -427,7 +461,7 @@ static int sctp_v6_is_any(const union sctp_addr *addr)
}
/* Should this be available for binding? */
static
int
sctp_v6_available
(
const
union
sctp_addr
*
addr
)
static
int
sctp_v6_available
(
union
sctp_addr
*
addr
,
struct
sctp_opt
*
sp
)
{
int
type
;
struct
in6_addr
*
in6
=
(
struct
in6_addr
*
)
&
addr
->
v6
.
sin6_addr
;
...
...
@@ -435,6 +469,12 @@ static int sctp_v6_available(const union sctp_addr *addr)
type
=
ipv6_addr_type
(
in6
);
if
(
IPV6_ADDR_ANY
==
type
)
return
1
;
if
(
type
==
IPV6_ADDR_MAPPED
)
{
if
(
sp
&&
!
sp
->
v4mapped
)
return
0
;
sctp_v6_map_v4
(
addr
);
return
sctp_get_af_specific
(
AF_INET
)
->
available
(
addr
,
sp
);
}
if
(
!
(
type
&
IPV6_ADDR_UNICAST
))
return
0
;
...
...
@@ -448,11 +488,20 @@ static int sctp_v6_available(const union sctp_addr *addr)
* Return 0 - If the address is a non-unicast or an illegal address.
* Return 1 - If the address is a unicast.
*/
static
int
sctp_v6_addr_valid
(
union
sctp_addr
*
addr
)
static
int
sctp_v6_addr_valid
(
union
sctp_addr
*
addr
,
struct
sctp_opt
*
sp
)
{
int
ret
=
ipv6_addr_type
(
&
addr
->
v6
.
sin6_addr
);
/* FIXME: v4-mapped-v6 address support. */
/* Support v4-mapped-v6 address. */
if
(
ret
==
IPV6_ADDR_MAPPED
)
{
/* Note: This routine is used in input, so v4-mapped-v6
* are disallowed here when there is no sctp_opt.
*/
if
(
!
sp
||
!
sp
->
v4mapped
)
return
0
;
sctp_v6_map_v4
(
addr
);
return
sctp_get_af_specific
(
AF_INET
)
->
addr_valid
(
addr
,
sp
);
}
/* Is this a non-unicast address */
if
(
!
(
ret
&
IPV6_ADDR_UNICAST
))
...
...
@@ -536,7 +585,7 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk,
newnp
->
saddr
=
np
->
saddr
;
newnp
->
rcv_saddr
=
np
->
rcv_saddr
;
newinet
->
dport
=
htons
(
asoc
->
peer
.
port
);
newnp
->
daddr
=
asoc
->
peer
.
primary_addr
.
v6
.
sin6_addr
;
sctp_v6_to_sk_daddr
(
&
asoc
->
peer
.
primary_addr
,
newsk
)
;
/* Init the ipv4 part of the socket since we can have sockets
* using v6 API for ipv4.
...
...
@@ -566,6 +615,13 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk,
return
newsk
;
}
/* Map v4 address to mapped v6 address */
static
void
sctp_v6_addr_v4map
(
struct
sctp_opt
*
sp
,
union
sctp_addr
*
addr
)
{
if
(
sp
->
v4mapped
&&
AF_INET
==
addr
->
sa
.
sa_family
)
sctp_v4_map_v6
(
addr
);
}
/* Where did this skb come from? */
static
int
sctp_v6_skb_iif
(
const
struct
sk_buff
*
skb
)
{
...
...
@@ -617,10 +673,11 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
*/
/* Map ipv4 address into v4-mapped-on-v6 address. */
if
(
AF_INET
==
addr
->
sa
.
sa_family
)
{
/* FIXME: Easy, but there was no way to test this
* yet.
*/
if
(
sctp_sk
(
event
->
asoc
->
base
.
sk
)
->
v4mapped
&&
AF_INET
==
addr
->
sa
.
sa_family
)
{
sctp_v4_map_v6
((
union
sctp_addr
*
)
sin6
);
sin6
->
sin6_addr
.
s6_addr32
[
3
]
=
addr
->
v4
.
sin_addr
.
s_addr
;
return
;
}
...
...
@@ -644,16 +701,15 @@ static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname,
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin6
->
sin6_port
=
sh
->
source
;
/*
FIXME:
Map ipv4 address into v4-mapped-on-v6 address. */
if
(
__constant_htons
(
ETH_P_IP
)
==
skb
->
protocol
)
{
/* FIXME: The latest I-D added options for two
* behaviors.
*/
/* Map ipv4 address into v4-mapped-on-v6 address. */
if
(
sctp_sk
(
skb
->
sk
)
->
v4mapped
&&
skb
->
nh
.
iph
->
version
==
4
)
{
sctp_v4_map_v6
((
union
sctp_addr
*
)
sin6
);
sin6
->
sin6_addr
.
s6_addr32
[
3
]
=
skb
->
nh
.
iph
->
saddr
;
return
;
}
/* Otherwise, just copy the v6 address. */
ipv6_addr_copy
(
&
sin6
->
sin6_addr
,
&
skb
->
nh
.
ipv6h
->
saddr
);
if
(
ipv6_addr_type
(
&
sin6
->
sin6_addr
)
&
IPV6_ADDR_LINKLOCAL
)
{
struct
sctp_ulpevent
*
ev
=
sctp_skb2event
(
skb
);
...
...
@@ -663,16 +719,15 @@ static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname,
}
/* Do we support this AF? */
static
int
sctp_inet6_af_supported
(
sa_family_t
family
)
static
int
sctp_inet6_af_supported
(
sa_family_t
family
,
struct
sctp_opt
*
sp
)
{
/* FIXME: v4-mapped-v6 addresses. The I-D is still waffling
* on what to do with sockaddr formats for PF_INET6 sockets.
* For now assume we'll support both.
*/
switch
(
family
)
{
case
AF_INET6
:
case
AF_INET
:
return
1
;
/* v4-mapped-v6 addresses */
case
AF_INET
:
if
(
sp
->
v4mapped
)
return
1
;
default:
return
0
;
}
...
...
@@ -730,7 +785,7 @@ static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
}
af
=
opt
->
pf
->
af
;
}
return
af
->
available
(
addr
);
return
af
->
available
(
addr
,
opt
);
}
/* Verify that the provided sockaddr looks bindable. Common verification,
...
...
@@ -863,6 +918,7 @@ static struct sctp_pf sctp_pf_inet6_specific = {
.
send_verify
=
sctp_inet6_send_verify
,
.
supported_addrs
=
sctp_inet6_supported_addrs
,
.
create_accept_sk
=
sctp_v6_create_accept_sk
,
.
addr_v4map
=
sctp_v6_addr_v4map
,
.
af
=
&
sctp_ipv6_specific
,
};
...
...
net/sctp/protocol.c
View file @
845ddb44
...
...
@@ -340,7 +340,7 @@ static int sctp_v4_is_any(const union sctp_addr *addr)
* Return 0 - If the address is a non-unicast or an illegal address.
* Return 1 - If the address is a unicast.
*/
static
int
sctp_v4_addr_valid
(
union
sctp_addr
*
addr
)
static
int
sctp_v4_addr_valid
(
union
sctp_addr
*
addr
,
struct
sctp_opt
*
sp
)
{
/* Is this a non-unicast address or a unusable SCTP address? */
if
(
IS_IPV4_UNUSABLE_ADDRESS
(
&
addr
->
v4
.
sin_addr
.
s_addr
))
...
...
@@ -350,7 +350,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr)
}
/* Should this be available for binding? */
static
int
sctp_v4_available
(
const
union
sctp_addr
*
addr
)
static
int
sctp_v4_available
(
union
sctp_addr
*
addr
,
struct
sctp_opt
*
sp
)
{
int
ret
=
inet_addr_type
(
addr
->
v4
.
sin_addr
.
s_addr
);
...
...
@@ -580,6 +580,12 @@ struct sock *sctp_v4_create_accept_sk(struct sock *sk,
return
newsk
;
}
/* Map address, empty for v4 family */
static
void
sctp_v4_addr_v4map
(
struct
sctp_opt
*
sp
,
union
sctp_addr
*
addr
)
{
/* Empty */
}
/* Dump the v4 addr to the seq file. */
static
void
sctp_v4_seq_dump_addr
(
struct
seq_file
*
seq
,
union
sctp_addr
*
addr
)
{
...
...
@@ -709,7 +715,7 @@ static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *len)
}
/* Do we support this AF? */
static
int
sctp_inet_af_supported
(
sa_family_t
family
)
static
int
sctp_inet_af_supported
(
sa_family_t
family
,
struct
sctp_opt
*
sp
)
{
/* PF_INET only supports AF_INET addresses. */
return
(
AF_INET
==
family
);
...
...
@@ -737,7 +743,7 @@ static int sctp_inet_cmp_addr(const union sctp_addr *addr1,
*/
static
int
sctp_inet_bind_verify
(
struct
sctp_opt
*
opt
,
union
sctp_addr
*
addr
)
{
return
sctp_v4_available
(
addr
);
return
sctp_v4_available
(
addr
,
opt
);
}
/* Verify that sockaddr looks sendable. Common verification has already
...
...
@@ -783,6 +789,7 @@ static struct sctp_pf sctp_pf_inet = {
.
send_verify
=
sctp_inet_send_verify
,
.
supported_addrs
=
sctp_inet_supported_addrs
,
.
create_accept_sk
=
sctp_v4_create_accept_sk
,
.
addr_v4map
=
sctp_v4_addr_v4map
,
.
af
=
&
sctp_ipv4_specific
,
};
...
...
net/sctp/socket.c
View file @
845ddb44
...
...
@@ -156,6 +156,9 @@ struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
if
(
id_asoc
&&
(
id_asoc
!=
addr_asoc
))
return
NULL
;
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sctp_sk
(
sk
),
(
union
sctp_addr
*
)
addr
);
return
transport
;
}
...
...
@@ -206,7 +209,7 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_opt *opt,
return
NULL
;
/* Does this PF support this AF? */
if
(
!
opt
->
pf
->
af_supported
(
addr
->
sa
.
sa_family
))
if
(
!
opt
->
pf
->
af_supported
(
addr
->
sa
.
sa_family
,
opt
))
return
NULL
;
/* If we get this far, af is valid. */
...
...
@@ -1362,7 +1365,7 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk,
/* Free the event which includes releasing the reference to
* the owner of the skb, freeing the skb and updating the
* rwnd.
*/
*/
sctp_ulpevent_free
(
event
);
}
out:
...
...
@@ -1747,14 +1750,18 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char *optval, int optlen)
static
int
sctp_setsockopt_mappedv4
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
int
val
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
if
(
optlen
<
sizeof
(
int
))
return
-
EINVAL
;
if
(
get_user
(
val
,
(
int
*
)
optval
))
return
-
EFAULT
;
/* FIXME: Put real support here. */
if
(
val
)
sp
->
v4mapped
=
1
;
else
sp
->
v4mapped
=
0
;
return
-
ENOPROTOOPT
;
return
0
;
}
/*
...
...
@@ -2305,6 +2312,9 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, char *optval,
status
.
sstat_primary
.
spinfo_assoc_id
=
sctp_assoc2id
(
transport
->
asoc
);
memcpy
(
&
status
.
sstat_primary
.
spinfo_address
,
&
(
transport
->
ipaddr
),
sizeof
(
union
sctp_addr
));
/* Map ipv4 address into v4-mapped-on-v6 address. */
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sctp_sk
(
sk
),
(
union
sctp_addr
*
)
&
status
.
sstat_primary
.
spinfo_address
);
status
.
sstat_primary
.
spinfo_state
=
transport
->
active
;
status
.
sstat_primary
.
spinfo_cwnd
=
transport
->
cwnd
;
status
.
sstat_primary
.
spinfo_srtt
=
transport
->
srtt
;
...
...
@@ -2642,6 +2652,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
struct
sctp_getaddrs
getaddrs
;
struct
sctp_transport
*
from
;
struct
sockaddr_storage
*
to
;
union
sctp_addr
temp
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
if
(
len
!=
sizeof
(
struct
sctp_getaddrs
))
return
-
EINVAL
;
...
...
@@ -2660,7 +2672,9 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
to
=
getaddrs
.
addrs
;
list_for_each
(
pos
,
&
asoc
->
peer
.
transport_addr_list
)
{
from
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
if
(
copy_to_user
(
to
,
&
from
->
ipaddr
,
sizeof
(
from
->
ipaddr
)))
memcpy
(
&
temp
,
&
from
->
ipaddr
,
sizeof
(
temp
));
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
&
temp
);
if
(
copy_to_user
(
to
,
&
temp
,
sizeof
(
temp
)))
return
-
EFAULT
;
to
++
;
cnt
++
;
...
...
@@ -2722,6 +2736,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
struct
sctp_getaddrs
getaddrs
;
struct
sctp_sockaddr_entry
*
from
;
struct
sockaddr_storage
*
to
;
union
sctp_addr
temp
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
if
(
len
!=
sizeof
(
struct
sctp_getaddrs
))
return
-
EINVAL
;
...
...
@@ -2750,7 +2766,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
from
=
list_entry
(
pos
,
struct
sctp_sockaddr_entry
,
list
);
if
(
copy_to_user
(
to
,
&
from
->
a
,
sizeof
(
from
->
a
)))
memcpy
(
&
temp
,
&
from
->
a
,
sizeof
(
temp
));
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
&
temp
);
if
(
copy_to_user
(
to
,
&
temp
,
sizeof
(
temp
)))
return
-
EFAULT
;
to
++
;
cnt
++
;
...
...
@@ -2774,6 +2792,7 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
{
struct
sctp_prim
prim
;
struct
sctp_association
*
asoc
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
if
(
len
!=
sizeof
(
struct
sctp_prim
))
return
-
EINVAL
;
...
...
@@ -2791,6 +2810,9 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
memcpy
(
&
prim
.
ssp_addr
,
&
asoc
->
peer
.
primary_path
->
ipaddr
,
sizeof
(
union
sctp_addr
));
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
(
union
sctp_addr
*
)
&
prim
.
ssp_addr
);
if
(
copy_to_user
(
optval
,
&
prim
,
sizeof
(
struct
sctp_prim
)))
return
-
EFAULT
;
...
...
@@ -2805,6 +2827,8 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
* specify a default set of parameters that would normally be supplied
* through the inclusion of ancillary data. This socket option allows
* such an application to set the default sctp_sndrcvinfo structure.
* The application that wishes to use this socket option simply passes
* in to this call the sctp_sndrcvinfo structure defined in Section
* 5.2.2) The input parameters accepted by this call include
...
...
@@ -3012,12 +3036,13 @@ static int sctp_getsockopt_mappedv4(struct sock *sk, int len,
char
*
optval
,
int
*
optlen
)
{
int
val
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
if
(
len
<
sizeof
(
int
))
return
-
EINVAL
;
len
=
sizeof
(
int
);
/* FIXME: Until we have support, return disabled. */
val
=
0
;
val
=
sp
->
v4mapped
;
if
(
put_user
(
len
,
optlen
))
return
-
EFAULT
;
if
(
copy_to_user
(
optval
,
&
val
,
len
))
...
...
@@ -3863,7 +3888,7 @@ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
return
-
EINVAL
;
/* Is this a valid SCTP address? */
if
(
!
af
->
addr_valid
(
addr
))
if
(
!
af
->
addr_valid
(
addr
,
sctp_sk
(
sk
)
))
return
-
EINVAL
;
if
(
!
sctp_sk
(
sk
)
->
pf
->
send_verify
(
sctp_sk
(
sk
),
(
addr
)))
...
...
net/sctp/ulpevent.c
View file @
845ddb44
...
...
@@ -35,6 +35,7 @@
* Written or modified by:
* Jon Grimm <jgrimm@us.ibm.com>
* La Monte H.P. Yarroll <piggy@acm.org>
* Ardelle Fan <ardelle.fan@intel.com>
* Sridhar Samudrala <sri@us.ibm.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
...
...
@@ -286,6 +287,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
*/
memcpy
(
&
spc
->
spc_aaddr
,
aaddr
,
sizeof
(
struct
sockaddr_storage
));
/* Map ipv4 address into v4-mapped-on-v6 address. */
sctp_get_pf_specific
(
asoc
->
base
.
sk
->
sk_family
)
->
addr_v4map
(
sctp_sk
(
asoc
->
base
.
sk
),
(
union
sctp_addr
*
)
&
spc
->
spc_aaddr
);
return
event
;
fail:
...
...
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