TCP повторно предаване за същия пакет, но с различен TCP полезен товар

Разработвам Ethernet драйвер в Linux платформа. Открих, че при възникване на TCP повторно предаване, TCP полезните натоварвания на множество пакети за повторно предаване, отнасящи се до едни и същи пакети с пореден номер, са различни. Не мога да разбера защо би се случило. В моя драйвер току-що разпределих нормално мрежово устройство без никакви специфични флагове. Между другото, полето за контролна сума на TCP също беше грешно в тези пакети за повторно предаване, но контролната сума във всички други типове TCP пакети беше правилна, като SYNC, ACK и DUP ACK.

Улових пакетите от wireshark и това означава, че пакетите, които улових, не бяха обработени от моя драйвер, а само от TCP стека в ядрото на Linux. Но когато тествах с други Ethernet устройства и драйвери, този проблем не се случи. Та въпросите ми бяха следните.

  1. Възможно ли е TCP стека да препредава същите пакети без същия полезен товар?
  2. Кои видове параметри в ядрото на Linux биха причинили тези проблеми?
  3. Как моят драйвер може да причини този проблем?

person cuibuaa    schedule 15.04.2015    source източник
comment
Вие просто казвате, че са различни, но всъщност не обяснявате какво сте гледали, когато сте открили, че са различни. По какъв начин са различни?   -  person Bratchley    schedule 15.04.2015
comment
Предполагам, че unix.stackexchange.com/questions/196341/ също е ваш, изглежда, че имате двама потребители. Така че може да не сте видели предложението на другото, което вероятно е по-добре да попитате в Stack Overflow и да включите код, ако изобщо е възможно.   -  person derobert    schedule 15.04.2015


Отговори (1)


Благодаря за всичките ви отговори.

Намерих причината за този проблем. Това е много, много глупава грешка.

Поради това, че адресът на всички DMA буфери (в моя драйвер е skb->data) е подравнен на 4 байта, извиках функция memmove, за да направя това. Всъщност данните, посочени от skb->data, се споделят от целия TCP/IP стек в ядрото. Така че след тази грешна операция, когато се случи TCP повторно предаване, адресът, посочен от skb->data в TCP стека, все още поддържа оригиналния. Ето защо контролната сума, базирана на оригинални данни, изглежда грешна в wireshark. Кодовете в моя драйвер са като следното.

u32 skb_len = skb->len;
u32 align = check_aligned(skb);
if !align
    return skb;

skb_push(skb,align);
memmove(skb->data, skb->data+align, skb_len);
skb_trim(skb, skb_len);
return skb;

Надявам се моят опит да помогне на другите да избегнат тази глупава грешка.

person cuibuaa    schedule 16.04.2015