Linux GRE Tunnel Persistence Issue: Unable to Delete gre0 Interface Despite Reboots


2 views

During network configuration on a Linux 2.6.26 system, I encountered persistent behavior with a GRE tunnel interface that defies normal management commands. The gre0 tunnel appears to be hardcoded or specially handled by the kernel.

# Standard deletion attempt fails
ip tunnel del gre0
ioctl: Operation not permitted

# Modification attempts also fail
ip tunnel change gre0 remote 192.168.1.100 local 192.168.1.1
ioctl: No such file or directory

This isn't a typical tunnel management problem. Key observations:

  • The interface persists across reboots
  • Other tunnels (gre1, gre2, etc.) behave normally
  • Module unloading makes it disappear temporarily
  • Reappears immediately upon module reload

The gre0 interface appears to be a default tunnel created by the ip_gre kernel module. In older Linux versions, some tunneling modules automatically create default interfaces that can't be removed through standard tools.

# Check module parameters
modinfo ip_gre | grep parm
parm:           gre_tap_dev:bool

Method 1: Blacklist the Interface

# Prevent gre0 creation on module load
echo "options ip_gre gre_tap_dev=0" > /etc/modprobe.d/gre.conf
rmmod ip_gre
modprobe ip_gre

Method 2: Kernel Module Workaround

# Create persistent configuration
echo "install ip_gre /sbin/modprobe --ignore-install ip_gre && ip link del gre0" > /etc/modprobe.d/gre_fix.conf

Method 3: Systemd Service (for modern systems)

# /etc/systemd/system/gre-cleanup.service
[Unit]
Description=GRE Tunnel Cleanup
After=network.target

[Service]
Type=oneshot
ExecStart=/sbin/ip link del gre0
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

The persistence comes from:

  • Kernel module defaults (/lib/modules/.../ip_gre.ko)
  • Potentially sysfs entries (/sys/module/ip_gre/parameters)
  • Module load configuration (/etc/modprobe.d/)

After applying any solution:

# Verify interface status
ip link show gre0 2>&1 | grep "does not exist" && echo "Success" || echo "Failed"

# Check module parameters
cat /sys/module/ip_gre/parameters/gre_tap_dev

For production systems where module modification isn't desirable:

# Create a wrapper script for tunnel management
#!/bin/bash
if [ "$1" = "del" ] && [ "$2" = "gre0" ]; then
    echo "Ignoring deletion of gre0"
    exit 0
fi
exec /sbin/ip "$@"

While working with Linux kernel 2.6.26's GRE tunnel implementation, I encountered a particularly stubborn issue where the default gre0 tunnel refused to be deleted through standard ip commands. This behavior differs from regular GRE tunnels which can be created/modified/deleted normally.

The system consistently returns errors when attempting tunnel management operations:

# ip tunnel del gre0
ioctl: Operation not permitted

# ip tunnel change gre0 remote 192.168.1.1 local 192.168.1.2
ioctl: No such file or directory

The tunnel persists across reboots and interface state changes, only disappearing when unloading the ip_gre kernel module.

The gre0 interface is automatically created by the Linux kernel's GRE module as a default tunnel device. This differs from user-created tunnels in several ways:

  • Created during module initialization
  • Maintained by kernel rather than userspace
  • Uses special internal configuration storage

Module Reload Approach

The most reliable solution is to completely unload and reload the GRE module:

# rmmod ip_gre
# modprobe ip_gre

This will destroy all GRE tunnels (including gre0) and recreate only the default gre0 tunnel with clean state.

Kernel Parameter Method

Prevent gre0 creation at module load by passing parameter:

# modprobe ip_gre ignore_df=1

For systems where gre0 must be permanently disabled:

  1. Create /etc/modprobe.d/disable-gre0.conf with:
  2. options ip_gre ignore_df=1
  3. Update initramfs (if applicable):
  4. # update-initramfs -u

The tunnel configuration survives reboots because it's stored in:

  • Kernel's internal data structures (while running)
  • Module parameters (for persistent settings)
  • Network configuration files (if manually configured)

For systems where module unloading isn't desirable, consider:

# ip link set gre0 down
# ip addr flush dev gre0

This effectively neutralizes the tunnel while keeping the interface existing.

This behavior is particularly noticeable in:

  • Linux 2.6.x kernel series
  • Early 3.x kernels

Newer kernels (4.4+) have more flexible GRE tunnel management.