diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c index e2e6d02a2a..41a93f4ff6 100644 --- a/bpf_progs/netd.c +++ b/bpf_progs/netd.c @@ -56,6 +56,8 @@ static const bool TRACE_OFF = false; // see include/uapi/linux/tcp.h #define TCP_FLAG32_OFF 12 +#define TCP_FLAG8_OFF (TCP_FLAG32_OFF + 1) + // For maps netd does not need to access #define DEFINE_BPF_MAP_NO_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \ DEFINE_BPF_MAP_EXT(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, \ @@ -274,13 +276,27 @@ static __always_inline inline void do_packet_tracing( uint8_t flags = 0; __be16 sport = 0, dport = 0; - if (proto == IPPROTO_TCP && L4_off >= 20) { - (void)bpf_skb_load_bytes_net(skb, L4_off + TCP_FLAG32_OFF + 1, &flags, sizeof(flags), kver); - (void)bpf_skb_load_bytes_net(skb, L4_off + TCP_OFFSET(source), &sport, sizeof(sport), kver); - (void)bpf_skb_load_bytes_net(skb, L4_off + TCP_OFFSET(dest), &dport, sizeof(dport), kver); - } else if (proto == IPPROTO_UDP && L4_off >= 20) { - (void)bpf_skb_load_bytes_net(skb, L4_off + UDP_OFFSET(source), &sport, sizeof(sport), kver); - (void)bpf_skb_load_bytes_net(skb, L4_off + UDP_OFFSET(dest), &dport, sizeof(dport), kver); + if (L4_off >= 20) { + switch (proto) { + case IPPROTO_TCP: + (void)bpf_skb_load_bytes_net(skb, L4_off + TCP_FLAG8_OFF, &flags, sizeof(flags), kver); + // fallthrough + case IPPROTO_DCCP: + case IPPROTO_UDP: + case IPPROTO_UDPLITE: + case IPPROTO_SCTP: + // all of these L4 protocols start with be16 src & dst port + (void)bpf_skb_load_bytes_net(skb, L4_off + 0, &sport, sizeof(sport), kver); + (void)bpf_skb_load_bytes_net(skb, L4_off + 2, &dport, sizeof(dport), kver); + break; + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + // Both IPv4 and IPv6 icmp start with u8 type & code, which we store in the bottom + // (ie. second) byte of sport/dport (which are be16s), the top byte is already zero. + (void)bpf_skb_load_bytes_net(skb, L4_off + 0, (char *)&sport + 1, 1, kver); //type + (void)bpf_skb_load_bytes_net(skb, L4_off + 1, (char *)&dport + 1, 1, kver); //code + break; + } } pkt->timestampNs = bpf_ktime_get_boot_ns();