How Linux Network Packet Transmission Works: From LAN Encapsulation to Cross-Network Routing

This article breaks down the complete Linux network transmission path from application send to target process receive. It covers LAN communication, cross-network routing, TCP/IP layered encapsulation, and the Linux kernel’s sk_buff packet-processing model to answer the question: where does data go after send()? Keywords: Linux networking, MAC/IP, route forwarding.

Technical Specifications at a Glance

Parameter Description
Domain Linux network transmission principles
Core Language C / C++
Protocol Stack Ethernet, IP, TCP/UDP, ARP
Runtime Environment Linux kernel networking subsystem
Core Dependencies socket, sk_buff, tcphdr, iphdr
Reference Popularity Originally marked with 623 views and 45 likes
Content Format Conceptual explanation + kernel structs + routing workflow

This article builds a unified mental model from the application layer to the link layer

Many backend engineers know how to call send(), capture packets, and troubleshoot timeouts, but they still lack a complete picture of how data actually moves through the protocol stack. As a result, once an issue involves packet loss, incorrect routing, TTL, ARP, or port demultiplexing, troubleshooting quickly loses focus.

The core value of this article is not to repeat textbook material. Instead, it closes the loop across three questions: who handles LAN addressing, who handles internet-wide routing, and how the Linux kernel efficiently performs encapsulation and decapsulation.

Network transmission workflow overview AI Visual Insight: This diagram provides a global view of how data descends through the layers from the application, leaves through the NIC, and then moves upward layer by layer on the destination host. It is the ideal entry point for understanding “logical layered communication, physical hop-by-hop delivery.”

The delivery analogy maps packet headers and payloads precisely

A network packet maps cleanly to parcel delivery: the actual business data is the payload, while the control information added around it is the header. Each protocol layer prepends its own “shipping label” to tell the next layer how to handle the data.

This analogy matters because it explains that encapsulation does not “rewrite the original data.” Instead, it appends structured control metadata around the original data. On the receiving side, the stack removes these headers in reverse order and dispatches the payload to the correct module based on header fields.

Encapsulation and payload diagram AI Visual Insight: This diagram typically uses a parcel, a shipping label, and contents to illustrate the relationship between headers and payloads. It emphasizes that protocol fields are not business data themselves, but control metadata used by network devices and protocol stacks for forwarding, validation, and demultiplexing.

MAC addresses and IP addresses serve different layers of addressing

A MAC address works at the data link layer and answers the question, “Who should receive this frame on the current LAN hop?” An IP address works at the network layer and answers the question, “Which host should ultimately receive this packet across the internet?” These are not competing mechanisms. They cooperate to deliver hop-by-hop forwarding and end-to-end addressing.

The most important rule is this: once a packet crosses a router, the MAC address changes, while the IP address usually does not. That is why packet captures show different Ethernet frame headers at each hop while the source and destination IPs in the IP header remain stable.

MAC addresses determine local delivery within a LAN

A MAC address is a NIC-level identifier, typically 48 bits long. Its real value is not simply “global uniqueness,” but the fact that a NIC can quickly determine whether an incoming frame is intended for it.

In traditional shared Ethernet, simultaneous transmission from multiple devices could cause collisions, which is why CSMA/CD existed. Modern switches dramatically reduce physical collisions, but understanding the concept of a collision domain remains foundational for interviews and troubleshooting.

ip addr  # View NIC addresses and link-layer information
ip route # View the routing table and verify the default gateway

These commands help you confirm the local host’s MAC/IP information and the next-hop decision basis for cross-network communication.

IP addresses define end-to-end routing targets

An IPv4 address is a 32-bit logical address. Its real significance goes beyond acting like a street number. Routers and hosts can process it using routing tables, subnet masks, and prefix matching. The network layer relies on these mechanisms to determine the destination subnet, select the next hop, and plan the delivery path.

In that sense, an IP address is fundamentally a computable, aggregatable, and routable address system. Without it, the internet would remain a set of isolated Layer 2 broadcast domains rather than a globally interconnected network.

MAC vs. IP comparison diagram AI Visual Insight: This diagram usually compares MAC and IP side by side in terms of layer, format, and scope. It is especially useful for understanding the key idea that “MAC handles the local hop, while IP handles the global path,” and it works well as a compact interview explanation template.

LAN communication is fundamentally layered encapsulation and layered demultiplexing

A typical LAN transmission works like this: the application generates data, the transport layer adds ports and reliability fields, the network layer adds IP routing information, the link layer adds MAC addresses and frame type, and the NIC finally transmits the frame onto the physical medium.

The receiving side performs the exact reverse process: it checks the destination MAC first, then the IP protocol number, then the TCP/UDP destination port, and finally delivers the payload to the target process. The key concept here is not just “transmission,” but “demultiplexing.”

The TCP header binds data to a specific process and transport semantic

In the TCP header, port numbers identify the process, sequence and acknowledgment numbers support reliable delivery, the window field supports flow control, and flags support connection state management. Together, these fields define TCP not as “sending bytes,” but as “sending a byte stream according to strict rules.”

struct tcphdr {
    __be16 source;   // Source port: identifies the sending process
    __be16 dest;     // Destination port: identifies the receiving process
    __be32 seq;      // Sequence number: guarantees ordered delivery
    __be32 ack_seq;  // Acknowledgment number: enables reliable acknowledgment
    __be16 window;   // Window size: used for flow control
    __sum16 check;   // Checksum: detects transmission corruption
};

This struct captures TCP’s three core responsibilities: demultiplexing, reliability, and flow control.

The IP header encapsulates a segment as a routable datagram

The IP layer does not care about application semantics. It only cares where the datagram should go, how many hops it can survive, and which upper-layer protocol it carries. The protocol field decides whether the payload should be passed to TCP or UDP, ttl prevents infinite routing loops, and saddr/daddr provide stable end-to-end identities.

struct iphdr {
    __u8 ihl:4, version:4; // Version and header length
    __u8 tos;              // Type of service
    __be16 tot_len;        // Total length
    __u8 ttl;              // Time to live: decremented by 1 at each hop
    __u8 protocol;         // Upper-layer protocol number: 6=TCP, 17=UDP
    __be32 saddr;          // Source IP address
    __be32 daddr;          // Destination IP address
};

This struct shows that the IP layer is fundamentally responsible for addressing, routing, and upper-layer protocol dispatch.

The Linux kernel uses sk_buff to organize encapsulation and decapsulation efficiently

User space sees send(), but the kernel actually manages packets through sk_buff. It is not just a simple buffer. It is a packet descriptor organized around header pointers, a data area, and protocol-layer offsets.

The key to high performance is this: encapsulation usually does not require large-scale payload copying. Instead, the kernel moves header pointers, reserves space for new protocol headers, and then writes the necessary fields. This reduces memory copying and cache pollution.

struct iphdr *iph;

iph = (struct iphdr *)skb_push(skb, sizeof(struct iphdr)); // Move the head pointer backward to reserve the IP header
iph->version = 4;              // Specify IPv4
iph->ihl = 5;                  // Header length: 20 bytes
iph->ttl = 64;                 // Default hop limit
iph->protocol = IPPROTO_TCP;   // Upper-layer protocol is TCP
iph->saddr = source_ip;        // Fill in the source IP
iph->daddr = dest_ip;          // Fill in the destination IP
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); // Compute the header checksum

This pseudocode shows the core IP-header encapsulation steps in the kernel: reserve space, fill fields, and compute the checksum.

Cross-network communication depends on routers for hop-by-hop forwarding rather than direct end-to-end delivery

When the destination IP is outside the local subnet, the source host does not look up the destination host’s MAC address directly. Instead, it sends the data to the default gateway first. In that case, the destination MAC in the Ethernet frame belongs to the gateway interface, not the remote host.

After the router receives the frame, it strips the Layer 2 header, reads the destination IP address, looks up the routing table, selects an outbound interface, and then re-encapsulates the packet with a new Layer 2 header for the next hop. That is the precise meaning of “IP stays the same, while MAC is updated at each hop.”

Hop-by-hop cross-network routing diagram AI Visual Insight: This diagram usually shows Host A, the gateway, the destination subnet, and Host B, while marking how the source and destination MAC addresses change across different link segments. It is ideal for visually explaining how routers only rewrite Layer 2 encapsulation and TTL, not the end-to-end IP addresses.

A router’s key behavior can be reduced to four steps

First, the host uses the subnet mask to determine whether the destination is on the same subnet. Second, if it is not, the host uses ARP to obtain the gateway MAC address. Third, the router decapsulates the frame and performs a route lookup. Fourth, the router re-encapsulates the packet with a new source and destination MAC address and forwards it.

This model also applies to multi-hop networks. The only difference is that the “lookup and re-encapsulate” process repeats at each hop until the packet reaches the LAN where the destination host resides.

The most practical troubleshooting framework for interviews and production should be fixed in memory

When you face a networking issue, break it down across four layers: whether the link layer delivers the frame, whether the network layer can route it, whether the transport layer demultiplexes it correctly, and whether the application layer consumes it normally. This framework is far more valuable than memorizing isolated header fields.

If a packet capture shows frames but no application data, check the destination MAC first. If data reaches the host but not the process, focus on the destination IP, protocol number, and port. If cross-network communication times out, start with the default route, ARP, TTL, and gateway reachability.

FAQ

Q1: Why can’t cross-network communication use the destination host’s MAC address directly?

A: Because a MAC address is valid only within the current Layer 2 broadcast domain. In cross-network communication, the source host cannot deliver a frame directly into a remote LAN. It must first send the frame to the local gateway, and routers then forward it hop by hop.

Q2: Why does the IP address usually stay the same while the MAC address changes?

A: The IP address identifies the two endpoints in end-to-end communication and serves as the stable identity at the network layer. The MAC address identifies the sender and receiver on the current link and belongs to the one-hop encapsulation at the data link layer, so routers must rewrite it at every hop.

Q3: What do skb_push and skb_pull do in the Linux kernel?

A: skb_push reserves space at the packet head and supports encapsulation. skb_pull consumes header space and supports decapsulation. Both improve protocol-stack efficiency by moving pointers rather than copying large blocks of data.

Core Summary: This article systematically reconstructs the full Linux network transmission workflow around MAC, IP, encapsulation/decapsulation, hop-by-hop routing, and the kernel implementation of sk_buff, helping developers move from socket calls to a deeper understanding of LAN communication and cross-network forwarding.