Merge "ebpf offload - do L4 header present check earlier" am: 2c0edb112f

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1591367

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I154915d8db2f7efe6f12ce311d456d0cce59c0c1
This commit is contained in:
Maciej Żenczykowski
2021-02-18 07:20:12 +00:00
committed by Automerger Merge Worker
2 changed files with 13 additions and 0 deletions

View File

@@ -41,6 +41,7 @@
ERR(CHECKSUM) \
ERR(NON_TCP_UDP) \
ERR(NON_TCP) \
ERR(SHORT_L4_HEADER) \
ERR(SHORT_TCP_HEADER) \
ERR(SHORT_UDP_HEADER) \
ERR(TRUNCATED_IPV4) \

View File

@@ -403,6 +403,18 @@ static inline __always_inline int do_forward4(struct __sk_buff* skb, const bool
// out all the non-tcp logic. Also note that at this point is_udp === !is_tcp.
const bool is_tcp = !updatetime || (ip->protocol == IPPROTO_TCP);
// This is a bit of a hack to make things easier on the bpf verifier.
// (In particular I believe the Linux 4.14 kernel's verifier can get confused later on about
// what offsets into the packet are valid and can spuriously reject the program, this is
// because it fails to realize that is_tcp && !is_tcp is impossible)
//
// For both TCP & UDP we'll need to read and modify the src/dst ports, which so happen to
// always be in the first 4 bytes of the L4 header. Additionally for UDP we'll need access
// to the checksum field which is in bytes 7 and 8. While for TCP we'll need to read the
// TCP flags (at offset 13) and access to the checksum field (2 bytes at offset 16).
// As such we *always* need access to at least 8 bytes.
if (data + l2_header_size + sizeof(*ip) + 8 > data_end) PUNT(SHORT_L4_HEADER);
struct tcphdr* tcph = is_tcp ? (void*)(ip + 1) : NULL;
struct udphdr* udph = is_tcp ? NULL : (void*)(ip + 1);