Hi,
I suspect that the virtio network driver calls some skb BPF programs with skb->data_end - skb->data != skb->len, but only for forwarded packets.
For instance, the attached sched_cls tc program prints skb->data, skb->data_end and skb->len for each packet:
<idle>-0 [000] ..s. 491.561727: 0: data: 3110080576 data_end: 3110080704 len: 262
<idle>-0 [000] .Ns. 491.561752: 0: data: 3110080064 data_end: 3110080192 len: 250
As it can be seen, the frame length should be 262 and 250 bytes, but data_end - data is always 128. For packets smaller than 128 it works fine.
I've tried the latest kernel (5.3-rc1) besides 4.14, 4.19, 5.2, etc., and the error persists. Other drivers than virtio work as expected and I can inspect every byte of the packet. Locally generated traffic also works as expected.
To carry out this experiment I've used a Debian 10 virtual machine with net.ipv4.ip_forward=1 and net.ipv4.conf.eth0.forwarding=1, forwarding packets between its two virtio interfaces. The example program is run with the following command, having BCC installed:
$> sudo python3 pkt_len_text.py eth0
Where "eth0" could be another ingress interface. The output is showed at /sys/kernel/debug/tracing/trace_pipe.
Can anyone confirm if this error is reproducible, and does it have any solutions?
BR.
Arnau
I suspect that the virtio network driver calls some skb BPF programs with skb->data_end - skb->data != skb->len, but only for forwarded packets.
For instance, the attached sched_cls tc program prints skb->data, skb->data_end and skb->len for each packet:
<idle>-0 [000] ..s. 491.561727: 0: data: 3110080576 data_end: 3110080704 len: 262
<idle>-0 [000] .Ns. 491.561752: 0: data: 3110080064 data_end: 3110080192 len: 250
As it can be seen, the frame length should be 262 and 250 bytes, but data_end - data is always 128. For packets smaller than 128 it works fine.
I've tried the latest kernel (5.3-rc1) besides 4.14, 4.19, 5.2, etc., and the error persists. Other drivers than virtio work as expected and I can inspect every byte of the packet. Locally generated traffic also works as expected.
To carry out this experiment I've used a Debian 10 virtual machine with net.ipv4.ip_forward=1 and net.ipv4.conf.eth0.forwarding=1, forwarding packets between its two virtio interfaces. The example program is run with the following command, having BCC installed:
$> sudo python3 pkt_len_text.py eth0
Where "eth0" could be another ingress interface. The output is showed at /sys/kernel/debug/tracing/trace_pipe.
Can anyone confirm if this error is reproducible, and does it have any solutions?
BR.
Arnau
#!/usr/bin/python # Copyright (c) PLUMgrid, Inc. # Licensed under the Apache License, Version 2.0 (the "License") import sys from bcc import BPF from pyroute2 import IPRoute ipr = IPRoute() text = """ int pkt_len_test(struct __sk_buff *skb) { void *data_end = (void *) (long)skb->data_end; void *data = (void *) (long)skb->data; bpf_trace_printk("data: %u end: %u len: %d \\n", data, data_end, skb->len); return 1; } """ try: b = BPF(text=text, debug=0) fn = b.load_func("pkt_len_test", BPF.SCHED_CLS) idx = ipr.link_lookup(ifname=str(sys.argv[1]))[0] ipr.tc("add", "ingress", idx, "ffff:") ipr.tc("add-filter", "bpf", idx, ":1", fd=fn.fd, name=fn.name, parent="ffff:", action="ok", classid=1) ipr.tc("add", "sfq", idx, "1:") ipr.tc("add-filter", "bpf", idx, ":1", fd=fn.fd, name=fn.name, parent="1:", action="ok", classid=1) foo = input("Press any key to remove the filters and stop the program") ipr.tc("del", "ingress", idx, "ffff:") ipr.tc("del", "sfq", idx, "1:") print("Filters deleted") except Exception as e: print("Error: %s", e)
_______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization