Linux networking

Sockets, TCP, IP, ports, routing, packets, interfaces, drivers, DNS, iptables, and NICs all at once. The easiest way through is to follow one packet from the application to the network.

Start with one HTTPS request ↓

The picture to keep in mind

An application does not control the network card

Just like CPU scheduling, memory, and storage, an application does not directly control the network card. The application asks the Linux kernel to send or receive data, and the kernel’s networking stack handles everything required to move that data between the application and the physical network.

Suppose we have a Python application that wants to connect to an API:

requests.get("https://example.com")

At a very high level, the journey looks like this:

Linux network path from Application through Socket, Kernel, TCP or UDP, IP, Routing, Network Interface, and Device Driver down to the NIC and physical network.
Follow one packet. The application talks to a socket. The kernel walks TCP or UDP, IP, routing, the interface, and the driver before the NIC puts bits on the wire.
User Space

Everything starts with the application

Suppose we are running Nginx, Python, MySQL, Kubernetes, vLLM, or PyTorch. These applications live in User Space. They cannot simply tell the Ethernet card: “Send these bytes to another server.” Instead, they use the operating system’s networking interface. That interface starts with a socket.

User Space
├── Nginx
├── Python
├── MySQL
├── vLLM
└── PyTorch
Sockets

A socket is the endpoint the application actually talks to

A socket is simply an endpoint through which an application communicates over the network.

Application Socket Network

For example, a web server might listen on 10.0.0.10:443. The IP identifies the machine or interface. The port helps identify the application or service.

Port Service
22 SSH
80 HTTP
443 HTTPS

When Nginx listens on port 443, Linux knows that incoming connections for that socket should be delivered to Nginx.

System calls

The application asks the kernel

The application interacts with networking through system calls such as socket(), bind(), listen(), accept(), connect(), send(), and recv().

Application send() System Call Linux Kernel
This is the same User Space → Kernel Space boundary from the Kernel lesson. Networking is another service the kernel provides.
Transport

TCP and UDP

Once the request enters the kernel, Linux needs to know how the application wants to communicate. Two of the most important transport protocols are TCP and UDP.

TCP

Connection-oriented. Before sending application data, TCP normally establishes a connection. It provides reliable delivery, ordering, retransmission, flow control, and congestion control. HTTP/HTTPS commonly runs over TCP, though HTTP/3 uses QUIC over UDP.

UDP

Simpler. There is no TCP-style connection setup. UDP does not provide TCP’s built-in guarantees for delivery or ordering. Applications can build additional reliability on top when needed.

TCP three-way handshake

Before the data, TCP sets up a connection

Client Server
SYN →
← SYN-ACK
ACK →

After this, the connection is established. UDP skips that setup:

Application Send packet UDP Network
Internet Protocol

IP answers “where does this packet need to go?”

TCP or UDP has prepared the transport information. The next layer is IP — Internet Protocol. IP is responsible for addressing and moving packets between networks. For example, source 10.0.0.10 and destination 10.0.1.20.

Application Data TCP Header IP Header Packet
Routing

Linux checks the routing table before the packet leaves

Suppose the destination is 10.0.1.20. Linux checks its routing table. You can see it with:

ip route

For example:

default via 10.0.0.1 dev eth0
10.0.0.0/24 dev eth0

Linux uses this information to decide which interface, which gateway, and which route. If the destination is outside the local network, Linux may send the packet to a gateway.

Packet Routing Table eth0
Firewall

Netfilter, nftables, and iptables can still drop a healthy service

Before a packet leaves or after one arrives, Linux may apply firewall or packet-processing rules. This is handled through the kernel’s Netfilter framework. Tools such as iptables and nftables configure rules that Netfilter applies.

Allowed

Packet arrives Firewall rules Continue

Denied

Packet arrives Firewall rules Drop

This is why a service may be running perfectly but still be unreachable. Nginx can be running, port 443 can be listening, the route can be working — and the firewall still drops port 443. The application itself may have nothing wrong with it.

Network interface

After routing, Linux sends the packet toward an interface

Check interfaces with:

ip addr

or:

ip link

You might see eth0, ens5, or enp0s3. In cloud systems, names such as ens5 are common. The interface represents the network device from Linux’s perspective.

Device Driver

The kernel cannot speak every NIC the same way

It uses a device driver. The driver understands the specific hardware — an Intel NIC, a Mellanox / NVIDIA NIC, a virtio network device, or ENA on AWS.

Linux Network Stack Network Interface Device Driver NIC
Outgoing path

Finally, the NIC sends the packet

Application Socket TCP / UDP IP Routing Netfilter Network Interface Driver NIC Physical Network
That is the outgoing network path.
Incoming path

When a packet comes back, the path is roughly reversed

Network NIC Device Driver Linux Kernel IP TCP / UDP Socket Application

The kernel figures out which connection, which port, which socket, and which process — then delivers the data to the correct application.

A simple web server

Nginx listening on 10.0.0.10:443

A request arrives:

Client Network NIC Linux Driver IP TCP Port 443 Nginx Socket Nginx
Networking troubleshooting is often about finding where in this path the packet stopped.
Listening ports

How do we check which ports are listening?

One of the most important commands is:

ss -lntp

For example:

LISTEN  0  511  0.0.0.0:443  0.0.0.0:*  users:(("nginx",pid=1234))
Port 443 Listening nginx PID 1234
This is one of the first commands I would run when someone says: “My application is running, but I cannot connect to it.”
Existing connections

TCP states tell you more than “it is down”

ss -tan

You may see TCP states such as LISTEN, ESTABLISHED, SYN-SENT, SYN-RECV, TIME-WAIT, and CLOSE-WAIT.

What you see What it may mean
Many SYN-SENT The application is trying to connect but not receiving a response.
Many CLOSE-WAIT The remote side closed connections, but the local application has not properly closed its socket.

That CLOSE-WAIT pattern becomes a very useful application troubleshooting clue.

ping

The simplest network test is only one small test

ping 10.0.0.20

This helps determine whether basic IP connectivity exists. There is an important point: a successful ping does not mean the application is working. You could have ping working, but port 443 blocked, or Nginx not listening. So ping is only one small test.

Path

traceroute shows where packets go between networks

traceroute example.com

or on some systems:

tracepath example.com
Your Server Router 1 Router 2 Router 3 Destination

This becomes useful when connectivity fails somewhere between networks.

Interface statistics

ip -s link shows errors and drops

ip -s link

Look for RX packets, TX packets, errors, and dropped. RX errors increasing may indicate a driver problem, a NIC problem, a network configuration problem, or a physical/network issue.

RX errors

Packets arrived at the NIC but were corrupted or invalid. Common causes: bad cable, CRC/frame errors, duplex/link problems, or NIC/driver issues.

RX dropped

Packets arrived, but the system could not process them fast enough. Common causes: overloaded CPU, receive queues filling up, driver/NAPI backlog, or insufficient NIC ring buffers.

TX errors

The system tried to transmit but the NIC/driver encountered a problem. Common causes: NIC/driver problems, link issues, or hardware errors.

TX dropped

Packets were discarded before transmission, often because the transmit queue or qdisc became full during heavy traffic.

ethtool

Deeper NIC information lives here

ethtool eth0

This can show speed, duplex, and whether a link is detected.

For driver information:

ethtool -i eth0

You may see driver, version, and firmware-version.

For NIC statistics:

ethtool -S eth0

This can become extremely useful when debugging packet drops or hardware/driver issues.

Watch the packets

tcpdump is one of the most important network tools

Suppose an application says “I sent the request.” Instead of guessing, we can actually watch the packets.

tcpdump -i eth0

For port 443:

tcpdump -i eth0 port 443

Now you can answer: did the packet leave? Did the response come back? Did we see SYN? Did we see SYN-ACK?

Client → SYN Client → SYN Client → SYN No SYN-ACK
Repeated SYNs with no SYN-ACK tell you something very different from an application error.

This is why tcpdump is one of the most valuable Linux networking tools.

TCP retransmissions

No ACK, wait, then send it again

Suppose TCP sends a packet but does not receive confirmation. It may retransmit it.

Send packet No ACK Wait Retransmit

A high number of retransmissions can indicate packet loss, network congestion, a bad connection, an overloaded receiver, or a network path problem. You can inspect TCP statistics with:

nstat

and:

ss -s
Network buffers

Networking also depends heavily on memory

Linux maintains buffers for incoming and outgoing network data.

Receive

Network Kernel Receive Buffer Application

Send

Application Kernel Send Buffer Network

If the application cannot consume data quickly enough:

Packets arrive Receive queue grows Buffers fill Packets may be dropped

So networking is closely connected to the memory management topic we just covered.

CPU also matters

Packets need CPU time too

The CPU has to process interrupts, driver work, TCP, IP, firewall rules, and socket processing. So networking also connects to the Process Scheduler and CPU management.

CPU Scheduler Memory Manager Network Stack Network Driver NIC
These kernel components do not work independently.
GenAI

The GPU cannot start until the request arrives

Imagine we are running a GenAI inference service. The GPU might generate the tokens, but before the GPU does anything, the request must arrive over the network.

GenAI inference over the network: User, HTTPS request, load balancer, Linux server and NIC, vLLM socket, CPU preprocessing, then GPU.
A healthy GPU can still look slow if the network path is the bottleneck.

And after the GPU generates output:

GPU Application Linux Socket TCP/IP NIC User

So an inference system can have a perfectly healthy GPU and still have terrible performance because of network latency, packet loss, TCP retransmissions, connection limits, firewall problems, socket backlog, or NIC saturation.

Distributed training

Networking becomes even more important across GPU servers

Imagine training a large model on four GPU servers. The GPUs need to exchange enormous amounts of data.

GPU 0 Gradients Network GPU 1

Now networking can become one of the biggest bottlenecks. This is where technologies such as NCCL, InfiniBand, RDMA, RoCE, and GPUDirect RDMA become important. The goal is to move data between GPUs and machines as efficiently as possible.

Two paths

Traditional copies vs GPUDirect RDMA

A simplified traditional path might look like GPU → CPU memory → kernel → NIC → network. For very high-performance AI systems, technologies such as GPUDirect RDMA can reduce unnecessary CPU involvement and memory copies in supported setups.

Traditional

GPU CPU Memory Kernel NIC Network

GPUDirect RDMA

GPU NIC Network Remote GPU

That is one reason networking knowledge has become even more important in modern AI infrastructure.

Before you go

The troubleshooting journey I would teach

Question Where to look
What interfaces do I have? ip addr
What is my route? ip route
Is my application listening? ss -lntp
Can I reach the destination? ping
What path is being used? traceroute / tracepath
Are packets actually moving? tcpdump
Are there interface errors? ip -s link
What is happening at the NIC? ethtool
Need TCP statistics? ss -s / nstat

For deeper production troubleshooting, you can later introduce tc, conntrack, nft, bpftrace, eBPF networking tools, and perf.

1. Apps talk to sockets, not NICs. send() and recv() become system calls.

2. IP and routing pick the path. TCP or UDP wraps the data. The routing table picks the interface.

3. A listening process can still be unreachable. Netfilter can drop the packet after Nginx is healthy.

4. ping is not the application. Use ss, then tcpdump, when “it cannot connect.”

5. A healthy GPU can still look slow. Inference and distributed training both depend on the Linux network path.