Skip to content

Commit

Permalink
Determine conntrack status based on connection info (#20977)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
akarpz authored Nov 23, 2023
1 parent 2458f92 commit 0baced3
Show file tree
Hide file tree
Showing 11 changed files with 15 additions and 58 deletions.
17 changes: 5 additions & 12 deletions pkg/network/ebpf/c/prebuilt/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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();
Expand Down
13 changes: 9 additions & 4 deletions pkg/network/ebpf/c/prebuilt/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 0 additions & 4 deletions pkg/network/ebpf/c/prebuilt/offset-guess.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions pkg/network/ebpf/c/prebuilt/offset-guess.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ typedef struct {
__u64 offset_ino;

__u32 saddr;
__u32 status;
__u32 netns;
} conntrack_status_t;

Expand Down Expand Up @@ -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
5 changes: 0 additions & 5 deletions pkg/network/ebpf/c/runtime/offsetguess-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
20 changes: 1 addition & 19 deletions pkg/network/tracer/offsetguess/conntrack.go
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion pkg/network/tracer/offsetguess/offsetguess.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ var whatString = map[GuessWhat]string{

GuessCtTupleOrigin: "conntrack origin tuple",
GuessCtTupleReply: "conntrack reply tuple",
GuessCtStatus: "conntrack status",
GuessCtNet: "conntrack network namespace",
}

Expand Down
1 change: 0 additions & 1 deletion pkg/network/tracer/offsetguess/offsetguess_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions pkg/network/tracer/offsetguess/offsetguess_types_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions pkg/network/tracer/offsetguess/overlaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
5 changes: 0 additions & 5 deletions pkg/network/tracer/offsetguess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ const (
offsetSkBuffHead
offsetCtOrigin
offsetCtReply
offsetCtStatus
offsetCtNetns
offsetCtIno
offsetMax
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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":
Expand Down

0 comments on commit 0baced3

Please sign in to comment.