tcp_splice_conn_from_sock() needs to check if an inany is either the IPv6
loopback address (::) or an IPv4 loopback address (127.0.0.0/8). We may
have other places that also want to check this in future, so simplify it
with an inany_is_loopback() helper.
Signed-off-by: David Gibson
---
inany.h | 13 +++++++++++++
tcp_splice.c | 14 +++-----------
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/inany.h b/inany.h
index fe652ff7..d758f7ba 100644
--- a/inany.h
+++ b/inany.h
@@ -55,6 +55,19 @@ static inline bool inany_equals(const union inany_addr *a,
return IN6_ARE_ADDR_EQUAL(&a->a6, &b->a6);
}
+/** inany_is_loopback - Check if address is loopback
+ * @a: IPv[46] address
+ *
+ * Return: true if @a is either ::1 or in 127.0.0.1/8
+ */
+static inline bool inany_is_loopback(const union inany_addr *a)
+{
+ const struct in_addr *v4;
+
+ return IN6_IS_ADDR_LOOPBACK(&a->a6) ||
+ ((v4 = inany_v4(a)) && IN4_IS_ADDR_LOOPBACK(v4));
+}
+
/** inany_from_af - Set IPv[46] address from IPv4 or IPv6 address
* @aa: Pointer to store IPv[46] address
* @af: Address family of @addr
diff --git a/tcp_splice.c b/tcp_splice.c
index 76258e89..fbce4879 100644
--- a/tcp_splice.c
+++ b/tcp_splice.c
@@ -436,24 +436,16 @@ bool tcp_splice_conn_from_sock(const struct ctx *c,
struct tcp_splice_conn *conn, int s,
const struct sockaddr *sa)
{
- const struct in_addr *a4;
union inany_addr aany;
in_port_t port;
ASSERT(c->mode == MODE_PASTA);
inany_from_sockaddr(&aany, &port, sa);
- a4 = inany_v4(&aany);
+ if (!inany_is_loopback(&aany))
+ return false;
- if (a4) {
- if (!IN4_IS_ADDR_LOOPBACK(a4))
- return false;
- conn->flags = 0;
- } else {
- if (!IN6_IS_ADDR_LOOPBACK(&aany.a6))
- return false;
- conn->flags = SPLICE_V6;
- }
+ conn->flags = inany_v4(&aany) ? 0 : SPLICE_V6;
if (setsockopt(s, SOL_TCP, TCP_QUICKACK, &((int){ 1 }), sizeof(int)))
flow_trace(conn, "failed to set TCP_QUICKACK on %i", s);
--
2.43.0