@@ -308,9 +308,16 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
308308 if (len < sizeof (struct sockaddr ))
309309 return NULL ;
310310
311- /* Does this PF support this AF? */
312- if (!opt -> pf -> af_supported (addr -> sa .sa_family , opt ))
313- return NULL ;
311+ /* V4 mapped address are really of AF_INET family */
312+ if (addr -> sa .sa_family == AF_INET6 &&
313+ ipv6_addr_v4mapped (& addr -> v6 .sin6_addr )) {
314+ if (!opt -> pf -> af_supported (AF_INET , opt ))
315+ return NULL ;
316+ } else {
317+ /* Does this PF support this AF? */
318+ if (!opt -> pf -> af_supported (addr -> sa .sa_family , opt ))
319+ return NULL ;
320+ }
314321
315322 /* If we get this far, af is valid. */
316323 af = sctp_get_af_specific (addr -> sa .sa_family );
@@ -4395,6 +4402,11 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
43954402 (AF_INET6 == addr -> a .sa .sa_family ))
43964403 continue ;
43974404
4405+ if ((PF_INET6 == sk -> sk_family ) &&
4406+ inet_v6_ipv6only (sk ) &&
4407+ (AF_INET == addr -> a .sa .sa_family ))
4408+ continue ;
4409+
43984410 cnt ++ ;
43994411 }
44004412 rcu_read_unlock ();
@@ -4435,6 +4447,10 @@ static int sctp_copy_laddrs_old(struct sock *sk, __u16 port,
44354447 if ((PF_INET == sk -> sk_family ) &&
44364448 (AF_INET6 == addr -> a .sa .sa_family ))
44374449 continue ;
4450+ if ((PF_INET6 == sk -> sk_family ) &&
4451+ inet_v6_ipv6only (sk ) &&
4452+ (AF_INET == addr -> a .sa .sa_family ))
4453+ continue ;
44384454 memcpy (& temp , & addr -> a , sizeof (temp ));
44394455 if (!temp .v4 .sin_port )
44404456 temp .v4 .sin_port = htons (port );
@@ -4470,6 +4486,10 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
44704486 if ((PF_INET == sk -> sk_family ) &&
44714487 (AF_INET6 == addr -> a .sa .sa_family ))
44724488 continue ;
4489+ if ((PF_INET6 == sk -> sk_family ) &&
4490+ inet_v6_ipv6only (sk ) &&
4491+ (AF_INET == addr -> a .sa .sa_family ))
4492+ continue ;
44734493 memcpy (& temp , & addr -> a , sizeof (temp ));
44744494 if (!temp .v4 .sin_port )
44754495 temp .v4 .sin_port = htons (port );
@@ -5568,8 +5588,8 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
55685588 sk2 -> sk_state != SCTP_SS_LISTENING )
55695589 continue ;
55705590
5571- if (sctp_bind_addr_match (& ep2 -> base .bind_addr , addr ,
5572- sctp_sk (sk ))) {
5591+ if (sctp_bind_addr_conflict (& ep2 -> base .bind_addr , addr ,
5592+ sctp_sk (sk2 ), sctp_sk ( sk ))) {
55735593 ret = (long )sk2 ;
55745594 goto fail_unlock ;
55755595 }
0 commit comments