Commit 9bb68814 authored by Sridhar Samudrala's avatar Sridhar Samudrala Committed by Jon Grimm

[SCTP] Support for IPV6_V6ONLY socket option. (Ardelle.fan)

parent 8d10a2eb
...@@ -588,6 +588,7 @@ struct sctp6_sock { ...@@ -588,6 +588,7 @@ struct sctp6_sock {
#endif /* CONFIG_IPV6 */ #endif /* CONFIG_IPV6 */
#define sctp_sk(__sk) (&((struct sctp_sock *)__sk)->sctp) #define sctp_sk(__sk) (&((struct sctp_sock *)__sk)->sctp)
#define sctp_opt2sk(__sp) &container_of(__sp, struct sctp_sock, sctp)->sk
/* Is a socket of this style? */ /* Is a socket of this style? */
#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
......
...@@ -475,6 +475,8 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_opt *sp) ...@@ -475,6 +475,8 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_opt *sp)
if (type == IPV6_ADDR_MAPPED) { if (type == IPV6_ADDR_MAPPED) {
if (sp && !sp->v4mapped) if (sp && !sp->v4mapped)
return 0; return 0;
if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
return 0;
sctp_v6_map_v4(addr); sctp_v6_map_v4(addr);
return sctp_get_af_specific(AF_INET)->available(addr, sp); return sctp_get_af_specific(AF_INET)->available(addr, sp);
} }
...@@ -502,6 +504,8 @@ static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_opt *sp) ...@@ -502,6 +504,8 @@ static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_opt *sp)
*/ */
if (!sp || !sp->v4mapped) if (!sp || !sp->v4mapped)
return 0; return 0;
if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
return 0;
sctp_v6_map_v4(addr); sctp_v6_map_v4(addr);
return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp); return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp);
} }
...@@ -731,7 +735,7 @@ static int sctp_inet6_af_supported(sa_family_t family, struct sctp_opt *sp) ...@@ -731,7 +735,7 @@ static int sctp_inet6_af_supported(sa_family_t family, struct sctp_opt *sp)
return 1; return 1;
/* v4-mapped-v6 addresses */ /* v4-mapped-v6 addresses */
case AF_INET: case AF_INET:
if (sp->v4mapped) if (!__ipv6_only_sock(sctp_opt2sk(sp)) && sp->v4mapped)
return 1; return 1;
default: default:
return 0; return 0;
...@@ -776,7 +780,7 @@ static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr) ...@@ -776,7 +780,7 @@ static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
else { else {
struct sock *sk; struct sock *sk;
int type = ipv6_addr_type(&addr->v6.sin6_addr); int type = ipv6_addr_type(&addr->v6.sin6_addr);
sk = &container_of(opt, struct sctp6_sock, sctp)->sk; sk = sctp_opt2sk(opt);
if (type & IPV6_ADDR_LINKLOCAL) { if (type & IPV6_ADDR_LINKLOCAL) {
/* Note: Behavior similar to af_inet6.c: /* Note: Behavior similar to af_inet6.c:
* 1) Overrides previous bound_dev_if * 1) Overrides previous bound_dev_if
...@@ -806,7 +810,7 @@ static int sctp_inet6_send_verify(struct sctp_opt *opt, union sctp_addr *addr) ...@@ -806,7 +810,7 @@ static int sctp_inet6_send_verify(struct sctp_opt *opt, union sctp_addr *addr)
else { else {
struct sock *sk; struct sock *sk;
int type = ipv6_addr_type(&addr->v6.sin6_addr); int type = ipv6_addr_type(&addr->v6.sin6_addr);
sk = &container_of(opt, struct sctp6_sock, sctp)->sk; sk = sctp_opt2sk(opt);
if (type & IPV6_ADDR_LINKLOCAL) { if (type & IPV6_ADDR_LINKLOCAL) {
/* Note: Behavior similar to af_inet6.c: /* Note: Behavior similar to af_inet6.c:
* 1) Overrides previous bound_dev_if * 1) Overrides previous bound_dev_if
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment