Skip to content

redistribution

Thomas Mangin edited this page Apr 8, 2026 · 4 revisions

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

Redistribution filters are how policy plugins attach to peers. A filter is a named entry point (<plugin>:<filter>) that the plugin declares at stage 1 of startup. You reference it under redistribution { import [...] export [...] } on a peer, a group, or the BGP globals. The engine runs the chain on every received or forwarded UPDATE.

The filter framework is implemented; the specific filter set keeps growing. The mandatory filter is rfc:otc (RFC 9234 role OTC), which runs automatically when the role plugin is loaded. Default (non-mandatory) filters are rfc:no-self-as and rfc:bogon-check. User filters are explicit.

The plugin-author side is documented on the plugin development pages. This page is for operators picking filters, not authors writing them.

A minimal example

bgp {
    redistribution {
        import [ rpki:validate ]
    }
    group customers {
        redistribution {
            import [ community:scrub ]
            export [ aspath:prepend ]
        }
        peer customer-a {
            remote { ip 10.0.0.1; as 65001; }
            redistribution {
                export [ community:mark-customer-a ]
            }
        }
    }
}

The effective chain for customer-a on import is rpki:validate -> community:scrub. On export it is aspath:prepend -> community:mark-customer-a. The mandatory filter (rfc:otc) and default filters (rfc:no-self-as, rfc:bogon-check) run first on both sides, before any user filter.

Filter syntax

Every filter is referenced as <plugin>:<filter>.

  • <plugin> is the name of the plugin that declared the filter in its stage-1 declare-registration.
  • <filter> is the name the plugin gave the filter at declaration time.

Filters are declared with a direction (import, export, or both), a list of attributes they want to receive, and a failure mode. Operators only see the references; the declarations live in the plugin.

Filter categories

The framework distinguishes three kinds of filters.

Category Behaviour Visible in config Example
Mandatory Always on, cannot be overridden. No. rfc:otc (RFC 9234 role filtering).
Default On by default, can be overridden. No (override via a user filter). rfc:no-self-as (loop prevention).
User Only when explicitly configured. Yes. rpki:validate, community:scrub.

Mandatory and default filters do not appear in config. What you see in the config is only the user-level chain.

How the chain resolves

Chains are cumulative across config levels. The effective chain for a peer is the concatenation of the mandatory filters, the default filters, the BGP-level user chain, the group's user chain, and the peer's user chain, in that order.

Level Merge rule
Mandatory Always first, implicit.
Default After mandatory, implicit.
bgp { redistribution } Base user chain.
group { redistribution } Appended to the BGP chain.
peer { redistribution } Appended to the group chain.

If the BGP globals declare rpki:validate, the group declares community:scrub, and the peer declares aspath:prepend, the effective import chain for that peer is:

[rfc:otc] -> [rfc:no-self-as] -> [rfc:bogon-check] -> rpki:validate -> community:scrub -> aspath:prepend

Mandatory filters are always in brackets in this notation because you cannot remove them.

Overriding a default filter

A user filter can declare that it overrides a specific default filter. When the user filter is present on a peer, the overridden default is removed from that peer's chain. Mandatory filters cannot be overridden.

peer special {
    remote { ip 10.0.0.2; as 65002; }
    redistribution {
        import [ allow-own-as:relaxed ]
    }
}

If allow-own-as:relaxed declares overrides: ["rfc:no-self-as"], then rfc:no-self-as is removed from this peer's chain, and Ze stops rejecting routes that carry the local ASN in the AS_PATH. Every other peer still has rfc:no-self-as, because the override is local.

This is the mechanism for "I need to accept my own ASN on this one session for a specific reason". Use it sparingly.

Filter responses

Every filter, on every invocation, returns one of three responses.

Response Meaning
accept Pass the update through unchanged.
reject Drop the update. The chain short-circuits: no subsequent filter runs.
modify Change specific attributes.

On modify, the filter returns only the changed fields (delta only). The engine uses dirty tracking to re-encode only the modified attributes into the wire bytes. When the filter returns accept with no changes, nothing is re-encoded.

Failure handling

Each filter declares its failure mode at stage 1. Failure means the plugin did not respond within the timeout, or the IPC returned an error.

Mode Behaviour on failure
reject Fail-closed. The update is dropped.
accept Fail-open. The update passes through.

The plugin author picks based on the security semantics of the filter. An RPKI validator that fails closed would reject everything if the cache becomes unreachable; an RPKI validator that fails open would accept unvalidated routes. Neither is universally right. The decision lives with the plugin.

Copy-on-need on egress

This is where the filter framework interacts with Ze's zero-copy architecture. On the egress side, a filter writes attribute modifications into a ModAccumulator that is lazy: if nothing writes to it, no copy of the wire bytes is allocated. A destination peer with no egress-modifying filters gets the cached bytes unchanged when the source and destination share an encoding context.

This is why a route server with identical peers stays fast even with filters declared: the filters run, but they do not allocate when they do not modify.

Writing your own filter

Writing a filter plugin is the same as writing any Ze plugin, except that the plugin's stage-1 declare-registration includes a filters field listing the filters it provides. See plugin development for the general plugin surface and the in-tree architecture reference for the wire protocol.

See also

Adapted from main/docs/guide/redistribution.md.

Home

About

First Steps

Configuration

Operation

Interfaces

Plugins

Plugin Development

Chaos Testing

Blueprints

Development

Reference

Clone this wiki locally