Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package bird3 for openSUSE:Factory checked 
in at 2026-06-15 19:49:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/bird3 (Old)
 and      /work/SRC/openSUSE:Factory/.bird3.new.1981 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "bird3"

Mon Jun 15 19:49:35 2026 rev:8 rq:1359499 version:3.3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/bird3/bird3.changes      2026-04-10 
18:02:44.545940203 +0200
+++ /work/SRC/openSUSE:Factory/.bird3.new.1981/bird3.changes    2026-06-15 
19:53:21.144347528 +0200
@@ -1,0 +2,48 @@
+Wed Jun 10 06:37:21 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 3.3.1
+  * BGP: Fix crash when incoming connection for disabled protocol
+    arrives.
+  * BGP: Fix parsing labelled NLRIs with no next hop.
+  * BGP: Fix cork behavior in collision with graceful restart.
+  * BGP: Fix crash on dumping pending export statistics.
+  * BGP: Fix several issues in Flowspec handling.
+  * BMP/Nest: No refeed after listener or protocol restart.
+  * MPLS: Fix crash on reconfiguring CS_DOWN channel.
+  * OSPF: Fix handling of LLS data length field.
+  * OSPF: Fix OOB read in authentication check.
+  * OSPF: Fix OOB read in Router-LSA validation.
+  * Proto: Fix regression in protocol enabling.
+  * Channel: Fix refeeds and reloads during graceful restart.
+  * Export: Mitigate duplicate withdrawals.
+  * Filters: Fix crash when setting gateway on recursive nexthops.
+  * Filters: Fix path matching when AS path is too long.
+  * Table: Fix RCU double-anchor.
+  * Table: Propagate thread group config into aux.
+  * RCU: Catch leaks sooner.
+
+-------------------------------------------------------------------
+Mon May 25 18:09:52 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 3.3.0
+  * BGP: Export memory consumption optimization.
+  * BGP: Fix hostentry handling of MPLS and EVPN routes.
+  * BGP: Block connections on explicitly disabled instances.
+  * Proto/CLI: Lock show-commands.
+  * Proto: Loop persists through down state.
+  * Nest/CLI: Show only the longest prefix match in
+    'show route for'.
+  * Nest: Lockless attribute cache.
+  * Removed locking in random number generation.
+  * ASPA: Fix downstream validation.
+  * BMP: Fix route sending.
+  * BGP: Fix route refresh after restart.
+  * BGP: Fix dynamic peer connection.
+  * Filters: Fix string attributes.
+  * Filters: Fix ROA check autoreload reconfiguration.
+  * Logging: Fix error handling.
+  * Kernel: Fix graceful recovery.
+  * Pipe: Fix rare collision bug.
+  * Config: Allow keyword redefinition.
+
+-------------------------------------------------------------------

Old:
----
  bird-3.2.1.tar.gz
  bird-doc-3.2.1.tar.gz

New:
----
  bird-3.3.1.tar.gz
  bird-doc-3.3.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ bird3.spec ++++++
--- /var/tmp/diff_new_pack.XirIyP/_old  2026-06-15 19:53:22.264394501 +0200
+++ /var/tmp/diff_new_pack.XirIyP/_new  2026-06-15 19:53:22.268394669 +0200
@@ -17,7 +17,7 @@
 
 %define bird_runtimedir %{_rundir}/bird
 Name:           bird3
-Version:        3.2.1
+Version:        3.3.1
 Release:        0
 Summary:        The BIRD Internet Routing Daemon
 License:        GPL-2.0-or-later

++++++ bird-3.2.1.tar.gz -> bird-3.3.1.tar.gz ++++++
++++ 22792 lines of diff (skipped)

++++++ bird-doc-3.2.1.tar.gz -> bird-doc-3.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird-1.html 
new/bird-doc-3.3.1/doc/bird-1.html
--- old/bird-doc-3.2.1/doc/bird-1.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird-1.html  2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide: Introduction</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide: Introduction</TITLE>
  <LINK HREF="bird-2.html" REL=next>
 
  <LINK HREF="bird.html#toc1" REL=contents>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird-2.html 
new/bird-doc-3.3.1/doc/bird-2.html
--- old/bird-doc-3.2.1/doc/bird-2.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird-2.html  2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide: Architecture</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide: Architecture</TITLE>
  <LINK HREF="bird-3.html" REL=next>
  <LINK HREF="bird-1.html" REL=previous>
  <LINK HREF="bird.html#toc2" REL=contents>
@@ -114,6 +114,17 @@
 <LI>(PK) AS number</LI>
 </UL>
 <P>
+<H3><A NAME="aspa-routes"></A> Autonomous System Provider Authorization 
routes</H3>
+
+<P>These entries can be used to validate <CODE>AS_PATH</CODE> attribute of BGP 
routes.
+An ASPA entry specifies a list of valid providers for specific Autonomous 
System.
+Configuration keyword is <CODE>aspa</CODE>.
+<P>
+<UL>
+<LI>(PK) AS number</LI>
+<LI>List of AS numbers of providers</LI>
+</UL>
+<P>
 <H3><A NAME="flow-routes"></A> Flowspec for IPv4 and IPv6</H3>
 
 <P>Flowspec rules are a form of firewall and traffic flow control rules
@@ -127,6 +138,21 @@
 <LI>Flow action (encoded internally as BGP communities according to <A 
HREF="http://www.rfc-editor.org/info/rfc8955";>RFC 8955</A>)</LI>
 </UL>
 <P>
+<H3><A NAME="eth-routes"></A> Ethernet forwarding entries</H3>
+
+<P>Ethernet forwarding entries are entries in bridge forwarding database. They
+control forwarding of ethernet frames based on destination MAC addresses. Each
+entry maps a MAC address (and VLAN ID) to a specific port, determining which
+interface should receive frames destined for that address. Optionally, next hop
+can be used for VXLAN encapsulation (as part of EVPN deployment). Configuration
+keyword is <CODE>eth</CODE>.
+<P>
+<UL>
+<LI>(PK) MAC address</LI>
+<LI>(PK) VLAN ID</LI>
+<LI>Route interface (and next hop)</LI>
+</UL>
+<P>
 <H3><A NAME="mpls-routes"></A> MPLS switching rules</H3>
 
 <P>MPLS routes control MPLS forwarding in the same way as IP routes control IP
@@ -138,6 +164,80 @@
 <LI>Route next hops</LI>
 </UL>
 <P>
+<H3><A NAME="evpn-routes"></A> EVPN routes</H3>
+
+<P>EVPN routes encode control plane information for Ethernet VPN (EVPN)
+networks. They carry MAC address and IP address reachability information using
+BGP advertisements. There are several types of EVPN routes, each serves 
specific
+purposes - MAC (type 2) routes advertise MAC/IP locations, IMET (type 3) routes
+announce endpoints for broadcast / unknown / multicast communication. These
+routes enable distributed learning of endpoint locations across multiple sites
+in the overlay network. Configuration keyword is <CODE>evpn</CODE>.
+<P>
+<H3><A NAME="evpn-ead-routes"></A> EVPN Ethernet Auto-Discovery (EAD) 
routes</H3>
+
+<P>EVPN EAD routes advertise Ethernet segment reachability and enable
+multihoming redundancy mechanisms. Currently not used by BIRD.
+<P>
+<UL>
+<LI>(PK) Ethernet Segment Identifier (ESI)</LI>
+<LI>(PK) Ethernet Tag ID (tag)</LI>
+<LI>(PK) Route Distinguisher (RD)</LI>
+<LI>MPLS label / VNI</LI>
+</UL>
+<P>
+<H3><A NAME="evpn-mac-routes"></A> EVPN MAC/IP Advertisement (MAC) routes</H3>
+
+<P>EVPN MAC routes advertise MAC addresses and optionally their associated IP
+addresses within an EVPN instance.
+<P>
+<UL>
+<LI>(PK) MAC address</LI>
+<LI>(PK) IP address (optional)</LI>
+<LI>(PK) Ethernet Tag ID (tag)</LI>
+<LI>(PK) Route Distinguisher (RD)</LI>
+<LI>Ethernet Segment Identifier (ESI)</LI>
+<LI>Router IP address</LI>
+<LI>MPLS label / VNI</LI>
+</UL>
+<P>
+<H3><A NAME="evpn-imet-routes"></A> EVPN Inclusive Multicast Ethernet Tag 
(IMET) routes</H3>
+
+<P>EVPN IMET routes advertise endpoints for BUM (Broadcast, Unknown, Multicast)
+traffic forwarding.
+<P>
+<UL>
+<LI>(PK) Ethernet Tag ID (tag)</LI>
+<LI>(PK) Route Distinguisher (RD)</LI>
+<LI>(PK) Router IP address</LI>
+<LI>MPLS label / VNI (in PMSI attribute)</LI>
+</UL>
+<P>
+<H3><A NAME="evpn-es-routes"></A> EVPN Ethernet Segment (ES) routes</H3>
+
+<P>EVPN ES routes advertise Ethernet segment identifiers and designated
+forwarder election information for multihoming. Currently not used by BIRD.
+<P>
+<UL>
+<LI>(PK) Ethernet Segment Identifier (ESI)</LI>
+<LI>(PK) Route Distinguisher (RD)</LI>
+<LI>(PK) Router IP address</LI>
+</UL>
+<P>
+<H3><A NAME="neighbor-routes"></A> Neighbor entries</H3>
+
+<P>Neighbor entries represent discovered network neighbors. These are used to
+exchange neighbor information between protocols. For example, in automatic BGP
+peering scenarios, protocols responsible for router discovery (such as RAdv)
+announce these entries, which are then exported to a dynamic BGP instance to
+automatically establish peering sessions. The same type is used for both IPv4
+and IPv6 neighbors. Configuration keyword is <CODE>neighbor</CODE>.
+<P>
+<UL>
+<LI>(PK) IP address</LI>
+<LI>(PK) Interface index</LI>
+</UL>
+<P>
 <H3><A NAME="route-next-hop"></A> Route next hops</H3>
 
 <P>This is not a nettype. The route next hop is a complex attribute common for 
many
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird-3.html 
new/bird-doc-3.3.1/doc/bird-3.html
--- old/bird-doc-3.2.1/doc/bird-3.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird-3.html  2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide: Configuration</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide: Configuration</TITLE>
  <LINK HREF="bird-4.html" REL=next>
  <LINK HREF="bird-2.html" REL=previous>
  <LINK HREF="bird.html#toc3" REL=contents>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird-4.html 
new/bird-doc-3.3.1/doc/bird-4.html
--- old/bird-doc-3.2.1/doc/bird-4.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird-4.html  2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide: Remote control</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide: Remote control</TITLE>
  <LINK HREF="bird-5.html" REL=next>
  <LINK HREF="bird-3.html" REL=previous>
  <LINK HREF="bird.html#toc4" REL=contents>
@@ -76,6 +76,10 @@
 reconfiguration.
 <P>
 <DT><CODE>
+<A NAME="cli-show-memory"></A> show memory</CODE><DD><P>Show BIRD memory 
statistics. BIRD does not stop other computations in order to measure
+the used memory, hence the measured memory usage may differ from the real 
memory usage.
+<P>
+<DT><CODE>
 <A NAME="cli-show-interfaces"></A> show interfaces [summary]</CODE><DD><P>Show 
the list of interfaces. For each interface, print its type, state,
 MTU and addresses assigned.
 <P>
@@ -258,7 +262,7 @@
 <A NAME="cli-debug"></A> debug <I>protocol</I>|<I>pattern</I>|all all|off|{ 
states|routes|filters|events|packets [, <I>...</I>] }</CODE><DD><P>Control 
protocol debugging.
 <P>
 <DT><CODE>
-<A NAME="cli-dump"></A> dump resources|sockets|ao 
keys|events|interfaces|neighbors|attributes|routes|protocols 
"<I>file</I>"</CODE><DD><P>Creates the given file (it must not exist) and dumps 
contents of
+<A NAME="cli-dump"></A> dump resources|sockets|ao 
keys|events|interfaces|neighbors|attributes|attribute stats|routes|protocols 
"<I>file</I>"</CODE><DD><P>Creates the given file (it must not exist) and dumps 
contents of
 internal data structures there. By sending SIGUSR1, you get all of
 these concatenated to <CODE>bird.dump</CODE> in the current directory.
 The file is only readable for the user running the daemon.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird-5.html 
new/bird-doc-3.3.1/doc/bird-5.html
--- old/bird-doc-3.2.1/doc/bird-5.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird-5.html  2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide: Filters</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide: Filters</TITLE>
  <LINK HREF="bird-6.html" REL=next>
  <LINK HREF="bird-4.html" REL=previous>
  <LINK HREF="bird.html#toc5" REL=contents>
@@ -183,6 +183,10 @@
 <CODE>1.2.3.4.mask(8) = 1.0.0.0</CODE> is true.
 <P>
 <DT><CODE>
+<A NAME="type-mac"></A> mac</CODE><DD><P>This type can hold a single MAC 
address. MAC addresses are written
+in the usual notation (e.g. <CODE>62:68:7f:d9:c6:ec</CODE>).
+<P>
+<DT><CODE>
 <A NAME="type-prefix"></A> prefix</CODE><DD><P>This type can hold a network 
prefix consisting of IP address, prefix
 length and several other values. This is the key in route tables.
 <P>Prefixes may be of several types, which can be determined by the special
@@ -208,12 +212,31 @@
 together with an ASN. They support the same special operators as IP
 prefixes, and also <CODE>.maxlen</CODE> which extracts maximal prefix length,
 and <CODE>.asn</CODE> which extracts the ASN.
+<P><CODE>NET_ASPA</CODE> prefixes hold an ASN, which can be extracted by 
<CODE>.asn</CODE>
+operator.
 <P><CODE>NET_FLOW4</CODE> and <CODE>NET_FLOW6</CODE> hold an IP prefix 
together with a
 flowspec rule. Filters currently do not support much flowspec parsing,
 only <CODE>.src</CODE> and <CODE>.dst</CODE> operators to get source and 
destination
 parts of the flowspec as separate <CODE>NET_IP4</CODE> / <CODE>NET_IP6</CODE> 
values.
+<P><CODE>NET_ETH</CODE> prefixes holds a MAC address and a VLAN ID, which can 
be
+extracted by operators <CODE>.mac</CODE> and <CODE>.vlan_id</CODE>, 
respectively.
 <P><CODE>NET_MPLS</CODE> holds a single MPLS label and its handling is 
currently
 not implemented.
+<P><CODE>NET_EVPN</CODE> is a complex nettype that holds reachability 
information
+for Ethernet VPN. It has several subtypes (<CODE>NET_EVPN_EAD</CODE>,
+<CODE>NET_EVPN_MAC</CODE>, <CODE>NET_EVPN_IMET</CODE>, 
<CODE>NET_EVPN_ES</CODE>), which can be
+determined by the operator <CODE>.evpn_type</CODE>. Fields and related 
operators
+are: Route Distinguisher (<CODE>.rd</CODE>), MAC address (<CODE>.mac</CODE>), 
IP address
+(<CODE>.ip</CODE>), EVPN tag (<CODE>.evpn_tag</CODE>), Ethernet Segment 
Identifier
+(<CODE>.evpn_esi</CODE>), router IP (<CODE>.router_ip</CODE>). Note that only 
fields
+that are a part of primary key for given route subtype can be accessed
+by these operators (e.g. <CODE>.evpn_esi</CODE> can be used for 
<CODE>NET_EVPN_ES</CODE>,
+but not for <CODE>NET_EVPN_MAC</CODE> or other types), remaining attributes are
+stored outside prefix as other route attributes. See 
+<A HREF="bird-2.html#evpn-routes">EVPN routes</A> for description of specific 
subtypes.
+<P><CODE>NET_NEIGHBOR</CODE> holds a single IP address and an interface index.
+The IP address can be accessed by operator <CODE>.ip</CODE>, while the access
+to the interface index is not implemented.
 <P>
 <DT><CODE>
 <A NAME="type-rd"></A> <A NAME="type-vpnrd"></A> rd</CODE><DD><P>This is a 
route distinguisher according to <A 
HREF="http://www.rfc-editor.org/info/rfc4364";>RFC 4364</A>. There are
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird-6.html 
new/bird-doc-3.3.1/doc/bird-6.html
--- old/bird-doc-3.2.1/doc/bird-6.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird-6.html  2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide: Protocols</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide: Protocols</TITLE>
  <LINK HREF="bird-7.html" REL=next>
  <LINK HREF="bird-5.html" REL=previous>
  <LINK HREF="bird.html#toc6" REL=contents>
@@ -1469,7 +1469,9 @@
  <CODE>vpn4 multicast</CODE> </TD><TD> <CODE>vpn4</CODE> </TD><TD> 
<CODE>ipv4</CODE> and <CODE>ipv6</CODE> </TD><TD> 1 </TD><TD> 
129</TD></TR><TR><TD>
  <CODE>vpn6 multicast</CODE> </TD><TD> <CODE>vpn6</CODE> </TD><TD> 
<CODE>ipv4</CODE> and <CODE>ipv6</CODE> </TD><TD> 2 </TD><TD> 
129</TD></TR><TR><TD>
  <CODE>flow4</CODE> </TD><TD> <CODE>flow4</CODE> </TD><TD> --- </TD><TD> 1 
</TD><TD> 133</TD></TR><TR><TD>
- <CODE>flow6</CODE> </TD><TD> <CODE>flow6</CODE> </TD><TD> --- </TD><TD> 2 
</TD><TD> 133
+ <CODE>flow6</CODE> </TD><TD> <CODE>flow6</CODE> </TD><TD> --- </TD><TD> 2 
</TD><TD> 133</TD></TR><TR><TD>
+ <CODE>evpn</CODE> </TD><TD> <CODE>evpn</CODE> </TD><TD> <CODE>ipv4</CODE> and 
<CODE>ipv6</CODE> </TD><TD> 25 </TD><TD> 70</TD></TR><TR><TD>
+ <CODE>neighbors</CODE> </TD><TD> <CODE>neighbor</CODE> </TD><TD> --- 
</TD><TD> --- </TD><TD> ---
 
 </TD></TR></TABLE></CENTER>
 <P>
@@ -1491,6 +1493,17 @@
 configuration). Note that blanket policies like <CODE>all</CODE> or 
<CODE>none</CODE> can still
 be used in explicit configuration.
 <P>
+<P>The <CODE>neighbors</CODE> channel is a special channel used for BGP 
unnumbered
+automatic peering. Unlike traditional AFI/SAFI channels that exchange routing
+information, the <CODE>neighbors</CODE> channel is used to dynamically trigger 
the
+creation of new BGP sessions. When present in a dynamic BGP configuration,
+exporting neighbor objects (typically from RAdv with router discovery enabled)
+to this channel will automatically spawn new BGP sessions for each discovered
+neighbor. The lifetime of these automatic sessions is tied to the presence of
+neighbor objects in the neighbor routing table, withdrawing an object will
+trigger deprecation of the corresponding BGP session. This channel is only
+allowed in dynamic BGP instances (those configured with <CODE>neighbor 
range</CODE>).
+<P>
 <P>BGP channels have additional config options (together with the common ones):
 <P>
 <DL>
@@ -1927,6 +1940,14 @@
 route reflector prepends its cluster ID when reflecting the route.
 <P>
 <DT><CODE>
+<A NAME="rta-bgp-pmsi-tunnel"></A> void bgp_pmsi_tunnel [O]</CODE><DD><P>The 
PMSI (P-Multicast Service Interface) tunnel BGP attribute is carried
+by EVPN IMET routes to describe the multicast tunnel information that
+carries BUM (Broadcast, Unknown, Multicast) traffic. It specifies the
+tunnel type (such as PIM-SSM, PIM-ASM, or Ingress Replication), the
+tunnel identifier, and the MPLS/VNI label for a specific EVPN instance.
+Currently, the attribute is not accessible from filters.
+<P>
+<DT><CODE>
 <A NAME="rta-bgp-aigp"></A> void bgp_aigp [O]</CODE><DD><P>This attribute 
contains accumulated IGP metric, which is a total
 distance to the destination through multiple autonomous systems.
 Currently, the attribute is not accessible from filters.
@@ -2008,6 +2029,50 @@
 </PRE>
 <HR>
 <P>
+<P>Example configuration for BGP unnumbered automatic peering using router 
discovery:
+<P>
+<P>
+<HR>
+<PRE>
+# Table for discovered peers
+neighbor table peers;
+
+# RAdv protocol with router discovery enabled
+protocol radv {
+        neighbors { table peers; };     # Export discovered peers to this table
+
+        interface "eth*" {
+                # Normal RAdv configuration options...
+                router discovery yes;   # Enable reception of ICMPv6 RAs
+        };
+}
+
+# Dynamic BGP with neighbor channel for automatic peering
+protocol bgp bgp_root {
+        local as 65000;
+        neighbor range fe80::/64 external;      # Accept link-local peers
+        dynamic name "bgp_auto_";       # Name spawned sessions with this 
prefix
+        dynamic name digits 2;          # Number of digits in name after prefix
+
+        ipv4 {
+                export all;
+                import all;
+                extended next hop;      # Allow IPv6 next hops for IPv4 routes
+        };
+
+        ipv6 {
+                export all;
+                import all;
+        };
+
+        neighbors {
+                table peers;            # Import peer discovery objects from 
this table
+                export all;             # Allow all discovered peers to 
trigger sessions
+        };
+}
+</PRE>
+<HR>
+<P>
 <P>
 <H2><A NAME="bmp"></A> <A NAME="ss6.5">6.5</A> <A 
HREF="bird.html#toc6.5">BMP</A>
 </H2>
@@ -2015,9 +2080,7 @@
 <P>The BGP Monitoring Protocol is used for monitoring BGP sessions and 
obtaining
 routing table data. The current implementation in BIRD is a preliminary release
 with a limited feature set, it will be subject to significant changes in the
-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
-<CODE>--with-protocols=</CODE>.
+future.
 <P>
 <P>The implementation supports monitoring protocol state changes, pre-policy
 routes (in 
@@ -2055,7 +2118,112 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="device"></A> <A NAME="ss6.6">6.6</A> <A 
HREF="bird.html#toc6.6">Device</A>
+<H2><A NAME="bridge"></A> <A NAME="ss6.6">6.6</A> <A 
HREF="bird.html#toc6.6">Bridge</A>
+</H2>
+
+<P>The Bridge protocol is responsible for synchronization of BIRD's ethernet
+table with a forwarding database of a bridge device in the OS kernel. Similarly
+to the 
+<A HREF="#krt">Kernel</A> protocol, it sends all ethernet table
+updates to the OS kernel, listens to notifications from the OS kernel and from
+time to time it scans the OS bridge forwarding database to see whether some
+routes have changed.
+<P>
+<P>The Bridge protocol support not only regular forwarding entries to local
+interfaces, but also forwarding entries with VXLAN encapsulation to remote
+targets. Due to peculiarities of Linux OS networking stack, VXLAN interface 
bound
+to the bridge interface has its own forwarding database. The Bridge protocol in
+BIRD is responsible for managing both.
+<P>
+<P>Currently, the bridge protocol is limited to Linux.
+<P>
+<H3><A NAME="bridge-config"></A> Configuration</H3>
+
+<P>The Bridge protocol uses one ethernet channel. There are some options:
+<P>
+<P>
+<DL>
+<DT><CODE>
+<A NAME="bridge-bridge-device"></A> bridge device 
"<I>name</I>"</CODE><DD><P>The name of bridge device that is managed by the 
Bridge protocol instance.
+Mandatory.
+<P>
+<DT><CODE>
+<A NAME="bridge-vlan-filtering"></A> vlan filtering 
<I>switch</I></CODE><DD><P>Specify whether the bridge is VLAN-aware or not. 
Allows export and
+import of ethernet forwarding entries with defined VLAN ID. The OS
+bridge device must be created with <CODE>vlan_filtering 1</CODE> in order to be
+VLAN-aware. Default: off.
+<P>
+<DT><CODE>
+<A NAME="bridge-scan-time"></A> scan time <I>time</I></CODE><DD><P>Time 
between two consecutive scans of the forwarding database of the
+bridge device. Default: 60 s.
+</DL>
+<P>
+<H3><A NAME="bridge-exam"></A> Example</H3>
+
+<P>
+<HR>
+<PRE>
+eth table ethtab0;
+
+protocol static {
+        eth { table ethtab0; };
+
+        # Locally reachable MAC address
+        route eth 12:20:30:40:50:60 via "eth0";
+
+        # Remotely reachable MAC address through VXLAN (dst 10.1.1.100 vni 
100);
+        route eth 12:20:30:40:50:80 via 10.1.1.100 dev "vxlan0" mpls 100;
+}
+
+protocol bridge {
+        eth { table ethtab0; export all; };
+
+        bridge device "br0";
+        scan time 20 s;
+}
+</PRE>
+<HR>
+<P>
+<H3><A NAME="bridge-setup"></A> OS setup</H3>
+
+<P>The user is responsible to prepare bridge and (optionally) VXLAN interfaces
+on OS level. Here is an example how to setup simple bridge with VXLAN interface
+that uses fixed VNI:
+<P>
+<HR>
+<PRE>
+ip link add name $BRIDGE type bridge
+ip link set $BRIDGE up
+
+ip link add name $TUNNEL type vxlan id $VNI local $ROUTER_ADDR dstport 4789 
nolearning
+ip link set $TUNNEL master $BRIDGE
+bridge link set dev $TUNNEL learning off
+ip link set $TUNNEL up
+</PRE>
+<HR>
+<P>
+<P>And here is an example how to setup VLAN-aware bridge with VXLAN interface
+that allows multiple VNIs and dynamic mapping between VNIs and VLANs:
+<P>
+<HR>
+<PRE>
+ip link add name $BRIDGE type bridge vlan_filtering 1
+ip link set $BRIDGE up
+
+ip link add name $TUNNEL type vxlan local $ROUTER_ADDR dstport 4789 nolearning 
external
+ip link set $TUNNEL master $BRIDGE
+bridge link set dev $TUNNEL learning off
+bridge link set dev $TUNNEL vlan_tunnel on
+ip link set $TUNNEL up
+</PRE>
+<HR>
+<P>
+<P>When VLANs are defined by EVPN protocol, The membership of the VXLAN
+interface in VLANs is managed by BIRD, while user is responsible for setting
+VLANs for other (physical) interfaces in the bridge.
+<P>
+<P>
+<H2><A NAME="device"></A> <A NAME="ss6.7">6.7</A> <A 
HREF="bird.html#toc6.7">Device</A>
 </H2>
 
 <P>The Device protocol is not a real routing protocol. It doesn't generate any
@@ -2114,7 +2282,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="direct"></A> <A NAME="ss6.7">6.7</A> <A 
HREF="bird.html#toc6.7">Direct</A>
+<H2><A NAME="direct"></A> <A NAME="ss6.8">6.8</A> <A 
HREF="bird.html#toc6.8">Direct</A>
 </H2>
 
 <P>The Direct protocol is a simple generator of device routes for all the
@@ -2169,7 +2337,203 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="krt"></A> <A NAME="ss6.8">6.8</A> <A 
HREF="bird.html#toc6.8">Kernel</A>
+<H2><A NAME="evpn"></A> <A NAME="ss6.9">6.9</A> <A 
HREF="bird.html#toc6.9">EVPN</A>
+</H2>
+
+<H3><A NAME="evpn-intro"></A> Introduction</H3>
+
+<P>The EVPN protocol is a component for Ethernet VPNs (<A 
HREF="http://www.rfc-editor.org/info/rfc7432";>RFC 7432</A>) with
+VXLAN overlay (<A HREF="http://www.rfc-editor.org/info/rfc8365";>RFC 8365</A>) 
and implements policies defined there. It serves
+as a translator between BGP EVPN routes and ethernet forwarding entries.
+<P>
+<P>In BGP EVPNs, route distribution is controlled by Route Targets (RT). EVPN
+instances 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 
+<A HREF="#rta-bgp-ext-community">bgp_ext_community</A>. A route is then
+imported into each EVPN instance that shares an associated Route Target. The
+EVPN protocol implements this mechanism through mandatory <CODE>import 
target</CODE> and
+<CODE>export target</CODE> protocol options.
+<P>
+<P>One EVPN instance can consist of multiple broadcast domains (VLANs), these
+are identified by EVPN tags on BGP EVPN side and are mapped to VLAN IDs (VID) 
on
+ethernet side.
+<P>
+<P>The current EVPN implementation in BIRD is a preliminary release limited to
+basic handling of MAC and IMET EVPN routes, it will be subject to changes in 
the
+future.
+<P>
+<H3><A NAME="evpn-config"></A> Configuration</H3>
+
+<P>The EVPN protocol instance always must have two channels: <CODE>evpn</CODE> 
and
+<CODE>eth</CODE>. For convenience, the default export filter in these channels 
is
+<CODE>all</CODE>, as the primary way to control import and export of routes is 
through
+protocol options <CODE>import target</CODE> and <CODE>export target</CODE>. 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>
+<P>Note that outside of BIRD, it is necessary to configure bridge and VXLAN
+interface on Linux OS level. See 
+<A HREF="#bridge">Bridge</A> protocol for
+details. When VLANs are used, EVPN and Bridge protocols in BIRD are responsible
+for configuring VLANs on the bridge interface for the VXLAN interface, while
+user is responsible for setting VLANs for other (physical) interfaces in the
+bridge.
+<P>
+<HR>
+<PRE>
+protocol evpn [&lt;name>] {
+        route distinguisher &lt;rd>;
+        rd &lt;rd>;
+        import target &lt;ec> | &lt;ec-set>
+        export target &lt;ec> | &lt;ec-set>
+        route target &lt;ec> | &lt;ec-set>
+        vni &lt;number>;
+        vid &lt;number>;
+        tag &lt;number>;
+        encapsulation vxlan {
+                tunnel device "&lt;name>";
+                router address &lt;ip>;
+        };
+        vlan &lt;number> {
+                range &lt;number>;
+                vni &lt;number>;
+                vid &lt;number>;
+        };
+}
+</PRE>
+<HR>
+<P>
+<P>
+<DL>
+<DT><CODE>
+<A NAME="evpn-route-distinguisher"></A> route distinguisher 
<I>rd</I></CODE><DD><P>The route distinguisher that is attached to routes in 
the export
+direction. Mandatory.
+<P>
+<DT><CODE>
+<A NAME="evpn-rd"></A> rd <I>rd</I></CODE><DD><P>A shorthand for the option 
<CODE>route distinguisher</CODE>.
+<P>
+<DT><CODE>
+<A NAME="evpn-import-target"></A> import target 
<I>ec</I>|<I>ec-set</I>|none|all</CODE><DD><P>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 EVPN protocol. Mandatory.
+<P>
+<DT><CODE>
+<A NAME="evpn-export-target"></A> export target 
<I>ec</I>|<I>ec-set</I>|none</CODE><DD><P>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.
+<P>
+<DT><CODE>
+<A NAME="evpn-route-target"></A> route target 
<I>ec</I>|<I>ec-set</I>|none</CODE><DD><P>A shorthand for both <CODE>import 
target</CODE> and <CODE>export target</CODE>.
+<P>
+<DT><CODE>
+<A NAME="evpn-encapsulation"></A> encapsulation <I>type</I> { <I>options</I> 
}</CODE><DD><P>The encapsulation block specifies how ethernet frames are 
encapsulated
+when forwarded through overlay network. Currently, the only supported
+encapsulation type is <CODE>vxlan</CODE>.
+<P>
+<DT><CODE>
+<A NAME="evpn-tunnel-device"></A> tunnel device "<I>name</I>"</CODE><DD><P>The 
name of VXLAN tunnel device that is used for encapsulation.
+Mandatory.
+<P>
+<DT><CODE>
+<A NAME="evpn-router-address"></A> router address <I>ip</I></CODE><DD><P>The 
IP address used for encapsulated traffic. Can be usually
+autodetected from the VXLAN device.
+<P>
+<DT><CODE>
+<A NAME="evpn-tag"></A> tag <I>number</I></CODE><DD><P>EVPN tag is used in BGP 
EVPN to identify specific broadcast domain. Must
+be unique per EVPN instance. Can be used as a protocol option to specify
+non-zero tag for the EVPN instance. Default: 0
+<P>
+<DT><CODE>
+<A NAME="evpn-vni"></A> vni <I>number</I></CODE><DD><P>VNI label is used in 
dataplane encapsulation to identify specific
+broadcast domain. Must be unique per PE router. Can be used both as a
+protocol option (to specify VNI when the EVPN instance is one broadcast
+domain) or in <CODE>vlan</CODE> block (to specify VNI for each VLAN). Mandatory
+as a protocol option (unless autodetected from the VXLAN device).
+<P>
+<DT><CODE>
+<A NAME="evpn-vid"></A> vid <I>number</I></CODE><DD><P>VLAN ID is used on 
ethernet to identify specific ethernet VLAN. Must be
+unique per ethernet network. Can be used both as a protocol option (to
+specify VID when the EVPN instance is one broadcast domain) or in
+<CODE>vlan</CODE> block (to specify VID for each VLAN). Default: 0 (untagged)
+as a protocol option.
+<P>
+<DT><CODE>
+<A NAME="evpn-vlan"></A> vlan <I>number</I> { <I>options</I> 
}</CODE><DD><P>Defines a separate broadcast domain (VLAN) in an EVPN instance.
+Each VLAN has its own EVPN tag, encapsulation VNI, and ethernet VID, all
+initialized to the same value (the <CODE>vlan</CODE> argument), but VNI and VID
+can be changed by options in <CODE>vlan</CODE> block. When used with 
<CODE>range</CODE>
+option, it can define an interval of VLANs instead of just one VLAN.
+<P>
+<DT><CODE>
+<A NAME="evpn-range"></A> range <I>number</I></CODE><DD><P>Extends 
<CODE>vlan</CODE> block to define an interval of VLANs instead of just
+one VLAN. Defined VLANs have consecutive values of EVPN tags, VNIs, and
+VIDs. See 
+<A HREF="#evpn-exam">example</A>.
+</DL>
+<P>
+<H3><A NAME="evpn-attr"></A> Attributes</H3>
+
+<P>The EVPN protocol does not define any route attributes, but uses several BGP
+attributes for EVPN routes.
+<P>
+<H3><A NAME="evpn-exam"></A> Example</H3>
+
+<P>Here is an example of EVPN setup with one VPN and BGP uplink. Locally
+reachable MAC addresses are learned by the Bridge protocol instance
+<CODE>bridge0</CODE> as ethernet forwarding entries and stored in the table
+<CODE>ethtab0</CODE>, then translated by the EVPN protocol instance 
<CODE>evpn0</CODE> and
+stored in global EVPN table <CODE>evpntab</CODE>. Routes can also be exchanged 
through
+BGP with different sites hosting that VPN. Remotelly reachable MAC addresses 
are
+received by BGP as EVPN routes, translated by <CODE>evpn0</CODE> to ethernet 
forwarding
+entries directed at <CODE>vxlan0</CODE> interface and then exported to the 
kernel by
+<CODE>bridge0</CODE>. Forwarding of VPN traffic through the network is handled 
by VXLAN.
+<P>
+<HR>
+<PRE>
+evpn table evpntab;
+
+# Exchange EVPN routes through BGP
+protocol bgp {
+        evpn { table evpntab; import all; export all; };
+        local 10.0.0.1 as 10;
+        neighbor 10.0.0.2 as 10;
+}
+
+# EVPN Instance 0
+eth table ethtab0;
+
+protocol bridge bridge0 {
+        eth { table ethtab0; export all; };
+
+        bridge device "br0";
+        vlan filtering;
+}
+
+protocol evpn evpn0 {
+        eth { table ethtab0; };
+        evpn { table evpntab; };
+
+        rd 10:12;
+        route target (rt, 10, 10);
+
+        encapsulation vxlan {
+                tunnel device "vxlan0";
+        };
+
+        # VNI for untagged traffic
+        vni 100;
+
+        # VLANs 20-29, VNIs 120-129
+        vlan 20 { range 10; vni 120; };
+}
+</PRE>
+<HR>
+<P>
+<P>
+<H2><A NAME="krt"></A> <A NAME="ss6.10">6.10</A> <A 
HREF="bird.html#toc6.10">Kernel</A>
 </H2>
 
 <P>The Kernel protocol is not a real routing protocol. Instead of communicating
@@ -2359,7 +2723,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="l3vpn"></A> <A NAME="ss6.9">6.9</A> <A 
HREF="bird.html#toc6.9">L3VPN</A>
+<H2><A NAME="l3vpn"></A> <A NAME="ss6.11">6.11</A> <A 
HREF="bird.html#toc6.11">L3VPN</A>
 </H2>
 
 <H3><A NAME="l3vpn-intro"></A> Introduction</H3>
@@ -2493,7 +2857,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="mrt"></A> <A NAME="ss6.10">6.10</A> <A 
HREF="bird.html#toc6.10">MRT</A>
+<H2><A NAME="mrt"></A> <A NAME="ss6.12">6.12</A> <A 
HREF="bird.html#toc6.12">MRT</A>
 </H2>
 
 <H3><A NAME="mrt-intro"></A> Introduction</H3>
@@ -2568,7 +2932,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="ospf"></A> <A NAME="ss6.11">6.11</A> <A 
HREF="bird.html#toc6.11">OSPF</A>
+<H2><A NAME="ospf"></A> <A NAME="ss6.13">6.13</A> <A 
HREF="bird.html#toc6.13">OSPF</A>
 </H2>
 
 <H3><A NAME="ospf-intro"></A> Introduction</H3>
@@ -3194,7 +3558,7 @@
 </PRE>
 <HR>
 <P>
-<H2><A NAME="pipe"></A> <A NAME="ss6.12">6.12</A> <A 
HREF="bird.html#toc6.12">Pipe</A>
+<H2><A NAME="pipe"></A> <A NAME="ss6.14">6.14</A> <A 
HREF="bird.html#toc6.14">Pipe</A>
 </H2>
 
 <H3><A NAME="pipe-intro"></A> Introduction</H3>
@@ -3316,7 +3680,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="radv"></A> <A NAME="ss6.13">6.13</A> <A 
HREF="bird.html#toc6.13">RAdv</A>
+<H2><A NAME="radv"></A> <A NAME="ss6.15">6.15</A> <A 
HREF="bird.html#toc6.15">RAdv</A>
 </H2>
 
 <H3><A NAME="radv-intro"></A> Introduction</H3>
@@ -3330,7 +3694,12 @@
 in <A HREF="http://www.rfc-editor.org/info/rfc4861";>RFC 4861</A>, router 
preferences and specific routes (<A 
HREF="http://www.rfc-editor.org/info/rfc4191";>RFC 4191</A>),
 and DNS extensions (<A HREF="http://www.rfc-editor.org/info/rfc6106";>RFC 
6106</A>).
 <P>
-<P>The RAdv protocols supports just IPv6 channel.
+<P>The RAdv protocols supports the IPv6 channel (for the 
+<A HREF="#radv-trigger">trigger prefix</A>
+and 
+<A HREF="#radv-propagate-routes">more specific route propagation</A>)
+and the <CODE>neighbors</CODE> channel (for the 
+<A HREF="#radv-router-discovery">router discovery</A>).
 <P>
 <H3><A NAME="radv-config"></A> Configuration</H3>
 
@@ -3524,6 +3893,17 @@
 <DT><CODE>
 <A NAME="radv-iface-custom-local"></A> custom option local 
<I>switch</I></CODE><DD><P>Use only local custom option definitions for this 
interface. See <CODE>rdnss local</CODE>
 option above. Default: no.
+<P>
+<DT><CODE>
+<A NAME="radv-router-discovery"></A> router discovery 
<I>switch</I></CODE><DD><P>Enable reception and processing of incoming ICMPv6 
Router Advertisement
+messages. When enabled, the RAdv protocol listens for RA messages on
+configured interfaces and creates route-like objects in a peers routing
+table based on detected advertisements. These objects contain information
+about discovered routers and their lifetimes are managed by the Router
+Lifetime field in the RA messages. When an RA expires, the corresponding
+object is automatically removed from the peers table. Currently, this feature
+is primarily used in conjunction with BGP unnumbered automatic peering to
+automatically discover BGP neighbors. Default: no.
 </DL>
 <P>
 <P>Prefix specific options
@@ -3676,7 +4056,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="rip"></A> <A NAME="ss6.14">6.14</A> <A 
HREF="bird.html#toc6.14">RIP</A>
+<H2><A NAME="rip"></A> <A NAME="ss6.16">6.16</A> <A 
HREF="bird.html#toc6.16">RIP</A>
 </H2>
 
 <H3><A NAME="rip-intro"></A> Introduction</H3>
@@ -3965,7 +4345,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="rpki"></A> <A NAME="ss6.15">6.15</A> <A 
HREF="bird.html#toc6.15">RPKI</A>
+<H2><A NAME="rpki"></A> <A NAME="ss6.17">6.17</A> <A 
HREF="bird.html#toc6.17">RPKI</A>
 </H2>
 
 <H3><A NAME="rpki-introduction"></A> Introduction</H3>
@@ -4210,7 +4590,7 @@
 <HR>
 <P>
 <P>
-<H2><A NAME="static"></A> <A NAME="ss6.16">6.16</A> <A 
HREF="bird.html#toc6.16">Static</A>
+<H2><A NAME="static"></A> <A NAME="ss6.18">6.18</A> <A 
HREF="bird.html#toc6.18">Static</A>
 </H2>
 
 <P>The Static protocol doesn't communicate with other routers in the network,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird-7.html 
new/bird-doc-3.3.1/doc/bird-7.html
--- old/bird-doc-3.2.1/doc/bird-7.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird-7.html  2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide: Conclusions</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide: Conclusions</TITLE>
  <LINK HREF="bird-6.html" REL=previous>
  <LINK HREF="bird.html#toc7" REL=contents>
 </HEAD>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/bird.html 
new/bird-doc-3.3.1/doc/bird.html
--- old/bird-doc-3.2.1/doc/bird.html    2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/bird.html    2026-06-09 11:02:33.000000000 +0200
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
- <TITLE>BIRD 3.2.1 User's Guide</TITLE>
+ <TITLE>BIRD 3.3.1 User's Guide</TITLE>
  <LINK HREF="bird-1.html" REL=next>
 
 
@@ -12,12 +12,12 @@
 Previous
 Contents
 <HR>
-<H1>BIRD 3.2.1 User's Guide</H1>
+<H1>BIRD 3.3.1 User's Guide</H1>
 
 <H2>Ondrej Filip <I>&lt;[email protected]&gt;</I>,
 Martin Mares <I>&lt;[email protected]&gt;</I>,
 Maria Matejka <I>&lt;[email protected]&gt;</I>,
-Ondrej Zajicek <I>&lt;[email protected]&gt;</I></H2>Wed, 1 Apr 2026 
20:02:46 +0200bird-userdoc
+Ondrej Zajicek <I>&lt;[email protected]&gt;</I></H2>Tue, 9 Jun 2026 
11:02:33 +0200bird-userdoc
 <P><HR>
 <EM>This document contains user documentation for the BIRD Internet Routing 
Daemon project.</EM>
 <HR>
@@ -79,17 +79,19 @@
 <LI><A NAME="toc6.3">6.3</A> <A HREF="bird-6.html#ss6.3">BFD</A>
 <LI><A NAME="toc6.4">6.4</A> <A HREF="bird-6.html#ss6.4">BGP</A>
 <LI><A NAME="toc6.5">6.5</A> <A HREF="bird-6.html#ss6.5">BMP</A>
-<LI><A NAME="toc6.6">6.6</A> <A HREF="bird-6.html#ss6.6">Device</A>
-<LI><A NAME="toc6.7">6.7</A> <A HREF="bird-6.html#ss6.7">Direct</A>
-<LI><A NAME="toc6.8">6.8</A> <A HREF="bird-6.html#ss6.8">Kernel</A>
-<LI><A NAME="toc6.9">6.9</A> <A HREF="bird-6.html#ss6.9">L3VPN</A>
-<LI><A NAME="toc6.10">6.10</A> <A HREF="bird-6.html#ss6.10">MRT</A>
-<LI><A NAME="toc6.11">6.11</A> <A HREF="bird-6.html#ss6.11">OSPF</A>
-<LI><A NAME="toc6.12">6.12</A> <A HREF="bird-6.html#ss6.12">Pipe</A>
-<LI><A NAME="toc6.13">6.13</A> <A HREF="bird-6.html#ss6.13">RAdv</A>
-<LI><A NAME="toc6.14">6.14</A> <A HREF="bird-6.html#ss6.14">RIP</A>
-<LI><A NAME="toc6.15">6.15</A> <A HREF="bird-6.html#ss6.15">RPKI</A>
-<LI><A NAME="toc6.16">6.16</A> <A HREF="bird-6.html#ss6.16">Static</A>
+<LI><A NAME="toc6.6">6.6</A> <A HREF="bird-6.html#ss6.6">Bridge</A>
+<LI><A NAME="toc6.7">6.7</A> <A HREF="bird-6.html#ss6.7">Device</A>
+<LI><A NAME="toc6.8">6.8</A> <A HREF="bird-6.html#ss6.8">Direct</A>
+<LI><A NAME="toc6.9">6.9</A> <A HREF="bird-6.html#ss6.9">EVPN</A>
+<LI><A NAME="toc6.10">6.10</A> <A HREF="bird-6.html#ss6.10">Kernel</A>
+<LI><A NAME="toc6.11">6.11</A> <A HREF="bird-6.html#ss6.11">L3VPN</A>
+<LI><A NAME="toc6.12">6.12</A> <A HREF="bird-6.html#ss6.12">MRT</A>
+<LI><A NAME="toc6.13">6.13</A> <A HREF="bird-6.html#ss6.13">OSPF</A>
+<LI><A NAME="toc6.14">6.14</A> <A HREF="bird-6.html#ss6.14">Pipe</A>
+<LI><A NAME="toc6.15">6.15</A> <A HREF="bird-6.html#ss6.15">RAdv</A>
+<LI><A NAME="toc6.16">6.16</A> <A HREF="bird-6.html#ss6.16">RIP</A>
+<LI><A NAME="toc6.17">6.17</A> <A HREF="bird-6.html#ss6.17">RPKI</A>
+<LI><A NAME="toc6.18">6.18</A> <A HREF="bird-6.html#ss6.18">Static</A>
 </UL>
 <P>
 <H2><A NAME="toc7">7.</A> <A HREF="bird-7.html">Conclusions</A></H2>
Binary files old/bird-doc-3.2.1/doc/bird.pdf and 
new/bird-doc-3.3.1/doc/bird.pdf differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/prog-2.html 
new/bird-doc-3.3.1/doc/prog-2.html
--- old/bird-doc-3.2.1/doc/prog-2.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/prog-2.html  2026-06-09 11:02:33.000000000 +0200
@@ -933,38 +933,87 @@
 
 
 <HR><H3>Function</H3>
-<P><I>int</I>
-<B>ea_same</B>
-(<I>ea_list *</I> <B>x</B>, <I>ea_list *</I> <B>y</B>) --     compare two 
<I>ea_list</I>'s
+<P><I>void</I>
+<B>ea_do_prune</B>
+(<I>ea_list *</I> <B>e</B>)
+<H3>Arguments</H3>
+<P>
+<DL>
+<DT><I>ea_list *</I> <B>e</B><DD><P>-- undescribed --
+</DL>
+<H3>Description</H3>
+<P>for this reason.
+
+
+<HR><H3>Function</H3>
+<P><I>void</I>
+<B>ea_sort</B>
+(<I>ea_list *</I> <B>e</B>) --     sort an attribute list
 <P>
 <H3>Arguments</H3>
 <P>
 <DL>
-<DT><I>ea_list *</I> <B>x</B><DD><P>attribute list
-<DT><I>ea_list *</I> <B>y</B><DD><P>attribute list
+<DT><I>ea_list *</I> <B>e</B><DD><P>list to be sorted
 </DL>
 <H3>Description</H3>
-<P><B>ea_same()</B> compares two normalized attribute lists <B>x</B> and 
<B>y</B> and returns
-1 if they contain the same attributes, 0 otherwise.
+<P>This function takes a <I>ea_list</I> chain and sorts the attributes
+within each of its entries.
+<P>If an attribute occurs multiple times in a single <I>ea_list</I>,
+<B>ea_sort()</B> leaves only the first (the only significant) occurrence.
 
 
 <HR><H3>Function</H3>
-<P><I>ea_list *</I>
-<B>ea_normalize</B>
-(<I>ea_list *</I> <B>e</B>, <I>u32</I> <B>upto</B>) --     create a normalized 
version of attributes
+<P><I>unsigned</I>
+<B>ea_scan</B>
+(<I>const ea_list *</I> <B>e</B>, <I>u32</I> <B>upto</B>) --     estimate 
attribute list size
+<P>
+<H3>Arguments</H3>
+<P>
+<DL>
+<DT><I>const ea_list *</I> <B>e</B><DD><P>attribute list
+<DT><I>u32</I> <B>upto</B><DD><P>-- undescribed --
+</DL>
+<H3>Description</H3>
+<P>This function calculates an upper bound of the size of
+a given <I>ea_list</I> after merging with <B>ea_merge()</B>.
+
+
+<HR><H3>Function</H3>
+<P><I>void</I>
+<B>ea_merge</B>
+(<I>ea_list *</I> <B>e</B>, <I>ea_list *</I> <B>t</B>, <I>u32</I> <B>upto</B>) 
--     merge segments of an attribute list
+<P>
+<H3>Arguments</H3>
+<P>
+<DL>
+<DT><I>ea_list *</I> <B>e</B><DD><P>attribute list
+<DT><I>ea_list *</I> <B>t</B><DD><P>buffer to store the result to
+<DT><I>u32</I> <B>upto</B><DD><P>-- undescribed --
+</DL>
+<H3>Description</H3>
+<P>This function takes a possibly multi-segment attribute list
+and merges all of its segments to one.
+<P>The primary use of this function is for <I>ea_list</I> normalization:
+first call <B>ea_scan()</B> to determine how much memory will the result
+take, then allocate a buffer (usually using <B>alloca()</B>), merge the
+segments with <B>ea_merge()</B> and finally sort and prune the result
+by calling <B>ea_sort()</B>.
+
+
+<HR><H3>Function</H3>
+<P><I>int</I>
+<B>ea_same</B>
+(<I>ea_list *</I> <B>x</B>, <I>ea_list *</I> <B>y</B>) --     compare two 
<I>ea_list</I>'s
 <P>
 <H3>Arguments</H3>
 <P>
 <DL>
-<DT><I>ea_list *</I> <B>e</B><DD><P>input attributes
-<DT><I>u32</I> <B>upto</B><DD><P>bitmask of layers which should stay as an 
underlay
+<DT><I>ea_list *</I> <B>x</B><DD><P>attribute list
+<DT><I>ea_list *</I> <B>y</B><DD><P>attribute list
 </DL>
 <H3>Description</H3>
-<P>This function squashes all updates done atop some ea_list
-and creates the final structure useful for storage or fast searching.
-The method is a bucket sort.
-<P>Returns the final ea_list allocated from the tmp_linpool.
-The adata is linked from the original places.
+<P><B>ea_same()</B> compares two normalized attribute lists <B>x</B> and 
<B>y</B> and returns
+1 if they contain the same attributes, 0 otherwise.
 
 
 <HR><H3>Function</H3>
@@ -1031,27 +1080,207 @@
 <P>This function appends the <I>ea_list</I> <B>what</B> at the end of
 <I>ea_list</I> <B>to</B> and returns a pointer to the resulting list.
 
+<H2><A NAME="route-attribute-storage"></A> <A NAME="ss2.4">2.4</A> <A 
HREF="prog.html#toc2.4">Route attribute storage</A>
+</H2>
 
-<HR><H3>Function</H3>
+<P>
+<P>While local procesing of routes is done on local structures, the attributes
+have to be stored to a global data structure to have sufficient lifetime.
+The global storage also serves deduplication purposes, i.e. when an identical
+attribute set is about to be stored, an existing structure is returned instead.
+<P>All the globally-stored attribute sets have the attributes sorted by ID.
+<P>The public interface consists of:
+<P>- <B>ea_lookup()</B> to get the global instance of the given attribute list,
+or to bump its usecount
+- <B>ea_free()</B> to decrease the instance's usecount, with possibly delayed 
free
+- <B>ea_lookup_tmp()</B> to do <B>ea_lookup()</B> with <B>ea_free()</B> 
auto-called after the end
+of the task
+<P>There are also several low-level interface functions and helpers.
+<P>There may be attributes which need to recursively refer to another 
attribute set.
+These attributes must have <CODE>stored</CODE> and <CODE>freed</CODE> hooks of 
their <CODE>struct ea_class</CODE>
+defined.
+<P>Description of the data structure follows; more detailed information is
+directly in the code.
+<P>**************************************
+Internal structure of route storage *
+**************************************
+<P>Attribute lists, publicly available as <CODE>ea_list</CODE>, are stored as 
<CODE>ea_storage</CODE>
+which contains the <CODE>ea_list</CODE> and adds storage-private data. One 
should not access
+the <CODE>ea_storage</CODE> from <CODE>ea_list</CODE>, and definitely not 
change it.
+<P>These <CODE>struct ea_storage</CODE> objects are arranged in a hash array
+(array of linked lists) stored in the <CODE>rta_hash</CODE> table. This table
+gets automatically rehashed by <B>ea_rehash()</B> whenever needed.
+<P>The usecounts of <CODE>ea_storage</CODE> must be kept at 1 at all times. 
Whenever
+the usecount reaches zero, it must not be increased again and the 
<CODE>ea_storage</CODE>
+is waiting for free.
+<P>There are two <CODE>ea_hash_array</CODE>s which are used to allow rehashing 
without hard locking.
+These are switched atomically when the rehash is done. Rehash awareness is 
required
+for reasonable lockless lookup and free.
+<P>*********
+Lookup *
+*********
+<P>The lookup function always checks whether it can return an already existing 
structure
+containing the same data. Therefore, after normalizing the attribute set 
contents,
+it calculates a hash value from its whole content, and looks into the hash 
array.
+<P>If an entry is already there, the existing structure is returned, otherwise 
a new
+structure is allocated and put there.
+<P>That would work in one thread though. We need thread-safe operation and 
lockless
+collision resolution. With that, the hash chain pass is done as RCU critical 
section,
+and we can't do time-consuming operations during that. Even though in most 
cases,
+mslab allocation is waitless (threads have pre-allocated objects), we may still
+end up doing a syscall during allocation (mmap), and that's not acceptable.
+Also very large objects (over 1.3k) use mutexes when allocating.
+<P>Therefore, we do multiple passes. In the zeroth pass, we check for en 
existing entry.
+If it is already there, the situation is the easiest, we can just use that,
+and spare the allocation.
+<P>Otherwise, we allocate the entry and run another pass. It may have happened
+that another thread has just done exactly the same, and we may end up
+re-using that entry. In such case, we simply refcount that, and de-allocate
+our version. Otherwise, we put the item into the chain.
+<P>But we may have run into a collision again with somebody putting their item
+into the chain. That is unfortunate, and therefore we try pass 2, with the
+same objective as with pass 1: check for collisions, insert.
+<P>We are not infinitely patient though, and on the pass 3, if we encounter
+a collision again, we stop checking the chain and just insert the entry.
+That may lead to deduplication, and therefore we issue a warning in such case.
+While developing and stress testing, we have never managed to actually trigger 
it.
+<P>Note: There may be situations where we encounter an entry which is about
+to be removed. We ignore these entries.
+<P>************
+Use count *
+************
+<P>The entries are use-counted. That is an easy way to track their lifetimes
+but it brings another catch. What if one thread tries to insert an entry at
+the same time as another thread is deleting it?
+<P>First, we would like to refuse to increase usecounts which are already zero.
+That is not so easy though. The easy approach would be that both lookup
+and free first fetch the count, locally increment/decrement, and then
+they try to atomically exchange it for the previous value.
+<P>Yet, when these collide, the cache gets invalidated over and over again,
+and in our measurements, the allocation times were severely hampered by waiting
+for the usecount update.
+<P>While the allocations are scattered quite randomly all around the time
+in locked contexts of various degrees, free is by default deferred to the
+end of the task, almost always happens in batches, and does not hold
+any additional lock. Therefore, we want to speed up allocations.
+<P>****************************
+Free: Marking for removal *
+****************************
+<P>The whole entry removal ordeal begins with lowering the usecount, and
+if we are lucky, it is still more than one.
+<P>If the usecount becomes zero, the hard time starts. It may have been so
+that the allocator has just found this entry, and raised the usecount again.
+While we could, in the allocator, first read the usecount and then decide,
+it's slow (see above). Instead, the allocator just comes, increments,
+and is done (almost).
+<P>The allocator also can't simply check for zero usecount after the increment.
+While that may be seen by the allocator, another allocating thread may have
+come just after that, seen <CODE>uc == 1</CODE>, and considered the entry 
proper again.
+Or even worse, there may be multiple threads serializing in the most peculiar 
ways.
+<P>Therefore, we need a flag. Whenever the usecount becomes zero, the thread
+subsequently tries to atomically replace that zero by 
<CODE>EA_FREE_FLAG</CODE>,
+which is a very high value reserved for an entry which is about to be
+removed from the chain. Suddenly, either at least one of the allocating
+threads has serialized before this, and therefore the zero replacement
+fails (because the entry has been revived), or they serialize after the
+exchange, and they now see the flag, and can back off.
+<P>As soon as the entry is successfully flagged, it can be safely removed from 
the chain.
+<P>*****************************************
+Free: Actually removing from the chain *
+*****************************************
+<P>Chain removal is not safe when multiple threads are removing at once,
+and there is a well-known race condition between two linked-list deleters,
+mistakenly reviving an item. Therefore we need to avoid multiple deleters
+running in parallel. Also, to delete an item, one has to walk the chain from
+the beginning, to find the ancestor.
+<P>There is a parallel atomic integer array <CODE>delist</CODE>, which has an 
entry
+for every chain in the table. That entry is a hybrid semaphore-spinlock.
+<P>Every deleter increments the appropriate <CODE>delist</CODE> entry when it's
+about to remove an item from a chain. The first one wins the cleanup job,
+starts walking the chain and removing items. All other deleters find out
+that the cleaner is running right now, and they just let go.
+<P>The removal is just pointer manipulation, and it does not collide with
+allocation, with the exception of the very first entry in the list,
+where it may cause an additional lookup pass.
+<P>When the cleaner is done with removing one item, it decrements the
+<CODE>delist</CODE> entry but it continues with removing more entries until the
+entry is zero again. This loop could, theoretically, be infinite, but
+considering the workload characteristics, it's very improbable.
+<P>There could be also a race condition where another cleaner marks an entry
+for deletion, and the cleaner removes that from the chain before the
+<CODE>delist</CODE> counter could get incremented. However, that means that
+there was another deletion pending, and the cleaner just picked the new one.
+<P>If the cleaner ends before all finished entries are removed from the chain,
+it must have been caused by some other threads not yet incrementing the
+<CODE>delist</CODE> counter, and one of them will inevitably become the new 
cleaner,
+keeping the balance.
+<P>********************************
+Free: Deallocating the memory *
+********************************
+<P>We must not immediately return the memory block to the mslab, that would be
+a gross negligence punishable by segfault. Even though the entry has been 
removed
+from the list, there may still be an allocator thread holding a pointer to 
that,
+sleeping just before checking the usecount (where it would find out that it is
+indeed bad and ultimately retry).
+<P>We could simply call <B>synchronize_rcu()</B> to actively wait until all 
these sleeping
+threads get flushed but that adds a lot of overhead when freeing hundreds of 
thousands
+of routes at once. Instead, we collect these items into a defer call structure,
+storing the current RCU phase with them, and only after all the chain removals
+are done, the deferred call waits for RCU synchronization once for all removed 
entries.
+<P>Then, and only then, are the entries returned to the mslab.
+<P>************
+Rehashing *
+************
+<P>Hold on a minute. The hash array is not constantly sized, and it must grow 
with
+the amount of actually stored entries. Therefore, all the operations keep track
+of the number of items inside the whole structure, and whenever the total 
amount
+gets over or under certain threshold, the hash array grows or shrinks.
+<P>The rehash does not lock. Instead, it double-uses the already existing 
mechanisms
+to avoid collisions. The only locking mechanism it uses, is the fixation of 
this
+task into the main thread, making it impossible to collide two rehashes at 
once.
+<P>First, it allocates all the new structures aside, and initializes them. 
Most notably,
+it initializes all the new <CODE>delist</CODE> entries to 1. The fully
+initialized <CODE>ea_hash_array</CODE> is then atomically released, with RCU 
synchronization
+to flush all previous readers before actually starting the rehash procedure.
+<P>Lookups always check both arrays whenever rehash is running, and they always
+add entries to the new one. And free is even easier -- if freeing from
+a not-yet-rehashed chain, it sees <CODE>delist</CODE> initialized to 1, and 
backs off.
+The rehash routine then simply drops all obsolete entries when rehashing.
+<P>
+<P><HR><H3>Function</H3>
 <P><I>ea_list *</I>
 <B>ea_lookup_slow</B>
-(<I>ea_list *</I> <B>o</B>, <I>u32</I> <B>squash_upto</B>, <I>enum 
ea_stored</I> <B>oid</B>) --     look up a <I>rta</I> in attribute cache
+(<I>ea_list *</I> <B>o</B>, <I>u32</I> <B>squash_upto</B>, <I>enum 
ea_stored</I> <B>oid</B>) --     find and reference the given ea_list
+<P>
+<H3>Arguments</H3>
+<P>
+<DL>
+<DT><I>ea_list *</I> <B>o</B><DD><P>list to insert
+<DT><I>u32</I> <B>squash_upto</B><DD><P>storage levels to stop where squashing 
(bitmask)
+<DT><I>enum ea_stored</I> <B>oid</B><DD><P>the storage level of this ea_list
+</DL>
+<H3>Description</H3>
+<P>Expects a locally-allocated ea_list, possibly with multiple layers,
+possibly atop another already cached ea_list. Performs normalization,
+squashing and cache lookup.
+<P>Returns a globally-available ea_list object with a use count already 
incremented.
+The caller must subsequently explicitly call <B>ea_free()</B> to unreference 
the object.
+
+
+<HR><H3>Function</H3>
+<P><I>void</I>
+<B>ea_free_deferred</B>
+(<I>struct deferred_call *</I> <B>dc</B>) --     defer callback to process 
unreferencing of ea_storage
 <P>
 <H3>Arguments</H3>
 <P>
 <DL>
-<DT><I>ea_list *</I> <B>o</B><DD><P>a un-cached <I>rta</I>
-<DT><I>u32</I> <B>squash_upto</B><DD><P>-- undescribed --
-<DT><I>enum ea_stored</I> <B>oid</B><DD><P>-- undescribed --
+<DT><I>struct deferred_call *</I> <B>dc</B><DD><P>the deferred call
 </DL>
 <H3>Description</H3>
-<P><B>rta_lookup()</B> gets an un-cached <I>rta</I> structure and returns its 
cached
-counterpart. It starts with examining the attribute cache to see whether
-there exists a matching entry. If such an entry exists, it's returned and
-its use count is incremented, else a new entry is created with use count
-set to 1.
-<P>The extended attribute lists attached to the <I>rta</I> are automatically
-converted to the normalized form.
+<P>This callback is scheduled by <B>ea_free()</B> and <B>ea_free_later()</B>, 
to use-uncount
+one <CODE>ea_storage</CODE>. The callback runs as a deferred call to ensure 
that
+the user may actually get an easy reference with task-local lifetime.
 
 
 <HR><H3>Function</H3>
@@ -1114,7 +1343,7 @@
 user (which <B>rta_free()</B> tests by inspecting the use count).
 
 <P>
-<H2><A NAME="routing-protocols"></A> <A NAME="ss2.4">2.4</A> <A 
HREF="prog.html#toc2.4">Routing protocols</A>
+<H2><A NAME="routing-protocols"></A> <A NAME="ss2.5">2.5</A> <A 
HREF="prog.html#toc2.5">Routing protocols</A>
 </H2>
 
 <H3><A NAME="routing-protocols-introduction"></A> Introduction</H3>
@@ -1343,7 +1572,7 @@
 protocol is shut down and a new instance is started with the new
 configuration after the shutdown is completed.
 
-<H2><A NAME="graceful-restart-recovery"></A> <A NAME="ss2.5">2.5</A> <A 
HREF="prog.html#toc2.5">Graceful restart recovery</A>
+<H2><A NAME="graceful-restart-recovery"></A> <A NAME="ss2.6">2.6</A> <A 
HREF="prog.html#toc2.6">Graceful restart recovery</A>
 </H2>
 
 <P>
@@ -1537,7 +1766,7 @@
 and might execute start callback of protocol; therefore,
 it should be used at tail positions of protocol callbacks.
 
-<H2><A NAME="protocol-hooks"></A> <A NAME="ss2.6">2.6</A> <A 
HREF="prog.html#toc2.6">Protocol hooks</A>
+<H2><A NAME="protocol-hooks"></A> <A NAME="ss2.7">2.7</A> <A 
HREF="prog.html#toc2.7">Protocol hooks</A>
 </H2>
 
 <P>
@@ -1942,7 +2171,7 @@
 is removed from a routing table.
 <P>Please avoid using this function in new protocols.
 
-<H2><A NAME="interfaces"></A> <A NAME="ss2.7">2.7</A> <A 
HREF="prog.html#toc2.7">Interfaces</A>
+<H2><A NAME="interfaces"></A> <A NAME="ss2.8">2.8</A> <A 
HREF="prog.html#toc2.8">Interfaces</A>
 </H2>
 
 <P>
@@ -2143,7 +2372,7 @@
 <P>This function is called during BIRD startup to initialize
 all data structures of the interface module.
 
-<H2><A NAME="mpls"></A> <A NAME="ss2.8">2.8</A> <A 
HREF="prog.html#toc2.8">MPLS</A>
+<H2><A NAME="mpls"></A> <A NAME="ss2.9">2.9</A> <A 
HREF="prog.html#toc2.9">MPLS</A>
 </H2>
 
 <P>
@@ -2208,7 +2437,7 @@
 - special handling of reserved labels
 <P>
 <P>
-<H2><A NAME="neighbor-cache"></A> <A NAME="ss2.9">2.9</A> <A 
HREF="prog.html#toc2.9">Neighbor cache</A>
+<H2><A NAME="neighbor-cache"></A> <A NAME="ss2.10">2.10</A> <A 
HREF="prog.html#toc2.10">Neighbor cache</A>
 </H2>
 
 <P>
@@ -2387,7 +2616,7 @@
 <P>This function is called during BIRD startup to initialize
 the neighbor cache module.
 
-<H2><A NAME="command-line-interface"></A> <A NAME="ss2.10">2.10</A> <A 
HREF="prog.html#toc2.10">Command line interface</A>
+<H2><A NAME="command-line-interface"></A> <A NAME="ss2.11">2.11</A> <A 
HREF="prog.html#toc2.11">Command line interface</A>
 </H2>
 
 <P>
@@ -2472,7 +2701,7 @@
 <P>This function is called during BIRD startup to initialize
 the internal data structures of the CLI module.
 
-<H2><A NAME="object-locks"></A> <A NAME="ss2.11">2.11</A> <A 
HREF="prog.html#toc2.11">Object locks</A>
+<H2><A NAME="object-locks"></A> <A NAME="ss2.12">2.12</A> <A 
HREF="prog.html#toc2.12">Object locks</A>
 </H2>
 
 <P>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/prog-5.html 
new/bird-doc-3.3.1/doc/prog-5.html
--- old/bird-doc-3.2.1/doc/prog-5.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/prog-5.html  2026-06-09 11:02:33.000000000 +0200
@@ -495,10 +495,12 @@
 RFC 5668 - 4-Octet AS Specific BGP Extended Community
 RFC 5925 - TCP Authentication Option
 RFC 6286 - AS-Wide Unique BGP Identifier
+RFC 6514 - BGP PMSI Tunnel Attribute
 RFC 6608 - Subcodes for BGP Finite State Machine Error
 RFC 6793 - BGP Support for 4-Octet AS Numbers
 RFC 7311 - Accumulated IGP Metric Attribute for BGP
 RFC 7313 - Enhanced Route Refresh Capability for BGP
+RFC 7432 - BGP MPLS-Based Ethernet VPN
 RFC 7606 - Revised Error Handling for BGP UPDATE Messages
 RFC 7911 - Advertisement of Multiple Paths in BGP
 RFC 7947 - Internet Exchange BGP Route Server
@@ -517,9 +519,9 @@
 draft-walton-bgp-hostname-capability-02
 <P>
 <P><HR><H3>Function</H3>
-<P><I>int</I>
-<B>bgp_open</B>
-(<I>struct bgp_proto *</I> <B>p</B>) --     open a BGP instance
+<P><I>struct bgp_listen_request *</I>
+<B>bgp_default_listen_request</B>
+(<I>struct bgp_proto *</I> <B>p</B>) --     prepare BGP's default listen 
request based on configuration
 <P>
 <H3>Arguments</H3>
 <P>
@@ -527,24 +529,23 @@
 <DT><I>struct bgp_proto *</I> <B>p</B><DD><P>BGP instance
 </DL>
 <H3>Description</H3>
-<P>This function allocates and configures shared BGP resources, mainly 
listening
-sockets. Should be called as the last step during initialization (when lock
-is acquired and neighbor is ready). When error, caller should change state to
-PS_DOWN and return immediately.
+<P>This function prepares and returns the default listen request so that the 
protocol
+can register it and later start listening on it.
 
 
 <HR><H3>Function</H3>
-<P><I>void</I>
-<B>bgp_close</B>
-(<I>struct bgp_proto *</I> <B>p</B>) --     close a BGP instance
+<P><I>int</I>
+<B>bgp_listen_start</B>
+(<I>const struct bgp_proto *</I> <B>p</B>, <I>const struct bgp_listen_request 
*</I> <B>req</B>) --     nudge the possibly dormant listen request to actually 
start listening
 <P>
 <H3>Arguments</H3>
 <P>
 <DL>
-<DT><I>struct bgp_proto *</I> <B>p</B><DD><P>BGP instance
+<DT><I>const struct bgp_proto *</I> <B>p</B><DD><P>BGP instance
+<DT><I>const struct bgp_listen_request *</I> <B>req</B><DD><P>the request to 
start
 </DL>
 <H3>Description</H3>
-<P>This function frees and deconfigures shared BGP resources.
+<P>Returns zero on success, -1 on failure.
 
 
 <HR><H3>Function</H3>
@@ -757,8 +758,8 @@
 
 <HR><H3>Function</H3>
 <P><I>struct bgp_listen_request *</I>
-<B>bgp_find_proto</B>
-(<I>struct bgp_socket_private *</I> <B>bs</B>, <I>sock *</I> <B>sk</B>) --     
find existing proto for incoming connection
+<B>bgp_find_listen</B>
+(<I>struct bgp_socket_private *</I> <B>bs</B>, <I>sock *</I> <B>sk</B>) --     
find existing listening request for incoming connection
 <P>
 <H3>Arguments</H3>
 <P>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/prog-8.html 
new/bird-doc-3.3.1/doc/prog-8.html
--- old/bird-doc-3.2.1/doc/prog-8.html  2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/prog-8.html  2026-06-09 11:02:33.000000000 +0200
@@ -130,13 +130,13 @@
 <HR><H3>Function</H3>
 <P><I>void *</I>
 <B>ralloc</B>
-(<I>pool *</I> <B>p</B>, <I>struct resclass *</I> <B>c</B>) --     create a 
resource
+(<I>pool *</I> <B>p</B>, <I>const struct resclass *</I> <B>c</B>) --     
create a resource
 <P>
 <H3>Arguments</H3>
 <P>
 <DL>
 <DT><I>pool *</I> <B>p</B><DD><P>pool to create the resource in
-<DT><I>struct resclass *</I> <B>c</B><DD><P>class of the new resource
+<DT><I>const struct resclass *</I> <B>c</B><DD><P>class of the new resource
 </DL>
 <H3>Description</H3>
 <P>This function is called by the resource classes to create a new
@@ -405,6 +405,24 @@
 <P>Example: Nodes of a FIB are allocated from a per-FIB Slab.
 <P>
 <P><HR><H3>Function</H3>
+<P><I>uint</I>
+<B>sl_obj_count</B>
+(<I>const uint</I> <B>total_size</B>, <I>const uint</I> <B>fixed_overhead</B>, 
<I>const uint</I> <B>obj_size</B>, <I>const uint</I> <B>bits</B>) --     
calculate how many items fit into a memory block
+<P>
+<H3>Arguments</H3>
+<P>
+<DL>
+<DT><I>const uint</I> <B>total_size</B><DD><P>total size of the available 
memory block, e.g. page size
+<DT><I>const uint</I> <B>fixed_overhead</B><DD><P>fixed size of a header 
structure
+<DT><I>const uint</I> <B>obj_size</B><DD><P>size of blocks to fit
+<DT><I>const uint</I> <B>bits</B><DD><P>bits to allocate per fitted block
+</DL>
+<H3>Description</H3>
+<P>Returns the amount of items which fit into the memory block, when packed
+together with the header structure and bitfields.
+
+
+<HR><H3>Function</H3>
 <P><I>slab *</I>
 <B>sl_new</B>
 (<I>pool *</I> <B>p</B>, <I>uint</I> <B>size</B>) --     create a new Slab
@@ -553,7 +571,32 @@
 <H3>Description</H3>
 <P>This function calls <B>ev_run()</B> for all events enqueued in the list 
<B>l</B>.
 
-<H2><A NAME="sockets"></A> <A NAME="ss8.7">8.7</A> <A 
HREF="prog.html#toc8.7">Sockets</A>
+<H2><A NAME="publish/subscribe-queues"></A> <A NAME="ss8.7">8.7</A> <A 
HREF="prog.html#toc8.7">Publish/Subscribe Queues</A>
+</H2>
+
+<P>
+<P>BIRD implements a publish/subscribe messaging system with dynamic topic
+management and resource tracking. The system allows multiple publishers to
+send messages to named topics, which are then distributed to all subscribers
+of those topics.
+<P>The system is built around four main components: queues, topics, publishers,
+and subscribers. A <I>ps_queue</I> serves as the central coordination point,
+maintaining list of topics. Topics are created dynamically when first
+referenced and can have multiple publishers and subscribers attached.
+<P>Publishers and subscribers are implemented as managed resources. Each
+publisher or subscriber can be attached to only one topic. When publishers or
+subscribers are destroyed, they automatically detach from their associated
+topics.
+<P>The <B>ps_init_queue()</B> function initializes a new message queue with a 
given
+name and memory pool. Topics are created on-demand through 
<B>ps_get_topic()</B>.
+Publishers attach to topics using <B>ps_attach()</B> and can send messages via
+<B>ps_publish()</B>, which sends notification to all subscribers. Subscribers 
use
+<B>ps_subscribe()</B> to register for topic updates. When a subscriber joins
+a topic with attached publishers, these publishers are notified of the new
+subscription through their subscribe hooks.
+<P>
+<P>
+<H2><A NAME="sockets"></A> <A NAME="ss8.8">8.8</A> <A 
HREF="prog.html#toc8.8">Sockets</A>
 </H2>
 
 <P>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bird-doc-3.2.1/doc/prog.html 
new/bird-doc-3.3.1/doc/prog.html
--- old/bird-doc-3.2.1/doc/prog.html    2026-04-01 20:02:46.000000000 +0200
+++ new/bird-doc-3.3.1/doc/prog.html    2026-06-09 11:02:33.000000000 +0200
@@ -37,14 +37,15 @@
 <LI><A NAME="toc2.1">2.1</A> <A HREF="prog-2.html#ss2.1">Forwarding 
Information Base</A>
 <LI><A NAME="toc2.2">2.2</A> <A HREF="prog-2.html#ss2.2">Routing tables</A>
 <LI><A NAME="toc2.3">2.3</A> <A HREF="prog-2.html#ss2.3">Route attribute 
cache</A>
-<LI><A NAME="toc2.4">2.4</A> <A HREF="prog-2.html#ss2.4">Routing protocols</A>
-<LI><A NAME="toc2.5">2.5</A> <A HREF="prog-2.html#ss2.5">Graceful restart 
recovery</A>
-<LI><A NAME="toc2.6">2.6</A> <A HREF="prog-2.html#ss2.6">Protocol hooks</A>
-<LI><A NAME="toc2.7">2.7</A> <A HREF="prog-2.html#ss2.7">Interfaces</A>
-<LI><A NAME="toc2.8">2.8</A> <A HREF="prog-2.html#ss2.8">MPLS</A>
-<LI><A NAME="toc2.9">2.9</A> <A HREF="prog-2.html#ss2.9">Neighbor cache</A>
-<LI><A NAME="toc2.10">2.10</A> <A HREF="prog-2.html#ss2.10">Command line 
interface</A>
-<LI><A NAME="toc2.11">2.11</A> <A HREF="prog-2.html#ss2.11">Object locks</A>
+<LI><A NAME="toc2.4">2.4</A> <A HREF="prog-2.html#ss2.4">Route attribute 
storage</A>
+<LI><A NAME="toc2.5">2.5</A> <A HREF="prog-2.html#ss2.5">Routing protocols</A>
+<LI><A NAME="toc2.6">2.6</A> <A HREF="prog-2.html#ss2.6">Graceful restart 
recovery</A>
+<LI><A NAME="toc2.7">2.7</A> <A HREF="prog-2.html#ss2.7">Protocol hooks</A>
+<LI><A NAME="toc2.8">2.8</A> <A HREF="prog-2.html#ss2.8">Interfaces</A>
+<LI><A NAME="toc2.9">2.9</A> <A HREF="prog-2.html#ss2.9">MPLS</A>
+<LI><A NAME="toc2.10">2.10</A> <A HREF="prog-2.html#ss2.10">Neighbor cache</A>
+<LI><A NAME="toc2.11">2.11</A> <A HREF="prog-2.html#ss2.11">Command line 
interface</A>
+<LI><A NAME="toc2.12">2.12</A> <A HREF="prog-2.html#ss2.12">Object locks</A>
 </UL>
 <P>
 <H2><A NAME="toc3">3.</A> <A HREF="prog-3.html">Configuration</A></H2>
@@ -105,7 +106,8 @@
 <LI><A NAME="toc8.4">8.4</A> <A HREF="prog-8.html#ss8.4">Linear memory 
pools</A>
 <LI><A NAME="toc8.5">8.5</A> <A HREF="prog-8.html#ss8.5">Slabs</A>
 <LI><A NAME="toc8.6">8.6</A> <A HREF="prog-8.html#ss8.6">Events</A>
-<LI><A NAME="toc8.7">8.7</A> <A HREF="prog-8.html#ss8.7">Sockets</A>
+<LI><A NAME="toc8.7">8.7</A> <A HREF="prog-8.html#ss8.7">Publish/Subscribe 
Queues</A>
+<LI><A NAME="toc8.8">8.8</A> <A HREF="prog-8.html#ss8.8">Sockets</A>
 </UL>
 <HR>
 <A HREF="prog-1.html">Next</A>
Binary files old/bird-doc-3.2.1/doc/prog.pdf and 
new/bird-doc-3.3.1/doc/prog.pdf differ

Reply via email to