As part of the upstream master commit (f3575f61c7 bgpd: Sort the
bgp_path_inf) the snippet of the code for dmed check condition
left out, which leads to an issue of selecting incorrect bestpath.
As an example:
During the bestpath selection local route looses to another path due
to dmed condition being hit.
The snippet of the logs:
2025/02/20 03:06:20.131441 BGP: [JW7VP-K1YVV]
[2]:[0]:[48]:[00:92:00:00:00:10](VRF default): Comparing path
27.0.0.7 flags Valid with path Static announcement flags Selected Valid Attr Changed Unsorted
2025/02/20 03:06:20.131445 BGP: [SYTDR-QV6X9] [2]:[0]:[48]:[00:92:00:00:00:10]: path 27.0.0.7 loses to path Static announcement as ES 03:44:38:39:ff:ff:02:00:00:01 is same and local
2025/02/20 03:06:20.131452 BGP: [JW7VP-K1YVV] [2]:[0]:[48]:[00:92:00:00:00:10](VRF default): Comparing path 27.0.0.8 flags Valid with path Static announcement flags Selected Valid Attr Changed Unsorted
2025/02/20 03:06:20.131456 BGP: [SYTDR-QV6X9] [2]:[0]:[48]:[00:92:00:00:00:10]: path 27.0.0.8 loses to path Static announcement as ES 03:44:38:39:ff:ff:02:00:00:01 is same and local
2025/02/20 03:06:20.131458 BGP: [WEWEC-8SE72] [2]:[0]:[48]:[00:92:00:00:00:10](VRF default): path Static announcement is the bestpath from AS 0 <<<< static is best
2025/02/20 03:06:20.131463 BGP: [Z3A78-GM3G5] bgp_best_selection: [2]:[0]:[48]:[00:92:00:00:00:10](VRF default) pi 27.0.0.7 dmed
2025/02/20 03:06:20.131467 BGP: [Z3A78-GM3G5] bgp_best_selection: [2]:[0]:[48]:[00:92:00:00:00:10](VRF default) pi 27.0.0.8 dmed
2025/02/20 03:06:20.131471 BGP: [N6CTF-2RSKS] [2]:[0]:[48]:[00:92:00:00:00:10](VRF default): After path selection, newbest is path 27.0.0.7 oldbest was Static announce
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
In bgp_show_table_rd(), the is_last argument is determined using the
expression "next == NULL" to check if the RD table is the last one. This
helps ensure proper JSON formatting.
However, if next is not NULL but is no longer associated with a BGP
table, the JSON output becomes malformed.
Updates the condition to also verify the existence of the next bgp_dest
table.
Fixes: 1ae44dfcba ("bgpd: unify 'show bgp' with RD with normal unicast bgp show")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Even if we have unnumbered peering, let's respect `no neighbor X capability link-local`
and disable it per-neighbor on demand.
Fixes: db853cc97e ("bgpd: Implement Link-Local Next Hop capability")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Memory is being leaked when processing the eoiu marker.
BGP is creating a dummy dest to contain the data but
it was never freed. As well as the eoiu info was
not being freed either.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
When you have suppress-fib-pending turned on it is possible
to end up in a situation where the prefix is not withdrawn
from downstream peers.
Here is the timing that I believe is happening:
a) have 2 paths to a peer.
b) receive a withdrawal from 1 path, set BGP_NODE_FIB_INSTALL_PENDING
and send the route install to zebra.
c) receive a withdrawal from the other path.
d) At this point we have a dest->flags set BGP_NODE_FIB_INSTALL_PENDING
old_select the path_info going away, new_select is NULL
e) A bit further down we call group_announce_route() which calls
the code to see if we should advertise the path. It sees the
BGP_NODE_FIB_INSTALL_PENDING flag and says, nope.
f) the route is sent to zebra to withdraw, which unsets the
BGP_NODE_FIB_INSTALL_PENDING.
g) This function winds up and deletes the path_info. Dest now
has no path infos.
h) BGP receives the route install(from step b) and unsets the
BGP_NODE_FIB_INSTALL_PENDING flag
i) BGP receives the route removed from zebra (from step f) and
unsets the flag again.
We know if there is no new_select, let's go ahead and just
unset the PENDING flag to allow the withdrawal to go out
at the time when the second withdrawal is received.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
The json output of advertised-routes is incorrect, as there is a missing
brace with route-distinguisher:
observed with the bgp_vpnv4_noretain test:
> "bgpTableVersion":0,"bgpLocalRouterId":"192.0.2.1","defaultLocPrf":100,"localAS":65500,
> "advertisedRoutes": "192.0.2.1:1":{"rd":"192.0.2.1:1","10.101.0.0/24":{"prefix":"10.101.0.0/24",
expected:
> "bgpTableVersion":0,"bgpLocalRouterId":"192.0.2.1","defaultLocPrf":100,"localAS":65500,
> "advertisedRoutes": { "192.0.2.1:1":{"rd":"192.0.2.1:1","10.101.0.0/24":{"prefix":"10.101.0.0/24",
> ^
> missing brace
Fix this by adding the missing braces.
Fixes: 4838bac033 ("bgpd: neighbors received-routes/advertised-routes stringify changes")
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
When aggregate is used, the suppressed information is not displayed in
the json attributes of a given path. To illustrate, the dump of the
192.168.2.1/32 path in the bgp_aggregate_address_topo1 topotest:
> # show bgp ipv4
> [..]
> s> 192.168.2.1/32 10.0.0.2 0 65001 i
>
> # show bgp ipv4 detail
> [..]
> BGP routing table entry for 192.168.2.1/32, version 17
> Paths: (1 available, best #1, table default, vrf (null), Advertisements suppressed by an aggregate.)
> Not advertised to any peer
> 65001 <---- missing suppressed flag
> 10.0.0.2 from 10.0.0.2 (10.254.254.3)
> Origin IGP, valid, external, best (First path received)
> Last update: Fri Jan 24 13:11:41 2025
>
> # show bgp ipv4 detail json
> [..]
> ,"192.168.2.1/32": [{"aspath":{"string":"65001","segments":[{"type":"as-sequence","list":[65001]}],"length":1},"origin":"IGP","valid":true,"version":17,
> "bestpath":{"overall":true,"selectionReason":"First path received"}, <---- missing suppressed flag
> "lastUpdate":{"epoch":1737720700,"string":"Fri Jan 24 13:11:40 2025\n"},
> "nexthops":[{"ip":"10.0.0.2","afi":"ipv4","metric":0,"accessible":true,"used":true}],
> "peer":{"peerId":"10.0.0.2","routerId":"10.254.254.3","type":"external"}}]
Fix this by adding the json information.
> # show bgp ipv4 detail
> [..]
> BGP routing table entry for 192.168.2.1/32, version 17
> Paths: (1 available, best #1, table default, vrf (null), Advertisements suppressed by an aggregate.)
> Not advertised to any peer
> 65001, (suppressed)
> 10.0.0.2 from 10.0.0.2 (10.254.254.3)
> Origin IGP, valid, external, best (First path received)
> Last update: Fri Jan 24 13:11:41 2025
>
> # show bgp ipv4 detail json
> [..]
> ,"192.168.2.1/32": [{"aspath":{"string":"65001","segments":[{"type":"as-sequence","list":[65001]}],"length":1},"suppressed":true,"origin":"IGP","valid":true,"version":17,
> "bestpath":{"overall":true,"selectionReason":"First path received"},
> "lastUpdate":{"epoch":1737720991,"string":"Fri Jan 24 13:16:31 2025"},
> "nexthops":[{"ip":"10.0.0.2","afi":"ipv4","metric":0,"accessible":true,"used":true}],"peer":{"peerId":"10.0.0.2","routerId":"10.254.254.3","type":"external"}}]
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
EVPN imported routes AF is not AF_EVPN, in that case
the path info extra with EVPN is nver created.
In order to create evpn info under path extra, define
new api which does not specifically check for AF_EVPN
afi type.
Signed-off-by: Chirag Shah <chirag@nvidia.com>
draft-uttaro-idr-bgp-oad says:
Extended communities which are non-transitive across an AS boundary MAY be
advertised over an EBGP-OAD session if allowed by explicit policy configuration.
If allowed, all the members of the OAD SHOULD be configured to use the same
criteria.
For example, the Origin Validation State Extended Community, defined as
non-transitive in [RFC8097], can be advertised to peers in the same OAD.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Some bgp evpn memory contexts are not freed at the end of the bgp
process.
> =================================================================
> ==1208677==ERROR: LeakSanitizer: detected memory leaks
>
> Direct leak of 96 byte(s) in 2 object(s) allocated from:
> #0 0x7f93ad4b4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
> #1 0x7f93ace77233 in qcalloc lib/memory.c:106
> #2 0x563bb68f4df1 in process_type5_route bgpd/bgp_evpn.c:5084
> #3 0x563bb68fb663 in bgp_nlri_parse_evpn bgpd/bgp_evpn.c:6302
> #4 0x563bb69ea2a9 in bgp_nlri_parse bgpd/bgp_packet.c:347
> #5 0x563bb69f7716 in bgp_update_receive bgpd/bgp_packet.c:2482
> #6 0x563bb6a04d3b in bgp_process_packet bgpd/bgp_packet.c:4091
> #7 0x7f93acf8082d in event_call lib/event.c:1996
> #8 0x7f93ace48931 in frr_run lib/libfrr.c:1232
> #9 0x563bb6880ae1 in main bgpd/bgp_main.c:557
> #10 0x7f93ac829d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
Actually, the bgp evpn context may noy be used if adj rib in is unused.
This may lead to memory leaks. Fix this by freeing the context in those
corner cases.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
The 'show bgp ipv[4,6] json' command does not display the interface
value of the nexthop, when BGP sessions are unnumbered, whereas the
non json output displays it correctly. The below example indicates
'r1-eth0' wheras in json, the value is not displayed.
> r1# show bgp ipv4
> BGP table version is 3, local router ID is 10.254.254.1, vrf id 0
> Default local pref 100, local AS 101
> Status codes: s suppressed, d damped, h history, u unsorted, * valid, > best, = multipath,
> i internal, r RIB-failure, S Stale, R Removed
> Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
> Origin codes: i - IGP, e - EGP, ? - incomplete
> RPKI validation codes: V valid, I invalid, N Not found
>
> Network Next Hop Metric LocPrf Weight Path
> *> 10.254.254.1/32 0.0.0.0 0 32768 ?
> *> 10.254.254.2/32 r1-eth0 0 0 102 ?
>
> Displayed 2 routes and 2 total paths
Fix this by adding an 'interface' keyword in the json attributes.
> "nexthops":[{"ip":"2001:db8:1::2","hostname":"r2","afi":"ipv6",
> "scope":"global"},{"interface":"r1-eth0","ip":"fe80::1868:d7ff:fe66:45ae",
> "hostname":"r2","afi":"ipv6","scope":"link-local","used":true}]}]
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Sometimes it's very useful to compare pointers from the gdb (and/or from the
logs) or just do some quick adhoc analysis.
```
donatas# sh ip bgp 1.1.1.0/24 internal
BGP routing table entry for 1.1.1.0/24, version 0
Paths: (1 available, no best path)
Not advertised to any peer
65002
127.0.0.1 (inaccessible, import-check enabled) from 127.0.0.1 (127.0.0.2)
Origin IGP, invalid, external
Last update: Thu Jan 16 16:49:53 2025
net: 0x63f3e6fc2ea0, path: 0x63f3e6fc2f50, pathext: 0x63f3e6faed00, attr: 0x63f3e6e8c550
flags net: 0x0, path: 0x1024, attr: 0x7
donatas#
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Related: https://datatracker.ietf.org/doc/html/draft-white-linklocal-capability
TL;DR; use 16 bytes long next-hops for point-to-point (unnumbered) links instead
of sending 32 bytes (::/LL, GUA/LL, LL/LL combinations).
For backward compatiblity we should handle even 32 bytes existing next hops.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Route aggregation should be checked after a route is added, and
not before. This is for code flow and consistency.
Signed-off-by: Enke Chen <enchen@paloaltonetworks.com>
Currently when an aggregate-address is configured, the existing
entry is always removed regardless whether any change is involved.
This would create unnecessary churn of the aggregate route when
the same config is applied for the aggregate address.
The fix is to check for duplicate aggregate-address config.
Signed-off-by: Enke Chen <enchen@paloaltonetworks.com>
su_local and su_remote in the peer can change based upon
if we are initiating the remote connection or receiving it.
As such we need to treat it as a property of the connection.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Currently when re-evaluating an aggregate route, the full attribute of
the aggregate route is not compared with the existing one in the BGP
table. That can result in unnecessary churns (un-install and then
install) of the aggregate route when a more specific route is added or
deleted, or when the route-map for the aggregate changes. The churn
would impact route installation and route advertisement.
The fix is to apply the route-map for the aggregate first and then
compare the attribute.
Here is an example of the churn:
debug bgp aggregate prefix 5.5.5.0/24
!
route-map set-comm permit 10
set community 65004:200
!
router bgp 65001
address-family ipv4 unicast
redistribute static
aggregate-address 5.5.5.0/24 route-map set-comm
!
Step 1:
ip route 5.5.5.1/32 Null0
Jan 8 10:28:49 enke-vm1 bgpd[285786]: [J7PXJ-A7YA2] bgp_aggregate_install: aggregate 5.5.5.0/24, count 1
Jan 8 10:28:49 enke-vm1 bgpd[285786]: [Y444T-HEVNG] aggregate 5.5.5.0/24: installed
Step 2:
ip route 5.5.5.2/32 Null0
Jan 8 10:29:03 enke-vm1 bgpd[285786]: [J7PXJ-A7YA2] bgp_aggregate_install: aggregate 5.5.5.0/24, count 2
Jan 8 10:29:03 enke-vm1 bgpd[285786]: [S2EH5-EQSX6] aggregate 5.5.5.0/24: existing, removed
Jan 8 10:29:03 enke-vm1 bgpd[285786]: [Y444T-HEVNG] aggregate 5.5.5.0/24: installed
---
Signed-off-by: Enke Chen <enchen@paloaltonetworks.com>
If the peer which has allowas-in enabled and then reimports the routes to another
local VRF, respect that value.
This was working with < 10.2 releases.
Fixes: d4426b62d2 ("bgpd: copy source vrf ASN to leaked route and block loops")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This reverts commit ee1986f1b5.
The fix is incomplete, and is no longer needed with the fix that applies
the route-map for an aggregate and then compares the attribute.
Signed-off-by: Enke Chen <enchen@paloaltonetworks.com>
When stopping and restarting BGP daemon part of the configuration
remains. It should be cleared.
Particulary those are address-family parametes, like: distance,
ead-es-frag, disable-ead-evi-rx, disable-ead-evi-tx.
Signed-off-by: Yaroslav Kholod <y.kholod@vyos.io>
The rpki current state was ignored when calling for the 'show bgp ipvX
detail' command. Handle the support for this, with json support too.
> "rpkiValidationState" : "valid",
> "rpkiValidationState" : "invalid",
> "rpkiValidationState" : "not used",
> "rpkiValidationState" : "not found",
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Signed-off-by: Dmytro Shytyi <dmytro.shytyi@6wind.com>