Common questions about Linux networking, each with a short answer and the steps of the simulation where it happens. Follow a link to see the packet at that point, with commands to check it on your own machine.Типові питання про мережу в Linux, кожне з короткою відповіддю і кроками симуляції, де це відбувається. Перейди за посиланням, щоб побачити пакет у цьому місці, з командами для перевірки на своїй машині.
tcpdump sees an incoming packet very early, in netif_receive_skb(), before tc, the firewall and routing. Anything after that point can still drop it: a tc or nftables ingress program, the PREROUTING or INPUT chain, a routing decision (the packet is not for this host and forwarding is off), or a missing socket on the port. To find the exact place, run perf trace -e skb:kfree_skb: it prints every freed packet with the function and, on newer kernels, the reason.tcpdump бачить вхідний пакет дуже рано, в netif_receive_skb(), до tc, файрвола і маршрутизації. Усе, що далі, ще може його відкинути: програма tc або nftables ingress, ланцюжок PREROUTING чи INPUT, рішення маршрутизації (пакет не для цього хоста, а пересилання вимкнене) або відсутній сокет на порту. Щоб знайти точне місце, запусти perf trace -e skb:kfree_skb: він друкує кожен звільнений пакет із функцією, а на новіших ядрах і з причиною.
See:Дивись: Receive 4Прийом 4 · Receive 5Прийом 5 · Receive 6Прийом 6 · Receive 7Прийом 7 · Receive UDP 8Прийом UDP 8
Nothing is listening on that port. The kernel drops the datagram, counts it in UdpNoPorts (nstat -az UdpNoPorts) and sends back ICMP “port unreachable”, which the client reports as “connection refused”.На цьому порту ніхто не слухає. Ядро відкидає датаграму, рахує її в UdpNoPorts (nstat -az UdpNoPorts) і відповідає ICMP «port unreachable», що клієнт показує як «connection refused».
See:Дивись: Receive UDP 8Прийом UDP 8
If the application doesn’t call accept() fast enough, the listening socket’s accept queue fills up. The final ACK of a new handshake is then dropped and ListenOverflows grows: nstat -az TcpExtListenOverflows.Якщо застосунок не встигає викликати accept(), черга accept слухаючого сокета заповнюється. Тоді останній ACK нового рукостискання відкидається, і росте ListenOverflows: nstat -az TcpExtListenOverflows.
See:Дивись: Receive 8Прийом 8
It depends on where the packet goes. Into this host: PREROUTING → routing → INPUT. Out of this host: OUTPUT → POSTROUTING. Through it (a router): PREROUTING → routing → FORWARD → POSTROUTING. Before all of them, netdev ingress chains run on the interface; on the way out, netdev egress chains run on the device, before tc egress and the qdisc.Залежить від того, куди йде пакет. Цьому хосту: PREROUTING → маршрутизація → INPUT. Від цього хоста: OUTPUT → POSTROUTING. Крізь нього (роутер): PREROUTING → маршрутизація → FORWARD → POSTROUTING. Раніше за всіх на інтерфейсі виконуються ланцюжки netdev ingress; на виході ланцюжки netdev egress працюють на пристрої, перед tc egress і qdisc.
See:Дивись: Receive 5Прийом 5 · Receive 7Прийом 7 · Send 7Відправка 7 · Send 8Відправка 8 · Forward 8Пересилання 8 · Receive 4Прийом 4 · Send 11Відправка 11
A transit packet never passes INPUT or OUTPUT. It goes through FORWARD, so filtering rules for routed traffic belong there.Транзитний пакет ніколи не проходить INPUT чи OUTPUT. Він іде через FORWARD, тож правила для трафіку, що маршрутизується, мають бути там.
See:Дивись: Forward 8Пересилання 8
Destination NAT (port forwarding) runs in PREROUTING for incoming packets, before the routing decision, so the new address decides where the packet goes; for the host’s own connections the nat table runs in OUTPUT. Source NAT and masquerade run in POSTROUTING, after routing: that is how a home router or a Kubernetes node rewrites the source address to its own.Destination NAT (проброс портів) виконується в PREROUTING для вхідних пакетів, до рішення маршрутизації, тож куди піде пакет, вирішує вже нова адреса; для власних з’єднань хоста таблиця nat працює в OUTPUT. Source NAT і masquerade виконуються в POSTROUTING, після маршрутизації: так домашній роутер чи вузол Kubernetes підміняє адресу відправника на свою.
See:Дивись: Receive 5Прийом 5 · Send 7Відправка 7 · Forward 9Пересилання 9
Incoming packets: before. tcpdump gets its copy in netif_receive_skb(), before PREROUTING and its DNAT. Outgoing packets: after. The copy is taken by dev_queue_xmit_nit() at the moment the packet is handed to the driver, after POSTROUTING (SNAT) and the qdisc. So on a NAT router the outside interface shows the translated source address.Вхідні пакети — до. tcpdump отримує копію в netif_receive_skb(), до PREROUTING і його DNAT. Вихідні — після. Копію робить dev_queue_xmit_nit() у момент, коли пакет передається драйверу, після POSTROUTING (SNAT) і qdisc. Тож на NAT-роутері зовнішній інтерфейс показує вже підмінену адресу відправника.
See:Дивись: Receive 4Прийом 4 · Send 8Відправка 8 · live example, section 2живий приклад, розділ 2
First, forwarding must be on: with net.ipv4.ip_forward = 0 a packet for another host is simply dropped at the routing decision. Then the FORWARD chain must let it through. A packet whose TTL runs out is dropped too, and the sender gets ICMP “time exceeded”.Спершу має бути ввімкнене пересилання: з net.ipv4.ip_forward = 0 пакет для іншого хоста просто відкидається на рішенні маршрутизації. Далі його має пропустити ланцюжок FORWARD. Пакет, у якого закінчився TTL, теж відкидається, а відправник отримує ICMP «time exceeded».
See:Дивись: Receive 6Прийом 6 · Forward 7Пересилання 7 · Forward 8Пересилання 8
The route is fine, but nobody answered ARP. The kernel asks “who has this IP?” about three times; with no reply the neighbour entry goes from INCOMPLETE to FAILED, the waiting packets are dropped, and the local application gets “No route to host”. Check with ip neigh show.Маршрут у порядку, але ніхто не відповів на ARP. Ядро питає «у кого ця IP?» приблизно тричі; без відповіді запис сусіда переходить з INCOMPLETE у FAILED, пакети, що чекали, відкидаються, а локальний застосунок отримує «No route to host». Перевір через ip neigh show.
See:Дивись: Send 10Відправка 10
Probably a Path MTU black hole. A router can’t forward a packet larger than the next link’s MTU when Don’t Fragment is set, so it drops it and sends back ICMP “fragmentation needed”. If a firewall on the way blocks that ICMP, the sender never learns to send smaller packets.Ймовірно, «чорна діра» Path MTU. Роутер не може переслати пакет, більший за MTU наступного каналу, якщо стоїть Don’t Fragment, тому відкидає його і шле назад ICMP «fragmentation needed». Якщо файрвол по дорозі блокує цей ICMP, відправник так і не дізнається, що треба слати менші пакети.
See:Дивись: Forward 7Пересилання 7
The physical card is a bridge port, so its rx_handler() hands the frame to the bridge instead of IP. The bridge looks up the destination MAC and sends the frame out of the right port: the host end of the container’s veth pair. veth passes the same sk_buff to its peer, eth0 in the container’s network namespace, and receiving starts again there. Between containers on one bridge, frames are switched at layer 2 and IP on the host never sees them.Фізична карта — порт бриджа, тож її rx_handler() віддає кадр бриджу, а не IP. Бридж шукає MAC отримувача і відправляє кадр у потрібний порт: хостовий кінець veth-пари контейнера. veth передає той самий sk_buff своєму парному кінцю, eth0 у мережевому просторі імен контейнера, і там прийом починається знову. Між контейнерами на одному бриджі кадри комутуються на рівні 2, і IP хоста їх не бачить.
See:Дивись: Receive 4Прийом 4 · Bridge 5Бридж 5 · Bridge 6Бридж 6 · Bridge 8Бридж 8 · Bridge 9Бридж 9
There is no bridge. A tc BPF program on the host interface sees the packet right after the sniffers, before netfilter and IP, and redirects it into the pod with bpf_redirect_peer(). The packet skips the veth transmit and the backlog queue and continues inside the pod in the same softirq run.Бриджа немає. BPF-програма tc на інтерфейсі хоста бачить пакет одразу після сніферів, до netfilter і IP, і перенаправляє його в под через bpf_redirect_peer(). Пакет оминає відправку через veth і чергу backlog і продовжує шлях усередині пода в тому самому проході softirq.
See:Дивись: tc redirect 5tc redirect 5 · tc redirect 6tc redirect 6
Bridged frames normally bypass IP entirely. With the br_netfilter module loaded and net.bridge.bridge-nf-call-iptables = 1, IPv4 packets crossing the bridge also pass the regular iptables chains. Kubernetes relies on this to apply Service rules to traffic between pods on one node.Кадри через бридж зазвичай повністю оминають IP. Якщо завантажений модуль br_netfilter і net.bridge.bridge-nf-call-iptables = 1, IPv4-пакети через бридж проходять і звичайні ланцюжки iptables. На цьому Kubernetes будує правила Service для трафіку між подами на одному вузлі.
See:Дивись: Bridge 5Бридж 5
An application joins the group with setsockopt(IP_ADD_MEMBERSHIP). The kernel adds the group’s multicast MAC to the card’s filter and sends an IGMP membership report, so switches and routers start sending the group to this host. Check with ip maddr show.Застосунок приєднується до групи через setsockopt(IP_ADD_MEMBERSHIP). Ядро додає мультикаст-MAC групи у фільтр карти і шле IGMP membership report, щоб комутатори й роутери почали надсилати групу цьому хосту. Перевір через ip maddr show.
See:Дивись: Multicast 2Мультикаст 2 · Multicast 8Мультикаст 8
Only with a multicast routing daemon such as pimd or smcroute, which turns multicast forwarding on. Then ip_mr_input() looks the group up in the multicast routing cache and sends copies out of the listed interfaces (ip mroute show).Лише з демоном мультикаст-маршрутизації, як-от pimd чи smcroute, який вмикає мультикаст-пересилання. Тоді ip_mr_input() шукає групу в кеші мультикаст-маршрутів і відправляє копії в перелічені інтерфейси (ip mroute show).
See:Дивись: Receive UDP 6Прийом UDP 6 · Multicast router 7Мультикаст-роутер 7 · Multicast router 8Мультикаст-роутер 8
The card’s interrupt handler only schedules NAPI. The packets themselves are processed in batches by the NET_RX softirq, and under load that work moves to the ksoftirqd threads. /proc/net/softnet_stat shows per CPU how many packets were processed and how often the budget ran out; /proc/interrupts shows which CPUs take the card’s interrupts.Обробник переривання карти лише планує NAPI. Самі пакети обробляються пачками в softirq NET_RX, а під навантаженням ця робота переходить у потоки ksoftirqd. /proc/net/softnet_stat показує по кожному CPU, скільки пакетів оброблено і як часто закінчувався бюджет; /proc/interrupts — які CPU приймають переривання карти.
See:Дивись: Receive 3Прийом 3 · live example, section 7живий приклад, розділ 7