Skip to content

Commit

Permalink
feat(backend/cgroup-skb): Experimental support for displaying thread …
Browse files Browse the repository at this point in the history
…ID and name in cgroup-skb output
  • Loading branch information
mozillazg committed Dec 21, 2024
1 parent e3fa2ee commit dcab927
Show file tree
Hide file tree
Showing 25 changed files with 144 additions and 10 deletions.
3 changes: 2 additions & 1 deletion bpf/bpf_arm64_bpfel.go

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

Binary file modified bpf/bpf_arm64_bpfel.o
Binary file not shown.
Binary file modified bpf/bpf_legacy_arm64_bpfel.o
Binary file not shown.
Binary file modified bpf/bpf_legacy_x86_bpfel.o
Binary file not shown.
Binary file modified bpf/bpf_no_tracing_arm64_bpfel.o
Binary file not shown.
Binary file modified bpf/bpf_no_tracing_x86_bpfel.o
Binary file not shown.
3 changes: 2 additions & 1 deletion bpf/bpf_x86_bpfel.go

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

Binary file modified bpf/bpf_x86_bpfel.o
Binary file not shown.
9 changes: 9 additions & 0 deletions bpf/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ struct process_meta_t {
u32 pidns_id;
u32 mntns_id;
u32 netns_id;
u32 tid;
char tname[TASK_COMM_LEN];
char cgroup_name[MAX_CGROUP_NAME_LEN];
};

Expand Down Expand Up @@ -158,6 +160,7 @@ static __always_inline int process_filter(struct task_struct *task) {

if (!should_filter) {
if (g.filter_comm_enable == 1) {
// TODO: check real process name instead of comm
char comm[TASK_COMM_LEN];
__builtin_memset(&comm, 0, sizeof(comm));
BPF_CORE_READ_STR_INTO(&comm, task, comm);
Expand Down Expand Up @@ -255,6 +258,12 @@ static __always_inline void fill_process_meta(struct task_struct *task, struct p
}
}

static __always_inline void fill_process_meta_with_thread(struct task_struct *task, struct process_meta_t *meta) {
fill_process_meta(task, meta);
BPF_CORE_READ_INTO(&meta->tid, task, pid);
BPF_CORE_READ_STR_INTO(&meta->tname, task, comm);
}

static __always_inline void handle_exec(void *ctx, struct task_struct *task, pid_t old_pid, struct linux_binprm *bprm) {
// if (process_filter(task) < 0) {
// return;
Expand Down
2 changes: 1 addition & 1 deletion bpf/ptcpdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ static __always_inline int fill_packet_event_meta(struct __sk_buff *skb, bool cg
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
if (task && !is_kernel_thread(task)) {
event_meta->l3_protocol = bpf_ntohs(skb->protocol);
fill_process_meta(task, pid_meta);
fill_process_meta_with_thread(task, pid_meta);
if (pid_meta->pid > 0) {
// debug_log("[ptcpdump][cgroup_sk] get_current_task success\n");
return 0;
Expand Down
4 changes: 2 additions & 2 deletions cmd/capture.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ func headerTips(opts *Options) {
interfaces = fmt.Sprintf("[%s]", strings.Join(opts.ifaces, ", "))
}

msg := fmt.Sprintf("capturing on %s, link-type EN10MB (Ethernet), snapshot length %d bytes",
interfaces, opts.snapshotLength)
msg := fmt.Sprintf("capturing on %s, link-type EN10MB (Ethernet), snapshot length %d bytes, backend %s",
interfaces, opts.snapshotLength, opts.backend)

if opts.verbose < 1 {
log.Warn("ptcpdump: verbose output suppressed, use -v[v]... for verbose output")
Expand Down
12 changes: 11 additions & 1 deletion cmd/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
extPcapNG = ".pcapng"

contextProcess = "process"
contextThread = "thread"
contextParentProc = "parentproc"
contextContainer = "container"
contextPod = "pod"
Expand Down Expand Up @@ -154,12 +155,14 @@ func prepareOptions(opts *Options, rawArgs []string, args []string) {

if len(opts.enhancedContexts) == 0 {
opts.enhancedContext = types.EnhancedContextProcess | types.EnhancedContextParentProc |
types.EnhancedContextContainer | types.EnhancedContextPod
types.EnhancedContextContainer | types.EnhancedContextPod | types.EnhancedContextThread
}
for _, c := range opts.enhancedContexts {
switch c {
case contextProcess:
opts.enhancedContext |= types.EnhancedContextProcess
case contextThread:
opts.enhancedContext |= types.EnhancedContextThread
case contextParentProc:
opts.enhancedContext |= types.EnhancedContextParentProc
case contextContainer:
Expand All @@ -169,6 +172,13 @@ func prepareOptions(opts *Options, rawArgs []string, args []string) {
}
}

switch opts.backend {
case string(types.NetHookBackendCgroupSkb):
break
default:
opts.backend = string(types.NetHookBackendTc)
}

}

func getPodNameFilter(raw string) (name, ns string) {
Expand Down
15 changes: 15 additions & 0 deletions cmd/read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,21 @@ func TestFormat(t *testing.T) {
},
expectedOutFile: "../testdata/format/icmp.pcapng.out.txt",
},
{
name: "thread",
opts: &Options{
readFilePath: "../testdata/format/curl-thread.pcapng",
},
expectedOutFile: "../testdata/format/curl-thread.pcapng.out.txt",
},
{
name: "thread -v",
opts: &Options{
readFilePath: "../testdata/format/curl-thread.pcapng",
verbose: 1,
},
expectedOutFile: "../testdata/format/curl-thread.pcapng.-v.out.txt",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func init() {
rootCmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false,
"Quiet output. Print less protocol information so output lines are shorter")
rootCmd.Flags().StringSliceVar(&opts.enhancedContexts, "context",
[]string{contextProcess, contextParentProc, contextContainer, contextPod},
[]string{contextProcess, contextThread, contextParentProc, contextContainer, contextPod},
"Specify which context information to include in the output")
rootCmd.Flags().StringVar(&opts.backend, "backend", string(types.NetHookBackendTc),
"Specify the backend to use for capturing packets. "+
Expand Down
8 changes: 6 additions & 2 deletions internal/event/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type Packet struct {
Type packetType
Device types.Device
Pid int
Tid int
TName string
MntNs int
NetNs int
Truncated bool
Expand All @@ -50,13 +52,15 @@ func ParsePacketEvent(deviceCache *metadata.DeviceCache, event bpf.BpfPacketEven
p.Time = t.UTC()
}
p.Pid = int(event.Meta.Process.Pid)
p.Tid = int(event.Meta.Process.Tid)
p.TName = utils.GoString(event.Meta.Process.Tname[:])
p.MntNs = int(event.Meta.Process.MntnsId)
p.NetNs = int(event.Meta.Process.NetnsId)
p.CgroupName = utils.GoString(event.Meta.Process.CgroupName[:])
p.Device, _ = deviceCache.GetByIfindex(int(event.Meta.Ifindex), event.Meta.Process.NetnsId)

log.Infof("new packet event, pid: %d mntns: %d, netns: %d, cgroupName: %s",
p.Pid, p.MntNs, p.NetNs, p.CgroupName)
log.Infof("new packet event, thread: %s.%d, pid: %d mntns: %d, netns: %d, cgroupName: %s",
p.TName, p.Tid, p.Pid, p.MntNs, p.NetNs, p.CgroupName)

p.L3Protocol = event.Meta.L3Protocol
p.FirstLayer = firstLayerType(event.Meta.FirstLayer)
Expand Down
2 changes: 2 additions & 0 deletions internal/event/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func FromPacketOptions(opts pcapgo.NgPacketOptions) (types.ProcessExec, types.Pa
pctx.FromPacketComments(opts.Comments)
p.PPid = pctx.Parent.Pid
p.Pid = pctx.Pid
p.Tid = pctx.Tid
p.TName = pctx.TName
p.Filename = pctx.Cmd
p.FilenameTruncated = pctx.CmdTruncated
p.Args = pctx.Args
Expand Down
2 changes: 2 additions & 0 deletions internal/parser/pcapng.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func (p *PcapNGParser) Parse() (*event.Packet, error) {

exec, ctx := event.FromPacketOptions(opts)
e.Pid = exec.Pid
e.Tid = exec.Tid
e.TName = exec.TName
p.pcache.AddItemWithContext(exec, ctx)

return e, nil
Expand Down
4 changes: 4 additions & 0 deletions internal/types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ func (c *PacketContext) FromPacketComments(comments []string) {
switch key {
case "PID":
c.Pid, _ = strconv.Atoi(value)
case "ThreadId", "TID":
c.Tid, _ = strconv.Atoi(value)
case "ThreadName":
c.TName = value
case "ParentPID":
c.Parent.Pid, _ = strconv.Atoi(value)
case "Command", "Cmd", "ParentCommand", "ParentCmd":
Expand Down
5 changes: 5 additions & 0 deletions internal/types/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ const (
EnhancedContextParentProc
EnhancedContextContainer
EnhancedContextPod
EnhancedContextThread
)

func (c EnhancedContext) ProcessContext() bool {
return c == 0 || c&EnhancedContextProcess != 0
}

func (c EnhancedContext) ThreadContext() bool {
return c == 0 || c&EnhancedContextThread != 0
}

func (c EnhancedContext) ParentProcContext() bool {
return c == 0 || c&EnhancedContextParentProc != 0
}
Expand Down
5 changes: 5 additions & 0 deletions internal/types/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ type ProcessBase struct {
Pid int
Cmd string
CmdTruncated bool
Tid int
TName string

Args []string
ArgsTruncated bool
Expand All @@ -31,6 +33,9 @@ type ProcessExec struct {
PPid int
Pid int

Tid int
TName string

Filename string
FilenameTruncated bool

Expand Down
10 changes: 9 additions & 1 deletion internal/writer/pcapng.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,22 @@ func (w *PcapNGWriter) Write(e *event.Packet) error {
InterfaceIndex: w.getInterfaceIndex(e.Device),
}
p := w.pcache.Get(e.Pid, e.MntNs, e.NetNs, e.CgroupName)
p.Tid = e.Tid
p.TName = e.TName

opts := pcapgo.NgPacketOptions{}
if w.enhancedContext.ProcessContext() && p.Pid != 0 {
if w.enhancedContext.ProcessContext() && p.Pid > 0 {
log.Debugf("found pid from cache: %d", e.Pid)
opts.Comments = append(opts.Comments,
fmt.Sprintf("PID: %d\nCmd: %s\nArgs: %s",
e.Pid, p.Cmd, p.FormatArgs()),
)
if w.enhancedContext.ThreadContext() && p.Tid > 0 {
opts.Comments = append(opts.Comments,
fmt.Sprintf("ThreadId: %d\nThreadName: %s",
p.Tid, p.TName),
)
}
if w.enhancedContext.ParentProcContext() && p.Parent.Pid > 0 {
opts.Comments = append(opts.Comments,
fmt.Sprintf("ParentPID: %d\nParentCmd: %s\nParentArgs: %s",
Expand Down
15 changes: 15 additions & 0 deletions internal/writer/stdout.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ func (w *StdoutWriter) Write(e *event.Packet) error {
packetType = "In"
}
p := w.pcache.Get(e.Pid, e.MntNs, e.NetNs, e.CgroupName)
p.Tid = e.Tid
p.TName = e.TName

processInfo := ""
threadInfo := ""
parentProcInfo := ""
containerInfo := ""
PodInfo := ""
Expand All @@ -71,6 +74,9 @@ func (w *StdoutWriter) Write(e *event.Packet) error {
processInfo = fmt.Sprintf("Process (pid %d, cmd %s, args %s)",
e.Pid, p.Cmd, p.FormatArgs())
}
if w.enhancedContext.ProcessContext() && p.Tid > 0 {
threadInfo = fmt.Sprintf("Thread (tid %d, name %s)", p.Tid, p.TName)
}
if w.enhancedContext.ParentProcContext() && p.Parent.Pid > 0 {
parentProcInfo = fmt.Sprintf("ParentProc (pid %d, cmd %s, args %s)",
p.Parent.Pid, p.Parent.Cmd, p.Parent.FormatArgs())
Expand All @@ -88,6 +94,9 @@ func (w *StdoutWriter) Write(e *event.Packet) error {
if w.enhancedContext.ProcessContext() && e.Pid > 0 {
processInfo = fmt.Sprintf("%s.%d", p.Comm(), e.Pid)
}
if w.enhancedContext.ThreadContext() && p.Tid > 0 {
threadInfo = fmt.Sprintf("Thread [%s.%d]", p.TName, p.Tid)
}
if w.enhancedContext.ParentProcContext() && p.Parent.Pid > 0 {
parentProcInfo = fmt.Sprintf("ParentProc [%s.%d]", p.Parent.Comm(), p.Parent.Pid)
}
Expand Down Expand Up @@ -139,6 +148,9 @@ func (w *StdoutWriter) Write(e *event.Packet) error {
builder.WriteString(fmt.Sprintf("%s\n", formatedHeader))
if processInfo != "" {
builder.WriteString(fmt.Sprintf(" %s\n", processInfo))
if threadInfo != "" {
builder.WriteString(fmt.Sprintf(" %s\n", threadInfo))
}
if parentProcInfo != "" {
builder.WriteString(fmt.Sprintf(" %s\n", parentProcInfo))
}
Expand All @@ -152,6 +164,9 @@ func (w *StdoutWriter) Write(e *event.Packet) error {
break
default:
builder.WriteString(formatedHeader)
if threadInfo != "" {
builder.WriteString(fmt.Sprintf(", %s", threadInfo))
}
if parentProcInfo != "" {
builder.WriteString(fmt.Sprintf(", %s", parentProcInfo))
}
Expand Down
Binary file added testdata/format/curl-thread.pcapng
Binary file not shown.
43 changes: 43 additions & 0 deletions testdata/format/curl-thread.pcapng.-v.out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
02:00:37.400239 ens33 Out IP (tos 0x0, ttl 64, id 18924, offset 0, flags [DF], proto TCP (6), length 60)
10.0.2.15.53258 > 198.185.159.144.80: Flags [S], cksum 0x7287, seq 1249028847, win 64240, options [mss 1460,sackOK,TS val 3410064770 ecr 0,nop,wscale 7], length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
Thread (tid 122868, name curl)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:37.918397 ens33 In IP (tos 0x0, ttl 128, id 9697, offset 0, flags [none], proto TCP (6), length 44)
198.185.159.144.80 > 10.0.2.15.53258: Flags [S.], cksum 0xc02d, seq 2029530089, ack 1249028848, win 64240, options [mss 1460], length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:37.918739 ens33 Out IP (tos 0x0, ttl 64, id 18925, offset 0, flags [DF], proto TCP (6), length 40)
10.0.2.15.53258 > 198.185.159.144.80: Flags [.], cksum 0x7273, seq 1249028848, ack 2029530090, win 64240, length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:37.918979 ens33 Out IP (tos 0x0, ttl 64, id 18926, offset 0, flags [DF], proto TCP (6), length 113)
10.0.2.15.53258 > 198.185.159.144.80: Flags [P.], cksum 0x72bc, seq 1249028848:1249028921, ack 2029530090, win 64240, length 73
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
Thread (tid 122868, name curl)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:37.919376 ens33 In IP (tos 0x0, ttl 128, id 9698, offset 0, flags [none], proto TCP (6), length 40)
198.185.159.144.80 > 10.0.2.15.53258: Flags [.], cksum 0xd7a1, seq 2029530090, ack 1249028921, win 64240, length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:38.459435 ens33 In IP (tos 0x0, ttl 128, id 9701, offset 0, flags [none], proto TCP (6), length 292)
198.185.159.144.80 > 10.0.2.15.53258: Flags [P.], cksum 0x8523, seq 2029530090:2029530342, ack 1249028921, win 64240, length 252
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:38.459846 ens33 Out IP (tos 0x0, ttl 64, id 18927, offset 0, flags [DF], proto TCP (6), length 40)
10.0.2.15.53258 > 198.185.159.144.80: Flags [.], cksum 0x7273, seq 1249028921, ack 2029530342, win 63988, length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:38.460535 ens33 Out IP (tos 0x0, ttl 64, id 18928, offset 0, flags [DF], proto TCP (6), length 40)
10.0.2.15.53258 > 198.185.159.144.80: Flags [F.], cksum 0x7273, seq 1249028921, ack 2029530342, win 63988, length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
Thread (tid 122868, name curl)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:38.462021 ens33 In IP (tos 0x0, ttl 128, id 9702, offset 0, flags [none], proto TCP (6), length 40)
198.185.159.144.80 > 10.0.2.15.53258: Flags [.], cksum 0xd6a5, seq 2029530342, ack 1249028922, win 64239, length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
02:00:38.973317 ens33 Out IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
10.0.2.15.53258 > 198.185.159.144.80: Flags [.], cksum 0xd79f, seq 1249028922, ack 2029530343, win 63988, length 0
Process (pid 122868, cmd /usr/bin/curl, args curl kernel.com)
ParentProc (pid 53229, cmd /usr/bin/bash, args -bash)
10 changes: 10 additions & 0 deletions testdata/format/curl-thread.pcapng.out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
02:00:37.400239 ens33 curl.122868 Out IP 10.0.2.15.53258 > 198.185.159.144.80: Flags [S], seq 1249028847, win 64240, options [mss 1460,sackOK,TS val 3410064770 ecr 0,nop,wscale 7], length 0, Thread [curl.122868], ParentProc [bash.53229]
02:00:37.918397 ens33 curl.122868 In IP 198.185.159.144.80 > 10.0.2.15.53258: Flags [S.], seq 2029530089, ack 1249028848, win 64240, options [mss 1460], length 0, ParentProc [bash.53229]
02:00:37.918739 ens33 curl.122868 Out IP 10.0.2.15.53258 > 198.185.159.144.80: Flags [.], seq 1249028848, ack 2029530090, win 64240, length 0, ParentProc [bash.53229]
02:00:37.918979 ens33 curl.122868 Out IP 10.0.2.15.53258 > 198.185.159.144.80: Flags [P.], seq 1249028848:1249028921, ack 2029530090, win 64240, length 73, Thread [curl.122868], ParentProc [bash.53229]
02:00:37.919376 ens33 curl.122868 In IP 198.185.159.144.80 > 10.0.2.15.53258: Flags [.], seq 2029530090, ack 1249028921, win 64240, length 0, ParentProc [bash.53229]
02:00:38.459435 ens33 curl.122868 In IP 198.185.159.144.80 > 10.0.2.15.53258: Flags [P.], seq 2029530090:2029530342, ack 1249028921, win 64240, length 252, ParentProc [bash.53229]
02:00:38.459846 ens33 curl.122868 Out IP 10.0.2.15.53258 > 198.185.159.144.80: Flags [.], seq 1249028921, ack 2029530342, win 63988, length 0, ParentProc [bash.53229]
02:00:38.460535 ens33 curl.122868 Out IP 10.0.2.15.53258 > 198.185.159.144.80: Flags [F.], seq 1249028921, ack 2029530342, win 63988, length 0, Thread [curl.122868], ParentProc [bash.53229]
02:00:38.462021 ens33 curl.122868 In IP 198.185.159.144.80 > 10.0.2.15.53258: Flags [.], seq 2029530342, ack 1249028922, win 64239, length 0, ParentProc [bash.53229]
02:00:38.973317 ens33 curl.122868 Out IP 10.0.2.15.53258 > 198.185.159.144.80: Flags [.], seq 1249028922, ack 2029530343, win 63988, length 0, ParentProc [bash.53229]

0 comments on commit dcab927

Please sign in to comment.