tcpdump показывает incorrect checksum у исходящих пакетов: сеть цела, это разгрузка сетевой карты
Сняли дамп на сервере, открыли — и половина пакетов красная: «incorrect checksum». Первая мысль почти у всех одинаковая: сыпется сетевая карта, гнилой патч-корд, надо менять железо. В девяти случаях из десяти менять не надо ничего. Вы просто смотрите на пакет раньше, чем его дописала сетевая карта. В статье разберу, что на самом деле лежит в поле контрольной суммы, как за три минуты отличить артефакт захвата от реальной порчи трафика, как убрать этот шум в tcpdump и Wireshark и почему у одного моего клиента рвались выгрузки после того, как ему уже успели поменять сетевую плату.
Вы смотрите на пакет до того, как его дописало железо
Начну с механики, потому что без неё дальше будет непонятно. Когда вы запускаете tcpdump -i eth0 -v, вы не подключаетесь к проводу. Вы вешаете AF_PACKET-сокет на сетевое устройство внутри ядра Linux. Для исходящего трафика ядро отдаёт вам копию буфера в тот момент, когда пакет уже прошёл весь сетевой стек и вот-вот будет передан драйверу, а драйвер отдаст его карте по DMA. Ключевое слово — «вот-вот». Всё, что делает с пакетом сама карта, происходит уже после точки захвата.
А современная карта делает с пакетом много. Расчёт контрольной суммы TCP и UDP — операция, которая требует пройти по всей полезной нагрузке; на гигабите это ещё терпимо, на десяти — это заметные проценты процессорного времени. Поэтому её десятилетиями отдают железу. Диего Пино из Igalia формулирует это в лоб: «TCP checksumming is generally offloaded to the NIC, since it's a relatively expensive operation... Since tcpdump captures outgoing packets before they hit the NIC, the checksum value hasn't been calculated yet and likely contains garbage». Руководство пользователя Wireshark говорит ровно то же: «Wireshark gets these „empty“ checksums and displays them as invalid, even though the packets will contain valid checksums when they transit the network».
Отсюда сразу вытекает диагностический признак, который снимает 90 % вопросов. Смотрите на направление. Битые суммы только у исходящих пакетов, только у тех, что порождены этим самым хостом, и при этом входящие в том же дампе — идеально чистые? Это разгрузка. Никакая реальная порча трафика не умеет бить строго одно направление и строго локально сгенерированные пакеты, оставляя нетронутым всё остальное. Порча — она про физику, ей всё равно, кто автор пакета.
Отдельно про транзит и про виртуалки. На шлюзе, который просто форвардит чужие пакеты, суммы обычно нормальные — их посчитал и проверил кто-то другой, ядро их не пересобирает. Но если на шлюзе есть NAT и на исходящем интерфейсе включена разгрузка, вы снова можете увидеть «incorrect» — ядро отложило пересчёт. А внутри виртуальной машины с virtio-net или VMXNET3 это вообще норма жизни: гипервизор и гость договорились не считать суммы для трафика, который никогда не выйдет на физический провод, и для внутрихостового трафика сумма может быть не посчитана вообще никем.
- точка захвата tcpdump — внутри ядра, до драйвера и до сетевой карты;
- битые суммы только у исходящих, локально порождённых пакетов — почти наверняка offload;
- входящие пакеты в том же дампе идут с уже проверенными и корректными суммами;
- в виртуальной машине картина ещё «грязнее» — там суммы часто не считает никто, и это штатно.
В поле лежит не мусор, а частичная сумма с псевдозаголовком
Формулировка «в поле контрольной суммы мусор» кочует по форумам с 2010 года и сегодня уже неточна. Для TCP и UDP Linux кладёт туда вполне осмысленное число. Документация ядра описывает режим CHECKSUM_PARTIAL так: драйвер обязан посчитать сумму от csum_start до конца пакета и записать результат по смещению csum_start + csum_offset, а значение, которое стек положил в поле заранее, будет включено в расчёт. Стек кладёт туда сумму псевдозаголовка — адреса источника и назначения, номер протокола и длину сегмента.
Сделано так по вполне приземлённой причине: csum_offset не может быть отрицательным, то есть карта не умеет «залезть назад» и добрать вклад IP-заголовка, которого в её зоне ответственности уже нет. Поэтому этот вклад ей подсовывают заранее, прямо в то же поле. Получается частичная сумма: половина работы сделана программно, вторую половину дожмёт железо. Wireshark User's Guide прямо это фиксирует: «Linux and Windows, when offloading checksums, will calculate the contribution from the pseudo header and place it in the checksum field».
Практический вывод для тех, кто смотрит дампы: начиная с Wireshark 4.2.0 такие суммы распознаются как «valid but partial» и, цитирую руководство, «will not be colored as Bad Checksums by the default coloring rules». То есть если у вас свежий Wireshark (актуальная стабильная ветка на сентябрь 2026 — 4.6.x, в загрузках лежит 4.6.8, старая стабильная 4.4.18), а пакеты всё равно красные — стоит внимательнее посмотреть, действительно ли это частичная сумма или там реально нули и произвольные байты от драйвера, который вообще ничего не заполняет.
И не удивляйтесь, если пустой окажется ещё и контрольная сумма IPv4-заголовка. Её тоже умеют разгружать: в ethtool за это отвечает отдельная фича tx-checksum-ipv4. В tcpdump это выглядит вот так — и, кстати, tcpdump проверяет суммы только в подробном режиме, без -v вы этих скобок просто не увидите:
- `CHECKSUM_PARTIAL`: стек кладёт в поле сумму псевдозаголовка, драйвер/карта досчитывает остальное от `csum_start`;
- tcpdump проверяет суммы TCP/UDP только с `-v` и без `-K` — без этих условий строки «incorrect» не появятся;
- `cksum X (incorrect -> Y)`: X лежит в буфере сейчас, Y — что насчитал tcpdump и что в итоге запишет железо;
- Wireshark 4.2.0+ помечает такие суммы как «valid but partial» и не красит их правилом Checksum Errors;
- контрольную сумму IPv4-заголовка тоже можно разгрузить — фича `tx-checksum-ipv4` в выводе `ethtool -k`.
Три минуты, чтобы закрыть вопрос окончательно
Спорить с логикой «а вдруг всё-таки карта» бессмысленно, проще доказать. У меня на это уходит один заход по SSH. Первым делом смотрю состояние разгрузки на интерфейсе — ключ -k (он же --show-features, он же --show-offload), а меняется всё ключом -K (--features, --offload):
Если в выводе tx-checksumming: on, вопрос по сути исчерпан: ядро физически не считало эту сумму, и жаловаться tcpdump будет всегда. Дальше — контрольный выстрел: снять дамп на приёмнике или с зеркального порта коммутатора. Пакеты, дошедшие до второй точки, уже прошли через карту отправителя, и суммы в них настоящие. Если там ноль ошибок — трафик по проводу целый, разговор окончен. Если ошибки есть и там — вот тогда это интересно, и надо смотреть на физику.
Третий шаг — счётчики ошибок на самом железе. Реальная порча кадров почти всегда сначала видна как ошибки FCS/CRC на порту, а не как битые L4-суммы: контрольная сумма Ethernet-кадра ловит подавляющее большинство искажений, и битый кадр до TCP-уровня просто не доживёт. Поэтому если rx_crc_errors по нулям, а порт коммутатора чист, версия «гнилой кабель» отваливается сама.
И четвёртое, самое дешёвое: попросите tcpdump вообще не проверять суммы. В мануале про ключ -K (--dont-verify-checksums) написано прямым текстом: «Don't attempt to verify IP, TCP, or UDP checksums. This is useful for interfaces that perform some or all of those checksum calculation in hardware; otherwise, all outgoing TCP checksums will be flagged as bad».
- `ethtool -k eth0` — узнать, включена ли разгрузка;
- снять параллельный дамп на приёмнике или со SPAN-порта — единственное настоящее доказательство;
- `ip -s link show eth0` и `ethtool -S eth0 | grep -iE 'err|crc|drop'` — счётчики реальных ошибок;
- `tcpdump -K` — убрать шум из вывода и не морочить себе голову.
Шум лечится в инструменте, а не в сети
Массовое заблуждение: чтобы «починить» суммы, надо выключить разгрузку на боевом сервере. Не надо. Вы боретесь не с сетью, а с отображением в анализаторе — вот там и правьте. В Wireshark проверка сумм давно выключена по умолчанию именно из-за повсеместной разгрузки; руководство пишет, что свежие версии «disable checksum validation by default due to the prevalence of offloading in modern hardware and operating systems». Если у вас она включена — значит, кто-то её включил руками или притащил старый профиль настроек.
Путь до переключателя: Edit → Preferences → Protocols → TCP, галочка «Validate the TCP checksum if possible». Аналогичные галочки есть у UDP и IPv4. В консольном tshark то же самое делается ключом -o, что удобно вписывать в скрипты разбора. А раскраска строк живёт отдельно: за красные строки отвечает правило Checksum Errors, которое сравнивает поля вида tcp.checksum.status и ip.checksum.status со значением «Bad». Если хотите видеть ошибки, но не хотите, чтобы половина дампа была красной, — правило можно просто отключить в View → Coloring Rules, не трогая сами проверки.
Есть и обратная ситуация, про которую забывают. Если вы разбираете дамп, снятый со SPAN-порта коммутатора или на принимающем хосте, — проверку сумм имеет смысл включить осознанно. Там она уже несёт информацию: пакеты прошли через железо отправителя, суммы настоящие, и ошибка в них — это повод искать middlebox, который что-то переписал и не пересчитал, или совсем экзотику вроде порчи памяти на промежуточном устройстве.
Отдельно оговорюсь про Windows: там ровно та же история, и Wireshark на Windows-хосте покажет ровно те же «incorrect checksum» у исходящих. Состояние разгрузки смотрится через Get-NetAdapterChecksumOffload, выключается Disable-NetAdapterChecksumOffload. Но выключать я и там не советую — по тем же причинам, что и в Linux.
- Wireshark: Edit → Preferences → Protocols → TCP → снять «Validate the TCP checksum if possible»;
- tshark: `tshark -r cap.pcap -o tcp.check_checksum:FALSE -o udp.check_checksum:FALSE`;
- раскраска: View → Coloring Rules → правило Checksum Errors — отключается независимо от проверок;
- Windows: `Get-NetAdapterChecksumOffload` покажет состояние, но лечить надо всё равно в анализаторе.
Разгрузка врёт не только про суммы: TSO, GSO, GRO и LRO
Контрольные суммы — самая заметная, но не самая вредная ложь захвата на хосте. Гораздо коварнее сегментация. При включённом TSO (tcp-segmentation-offload) или его программном собрате GSO ядро отдаёт карте один большой буфер, а карта уже сама режет его на сегменты по MSS. tcpdump снимает копию до нарезки — и вы видите в дампе «TCP-пакет» длиной 24 820 или 41 720 байт при MTU 1500. Человек, который этого не знает, делает вывод «у нас в сети джамбо-кадры» или «MTU поехал» и уходит искать несуществующую проблему.
На приёме зеркальная история: GRO (generic-receive-offload) и LRO склеивают пришедшие подряд сегменты в один большой буфер до того, как их увидит захват. Последствия для анализа неприятные: вы недосчитаетесь пакетов, у вас поплывёт картина по ACK, а главное — вы можете не увидеть ретрансмиты и дубли ACK, потому что склейка их проглотила. Ищете потери — а инструмент показывает идеально гладкий поток.
Поэтому когда я разбираю действительно тонкий случай — потери, задержки, странности с MSS и фрагментацией — я на время диагностики выключаю разгрузку на конкретном интерфейсе. Именно на время, с фиксацией того, что было до. И имейте в виду две вещи. Во-первых, фичи зависят друг от друга: документация ядра по netdev features прямо требует от драйвера разрешать зависимости в ndo_fix_features и скорее выключать фичу, чем тянуть за собой её зависимость, — поэтому после ethtool -K eth0 tx off у большинства драйверов вместе с суммами уезжают и TSO, а ethtool выводит блок «Actual changes» с тем, что реально поменялось. Во-вторых, часть фич в выводе ethtool -k помечена [fixed] — их драйвер переключать не даёт, и ethtool честно сообщит, что изменить не смог.
Ещё один нюанс, на котором спотыкаются: tcpdump -i any. Псевдоинтерфейс any удобен, но он, как сказано в мануале, не работает в promiscuous-режиме, и картина по заголовкам там своя. Для аккуратного разбора я всегда снимаю на конкретном физическом интерфейсе, а any использую только чтобы быстро понять, куда вообще уходит трафик.
- `tso` / `gso` — в дампе на отправителе появляются «пакеты» в десятки килобайт;
- `gro` / `lro` — на приёмнике сегменты склеиваются, пропадают ретрансмиты и dup-ACK;
- фичи зависимы: после выключения `tx` драйвер обычно сам гасит `tso`, что видно в «Actual changes»;
- фичи с пометкой `[fixed]` в `ethtool -k` не переключаются вообще — это нормально.
Когда разгрузка действительно ломает трафик: туннели, мосты, виртуалки
Было бы нечестно сказать, что «incorrect checksum» всегда безобиден. Слабое место механизма описано в самой документации ядра: интерфейс TX-разгрузки позволяет отдать железу только одну контрольную сумму. В инкапсулированном пакете — VXLAN, GENEVE, GRE с UDP внутри — сумм несколько, на разных уровнях, и все остальные должны досчитываться другими механизмами вроде LCO (Local Checksum Offload). Каждая такая связка «виртуальный интерфейс туннеля → драйвер → карта, которая умеет или не умеет разбирать туннельные заголовки» — место, где сумма может так и остаться частичной уже на проводе.
Хрестоматийный пример — Kubernetes с flannel в режиме VXLAN на виртуальных машинах. В issue flannel №1279 (RHEL 7.8, flannel 0.11) сервисные IP подов на соседних нодах переставали отвечать, а в журнале ядра принимающей ноды сыпалось UDP: bad checksum ... :8472. Ключевая разница с артефактом захвата: ошибку видит ПРИЁМНИК, и он пакеты отбрасывает. Обходной путь из той же issue — выключить разгрузку суммы на VXLAN-интерфейсе: ethtool -K flannel.1 tx-checksum-ip-generic off. Похожие истории всплывают с VMXNET3 и туннельными портами: у драйвера есть собственная разгрузка VXLAN/GENEVE, и при нестандартных портах или старых версиях ядра/VMware Tools внутренние суммы оказываются неверными.
С мостами и virtio картина двоякая. Если вы снимаете дамп на br0, vnet*/tap* или veth хоста виртуализации, трафик гостей почти всегда будет с частичными суммами — гость отдал его с флагом «досчитать потом», и это нормально, пока где-то дальше по пути сумму досчитывают (физическая карта или ядро программно перед отправкой). Проблема начинается, когда пакет уходит в место, которое этого флага не понимает: пользовательский сетевой стек, самописный туннель, старое DPDK-приложение, отдельный фильтр, пересобирающий пакет. Там частичная сумма превращается в настоящую ошибку.
Как отличить. Реальная поломка всегда видна на принимающей стороне: растут счётчики InCsumErrors в nstat на приёмнике, в dmesg появляются «bad checksum», приложение ловит таймауты, а в дампе на приёмнике суммы тоже битые. Если всё это есть и трафик идёт через туннель или виртуальный коммутатор — вот тогда выключение конкретной фичи на конкретном интерфейсе (а не всей разгрузки на всех картах) оправдано и как временная мера, и как постоянная, до обновления драйвера.
- ошибки сумм видны на приёмнике и растёт `InCsumErrors` — это уже не артефакт захвата;
- в пути есть VXLAN/GENEVE/GRE, overlay-сеть Kubernetes или туннель внутри ВМ — первый подозреваемый;
- проблема пропадает после `ethtool -K <туннельный интерфейс> tx-checksum-ip-generic off` — подтверждение диагноза;
- выключать точечно: одну фичу на одном интерфейсе, а не `rx off tx off` на всех картах;
- постоянное решение — обновить драйвер/ядро/VMware Tools, ethtool-правку оформить unit-файлом systemd до обновления.
Разбор: служба доставки «Быстрый путь», 30 рабочих мест — карту поменяли, а виноват был MSS
Служба доставки «Быстрый путь», 30 рабочих мест: диспетчеры, логисты, склад и бухгалтерия. На обслуживание мы взяли её в конце прошлого года. Жалоба на входе: выгрузка реестров отправлений и фотоотчётов курьеров в личный кабинет партнёра-агрегатора «рвётся на середине». Мелкие запросы летают, интерфейс отзывчивый, а архивы по 200–300 МБ обрываются. До нас там работал приходящий админ, и он сделал ровно то, о чём эта статья: снял tcpdump на шлюзе (Debian 12, ядро 6.1, шлюз с nginx перед публикацией 1С), увидел, что 100 % исходящих TCP помечены «incorrect checksum», и вынес вердикт — деградирует сетевая плата. Купили Intel i350-T2 за 9 400 рублей, поменяли, съездили на площадку два раза. Ничего не изменилось: и обрывы остались, и надписи «incorrect» в дампе остались.
Мы начали с того, что развели два захвата одновременно — на шлюзе и на принимающем хосте в ЦОД. Дамп на 40 минут, 1,4 ГБ, 912 406 пакетов. На отправителе — 100 % исходящих с битыми суммами, на приёмнике — ноль ошибок сумм. Всё, версия «порча трафика» закрыта за пятнадцать минут, и стало видно, что железо меняли зря. ethtool -k показал ровно то, что и ожидалось: tx-checksumming: on, tcp-segmentation-offload: on, generic-segmentation-offload: on. Заодно в дампе на отправителе висели «пакеты» по 24 820 байт — тот самый TSO, из-за которого админ до этого гонялся ещё и за призраком «сломанного MTU».
Настоящая причина нашлась там, где и должна была. Обрывы происходили всегда примерно после 1,2 МБ переданных данных — то есть после того, как соединение раскачивало окно и начинало слать полноразмерные сегменты. Провайдер отдавал канал через туннель с MTU 1400, а ICMP type 3 code 4 («fragmentation needed») резался фильтром на промежуточном оборудовании. Классический PMTUD blackhole: мелкие пакеты проходят, большие молча исчезают, соединение виснет и отваливается по таймауту. Ни к контрольным суммам, ни к сетевой плате это не имело никакого отношения.
Лечится в одну строчку — принудительным ограничением MSS на форварде. После правила выгрузка 300 МБ прошла целиком за 4 минуты 10 секунд, до этого не доживала и до половины. Итог по деньгам: 9 400 рублей за ненужную сетевую плату, два выезда и примерно три недели, в течение которых бизнес каждый вечер не мог нормально отправить реестры, а диспетчеры досылали фотоотчёты кусками вручную. И всё потому, что артефакт захвата приняли за диагноз.
- было: 100 % исходящих с «incorrect checksum» на отправителе, 0 ошибок на приёмнике;
- ложный след №1 — «битая сетевая карта» (следствие tx-checksumming);
- ложный след №2 — «сломанный MTU, джамбо-кадры» (следствие TSO);
- реальная причина — PMTUD blackhole: MTU 1400 в туннеле плюс зарезанный ICMP type 3 code 4.
Выключать ли разгрузку насовсем: мой ответ — нет
Каждый раз, когда я публикую этот разбор внутри команды, находится человек, который предлагает «просто выключить offload везде, чтобы не путаться». Отвечаю прямо: не надо. Разгрузка появилась не от хорошей жизни, она реально экономит процессор. На гигабите вы, может, и не заметите разницы на глазок, но на 10-гигабитном линке или на шлюзе с высоким pps выключение расчёта сумм и сегментации — это ощутимая просадка пропускной способности и рост системного времени. Вы поменяете невидимую косметическую проблему в дампе на вполне видимую проблему в проде.
Где я всё-таки выключаю. Первое — на время диагностики, на конкретном интерфейсе, с обязательной фиксацией исходного состояния и возвратом после. Второе — на выделенных машинах-анализаторах и стендах, где производительность не важна, а достоверность захвата важна абсолютно. Третье — при подтверждённом баге драйвера: такие истории случаются, особенно на старых прошивках и в связке с виртуализацией, но диагноз «баг драйвера» ставится по симптомам реальной порчи данных, а не по надписи в tcpdump.
И честно про спорное. Есть лагерь, который считает, что на серверах, где сеть не является узким местом, разгрузку разумно держать выключенной по умолчанию — ради предсказуемости захватов и меньшего числа граблей с драйверами. Позиция имеет право на жизнь, я её понимаю, но сам так не делаю: слишком часто «сеть не узкое место» перестаёт быть правдой через полгода, а настройку никто не пересматривает. Мой компромисс — оставить всё включённым и просто научить людей читать дамп.
Если сводить всё в короткий регламент, он у меня выглядит так. Увидел «incorrect checksum» — посмотри направление. Только исходящие и только с этого хоста — забудь, это разгрузка, добавь -K и работай дальше. Есть сомнения — сними второй дамп на приёмнике, это тридцать секунд работы и стопроцентный ответ. Проверь ip -s link и ethtool -S на предмет CRC-ошибок, потому что настоящая физика видна именно там. И только когда всё это чисто — иди искать реальную причину в MTU, MSS, потерях на аплинке или в приложении. Железо в этом списке идёт последним, а не первым.
- не выключать offload на боевых серверах ради читаемости дампа;
- выключать точечно и временно — только на время разбора, с возвратом настроек;
- диагноз «баг драйвера» ставится по реальной порче данных, а не по надписи в анализаторе;
- порядок поиска: направление в дампе → второй дамп на приёмнике → счётчики CRC → MTU/MSS → приложение → и только потом железо.
Частые вопросы
Как за минуту понять, артефакт это или реальная порча трафика?
Посмотрите направление. Если битые суммы только у исходящих пакетов, порождённых этим же хостом, а входящие в том же дампе чистые — это разгрузка сетевой карты. Стопроцентная проверка — снять параллельный дамп на приёмнике или со SPAN-порта коммутатора: там пакеты уже прошли через карту отправителя, и суммы в них настоящие. Ноль ошибок на приёмнике закрывает вопрос.
Надо ли выключать checksum offload, чтобы дампы были чистыми?
На боевом сервере — нет. Вы получите рост загрузки процессора и изменение поведения системы прямо в момент диагностики. Шум лечится в анализаторе: ключ `-K` у tcpdump, снятая галочка «Validate the TCP checksum if possible» в Wireshark или отключённое правило раскраски Checksum Errors. Выключать разгрузку имеет смысл точечно, на время разбора, с возвратом настроек.
Что реально лежит в поле контрольной суммы у исходящего пакета?
Для TCP и UDP в Linux — не мусор, а частичная сумма: вклад псевдозаголовка (адреса, протокол, длина), который стек посчитал заранее и положил в поле, чтобы карта дожала остальное. Это режим CHECKSUM_PARTIAL из документации ядра. Wireshark начиная с 4.2.0 распознаёт такие значения как «valid but partial» и не красит их как ошибки по умолчанию.
Почему в дампе видны TCP-пакеты по 40 килобайт при MTU 1500?
Это TSO или GSO: ядро отдаёт карте один большой буфер, карта сама режет его на сегменты по MSS, а захват снимает копию до нарезки. MTU в сети при этом абсолютно нормальный. Симметричная история на приёме — GRO и LRO склеивают сегменты, из-за чего в дампе могут пропасть ретрансмиты и дублирующие ACK.
Какие признаки говорят, что трафик действительно портится?
Ошибки CRC/FCS на порту коммутатора и в счётчиках интерфейса — `ip -s link show eth0`, `ethtool -S eth0 | grep -iE 'err|crc'`. Битые суммы, видимые на приёмнике, а не только на отправителе. Симметричность: реальная порча не выбирает направление и не щадит транзитный трафик. Если счётчики по нулям, версию про кабель и плату можно закрывать.
В виртуальной машине суммы битые постоянно — это нормально?
Как правило, да. С virtio-net и VMXNET3 гость отдаёт пакеты с частичной суммой, и её досчитывают дальше по пути — физическая карта хоста или ядро программно. В дампе внутри гостя или на `tap`/`vnet`-интерфейсе хоста это выглядит как «incorrect», но на проводе суммы правильные. Тревожиться стоит, если ошибки видит приёмник: особенно в overlay-сетях с VXLAN, где известны случаи реально битых внутренних сумм.
Когда checksum offload — это реальная проблема, а не артефакт?
Когда битые суммы видит приёмник: растёт `InCsumErrors` в `nstat`, в `dmesg` пишется «bad checksum», пакеты отбрасываются. Чаще всего это туннели и overlay-сети (VXLAN, GENEVE) поверх виртуальных NIC: интерфейс ядра умеет разгружать только одну сумму, а в инкапсулированном пакете их несколько. Лечится точечным отключением фичи на туннельном интерфейсе, например `ethtool -K flannel.1 tx-checksum-ip-generic off`, и обновлением драйвера.
Помогает ли ключ -K в tcpdump увидеть настоящие проблемы?
Он ничего не скрывает по сути — он просто отключает попытку проверки сумм самим tcpdump, чтобы вывод не тонул в ложных «incorrect». Реальные проблемы вы всё равно ищете по ретрансмитам, таймаутам, счётчикам интерфейса и дампу с приёмной стороны. Для повседневного захвата на отправителе я держу `-K` включённым всегда.
Источники
- Wireshark User's Guide — Checksums / Checksum Offloading — Раздел «Checksums», подраздел про checksum offloading и partial checksums: формулировки «Wireshark gets these „empty“ checksums and displays them as invalid», «Linux and Windows, when offloading checksums, will calculate the contribution from the pseudo header and place it in the checksum field», а также про Wireshark 4.2.0+ и «valid but partial». https://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html
- Linux kernel documentation — Checksum Offloads — Описание режима CHECKSUM_PARTIAL для передачи: драйвер считает сумму от csum_start до конца пакета и пишет результат по csum_start + csum_offset, а предзаполненное значение (вклад псевдозаголовка) включается в расчёт; там же CHECKSUM_UNNECESSARY и CHECKSUM_COMPLETE для приёма. https://www.kernel.org/doc/html/latest/networking/checksum-offloads.html Там же: TX-разгрузка поддерживает только одну сумму, для инкапсуляции нужны LCO/RCO.
- ethtool(8), man-страница — Синтаксис `-k --show-features --show-offload devname` и `-K --features --offload devname feature on|off`, перечень фич rx, tx, sg, tso, ufo, gso, gro, lro, rxvlan, txvlan, ntuple, rxhash. https://man7.org/linux/man-pages/man8/ethtool.8.html
- tcpdump(1), man-страница — Описание ключа `-K` / `--dont-verify-checksums`: «Don't attempt to verify IP, TCP, or UDP checksums... otherwise, all outgoing TCP checksums will be flagged as bad»; там же оговорка про псевдоинтерфейс `any` и promiscuous-режим. https://www.tcpdump.org/manpages/tcpdump.1.html
- Linux kernel documentation — Netdev features mess and how to get out from it alive — Про `ndo_fix_features`: драйвер разрешает зависимости между фичами и безопаснее выключает фичу, чем форсирует зависимость; фичи NETIF_F_NEVER_CHANGE не меняются. https://www.kernel.org/doc/html/latest/networking/netdev-features.html
- flannel-io/flannel — issue #1279 «UDP: bad checksum on VXLAN interface» — Реальная порча сумм в VXLAN-оверлее: приёмник отбрасывает пакеты с «UDP: bad checksum», обход `ethtool -K flannel.1 tx-checksum-ip-generic off`. https://github.com/flannel-io/flannel/issues/1279
- Diego Pino (Igalia) — Fast checksum computation — Инженерный разбор расчёта контрольных сумм, пример `ethtool --show-offload <nic> | grep checksumming` и тезис «Since tcpdump captures outgoing packets before they hit the NIC, the checksum value hasn't been calculated yet». https://blogs.igalia.com/dpino/2018/06/14/fast-checksum-computation/
- Wireshark — страница загрузки (актуальные версии) — На сентябрь 2026: стабильная ветка 4.6.8, старая стабильная 4.4.18, разрабатываемая 4.7.3. https://www.wireshark.org/download.html
