Add a note on MAC addresses and an af-packet trace to show end to end
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-05-03 18:45:20 +02:00
parent 8918821413
commit 7d3f617966

View File

@ -248,10 +248,32 @@ eth1@if530577 UP 02:42:c0:00:02:02 <BROADCAST,MULTICAST,UP,LOWER_
``` ```
One of the many awesome features of VPP is its ability to attach to these `veth` devices by means of One of the many awesome features of VPP is its ability to attach to these `veth` devices by means of
its `af-packet` driver. I first take a look at the linux its `af-packet` driver, by reusing the same MAC address (in this case `02:42:c0:00:02:02`). I first
[[manpage](https://man7.org/linux/man-pages/man7/packet.7.html)] for it, and then read up on the VPP take a look at the linux [[manpage](https://man7.org/linux/man-pages/man7/packet.7.html)] for it,
and then read up on the VPP
[[documentation](https://fd.io/docs/vpp/v2101/gettingstarted/progressivevpp/interface)] on the [[documentation](https://fd.io/docs/vpp/v2101/gettingstarted/progressivevpp/interface)] on the
topic. Armed with this knowledge, I can bind the container-side veth pair called `eth1` to VPP, like topic.
However, my attention is drawn to Docker assigning an IPv4 and IPv6 address to the container:
```
root@d57c3716eee9:/# ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0@if530566 UP 172.17.0.2/16
eth1@if530577 UP 192.0.2.2/24 2001:db8::2/64 fe80::42:c0ff:fe00:202/64
root@d57c3716eee9:/# ip addr del 192.0.2.2/24 dev eth1
root@d57c3716eee9:/# ip addr del 2001:db8::2/64 dev eth1
```
I decide to remove them from here, as in the end, `eth1` will be owned by VPP so _it_ should be
setting the IPv4 and IPv6 addresses. For the life of me, I don't see how I can avoid Docker from
assinging IPv4 and IPv6 addresses to this container ... and the
[[docs](https://docs.docker.com/engine/network/)] seem to be off as well, as they suggest I can pass
a flagg `--ipv4=False` but that flag doesn't exist, at least not on my Bookworm Docker variant. I
make a mental note to discuss this with the folks in the Containerlab community.
Anyway, armed with this knowledge I can bind the container-side veth pair called `eth1` to VPP, like
so: so:
``` ```
@ -261,7 +283,7 @@ root@d57c3716eee9:/# vppctl
_/ _// // / / / _ \ | |/ / ___/ ___/ _/ _// // / / / _ \ | |/ / ___/ ___/
/_/ /____(_)_/\___/ |___/_/ /_/ /_/ /____(_)_/\___/ |___/_/ /_/
vpp-clab# create host-interface v2 name eth1 vpp-clab# create host-interface name eth1 hw-addr 02:42:c0:00:02:02
vpp-clab# set interface name host-eth1 eth1 vpp-clab# set interface name host-eth1 eth1
vpp-clab# set interface mtu 1500 eth1 vpp-clab# set interface mtu 1500 eth1
vpp-clab# set interface ip address eth1 192.0.2.2/24 vpp-clab# set interface ip address eth1 192.0.2.2/24
@ -304,6 +326,105 @@ PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.
5 packets transmitted, 5 received, 0% packet loss, time 4063ms 5 packets transmitted, 5 received, 0% packet loss, time 4063ms
rtt min/avg/max/mdev = 0.019/0.032/0.043/0.008 ms rtt min/avg/max/mdev = 0.019/0.032/0.043/0.008 ms
``` ```
And in case that simple ping-test wasn't enough to get you excited, here's a packet trace from VPP
itself, while I'm performing this ping:
```
vpp-clab# trace add af-packet-input 100
vpp-clab# wait 3
vpp-clab# show trace
------------------- Start of thread 0 vpp_main -------------------
Packet 1
00:07:03:979275: af-packet-input
af_packet: hw_if_index 1 rx-queue 0 next-index 4
block 47:
address 0x7fbf23b7d000 version 2 seq_num 48 pkt_num 0
tpacket3_hdr:
status 0x20000001 len 98 snaplen 98 mac 92 net 106
sec 0x68164381 nsec 0x258e7659 vlan 0 vlan_tpid 0
vnet-hdr:
flags 0x00 gso_type 0x00 hdr_len 0
gso_size 0 csum_start 0 csum_offset 0
00:07:03:979293: ethernet-input
IP4: 02:42:09:97:28:c6 -> 02:42:c0:00:02:02
00:07:03:979306: ip4-input
ICMP: 192.0.2.1 -> 192.0.2.2
tos 0x00, ttl 64, length 84, checksum 0x5e92 dscp CS0 ecn NON_ECN
fragment id 0x5813, flags DONT_FRAGMENT
ICMP echo_request checksum 0xc16 id 21197
00:07:03:979315: ip4-lookup
fib 0 dpo-idx 9 flow hash: 0x00000000
ICMP: 192.0.2.1 -> 192.0.2.2
tos 0x00, ttl 64, length 84, checksum 0x5e92 dscp CS0 ecn NON_ECN
fragment id 0x5813, flags DONT_FRAGMENT
ICMP echo_request checksum 0xc16 id 21197
00:07:03:979322: ip4-receive
fib:0 adj:9 flow:0x00000000
ICMP: 192.0.2.1 -> 192.0.2.2
tos 0x00, ttl 64, length 84, checksum 0x5e92 dscp CS0 ecn NON_ECN
fragment id 0x5813, flags DONT_FRAGMENT
ICMP echo_request checksum 0xc16 id 21197
00:07:03:979323: ip4-icmp-input
ICMP: 192.0.2.1 -> 192.0.2.2
tos 0x00, ttl 64, length 84, checksum 0x5e92 dscp CS0 ecn NON_ECN
fragment id 0x5813, flags DONT_FRAGMENT
ICMP echo_request checksum 0xc16 id 21197
00:07:03:979323: ip4-icmp-echo-request
ICMP: 192.0.2.1 -> 192.0.2.2
tos 0x00, ttl 64, length 84, checksum 0x5e92 dscp CS0 ecn NON_ECN
fragment id 0x5813, flags DONT_FRAGMENT
ICMP echo_request checksum 0xc16 id 21197
00:07:03:979326: ip4-load-balance
fib 0 dpo-idx 5 flow hash: 0x00000000
ICMP: 192.0.2.2 -> 192.0.2.1
tos 0x00, ttl 64, length 84, checksum 0x88e1 dscp CS0 ecn NON_ECN
fragment id 0x2dc4, flags DONT_FRAGMENT
ICMP echo_reply checksum 0x1416 id 21197
00:07:03:979325: ip4-rewrite
tx_sw_if_index 1 dpo-idx 5 : ipv4 via 192.0.2.1 eth1: mtu:1500 next:3 flags:[] 0242099728c60242c00002020800 flow hash: 0x00000000
00000000: 0242099728c60242c00002020800450000542dc44000400188e1c0000202c000
00000020: 02010000141652cd00018143166800000000399d0900000000001011
00:07:03:979326: eth1-output
eth1 flags 0x02180005
IP4: 02:42:c0:00:02:02 -> 02:42:09:97:28:c6
ICMP: 192.0.2.2 -> 192.0.2.1
tos 0x00, ttl 64, length 84, checksum 0x88e1 dscp CS0 ecn NON_ECN
fragment id 0x2dc4, flags DONT_FRAGMENT
ICMP echo_reply checksum 0x1416 id 21197
00:07:03:979327: eth1-tx
af_packet: hw_if_index 1 tx-queue 0
tpacket3_hdr:
status 0x1 len 108 snaplen 108 mac 0 net 0
sec 0x0 nsec 0x0 vlan 0 vlan_tpid 0
vnet-hdr:
flags 0x00 gso_type 0x00 hdr_len 0
gso_size 0 csum_start 0 csum_offset 0
buffer 0xf97c4:
current data 0, length 98, buffer-pool 0, ref-count 1, trace handle 0x0
local l2-hdr-offset 0 l3-hdr-offset 14
IP4: 02:42:c0:00:02:02 -> 02:42:09:97:28:c6
ICMP: 192.0.2.2 -> 192.0.2.1
tos 0x00, ttl 64, length 84, checksum 0x88e1 dscp CS0 ecn NON_ECN
fragment id 0x2dc4, flags DONT_FRAGMENT
ICMP echo_reply checksum 0x1416 id 21197
```
Well, that's a mouthfull, isn't it! Here, I get to show you VPP in action. After receiving the
packet on its `af-packet-input` node from 192.0.2.1 (Summer, who is pinging us) to 192.0.2.2 (the
VPP container), the packet traverses the dataplane graph. It goes through `ethernet-input`, then
`ip4-input`, which sees it's destined to an IPv4 address configured, so the packet is handed to
`ip4-receive`. That one sees that the IP protocol is ICMP, so it hands the packet to
`ip4-icmp-input` which notices that the packet is an ICMP echo request, so off to
`ip4-icmp-echo-request` our little packet goes. The ICMP plugin in VPP now answers by
`ip4-rewrite`'ing the packet, sending the return to 192.0.2.1 at MAC address `02:42:09:97:28:c6`
(this is Summer, the host doing the pinging!), after which the newly created ICMP echo-reply is
handed to `eth1-output` which marshalls it back into the kernel's AF_PACKET interface using
`eth1-tx`.
Boom. I could not be more pleased.
## What's Next ## What's Next
This was a nice exercise for me! I'm going this direction becaue the This was a nice exercise for me! I'm going this direction becaue the
@ -334,4 +455,10 @@ Once we have that, there's still quite some work for me to do. Notably:
`vppcfg.yaml`, as well as some manual pre- and post-flight configuration for the more esoteric `vppcfg.yaml`, as well as some manual pre- and post-flight configuration for the more esoteric
stuff. Building the plumbing for this is a TODO for now. stuff. Building the plumbing for this is a TODO for now.
First order of business: get it to ping at all :) ## Acknowledgements
I wanted to give a shout-out to Nardus le Roux who inspired me to contribute this Containerlab VPP
node type, and to Roman Dodin for his help getting the Containerlab parts squared away when I got a
little bit stuck.
First order of business: get it to ping at all ... it'll go faster from there on out :)