ipv4 tethering offload - decrement ttl during forwarding
Bug: 192635131 Test: atest, TreeHugger, flashed on phone, forwarded ipv4 traffic Signed-off-by: Maciej Żenczykowski <maze@google.com> Original-Change: https://android-review.googlesource.com/1755049 Merged-In: I88e5293a54b7867a8e7dd76f6fd8e2a52d31e51a Change-Id: I88e5293a54b7867a8e7dd76f6fd8e2a52d31e51a
This commit is contained in:
committed by
Maciej Zenczykowski
parent
0868536de9
commit
f416b8a1ff
@@ -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.
|
// For a rawip tx interface it will simply be a bunch of zeroes and later stripped.
|
||||||
*eth = v->macHeader;
|
*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 l4_offs_csum = is_tcp ? ETH_IP4_TCP_OFFSET(check) : ETH_IP4_UDP_OFFSET(check);
|
||||||
const int sz4 = sizeof(__be32);
|
const int sz4 = sizeof(__be32);
|
||||||
// UDP 0 is special and stored as FFFF (this flag also causes a csum of 0 to be unmodified)
|
// 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_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);
|
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
|
// 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.
|
// 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);
|
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),
|
bpf_skb_store_bytes(skb, is_tcp ? ETH_IP4_TCP_OFFSET(dest) : ETH_IP4_UDP_OFFSET(dest),
|
||||||
&v->dstPort, sz2, 0);
|
&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,
|
// 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.
|
// and backported to all Android Common Kernel 4.14+ trees.
|
||||||
if (updatetime) v->last_used = bpf_ktime_get_boot_ns();
|
if (updatetime) v->last_used = bpf_ktime_get_boot_ns();
|
||||||
|
|||||||
Reference in New Issue
Block a user