【发布时间】:2021-10-23 06:52:26
【问题描述】:
我正在尝试使用原始数据包将数据包从一个接口传输到另一个接口(仅用于播放)。 首先,我专注于接收到的数据包。
在我的机器(archlinux,IP 为 192.168.30.3)上,我创建了以下代码:
#include <stdio.h>
#include <net/ethernet.h> /* the L2 protocols */
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
int main()
{
int packet_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP));
/* test reception */
char packet[4096];
struct sockaddr rcvaddr;
struct in_addr addr;
addr.s_addr = inet_addr("192.168.30.3"); //my ip
// use nc to send a use packet
while (1) {
int len = sizeof(rcvaddr);
int len_packet =
recvfrom(packet_socket, packet, 4096, 0, &rcvaddr, &len);
// check if the packet is for us
struct iphdr *iph =
(struct iphdr *) (packet + sizeof(struct ethhdr));
if (iph->daddr != inet_addr("192.168.30.3"))
continue;
// check if tcp
if (iph->protocol != IPPROTO_TCP)
continue;
printf("Total packet length: %d\n",
sizeof(struct ethhdr) + ntohs(iph->tot_len));
}
}
然后我以root身份运行它并执行nc -lp 12345 -n > /dev/null。
在另一台机器上(debian,192.168.30.4)我运行dd if=/dev/urandom | nc 192.168.30.3 12345
这使得我之前的程序打印接收到的数据包的长度。
从中,我看到有大于 MTU 大小的数据包(即 1500 在两台机器上)。例如,我可以从我的程序中读取“总数据包长度:16962”。 (linux raw ethernet socket receive more bytes than MTU 也观察到了)。
我知道 IP 分段,所以我首先想到了 IP 重组。
但是我在man 7 raw 中读到:
“请注意,与原始套接字不同,数据包套接字不会重新组装 IP 片段。”
因为我使用了数据包套接字(AF_PACKET),所以我不应该有数据包
重新组装然后保持 MTU 大小正确?
我也做了sudo ethtool -K ens3 tx off sg off tso off 并使用值 0、1、2 和 3 进行测试
在两台机器上的 /proc/sys/net/ipv4/ip_no_pmtu_disc 中。
您认为 192.168.30.4 发送的 MTU 更多吗?或者我的机器是否进行了一些重新组装,尽管 说明书上写了什么?
ethtool -k ens3 给出:
在 192.168.30.4:
seb@SERVER:~$ sudo ethtool -k ens3
Features for ens3:
rx-checksumming: off
tx-checksumming: off
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: off
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
scatter-gather: off
tx-scatter-gather: off
tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: off
tx-tcp-segmentation: off
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp-mangleid-segmentation: off
tx-tcp6-segmentation: off [fixed]
udp-fragmentation-offload: off
generic-segmentation-offload: off [requested on]
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: on
tx-vlan-offload: on [fixed]
ntuple-filters: off [fixed]
receive-hashing: off [fixed]
highdma: off [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
tx-gre-segmentation: off [fixed]
tx-gre-csum-segmentation: off [fixed]
tx-ipxip4-segmentation: off [fixed]
tx-ipxip6-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
tx-udp_tnl-csum-segmentation: off [fixed]
tx-gso-partial: off [fixed]
tx-sctp-segmentation: off [fixed]
tx-esp-segmentation: off [fixed]
tx-udp-segmentation: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: off
loopback: off [fixed]
rx-fcs: off
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
l2-fwd-offload: off [fixed]
hw-tc-offload: off [fixed]
esp-hw-offload: off [fixed]
esp-tx-csum-hw-offload: off [fixed]
rx-udp_tunnel-port-offload: off [fixed]
tls-hw-tx-offload: off [fixed]
tls-hw-rx-offload: off [fixed]
rx-gro-hw: off [fixed]
tls-hw-record: off [fixed]
在 192.168.30.3:
[seb@archlinux ~]$ sudo ethtool -k ens3
Features for ens3:
rx-checksumming: off
tx-checksumming: off
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: off
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
scatter-gather: off
tx-scatter-gather: off
tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: off
tx-tcp-segmentation: off
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp-mangleid-segmentation: off
tx-tcp6-segmentation: off [fixed]
generic-segmentation-offload: off [requested on]
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: on
tx-vlan-offload: on [fixed]
ntuple-filters: off [fixed]
receive-hashing: off [fixed]
highdma: off [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
tx-gre-segmentation: off [fixed]
tx-gre-csum-segmentation: off [fixed]
tx-ipxip4-segmentation: off [fixed]
tx-ipxip6-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
tx-udp_tnl-csum-segmentation: off [fixed]
tx-gso-partial: off [fixed]
tx-tunnel-remcsum-segmentation: off [fixed]
tx-sctp-segmentation: off [fixed]
tx-esp-segmentation: off [fixed]
tx-udp-segmentation: off [fixed]
tx-gso-list: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: off
loopback: off [fixed]
rx-fcs: off
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
l2-fwd-offload: off [fixed]
hw-tc-offload: off [fixed]
esp-hw-offload: off [fixed]
esp-tx-csum-hw-offload: off [fixed]
rx-udp_tunnel-port-offload: off [fixed]
tls-hw-tx-offload: off [fixed]
tls-hw-rx-offload: off [fixed]
rx-gro-hw: off [fixed]
tls-hw-record: off [fixed]
rx-gro-list: off
macsec-hw-offload: off [fixed]
rx-udp-gro-forwarding: off
hsr-tag-ins-offload: off [fixed]
hsr-tag-rm-offload: off [fixed]
hsr-fwd-offload: off [fixed]
hsr-dup-offload: off [fixed]
另外,请注意这两台机器是由 GNS3 运行的 qemu 机器,具有以下网络选项:-net none -device e1000,mac=0c:7e:08:49:13:00,netdev=gns3-0 -netdev socket,id=gns3-0,udp=127.0.0.1:20049,localaddr=127.0.0.1:20048
【问题讨论】:
-
不幸的是,关闭 lro 会产生相同的结果。我只是编辑我的问题以添加您想要的信息。由于两台机器都是VM,所以我会在真机上尝试(可能hypervisor创建了一个大缓冲区)
-
我的猜测:您忽略了选项。开始阅读这些 RFC...
-
@wildplasser:你能详细说明一下吗?你在说什么“选项”?什么 RFC?
-
@stackinside :我禁用了通用接收卸载。这会产生更好的结果。在确认之前我正在做更多的实验。
-
@stackinside:我确认禁用 GRO 可以解决我的问题(出于性能原因,这可能不是一件好事,但它回答了我的问题)。您的第一条评论显然给了我很好的思考方式,所以是的,您可以提供 LRO/GRO 建议作为答案。
标签: c networking raw-sockets mtu