Philippe Guibert [Tue, 18 Jun 2024 15:40:08 +0000 (17:40 +0200)]
sharpd: fix set ZAPI_MESSAGE_NEXTHOP in nhg only when nexthops used
The ZAPI_MESSAGE_NEXTHOP flag is systematically set, even if the
route message does not include any nexthops. Limit the usage of this
value only when nexthops are present.
Fixes: 8a71d93d85a6 ("sharpd: Add Super Happy Advanced Routing Protocol") Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd: Move sticky, default_gw, router_flag into a single flags variable
Instead of using 3 uint8_t variables under struct attr, let's use a single
uint8_t as the flags. Saving 2-bytes. Not a big deal, but it's even easier to
track EVPN-related flags/variables.
vivek [Wed, 26 Jun 2024 22:49:45 +0000 (15:49 -0700)]
*: Add and use option for graceful (re)start
Add a new start option "-K" to libfrr to denote a graceful start,
and use it in zebra and bgpd.
zebra will use this option to denote a planned FRR graceful restart
(supporting only bgpd currently) to wait for a route sync completion
from bgpd before cleaning up old stale routes from the FIB. An optional
timer provides an upper-bounds for this cleanup.
bgpd will use this option to denote either a planned FRR graceful
restart or a bgpd-only graceful restart, and this will drive the BGP
GR restarting router procedures.
vivek [Mon, 26 Oct 2020 00:05:48 +0000 (17:05 -0700)]
bgpd: Refine restarter operation - R-bit & F-bit
Introduce BGP-wide flags to denote if BGP has started gracefully
and GR is in progress or not. Use this for setting of the R-bit in
the GR capability, and not a timer which is set for any new
instance creation. Mark graceful restart is complete when the
deferred path selection has been done and route sync with zebra as
well as deferred EOR advertisement has been initiated.
Introduce a function to check on F-bit setting rather than just
base it on configuration.
Subsequent commits will extend these functionalities.
Quentin Young [Fri, 29 Sep 2023 00:11:31 +0000 (20:11 -0400)]
doc: add ability to disambiguate clicmds
Multiple daemons have the same CLI commands defined, but the current
directive used to document CLI commands only takes the command
definition string. Since CLI command objects can be cross-referenced
using the :clicmd: directive, and are placed in the index, each object
needs to be unique.
To accomplish this, add a custom directive. This directive extends the
directive class used by sphinx's add_object_type to add a :daemon:
option. By specifying this option where needed, the object name becomes
"(<daemon>) <definition>", disambiguating it.
Signed-off-by: Quentin Young <qlyoung@qlyoung.net>
vivek [Sun, 25 Oct 2020 18:31:42 +0000 (11:31 -0700)]
bgpd: Streamline GR config, act on change immediately
Streamline the BGP graceful-restart configuration at the global and
peer level some more. Similar to many other neighbor capability
parameters like MP and ENHE, reset the session immediately upon a
change to the configuration. This will be more aligned with the
transactional UI model also and will not require a separate 'clear'
command to be executed.
Note: Peer-group graceful-restart configuration is not yet supported.
vivek [Sat, 24 Oct 2020 21:38:58 +0000 (14:38 -0700)]
bgpd: Implement BGP-wide configuration for graceful restart
Add support for a BGP-wide setting for graceful restart modes and
parameters. This setting will apply to all BGP peers across all BGP
instances, but per-neighbor configuration can override it.
Per-instance configuration is disallowed if the BGP-wide setting
is in effect.
zhou-run [Thu, 27 Jun 2024 03:51:02 +0000 (11:51 +0800)]
isisd: fix crash when obtaining the next hop to calculate LFA on LAN links
When a neighbor connection is disconnected, it may trigger LSP re-generation as a timer task, but this process may be delayed. As a result, the list of neighbors in area->adjacency_list may be inconsistent with the neighbors in lsp->tlvs->oldstyle_reach/extended_reach. For example, the area->adjacency_list may lack certain neighbors even though they are present in the LSP. When computing SPF, the call to isis_spf_build_adj_list() generates the spftree->sadj_list, which reflects the real neighbors in the area->adjacency_list. However, in the case of LAN links, spftree->sadj_list may include additional pseudo neighbors.
The pre-loading of tents through the call to isis_spf_preload_tent involves two steps:
1. isis_spf_process_lsp() is called to generate real neighbor vertices based on the root LSP and pseudo LSP.
2. isis_spf_add_local() is called to add corresponding next hops to the vertex->Adj_N list for the real neighbor vertices.
In the case of LAN links, the absence of corresponding real neighbors in the spftree->sadj_list prevents the execution of the second step. Consequently, the vertex->Adj_N list for the real neighbor vertices lacks corresponding next hops. This leads to a null pointer access when isis_lfa_compute() is called to calculate LFA.
As for P2P links, since there are no pseudo neighbors, only the second step is executed, which does not create real neighbor vertices and therefore does not encounter this issue.
The backtrace is as follows:
(gdb) bt
#0 0x00007fd065277fe1 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007fd065398972 in core_handler (signo=11, siginfo=0x7ffc5c0636b0, context=0x7ffc5c063580) at ../lib/sigevent.c:261
#2 <signal handler called>
#3 0x00005564d82f8408 in isis_lfa_compute (area=0x5564d8b143f0, circuit=0x5564d8b21d10, spftree=0x5564d8b06bf0, resource=0x7ffc5c064410) at ../isisd/isis_lfa.c:2134
#4 0x00005564d82f8d78 in isis_spf_run_lfa (area=0x5564d8b143f0, spftree=0x5564d8b06bf0) at ../isisd/isis_lfa.c:2344
#5 0x00005564d8315964 in isis_run_spf_with_protection (area=0x5564d8b143f0, spftree=0x5564d8b06bf0) at ../isisd/isis_spf.c:1827
#6 0x00005564d8315c15 in isis_run_spf_cb (thread=0x7ffc5c064590) at ../isisd/isis_spf.c:1889
#7 0x00007fd0653b1f04 in thread_call (thread=0x7ffc5c064590) at ../lib/thread.c:1990
#8 0x00007fd06534a97b in frr_run (master=0x5564d88103c0) at ../lib/libfrr.c:1198
#9 0x00005564d82e7d5d in main (argc=5, argv=0x7ffc5c0647b8, envp=0x7ffc5c0647e8) at ../isisd/isis_main.c:273
(gdb) f 3
#3 0x00005564d82f8408 in isis_lfa_compute (area=0x5564d8b143f0, circuit=0x5564d8b21d10, spftree=0x5564d8b06bf0, resource=0x7ffc5c064410) at ../isisd/isis_lfa.c:2134
2134 ../isisd/isis_lfa.c: No such file or directory.
(gdb) p vadj_primary
$1 = (struct isis_vertex_adj *) 0x0
(gdb) p vertex->Adj_N->head
$2 = (struct listnode *) 0x0
(gdb) p (struct isis_vertex *)spftree->paths->l.list->head->next->next->next->next->data
$8 = (struct isis_vertex *) 0x5564d8b5b240
(gdb) p $8->type
$9 = VTYPE_NONPSEUDO_TE_IS
(gdb) p $8->N.id
$10 = "\000\000\000\000\000\002"
(gdb) p $8->Adj_N->count
$11 = 0
(gdb) p (struct isis_vertex *)spftree->paths->l.list->head->next->next->next->next->next->data
$12 = (struct isis_vertex *) 0x5564d8b73dd0
(gdb) p $12->type
$13 = VTYPE_NONPSEUDO_TE_IS
(gdb) p $12->N.id
$14 = "\000\000\000\000\000\003"
(gdb) p $12->Adj_N->count
$15 = 0
(gdb) p area->adjacency_list->count
$16 = 0
The backtrace provided above pertains to version 8.5.4, but it seems that the same issue exists in the code of the master branch as well.
The scenario where a vertex has no next hop is normal. For example, the "clear isis neighbor" command invokes isis_vertex_adj_del() to delete the next hop of a vertex. Upon reviewing all the instances where the vertex->Adj_N list is used, I found that only isis_lfa_compute() lacks a null check. Therefore, I believe that modifying this part will be sufficient. Additionally, the vertex->parents list for IP vertices is guaranteed not to be empty.
Test scenario:
Setting up LFA for LAN links and executing the "clear isis neighbor" command easily reproduces the issue.
David Lamparter [Wed, 26 Jun 2024 14:13:50 +0000 (16:13 +0200)]
pimd: refactor `pim_rp_set_upstream_addr`
Somehow this tiny function ended up being written in a very convoluted
way that enabled the braces mixup in the previous commit. Rewrite it to
be less confusing.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Loïc Sang [Wed, 19 Jun 2024 14:19:22 +0000 (16:19 +0200)]
bgpd: avoid clearing routes for peers that were never established
Under heavy system load with many peers in passive mode and a large
number of routes, bgpd can enter an infinite loop. This occurs while
processing timeout BGP_OPEN messages, which prevents it from accepting
new connections. The following log entries illustrate the issue:
>bgpd[6151]: [VX6SM-8YE5W][EC 33554460] 3.3.2.224: nexthop_set failed, resetting connection - intf 0x0
>bgpd[6151]: [P790V-THJKS][EC 100663299] bgp_open_receive: bgp_getsockname() failed for peer: 3.3.2.224
>bgpd[6151]: [HTQD2-0R1WR][EC 33554451] bgp_process_packet: BGP OPEN receipt failed for peer: 3.3.2.224
... repeating
The issue occurs when bgpd handles a massive number of routes in the RIB
while receiving numerous BGP_OPEN packets. If bgpd is overloaded, it
fails to process these packets promptly, leading the remote peer to
close the connection and resend BGP_OPEN packets.
When bgpd eventually starts processing these timeout BGP_OPEN packets,
it finds the TCP connection closed by the remote peer, resulting in
"bgp_stop()" being called. For each timeout peer, bgpd must iterate
through the routing table, which is time-consuming and causes new
incoming BGP_OPEN packets to timeout, perpetuating the infinite loop.
To address this issue, the code is modified to check if the peer has
been established at least once before calling "bgp_clear_route_all()".
This ensures that routes are only cleared for peers that had a
successful session, preventing unnecessary iterations over the routing
table for peers that never established a connection.
With this change, BGP_OPEN timeout messages may still occur, but in the
worst case, bgpd will stabilize. Before this patch, bgpd could enter a
loop where it was unable to accpet any new connections.
Quentin Young [Tue, 25 Jun 2024 17:48:33 +0000 (13:48 -0400)]
doc: improve table-of-contents organization
The current TOC organization is not really following Sphinx best
practices and is resulting in a jumble of articles showing up in the
sidebar.
This change primarily organizes existing articles into three major
sections:
* Introduction
- Contains system requirements, architecture & design, installation,
basic setup
* Basics
- Covers basic commands, concepts, and some random things that don't
fit elsewhere
* Protocols
- Contains all protocol documentation, and other miscellaneous daemon
docs such as those on Zebra, watchfrr, mgmtd, etc.
The appendix has been left as is, but the TOC now has a caption which
has the effect of adding a section separator in the nav sidebar.
In order to make the new structure make sense:
* Some content has been lifted up from the "Overview" page into the
index page
* Most content has been pushed down from the "Overview" page into the
"About" page (new)
* BFD's page is now titled "BFD" for consistencty; it was the only one
that had the full protocol name written out in the title
And a couple drivebys:
* BFD's intro description paragraph was rewritten to make more sense
* Old language stating that we publish platform packages on the Github
releases page was removed
* References to source building instructions were consolidated into that
section
Signed-off-by: Quentin Young <qlyoung@qlyoung.net>
Piotr Suchy [Wed, 22 May 2024 08:41:52 +0000 (10:41 +0200)]
bgpd: Ignore routes from evpn if VRF is unknown
Fix for a bug, where FRR fails to install route received for an unknown but later-created VRF - detailed description can be found here https://github.com/FRRouting/frr/issues/13708
Donatas Abraitis [Mon, 24 Jun 2024 17:16:16 +0000 (20:16 +0300)]
bgpd: Relax OAD (One-Administration-Domain) for RFC8212
RFC 8212 defines leak prevention for eBGP peers, but BGP-OAD defines a new
peering type One Administrative Domain (OAD), where multiple ASNs could be used
inside a single administrative domain. OAD allows sending non-transitive attributes,
so this prevention should be relaxed too.
________________________________________________________________________________________________________
*** CID 1594014: Null pointer dereferences (FORWARD_NULL)
/zebra/zebra_srv6.c: 1860 in release_srv6_sid_func_explicit()
1854
1855 /* Lookup SID function in the functions allocated list of EWLIB range */
1856 for (ALL_LIST_ELEMENTS_RO(block->u.usid
1857 .wide_lib[sid_func]
1858 .func_allocated,
1859 node, sid_func_ptr))
CID 1594014: Null pointer dereferences (FORWARD_NULL)
Dereferencing null pointer "sid_wide_func_ptr".
1860 if (*sid_wide_func_ptr == sid_wide_func)
1861 break;
1862
1863 /* Ensure that the SID function is allocated */
1864 if (!sid_wide_func_ptr) {
1865 zlog_warn("%s: failed to release wide SID function %u, function is not allocated",
** CID 1594016: Possible Control flow issues (DEADCODE)
/zebra/zebra_srv6.c: 1871 in release_srv6_sid_func_explicit()
________________________________________________________________________________________________________
*** CID 1594016: Possible Control flow issues (DEADCODE)
/zebra/zebra_srv6.c: 1871 in release_srv6_sid_func_explicit()
1865 zlog_warn("%s: failed to release wide SID function %u, function is not allocated",
1866 __func__, sid_wide_func);
1867 return -1;
1868 }
1869
1870 /* Release the SID function from the EWLIB range */
CID 1594016: Possible Control flow issues (DEADCODE)
Execution cannot reach this statement: "listnode_delete(block->u.us...".
1871 listnode_delete(block->u.usid.wide_lib[sid_func]
1872 .func_allocated,
1873 sid_wide_func_ptr);
1874 zebra_srv6_sid_func_free(sid_wide_func_ptr);
1875 } else {
1876 zlog_warn("%s: function %u is outside ELIB [%u/%u] and EWLIB alloc ranges [%u/%u]",
Louis Scalbert [Fri, 21 Jun 2024 08:59:43 +0000 (10:59 +0200)]
isisd: fix display crash srv6 sid structure in json
Fix a crash when doing "show isis database detail json" in
isis_srv6_topo1 topotest.
> #0 raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:50
> #1 0x00007fad89524e2c in core_handler (signo=6, siginfo=0x7ffe86a4b8b0, context=0x7ffe86a4b780) at lib/sigevent.c:258
> #2 <signal handler called>
> #3 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
> #4 0x00007fad8904e537 in __GI_abort () at abort.c:79
> #5 0x00007fad8904e40f in __assert_fail_base (fmt=0x7fad891c5688 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x7fad8a3e70e8 "json_object_get_type(jso) == json_type_object",
> file=0x7fad8a3e7064 "./json_object.c", line=590, function=<optimized out>) at assert.c:92
> #6 0x00007fad8905d662 in __GI___assert_fail (assertion=0x7fad8a3e70e8 "json_object_get_type(jso) == json_type_object", file=0x7fad8a3e7064 "./json_object.c", line=590,
> function=0x7fad8a3e7440 "json_object_object_add_ex") at assert.c:101
> #7 0x00007fad8a3dfe93 in json_object_object_add_ex () from /lib/x86_64-linux-gnu/libjson-c.so.5
> #8 0x000055708e3f8f7f in format_subsubtlv_srv6_sid_structure (sid_struct=0x602000172b70, buf=0x0, json=0x6040000a21d0, indent=6) at isisd/isis_tlvs.c:2880
> #9 0x000055708e3f9acb in isis_format_subsubtlvs (subsubtlvs=0x602000172b50, buf=0x0, json=0x6040000a21d0, indent=6) at isisd/isis_tlvs.c:3022
> #10 0x000055708e3eefb0 in format_item_ext_subtlvs (exts=0x614000047440, buf=0x0, json=0x6040000a2190, indent=2, mtid=2) at isisd/isis_tlvs.c:1313
> #11 0x000055708e3fd599 in format_item_extended_reach (mtid=2, i=0x60300015aed0, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:3763
> #12 0x000055708e40d46a in format_item (mtid=2, context=ISIS_CONTEXT_LSP, type=ISIS_TLV_MT_REACH, i=0x60300015aed0, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:6789
> #13 0x000055708e40d4fc in format_items_ (mtid=2, context=ISIS_CONTEXT_LSP, type=ISIS_TLV_MT_REACH, items=0x60600021d160, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:6804
> #14 0x000055708e40edbc in format_mt_items (context=ISIS_CONTEXT_LSP, type=ISIS_TLV_MT_REACH, m=0x6180000845d8, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:7147
> #15 0x000055708e4111e9 in format_tlvs (tlvs=0x618000084480, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:7572
> #16 0x000055708e4114ce in isis_format_tlvs (tlvs=0x618000084480, json=0x6040000a1bd0) at isisd/isis_tlvs.c:7613
> #17 0x000055708e36f167 in lsp_print_detail (lsp=0x612000058b40, vty=0x0, json=0x6040000a1bd0, dynhost=1 '\001', isis=0x60d00001f800) at isisd/isis_lsp.c:785
> #18 0x000055708e36f31f in lsp_print_all (vty=0x0, json=0x6040000a0490, head=0x61f000005488, detail=1 '\001', dynhost=1 '\001', isis=0x60d00001f800) at isisd/isis_lsp.c:820
> #19 0x000055708e4379fc in show_isis_database_lspdb_json (json=0x6040000a0450, area=0x61f000005480, level=0, lspdb=0x61f000005488, sysid_str=0x0, ui_level=1) at isisd/isisd.c:2683
> #20 0x000055708e437ef9 in show_isis_database_json (json=0x6040000a0310, sysid_str=0x0, ui_level=1, isis=0x60d00001f800) at isisd/isisd.c:2754
> #21 0x000055708e438357 in show_isis_database_common (vty=0x62e000060400, json=0x6040000a0310, sysid_str=0x0, ui_level=1, isis=0x60d00001f800) at isisd/isisd.c:2788
> #22 0x000055708e438591 in show_isis_database (vty=0x62e000060400, json=0x6040000a0310, sysid_str=0x0, ui_level=1, vrf_name=0x7fad89806300 <vrf_default_name> "default", all_vrf=false)
> at isisd/isisd.c:2825
> #23 0x000055708e43891d in show_database (self=0x55708e5519c0 <show_database_cmd>, vty=0x62e000060400, argc=5, argv=0x6040000a02d0) at isisd/isisd.c:2855
> #24 0x00007fad893a9767 in cmd_execute_command_real (vline=0x60300015f220, vty=0x62e000060400, cmd=0x0, up_level=0) at lib/command.c:1002
> #25 0x00007fad893a9adc in cmd_execute_command (vline=0x60300015f220, vty=0x62e000060400, cmd=0x0, vtysh=0) at lib/command.c:1061
> #26 0x00007fad893aa728 in cmd_execute (vty=0x62e000060400, cmd=0x621000025900 "show isis database detail json ", matched=0x0, vtysh=0) at lib/command.c:1227
Note that prior to 2e670cd779, there was no crash but only the last
"srv6-sid-structure" was displayed. A "srv6-sid-structure" should be
displayed for each "sid". This commit also fix this.
Chirag Shah [Wed, 19 Jun 2024 00:21:49 +0000 (17:21 -0700)]
zebra: fix evpn mh bond member proto reinstall
In case of EVPN MH bond, a member port going in
protodown state due to external reason (one case being linkflap),
frr updates the state correctly but upon manually
clearing external reason trigger FRR to reinstate
protodown without any reason code.
Fix is to ensure if the protodown reason was external
and new state is to have protodown 'off' then do no reinstate
protodown.
Ticket: #3947432
Testing:
switch:#ip link show swp1
4: swp1: <NO-CARRIER,BROADCAST,MULTICAST,SLAVE,UP> mtu 9216 qdisc
pfifo_fast master bond1 state DOWN mode DEFAULT group default qlen
1000
link/ether 1c:34:da:2c:aa:68 brd ff:ff:ff:ff:ff:ff protodown on
protodown_reason <linkflap>
switch:#ip link set swp1 protodown off protodown_reason linkflap off
switch:#ip link show swp1
4: swp1: <NO-CARRIER,BROADCAST,MULTICAST,SLAVE,UP> mtu 9216 qdisc
pfifo_fast master bond1 state DOWN mode DEFAULT group default qlen
1000
link/ether 1c:34:da:2c:aa:68 brd ff:ff:ff:ff:ff:ff
Acee Lindem [Fri, 31 May 2024 14:08:04 +0000 (14:08 +0000)]
ospfd: Improve OSPF neighbor retransmission list granularity and precision
The current OSPF neighbor retransmission operates on a single per-neighbor
periodic timer that sends all LSAs on the list when it expires.
Additionally, since it skips the first retransmission of received LSAs so
that at least the retransmission interval (resulting in a delay of between
the retransmission interval and twice the interval. In environments where
the links are lossy on P2MP networks with "delay-reflood" configured (which
relies on neighbor retransmission in partial meshs), the implementation
is sub-optimal (to say the least).
This commit reimplements OSPF neighbor retransmission as follows:
1. A new data structure making use the application managed
typesafe.h doubly linked list implements an OSPF LSA
list where each node includes a timestamp.
2. The existing neighbor LS retransmission LSDB data structure
is augmented with a pointer to the list node on the LSA
list to faciliate O(1) removal when the LSA is acknowledged.
3. The neighbor LS retransmission timer is set to the expiration
timer of the LSA at the top of the list.
4. When the timer expires, LSAs are retransmitted that within
the window of the current time and a small delta (50 milli-secs
default). The LSAs that are retransmited are given an updated
retransmission time and moved to the end of the LSA list.
5. Configuration is added to set the "retransmission-window" to a
value other than 50 milliseconds.
6. Neighbor and interface LSA retransmission counters are added
to provide insight into the lossiness of the links. However,
these will increment quickly on non-fully meshed P2MP networks
with "delay-reflood" configured.
7. Added a topotest to exercise the implementation on a non-fully
meshed P2MP network with "delay-reflood" configured. The
alternative was to use existing mechanisms to instroduce loss
but these seem less determistic in a topotest.
David Lamparter [Fri, 25 Jun 2021 09:42:38 +0000 (11:42 +0200)]
pimd: prepare NHT for tracking BSM C-RPs
For BSMs, we should track which of the RP candidates in the BSM message
are actually available, before trying to use them (which also puts them
in NHT for that). This applies for both BSRs as well as BSM receivers.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
David Lamparter [Sat, 9 Jul 2022 16:47:43 +0000 (18:47 +0200)]
pimd: allow sending packets without pinned iface
The upcoming Candidate-RP code needs to send PIM packets that go through
normal unicast routing, without forcing a specific output interface.
Allow passing in NULL ifp to do that.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>