Date created: Monday, June 22, 2026 2:48:53 PM. Last modified: Tuesday, June 23, 2026 2:30:51 PM
7280R3 - diag packet tx
Overview
Inject a custom packet into the ASIC and capture the lookup and result to understand the decision the ASIC makes when processing such a packet.
Setup
Two interfaces are physically looped together for testing, a packet will be injected into Eth12 and we should see it come out of Eth11:
conf t vrf instance LAB-DFZ-TEST description - LAB-DFZ-TEST exit ip routing vrf LAB-DFZ-TEST ipv6 unicast-routing vrf LAB-DFZ-TEST interface Ethernet11 link-debounce time 1000 0 no switchport vrf LAB-DFZ-TEST ip address 10.11.12.0/31 no lldp transmit no lldp receive no loop-protection no mpls ip transceiver media override 10gbase-lr exit interface Ethernet12 link-debounce time 1000 0 no switchport vrf LAB-DFZ-TEST ip address 10.11.12.2/31 no lldp transmit no lldp receive no loop-protection no mpls ip transceiver media override 10gbase-lr exit
Create static ARP entries so that the ASIC has everything it needs to forward an incoming packet from Ethernet11 to Ethernet12:
conf t
! Target MAC
arp vrf LAB-DFZ-TEST 10.11.12.1 aaaa.bbbb.cccc arpa
! Source MAC
arp vrf LAB-DFZ-TEST 10.11.12.3 1122.3344.5566 arpa
#show ip route vrf LAB-DFZ-TEST 10.11.12.0/24 longer-prefixes | beg /
C 10.11.12.0/31
directly connected, Ethernet11
C 10.11.12.2/31
directly connected, Ethernet12
#show ip arp vrf LAB-DFZ-TEST
Legend:
not learned: Associated MAC address is not present in the MAC address table
-: Static (configuration or programmed by feature)
Address Age (sec) Hardware Addr Interface
10.11.12.1 - aaaa.bbbb.cccc Ethernet11
10.11.12.3 - 0022.3344.5566 Ethernet12
Capture packets going out of Ethernet11 and verify that it's the packet being injected into Ethernet12:
conf t
monitor session j1 source Ethernet11 tx
monitor session j1 destination Cpu
# bash tcpdump -i mirror0 -w /dev/null -v
Inject and Capture
We need to get the fap port IDs for Ethernet11 and Ethernet12 (which are 118 and 119 below, respectively).
We want to send a packet into the ASIC as if it came into that port, we don't send a packet out of that physical port on to the wire, so we use the Fap port ID to tell the ASIC the source port the packet was received on, so that it is processed in the context of that ingress port:.
#show platform jericho2 mapping interface Ethernet 11-12 Fap0 (FapId: 0 BaseSystemCoreId: 0) Port SysPhyPort Voq Core FapPort OtmPort BaseQPair QPairs Xlge NifPort Qsgmii Serdes -------------------------------------------------------------------------------------------------------------------------- Ethernet11 119 776 0 118 118 128 8 - 110 - (110) Ethernet12 120 784 0 119 119 136 8 - 111 - (111) #platform jericho2 diag port status 118-119 Fap0 diag port status 118-119: ========================================================================= | Port status | ========================================================================= | Port | Ena/Link | Speed | Linkscan | Autoneg | FEC | Loopback | ========================================================================= | eth118(118) | up | 10G | None | No | NONE | NONE | | eth119(119) | up | 10G | None | No | NONE | NONE | =========================================================================
Now with the port IDs we can inject a packet into Ethernet12 using "platform jericho2 diag packet tx", this command has the following description:
#platform jericho2 diag packet tx help
Fap0 diag packet tx help:
SYNOPSISESC
PacKeT TX [DATA=<...>] [raw[=no]] [show[=no]] [port=<...>] [resume[=no]] [packet=<...>] [rx[=no]]
[size=<...>] [duration=<...>] [unit=<...>] [rate=<...>] [burst=<...>] [granularity=<...>] [sat[=no]]
DESCRIPTION
Send packet to the pipeline, providing list of protocols, that should compose it. There are default values
for each field in the header. Assign values for the ones that need to be different right after the protocol
name
ARGUMENTS
Argument (type:default) - description
DaTa (string:EMPTY) - String representing packet to be send
RAW (boolean:No) - Transmit composed packet from DATA
SHOW (boolean:No) - Show full packet content
Port (int32:201) - Use specific source logical port
ReSuMe (boolean:Yes) - Triggers signals cache clearance
PacKeT (string:EMPTY) - Allows sand packet from xml case
RX (boolean:No) - Record received packets
SiZe (uint32:0) - Packet Size(bytes)
DURation (uint32:-1) - Stream Duration(seconds)
UNIT (enum:kbits) - Rate units
Available Values
kbits - If set gtf rate is configured in kilobits per second
packets - If set gtf rate is configured in packets per second
RATE (uint32:0) - Stream Rate(kbits or packets per sec)
BURST (uint32:0) - Stream Burst(bytes)
GRaNuLarity (uint32:-1) - Clocks per cycle - set globally
SAT (boolean:No) - Generate SAT stream from the core of src_port
EXAMPLES
PacKeT TX PTCH_2 ETH1 IPv4 show resume=NO
PacKeT TX packet=simple rx
PacKeT TX packet=default sat port=1
PacKeT TX packet=default port=218 size=256 rate=10000 burst=10000 dur=1 unit=kbits
PacKeT TX pkt=sat
PacKeT TX packet=default sat port=1 duration=0 grnl=1000
PacKeT TX port=200 PTCH_2 PTCH_2.PP_SSP=27 ETH1 MPLS BIER IPv4
PacKeT TX PTCH_2 ETH1 ETH1.da=00:FF:EE:DD:DD:BB MPLS MPLS.Label=256 IPv6
PacKeT TX raw DATA=0x80c90000000000010000000000028100000108004500002e0000000040ff79d20000000000000000000102030405060708090a0b0c0d0e0f1011
PacKeT TX pkt=default
PacKeT TX pkt=mpls_ipv4
We can either parse the raw hex of a packet to send any packet we want, or specify the packet headers by name and their values (we can only specify values for the headers that are supported by the command, so less flexible but more user friendly).
Use "platform jericho2 diag packet list" to see packet headers that can be used to compose packets. This shows us the protocol names, but not the names of the header fields of each protocol.
Use "platform fap diag sig structure" to see the header field names for each protocol, their size, and data type.
The output of both commands can be seen here.
This is the packet we want to sent into Eth12:
- We need to specify the PTCH_2 header values for the injected packet (give it a fake source port)
- The IPv4 length is not auto calculated and needs to be specified
- The UDP length is not auto calculated and needs to be specified
- A fake UDP payload is added here
#platform jericho2 diag packet compose PTCH_2 PTCH_2.PP_SSP=119 ETH0 ETH0.da=e8:ae:c5:29:36:45 ETH0.sa=00:22:33:44:55:66 ipv4 ipv4.sip=10.11.12.3 ipv4.dip=10.11.12.1 ipv4.ttl=17 ipv4.Total_Length=32 udp udp.Src_Port=43690 udp.Dst_Port=43690 udp.Length=8 UDH_DATA_0 UDH_DATA_0.Value=0xAABBCCDD Fap0 diag packet compose PTCH_2 PTCH_2.PP_SSP=119 ETH0 ETH0.da=e8:ae:c5:29:36:45 ETH0.sa=00:22:33:44:55:66 ipv4 ipv4.sip=10.11.12.3 ipv4.dip=10.11.12.1 ipv4.ttl=17 ipv4.Total_Length=32 udp udp.Src_Port=43690 udp.Dst_Port=43690 udp.Length=8 UDH_DATA_0 UDH_DATA_0.Value=0xAABBCCDD: ====================================================== | Packet final headers and fields | | Size = 384 bits | ====================================================== | Header | Field | Value | ====================================================== | PTCH_2 | PTCH_2.PP_SSP | 119 | ------------------------------------------------------ | ETH0 | ETH0.da | e8:ae:c5:29:36:45 | | | ETH0.sa | 00:22:33:44:55:66 | | | ETH0.Type | 0x800 | ------------------------------------------------------ | IPv4 | ipv4.sip | 10.11.12.3 | | | ipv4.dip | 10.11.12.1 | | | ipv4.ttl | 17 | | | ipv4.Total_Length | 32 | | | IPv4.Protocol | 0x11 | | | IPv4.Checksum | 0x7db4 | ------------------------------------------------------ | UDP | udp.Src_Port | 43690 | | | udp.Dst_Port | 43690 | | | udp.Length | 8 | ------------------------------------------------------ | UDH_DATA_0 | UDH_DATA_0.Value | 0xAABBCCDD | ====================================================== String for tx: 0x8077e8aec52936450022334455660800450000200000000011117db40a0b0c030a0b0c01aaaaaaaa00080000aabbccdd
We can parse a raw hex string of a packet to see it be re-parsed into the header and field names (strip the first type bytes, 0x8077, which are for the PTCH_2 header, before parsing):
#platform jericho2 diag packet decode ETH=0xe8aec52936450022334455660800450000200000000011117db40a0b0c030a0b0c01aaaaaaaa00080000aabbccdd Fap0 diag packet decode ETH=0xe8aec52936450022334455660800450000200000000011117db40a0b0c030a0b0c01aaaaaaaa00080000aabbccdd: ======================================================================= | Parsing Results | | Total headers stack size: 42B | ======================================================================= | Object | Value | Size | ======================================================================= | ETH0 | e8aec52936450022334455660800 | 112b | | DA | E8:AE:C5:29:36:45 | 48b | | SA | 00:22:33:44:55:66 | 48b | | Type | IPv4(0x800) | 16b | ----------------------------------------------------------------------- | IPv4 | 450000200000000011117db40a0b0c030a0b0c01 | 160b | | Version | 04 | 4b | | IHL | 05 | 4b | | TOS | 00 | 8b | | DSCP | 00 | 6b | | ECN | 00 | 2b | | Total_Length | 0020 | 16b | | Identification | 0000 | 16b | | Flags | 00 | 3b | | Fragment_Offset | 0000 | 13b | | TTL | 11 | 8b | | Protocol | 11 | 8b | | Checksum | 7db4 | 16b | | SIP | 10.11.12.3 | 32b | | DIP | 10.11.12.1 | 32b | ----------------------------------------------------------------------- | UDP | aaaaaaaa00080000 | 64b | | Src_Port | aaaa | 16b | | Dst_Port | aaaa | 16b | | Length | 0008 | 16b | | Checksum | 0000 | 16b | =======================================================================
Trying to inject either a single packet or a stream of packets using raw hex doesn't seem to work well, one packet is sent and then the tool hangs. It should then restart after a while or you can kill it with:
sudo kill $(ps aux | grep SandFapNi-FixedSystem | grep root | awk '{print $2}')
This approach is only good in the lab though because it causes the ASIC to briefly flap so it's service impacting.
Specifying a packet by it's headers and values works fine as long as a stream is used, again, trying to send a single packet causes the tool to hang and requires a kill to recover (or sometimes it auto restarts after a minute or two).
Start a stream of packets being injected into Ethernet12, at a rate of 1000 packets per second, for 1 second (note we don't need to specify the packet source port ID in the PTCH_2):
#platform jericho2 diag packet tx port=119 sat rate=1 dur=1 PTCH_2 ETH0 ETH0.da=e8:ae:c5:29:36:45 ETH0.sa=00:22:33:44:55:66 ipv4 ipv4.sip=10.11.12.3 ipv4.dip=10.11.12.1 ipv4.ttl=17 ipv4.Total_Length=32 udp udp.Src_Port=43690 udp.Dst_Port=43690 udp.Length=8 UDH_DATA_0 UDH_DATA_0.Value=0xAABBCCDD
View active streams:
#platform jericho2 diag packet show Fap0 diag packet show: ============================================ | Active SAT Streams | ============================================ | Stream ID | GTF ID | Core | Rate | Burst | ============================================ | 1 | 0 | 0 | 1 | 1000 | ============================================
If sending a longer duration stream, you can stop it with (if using a 1 second duration the stream will stop itself after 1 second):
#platform jericho2 diag packet stop
The monitor session shows the packet being sent out of Ethernet11 (not sure why it's been padded?):
#bash tcpdump -i mirror0 -nlaSXev -s 0
tcpdump: listening on mirror0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:38:53.996541 e8:ae:c5:29:36:45 > aa:aa:bb:bb:cc:cc, ethertype IPv4 (0x0800), length 126: (tos 0x0, ttl 16, id 0, offset 0, flags [none], proto UDP (17), length 32)
10.11.12.3.43690 > 10.11.12.1.43690: UDP, length 0
0x0000: 4500 0020 0000 0000 1011 7eb4 0a0b 0c03 E.........~.....
0x0010: 0a0b 0c01 aaaa aaaa 0008 0000 aabb ccdd ................
0x0020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0030: 0102 0304 0102 0304 0102 0304 0102 0304 ................
0x0040: 0102 0304 0102 0304 0102 0304 0102 0304 ................
0x0050: 0102 0304 0102 0304 0102 0304 0102 0304 ................
0x0060: 0102 0304 0102 0304 0102 0304 0102 0304 ................
...
^C
971 packets captured
971 packets received by filter
0 packets dropped by kernel
In order to capture the thoughts and feelings of the ASIC pipeline, start a longer running stream, and then run the following command to capture the signals from all stages and all blocks of all stages.
The "visibility" feature of the FAP diagnostics allows us to see the signals from the stages in the pipeline as a packet is being processed, but it's returning the output for the last packet process, which could be any packet.
Therefore, in a lab scenario at least, with minimal background traffic, starting a stream of packets being injected into the ASIC and then running the following command a few times will show the signals for the packet we are injecting into Ethernet12 as it goes through the pipeline.
Dump output from all stages: #platform fap diag sig get all
It's possible to see all blocks and stages with: #platform fap diag sig stage
Then one can limit the output as needed:
#platform fap diag sig get block=IRPP name=Fwd_Action_Dst
#platform fap diag sig get block=ITPP name=PACKET_SIZE
#platform fap diag sig get block=ETPP core=0 name=PPH_Fwd_Domain
#platform fap diag sig get block=ETPP core=0 name=Context
#platform fap diag sig get block=IRPP name=Fwd_Domain_ID from=FWD1 to=FWD2
Improvements
It is possible to capture the signals for exactly the packet we want, but I haven't quite got it working yet.
The idea is to switch to "select" mode for the visibility:
#platform fap diag vis global Fap0 diag vis global: Visibility Mode Always Visibility PRT Qualifier 2 #platform fap diag vis global mode=select #platform fap diag vis global Fap0 diag vis global: Visibility Mode Select Visibility PRT Qualifier 2
Enable visibility for the ports we are interested in:
# platform fap diag vis port name=eth118-119 direction=both enable=on force=on #platform fap diag vis port eth118-119 Fap0 diag vis port eth118-119: ============================================================================== | Visibility Status Per Port | ============================================================================== | Name | PP | PP | Type | Core | Ingress | Ingress | Egress | Egress | | | Port | DSP | | | Enable | Force | Enable | Force | ============================================================================== | eth118 | 118 | 118 | NIF_ETH | 0 | 1 | 0 | 1 | 0 | | eth119 | 119 | 119 | NIF_ETH | 0 | 1 | 0 | 1 | 0 | ==============================================================================
Clear the visibility cache:
# platform fap diag vis resume direction=both zero
Send the packet(s):
#platform jericho2 diag packet tx port=119 sat rate=1 dur=1 ...
Capture the signals:
# platform fap diag sig get all
Then restore the visibility mode:
#platform fap diag vis global mode=always
Previous page: Traffic Policy Match Statements
Next page: 7280R3 - Finding Packet Loss