How to Create and Configure GENEVE Tunnel Interfaces in Linux Using ip link

Modern data centres and cloud environments rely heavily on network virtualisation to interconnect virtual machines and container workloads across physical underlay infrastructures. While Virtual Extensible LAN (VXLAN) has long been the dominant standard for Layer 2 over Layer 3 overlay networks, the Generic Network Virtualization Encapsulation (GENEVE) protocol, codified in RFC 8926, was engineered to unite the best attributes of VXLAN, NVGRE, and STT while introducing flexible, extensible metadata capabilities.

GENEVE operates by encapsulating standard Ethernet frames inside UDP packets using destination port 6081. Because it supports variable-length Type-Length-Value (TLV) option headers, GENEVE has become the default tunnel encapsulation protocol for modern Software-Defined Networking (SDN) solutions, such as Open Virtual Network (OVN) and Kubernetes CNI plugins. In this tutorial, you will learn how to create, configure, inspect, and troubleshoot native GENEVE tunnel interfaces in Linux using the standard ip link suite.

Understanding GENEVE Protocol Architecture and Headers

Before deploying tunnel endpoints, it is beneficial to understand how GENEVE handles encapsulation within the Linux network stack:

  • UDP Encapsulation: GENEVE wraps inner frames in UDP datagrams assigned to IANA standard destination port 6081. The source port is dynamically hashed from inner packet headers to enable Equal-Cost Multi-Path (ECMP) load balancing across network switches.
  • Virtual Network Identifier (VNI): Similar to VXLAN, GENEVE utilises a 24-bit VNI field, accommodating over 16 million logically isolated virtual broadcast domains across a shared physical network.
  • Extensible TLV Options: Unlike VXLAN fixed headers, GENEVE allows SDN controllers to append custom metadata fields (such as tenant tags, security group identifiers, and flow telemetry) without modifying the underlying protocol.
  • Header Overhead and MTU: The basic GENEVE header occupies 8 bytes, placed behind an 8-byte UDP header and a 20-byte outer IPv4 header (or 40-byte IPv6 header). Together with the 14-byte inner Ethernet header, GENEVE adds a minimum of 50 bytes of encapsulation overhead. Consequently, overlay interface MTUs must be reduced to 1450 on standard 1500-byte networks, or underlay networks must enable jumbo frames (typically MTU 9000).

Step 1: Verify Linux Kernel GENEVE Module Support

The Linux kernel includes native support for GENEVE. Confirm that the kernel module is loaded on your system using the following commands in your terminal:

# Load the geneve kernel module
sudo modprobe geneve

# Verify the module is active
lsmod | grep geneve

If the module loads without error and appears in the lsmod output, your kernel is fully equipped to instantiate GENEVE network interfaces.

Step 2: Create a Point-to-Point GENEVE Interface with ip link

To establish a tunnel between two Linux hosts, define the tunnel interface parameters using ip link add. Consider an architecture where Host A has physical IP 192.168.10.10 and Host B has physical IP 192.168.10.20.

Execute the following command on Host A:

sudo ip link add name geneve0 type geneve id 100 remote 192.168.10.20 dstport 6081

Let us break down each parameter passed to ip link:

  • name geneve0: Specifies the identifier for the new virtual network device.
  • type geneve: Instructs the netlink driver to create a GENEVE tunnel device.
  • id 100: Sets the 24-bit Virtual Network Identifier (VNI) to 100. Both endpoints must share the same VNI to communicate.
  • remote 192.168.10.20: Designates the remote underlay IPv4 address of Host B.
  • dstport 6081: Explicitly sets the destination UDP port to the IANA standard 6081.

Next, perform the reciprocal configuration on Host B, pointing back to Host A:

sudo ip link add name geneve0 type geneve id 100 remote 192.168.10.10 dstport 6081

Step 3: Assign Overlay IP Addresses and Bring Interfaces Up

Now that the virtual devices exist, configure private overlay IP addresses on both endpoints and bring the link state up.

On Host A:

# Assign an overlay subnet IP
sudo ip addr add 10.200.1.1/24 dev geneve0

# Configure MTU to avoid packet fragmentation
sudo ip link set dev geneve0 mtu 1450

# Bring the interface up
sudo ip link set dev geneve0 up

On Host B:

# Assign the peer overlay IP
sudo ip addr add 10.200.1.2/24 dev geneve0

# Match MTU configuration
sudo ip link set dev geneve0 mtu 1450

# Bring the interface up
sudo ip link set dev geneve0 up

Step 4: Inspect and Validate Tunnel Configuration

To review the detailed parameters of the instantiated GENEVE device, pass the -d (details) flag to ip link show:

ip -d link show dev geneve0

You will observe output similar to the following:

5: geneve0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:7a:5b:12 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65485 
    geneve id 100 remote 192.168.10.20 dstport 6081 ttl auto tos inherit df set

To test end-to-end communication across the newly created GENEVE overlay, execute a standard ICMP ping from Host A to Host B:

ping -c 4 10.200.1.2

If the ping succeeds, your encapsulated GENEVE packets are successfully transiting the physical underlay network.

Step 5: Monitor Encapsulated Packets with tcpdump

To observe GENEVE encapsulation in action, run tcpdump on the underlying physical interface (e.g. eth0) while running the ping test:

sudo tcpdump -ni eth0 udp port 6081 -vv

The packet trace will display outer UDP datagrams carrying the GENEVE header, complete with the designated VNI (vni 0x64, which corresponds to decimal 100), encapsulating the inner ICMP echo request and reply frames.

Persisting GENEVE Interfaces Across Reboots

Interfaces created via command-line ip link are ephemeral and vanish upon reboot. On modern Linux distributions running systemd-networkd, you can make GENEVE tunnels permanent by creating configuration files in /etc/systemd/network/.

1. Create the NetDev Definition (e.g. /etc/systemd/network/25-geneve0.netdev):

[NetDev]
Name=geneve0
Kind=geneve

[GENEVE]
Id=100
Remote=192.168.10.20
DestinationPort=6081

2. Create the Network Binding (e.g. /etc/systemd/network/25-geneve0.network):

[Match]
Name=geneve0

[Network]
Address=10.200.1.1/24
LinkLocalAddressing=no

[Link]
MTUBytes=1450

Restart the network daemon to initialise the persistent interface:

sudo systemctl restart systemd-networkd

Troubleshooting Common GENEVE Configuration Issues

  • Firewall Dropping UDP Traffic: Linux firewalls (such as ufw or nftables) frequently block unsolicited incoming UDP packets. Ensure UDP port 6081 is explicitly permitted on both endpoints:
    sudo ufw allow 6081/udp
  • VNI Mismatch: If endpoints specify differing VNIs (e.g., ID 100 on one host and ID 200 on another), the receiving kernel will silently discard the inner packets. Ensure the id parameter is identical.
  • Packet Fragmentation and MTU Blackholes: If small ICMP pings succeed but large SSH sessions or file transfers stall, packet fragmentation is likely occurring. Verify that the mtu on geneve0 is reduced to at least 50 bytes below the physical underlay interface MTU.
  • Routing Conflicts: Ensure that the overlay subnet (e.g. 10.200.1.0/24) does not overlap with any physical or Docker bridge subnets configured on either host.

Frequently Asked Questions

What are the primary differences between GENEVE and VXLAN?

While both encapsulate Layer 2 Ethernet frames over UDP using 24-bit VNIs, VXLAN employs a fixed 8-byte header on port 4789. GENEVE uses port 6081 and incorporates extensible TLV option headers. This permits SDN controllers to embed arbitrary security, routing, and telemetry data within the packet without violating the protocol specification.

Can GENEVE operate in multicast mode?

Yes. By specifying a multicast group address in the remote field (e.g. remote 239.1.1.100) and binding it to a physical interface using dev eth0, GENEVE can leverage IGMP and network multicast trees for broadcast and unknown unicast frame flooding.

Is GENEVE hardware offloading supported by physical network cards?

Yes. Modern enterprise Network Interface Cards (NICs) from manufacturers such as Intel, Broadcom, Mellanox (NVIDIA), and Chelsio support native hardware offloading for GENEVE, including Checksum Offload, TSO (TCP Segmentation Offload), and RSS (Receive Side Scaling).

Can I attach a GENEVE interface to a Linux network bridge?

Yes. You can add geneve0 directly to a Linux bridge (ip link set dev geneve0 master br0) or an Open vSwitch (OVS) datapath to bridge virtual machines and container network namespaces directly across hosts.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.