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
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@ -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 :)
|
||||||
|
Reference in New Issue
Block a user