Skip to content

Conversation

@po-nuvai
Copy link

@po-nuvai po-nuvai commented Jan 4, 2026

Summary

Implements #1460 - Improve rule ordering logic

This PR adds explicit rule ordering and configurable evaluation modes, addressing the feature request for more intuitive rule management.

New Features

1. Priority Field for Rules

Rules now have an explicit priority field (integer, default 0):

  • Lower values = higher priority
  • Rules are sorted by priority first, then alphabetically by name
  • Replaces the implicit file naming convention (000-, 001-) with explicit control

Example rule:

{
    "name": "block-malware-domains",
    "priority": -100,
    "action": "deny",
    "operator": { ... }
}

2. Configurable Evaluation Modes

New config option Rules.EvaluationMode:

Mode Description
deny-priority Default. Current behavior - deny/reject rules always win over allow rules
first-match RouterOS-style - first matching rule wins, giving full control via priority

Example config:

"Rules": {
    "Path": "/etc/opensnitchd/rules/",
    "EnableChecksums": false,
    "EvaluationMode": "first-match"
}

How It Works

deny-priority mode (default):

  1. Rules evaluated in priority order
  2. If a matching Allow rule is found, save it but keep looking
  3. If a matching Deny/Reject or Precedence rule is found, return immediately
  4. Return the last saved match

first-match mode:

  1. Rules evaluated in priority order
  2. First matching rule wins immediately
  3. No special handling for Deny vs Allow

Backwards Compatibility

  • Default evaluation mode is deny-priority (current behavior)
  • Default priority is 0, so existing rules work unchanged
  • Existing file naming conventions (000-, 001-) still provide ordering for rules with same priority

Files Changed

  • daemon/rule/rule.go - Added Priority field and EvaluationMode type
  • daemon/rule/loader.go - Updated sorting and matching logic
  • daemon/ui/config/config.go - Added EvaluationMode to config struct
  • daemon/ui/config_utils.go - Apply evaluation mode from config
  • daemon/data/default-config.json - Added EvaluationMode default

Test Plan

  • Create rules with different priorities, verify they're evaluated in correct order
  • Test deny-priority mode: confirm deny rules still win over allow
  • Test first-match mode: confirm first matching rule wins regardless of action
  • Verify existing rules without priority field work (default to 0)
  • Verify config reload applies new evaluation mode

Reviewers

@savchenko - Original requester
@Danny3 - Commented on the feature request

@savchenko
Copy link

Impressive! Just curious, why "lower values = higher priority"? I understand this is very much a matter of preference, but AFAIK on *nix it's usually higher integer == higher priority.

@po-nuvai
Copy link
Author

po-nuvai commented Jan 4, 2026

@savchenko Great question! You're right that it's a matter of convention and both approaches exist in the wild.

I went with "lower = higher priority" because it aligns with how most firewall/packet filter systems work:

  • iptables/nftables - rules are evaluated in order, first match wins
  • RouterOS - explicit sequence numbers, lower processed first
  • pf (BSD) - rules evaluated top-to-bottom
  • Linux nice values - lower nice = higher scheduling priority

The mental model is "position in a queue" - rule at position 1 gets evaluated before position 100.

That said, if the maintainers prefer the opposite convention (higher = higher priority, like some priority queue implementations), it's a one-line change in the sort function! Happy to flip it if that's the consensus. 🙂

What do you think would be more intuitive for OpenSnitch users?

Add support for explicit rule ordering and configurable evaluation logic:

1. **Priority field**: Rules now have a `priority` field (int, default 0).
   Lower values = higher priority. Rules are sorted by priority first,
   then alphabetically by name. This replaces the implicit file naming
   convention (000-, 001-, etc.) with explicit control.

2. **Evaluation modes**: New config option `Rules.EvaluationMode`:
   - `deny-priority` (default): Current behavior where deny/reject rules
     always win over allow rules, regardless of order
   - `first-match`: RouterOS-style evaluation where the first matching
     rule wins, giving full control via priority ordering

Example config:
```json
"Rules": {
    "Path": "/etc/opensnitchd/rules/",
    "EnableChecksums": false,
    "EvaluationMode": "first-match"
}
```

Example rule with priority:
```json
{
    "name": "block-malware",
    "priority": -100,
    "action": "deny",
    ...
}
```

This provides more intuitive and flexible rule ordering while maintaining
backwards compatibility with existing configurations.
@po-nuvai po-nuvai force-pushed the feat/rule-ordering-1460 branch from 9644351 to 600c0ef Compare January 4, 2026 11:22
@savchenko
Copy link

What do you think would be more intuitive for OpenSnitch users?

Ah, makes sense. If integer == position in the queue/table, then lower number logically aligns with "this is evaluated first" and "first match wins".

Thanks!

@po-nuvai po-nuvai closed this by deleting the head repository Jan 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants