Nathan Skrzypczak | 9ad39c0 | 2021-08-19 11:38:06 +0200 | [diff] [blame] | 1 | Using vpptrace.sh for VPP Packet Tracing |
| 2 | ======================================== |
| 3 | |
| 4 | VPP allows tracing of incoming packets using CLI commands ``trace add`` |
| 5 | and ``show trace`` as explained [here](VPP_PACKET_TRACING_K8S.html), but |
| 6 | it is a rather cumbersome process. |
| 7 | |
| 8 | The buffer for captured packets is limited in size, and once it gets |
| 9 | full the tracing stops. The user has to manually clear the buffer |
| 10 | content, and then repeat the trace command to resume the packet capture, |
| 11 | losing information about all packets received in the meantime. |
| 12 | |
| 13 | Packet filtering exposed via the CLI command ``trace filter`` is also |
| 14 | quite limited in what it can do. Currently there is just one available |
| 15 | filter, which allows you to keep only packets that include a certain |
| 16 | node in the trace or exclude a certain node in the trace. It is not |
| 17 | possible to filter the traffic by its content (e.g., by the |
| 18 | source/destination IP address, protocol, etc.). |
| 19 | |
| 20 | Last but not least, it is not possible to trace packets on a selected |
| 21 | interface like ``tcpdump``, which allows tracing via the option ``-i``. |
| 22 | VPP is only able to capture packets on the *RX side* of selected |
| 23 | *devices* (e.g., dpdk, virtio, af-packet). This means that interfaces |
| 24 | based on the same device cannot be traced for incoming packets |
| 25 | individually, but only all at the same time. In Contiv/VPP all pods are |
| 26 | connected with VPP via the same kind of the TAP interface, meaning that |
| 27 | it is not possible to capture packets incoming only from one selected |
| 28 | pod. |
| 29 | |
| 30 | Contiv/VPP ships with a simple bash script |
| 31 | `vpptrace.sh <https://github.com/contiv/vpp/blob/master/scripts/vpptrace.sh>`__, |
| 32 | which helps alleviate the aforementioned VPP limitations. The script |
| 33 | automatically re-initializes buffers and traces whenever it is close to |
| 34 | getting full, in order to avoid packet loss as much as possible. Next it |
| 35 | allows you to filter packets by the content of the trace. There are two |
| 36 | modes of filtering: - *substring mode* (default): packet trace must |
| 37 | contain a given sub-string in order to be included in the output - |
| 38 | *regex mode*: packet trace must match a given regex in order to be |
| 39 | printed |
| 40 | |
| 41 | The script is still limited, in that capture runs only on the RX side of |
| 42 | all interfaces that are built on top of selected devices. Using |
| 43 | filtering, however, it is possible to limit *traffic by interface* |
| 44 | simply by using the interface name as a substring to match against. |
| 45 | |
| 46 | Usage |
| 47 | ----- |
| 48 | |
| 49 | Run the script with option ``-h`` to get the usage printed: |
| 50 | |
| 51 | :: |
| 52 | |
| 53 | Usage: ./vpptrace.sh [-i <VPP-IF-TYPE>]... [-a <VPP-ADDRESS>] [-r] [-f <REGEXP> / <SUBSTRING>] |
| 54 | -i <VPP-IF-TYPE> : VPP interface *type* to run the packet capture on (e.g., dpdk-input, virtio-input, etc.) |
| 55 | - available aliases: |
| 56 | - af-packet-input: afpacket, af-packet, veth |
| 57 | - virtio-input: tap (version determined from the VPP runtime config), tap2, tapv2 |
| 58 | - tapcli-rx: tap (version determined from the VPP config), tap1, tapv1 |
| 59 | - dpdk-input: dpdk, gbe, phys* |
| 60 | - multiple interfaces can be watched at the same time - the option can be repeated with |
| 61 | different values |
| 62 | - default = dpdk + tap |
| 63 | -a <VPP-ADDRESS> : IP address or hostname of the VPP to capture packets from |
| 64 | - not supported if VPP listens on a UNIX domain socket |
| 65 | - default = 127.0.0.1 |
| 66 | -r : apply filter string (passed with -f) as a regexp expression |
| 67 | - by default the filter is NOT treated as regexp |
| 68 | -f : filter string that packet must contain (without -r) or match as regexp (with -r) to be printed |
| 69 | - default is no filtering |
| 70 | |
| 71 | ``VPP-IF-TYPE`` is a repeated option used to select the set of devices |
| 72 | (e.g., virtio, dpdk, etc.) to capture the incoming traffic. Script |
| 73 | provides multiple aliases, which are much easier to remember than the |
| 74 | device names. For ``dpdk-input`` one can enter just ``dpdk``, or |
| 75 | anything starting with ``phys``, etc. For TAPs, the script is even smart |
| 76 | enough to find out the TAP version used, which allows to enter just |
| 77 | ``tap`` as the device name. |
| 78 | |
| 79 | If ``VPP-IF-TYPE`` is not specified, then the default behaviour is to |
| 80 | capture from both ``dpdk`` (traffic entering the node from outside) and |
| 81 | ``tap`` (preferred interface type for pod-VPP and host-VPP |
| 82 | interconnection, receiving node-initiated traffic). |
| 83 | |
| 84 | vpptrace.sh can capture packets even from a VPP on a different host, |
| 85 | provided that VPP-CLI listens on a port, and not on a UNIX domain socket |
| 86 | (for security reasons IPC is the default communication link, see |
| 87 | ``/etc/vpp/contiv-vswitch.conf``). Enter the destination node IP address |
| 88 | via the option ``-a``\ (localhost is the default). |
| 89 | |
| 90 | The capture can be filtered via the ``-f`` option. The output will |
| 91 | include only packets whose trace matches contain the given |
| 92 | expression/sub-string. |
| 93 | |
| 94 | Option ``-r`` enables the regex mode for filtering. |
| 95 | |
| 96 | Examples |
| 97 | -------- |
| 98 | |
| 99 | - Capture all packets entering VPP via ``tapcli-1`` interface **AND** |
| 100 | all packets leaving VPP via ``tapcli-1`` that were sent from a pod, |
| 101 | or the host on the *same node* (sent from tap, not Gbe): |
| 102 | |
| 103 | :: |
| 104 | |
| 105 | $ vpptrace.sh -i tap -f "tapcli-1" |
| 106 | |
| 107 | - Capture all packets with source or destination IP address 10.1.1.3: |
| 108 | |
| 109 | :: |
| 110 | |
| 111 | $ vpptrace.sh -i tap -i dpdk -f "10.1.1.3" |
| 112 | |
| 113 | Or just: |
| 114 | $ vpptrace.sh "10.1.1.3" |
| 115 | |
| 116 | - Capture all SYN-ACKs received from outside: |
| 117 | |
| 118 | :: |
| 119 | |
| 120 | $ vpptrace.sh -i dpdk -f "SYN-ACK" |