From f416b8a1ff2b4197cbcf6c11c7bfef39ec60adf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Fri, 2 Jul 2021 21:36:48 +0000 Subject: [PATCH] ipv4 tethering offload - decrement ttl during forwarding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: 192635131 Test: atest, TreeHugger, flashed on phone, forwarded ipv4 traffic Signed-off-by: Maciej Żenczykowski Original-Change: https://android-review.googlesource.com/1755049 Merged-In: I88e5293a54b7867a8e7dd76f6fd8e2a52d31e51a Change-Id: I88e5293a54b7867a8e7dd76f6fd8e2a52d31e51a --- Tethering/bpf_progs/offload.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Tethering/bpf_progs/offload.c b/Tethering/bpf_progs/offload.c index 6ff370c23e..336d27a824 100644 --- a/Tethering/bpf_progs/offload.c +++ b/Tethering/bpf_progs/offload.c @@ -569,6 +569,16 @@ static inline __always_inline int do_forward4(struct __sk_buff* skb, const bool // For a rawip tx interface it will simply be a bunch of zeroes and later stripped. *eth = v->macHeader; + // Decrement the IPv4 TTL, we already know it's greater than 1. + // u8 TTL field is followed by u8 protocol to make a u16 for ipv4 header checksum update. + // Since we're keeping the ipv4 checksum valid (which means the checksum of the entire + // ipv4 header remains 0), the overall checksum of the entire packet does not change. + const int sz2 = sizeof(__be16); + const __be16 old_ttl_proto = *(__be16 *)&ip->ttl; + const __be16 new_ttl_proto = old_ttl_proto - htons(0x0100); + bpf_l3_csum_replace(skb, ETH_IP4_OFFSET(check), old_ttl_proto, new_ttl_proto, sz2); + bpf_skb_store_bytes(skb, ETH_IP4_OFFSET(ttl), &new_ttl_proto, sz2, 0); + const int l4_offs_csum = is_tcp ? ETH_IP4_TCP_OFFSET(check) : ETH_IP4_UDP_OFFSET(check); const int sz4 = sizeof(__be32); // UDP 0 is special and stored as FFFF (this flag also causes a csum of 0 to be unmodified) @@ -586,7 +596,6 @@ static inline __always_inline int do_forward4(struct __sk_buff* skb, const bool bpf_l3_csum_replace(skb, ETH_IP4_OFFSET(check), old_saddr, new_saddr, sz4); bpf_skb_store_bytes(skb, ETH_IP4_OFFSET(saddr), &new_saddr, sz4, 0); - const int sz2 = sizeof(__be16); // The offsets for TCP and UDP ports: source (u16 @ L4 offset 0) & dest (u16 @ L4 offset 2) are // actually the same, so the compiler should just optimize them both down to a constant. bpf_l4_csum_replace(skb, l4_offs_csum, k.srcPort, v->srcPort, sz2 | l4_flags); @@ -597,8 +606,6 @@ static inline __always_inline int do_forward4(struct __sk_buff* skb, const bool bpf_skb_store_bytes(skb, is_tcp ? ETH_IP4_TCP_OFFSET(dest) : ETH_IP4_UDP_OFFSET(dest), &v->dstPort, sz2, 0); - // TEMP HACK: lack of TTL decrement - // This requires the bpf_ktime_get_boot_ns() helper which was added in 5.8, // and backported to all Android Common Kernel 4.14+ trees. if (updatetime) v->last_used = bpf_ktime_get_boot_ns();