나는 라우터가 있는 매우 간단한 토폴로지를 가지고 있습니다.r1ICMP "에코 요청" 메시지를 다음으로 보냅니다.r22000바이트 페이로드 및 라우터 포함r2ICMP "에코 응답" 메시지를 사용하여 다음 메시지에 응답합니다.
라우터 Gi0/0/0 인터페이스의 MTU는 9000바이트입니다. 그림에 표시된 것처럼 두 라우터 사이에는 트래픽을 bond0 인터페이스로 미러링하는 수동 네트워크 탭도 있습니다.개인용 컴퓨터. bond0(및 eth2 및 eth3)의 MTU가 라인의 ICMP 메시지를 포함하는 이더넷 프레임보다 작은 경우 다음과 같은 패킷 캡처 유틸리티가 사용됩니다.TCP 덤프또는샤크ICMP 메시지의 부분 페이로드 부분만 표시됩니다. 예를 들어, 다음과 같이 말할 수 있습니다.r10xabcd 데이터로 채워진 ICMP 메시지를 보낸 다음 패킷 캡처 유틸리티가 bond0, eth2 또는 eth3 인터페이스에서 수신 대기합니다.개인용 컴퓨터다음 데이터를 참조하세요.
0x0000: abcd abcd abcd abcd abcd abcd abcd abcd ................
0x0010: abcd abcd abcd abcd abcd abcd abcd abcd ................
0x0020: abcd abcd abcd abcd abcd abcd abcd abcd ................
0x0030: abcd abcd abcd abcd abcd abcd abcd abcd ................
0x0040: abcd abcd abcd abcd abcd abcd abcd abcd ................
/* further data removed for brevity */
이 동작의 원인은 무엇입니까?
답변1
실제로 usbnet
범인일 가능성이 가장 높은 것으로 보입니다.
/* rx and tx sides can use different message sizes;
* bind() should set rx_urb_size in that case.
*/
dev->hard_mtu = net->mtu + net->hard_header_len;
net->netdev_ops = &usbnet_netdev_ops;
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->ethtool_ops = &usbnet_ethtool_ops;
// allow device-specific bind/init procedures
// NOTE net->name still not usable ...
if (info->bind) {
status = info->bind (dev, udev);
...
}
....
if (!dev->rx_urb_size)
dev->rx_urb_size = dev->hard_mtu;
http://lxr.free-electrons.com/source/drivers/net/usb/usbnet.c?v=4.4#L1661
rx_urb_size
내가 아는 한, cdc_ether는 스스로 설정되지 않습니다.
나는 URB 크기가 USB 컨트롤러에 전달되고 이더넷 프레임의 헤더가 잘려서 잘려져 있다고 가정합니다(다른 쪽 끝이 왜 안 되는지 묻지 마십시오). 내 말은,희망귀하의 실험으로 인해 하드웨어가 할당된 버퍼 외부에 DMA되지 않습니다. :)
ndo_change_mtu
cdc_ether가 rx_urb_size를 설정하더라도 usbnet의 콜백에 이상한 비트가 있습니다. MTU를 최대값으로 설정하면 결국 MTU에 훅 걸릴 수도 있는 것 같습니다.
솔직히 이것이 어떻게 작동하는지 전혀 모릅니다. 언뜻 보면 이상해 보입니다.
if (dev->rx_urb_size == old_hard_mtu) { dev->rx_urb_size = dev->hard_mtu;
http://lxr.free-electrons.com/source/drivers/net/usb/usbnet.c?v=4.4#L393