snort3: snort.uc passes --daq via the snort table, so every daq.modules variable is discarded (queue_maxlen has no effect, fail_open is never applied)
Nobody has claimed this yet.
- Dominant language
- Makefile
- Stars
- 4.6k
- Forks
- 4k
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 134
Description
Maintainer: @flyn-org, @graysky2 (template author: @efahl)
Environment: OpenWrt 25.12.5 x86/64, snort3 3.10.0.0-r1, libdaq3 3.0.23, kernel 6.12 (template identical on master, 3.12.2.0-r1)
Environment
Reproduced on OpenWrt 25.12.5 x86/64 with snort3 3.10.0.0-r1, libdaq3 3.0.23, kernel 6.12. The template on master (net/snort3 3.12.2.0-r1, files/snort.uc) is unchanged since 203e941 (2024-02-05) and byte-identical on openwrt-25.12. libdaq3 on master is 3.0.27; modules/nfq/daq_nfq.c is unchanged since v3.0.23.
Summary
With method=nfq, snort-mgr setup renders both
snort = {
['-Q'] = true,
['--daq'] = 'nfq', -- snort.uc line 44
['--max-packet-threads'] = 4,
}
daq = {
...
modules = { -- snort.uc lines 80-86 (daq table 75-87)
{ name = 'nfq', mode = 'inline',
variables = { 'device=eth2', 'queue_maxlen=8192', 'fanout_type=hash', 'fail_open', } }
}
}
Snort processes the snort table as its command line, and does so before any other table (src/main/finalize.lua:110-117). --daq nfq therefore becomes a bare module config on sc->daq_config (src/main/snort_module.cc:925 in 3.10.0.0, :889 on master). When the daq table is closed, SFDAQModule::end() (src/packet_io/sfdaq_module.cc:162, :168 on master) calls SFDAQConfig::overlay() (src/packet_io/sfdaq_config.cc:113-121), which replaces the entire daq.modules list with that bare entry. All variables (and the configured mode) are silently dropped without any warning, so the nfq DAQ runs with its defaults: queue_maxlen=1024 and no fail_open, whatever /etc/config/snort says. main.uc:121 documents the intent (queue_maxlen ... // --daq-var queue_maxlen=int), but the value never reaches libdaq.
Because the stock default is queue_maxlen '1024', the bug is invisible until someone raises the value: the setting then does nothing, and fail_open (unconditional in the template) is never active, so a full queue drops packets instead of bypassing inspection as the template intends.
Observed
dmesg:nfnetlink_queue: nf_queue: full at 1024 entries, dropping packets(s)withoption queue_maxlen '8192';queue_droppedin/proc/net/netfilter/nfnetlink_queueclimbing (165k in 3 days), i.e. no fail-open either.- A/B on the rendered file with
'debug'added todaq.modules[1].variables, Snort started on an unused queue: with line 44 present the DAQ prints nothing (the variable was discarded); with the line removed it printsSet socket receive buffer size to 12435456(= 8192 x 1518). Under load the kernel then logsfull at 8192 entries. copy_mode/copy_rangeare unaffected (libdaq sets them independently of the variables).
Reproduce
uci set snort.snort.method=nfq; uci set snort.nfq.queue_maxlen=8192; uci commit snort; /etc/init.d/snort restart, then generate enough load to overflow a queue:dmesgsaysfull at 1024.- Quick check without load: append
table.insert(daq.modules[1].variables, 'debug')to the rendered file and start Snort - no DAQ debug output. Remove['--daq'] = 'nfq',and start again: debug output appears and the receive buffer size reflectsqueue_maxlen.
Proposed fix
Delete the ['--daq'] = '{{ snort.method }}', line from the snort table in files/snort.uc. daq.modules[1].name already selects the module for all three methods (SFDAQ::init iterates the configured module list and falls back to pcap only when it is empty; snort -T passes for pcap, afpacket and nfq, and nfq starts and binds its queues). Nothing else in snort-mgr, main.uc or nftables.uc depends on snort['--daq']. Keeping --daq and dropping daq.modules instead is not an option, because the variables would have no home.
Notes
- After the fix
fail_openbecomes active as intended: a full queue then passes packets uninspected and increments no counter (__nfqnl_enqueue_packetwithNFQA_CFG_F_FAIL_OPEN), so the drop counters stop being a load indicator. Worth a comment insnort.config, or a UCI option to make it optional. - Minor:
fanout_typeis an afpacket variable. libdaq stores variables without validation and the nfq module only matchesdebug,fail_openandqueue_maxlen, so it is ignored rather than rejected. Harmless, but misleading in the nfq variable list.
I can open a PR for the template change.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with files/snort.uc, especially the snort and daq tables around the cited lines, then trace configuration handling through src/main/finalize.lua and SFDAQConfig::overlay(). Run snort -T for pcap, afpacket, and nfq and verify the rendered nfq configuration preserves queue_maxlen and fail_open in daq.modules.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux, lua
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100