Guide

ADD-PATH and PATHS-LIMIT

ADD-PATH (RFC 7911) allows multiple paths per prefix by including a Path Identifier with each NLRI. Route servers use it to forward all available paths rather than one best path.

PATHS-LIMIT (draft-abraitis-idr-addpath-paths-limit-04) lets a receiver request a maximum number of paths per prefix per family. Ze enforces the peer's negotiated limit on outbound routes.

Configuration

All ADD-PATH and PATHS-LIMIT config lives under session > capability > add-path.

Default Direction and Limit

Enable ADD-PATH for all negotiated families, with an optional default path count limit:

capability {
    add-path {
        direction send/receive;
        limit 10;
    }
}

The limit on the container is inherited by all families. Per-family entries can override it.

Per-Family Override

Override direction, set path count limits, or set negotiation mode per family:

capability {
    add-path {
        direction send;
        family {
            ipv4/unicast {
                direction send/receive;
                limit 10;
            }
            ipv6/unicast {
                direction receive;
                mode require;
            }
        }
    }
}

A family entry can carry no block at all. family { ipv4/unicast; } takes the container direction and the container limit. A bare entry adds no family when the container states no direction.

Full Example

bgp {
    peer transit-a {
        connection {
            remote { ip 10.0.0.1; }
            local { ip 10.0.0.2; }
        }
        session {
            asn { local 65000; remote 65001; }
            capability {
                add-path {
                    direction send/receive;
                    family {
                        ipv4/unicast { limit 10; }
                    }
                }
            }
            family {
                ipv4/unicast { prefix { maximum 1000; } }
                ipv6/unicast { prefix { maximum 1000; } }
            }
        }
    }
}

Direction and Mode

Direction Meaning
send Advertise multiple paths to peer
receive Accept multiple paths from peer
send/receive Both directions
Mode Meaning
enable (default) Negotiate ADD-PATH if peer supports it
require Reject peer if it does not support ADD-PATH
refuse Reject peer if it advertises ADD-PATH
disable Do not negotiate ADD-PATH for this family

PATHS-LIMIT

The limit leaf advertises a PATHS-LIMIT capability (code 76) for the family. The value (1-65535) requests the maximum number of paths per prefix Ze wants to receive.

This local limit is a receiver request, not a guarantee that the peer obeys it. It does not set Ze's outbound limit.

Setting Effect
Ze requests no path count limit for that family
limit 10 Request at most 10 paths per prefix from the peer
limit 1 Request one path per prefix, still with ADD-PATH identifiers
limit under mode disable Ze advertises no limit for the family. A limit reaches the wire only for a family Ze advertises in ADD-PATH

The peer's nonzero limit applies only when Ze negotiates ADD-PATH send for that family. Ze's local limit applies only to negotiated ADD-PATH receive. An absent limit or an unnegotiated ADD-PATH direction imposes no PATHS-LIMIT restriction.

Outbound Enforcement

Ze counts distinct advertised path IDs for each AFI/SAFI and prefix on the destination connection. The count persists across UPDATE messages and batches. All normal send and forwarding paths share this count, including route-server fast-path forwarding.

The count uses each family's route identity, not its forwarding fields. Labels do not create a new labeled IP prefix; VPN route distinguishers do. EVPN, VPLS, and MUP omit their non-key forwarding fields. Insignificant prefix padding cannot create another slot.

Event Effect
New path below the limit Admit the path and count its ID
New path at the limit Suppress the announcement
Replacement with an admitted path ID Send the replacement without consuming another slot
Withdrawal of an admitted path ID Remove the ID and free its slot
Destination reconnect Start with an empty count for the new connection

The first admitted paths keep their slots. Ze does not select the best paths or queue suppressed paths for later transmission. A later re-announcement can retry after a withdrawal frees a slot.

Named transactions retain separate path IDs for one prefix. They emit routes in deterministic identity order, with ascending path IDs for the same prefix. A lower ID does not displace a path admitted earlier on the connection.

The deliberate send ... raw message diagnostic command sends exact bytes outside normal route admission. PATHS-LIMIT does not filter this command.

How It Works

When ADD-PATH is negotiated, each NLRI is prefixed with a 4-byte Path Identifier. This allows the same prefix (e.g., 10.0.0.0/24) to appear multiple times with different path IDs, each carrying different attributes.

Wire Format

Without ADD-PATH:

[prefix-length][prefix-bytes]

With ADD-PATH:

[4-byte path-id][prefix-length][prefix-bytes]

Encoding Context

Peers that negotiate the same ADD-PATH modes share an encoding context (ContextID). The route server can forward wire bytes unchanged between peers with matching contexts, avoiding re-encoding.

Route Withdrawal

In an ADD-PATH direction, a withdrawal includes the same path ID used in the announcement. Withdrawing one ID leaves the other paths for that prefix in place. Path ID zero is a valid identifier, not an instruction to withdraw every path.

Ze Generates Its Own Path Identifiers

RFC 7911 Section 2 requires a speaker that re-advertises a route to generate its own Path Identifier, and to assign it so that (prefix, identifier) uniquely names a path advertised to a neighbor. Both forward rails do that instead of relaying the identifier the source chose.

Each route-server client picks its identifiers alone. Two clients that both pick 1 for one prefix would reach a third client as one (prefix, identifier) pair, and RFC 7911 Section 5 makes the receiver treat the second as a replacement for the first, so one path is lost. A source that negotiated no ADD-PATH sends every path under identifier 0, so without regeneration every path from every ordinary client reached an ADD-PATH client as (prefix, 0).

Property Behavior
Key The path at ingress, never the message and never the attributes. How much of the path the key holds follows what the source framed: a source that negotiated no ADD-PATH gets one identifier for its whole session, and a source that negotiated it gets one entry per family, received identifier and prefix
Withdrawal A withdrawn route carries no path attributes, so the ingress key is the only key that can be recomputed when the path leaves. The withdrawal names the identifier Ze advertised
Re-announcement A source that re-announces one path with changed attributes keeps the identifier it already has, so the destination sees a replacement rather than a duplicate
Release A source that framed no identifier holds its one entry until the peer is removed. A source that framed one has each pair freed when Ze has relayed that pair's withdraw. Neither is released at session down, so a reconnecting peer re-announces under the identifiers its destinations already hold
Zero Minted and accepted like any other value, which RFC 7911 Section 3 requires

Regeneration runs whenever either side of the forward frames identifiers. A session where neither side negotiated ADD-PATH keeps its zero-copy forward.

Interaction with Route Reflection

ADD-PATH fits the route server plugin (bgp-rs). Without ADD-PATH, the route server can only forward one path per prefix to each peer. With ADD-PATH, it forwards received paths within each destination's negotiated PATHS-LIMIT. Downstream routers make their own best-path decisions.