私はルータを持つ非常に単純なトポロジを持っています。r1ICMP「エコー要求」メッセージを次に送信します。r22000バイトのペイロードとルーターを含むr2ICMP「エコー応答」メッセージを使用して、次のメッセージに応答します。
ルータGi0/0/0インターフェイスのMTUは9000バイトです。図に示すように、2 つのルータ間にトラフィックを 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