From edc98519068171ebfb608aff33f653de7fee1c7c Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Thu, 21 Sep 2023 18:29:24 +0930 Subject: [PATCH] packetbeat/beater: deduplicate interface configs (#36576) When a config is provided by fleet, it will contain multiple definitions of the same interface, and in future we may allow individual datastreams to specify their own interface, so allow multiple distinct interfaces, but ensure that no interfaces have the same configuration by removing duplicates. --- CHANGELOG.next.asciidoc | 1 + packetbeat/beater/processor.go | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 56a4ff583fc..c7124830c0d 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -243,6 +243,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff] *Packetbeat* +- Improve efficiency of sniffers by deduplicating interface configurations. {issue}36574[36574] {pull}36576[36576] *Winlogbeat* diff --git a/packetbeat/beater/processor.go b/packetbeat/beater/processor.go index 513dbe2871c..4099099b7ea 100644 --- a/packetbeat/beater/processor.go +++ b/packetbeat/beater/processor.go @@ -220,14 +220,31 @@ func setupSniffer(id string, cfg config.Config, protocols *protos.ProtocolsStruc return nil, err } - for i, iface := range cfg.Interfaces { + // Ensure interfaces are uniquely represented so we don't listen on the + // same interface with multiple sniffers. + interfaces := make([]config.InterfaceConfig, 0, len(cfg.Interfaces)) + seen := make(map[uint64]bool) + for _, iface := range cfg.Interfaces { + // Currently we hash on all fields in the config. We can revise this in future. + h, err := hashstructure.Hash(iface, nil) + if err != nil { + return nil, fmt.Errorf("could not deduplicate interface configurations: %w", err) + } + if seen[h] { + continue + } + seen[h] = true + interfaces = append(interfaces, iface) + } + + for i, iface := range interfaces { if iface.BpfFilter != "" || cfg.Flows.IsEnabled() { continue } - cfg.Interfaces[i].BpfFilter = protocols.BpfFilter(iface.WithVlans, icmp.Enabled()) + interfaces[i].BpfFilter = protocols.BpfFilter(iface.WithVlans, icmp.Enabled()) } - return sniffer.New(id, false, "", decoders, cfg.Interfaces) + return sniffer.New(id, false, "", decoders, interfaces) } // CheckConfig performs a dry-run creation of a Packetbeat pipeline based