]> git.ipfire.org Git - thirdparty/bird.git/blobdiff - doc/bird.sgml
Formalized our contribution policy which we're currently applying
[thirdparty/bird.git] / doc / bird.sgml
index 6a8183309885c5e605cc9a2551d3b64837e69f4e..8035ec18550866a69e20e02a843c800d14a5278d 100644 (file)
@@ -341,10 +341,9 @@ Configuration keywords are <cf/flow4/ and <cf/flow6/.
 <sect1>MPLS switching rules
 <label id="mpls-routes">
 
-<p>This nettype is currently a stub before implementing more support of <rfc id="3031">.
-BIRD currently does not support any label distribution protocol nor any label assignment method.
-Only the Kernel, Pipe and Static protocols can use MPLS tables.
-Configuration keyword is <cf/mpls/.
+<p>MPLS routes control MPLS forwarding in the same way as IP routes control IP
+forwarding. MPLS-aware routing protocols produce both labeled IP routes and
+corresponding MPLS routes. Configuration keyword is <cf/mpls/.
 
 <itemize>
        <item>(PK) MPLS label
@@ -403,6 +402,79 @@ regular <ref id="cli-down" name="down"> command. In this way routing neighbors
 are notified about planned graceful restart and routes are kept in kernel table
 after shutdown.
 
+<sect>MPLS
+<label id="mpls">
+
+<p>Multiprotocol Label Switching (MPLS) is a networking technology which works
+below IP routing but above the link (e.g. ethernet) layer. It is described in
+<rfc id="3031">.
+
+In regular IP forwarding, the destination address of a packet is independently
+examined in each hop, a route with longest prefix match is selected from the
+routing table, and packet is processed accordingly. In general, there is no
+difference between border routers and internal routers w.r.t. IP forwarding.
+
+In MPLS forwarding, when a packet enters the network, it is classified (based on
+destination address, ingress interface and other factors) into one of forwarding
+equivalence classes (FECs), then a header with a MPLS label identifying the FEC
+is attached to it, and the packet is forwarded. In internal routers, only the
+MPLS label is examined, the matching MPLS route is selected from the MPLS
+routing table, and the packet is processed accordingly. The specific value of
+MPLS label has local meaning only and may change between hops (that is why it is
+called label switching). When the packet leaves the network, the MPLS header is
+removed.
+
+The advantage of the MPLS approach is that other factors than the destination
+address can be considered and used consistently in the whole network, for
+example IP traffic with multiple overlapping private address ranges could be
+mixed together, or particular paths for specific flows could be defined. Another
+advantage is that MPLS forwarding by internal routers can be much simpler than
+IP forwarding, as instead of the longest prefix match algorithm it uses simpler
+exact match for MPLS route selection. The disadvantage is additional complexity
+in signaling. For further details, see <rfc id="3031">.
+
+MPLS-aware routing protocols not only distribute IP routing information, but
+they also distribute labels. Therefore, they produce labeled routes - routes
+representing label switched paths (LSPs) through the MPLS domain. Such routes
+have IP prefix and next hop address like regular (non-labeled) routes, but they
+also have local MPLS label (in route attribute <ref id="rta-mpls-label"
+name="mpls_label">) and outgoing MPLS label (as a part of the next hop). They
+are stored in regular IP routing tables.
+
+Labeled routes are used for exchange of routing information between routing
+protocols and for ingress (IP -&gt; MPLS) forwarding, but they are not directly
+used for MPLS forwarding. For that purpose <ref id="mpls-routes" name="MPLS
+routes"> are used. These are routes that have local MPLS label as a primary key
+and they are stored in the MPLS routing table.
+
+In BIRD, the whole process generally works this way: A MPLS-aware routing
+protocol (say BGP) receives routing information including remote label. It
+produces a route with attribute <ref id="rta-mpls-policy" name="mpls_policy">
+specifying desired <ref id="mpls-channel-label-policy" name="MPLS label policy">.
+Such route then passes the import filter (which could modify the MPLS label
+policy or perhaps assign a static label) and when it is accepted, a local MPLS
+label is selected (according to the label policy) and attached to the route,
+producing labeled route. When a new MPLS label is allocated, the MPLS-aware
+protocol automatically produces corresponding MPLS route. When all labeled
+routes that use specific local MPLS label are retracted, the corresponding MPLS
+route is retracted too.
+
+There are three important concepts for MPLS in BIRD: MPLS domains, MPLS tables
+and MPLS channels. MPLS domain represents an independent label space, all
+MPLS-aware protocols are associated with some MPLS domain. It is responsible for
+label management, handling label allocation requests from MPLS-aware protocols.
+MPLS table is just a routing table for MPLS routes. Routers usually have one
+MPLS domain and one MPLS table, with Kernel protocol to export MPLS routes into
+kernel FIB.
+
+MPLS channels make protocols MPLS-aware, they are responsible for keeping track
+of active FECs (and corresponding allocated labels), selecting FECs / local
+labels for labeled routes, and maintaining correspondence between labeled routes
+and MPLS routes.
+
+Note that local labels are allocated to individual MPLS-aware protocols and
+therefore it is not possible to share local labels between different protocols.
+
 
 <chapt>Configuration
 <label id="config">
@@ -471,11 +543,12 @@ ipv6 table
 include "tablename.conf";;
 </code>
 
-       <tag><label id="opt-log">log "<m/filename/" [<m/limit/ "<m/backup/"] | syslog [name <m/name/] | stderr all|{ <m/list of classes/ }</tag>
+       <tag><label id="opt-log">log "<m/filename/" [<m/limit/ "<m/backup/"] | syslog [name <m/name/] | stderr | udp <m/address/ [port <m/port/] all|{ <m/list of classes/ }</tag>
        Set logging of messages having the given class (either <cf/all/ or <cf>{
        error|trace [, <m/.../] }</cf> etc.) into selected destination - a file
        specified as a filename string (with optional log rotation information),
-       syslog (with optional name argument), or the stderr output.
+       syslog (with optional name argument), the stderr output, or as a UDP
+       message (in <rfc id="3164"> syslog format).
 
        Classes are:
        <cf/info/, <cf/warning/, <cf/error/ and <cf/fatal/ for messages about local problems,
@@ -505,6 +578,11 @@ include "tablename.conf";;
        See <ref id="channel-debug" name="debug"> in the channel section.
        Default: off.
 
+       <tag><label id="opt-debug-tables">debug tables all|off|{ states|routes|filters|events [, <m/.../] }</tag>
+       Set global defaults of table debugging options.
+       See <ref id="table-debug" name="debug"> in the table section.
+       Default: off.
+
        <tag><label id="opt-debug-commands">debug commands <m/number/</tag>
        Control logging of client connections (0 for no logging, 1 for logging
        of connects and disconnects, 2 and higher for logging of all client
@@ -539,7 +617,7 @@ include "tablename.conf";;
        Define a filter. You can learn more about filters in the following
        chapter.
 
-       <tag><label id="opt-function">function <m/name/ (<m/parameters/) <m/local variables/ { <m/commands/ }</tag>
+       <tag><label id="opt-function">function <m/name/ (<m/parameters/) [ -&gt; <m/return type/ ] <m/local variables/ { <m/commands/ }</tag>
        Define a function. You can learn more about functions in the following chapter.
 
        <tag><label id="opt-protocol">protocol rip|ospf|bgp|<m/.../ [<m/name/ [from <m/name2/]] { <m>protocol options</m> }</tag>
@@ -626,6 +704,12 @@ include "tablename.conf";;
        defined by this option. See the <ref id="rtable-opts"
        name="routing table configuration section"> for routing table options.
 
+       <tag><label id="opt-mpls-domain">mpls domain <m/name/ [ { <m/option/; [<m/.../] } ]</tag>
+       Define a new MPLS domain. MPLS domains represent independent label
+       spaces and are responsible for MPLS label management. All MPLS-aware
+       protocols are associated with some MPLS domain. See the <ref id="mpls-opts"
+       name="MPLS configuration section"> for MPLS domain options.
+
        <tag><label id="opt-eval">eval <m/expr/</tag>
        Evaluates given filter expression. It is used by the developers for testing of filters.
 </descrip>
@@ -640,6 +724,12 @@ that implicit tables (<cf/master4/ and <cf/master6/) can be redefined in order
 to set options.
 
 <descrip>
+       <tag><label id="table-debug">debug all|off|{ states|routes|filters [, <m/.../] }</tag>
+       Set table debugging options. Like in <ref id="proto-debug"
+       name="protocol debugging">, tables are capable of writing trace
+       messages about its work to the log (with category <cf/trace/).
+       For now, this does nothing, but in version 3, it is used. Default: off.
+
        <tag><label id="rtable-sorted">sorted <m/switch/</tag>
        Usually, a routing table just chooses the selected (best) route from a
        list of routes for each network, while keeping remaining routes unsorted.
@@ -838,7 +928,7 @@ agreement").
        protocol packets are processed in the local TX queues. This option is
        Linux specific. Default value is 7 (highest priority, privileged traffic).
 
-       <tag><label id="proto-pass">password "<m/password/" | <m/hex_key/ [ { <m>password options</m> } ] </tag>
+       <tag><label id="proto-pass">password "<m/password/" | <m/bytestring/ [ { <m>password options</m> } ] </tag>
        Specifies a password that can be used by the protocol as a shared secret
        key. Password option can be used more times to specify more passwords.
        If more passwords are specified, it is a protocol-dependent decision
@@ -846,10 +936,8 @@ agreement").
        authentication is enabled, authentication can be enabled by separate,
        protocol-dependent <cf/authentication/ option.
 
-        A password can also be specified as a hexadecimal key. <m/hex_key/ is a
-        sequence of hexadecimal digit pairs, optionally colon-separated. A key
-        specified this way must be at least 16 bytes (32 digits) long (although
-        specific algorithms can impose other restrictions).
+       A password can be specified as a string or as a sequence of hexadecimal
+       digit pairs (<ref id="type-bytestring" name="bytestring">).
 
        This option is allowed in BFD, OSPF, RIP, and Babel protocols. BGP has
        also <cf/password/ option, but it is slightly different and described
@@ -869,7 +957,7 @@ agreement").
 
        <tag><label id="proto-pass-gen-from">generate from "<m/time/"</tag>
        The start time of the usage of the password for packet signing.
-       The format of <cf><m/time/</cf> is <tt>dd-mm-yyyy HH:MM:SS</tt>.
+       The format of <cf><m/time/</cf> is <tt>YYYY-MM-DD [hh:mm:ss[.sss]]</tt>.
 
        <tag><label id="proto-pass-gen-to">generate to "<m/time/"</tag>
        The last time of the usage of the password for packet signing.
@@ -932,7 +1020,7 @@ inherited from templates can be updated by new definitions.
        <tag><label id="proto-export">export <m/filter/</tag>
        This is similar to the <cf>import</cf> keyword, except that it works in
        the direction from the routing table to the protocol. Default: <cf/none/
-       (except for EBGP).
+       (except for EBGP and L3VPN).
 
        <tag><label id="proto-import-keep-filtered">import keep filtered <m/switch/</tag>
        Usually, if an import filter rejects a route, the route is forgotten.
@@ -1034,6 +1122,100 @@ protocol bgp from  {
 </code>
 
 
+<sect>MPLS options
+<label id="mpls-opts">
+
+<p>The MPLS domain definition is mandatory for a MPLS router. All MPLS channels
+and MPLS-aware protocols are associated with some MPLS domain (although usually
+implicitly with the sole one). In the MPLS domain definition you can configure
+details of MPLS label allocation. Currently, there is just one option,
+<cf/label range/.
+
+<p>Note that the MPLS subsystem is experimental, it is likely that there will be
+some backward-incompatible changes in the future.
+
+<descrip>
+       <tag><label id="mpls-domain-label-range">label range <m/name/ { start <m/number/; length <m/number/; [<m/.../] }</tag>
+       Define a new label range, or redefine implicit label ranges <cf/static/
+       and <cf/dynamic/. MPLS channels use configured label ranges for dynamic
+       label allocation, while <cf/static/ label range is used for static label
+       allocation. The label range definition must specify the extent of the
+       range. By default, the range <cf/static/ is 16-1000, while the range
+       <cf/dynamic/ is 1000-10000.
+</descrip>
+
+<p>MPLS channel should be defined in each MPLS-aware protocol in addition to its
+regular channels. It is responsible for label allocation and for announcing MPLS
+routes to the MPLS routing table. Besides common <ref id="channel-opts"
+name="channel options">, MPLS channels have some specific options:
+
+<descrip>
+       <tag><label id="mpls-channel-domain">domain <m/name/</tag>
+       Specify a MPLS domain to which this channel and protocol belongs.
+       Default: The first defined MPLS domain.
+
+       <tag><label id="mpls-channel-label-range">label range <m/name/</tag>
+       Use specific label range for dynamic label allocation. Note that static
+       labels always use the range <cf/static/. Default: the range <cf/dynamic/.
+
+       <tag><label id="mpls-channel-label-policy">label policy static|prefix|aggregate|vrf</tag>
+       Label policy specifies how routes are grouped to forwarding equivalence
+       classes (FECs) and how labels are assigned to them.
+
+       The policy <cf/static/ means no dynamic label allocation is done, and
+       static labels must be set in import filters using the route attribute
+       <ref id="rta-mpls-label" name="mpls_label">.
+
+       The policy <cf/prefix/ means each prefix uses separate label associated
+       with that prefix. When a labeled route is updated, it keeps the label.
+       This policy is appropriate for IGPs.
+
+       The policy <cf/aggregate/ means routes are grouped to FECs according to
+       their next hops (including next hop labels), and one label is used for
+       all routes in the same FEC. When a labeled route is updated, it may
+       change next hop, change FEC and therefore change label. This policy is
+       appropriate for BGP.
+
+       The policy <cf/vrf/ is only valid in L3VPN protocols. It uses one label
+       for all routes from a VRF, while replacing the original next hop with
+       lookup in the VRF.
+
+       Default: <cf/prefix/.
+</descrip>
+
+<p>This is a trivial example of MPLS setup:
+<code>
+mpls domain mdom {
+       label range bgprange { start 2000; length 1000; };
+}
+
+mpls table mtab;
+
+protocol static {
+       ipv6;
+       mpls;
+
+       route 2001:db8:1:1/64 mpls 100 via 2001:db8:1:2::1/64 mpls 200;
+}
+
+protocol bgp {
+       # regular channels
+       ipv6 mpls { ... };
+       vpn6 mpls { ... };
+
+       # MPLS channel
+       mpls {
+               # domain mdom;
+               # table mtab;
+               label range bgprange;
+               label policy aggregate;
+       };
+
+       ...
+}
+</code>
+
+
 <chapt>Remote control
 <label id="remote-control">
 
@@ -1106,8 +1288,9 @@ This argument can be omitted if there exists only a single instance.
        <tag><label id="cli-show-static">show static [<m/name/]</tag>
        Show detailed information about static routes.
 
-       <tag><label id="cli-show-bfd-sessions">show bfd sessions [<m/name/]</tag>
-       Show information about BFD sessions.
+       <tag><label id="cli-show-bfd-sessions">show bfd sessions [<m/name/] [address (<m/IP/|<m/prefix/)] [(interface|dev) "<m/name/"] [ipv4|ipv6] [direct|multihop] [all]</tag>
+       Show information about BFD sessions. Options could be used to filter
+       entries, or in the case of the option <cf/all/ to give verbose output.
 
        <tag><label id="cli-show-symbols">show symbols [table|filter|function|protocol|template|roa|<m/symbol/]</tag>
        Show the list of symbols defined in the configuration (names of
@@ -1296,20 +1479,24 @@ can group several statements to a single compound statement by using braces
 (<cf>{ <M>statements</M> }</cf>) which is useful if you want to make a bigger
 block of code conditional.
 
-<p>BIRD supports functions, so that you don't have to repeat the same blocks of
-code over and over. Functions can have zero or more parameters and they can have
-local variables. Recursion is not allowed. Function definitions look like this:
+<p>BIRD supports functions, so that you don not have to repeat the same blocks
+of code over and over. Functions can have zero or more parameters and they can
+have local variables. If the function returns value, then you should always
+specify its return type. Direct recursion is possible. Function definitions look
+like this:
 
 <code>
-function name ()
+function name() -> int
 {
        int local_variable;
        int another_variable = 5;
+       return 42;
 }
 
-function with_parameters (int parameter)
+function with_parameters(int parameter) -> pair
 {
        print parameter;
+       return (1, 2);
 }
 </code>
 
@@ -1323,7 +1510,7 @@ may return values using the <cf>return <m/[expr]/</cf> command. Returning a
 value exits from current function (this is similar to C).
 
 <p>Filters are defined in a way similar to functions except they cannot have
-explicit parameters. They get a route table entry as an implicit parameter, it
+explicit parameters and cannot return. They get a route table entry as an implicit parameter, it
 is also passed automatically to any functions called. The filter must terminate
 with either <cf/accept/ or <cf/reject/ statement. If there is a runtime error in
 filter, the route is rejected.
@@ -1387,6 +1574,23 @@ in the foot).
        !&tilde;/) operators could be used to match a string value against
        a shell pattern (represented also as a string).
 
+       <tag><label id="type-bytestring">bytestring</tag>
+       This is a sequences of arbitrary bytes. There are no ways to modify
+       bytestrings in filters. You can pass them between function, assign
+       them to variables of type <cf/bytestring/, print such values,
+       compare bytestings (<cf/=, !=/).
+
+       Bytestring literals are written as a sequence of hexadecimal digit
+       pairs, optionally colon-separated. A bytestring specified this way
+       must be either at least 16 bytes (32 digits) long, or prefixed by the
+       <cf/hex:/ prefix: <cf/01:23:45:67:89:ab:cd:ef:01:23:45:67:89:ab:cd:ef/,
+       <cf/0123456789abcdef0123456789abcdef/, <cf/hex:/, <cf/hex:12:34:56/,
+       <cf/hex:12345678/.
+
+       A bytestring can be made from a hex string using <cf/from_hex()/
+       function. Source strings can use any number of dots, colons, hyphens
+       and spaces as byte separators: <cf/from_hex(" 12.34 56:78 ab-cd-ef ")/.
+
        <tag><label id="type-ip">ip</tag>
        This type can hold a single IP address. The IPv4 addresses are stored as
        IPv4-Mapped IPv6 addresses so one data type for both of them is used.
@@ -1513,7 +1717,7 @@ in the foot).
        Prefix <cf><m>ip1</m>/<m>len1</m></cf> matches prefix
        pattern <cf><m>ip2</m>/<m>len2</m>{<m>l</m>,<m>h</m>}</cf> if the
        first <cf>min(len1, len2)</cf> bits of <cf/ip1/ and <cf/ip2/ are
-       identical and <cf>len1 &lt;= ip1 &lt;= len2</cf>. A valid prefix pattern
+       identical and <cf>l &lt;= len1 &lt;= h</cf>. A valid prefix pattern
        has to satisfy <cf>low &lt;= high</cf>, but <cf/pxlen/ is not
        constrained by <cf/low/ or <cf/high/. Obviously, a prefix matches a
        prefix set literal if it matches any prefix pattern in the prefix set
@@ -1569,23 +1773,24 @@ in the foot).
 
        <cf><m/P/.len</cf> returns the length of path <m/P/.
 
-       <cf><m/P/.empty</cf> makes the path <m/P/ empty.
+       <cf><m/P/.empty</cf> makes the path <m/P/ empty. Can't be used as a value, always modifies the object.
 
-       <cf>prepend(<m/P/,<m/A/)</cf> prepends ASN <m/A/ to path <m/P/ and
+       <cf><m/P/.prepend(<m/A/)</cf> prepends ASN <m/A/ to path <m/P/ and
        returns the result.
 
-       <cf>delete(<m/P/,<m/A/)</cf> deletes all instances of ASN <m/A/ from
+       <cf><m/P/.delete(<m/A/)</cf> deletes all instances of ASN <m/A/ from
        from path <m/P/ and returns the result. <m/A/ may also be an integer
        set, in that case the operator deletes all ASNs from path <m/P/ that are
        also members of set <m/A/.
 
-       <cf>filter(<m/P/,<m/A/)</cf> deletes all ASNs from path <m/P/ that are
-       not members of integer set <m/A/. I.e., <cf/filter/ do the same as
-       <cf/delete/ with inverted set <m/A/.
+       <cf><m/P/.filter(<m/A/)</cf> deletes all ASNs from path <m/P/ that are
+       not members of integer set <m/A/, and returns the result.
+       I.e., <cf/filter/ do the same as <cf/delete/ with inverted set <m/A/.
 
-       Statement <cf><m/P/ = prepend(<m/P/, <m/A/);</cf> can be shortened to
-       <cf><m/P/.prepend(<m/A/);</cf> if <m/P/ is appropriate route attribute
-       (for example <cf/bgp_path/). Similarly for <cf/delete/ and <cf/filter/.
+       Methods <cf>prepend</cf>, <cf>delete</cf> and <cf>filter</cf> keep the
+       original object intact as long as you use the result in any way. You can
+       also write e.g. <cf><m/P/.prepend(<m/A/);</cf> as a standalone statement.
+       This variant does modify the original object with the result of the operation.
 
        <tag><label id="type-bgpmask">bgpmask</tag>
        BGP masks are patterns used for BGP path matching (using <cf>path
@@ -1613,28 +1818,29 @@ in the foot).
 
        <cf><m/C/.len</cf> returns the length of clist <m/C/.
 
-       <cf><m/C/.empty</cf> makes the list <m/C/ empty.
+       <cf><m/C/.empty</cf> makes the list <m/C/ empty. Can't be used as a value, always modifies the object.
 
-       <cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist <m/C/ and
+       <cf><m/C/.add(<m/P/)</cf> adds pair (or quad) <m/P/ to clist <m/C/ and
        returns the result. If item <m/P/ is already in clist <m/C/, it does
        nothing. <m/P/ may also be a clist, in that case all its members are
        added; i.e., it works as clist union.
 
-       <cf>delete(<m/C/,<m/P/)</cf> deletes pair (or quad) <m/P/ from clist
+       <cf><m/C/.delete(<m/P/)</cf> deletes pair (or quad) <m/P/ from clist
        <m/C/ and returns the result. If clist <m/C/ does not contain item
        <m/P/, it does nothing. <m/P/ may also be a pair (or quad) set, in that
        case the operator deletes all items from clist <m/C/ that are also
        members of set <m/P/. Moreover, <m/P/ may also be a clist, which works
        analogously; i.e., it works as clist difference.
 
-       <cf>filter(<m/C/,<m/P/)</cf> deletes all items from clist <m/C/ that are
-       not members of pair (or quad) set <m/P/. I.e., <cf/filter/ do the same
+       <cf><m/C/.filter(<m/P/)</cf> deletes all items from clist <m/C/ that are
+       not members of pair (or quad) set <m/P/, and returns the result. I.e., <cf/filter/ do the same
        as <cf/delete/ with inverted set <m/P/. <m/P/ may also be a clist, which
        works analogously; i.e., it works as clist intersection.
 
-       Statement <cf><m/C/ = add(<m/C/, <m/P/);</cf> can be shortened to
-       <cf><m/C/.add(<m/P/);</cf> if <m/C/ is appropriate route attribute (for
-       example <cf/bgp_community/). Similarly for <cf/delete/ and <cf/filter/.
+       Methods <cf>add</cf>, <cf>delete</cf> and <cf>filter</cf> keep the
+       original object intact as long as you use the result in any way. You can
+       also write e.g. <cf><m/P/.add(<m/A/);</cf> as a standalone statement.
+       This variant does modify the original object with the result of the operation.
 
        <cf><m/C/.min</cf> returns the minimum element of clist <m/C/.
 
@@ -1849,6 +2055,29 @@ Common route attributes are:
        network for routes that do not have a native protocol metric attribute
        (like <cf/ospf_metric1/ for OSPF routes). It is used mainly by BGP to
        compare internal distances to boundary routers (see below).
+
+       <tag><label id="rta-mpls-label"><m/int/ mpls_label</tag>
+       Local MPLS label attached to the route. This attribute is produced by
+       MPLS-aware protocols for labeled routes. It can also be set in import
+       filters to assign static labels, but that also requires static MPLS
+       label policy.
+
+       <tag><label id="rta-mpls-policy"><m/enum/ mpls_policy</tag>
+       For MPLS-aware protocols, this attribute defines which
+       <ref id="mpls-channel-label-policy" name="MPLS label policy"> will be
+       used for the route. It can be set in import filters to change it on
+       per-route basis. Valid values are <cf/MPLS_POLICY_NONE/ (no label),
+       <cf/MPLS_POLICY_STATIC/ (static label), <cf/MPLS_POLICY_PREFIX/
+       (per-prefix label), <cf/MPLS_POLICY_AGGREGATE/ (aggregated label),
+       and <cf/MPLS_POLICY_VRF/ (per-VRF label). See <ref
+       id="mpls-channel-label-policy" name="MPLS label policy"> for details.
+
+       <tag><label id="rta-mpls-class"><m/int/ mpls_class</tag>
+       When <ref id="mpls-channel-label-policy" name="MPLS label policy"> is
+       set to <cf/aggregate/, it may be useful to apply more fine-grained
+       aggregation than just one based on next hops. When routes have different
+       value of this attribute, they will not be aggregated under one local
+       label even if they have the same next hops.
 </descrip>
 
 <p>Protocol-specific route attributes are described in the corresponding
@@ -1880,6 +2109,70 @@ protocol sections.
 <chapt>Protocols
 <label id="protocols">
 
+<sect>Aggregator
+<label id="aggregator">
+
+<sect1>Introduction
+<label id="aggregator-intro">
+<p>The Aggregator protocol explicitly merges routes by the given rules. There
+   are four phases of aggregation. First routes are filtered, then sorted into buckets,
+   then buckets are merged and finally the results are filtered once again.
+   Aggregating an already aggregated route is forbidden.
+
+<p>This is an experimental protocol, use with caution.
+
+<sect1>Configuration
+<label id="aggregator-config">
+<p><descrip>
+       <tag><label id="aggregator-table">table <m/table/</tag>
+       The table from which routes are exported to get aggregated.
+
+       <tag><label id="aggregator-export">export <m/.../</tag>
+       A standard channel's <cf/export/ clause, defining which routes are accepted into aggregation.
+
+       <tag><label id="aggregator-rule">aggregate on <m/expr/ | <m/attribute/ [<m/, .../]</tag>
+       All the given filter expressions and route attributes are evaluated for each route. Then routes
+       are sorted into buckets where <em/all/ values are the same. Note: due to performance reasons,
+        all filter expressions must return a compact type, e.g. integer, a BGP
+        (standard, extended, large) community or an IP address. If you need to compare e.g. modified
+       AS Paths in the aggregation rule, you can define a custom route attribute and set this attribute
+       in the export filter. For now, it's mandatory to say <cf/net/ here, we can't merge prefixes yet.
+
+       <tag><label id="aggregation-merge">merge by { <m/filter code/ }</tag>
+       The given filter code has an extra symbol defined: <cf/routes/. By iterating over <cf/routes/,
+       you get all the routes in the bucket and you can construct your new route. All attributes
+       selected in <cf/aggregate on/ are already set to the common values. For now, it's not possible
+       to use a named filter here. You have to finalize the route by calling <cf/accept/.
+
+       <tag><label id="aggregator-import">import <m/.../</tag>
+       Filter applied to the route after <cf/merge by/. Here you can use a named filter.
+
+       <tag><label id="aggregator-peer-table">peer table <m/table/</tag>
+       The table to which aggregated routes are imported. It may be the same table
+       as <cf/table/.
+</descrip>
+
+<sect1>Example
+<label id="aggregator-example">
+
+<p><code>
+protocol aggregator {
+  table master6;
+  export where defined(bgp_path);
+  /* Merge all routes with the same AS Path length */
+  aggregate on net, bgp_path.len;
+  merge by {
+    for route r in routes do {
+      if ! defined(bgp_path) then { bgp_path = r.bgp_path }
+      bgp_community = bgp_community.add(r.bgp_community);
+    }
+    accept;
+  };
+  import all;
+  peer table agr_result;
+}
+</code>
+
 <sect>Babel
 <label id="babel">
 
@@ -2425,7 +2718,6 @@ avoid routing loops.
 <item> <rfc id="5065"> - AS confederations for BGP
 <item> <rfc id="5082"> - Generalized TTL Security Mechanism
 <item> <rfc id="5492"> - Capabilities Advertisement with BGP
-<item> <rfc id="5549"> - Advertising IPv4 NLRI with an IPv6 Next Hop
 <item> <rfc id="5575"> - Dissemination of Flow Specification Rules
 <item> <rfc id="5668"> - 4-Octet AS Specific BGP Extended Community
 <item> <rfc id="6286"> - AS-Wide Unique BGP Identifier
@@ -2440,6 +2732,7 @@ avoid routing loops.
 <item> <rfc id="8203"> - BGP Administrative Shutdown Communication
 <item> <rfc id="8212"> - Default EBGP Route Propagation Behavior without Policies
 <item> <rfc id="8654"> - Extended Message Support for BGP
+<item> <rfc id="8950"> - Advertising IPv4 NLRI with an IPv6 Next Hop
 <item> <rfc id="9072"> - Extended Optional Parameters Length for BGP OPEN Message
 <item> <rfc id="9117"> - Revised Validation Procedure for BGP Flow Specifications
 <item> <rfc id="9234"> - Route Leak Prevention and Detection Using Roles
@@ -2587,10 +2880,9 @@ using the following configuration parameters:
        restarted. Optionally, it can be configured (by <cf/graceful/ argument)
        to trigger graceful restart instead of regular restart. It is also
        possible to specify section with per-peer BFD session options instead of
-       just switch argument. Most BFD session specific options are allowed here
-       with the exception of authentication options. here Note that BFD
-       protocol also has to be configured, see <ref id="bfd" name="BFD">
-       section for details. Default: disabled.
+       just the switch argument. All BFD session-specific options are allowed
+       here. Note that BFD protocol also has to be configured, see
+       <ref id="bfd" name="BFD"> section for details. Default: disabled.
 
        <tag><label id="bgp-ttl-security">ttl security <m/switch/</tag>
        Use GTSM (<rfc id="5082"> - the generalized TTL security mechanism). GTSM
@@ -2710,13 +3002,28 @@ using the following configuration parameters:
        changes its import filter, or if there is suspicion of inconsistency) it
        is necessary to do a new complete route exchange. BGP protocol extension
        Route Refresh (<rfc id="2918">) allows BGP speaker to request
-       re-advertisement of all routes from its neighbor. BGP protocol
-       extension Enhanced Route Refresh (<rfc id="7313">) specifies explicit
-       begin and end for such exchanges, therefore the receiver can remove
-       stale routes that were not advertised during the exchange. This option
-       specifies whether BIRD advertises these capabilities and supports
+       re-advertisement of all routes from its neighbor. This option
+       specifies whether BIRD advertises this capability and supports
        related procedures. Note that even when disabled, BIRD can send route
-       refresh requests.  Default: on.
+       refresh requests. Disabling Route Refresh also disables Enhanced Route Refresh.
+       Default: on.
+
+       <tag><label id="bgp-require-route-refresh">require route refresh <m/switch/</tag>
+       If enabled, the BGP Route Refresh capability (<rfc id="2918">) must be
+       announced by the BGP neighbor, otherwise the BGP session will not be
+       established. Default: off.
+
+       <tag><label id="bgp-enable-enhanced-route-refresh">enable enhanced route refresh <m/switch/</tag>
+       BGP protocol extension Enhanced Route Refresh (<rfc id="7313">)
+       specifies explicit begin and end for Route Refresh (see previous
+       option), therefore the receiver can remove stale routes that were not
+       advertised during the exchange. This option specifies whether BIRD
+       advertises this capability and supports related procedures. Default: on.
+
+       <tag><label id="bgp-require-enhanced-route-refresh">require enhanced route refresh <m/switch/</tag>
+       If enabled, the BGP Enhanced Route Refresh capability (<rfc id="7313">)
+       must be announced by the BGP neighbor, otherwise the BGP session
+       will not be established. Default: off.
 
        <tag><label id="bgp-graceful-restart">graceful restart <m/switch/|aware</tag>
        When a BGP speaker restarts or crashes, neighbors will discard all
@@ -2733,11 +3040,16 @@ using the following configuration parameters:
        restart requires also configuration of other protocols. Default: aware.
 
        <tag><label id="bgp-graceful-restart-time">graceful restart time <m/number/</tag>
-       The restart time is announced in the BGP graceful restart capability
+       The restart time is announced in the BGP Graceful Restart capability
        and specifies how long the neighbor would wait for the BGP session to
        re-establish after a restart before deleting stale routes. Default:
        120 seconds.
 
+       <tag><label id="bgp-require-graceful-restart">require graceful restart <m/switch/</tag>
+       If enabled, the BGP Graceful Restart capability (<rfc id="4724">)
+       must be announced by the BGP neighbor, otherwise the BGP session
+       will not be established. Default: off.
+
        <tag><label id="bgp-long-lived-graceful-restart">long lived graceful restart <m/switch/|aware</tag>
        The long-lived graceful restart is an extension of the traditional
        <ref id="bgp-graceful-restart" name="BGP graceful restart">, where stale
@@ -2751,12 +3063,17 @@ using the following configuration parameters:
        graceful restart is disabled.
 
        <tag><label id="bgp-long-lived-stale-time">long lived stale time <m/number/</tag>
-       The long-lived stale time is announced in the BGP long-lived graceful
-       restart capability and specifies how long the neighbor would keep stale
+       The long-lived stale time is announced in the BGP Long-lived Graceful
+       Restart capability and specifies how long the neighbor would keep stale
        routes depreferenced during long-lived graceful restart until either the
        session is re-stablished and synchronized or the stale time expires and
        routes are removed. Default: 3600 seconds.
 
+       <tag><label id="bgp-require-long-lived-graceful-restart">require long lived graceful restart <m/switch/</tag>
+       If enabled, the BGP Long-lived Graceful Restart capability (draft)
+       must be announced by the BGP neighbor, otherwise the BGP session
+       will not be established. Default: off.
+
        <tag><label id="bgp-interpret-communities">interpret communities <m/switch/</tag>
        <rfc id="1997"> demands that BGP speaker should process well-known
        communities like no-export (65535, 65281) or no-advertise (65535,
@@ -2776,11 +3093,21 @@ using the following configuration parameters:
        in neighbor's implementation of 4B AS extension. Even when disabled
        (off), BIRD behaves internally as AS4-aware BGP router. Default: on.
 
+       <tag><label id="bgp-require-as4">require as4 <m/switch/</tag>
+       If enabled, the BGP 4B AS number capability (<rfc id="6793">) must be
+       announced by the BGP neighbor, otherwise the BGP session will not be
+       established. Default: off.
+
        <tag><label id="bgp-enable-extended-messages">enable extended messages <m/switch/</tag>
        The BGP protocol uses maximum message length of 4096 bytes. This option
        provides an extension (<rfc id="8654">) to allow extended messages with
        length up to 65535 bytes. Default: off.
 
+       <tag><label id="bgp-require-extended-messages">require extended messages <m/switch/</tag>
+       If enabled, the BGP Extended Message capability (<rfc id="8654">) must
+       be announced by the BGP neighbor, otherwise the BGP session will not be
+       established. Default: off.
+
        <tag><label id="bgp-capabilities">capabilities <m/switch/</tag>
        Use capability advertisement to advertise optional capabilities. This is
        standard behavior for newer BGP implementations, but there might be some
@@ -2790,7 +3117,11 @@ using the following configuration parameters:
        capability-related error.
 
        <tag><label id="bgp-advertise-hostname">advertise hostname <m/switch/</tag>
-       Advertise hostname capability along with the hostname. Default: off.
+       Advertise the hostname capability along with the hostname. Default: off.
+
+       <tag><label id="bgp-require-hostname">require hostname <m/switch/</tag>
+       If enabled, the hostname capability must be announced by the BGP
+       neighbor, otherwise the BGP session negotiation fails. Default: off.
 
        <tag><label id="bgp-disable-after-error">disable after error <m/switch/</tag>
        When an error is encountered (either locally or by the other side),
@@ -2838,6 +3169,23 @@ using the following configuration parameters:
        negotiation. If the proposed hold time would lead to a lower value of
        the keepalive time, the session is rejected with error. Default: none.
 
+       <tag><label id="bgp-send-hold-time">send hold time <m/number/</tag>
+       Maximum time in seconds betweeen successfull transmissions of BGP messages.
+       Send hold timer drops the session if the neighbor is sending keepalives,
+       but does not receive our messages, causing the TCP connection to stall.
+       This may happen due to malfunctioning or overwhelmed neighbor. See
+       <HTMLURL URL="https://datatracker.ietf.org/doc/draft-ietf-idr-bgp-sendholdtimer/"
+       name="draft-ietf-idr-bgp-sendholdtimer"> for more details.
+
+       Like the option <cf/keepalive time/, the effective value depends on the
+       negotiated hold time, as it is scaled to maintain proportion between the
+       send hold time and the keepalive time. If it is set to zero, the timer
+       is disabled. Default: double of the hold timer limit.
+
+       The option <cf/disable rx/ is intended only for testing this feature and
+       should not be used anywhere else. It discards received messages and
+       disables the hold timer.
+
        <tag><label id="bgp-connect-delay-time">connect delay time <m/number/</tag>
        Delay in seconds between protocol startup and the first attempt to
        connect. Default: 5 seconds.
@@ -2955,6 +3303,18 @@ together with their appropriate channels follows.
 </tabular>
 </table>
 
+<p>The BGP protocol can be configured as MPLS-aware (by defining both AFI/SAFI
+channels and the MPLS channel). In such case the BGP protocol assigns labels to
+routes imported from MPLS-aware SAFIs (i.e. <cf/ipvX mpls/ and <cf/vpnX mpls/)
+and automatically announces corresponding MPLS route for each labeled route. As
+BGP generally processes a large amount of routes, it is suggested to set MPLS
+label policy to <cf/aggregate/.
+
+<p>Note that even BGP instances without MPLS channel and without local MPLS
+configuration can still propagate third-party MPLS labels, e.g. as route
+reflectors, they just will not assign local labels to imported routes and will
+not announce MPLS routes for local MPLS forwarding.
+
 <p>Due to <rfc id="8212">, external BGP protocol requires explicit configuration
 of import and export policies (in contrast to other protocols, where default
 policies of <cf/import all/ and <cf/export none/ are used in absence of explicit
@@ -3100,19 +3460,34 @@ be used in explicit configuration.
        associated network prefixes. This option provides an extension to use
        IPv4 next hops with IPv6 prefixes and vice versa. For IPv4 / VPNv4
        channels, the behavior is controlled by the Extended Next Hop Encoding
-       capability, as described in <rfc id="5549">. For IPv6 / VPNv6 channels,
+       capability, as described in <rfc id="8950">. For IPv6 / VPNv6 channels,
        just IPv4-mapped IPv6 addresses are used, as described in
        <rfc id="4798"> and <rfc id="4659">. Default: off.
 
+       <tag><label id="bgp-require-extended-next-hop">require extended next hop <m/switch/</tag>
+       If enabled, the BGP Extended Next Hop Encoding capability (<rfc id="8950">)
+       must be announced by the BGP neighbor, otherwise the BGP session will
+       not be established. Note that this option is relevant just for IPv4 /
+       VPNv4 channels, as IPv6 / VPNv6 channels use a different mechanism not
+       signalled by a capability. Default: off.
+
        <tag><label id="bgp-add-paths">add paths <m/switch/|rx|tx</tag>
        Standard BGP can propagate only one path (route) per destination network
-       (usually the selected one). This option controls the add-path protocol
+       (usually the selected one). This option controls the ADD-PATH protocol
        extension, which allows to advertise any number of paths to a
-       destination. Note that to be active, add-path has to be enabled on both
+       destination. Note that to be active, ADD-PATH has to be enabled on both
        sides of the BGP session, but it could be enabled separately for RX and
        TX direction. When active, all available routes accepted by the export
        filter are advertised to the neighbor. Default: off.
 
+       <tag><label id="bgp-require-add-paths">require add paths <m/switch/</tag>
+       If enabled, the BGP ADD-PATH capability (<rfc id="7911">) must be
+       announced by the BGP neighbor, otherwise the BGP session will not be
+       established. Announced directions in the capability must be compatible
+       with locally configured directions. E.g., If <cf/add path tx/ is
+       configured locally, then the neighbor capability must announce RX.
+       Default: off.
+
        <tag><label id="bgp-aigp">aigp <m/switch/|originate</tag>
        The BGP protocol does not use a common metric like other routing
        protocols, instead it uses a set of criteria for route selection
@@ -3258,10 +3633,21 @@ some of them (marked with `<tt/O/') are optional.
 
        <tag><label id="bgp-otc">int bgp_otc [O]</tag>
        This attribute is defined in <rfc id="9234">. OTC is a flag that marks
-       routes that should be sent only to customers. If <ref id="bgp-role"
-       name="local Role"> is configured it set automatically.
+       routes that should be sent only to customers. If <ref id="bgp-local-role"
+       name="local role"> is configured it set automatically.
 </descrip>
 
+<p>For attributes unknown by BIRD, the user can assign a name (on top level) to
+an attribute by its number. This defined name can be used then to get, set (as a
+bytestring, transitive) or unset the given attribute even though BIRD knows
+nothing about it.
+
+<p>Note that it is not possible to define an attribute with the same number
+as one known by BIRD, therefore use of this statement carries a risk of
+incompatibility with future BIRD versions.
+
+<tt><label id="bgp-attribute-custom">attribute bgp <m/number/ bytestring <m/name/;</tt>
+
 <sect1>Example
 <label id="bgp-exam">
 
@@ -3315,10 +3701,9 @@ future. It is not ready for production usage and therefore it is not compiled
 by default and have to be enabled during installation by the configure option
 <tt/--with-protocols=/.
 
-<p>The implementation is limited to monitor protocol state changes and routes
-in <ref id="bgp-import-table" name="BGP import tables"> (not regular routing
-tables), therefore import table must be enabled in BGP protocols. All BGP
-protocols are monitored automatically.
+<p>The implementation supports monitoring protocol state changes, pre-policy
+routes (in <ref id="bgp-import-table" name="BGP import tables">) and post-policy
+routes (in regular routing tables). All BGP protocols are monitored automatically.
 
 <sect1>Example
 <label id="bmp-exam">
@@ -3328,8 +3713,11 @@ protocol bmp {
        # The monitoring station to connect to
        station address ip 198.51.100.10 port 1790;
 
-       # required option
+       # Monitor received routes (in import table)
        monitoring rib in pre_policy;
+
+       # Monitor accepted routes (passed import filters)
+       monitoring rib in post_policy;
 }
 </code>
 
@@ -3454,9 +3842,8 @@ on the <cf/learn/ switch, such routes are either ignored or accepted to our
 table).
 
 <p>Note that routes created by OS kernel itself, namely direct routes
-representing IP subnets of associated interfaces, are not imported even with
-<cf/learn/ enabled. You can use <ref id="direct" name="Direct protocol"> to
-generate these direct routes.
+representing IP subnets of associated interfaces, are imported only with
+<cf/learn all/ enabled.
 
 <p>If your OS supports only a single routing table, you can configure only one
 instance of the Kernel protocol. If it supports multiple tables (in order to
@@ -3487,10 +3874,12 @@ channels.
        Time in seconds between two consecutive scans of the kernel routing
        table.
 
-       <tag><label id="krt-learn">learn <m/switch/</tag>
+       <tag><label id="krt-learn">learn <m/switch/|all</tag>
        Enable learning of routes added to the kernel routing tables by other
        routing daemons or by the system administrator. This is possible only on
-       systems which support identification of route authorship.
+       systems which support identification of route authorship. By default,
+       routes created by kernel (marked as "proto kernel") are not imported.
+       Use <cf/learn all/ option to import even these routes.
 
        <tag><label id="krt-kernel-table">kernel table <m/number/</tag>
        Select which kernel table should this particular instance of the Kernel
@@ -3573,15 +3962,17 @@ these attributes:
 <p>In Linux, there is also a plenty of obscure route attributes mostly focused
 on tuning TCP performance of local connections. BIRD supports most of these
 attributes, see Linux or iproute2 documentation for their meaning. Attributes
-<cf/krt_lock_*/ and <cf/krt_feature_*/ have type bool, others have type int.
-Supported attributes are:
+<cf/krt_lock_*/ and <cf/krt_feature_*/ have type bool, <cf/krt_congctl/ has type
+string, others have type int. Supported attributes are:
 
 <cf/krt_mtu/, <cf/krt_lock_mtu/, <cf/krt_window/, <cf/krt_lock_window/,
 <cf/krt_rtt/, <cf/krt_lock_rtt/, <cf/krt_rttvar/, <cf/krt_lock_rttvar/,
-<cf/krt_sstresh/, <cf/krt_lock_sstresh/, <cf/krt_cwnd/, <cf/krt_lock_cwnd/,
+<cf/krt_ssthresh/, <cf/krt_lock_ssthresh/, <cf/krt_cwnd/, <cf/krt_lock_cwnd/,
 <cf/krt_advmss/, <cf/krt_lock_advmss/, <cf/krt_reordering/, <cf/krt_lock_reordering/,
 <cf/krt_hoplimit/, <cf/krt_lock_hoplimit/, <cf/krt_rto_min/, <cf/krt_lock_rto_min/,
-<cf/krt_initcwnd/, <cf/krt_initrwnd/, <cf/krt_quickack/,
+<cf/krt_initcwnd/, <cf/krt_lock_initcwnd/, <cf/krt_initrwnd/, <cf/krt_lock_initrwnd/,
+<cf/krt_quickack/, <cf/krt_lock_quickack/, <cf/krt_congctl/, <cf/krt_lock_congctl/,
+<cf/krt_fastopen_no_cookie/, <cf/krt_lock_fastopen_no_cookie/,
 <cf/krt_feature_ecn/, <cf/krt_feature_allfrag/
 
 <sect1>Example
@@ -3600,7 +3991,7 @@ protocol kernel {
 <p><code>
 protocol kernel {              # Primary routing table
        learn;                  # Learn alien routes from the kernel
-       persist;                # Don't remove routes on bird shutdown
+       persist;                # Do not remove routes on bird shutdown
        scan time 10;           # Scan kernel routing table every 10 seconds
        ipv4 {
                import all;
@@ -3618,6 +4009,140 @@ protocol kernel {               # Secondary routing table
 </code>
 
 
+<sect>L3VPN
+<label id="l3vpn">
+
+<sect1>Introduction
+<label id="l3vpn-intro">
+
+<p>The L3VPN protocol serves as a translator between IP routes and VPN
+routes. It is a component for BGP/MPLS IP VPNs (<rfc id="4364">) and implements
+policies defined there. In import direction (VPN -&gt; IP), VPN routes matching
+import target specification are stripped of route distinguisher and MPLS labels
+and announced as IP routes, In export direction (IP -&gt; VPN), IP routes are
+expanded with specific route distinguisher, export target communities and MPLS
+label and announced as labeled VPN routes. Unlike the Pipe protocol, the L3VPN
+protocol propagates just the best route for each network.
+
+<p>In BGP/MPLS IP VPNs, route distribution is controlled by Route Targets (RT).
+VRFs are associated with one or more RTs. Routes are also associated with one or
+more RTs, which are encoded as route target extended communities
+in <ref id="rta-bgp-ext-community" name="bgp_ext_community">. A route is then
+imported into each VRF that shares an associated Route Target. The L3VPN
+protocol implements this mechanism through mandatory <cf/import target/ and
+<cf/export target/ protocol options.
+
+<sect1>Configuration
+<label id="l3vpn-config">
+
+<p>L3VPN configuration consists of a few mandatory options and multiple channel
+definitions. For convenience, the default export filter in L3VPN channels is
+<cf/all/, as the primary way to control import and export of routes is through
+protocol options <cf/import target/ and <cf/export target/. If custom filters
+are used, note that the export filter of the input channel is applied before
+the route translation, while the import filter of the output channel is applied
+after that.
+
+<p>In contrast to the Pipe protocol, the L3VPN protocol can handle both IPv4 and
+IPv6 routes in one instance, also both IP side and VPN side are represented as
+separate channels, although that may change in the future. The L3VPN is always
+MPLS-aware protocol, therefore a MPLS channel is mandatory. Altogether, L3VPN
+could have up to 5 channels: <cf/ipv4/, <cf/ipv6/, <cf/vpn4/, <cf/vpn6/, and
+<cf/mpls/.
+
+<p><descrip>
+       <tag><label id="l3vpn-route-distinguisher">route distinguisher <m/vpnrd/</tag>
+       The route distinguisher that is attached to routes in the export
+       direction. Mandatory.
+
+       <tag><label id="l3vpn-rd">rd <m/vpnrd/</tag>
+       A shorthand for the option <cf/route distinguisher/.
+
+       <tag><label id="l3vpn-import-target">import target <m/ec/|<m/ec-set/</tag>
+       Route target extended communities specifying which routes should be
+       imported. Either one community or a set. A route is imported if there is
+       non-empty intersection between extended communities of the route and the
+       import target of the L3VPN protocol. Mandatory.
+
+       <tag><label id="l3vpn-export-target">export target <m/ec/|<m/ec-set/</tag>
+       Route target extended communities that are attached to the route in the
+       export direction. Either one community or a set. Other route target
+       extended communities are removed. Mandatory.
+
+       <tag><label id="l3vpn-route-target">route target <m/ec/|<m/ec-set/</tag>
+       A shorthand for both <cf/import target/ and <cf/export target/.
+</descrip>
+
+<sect1>Attributes
+<label id="l3vpn-attr">
+
+<p>The L3VPN protocol does not define any route attributes.
+
+<sect1>Example
+<label id="l3vpn-exam">
+
+<p>Here is an example of L3VPN setup with one VPN and BGP uplink. IP routes
+learned from a customer in the VPN are stored in <cf/vrf0vX/ tables, which are
+mapped to kernel VRF vrf0. Routes can also be exchanged through BGP with
+different sites hosting that VPN. Forwarding of VPN traffic through the network
+is handled by MPLS.
+
+<p>Omitted from the example are some routing protocol to exchange routes with
+the customer and some sort of MPLS-aware IGP to resolve next hops for BGP VPN
+routes.
+
+<code>
+# MPLS basics
+mpls domain mdom;
+mpls table  mtab;
+
+protocol kernel krt_mpls {
+       mpls { table mtab; export all; };
+}
+
+vpn4 table vpntab4;
+vpn6 table vpntab6;
+
+# Exchange VPN routes through BGP
+protocol bgp {
+       vpn4 { table vpntab4; import all; export all; };
+       vpn6 { table vpntab6; import all; export all; };
+       mpls { label policy aggregate; };
+       local 10.0.0.1 as 10;
+       neighbor 10.0.0.2 as 10;
+}
+
+# VRF 0
+ipv4 table vrf0v4;
+ipv6 table vrf0v6;
+
+protocol kernel kernel0v4 {
+        vrf "vrf0";
+        ipv4 { table vrf0v4; export all; };
+        kernel table 100;
+}
+
+protocol kernel kernel0v6 {
+        vrf "vrf0";
+        ipv6 { table vrf0v6; export all; };
+        kernel table 100;
+}
+
+protocol l3vpn l3vpn0 {
+        vrf "vrf0";
+        ipv4 { table vrf0v4; };
+        ipv6 { table vrf0v6; };
+        vpn4 { table vpntab4; };
+        vpn6 { table vpntab6; };
+        mpls { label policy vrf; };
+
+        rd 10:12;
+        import target [(rt, 10, 32..40)];
+        export target [(rt, 10, 30), (rt, 10, 31)];
+}
+</code>
+
+
 <sect>MRT
 <label id="mrt">
 
@@ -4285,14 +4810,14 @@ protocol ospf MyOSPF {
                        authentication cryptographic;
                        password "abc" {
                                id 1;
-                               generate to "22-04-2003 11:00:06";
-                               accept from "17-01-2001 12:01:05";
+                               generate to "2023-04-22 11:00:06";
+                               accept from "2021-01-17 12:01:05";
                                algorithm hmac sha384;
                        };
                        password "def" {
                                id 2;
-                               generate to "22-07-2005 17:03:21";
-                               accept from "22-02-2001 11:34:06";
+                               generate to "2025-07-22";
+                               accept from "2021-02-22";
                                algorithm hmac sha512;
                        };
                };
@@ -4549,6 +5074,21 @@ definitions, prefix definitions and DNS definitions:
        options and there is a short variant <cf>dnssl <m/domain/</cf> that just
        specifies one DNS search domain.
 
+       <tag><label id="radv-custom-option">custom option type <m/number/ value <m/bytestring/</tag>
+       Custom option definitions allow to define an arbitrary option to
+       advertise. You need to specify the option type number and the binary
+       payload of the option. The length field is calculated automatically.
+       Like <cf/rdnss/ above, multiple definitions are cumulative, they can
+       be used also as interface-specific options.
+
+       The following example advertises PREF64 option (<rfc id="8781">) with
+       prefix <cf>2001:db8:a:b::/96</cf> and the lifetime of <cf/1 hour/:
+
+       <label id="radv-custom-option-exam">
+<p><code>
+custom option type 38 value hex:0e:10:20:01:0d:b8:00:0a:00:0b:00:00:00:00;
+</code>
+
        <tag><label id="radv-trigger">trigger <m/prefix/</tag>
        RAdv protocol could be configured to change its behavior based on
        availability of routes. When this option is used, the protocol waits in
@@ -4678,6 +5218,10 @@ definitions, prefix definitions and DNS definitions:
        <tag><label id="radv-iface-dnssl-local">dnssl local <m/switch/</tag>
        Use only local DNSSL definitions for this interface. See <cf/rdnss local/
        option above. Default: no.
+
+       <tag><label id="radv-iface-custom-local">custom option local <m/switch/</tag>
+       Use only local custom option definitions for this interface. See <cf/rdnss local/
+       option above. Default: no.
 </descrip>
 
 <p>Prefix specific options
@@ -5153,6 +5697,7 @@ protocol rpki [&lt;name&gt;] {
         roa6 { table &lt;tab&gt;; };
         remote &lt;ip&gt; | "&lt;domain&gt;" [port &lt;num&gt;];
         port &lt;num&gt;;
+        local address &lt;ip&gt;;
         refresh [keep] &lt;num&gt;;
         retry [keep] &lt;num&gt;;
         expire [keep] &lt;num&gt;;
@@ -5182,6 +5727,9 @@ specify both channels.
         number is 323 for transport without any encryption and 22 for transport
         with SSH encryption.
 
+        <tag>local address <m/ip/</tag>
+        Define local address we should use as a source address for the RTR session.
+
         <tag>refresh [keep] <m/num/</tag> Time period in seconds. Tells how
         long to wait before next attempting to poll the cache using a Serial
         Query or a Reset Query packet. Must be lower than 86400 seconds (one
@@ -5321,6 +5869,11 @@ but only routes of the same network type are allowed, as the static protocol
 has just one channel. E.g., to have both IPv4 and IPv6 static routes, define two
 static protocols, each with appropriate routes and channel.
 
+<p>The Static protocol can be configured as MPLS-aware (by defining both the
+primary channel and MPLS channel). In that case the Static protocol assigns
+labels to IP routes and automatically announces corresponding MPLS route for
+each labeled route.
+
 <p>Global options:
 
 <descrip>
@@ -5344,16 +5897,20 @@ static protocols, each with appropriate routes and channel.
 <ref id="type-prefix" name="dependent on network type">.
 
 <descrip>
-       <tag>route <m/prefix/ via <m/ip/|<m/"interface"/ [<m/per-nexthop options/] [via ...]</tag>
-       Regular routes may bear one or more <ref id="route-next-hop" name="next hops">.
-       Every next hop is preceded by <cf/via/ and configured as shown.
+       <tag>route <m/prefix/ [mpls <m/number/] via <m/ip/|<m/"interface"/ [<m/per-nexthop options/] [via ...]</tag>
+       Regular routes may bear one or more <ref id="route-next-hop" name="next
+       hops">. Every next hop is preceded by <cf/via/ and configured as shown.
+
+       When the Static protocol is MPLS-aware, the optional <cf/mpls/ statement
+       after <m/prefix/ specifies a static label for the labeled route, instead
+       of using dynamically allocated label.
 
-       <tag>route <m/prefix/ recursive <m/ip/ [mpls <m/num/[/<m/num/[/<m/num/[...]]]]</tag>
+       <tag>route <m/prefix/ [mpls <m/number/] recursive <m/ip/ [mpls <m/num/[/<m/num/[/<m/num/[...]]]]</tag>
        Recursive nexthop resolves the given IP in the configured IGP table and
        uses that route's next hop. The MPLS stacks are concatenated; on top is
        the IGP's nexthop stack and on bottom is this route's stack.
 
-       <tag>route <m/prefix/ blackhole|unreachable|prohibit</tag>
+       <tag>route <m/prefix/ [mpls <m/number/] blackhole|unreachable|prohibit</tag>
        Special routes specifying to silently drop the packet, return it as
        unreachable or return it as administratively prohibited. First two
        targets are also known as <cf/drop/ and <cf/reject/.
@@ -5387,6 +5944,12 @@ options (<cf/bfd/ and <cf/weight 1/), the second nexthop has just <cf/weight 2/.
        that BFD protocol also has to be configured, see <ref id="bfd" name="BFD">
        section for details. Default value is no.
 
+       <tag><label id="static-route-dev">dev <m/text/</tag>
+       The outgoing interface associated with the nexthop. Useful for
+       link-local nexthop addresses or when multiple interfaces use the same
+       network prefix. By default, the outgoing interface is resolved from the
+       nexthop address.
+
        <tag><label id="static-route-mpls">mpls <m/num/[/<m/num/[/<m/num/[...]]]</tag>
        MPLS labels that should be pushed to packets forwarded by the route.
        The option could be used for both IP routes (on MPLS ingress routers)
@@ -5408,6 +5971,13 @@ options (<cf/bfd/ and <cf/weight 1/), the second nexthop has just <cf/weight 2/.
 
 <p>The ROA config is just <cf>route <m/prefix/ max <m/int/ as <m/int/</cf> with no nexthop.
 
+<sect1>Autonomous System Provider Authorization
+
+<p>The ASPA config is <cf>route aspa <m/int/ providers <m/int/ [, <m/int/ ...]</cf> with no nexthop.
+  The first ASN is client and the following are a list of providers.
+  For a transit, you can also write <cf>route aspa <m/int/ transit</cf> to get
+  the no-provider ASPA.
+
 <sect1>Flowspec
 <label id="flowspec-network-type">
 
@@ -5567,7 +6137,8 @@ protocol static {
                via 198.51.100.20 bfd   # BFD-controlled next hop
                via 192.0.2.1;
        route 203.0.113.0/24 blackhole; # Sink route
-       route 10.2.0.0/24 via "arc0";   # Secondary network
+       route 10.2.0.0/24 via "arc0";   # Direct route
+       route 10.2.2.0/24 via 192.0.2.1 dev "eth0" onlink; # Route with both nexthop and iface
        route 192.168.10.0/24 via 198.51.100.100 {
                ospf_metric1 = 20;      # Set extended attribute
        };
@@ -5586,7 +6157,8 @@ protocol static {
        route 2001:db8:10::/48 via 2001:db8:1::1;       # Route with global nexthop
        route 2001:db8:20::/48 via fe80::10%eth0;       # Route with link-local nexthop
        route 2001:db8:30::/48 via fe80::20%'eth1.60';  # Iface with non-alphanumeric characters
-       route 2001:db8:40::/48 via "eth2";              # Direct route to eth2
+       route 2001:db8:40::/48 via fe80::30 dev "eth1"; # Another link-local nexthop
+       route 2001:db8:50::/48 via "eth2";              # Direct route to eth2
        route 2001:db8::/32 unreachable;                # Unreachable route
        route ::/0 via 2001:db8:1::1 bfd;               # BFD-controlled default route
 }