-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[NPM-3378] Adding eBPF-less network tracer POC #27100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 25 commits
49bed8e
4464eac
fca1a1e
f75cb82
059cbef
2e56ffe
c2a3d78
3959fe9
39853f1
90637ce
753fe21
6a92446
8d5952e
3851ef0
d881f84
de0b4a1
41d1606
856ac78
7e3ec04
81d931a
42e758f
de3545f
ce374c6
497aff8
361d783
72ad33a
8326634
2cd3aaa
e1258c9
4e502e6
31f27a6
08c06aa
b69ef5a
d985ac6
64fcc03
0e39567
7ff5a97
93fa333
6dc8d7d
1f504c4
61dec8d
c014ee7
bae0798
5a10f17
907b44d
b4efeb5
8c72538
398e8d8
ba54c03
7297f4b
cfa736d
714bf2d
a97b0af
c466fbb
15e587e
4819981
0502fb9
ab537d4
14b6ee9
21e40e3
e002855
0621be0
75bab0b
b0030e8
ac937f7
f6e3146
ef365aa
bce4868
6844568
eae3003
e533dd0
1a216d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,8 @@ const ( | |
| ) | ||
|
|
||
| func adjustNetwork(cfg config.Config) { | ||
| ebpflessEnabled := cfg.GetBool(netNS("enable_ebpf_less")) | ||
|
|
||
| limitMaxInt(cfg, spNS("max_conns_per_message"), maxConnsMessageBatchSize) | ||
|
|
||
| if cfg.GetBool(spNS("disable_tcp")) { | ||
|
|
@@ -90,4 +92,25 @@ func adjustNetwork(cfg config.Config) { | |
| log.Warn("disabling NPM connection rollups since USM connection rollups are not enabled") | ||
| cfg.Set(netNS("enable_connection_rollup"), false, model.SourceAgentRuntime) | ||
| } | ||
|
|
||
| // disable features that are not supported on certain | ||
| // configs/platforms | ||
| var disableConfigs []string | ||
| if ebpflessEnabled { | ||
| disableConfigs = append(disableConfigs, | ||
| spNS("enable_conntrack_all_namespaces"), | ||
| netNS("enable_protocol_classification"), | ||
| netNS("enable_http_monitoring"), | ||
| netNS("enable_https_monitoring"), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove, those are legacy USM values
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But if they are set by the customer shouldn't they be referenced here?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure I'm following the comment if a customer set them, USM is the one to handle them (we have backward compatibility) also, USM will be disabled with ebpfless mode, in that case, it does not matter what will be the content of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed them |
||
| evNS("network_process", "enabled"), | ||
| netNS("enable_root_netns"), | ||
| ) | ||
| } | ||
|
|
||
| for _, c := range disableConfigs { | ||
| if cfg.GetBool(c) { | ||
| log.Warnf("disabling %s since it is not supported for this config/platform", c) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. worth explaining why those are not supported
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| cfg.Set(c, false, model.SourceAgentRuntime) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,13 +9,20 @@ import ( | |
| "fmt" | ||
|
|
||
| "github.com/DataDog/datadog-agent/pkg/config" | ||
| "github.com/DataDog/datadog-agent/pkg/config/model" | ||
| "github.com/DataDog/datadog-agent/pkg/util/log" | ||
| ) | ||
|
|
||
| const ( | ||
| maxHTTPFrag = 512 // matches hard limit currently imposed in NPM driver | ||
| ) | ||
|
|
||
| func adjustUSM(cfg config.Config) { | ||
| if cfg.GetBool(netNS("enable_ebpf_less")) && cfg.GetBool(smNS("enabled")) { | ||
| log.Warn("disabling USM since ebpf-less network tracer is enabled") | ||
| cfg.Set(smNS("enabled"), false, model.SourceAgentRuntime) | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm concerned by the current change I think that if a customer enables USM on fargate, system probe should fail until they fix the configuration
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here https://github.com/datadog/datadog-agent/blob/hasan.mahmood/ebpfless-tracer/pkg/network/tracer/tracer.go#L152 we do continue if usm is enabled and not supported and npm is enabled. Isn't this equivalent scenario? I can add the check for npm enabled.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's not equivalent as I see it
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the idea is there is no ebpf-less implementation of USM yet, so how can we continue with enabling USM? This is just a way to not touch multiple points in code to disable USM later on during the load.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are assuming NPM configuration should take precedence over USM configuration The bottom line, we cannot assume what the customer meant, or even if the customer is aware ebpfless is not supported by USM |
||
| if cfg.GetBool(smNS("enabled")) { | ||
| applyDefault(cfg, netNS("enable_http_monitoring"), true) | ||
| applyDefault(cfg, netNS("enable_https_monitoring"), true) | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,13 +16,15 @@ var ( | |
| RuntimeCompiled BuildMode | ||
| CORE BuildMode | ||
| Fentry BuildMode | ||
| Ebpfless BuildMode | ||
| ) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like we should dedicate some time to the build modes. I don't think it's a blocker for this PR considering it's a PoC and the ebpfless mode isn't enabled by default (wdyt @brycekahle?), but we could probably find a way to reconciliate the actual eBPF build modes (prebuild/runtime/CORE) with
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| func init() { | ||
| Prebuilt = prebuilt{} | ||
| RuntimeCompiled = runtimeCompiled{} | ||
| CORE = core{} | ||
| Fentry = fentry{} | ||
| Ebpfless = ebpfless{} | ||
| } | ||
|
|
||
| // BuildMode is an eBPF build mode | ||
|
|
@@ -95,6 +97,23 @@ func (f fentry) Env() map[string]string { | |
| } | ||
| } | ||
|
|
||
| type ebpfless struct{} | ||
|
|
||
| func (e ebpfless) String() string { | ||
| return "eBPFless" | ||
| } | ||
|
|
||
| func (e ebpfless) Env() map[string]string { | ||
| return map[string]string{ | ||
| "NETWORK_TRACER_FENTRY_TESTS": "false", | ||
| "DD_ENABLE_RUNTIME_COMPILER": "false", | ||
| "DD_ENABLE_CO_RE": "false", | ||
| "DD_ALLOW_RUNTIME_COMPILED_FALLBACK": "false", | ||
| "DD_ALLOW_PRECOMPILED_FALLBACK": "false", | ||
| "DD_NETWORK_CONFIG_ENABLE_EBPF_LESS": "true", | ||
|
hmahmood marked this conversation as resolved.
Outdated
|
||
| } | ||
| } | ||
|
|
||
| // GetBuildMode returns which build mode the current environment matches, if any | ||
| func GetBuildMode() BuildMode { | ||
| for _, mode := range []BuildMode{Prebuilt, RuntimeCompiled, CORE, Fentry} { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -11,8 +11,6 @@ import ( | |||
| "fmt" | ||||
| "math" | ||||
|
|
||||
| "golang.org/x/net/bpf" | ||||
|
|
||||
| "github.com/vishvananda/netns" | ||||
|
|
||||
| manager "github.com/DataDog/ebpf-manager" | ||||
|
|
@@ -33,6 +31,26 @@ type dnsMonitor struct { | |||
|
|
||||
| // NewReverseDNS starts snooping on DNS traffic to allow IP -> domain reverse resolution | ||||
| func NewReverseDNS(cfg *config.Config, _ telemetry.Component) (ReverseDNS, error) { | ||||
| // Create the RAW_SOCKET inside the root network namespace | ||||
| var ( | ||||
| packetSrc *filterpkg.AFPacketSource | ||||
| srcErr error | ||||
| ns netns.NsHandle | ||||
| ) | ||||
| ns, err := cfg.GetRootNetNs() | ||||
| if err != nil { | ||||
| return nil, err | ||||
| } | ||||
| defer ns.Close() | ||||
|
|
||||
| err = kernel.WithNS(ns, func() error { | ||||
| packetSrc, srcErr = filterpkg.NewPacketSource(4) | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not clear to a reader that
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 4 MB comes from here:
|
||||
| return srcErr | ||||
| }) | ||||
| if err != nil { | ||||
| return nil, err | ||||
| } | ||||
|
|
||||
| currKernelVersion, err := kernel.HostVersion() | ||||
| if err != nil { | ||||
| // if the platform couldn't be determined, treat it as new kernel case | ||||
|
|
@@ -42,12 +60,11 @@ func NewReverseDNS(cfg *config.Config, _ telemetry.Component) (ReverseDNS, error | |||
| pre410Kernel := currKernelVersion < kernel.VersionCode(4, 1, 0) | ||||
|
|
||||
| var p *ebpfProgram | ||||
| var filter *manager.Probe | ||||
| var bpfFilter []bpf.RawInstruction | ||||
| if pre410Kernel { | ||||
| bpfFilter, err = generateBPFFilter(cfg) | ||||
| if err != nil { | ||||
| if pre410Kernel || cfg.EnableEbpfless { | ||||
| if bpfFilter, err := generateBPFFilter(cfg); err != nil { | ||||
| return nil, fmt.Errorf("error creating bpf classic filter: %w", err) | ||||
| } else if err = packetSrc.SetBPF(bpfFilter); err != nil { | ||||
| return nil, fmt.Errorf("could not set BPF filter on packet source: %w", err) | ||||
| } | ||||
| } else { | ||||
| p, err = newEBPFProgram(cfg) | ||||
|
|
@@ -59,35 +76,19 @@ func NewReverseDNS(cfg *config.Config, _ telemetry.Component) (ReverseDNS, error | |||
| return nil, fmt.Errorf("error initializing ebpf programs: %w", err) | ||||
| } | ||||
|
|
||||
| filter, _ = p.GetProbe(manager.ProbeIdentificationPair{EBPFFuncName: probes.SocketDNSFilter, UID: probeUID}) | ||||
| filter, _ := p.GetProbe(manager.ProbeIdentificationPair{EBPFFuncName: probes.SocketDNSFilter, UID: probeUID}) | ||||
|
leeavital marked this conversation as resolved.
|
||||
| if filter == nil { | ||||
| return nil, fmt.Errorf("error retrieving socket filter") | ||||
| } | ||||
| } | ||||
|
|
||||
| // Create the RAW_SOCKET inside the root network namespace | ||||
| var ( | ||||
| packetSrc *filterpkg.AFPacketSource | ||||
| srcErr error | ||||
| ns netns.NsHandle | ||||
| ) | ||||
| if ns, err = cfg.GetRootNetNs(); err != nil { | ||||
| return nil, err | ||||
| } | ||||
| defer ns.Close() | ||||
|
|
||||
| err = kernel.WithNS(ns, func() error { | ||||
| packetSrc, srcErr = filterpkg.NewPacketSource(filter, bpfFilter) | ||||
| return srcErr | ||||
| }) | ||||
| if err != nil { | ||||
| return nil, err | ||||
| packetSrc.SetEbpf(filter) | ||||
| } | ||||
|
|
||||
| snoop, err := newSocketFilterSnooper(cfg, packetSrc) | ||||
| if err != nil { | ||||
| return nil, err | ||||
| } | ||||
|
|
||||
| return &dnsMonitor{ | ||||
| snoop, | ||||
| p, | ||||
|
|
||||
Uh oh!
There was an error while loading. Please reload this page.