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 [<name>] { + route distinguisher <rd>; + rd <rd>; + import target <ec> | <ec-set> + export target <ec> | <ec-set> + route target <ec> | <ec-set> + vni <number>; + vid <number>; + tag <number>; + encapsulation vxlan { + tunnel device "<name>"; + router address <ip>; + }; + vlan <number> { + range <number>; + vni <number>; + vid <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><[email protected]></I>, Martin Mares <I><[email protected]></I>, Maria Matejka <I><[email protected]></I>, -Ondrej Zajicek <I><[email protected]></I></H2>Wed, 1 Apr 2026 20:02:46 +0200bird-userdoc +Ondrej Zajicek <I><[email protected]></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
