Output similar to Packet Tracer

I’m working on a little project to give output to VyOS similar to Packet Tracer on an ASA. I wanted to get some general feedback on if this would be useful to people. This isn’t fully like packet-tracer since it is just looking to see what policies across multiple categories match on that traffic. Here is what the output looks like currently:

------------------------------------------------
--------------- Phase 1: Routing ---------------
------------------------------------------------

Source:
 Route             | 0.0.0.0/0
 Protocol          | static
 VRF               | default
 Next Hop(s)       | 10.0.95.1,10.0.101.1,10.0.101.1
 Exit Interface(s) | eth0.101,eth0.101

Destination:
 Route             | 0.0.0.0/0
 Protocol          | static
 VRF               | default
 Next Hop(s)       | 10.0.95.1,10.0.101.1,10.0.101.1
 Exit Interface(s) | eth0.101,eth0.101

------------------------------------------------
----------------- Phase 2: NAT -----------------
------------------------------------------------

Source NAT matched on rule 100

------------------------------------------------
--------------- Phase 3: Firewall --------------
------------------------------------------------

Matching Rule Found:

Rule Information

---------------------------------
ipv4 Firewall "forward filter"

 Rule        | 1234
 Description |
 Action      | accept
 Protocol    | tcp
 Packets     | 0
 Bytes       | 0
 Conditions  | ip daddr 1.1.1.2 tcp dport @P_P1000 ip saddr 1.1.1.1 tcp sport 1 iifname "eth1" oifname "eth2"
             | accept

------------------------------------------------
----------------- Phase 4: PBR -----------------
------------------------------------------------

Policy Route matched on rule 10 of policy route TEST2

The planned command is:
show firewall packet-info source-ip <ip> destination-ip <ip> source-port <port> destination-port <port> protocol <protocol>

All of those parameters will be required, and vrf, inbound-interface, and outbound-interface will be optional additional switches that can be added.

cool , should it simulate traffic or is it just a output for those tuples ?

Sounds great.

On PaloAlto Networks firewalls there is this “test” command you can use to virtually construct a packet and then have a verdict on how that will be handled regarding rules, NAT, routing etc:

It’s not simulating the flows like packet-tracer, but it is showing what sections are matching on the theoretical flow. All data is pulled from the various tables and chains within Nftables.

So if a user is having issues with traffic working, and they expect routing, NAT, and firewalls to need a correct configuration to function, they can use it to scope their troubleshooting.

1 Like

Yeah, SRX has something similar as well, though it is only for security policies.

This output will require the user to understand their intent a little. I thought about adding a check if the source was private, and the destination public, indicating that NAT would be required.

I ultimately settled on the output being informative rather than instructive for the sake of programmatic simplicity.

2 Likes

I love it! This will be so helpful when troubleshooting :slight_smile:

I don’t find any general show commands for NAT or PBR to be very useful in this output. What does everyone think of adding the configuration item for those when matched. Here is how it looks with that:

vyos@vyos# run show firewall packet-info source-ip 1.1.1.1 destination-ip 1.1.1.2 source-port 1 destination-port 1000 protocol tcp outbound-interface eth2
------------------------------------------------
--------------- Phase 1: Routing ---------------
------------------------------------------------

Source:
 Route             | 0.0.0.0/0
 Protocol          | static
 VRF               | default
 Next Hop(s)       | 10.0.101.1
 Exit Interface(s) | eth0.101

Destination:
 Route             | 0.0.0.0/0
 Protocol          | static
 VRF               | default
 Next Hop(s)       | 10.0.101.1
 Exit Interface(s) | eth0.101

------------------------------------------------
----------------- Phase 2: NAT -----------------
------------------------------------------------

Source NAT matched on rule 100
------------------------------------------------
set nat source rule 100 destination address '1.1.1.2'
set nat source rule 100 destination port '1000'
set nat source rule 100 outbound-interface name 'eth2'
set nat source rule 100 protocol 'tcp'
set nat source rule 100 source address '1.1.1.1'
set nat source rule 100 source port '1'
set nat source rule 100 translation address 'masquerade'

------------------------------------------------
--------------- Phase 3: Firewall --------------
------------------------------------------------

Matching Rule Found:
Rule Information

---------------------------------
ipv4 Firewall "forward filter"

 Rule        | 1234
 Description |
 Action      | accept
 Protocol    | tcp
 Packets     | 0
 Bytes       | 0
 Conditions  | ip daddr 1.1.1.2 tcp dport @P_P1000 ip saddr 1.1.1.1 tcp sport 1
             | iifname "eth1" oifname "eth2"  accept

------------------------------------------------
----------------- Phase 4: PBR -----------------
------------------------------------------------

Policy Route matched on rule 10 of policy route TEST2
------------------------------------------------
set policy route TEST2 rule 10 destination address '1.1.1.2'
set policy route TEST2 rule 10 destination port '1000'
set policy route TEST2 rule 10 protocol 'tcp'
set policy route TEST2 rule 10 source address '1.1.1.1'
set policy route TEST2 rule 10 source port '1'
1 Like

Hmmm. Especially when debugging, there could be a world of difference between what’s in the config (intended) versus what is active (actual).

For NAT, what about parsing output of nft list table nat?

Can be a bit tricky though, especially with WAN load balancing in place.

I was approaching this from an operational standpoint and never considered the debugging use case.

The entire script is parsing nft already, and only printing when matching on what is in the actual table. The JSON that NFT spits out is very hard to work with.

{'rule': {'family': 'ip', 'table': 'vyos_filter', 'chain': 'VYOS_FORWARD_filter', 'handle': 25, 'comment': 'ipv4-FWD-filter-1234', 'expr': [{'match': {'op': '==', 'left': {'payload': {'protocol': 'ip', 'field': 'daddr'}}, 'right': '1.1.1.2'}}, {'match': {'op': '==', 'left': {'payload': {'protocol': 'tcp', 'field': 'dport'}}, 'right': '@P_P1000'}}, {'match': {'op': '==', 'left': {'payload': {'protocol': 'ip', 'field': 'saddr'}}, 'right': '1.1.1.1'}}, {'match': {'op': '==', 'left': {'payload': {'protocol': 'tcp', 'field': 'sport'}}, 'right': 1}}, {'match': {'op': '==', 'left': {'meta': {'key': 'iifname'}}, 'right': 'eth1'}}, {'match': {'op': '==', 'left': {'meta': {'key': 'oifname'}}, 'right': 'eth2'}}, {'counter': {'packets': 0, 'bytes': 0}}, {'accept': None}]}}

I parse that output into something that is easier to work with later:

{'source_ip': '1.1.1.1', 'destination_ip': '1.1.1.2', 'source_port': 1, 'destination_port': '@P_P1000', 'action': 'accept', 'comment': 'ipv4-FWD-filter-1234', 'protocols': ['ip', 'tcp'], 'iifname': 'eth1', 'oifname': 'eth2'}

I can have it store some additional values (family/table/chain/handle) that would make calling that specific rule later easy:

{'source_ip': '1.1.1.1', 'destination_ip': '1.1.1.2', 'source_port': 1, 'destination_port': '@P_P1000', 'action': 'accept', 'comment': 'ipv4-FWD-filter-1234', 'protocols': ['ip', 'tcp'], 'iifname': 'eth1', 'oifname': 'eth2', 'family': 'ip', 'table': 'vyos_filter', 'chain': 'VYOS_FORWARD_filter', 'handle': 25}

Here’s what it looks like after that change:

vyos@vyos# run show firewall packet-info source-ip 1.1.1.1 destination-ip 1.1.1.2 source-port 1 destination-port 1000 protocol tcp
------------------------------------------------
--------------- Phase 1: Routing ---------------
------------------------------------------------

Source:
 Route             | 0.0.0.0/0
 Protocol          | static
 VRF               | default
 Next Hop(s)       | 10.0.101.1
 Exit Interface(s) | eth0.101

Destination:
 Route             | 0.0.0.0/0
 Protocol          | static
 VRF               | default
 Next Hop(s)       | 10.0.101.1
 Exit Interface(s) | eth0.101

------------------------------------------------
----------------- Phase 2: NAT -----------------
------------------------------------------------

Source NAT matched on rule 100
------------------------------------------------
Configured:
set nat source rule 100 destination address '1.1.1.2'
set nat source rule 100 destination port '1000'
set nat source rule 100 outbound-interface name 'eth2'
set nat source rule 100 protocol 'tcp'
set nat source rule 100 source address '1.1.1.1'
set nat source rule 100 source port '1'
set nat source rule 100 translation address 'masquerade'

--------------------------------
Active Rule:
oifname "eth2" ip saddr 1.1.1.1 tcp sport 1 tcp dport 1000 ip daddr 1.1.1.2 counter packets 0 bytes 0 masquerade

------------------------------------------------
--------------- Phase 3: Firewall --------------
------------------------------------------------

Matching Rule Found:
Rule Information

---------------------------------
ipv4 Firewall "forward filter"

 Rule        | 1234
 Description |
 Action      | accept
 Protocol    | tcp
 Packets     | 0
 Bytes       | 0
 Conditions  | ip daddr 1.1.1.2 tcp dport @P_P1000 ip saddr 1.1.1.1 tcp sport 1
             | iifname "eth1" oifname "eth2"  accept

------------------------------------------------
----------------- Phase 4: PBR -----------------
------------------------------------------------

Policy Route matched on rule 10 of policy route TEST2
------------------------------------------------
Configured:
set policy route TEST2 rule 10 destination address '1.1.1.2'
set policy route TEST2 rule 10 destination port '1000'
set policy route TEST2 rule 10 protocol 'tcp'
set policy route TEST2 rule 10 source address '1.1.1.1'
set policy route TEST2 rule 10 source port '1'

--------------------------------
Active Rule:
ip daddr 1.1.1.2 ip saddr 1.1.1.1 tcp sport 1 tcp dport 1000 counter packets 0 bytes 0 return

By any chance, do you have a task on vyos.dev for that?
Looks very nice!
Thanks for investing time into this!

1 Like

I haven’t yet. I was waiting until I was closer to a PR to create one. I can create one if you want.

It´s up to you.
think it will give more audience and hopefully more valuable inputs

Yeah, that’s a good point!

Task added: ⚓ T6236 Packet-Tracer Output

3 Likes

Not sure if it is related to the packet flow but policing happens before routing :slight_smile:
NAT could be PRE or POST routing
And a ton of other nuances. Like routing without route table routes, I mean “policy based vpn” :wink:

1 Like