From 61902aeac36a56b6b697f6aa35b889638f474ad6 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 13 Sep 2023 12:34:29 +0930 Subject: [PATCH] packetbeat/beater: deduplicate interface configs 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 56a4ff583fc6..c7124830c0df 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 513dbe2871c7..4099099b7ea1 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