Skip to content

static routes

Thomas Mangin edited this page Jul 25, 2026 · 5 revisions

Pre-Alpha. This page describes behavior that may change.

Ze supports static routes with ECMP, weighted load balancing, BFD-tracked failover, blackhole, and reject. Routes are programmed directly to the kernel via netlink (or VPP when available).

Configuration

Routes live under named tables. The default table maps to the kernel main routing table.

static {
    table default {
        route 0.0.0.0/0 {
            next-hop 10.0.0.1 { }
        }
    }
}

Multiple next-hops (ECMP)

All next-hops are installed simultaneously as a multipath route:

static {
    table default {
        route 10.0.0.0/8 {
            next-hop 192.168.1.1 { }
            next-hop 192.168.1.2 { }
            next-hop 192.168.1.3 { }
        }
    }
}

Weighted ECMP

The weight field controls traffic distribution. Higher weight means more traffic. Default is 1 (equal distribution).

static {
    table default {
        route 0.0.0.0/0 {
            next-hop 10.0.0.1 {
                weight 3;
            }
            next-hop 10.0.0.2 {
                weight 1;
            }
        }
    }
}

This sends 75% of traffic via 10.0.0.1 and 25% via 10.0.0.2.

BFD failover

Reference a BFD profile on each next-hop. When the BFD session goes down, that next-hop is removed from the ECMP group and the route is reprogrammed with the remaining active next-hops. When the session recovers, the next-hop is re-added.

bfd {
    profile wan-fast {
        detect-multiplier 3;
        desired-min-tx-us 100000;
        required-min-rx-us 100000;
    }
}

static {
    table default {
        route 0.0.0.0/0 {
            next-hop 10.0.0.1 {
                weight 3;
                bfd-profile wan-fast;
            }
            next-hop 10.0.0.2 {
                weight 1;
                bfd-profile wan-fast;
            }
        }
    }
}

If all BFD-tracked next-hops go down, the route is withdrawn entirely.

Blackhole and reject

Blackhole silently discards matching packets. Reject discards and sends an ICMP unreachable reply.

static {
    table default {
        route 192.0.2.0/24 {
            blackhole { }
        }
        route 198.51.100.0/24 {
            reject { }
        }
    }
}

IPv6

IPv6 routes work the same way. For link-local next-hops, specify the outgoing interface:

static {
    table default {
        route 2001:db8::/32 {
            next-hop 2001:db8::1 { }
        }
        route 2001:db8:1::/48 {
            next-hop fe80::1 {
                interface eth0;
            }
        }
    }
}

Interface-only next-hops

For point-to-point links (PPPoE, GRE) where no gateway address is available, specify only the outgoing interface:

static {
    table default {
        route 0.0.0.0/0 {
            next-hop {
                interface pppoe0;
            }
        }
    }
}

Interface-only and gateway next-hops can be mixed in the same ECMP group. BFD profiles are not supported on interface-only next-hops (there is no peer address to probe).

Routing tables

Routes are grouped under named tables for policy-based routing. The default table maps to the kernel main table. Non-default tables require a routing-table registry entry mapping names to kernel table IDs.

routing-table {
    table custom {
        id 100;
    }
}

static {
    table default {
        route 0.0.0.0/0 {
            next-hop 10.0.0.1 { }
        }
    }
    table custom {
        route 192.168.0.0/16 {
            next-hop 10.0.1.1 { }
        }
    }
}
Path Type Description
routing-table/table/<name>/id uint32 Kernel table ID. Range: 1-252, 256+. IDs 0, 253-255 are reserved.

Non-default table routes skip BGP redistribution (they are for policy routing only, not for advertisement).

Route attributes

static {
    table default {
        route 172.16.0.0/12 {
            description "internal networks";
            metric 100;
            tag 42;
            next-hop 10.0.0.1 { }
        }
    }
}
  • description: operator note (not programmed to kernel).
  • metric: kernel route priority (lower is preferred).
  • tag: opaque value for route policy matching in redistribute.

CLI

ze> show static

Shows all configured static routes with their prefixes, next-hops, weights, and BFD status in JSON format.

Route programming

Static routes are programmed with RTPROT_ZE (protocol 250), the same identifier used by the FIB kernel plugin. On config reload, the plugin computes the diff between old and new routes and applies only the changes.

Kernel ECMP uses RTA_MULTIPATH with per-next-hop weight mapped from the weight field (kernel weight = weight - 1).

One bad route does not take down the section

A route the backend cannot program, typically because its next-hop does not resolve, is isolated rather than fatal. Everything else in static { } is applied, the failed route is recorded and logged at WARN, and configuration proceeds. The skipped route stays out of the diff baseline, so it is retried on the next apply and picked up as soon as its next-hop appears.

When the skipped route was replacing an existing one, the old route is withdrawn rather than left behind, both from the FIB and from redistribution. Leaving the stale entry programmed would blackhole traffic against a route the operator has already replaced.

The isolation is visible, not silent. Skipped routes appear in show static marked skipped with a skip-reason, and ze doctor reports them under doctor-static-route-skipped.

ze cli -c "show static"        # skipped routes carry skipped + skip-reason
ze doctor --json               # doctor-static-route-skipped when any are held back
ze explain doctor-static-route-skipped

Running the static plugin as an external process is a related trap: interface next-hops cannot be resolved from outside the daemon process, and the plugin warns at startup when it detects that.

Redistribute

Static routes register as protocol "static" in the redistribute framework. BGP redistribute can import static routes:

redistribute {
    destination bgp {
        import static { }
    }
}

See also

  • FIB for how routes reach the forwarding table.
  • BFD for the BFD profiles referenced in failover config.
  • Policy Routing for L3/L4-based traffic steering.

Adapted from main/docs/guide/static-routes.md.

Home

About

First Steps

Configuration

Operation

Interfaces

Plugins

Plugin Development

Chaos Testing

Blueprints

Development

Reference

Clone this wiki locally