sonic-net / sonic-mgmt

Configuration management examples for SONiC
Other
196 stars 720 forks source link

ptf_nn_agent unable to capture packets with vlan tag #1343

Closed mykolaf closed 4 years ago

mykolaf commented 4 years ago

Description When running traffic test (written in pytest) using ptf_nn_agent infrastructure, any test involving vlan tagging will fail. The cause for that that the RAW socket strips the vlan tag automatically. There was a similar issue with arp_responder I believe ( #1201 ).

Steps to reproduce the issue:

  1. Configure vlan.
  2. Send tagged packet.
  3. Expect tagged packet to be received on ptf port. testutils.verify_packet(ptfadapter, tagged_pkt, ptf_port_num)

Describe the results you received:

*** AssertionError: Did not receive expected packets on port 30 for device 0.
========== EXPECTED ==========
dst        : DestMACField         = 'ff:ff:ff:ff:ff:ff' (None)
src        : SourceMACField       = '00:22:00:00:00:02' (None)
type       : XShortEnumField      = 33024           (0)
--
prio       : BitField             = 0               (0)
id         : BitField             = 0               (0)
vlan       : BitField             = 100             (1)
type       : XShortEnumField      = 2048            (0)
--
version    : BitField             = 4               (4)
ihl        : BitField             = None            (None)
tos        : XByteField           = 0               (0)
len        : ShortField           = None            (None)
id         : ShortField           = 1               (1)
flags      : FlagsField           = 0               (0)
frag       : BitField             = 0               (0)
ttl        : ByteField            = 64              (64)
proto      : ByteEnumField        = 1               (0)
chksum     : XShortField          = None            (None)
src        : Emph                 = '192.168.0.1'   (None)
dst        : Emph                 = '192.168.0.2'   ('127.0.0.1')
options    : PacketListField      = []              ([])
--
type       : ByteEnumField        = 8               (8)
code       : MultiEnumField       = 0               (0)
chksum     : XShortField          = None            (None)
id         : ConditionalField     = 0               (0)
seq        : ConditionalField     = 0               (0)
ts_ori     : ConditionalField     = 32407470        (32407470)
ts_rx      : ConditionalField     = 32407470        (32407470)
ts_tx      : ConditionalField     = 32407470        (32407470)
gw         : ConditionalField     = '0.0.0.0'       ('0.0.0.0')
ptr        : ConditionalField     = 0               (0)
reserved   : ConditionalField     = 0               (0)
addr_mask  : ConditionalField     = '0.0.0.0'       ('0.0.0.0')
unused     : ConditionalField     = 0               (0)
--
load       : StrField             = ''              ('')
--
load       : StrField             = '0000000000000000000000000000000000000000000000000000000000' ('')
--
0000   FF FF FF FF FF FF 00 22  00 00 00 02 81 00 00 64   .......".......d
0010   08 00 45 00 00 56 00 01  00 00 40 01 F9 52 C0 A8   ..E..V....@..R..
0020   00 01 C0 A8 00 02 08 00  82 8A 00 00 00 00 30 30   ..............00
0030   30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30   0000000000000000
0040   30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30   0000000000000000
0050   30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30   0000000000000000
0060   30 30 30 30 30 30 30 30                            00000000
========== RECEIVED ==========
3 total packets. Displaying most recent 3 packets:
------------------------------
. . .
------------------------------
dst        : DestMACField         = 'ff:ff:ff:ff:ff:ff' (None)
src        : SourceMACField       = '00:22:00:00:00:02' (None)
type       : XShortEnumField      = 2048            (0)
--
version    : BitField             = 4L              (4)
ihl        : BitField             = 5L              (None)
tos        : XByteField           = 0               (0)
len        : ShortField           = 86              (None)
id         : ShortField           = 1               (1)
flags      : FlagsField           = 0L              (0)
frag       : BitField             = 0L              (0)
ttl        : ByteField            = 64              (64)
proto      : ByteEnumField        = 1               (0)
chksum     : XShortField          = 63826           (None)
src        : Emph                 = '192.168.0.1'   (None)
dst        : Emph                 = '192.168.0.2'   ('127.0.0.1')
options    : PacketListField      = []              ([])
--
type       : ByteEnumField        = 8               (8)
code       : MultiEnumField       = 0               (0)
chksum     : XShortField          = 33418           (None)
id         : ConditionalField     = 0               (0)
seq        : ConditionalField     = 0               (0)
ts_ori     : ConditionalField     = None            (32407470)
ts_rx      : ConditionalField     = None            (32407470)
ts_tx      : ConditionalField     = None            (32407470)
gw         : ConditionalField     = None            ('0.0.0.0')
ptr        : ConditionalField     = None            (0)
reserved   : ConditionalField     = None            (0)
addr_mask  : ConditionalField     = None            ('0.0.0.0')
unused     : ConditionalField     = None            (0)
--
load       : StrField             = '0000000000000000000000000000000000000000000000000000000000' ('')
--
0000   FF FF FF FF FF FF 00 22  00 00 00 02 08 00 45 00   ......."......E.
0010   00 56 00 01 00 00 40 01  F9 52 C0 A8 00 01 C0 A8   .V....@..R......
0020   00 02 08 00 82 8A 00 00  00 00 30 30 30 30 30 30   ..........000000
0030   30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30   0000000000000000
0040   30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30   0000000000000000
0050   30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30   0000000000000000
0060   30 30 30 30                                        0000
==============================

At the same time I capture the packet with the tag on ptf interface with tcpdump -e icmp -vvv -i eth5

Describe the results you expected:

The ptf_nn_agent receives the packet with the vlan tag, so that the testutils.verify_packet() can match it.

Additional information you deem important:

**Output of `show version`:**

```
(paste your output here)
```

**Attach debug file `sudo generate_dump`:**

```
(paste your output here)
```
volodymyrsamotiy commented 4 years ago

Issue is observed due to RAW socket used by ptf_nn_agent module for sending/receiving packets. It happens because Linux kernel does VLAN offloading on receiving packets and stores the tag in a different place. In order to fetch VLAN tag additional logic is required or PCAP library can be used. ptf already uses such approach for ptf dataplane implementation and looks like the same should be done for ptf_nn_agent.

Implementation of fetching VLAN tag is here: https://github.com/p4lang/ptf/blob/master/src/ptf/afpacket.py#L112

Below is example of using above approach: https://github.com/p4lang/ptf/blob/master/src/ptf/dataplane.py#L163

ptf_nn_agent module is part of ptf repository and sonic-buildimage just downloads it, so it should be properly fixed in ptf repository. ptf_nn_agent itself is located here: https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py

Also below is example how it is downloaded in SONiC PTF docker image: https://github.com/Azure/sonic-buildimage/blob/master/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2#L51

mykolaf commented 4 years ago

Should be fixed by #109