sctp: Don't advertise IPv4 addresses if ipv6only is set on the socket
If a socket is set ipv6only, it will still send IPv4 addresses in the
INIT and INIT_ACK packets. This potentially misleads the peer into using
them, which then would cause association termination.
The fix is to not add IPv4 addresses to ipv6only sockets.
Fixes: 1da177e4c3
("Linux-2.6.12-rc2")
Reported-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Tested-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
b6186d413b
Коммит
471e39df96
|
@ -353,11 +353,13 @@ enum {
|
||||||
ipv4_is_anycast_6to4(a))
|
ipv4_is_anycast_6to4(a))
|
||||||
|
|
||||||
/* Flags used for the bind address copy functions. */
|
/* Flags used for the bind address copy functions. */
|
||||||
#define SCTP_ADDR6_ALLOWED 0x00000001 /* IPv6 address is allowed by
|
#define SCTP_ADDR4_ALLOWED 0x00000001 /* IPv4 address is allowed by
|
||||||
local sock family */
|
local sock family */
|
||||||
#define SCTP_ADDR4_PEERSUPP 0x00000002 /* IPv4 address is supported by
|
#define SCTP_ADDR6_ALLOWED 0x00000002 /* IPv6 address is allowed by
|
||||||
|
local sock family */
|
||||||
|
#define SCTP_ADDR4_PEERSUPP 0x00000004 /* IPv4 address is supported by
|
||||||
peer */
|
peer */
|
||||||
#define SCTP_ADDR6_PEERSUPP 0x00000004 /* IPv6 address is supported by
|
#define SCTP_ADDR6_PEERSUPP 0x00000008 /* IPv6 address is supported by
|
||||||
peer */
|
peer */
|
||||||
|
|
||||||
/* Reasons to retransmit. */
|
/* Reasons to retransmit. */
|
||||||
|
|
|
@ -1565,12 +1565,15 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned int len)
|
||||||
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
|
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
|
||||||
enum sctp_scope scope, gfp_t gfp)
|
enum sctp_scope scope, gfp_t gfp)
|
||||||
{
|
{
|
||||||
|
struct sock *sk = asoc->base.sk;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
/* Use scoping rules to determine the subset of addresses from
|
/* Use scoping rules to determine the subset of addresses from
|
||||||
* the endpoint.
|
* the endpoint.
|
||||||
*/
|
*/
|
||||||
flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0;
|
flags = (PF_INET6 == sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0;
|
||||||
|
if (!inet_v6_ipv6only(sk))
|
||||||
|
flags |= SCTP_ADDR4_ALLOWED;
|
||||||
if (asoc->peer.ipv4_address)
|
if (asoc->peer.ipv4_address)
|
||||||
flags |= SCTP_ADDR4_PEERSUPP;
|
flags |= SCTP_ADDR4_PEERSUPP;
|
||||||
if (asoc->peer.ipv6_address)
|
if (asoc->peer.ipv6_address)
|
||||||
|
|
|
@ -461,6 +461,7 @@ static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest,
|
||||||
* well as the remote peer.
|
* well as the remote peer.
|
||||||
*/
|
*/
|
||||||
if ((((AF_INET == addr->sa.sa_family) &&
|
if ((((AF_INET == addr->sa.sa_family) &&
|
||||||
|
(flags & SCTP_ADDR4_ALLOWED) &&
|
||||||
(flags & SCTP_ADDR4_PEERSUPP))) ||
|
(flags & SCTP_ADDR4_PEERSUPP))) ||
|
||||||
(((AF_INET6 == addr->sa.sa_family) &&
|
(((AF_INET6 == addr->sa.sa_family) &&
|
||||||
(flags & SCTP_ADDR6_ALLOWED) &&
|
(flags & SCTP_ADDR6_ALLOWED) &&
|
||||||
|
|
|
@ -148,7 +148,8 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp,
|
||||||
* sock as well as the remote peer.
|
* sock as well as the remote peer.
|
||||||
*/
|
*/
|
||||||
if (addr->a.sa.sa_family == AF_INET &&
|
if (addr->a.sa.sa_family == AF_INET &&
|
||||||
!(copy_flags & SCTP_ADDR4_PEERSUPP))
|
(!(copy_flags & SCTP_ADDR4_ALLOWED) ||
|
||||||
|
!(copy_flags & SCTP_ADDR4_PEERSUPP)))
|
||||||
continue;
|
continue;
|
||||||
if (addr->a.sa.sa_family == AF_INET6 &&
|
if (addr->a.sa.sa_family == AF_INET6 &&
|
||||||
(!(copy_flags & SCTP_ADDR6_ALLOWED) ||
|
(!(copy_flags & SCTP_ADDR6_ALLOWED) ||
|
||||||
|
|
Загрузка…
Ссылка в новой задаче