Skip to content

Commit 06a8c04

Browse files
q2vendavem330
authored andcommitted
tcp: Save v4 address as v4-mapped-v6 in inet_bind2_bucket.v6_rcv_saddr.
In bhash2, IPv4/IPv6 addresses are saved in two union members, which complicate address checks in inet_bind2_bucket_addr_match() and inet_bind2_bucket_match_addr_any() considering uninitialised memory and v4-mapped-v6 conflicts. Let's simplify that by saving IPv4 address as v4-mapped-v6 address and defining tb2.rcv_saddr as tb2.v6_rcv_saddr.s6_addr32[3]. Then, we can compare v6 address as is, and after checking v4-mapped-v6, we can compare v4 address easily. Also, we can remove tb2->family. Note these functions will be further refactored in the next patch. Signed-off-by: Kuniyuki Iwashima <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 56f3e3f commit 06a8c04

File tree

3 files changed

+21
-29
lines changed

3 files changed

+21
-29
lines changed

include/net/inet_hashtables.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,11 @@ struct inet_bind2_bucket {
9696
int l3mdev;
9797
unsigned short port;
9898
#if IS_ENABLED(CONFIG_IPV6)
99-
unsigned short family;
100-
#endif
101-
union {
102-
#if IS_ENABLED(CONFIG_IPV6)
103-
struct in6_addr v6_rcv_saddr;
99+
struct in6_addr v6_rcv_saddr;
100+
#define rcv_saddr v6_rcv_saddr.s6_addr32[3]
101+
#else
102+
__be32 rcv_saddr;
104103
#endif
105-
__be32 rcv_saddr;
106-
};
107104
/* Node in the bhash2 inet_bind_hashbucket chain */
108105
struct hlist_node node;
109106
/* List of sockets hashed to this bucket */

include/net/ipv6.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -784,11 +784,6 @@ static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
784784
cpu_to_be32(0x0000ffff))) == 0UL;
785785
}
786786

787-
static inline bool ipv6_addr_v4mapped_any(const struct in6_addr *a)
788-
{
789-
return ipv6_addr_v4mapped(a) && ipv4_is_zeronet(a->s6_addr32[3]);
790-
}
791-
792787
static inline bool ipv6_addr_v4mapped_loopback(const struct in6_addr *a)
793788
{
794789
return ipv6_addr_v4mapped(a) && ipv4_is_loopback(a->s6_addr32[3]);

net/ipv4/inet_hashtables.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,13 @@ static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb,
110110
tb->l3mdev = l3mdev;
111111
tb->port = port;
112112
#if IS_ENABLED(CONFIG_IPV6)
113-
tb->family = sk->sk_family;
114113
if (sk->sk_family == AF_INET6)
115114
tb->v6_rcv_saddr = sk->sk_v6_rcv_saddr;
116115
else
116+
ipv6_addr_set_v4mapped(sk->sk_rcv_saddr, &tb->v6_rcv_saddr);
117+
#else
118+
tb->rcv_saddr = sk->sk_rcv_saddr;
117119
#endif
118-
tb->rcv_saddr = sk->sk_rcv_saddr;
119120
INIT_HLIST_HEAD(&tb->owners);
120121
INIT_HLIST_HEAD(&tb->deathrow);
121122
hlist_add_head(&tb->node, &head->chain);
@@ -149,17 +150,11 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2,
149150
const struct sock *sk)
150151
{
151152
#if IS_ENABLED(CONFIG_IPV6)
152-
if (sk->sk_family == AF_INET6) {
153-
if (tb2->family == AF_INET6)
154-
return ipv6_addr_equal(&tb2->v6_rcv_saddr, &sk->sk_v6_rcv_saddr);
155-
156-
return ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr) &&
157-
sk->sk_v6_rcv_saddr.s6_addr32[3] == tb2->rcv_saddr;
158-
}
153+
if (sk->sk_family == AF_INET6)
154+
return ipv6_addr_equal(&tb2->v6_rcv_saddr, &sk->sk_v6_rcv_saddr);
159155

160-
if (tb2->family == AF_INET6)
161-
return ipv6_addr_v4mapped(&tb2->v6_rcv_saddr) &&
162-
tb2->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr;
156+
if (!ipv6_addr_v4mapped(&tb2->v6_rcv_saddr))
157+
return false;
163158
#endif
164159
return tb2->rcv_saddr == sk->sk_rcv_saddr;
165160
}
@@ -836,16 +831,21 @@ bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const
836831

837832
#if IS_ENABLED(CONFIG_IPV6)
838833
if (sk->sk_family == AF_INET6) {
839-
if (tb->family == AF_INET6)
840-
return ipv6_addr_any(&tb->v6_rcv_saddr);
834+
if (ipv6_addr_any(&tb->v6_rcv_saddr))
835+
return true;
836+
837+
if (!ipv6_addr_v4mapped(&tb->v6_rcv_saddr))
838+
return false;
841839

842840
return ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr) &&
843841
tb->rcv_saddr == 0;
844842
}
845843

846-
if (tb->family == AF_INET6)
847-
return ipv6_addr_any(&tb->v6_rcv_saddr) ||
848-
ipv6_addr_v4mapped_any(&tb->v6_rcv_saddr);
844+
if (ipv6_addr_any(&tb->v6_rcv_saddr))
845+
return true;
846+
847+
if (!ipv6_addr_v4mapped(&tb->v6_rcv_saddr))
848+
return false;
849849
#endif
850850
return tb->rcv_saddr == 0;
851851
}

0 commit comments

Comments
 (0)