From 1db34f3b919f0863e0e80f29333ab43bbbf483a0 Mon Sep 17 00:00:00 2001 From: Ryan Zuklie Date: Fri, 20 Jan 2023 17:00:04 -0800 Subject: [PATCH] Add BPF helpers for ipv4/ipv6 and tcp/udp offsets. Test: build & install connectivity module Change-Id: I869810d05ad8266b6a4107a5276864fdbcdbd9b0 --- bpf_progs/bpf_net_helpers.h | 12 ++++++++++++ bpf_progs/netd.c | 6 ++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/bpf_progs/bpf_net_helpers.h b/bpf_progs/bpf_net_helpers.h index c39269ecfe..b7ca3af245 100644 --- a/bpf_progs/bpf_net_helpers.h +++ b/bpf_progs/bpf_net_helpers.h @@ -21,6 +21,18 @@ #include #include +// bionic kernel uapi linux/udp.h header is munged... +#define __kernel_udphdr udphdr +#include + +// Offsets from beginning of L4 (TCP/UDP) header +#define TCP_OFFSET(field) offsetof(struct tcphdr, field) +#define UDP_OFFSET(field) offsetof(struct udphdr, field) + +// Offsets from beginning of L3 (IPv4/IPv6) header +#define IP4_OFFSET(field) offsetof(struct iphdr, field) +#define IP6_OFFSET(field) offsetof(struct ipv6hdr, field) + // this returns 0 iff skb->sk is NULL static uint64_t (*bpf_get_socket_cookie)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_cookie; diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c index 1272f96fff..8ca6ec6a69 100644 --- a/bpf_progs/netd.c +++ b/bpf_progs/netd.c @@ -46,8 +46,6 @@ static const int BPF_MATCH = 1; static const bool INGRESS = false; static const bool EGRESS = true; -#define IP_PROTO_OFF offsetof(struct iphdr, protocol) -#define IPV6_PROTO_OFF offsetof(struct ipv6hdr, nexthdr) // offsetof(struct iphdr, ihl) -- but that's a bitfield #define IPPROTO_IHL_OFF 0 @@ -231,7 +229,7 @@ static __always_inline inline bool skip_owner_match(struct __sk_buff* skb, const if (skb->protocol == htons(ETH_P_IP)) { uint8_t proto; // no need to check for success, proto will be zeroed if bpf_skb_load_bytes_net() fails - (void)bpf_skb_load_bytes_net(skb, IP_PROTO_OFF, &proto, sizeof(proto), kver); + (void)bpf_skb_load_bytes_net(skb, IP4_OFFSET(protocol), &proto, sizeof(proto), kver); if (proto == IPPROTO_ESP) return true; if (proto != IPPROTO_TCP) return false; // handles read failure above uint8_t ihl; @@ -247,7 +245,7 @@ static __always_inline inline bool skip_owner_match(struct __sk_buff* skb, const } else if (skb->protocol == htons(ETH_P_IPV6)) { uint8_t proto; // no need to check for success, proto will be zeroed if bpf_skb_load_bytes_net() fails - (void)bpf_skb_load_bytes_net(skb, IPV6_PROTO_OFF, &proto, sizeof(proto), kver); + (void)bpf_skb_load_bytes_net(skb, IP6_OFFSET(nexthdr), &proto, sizeof(proto), kver); if (proto == IPPROTO_ESP) return true; if (proto != IPPROTO_TCP) return false; // handles read failure above // if the read below fails, we'll just assume no TCP flags are set, which is fine.