From 0baced3603b74a992f60b678a81bec833870277a Mon Sep 17 00:00:00 2001 From: Adam Karpowich Date: Wed, 22 Nov 2023 21:19:37 -0500 Subject: [PATCH] Determine conntrack status based on connection info (#20977) * init * check for more conditions * cleanup and use in fill_info * remove use of status in fill_info * use macro for dry * improve syntax * refactor and remove status field entirely * remove references to ct status * remove comment * remove lingering status ref * various cleanup * remove status from offset guess test * fix offset tests * fix copyright header --- pkg/network/ebpf/c/prebuilt/conntrack.c | 17 +++++----------- pkg/network/ebpf/c/prebuilt/conntrack.h | 13 ++++++++---- pkg/network/ebpf/c/prebuilt/offset-guess.c | 4 ---- pkg/network/ebpf/c/prebuilt/offset-guess.h | 2 -- pkg/network/ebpf/c/runtime/offsetguess-test.c | 5 ----- pkg/network/tracer/offsetguess/conntrack.go | 20 +------------------ pkg/network/tracer/offsetguess/offsetguess.go | 1 - .../tracer/offsetguess/offsetguess_types.go | 1 - .../offsetguess/offsetguess_types_linux.go | 3 --- pkg/network/tracer/offsetguess/overlaps.go | 2 -- pkg/network/tracer/offsetguess_test.go | 5 ----- 11 files changed, 15 insertions(+), 58 deletions(-) diff --git a/pkg/network/ebpf/c/prebuilt/conntrack.c b/pkg/network/ebpf/c/prebuilt/conntrack.c index c5cae4ec3be42..1b5210dd1b72b 100644 --- a/pkg/network/ebpf/c/prebuilt/conntrack.c +++ b/pkg/network/ebpf/c/prebuilt/conntrack.c @@ -15,17 +15,13 @@ SEC("kprobe/__nf_conntrack_hash_insert") int kprobe___nf_conntrack_hash_insert(struct pt_regs* ctx) { struct nf_conn *ct = (struct nf_conn*)PT_REGS_PARM1(ctx); - u32 status = ct_status(ct); - if (!(status&IPS_CONFIRMED) || !(status&IPS_NAT_MASK)) { - return 0; - } - - log_debug("kprobe/__nf_conntrack_hash_insert: netns: %u, status: %x", get_netns(ct), status); + log_debug("kprobe/__nf_conntrack_hash_insert: netns: %u", get_netns(ct)); conntrack_tuple_t orig = {}, reply = {}; if (nf_conn_to_conntrack_tuples(ct, &orig, &reply) != 0) { return 0; } + RETURN_IF_NOT_NAT(&orig, &reply); bpf_map_update_with_telemetry(conntrack, &orig, &reply, BPF_ANY); bpf_map_update_with_telemetry(conntrack, &reply, &orig, BPF_ANY); @@ -44,18 +40,15 @@ int kprobe_ctnetlink_fill_info(struct pt_regs* ctx) { struct nf_conn *ct = (struct nf_conn*)PT_REGS_PARM5(ctx); - u32 status = ct_status(ct); - if (!(status&IPS_CONFIRMED) || !(status&IPS_NAT_MASK)) { - return 0; - } - - log_debug("kprobe/ctnetlink_fill_info: netns: %u, status: %x", get_netns(ct), status); + log_debug("kprobe/ctnetlink_fill_info: netns: %u", get_netns(ct)); conntrack_tuple_t orig = {}, reply = {}; if (nf_conn_to_conntrack_tuples(ct, &orig, &reply) != 0) { return 0; } + RETURN_IF_NOT_NAT(&orig, &reply); + bpf_map_update_with_telemetry(conntrack, &orig, &reply, BPF_ANY); bpf_map_update_with_telemetry(conntrack, &reply, &orig, BPF_ANY); increment_telemetry_registers_count(); diff --git a/pkg/network/ebpf/c/prebuilt/conntrack.h b/pkg/network/ebpf/c/prebuilt/conntrack.h index 45280a155c983..29cd7870ca95e 100644 --- a/pkg/network/ebpf/c/prebuilt/conntrack.h +++ b/pkg/network/ebpf/c/prebuilt/conntrack.h @@ -29,10 +29,15 @@ offset_ct(status) offset_ct(netns) offset_ct(ino) -static __always_inline u32 ct_status(const struct nf_conn *ct) { - u32 status = 0; - bpf_probe_read_kernel_with_telemetry(&status, sizeof(status), (char*)ct + offset_ct_status()); - return status; +#define RETURN_IF_NOT_NAT(orig, reply) \ + if (!is_conn_nat(orig, reply)) { \ + return 0; \ + } + +static __always_inline bool is_conn_nat(const conntrack_tuple_t* orig, const conntrack_tuple_t* reply) { + return orig->daddr_l != reply->saddr_l || orig->dport != reply->sport || + orig->saddr_l != reply->daddr_l || orig->sport != reply->dport || + orig->daddr_h != reply->saddr_h; } static __always_inline u32 get_netns(struct nf_conn *ct) { diff --git a/pkg/network/ebpf/c/prebuilt/offset-guess.c b/pkg/network/ebpf/c/prebuilt/offset-guess.c index e6575e0da76be..74c8bb3b5016b 100644 --- a/pkg/network/ebpf/c/prebuilt/offset-guess.c +++ b/pkg/network/ebpf/c/prebuilt/offset-guess.c @@ -384,10 +384,6 @@ static __always_inline int guess_conntrack_offsets(conntrack_status_t* status, c new_status.offset_reply = aligned_offset(subject, status->offset_reply, SIZEOF_CT_TUPLE_REPLY); bpf_probe_read_kernel(&new_status.saddr, sizeof(new_status.saddr), subject + new_status.offset_reply); break; - case GUESS_CT_STATUS: - new_status.offset_status = aligned_offset(subject, status->offset_status, SIZEOF_CT_STATUS); - bpf_probe_read_kernel(&new_status.status, sizeof(new_status.status), subject + new_status.offset_status); - break; case GUESS_CT_NET: new_status.offset_netns = aligned_offset(subject, status->offset_netns, SIZEOF_CT_NET); bpf_probe_read_kernel(&possible_ct_net, sizeof(possible_net_t*), subject + new_status.offset_netns); diff --git a/pkg/network/ebpf/c/prebuilt/offset-guess.h b/pkg/network/ebpf/c/prebuilt/offset-guess.h index 52258ee0c2443..3d7b23daa7394 100644 --- a/pkg/network/ebpf/c/prebuilt/offset-guess.h +++ b/pkg/network/ebpf/c/prebuilt/offset-guess.h @@ -119,7 +119,6 @@ typedef struct { __u64 offset_ino; __u32 saddr; - __u32 status; __u32 netns; } conntrack_status_t; @@ -150,7 +149,6 @@ static const __u8 SIZEOF_SK_BUFF_HEAD = sizeof((void*)0); // char* static const __u8 SIZEOF_CT_TUPLE_ORIGIN = sizeof_member(conntrack_status_t, saddr); static const __u8 SIZEOF_CT_TUPLE_REPLY = sizeof_member(conntrack_status_t, saddr); -static const __u8 SIZEOF_CT_STATUS = sizeof_member(conntrack_status_t, status); static const __u8 SIZEOF_CT_NET = sizeof((void*)0); // possible_net_t* #endif //__OFFSET_GUESS_H diff --git a/pkg/network/ebpf/c/runtime/offsetguess-test.c b/pkg/network/ebpf/c/runtime/offsetguess-test.c index 65994b359de2e..91fd835628ed2 100644 --- a/pkg/network/ebpf/c/runtime/offsetguess-test.c +++ b/pkg/network/ebpf/c/runtime/offsetguess-test.c @@ -34,7 +34,6 @@ typedef enum { OFFSET_SK_BUFF_HEAD, OFFSET_CT_ORIGIN, OFFSET_CT_REPLY, - OFFSET_CT_STATUS, OFFSET_CT_NETNS, OFFSET_CT_INO, } offset_t; @@ -158,10 +157,6 @@ int kprobe__tcp_getsockopt(struct pt_regs* ctx) { offset += offsetof(struct nf_conntrack_tuple_hash, tuple); bpf_map_update_elem(&offsets, &o, &offset, BPF_ANY); - o = OFFSET_CT_STATUS; - offset = offsetof(struct nf_conn, status); - bpf_map_update_elem(&offsets, &o, &offset, BPF_ANY); - o = OFFSET_CT_NETNS; offset = offsetof(struct nf_conn, ct_net); bpf_map_update_elem(&offsets, &o, &offset, BPF_ANY); diff --git a/pkg/network/tracer/offsetguess/conntrack.go b/pkg/network/tracer/offsetguess/conntrack.go index 8cea2085872f5..f9c04f5aa66a7 100644 --- a/pkg/network/tracer/offsetguess/conntrack.go +++ b/pkg/network/tracer/offsetguess/conntrack.go @@ -102,7 +102,6 @@ func (c *conntrackOffsetGuesser) getConstantEditors() []manager.ConstantEditor { return []manager.ConstantEditor{ {Name: "offset_ct_origin", Value: c.status.Offset_origin}, {Name: "offset_ct_reply", Value: c.status.Offset_reply}, - {Name: "offset_ct_status", Value: c.status.Offset_status}, {Name: "offset_ct_netns", Value: c.status.Offset_netns}, {Name: "offset_ct_ino", Value: c.status.Offset_ino}, {Name: "tcpv6_enabled", Value: c.tcpv6Enabled}, @@ -154,25 +153,11 @@ func (c *conntrackOffsetGuesser) checkAndUpdateCurrentOffset(mp *ebpf.Map, expec } if c.status.Saddr == expected.daddr { - c.logAndAdvance(c.status.Offset_reply, GuessCtStatus) + c.logAndAdvance(c.status.Offset_reply, GuessCtNet) break } c.status.Offset_reply++ c.status.Offset_reply, _ = skipOverlaps(c.status.Offset_reply, c.nfConnRanges()) - case GuessCtStatus: - c.status.Offset_status, overlapped = skipOverlaps(c.status.Offset_status, c.nfConnRanges()) - if overlapped { - // adjusted offset from eBPF overlapped with another field, we need to check new offset - break - } - - if c.status.Status == expected.ctStatus { - c.status.Offset_netns = c.status.Offset_status + 1 - c.logAndAdvance(c.status.Offset_status, GuessCtNet) - break - } - c.status.Offset_status++ - c.status.Offset_status, _ = skipOverlaps(c.status.Offset_status, c.nfConnRanges()) case GuessCtNet: c.status.Offset_netns, overlapped = skipOverlaps(c.status.Offset_netns, c.nfConnRanges()) if overlapped { @@ -390,9 +375,6 @@ func (e *conntrackEventGenerator) populateUDPExpectedValues(expected *fieldValue expected.saddr = saddr expected.daddr = daddr - // IPS_CONFIRMED | IPS_SRC_NAT_DONE | IPS_DST_NAT_DONE - // see https://elixir.bootlin.com/linux/v5.19.17/source/include/uapi/linux/netfilter/nf_conntrack_common.h#L42 - expected.ctStatus = 0x188 expected.netns, err = kernel.GetCurrentIno() if err != nil { return err diff --git a/pkg/network/tracer/offsetguess/offsetguess.go b/pkg/network/tracer/offsetguess/offsetguess.go index 44333e7713b1e..182810cec5d31 100644 --- a/pkg/network/tracer/offsetguess/offsetguess.go +++ b/pkg/network/tracer/offsetguess/offsetguess.go @@ -74,7 +74,6 @@ var whatString = map[GuessWhat]string{ GuessCtTupleOrigin: "conntrack origin tuple", GuessCtTupleReply: "conntrack reply tuple", - GuessCtStatus: "conntrack status", GuessCtNet: "conntrack network namespace", } diff --git a/pkg/network/tracer/offsetguess/offsetguess_types.go b/pkg/network/tracer/offsetguess/offsetguess_types.go index 5756ef0c12760..e13c1938e0c68 100644 --- a/pkg/network/tracer/offsetguess/offsetguess_types.go +++ b/pkg/network/tracer/offsetguess/offsetguess_types.go @@ -61,7 +61,6 @@ const ( GuessCtTupleOrigin GuessWhat = C.GUESS_CT_TUPLE_ORIGIN GuessCtTupleReply GuessWhat = C.GUESS_CT_TUPLE_REPLY - GuessCtStatus GuessWhat = C.GUESS_CT_STATUS GuessCtNet GuessWhat = C.GUESS_CT_NET GuessNotApplicable GuessWhat = 99999 diff --git a/pkg/network/tracer/offsetguess/offsetguess_types_linux.go b/pkg/network/tracer/offsetguess/offsetguess_types_linux.go index d775d40ac22f8..89cc7031ead2c 100644 --- a/pkg/network/tracer/offsetguess/offsetguess_types_linux.go +++ b/pkg/network/tracer/offsetguess/offsetguess_types_linux.go @@ -85,9 +85,7 @@ type ConntrackStatus struct { Offset_netns uint64 Offset_ino uint64 Saddr uint32 - Status uint32 Netns uint32 - Pad_cgo_0 [4]byte } type ConntrackState uint8 @@ -120,7 +118,6 @@ const ( GuessCtTupleOrigin GuessWhat = 0x14 GuessCtTupleReply GuessWhat = 0x15 - GuessCtStatus GuessWhat = 0x16 GuessCtNet GuessWhat = 0x17 GuessNotApplicable GuessWhat = 99999 diff --git a/pkg/network/tracer/offsetguess/overlaps.go b/pkg/network/tracer/offsetguess/overlaps.go index aff7c4f83ba24..5cc058ddc6657 100644 --- a/pkg/network/tracer/offsetguess/overlaps.go +++ b/pkg/network/tracer/offsetguess/overlaps.go @@ -117,14 +117,12 @@ func (c *conntrackOffsetGuesser) nfConnRanges() []offsetRange { idx := slices.Index([]GuessWhat{ GuessCtTupleOrigin, GuessCtTupleReply, - GuessCtStatus, GuessCtNet, }, GuessWhat(c.status.What)) return []offsetRange{ {c.status.Offset_origin, sizeofNfConntrackTuple}, {c.status.Offset_reply, sizeofNfConntrackTuple}, - {c.status.Offset_status, uint64(unsafe.Sizeof(c.status.Status))}, {c.status.Offset_netns, uint64(unsafe.Sizeof(c.status.Netns))}, }[:idx] } diff --git a/pkg/network/tracer/offsetguess_test.go b/pkg/network/tracer/offsetguess_test.go index b505cbab4de73..55c88dc6b9ee6 100644 --- a/pkg/network/tracer/offsetguess_test.go +++ b/pkg/network/tracer/offsetguess_test.go @@ -61,7 +61,6 @@ const ( offsetSkBuffHead offsetCtOrigin offsetCtReply - offsetCtStatus offsetCtNetns offsetCtIno offsetMax @@ -117,8 +116,6 @@ func (o offsetT) String() string { return "offset_ct_origin" case offsetCtReply: return "offset_ct_reply" - case offsetCtStatus: - return "offset_ct_status" case offsetCtNetns: return "offset_ct_netns" case offsetCtIno: @@ -208,8 +205,6 @@ func testOffsetGuess(t *testing.T) { consts[offsetCtOrigin] = value case "offset_ct_reply": consts[offsetCtReply] = value - case "offset_ct_status": - consts[offsetCtStatus] = value case "offset_ct_netns": consts[offsetCtNetns] = value case "offset_ct_ino":