Skip to content

firewall: T8247: Allow both protocol names and numbers consistently#4978

Open
Nyandorew wants to merge 1 commit intovyos:currentfrom
Amiya-Corp:devin/1770277170-firewall-protocol-number-fix
Open

firewall: T8247: Allow both protocol names and numbers consistently#4978
Nyandorew wants to merge 1 commit intovyos:currentfrom
Amiya-Corp:devin/1770277170-firewall-protocol-number-fix

Conversation

@Nyandorew
Copy link
Copy Markdown

@Nyandorew Nyandorew commented Feb 10, 2026

Related Task(s)

https://vyos.dev/T8247

Change summary

Fixes inconsistent handling of protocol specification in firewall configuration. When users specify protocol by IANA number (e.g., 6 for TCP), certain options like port specifications, TCP flags, and GRE settings would fail validation because the checks compare against string names.

This PR normalizes protocol numbers to their string names early in verify_rule() so all subsequent validations work consistently.

Example of the bug:

# This works
set firewall ipv4 name RULE rule 1 protocol 6

# This fails with "Protocol must be tcp, udp, or tcp_udp when specifying a port"
set firewall ipv4 name RULE rule 2 protocol 6
set firewall ipv4 name RULE rule 2 destination port 443

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Related PR(s)

Component(s) name

src/conf_mode/firewall.py

How to test

#!/bin/vbash
source /opt/vyatta/etc/functions/script-template

# Safeguard: ensure script runs with vyattacfg group
if [ "$(id -g -n)" != 'vyattacfg' ] ; then
    exec sg vyattacfg -c "/bin/vbash $(readlink -f $0) $@"
fi

echo "=========================================="
echo "Firewall Protocol Number Test Script"
echo "Task: T8247"
echo "=========================================="

configure

# Initial setup - create base rule
echo ""
echo "[Setup] Creating base firewall rules..."
set firewall ipv4 name RULE default-action drop
set firewall ipv4 name RULE rule 1 action accept
set firewall ipv6 name RULE6 default-action drop
set firewall ipv6 name RULE6 rule 1 action accept
commit
echo "[Setup] Base rules created."

# ==========================================
# Test 1: Port specification (TCP) - Numeric protocol
# ==========================================
echo ""
echo "[Test 1a] Port specification with numeric protocol (6 = TCP)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol 6
set firewall ipv4 name RULE rule 1 destination port 443
if commit; then
    echo "[Test 1a] PASSED: Numeric protocol 6 with port 443 accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 1a] FAILED: Numeric protocol 6 with port 443 rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 destination
commit

# ==========================================
# Test 1b: Port specification (TCP) - String protocol
# ==========================================
echo ""
echo "[Test 1b] Port specification with string protocol (tcp)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol tcp
set firewall ipv4 name RULE rule 1 destination port 443
if commit; then
    echo "[Test 1b] PASSED: String protocol tcp with port 443 accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 1b] FAILED: String protocol tcp with port 443 rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 destination
commit

# ==========================================
# Test 2a: Port specification (UDP) - Numeric protocol
# ==========================================
echo ""
echo "[Test 2a] Port specification with numeric protocol (17 = UDP)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol 17
set firewall ipv4 name RULE rule 1 destination port 53
if commit; then
    echo "[Test 2a] PASSED: Numeric protocol 17 with port 53 accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 2a] FAILED: Numeric protocol 17 with port 53 rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 destination
commit

# ==========================================
# Test 2b: Port specification (UDP) - String protocol
# ==========================================
echo ""
echo "[Test 2b] Port specification with string protocol (udp)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol udp
set firewall ipv4 name RULE rule 1 destination port 53
if commit; then
    echo "[Test 2b] PASSED: String protocol udp with port 53 accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 2b] FAILED: String protocol udp with port 53 rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 destination
commit

# ==========================================
# Test 3a: TCP flags - Numeric protocol
# ==========================================
echo ""
echo "[Test 3a] TCP flags with numeric protocol (6 = TCP)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol 6
set firewall ipv4 name RULE rule 1 tcp flags syn
if commit; then
    echo "[Test 3a] PASSED: Numeric protocol 6 with tcp flags syn accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 3a] FAILED: Numeric protocol 6 with tcp flags syn rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 tcp
commit

# ==========================================
# Test 3b: TCP flags - String protocol
# ==========================================
echo ""
echo "[Test 3b] TCP flags with string protocol (tcp)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol tcp
set firewall ipv4 name RULE rule 1 tcp flags syn
if commit; then
    echo "[Test 3b] PASSED: String protocol tcp with tcp flags syn accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 3b] FAILED: String protocol tcp with tcp flags syn rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 tcp
commit

# ==========================================
# Test 4a: GRE matching - Numeric protocol
# ==========================================
echo ""
echo "[Test 4a] GRE matching with numeric protocol (47 = GRE)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol 47
set firewall ipv4 name RULE rule 1 gre flags checksum unset
set firewall ipv4 name RULE rule 1 gre key 100
if commit; then
    echo "[Test 4a] PASSED: Numeric protocol 47 with GRE options accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 4a] FAILED: Numeric protocol 47 with GRE options rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 gre
commit

# ==========================================
# Test 4b: GRE matching - String protocol
# ==========================================
echo ""
echo "[Test 4b] GRE matching with string protocol (gre)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol gre
set firewall ipv4 name RULE rule 1 gre flags checksum unset
set firewall ipv4 name RULE rule 1 gre key 100
if commit; then
    echo "[Test 4b] PASSED: String protocol gre with GRE options accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 4b] FAILED: String protocol gre with GRE options rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 gre
commit

# ==========================================
# Test 5a: synproxy action - Numeric protocol
# ==========================================
echo ""
echo "[Test 5a] synproxy action with numeric protocol (6 = TCP)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 action synproxy
set firewall ipv4 name RULE rule 1 protocol 6
set firewall ipv4 name RULE rule 1 synproxy tcp mss 1460
if commit; then
    echo "[Test 5a] PASSED: Numeric protocol 6 with synproxy accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 5a] FAILED: Numeric protocol 6 with synproxy rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 action
set firewall ipv4 name RULE rule 1 action accept
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 synproxy
commit

# ==========================================
# Test 5b: synproxy action - String protocol
# ==========================================
echo ""
echo "[Test 5b] synproxy action with string protocol (tcp)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 action synproxy
set firewall ipv4 name RULE rule 1 protocol tcp
set firewall ipv4 name RULE rule 1 synproxy tcp mss 1460
if commit; then
    echo "[Test 5b] PASSED: String protocol tcp with synproxy accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 5b] FAILED: String protocol tcp with synproxy rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 action
set firewall ipv4 name RULE rule 1 action accept
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 synproxy
commit

# ==========================================
# Test 6a: ICMP protocol (IPv4) - Numeric protocol
# ==========================================
echo ""
echo "[Test 6a] ICMP with numeric protocol (1 = ICMP)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol 1
set firewall ipv4 name RULE rule 1 icmp type-name echo-request
if commit; then
    echo "[Test 6a] PASSED: Numeric protocol 1 with ICMP type accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 6a] FAILED: Numeric protocol 1 with ICMP type rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 icmp
commit

# ==========================================
# Test 6b: ICMP protocol (IPv4) - String protocol
# ==========================================
echo ""
echo "[Test 6b] ICMP with string protocol (icmp)..."
echo "[Before]"
run show firewall ipv4 name RULE rule 1
set firewall ipv4 name RULE rule 1 protocol icmp
set firewall ipv4 name RULE rule 1 icmp type-name echo-request
if commit; then
    echo "[Test 6b] PASSED: String protocol icmp with ICMP type accepted."
    echo "[After]"
    run show firewall ipv4 name RULE rule 1
else
    echo "[Test 6b] FAILED: String protocol icmp with ICMP type rejected."
fi
# Cleanup
delete firewall ipv4 name RULE rule 1 protocol
delete firewall ipv4 name RULE rule 1 icmp
commit

# ==========================================
# Test 7a: ICMPv6 protocol (IPv6) - Numeric protocol
# ==========================================
echo ""
echo "[Test 7a] ICMPv6 with numeric protocol (58 = ICMPv6)..."
echo "[Before]"
run show firewall ipv6 name RULE6 rule 1
set firewall ipv6 name RULE6 rule 1 protocol 58
set firewall ipv6 name RULE6 rule 1 icmpv6 type-name echo-request
if commit; then
    echo "[Test 7a] PASSED: Numeric protocol 58 with ICMPv6 type accepted."
    echo "[After]"
    run show firewall ipv6 name RULE6 rule 1
else
    echo "[Test 7a] FAILED: Numeric protocol 58 with ICMPv6 type rejected."
fi
# Cleanup
delete firewall ipv6 name RULE6 rule 1 protocol
delete firewall ipv6 name RULE6 rule 1 icmpv6
commit

# ==========================================
# Test 7b: ICMPv6 protocol (IPv6) - String protocol
# ==========================================
echo ""
echo "[Test 7b] ICMPv6 with string protocol (ipv6-icmp)..."
echo "[Before]"
run show firewall ipv6 name RULE6 rule 1
set firewall ipv6 name RULE6 rule 1 protocol ipv6-icmp
set firewall ipv6 name RULE6 rule 1 icmpv6 type-name echo-request
if commit; then
    echo "[Test 7b] PASSED: String protocol ipv6-icmp with ICMPv6 type accepted."
    echo "[After]"
    run show firewall ipv6 name RULE6 rule 1
else
    echo "[Test 7b] FAILED: String protocol ipv6-icmp with ICMPv6 type rejected."
fi
# Cleanup
delete firewall ipv6 name RULE6 rule 1 protocol
delete firewall ipv6 name RULE6 rule 1 icmpv6
commit

# ==========================================
# Final cleanup - remove base rules
# ==========================================
echo ""
echo "[Cleanup] Removing base firewall rules..."
delete firewall ipv4 name RULE
delete firewall ipv6 name RULE6
commit

exit

echo ""
echo "=========================================="
echo "All tests completed!"
echo "=========================================="

Test result

test_firewall_protocol_result.txt
test_firewall_protocol.sh

admin@Y-ANDOU-VYOS15.Y-ANDOU-01:~$ grep 'Test [0-9]' test_firewall_protocol_result.txt
[Test 1a] Port specification with numeric protocol (6 = TCP)...
[Test 1a] PASSED: Numeric protocol 6 with port 443 accepted.
[Test 1b] Port specification with string protocol (tcp)...
[Test 1b] PASSED: String protocol tcp with port 443 accepted.
[Test 2a] Port specification with numeric protocol (17 = UDP)...
[Test 2a] PASSED: Numeric protocol 17 with port 53 accepted.
[Test 2b] Port specification with string protocol (udp)...
[Test 2b] PASSED: String protocol udp with port 53 accepted.
[Test 3a] TCP flags with numeric protocol (6 = TCP)...
[Test 3a] PASSED: Numeric protocol 6 with tcp flags syn accepted.
[Test 3b] TCP flags with string protocol (tcp)...
[Test 3b] PASSED: String protocol tcp with tcp flags syn accepted.
[Test 4a] GRE matching with numeric protocol (47 = GRE)...
[Test 4a] PASSED: Numeric protocol 47 with GRE options accepted.
[Test 4b] GRE matching with string protocol (gre)...
[Test 4b] PASSED: String protocol gre with GRE options accepted.
[Test 5a] synproxy action with numeric protocol (6 = TCP)...
[Test 5a] PASSED: Numeric protocol 6 with synproxy accepted.
[Test 5b] synproxy action with string protocol (tcp)...
[Test 5b] PASSED: String protocol tcp with synproxy accepted.
[Test 6a] ICMP with numeric protocol (1 = ICMP)...
[Test 6a] PASSED: Numeric protocol 1 with ICMP type accepted.
[Test 6b] ICMP with string protocol (icmp)...
[Test 6b] PASSED: String protocol icmp with ICMP type accepted.
[Test 7a] ICMPv6 with numeric protocol (58 = ICMPv6)...
[Test 7a] PASSED: Numeric protocol 58 with ICMPv6 type accepted.
[Test 7b] ICMPv6 with string protocol (ipv6-icmp)...
[Test 7b] PASSED: String protocol ipv6-icmp with ICMPv6 type accepted.

Checklist:

  • I have read the CONTRIBUTING document
  • I have linked this PR to one or more Phabricator Task(s)
  • I have run the components SMOKETESTS if applicable
  • My commit headlines contain a valid Task id
  • My change requires a change to the documentation
  • I have updated the documentation accordingly

Requested by: @Nyandorew

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 10, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 10, 2026

👍
No issues in PR Title / Commit Title

@Nyandorew
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

    - Add PROTOCOL_NUMBER_TO_NAME mapping for IANA protocol numbers
    - Normalize protocol numbers to names early in verify_rule()
    - Fix inconsistent behavior when protocol numbers used with various options
    - Ensures protocol numbers (e.g., 6 for TCP) work consistently across:
      * Port specifications
      * TCP flags
      * GRE settings
      * synproxy action
      * ICMP protocol validation
@Nyandorew Nyandorew force-pushed the devin/1770277170-firewall-protocol-number-fix branch from 2239417 to ad9154c Compare February 10, 2026 04:20
vyosbot added a commit to vyos/vyos-cla-signatures that referenced this pull request Feb 10, 2026
@github-actions
Copy link
Copy Markdown

CI integration ❌ failed!

Details

CI logs

  • CLI Smoketests ❌ failed
  • CLI Smoketests (interfaces only) ❌ failed
  • Config tests ❌ failed
  • RAID1 tests ❌ failed
  • CLI Smoketests VPP ⏭️ skipped
  • Config tests VPP ⏭️ skipped
  • TPM tests ⏭️ skipped

Copy link
Copy Markdown
Author

@Nyandorew Nyandorew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested this code and it works fine.

Comment on lines +54 to +68
# Protocol number to name mapping (IANA Protocol Numbers)
# This ensures consistent handling of numeric protocol specifications
PROTOCOL_NUMBER_TO_NAME = {
'1': 'icmp',
'2': 'igmp',
'6': 'tcp',
'17': 'udp',
'47': 'gre',
'50': 'esp',
'51': 'ah',
'58': 'ipv6-icmp',
'89': 'ospf',
'132': 'sctp',
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not believe this should be hardcoded. Instead, we could use nftables’ built-in interface to retrieve the list of supported protocols (nft describe inet_proto), or at minimum, reference /etc/protocols, which, if I recall correctly, is already used for validation in certain parts of the CLI.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged—thanks for the suggestion.
I’ll update this to avoid hardcoding and switch to using nftables’ built-in interface (nft describe inet_proto) or, alternatively, referencing /etc/protocols.
This will require a bit of investigation and implementation work, so could you please allow me a few days to post an update?

@Nyandorew Nyandorew requested a review from zdc February 12, 2026 04:54
@zdc
Copy link
Copy Markdown
Contributor

zdc commented Feb 25, 2026

@Nyandorew I see, you requested the review earlier, but there were no changes after the previous one - maybe this was done accidentally?

Could you confirm that you are still working on the PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants