Commit Graph

35009 Commits

Author SHA1 Message Date
Igor Ryzhov
11fad42e6f
Merge pull request #15596 from FRRouting/mergify/bp/dev/10.0/pr-15587
grpc: fix grpc for various failures (backport #15587)
2024-03-22 15:37:55 +02:00
Tomi Salminen
aa4e1f5032 zebra: Fix crash on macvlan link down/up
Whenever a link up change was detected on a macvlan device where
the linked device wasn't visible in the namespace zebra was
running in, the linked zebra interface was NULL. This was already
handled in the event of a link down, but was ommitted from the
upside. Added the same null check to the up-side.

Signed-off-by: Tomi Salminen <tlsalmin@gmail.com>
(cherry picked from commit bdf6a9ba81)
2024-03-22 13:01:47 +00:00
Christian Hopps
c371aef0f9 grpc: fix grpc for various failures
lib: don't define a `fallthrough` in c++ to avoid conflict with protobuf c++

check: add link libs required by some versions of grpc++ or it's dependent
linked libs

tests: don't fail the test due to known at exit memleaks
Signed-off-by: Christian Hopps <chopps@labn.net>
(cherry picked from commit 043a4183c2)
2024-03-22 07:21:23 +00:00
Russ White
2cf90b1dd2
Merge pull request #15576 from FRRouting/mergify/bp/dev/10.0/pr-15558
bgpd: Update default-originate route-map actual map structure (backport #15558)
2024-03-19 14:43:55 -04:00
Donatas Abraitis
51443f665a bgpd: Update default-originate route-map actual map structure
If using with `bgp listen range ... peer-group x`, default_rmap[afi][safi] is not
updated, and after the hard-reset in other side, this is flushed and never updated
again without restarting the sender BGP daemon.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 4f1e2dcd7a)
2024-03-19 14:26:55 +00:00
Russ White
be0b8686fa
Merge pull request #15521 from opensourcerouting/fix/backport_1818186432569d2bc3e4113945ff958c3ac4796b_10.0
bgpd: [10.0] Unset advertised capabilities if capability is disabled
2024-03-19 10:10:59 -04:00
Mark Stapp
2437d09b0d
Merge pull request #15569 from FRRouting/mergify/bp/dev/10.0/pr-15424
zebra: fix route deletion during zebra shutdown (backport #15424)
2024-03-18 13:06:18 -04:00
Alexander Skorichenko
e5e564a421 zebra: fix route deletion during zebra shutdown
Split zebra's vrf_terminate() into disable() and delete() stages.
The former enqueues all events for the dplane thread.
Memory freeing is performed in the second stage.

Signed-off-by: Alexander Skorichenko <askorichenko@netgate.com>
(cherry picked from commit 444ce317b2)
2024-03-18 11:45:05 +00:00
Donatas Abraitis
a0153fff18
Merge pull request #15547 from FRRouting/mergify/bp/dev/10.0/pr-15466
Bgp filter fun (backport #15466)
2024-03-15 07:29:06 +02:00
Donatas Abraitis
a509d69922
Merge pull request #15544 from FRRouting/mergify/bp/dev/10.0/pr-15532
bgpd: Check the route and the nexthop appropriately when validating NH (backport #15532)
2024-03-14 12:40:49 +02:00
Donald Sharp
44bc76db55 bgpd: Ensure community data is freed in some cases.
Customer has this valgrind trace:

Direct leak of 2829120 byte(s) in 70728 object(s) allocated from:
  0 in community_new ../bgpd/bgp_community.c:39
  1 in community_uniq_sort ../bgpd/bgp_community.c:170
  2 in route_set_community ../bgpd/bgp_routemap.c:2342
  3 in route_map_apply_ext ../lib/routemap.c:2673
  4 in subgroup_announce_check ../bgpd/bgp_route.c:2367
  5 in subgroup_process_announce_selected ../bgpd/bgp_route.c:2914
  6 in group_announce_route_walkcb ../bgpd/bgp_updgrp_adv.c:199
  7 in hash_walk ../lib/hash.c:285
  8 in update_group_af_walk ../bgpd/bgp_updgrp.c:2061
  9 in group_announce_route ../bgpd/bgp_updgrp_adv.c:1059
 10 in bgp_process_main_one ../bgpd/bgp_route.c:3221
 11 in bgp_process_wq ../bgpd/bgp_route.c:3221
 12 in work_queue_run ../lib/workqueue.c:282

The above leak detected by valgrind was from a screenshot so I copied it
by hand.  Any mistakes in line numbers are purely from my transcription.
Additionally this is against a slightly modified 8.5.1 version of FRR.
Code inspection of 8.5.1 -vs- latest master shows the same problem
exists.  Code should be able to be followed from there to here.

What is happening:

There is a route-map being applied that modifes the outgoing community
to a peer.  This is saved in the attr copy created in
subgroup_process_announce_selected.  This community pointer is not
interned.  So the community->refcount is still 0.  Normally when
a prefix is announced, the attr and the prefix are placed on a
adjency out structure where the attribute is interned.  This will
cause the community to be saved in the community hash list as well.
In a non-normal operation when the decision to send is aborted after
the route-map application, the attribute is just dropped and the
pointer to the community is just dropped too, leading to situations
where the memory is leaked.  The usage of bgp suppress-fib would
would be a case where the community is caused to be leaked.
Additionally the previous commit where an unsuppress-map is used
to modify the outgoing attribute but since unsuppress-map was
not considered part of outgoing policy the attribute would be dropped as
well.  This pointer drop also extends to any dynamically allocated
memory saved by the attribute pointer that was not interned yet as well.

So let's modify the return case where the decision is made to
not send the prefix to the peer to always just flush the attribute
to ensure memory is not leaked.

Fixes: #15459
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit addff17a55)
2024-03-14 08:26:15 +00:00
Donald Sharp
990c98d270 bgpd: Include unsuppress-map as a valid outgoing policy
If unsuppress-map is setup for outgoing peers, consider that
policy is being applied as for RFC 8212.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit 6814401c47)
2024-03-14 08:26:15 +00:00
Donald Sharp
3103af698b bgpd: Ensure that the correct aspath is free'd
Currently in subgroup_default_originate the attr.aspath
is set in bgp_attr_default_set, which hashs the aspath
and creates a refcount for it.  If this is a withdraw
the subgroup_announce_check and bgp_adj_out_set_subgroup
is called which will intern the attribute.  This will
cause the the attr.aspath to be set to a new value
finally at the bottom of the function it intentionally
uninterns the aspath which is not the one that was
created for this function.  This reduces the other
aspath's refcount by 1 and if a clear bgp * is issued
fast enough the aspath for that will be removed
and the system will crash.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit e613e12f12)
2024-03-14 08:26:15 +00:00
Donatas Abraitis
77f05ac096 bgpd: Check the route and the nexthop appropriately when validating NH
A route and its nexthop might belong to different VRFs. Therefore, we need
both the bgp and bgp_nexthop pointers.

Fixes: 8d51fafdcb ("bgpd: Drop bgp_static_update_safi() function")

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 778357e9ef)
2024-03-13 21:45:12 +00:00
Donatas Abraitis
21d6498ad0
Merge pull request #15528 from FRRouting/mergify/bp/dev/10.0/pr-15457
docker: Fix build for Alpine Linux after the recent changes since 9.1 (backport #15457)
2024-03-13 09:36:58 +02:00
Donatas Abraitis
99db263be5 lib: Drop include/linux/mroute[6].h
Not needed anymore since a5389154a1.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit a201559a4a)
2024-03-12 20:34:30 +00:00
Donatas Abraitis
e57b9042f7 docker: Fix post function for Alpine build (package)
It was using a wrong sysdir.

```
--------------------
  72 |     # Own the config / PID files
  73 |     RUN mkdir -p /var/run/frr
  74 | >>> RUN chown -R frr:frr /etc/frr /var/run/frr
  75 |
  76 |     # Simple init manager for reaping processes and forwarding signals
--------------------
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit b0b0d7ab08)
2024-03-12 20:34:30 +00:00
Donatas Abraitis
6d1bf1ef3d docker: Do not use pip Python package manager
Alpine Linux gets this with 3.19:

This is already installed with `pytest` via apk package manager.

```
15 78.20 error: externally-managed-environment
15 78.20
15 78.20 × This environment is externally managed
15 78.20 ╰─>
15 78.20     The system-wide python installation should be maintained using the system
15 78.20     package manager (apk) only.
15 78.20
15 78.20     If the package in question is not packaged already (and hence installable via
15 78.20     "apk add py3-somepackage"), please consider installing it inside a virtual
15 78.20     environment, e.g.:
15 78.20
15 78.20     python3 -m venv /path/to/venv
15 78.20     . /path/to/venv/bin/activate
15 78.20     pip install mypackage
15 78.20
15 78.20     To exit the virtual environment, run:
15 78.20
15 78.20     deactivate
15 78.20
15 78.20     The virtual environment is not deleted, and can be re-entered by re-sourcing
15 78.20     the activate file.
15 78.20
15 78.20     To automatically manage virtual environments, consider using pipx (from the
15 78.20     pipx package).
15 78.20
15 78.20 note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 3f7cc3b7f5)
2024-03-12 20:34:30 +00:00
Donatas Abraitis
d538c71383 docker: Use Alpine Linux version 3.19
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit fd93b7d89a)
2024-03-12 20:34:30 +00:00
Donatas Abraitis
99f99dfaa3 vtysh: Include fnctl.h for vtysh_main
Fixing compilation for Alpine Linux:

```
25 91.59 vtysh/vtysh_main.c: In function 'vtysh_flock_config':
25 91.59 vtysh/vtysh_main.c:276:20: warning: implicit declaration of function 'open'; did you mean 'popen'? [-Wimplicit-function-declaration]
25 91.59   276 |         flock_fd = open(flock_file, O_RDONLY, 0644);
25 91.59       |                    ^~~~
25 91.59       |                    popen
25 91.60 vtysh/vtysh_main.c:276:37: error: 'O_RDONLY' undeclared (first use in this function)
25 91.60   276 |         flock_fd = open(flock_file, O_RDONLY, 0644);
25 91.60       |                                     ^~~~~~~~
25 91.60 vtysh/vtysh_main.c:276:37: note: each undeclared identifier is reported only once for each function it appears in
25 91.60   CC       zebra/if_netlink.o
25 91.61 vtysh/vtysh_main.c: In function 'main':
25 91.61 vtysh/vtysh_main.c:637:49: error: 'O_CREAT' undeclared (first use in this function)
25 91.61   637 |                         fp = open(history_file, O_CREAT | O_EXCL,
25 91.61       |                                                 ^~~~~~~
25 91.62 vtysh/vtysh_main.c:637:59: error: 'O_EXCL' undeclared (first use in this function)
25 91.62   637 |                         fp = open(history_file, O_CREAT | O_EXCL,
25 91.62       |                                                           ^~~~~~
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit e9ff59401c)
2024-03-12 20:34:30 +00:00
Donatas Abraitis
59d117c344 lib: Fix unknown sig_atomic_t compile error
This is happening for Alpine Linux.

```
26 64.59 ./lib/sigevent.h:23:18: error: unknown type name 'sig_atomic_t'
26 64.59    23 |         volatile sig_atomic_t caught; /* private member   */
26 64.59       |                  ^~~~~~~~~~~~
26 64.60 In file included from ./lib/libfrr.h:12,
26 64.60                  from ./lib/vty.h:28,
26 64.60                  from ./lib/command.h:11,
26 64.60                  from ./lib/debug.h:11,
26 64.60                  from ./mgmtd/mgmt.h:12,
26 64.60                  from mgmtd/mgmt_history.c:14:
26 64.60 ./lib/sigevent.h:23:18: error: unknown type name 'sig_atomic_t'
26 64.60    23 |         volatile sig_atomic_t caught; /* private member   */
26 64.60       |                  ^~~~~~~~~~~~
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit f03b0bfaa4)
2024-03-12 20:34:30 +00:00
Donatas Abraitis
378e8d0845 docker: Use libyang 2.1.128 for Alpine builds
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 3ca01bf1e9)
2024-03-12 20:34:30 +00:00
Igor Ryzhov
a0e5996d60
Merge pull request #15529 from FRRouting/mergify/bp/dev/10.0/pr-15509
pimd: Cleanup inclusion of headers (backport #15509)
2024-03-12 21:44:05 +02:00
Donald Sharp
c1551644d6 pimd: Cleanup inclusion of headers
FRR needs to properly include the FreeBSD headers for
compilation on FreeBSD.  I have setup v6 as well
but I have not even tested it.  Since I know
that the form is the same I think this is ok
at the moment.  This is a step forward.

Because of this change *clearly* no-one is even
using pim on FreeBSD.  <look at the MRT_XXX values
to prove to yourself>.  In any event this is a step
in the direction of getting that working again.

Signed-off-by: Donald Sharp <sharpd@freebsd.network>
(cherry picked from commit a5389154a1)
2024-03-12 15:12:06 +00:00
Donatas Abraitis
abc238d65f
Merge pull request #15519 from FRRouting/mergify/bp/dev/10.0/pr-15513
bgpd: Fix `no` form for `neighbor X capability software-version` (backport #15513)
2024-03-12 12:13:52 +01:00
Donatas Abraitis
6d31b866e7 bgpd: Allow dynamically disable graceful-restart/long-lived graceful-restart
If we enter `bgp graceful-restart-disable`, make sure we disable the capabilities.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 78757362f2)
2024-03-12 09:47:46 +02:00
Donatas Abraitis
66f05651d4 bgpd: Unset advertised capabilities if capability is disabled
When using dynamic capabilities, do not forget to unset advertised capabilities.

Otherwise, it's kept as advertised.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 77102e853e)
2024-03-12 09:47:36 +02:00
Donatas Abraitis
5776a6040b tests: Check if capabilities can be disabled via dynamic capabilities
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit fd613d1b0c)
2024-03-11 17:25:34 +02:00
Donatas Abraitis
baf24d2fec bgpd: Fix no form for neighbor X capability software-version
If `bgp default software-version-capability` is enabled, allow unsetting this
for a single neighbor also.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 2038fad33e)
2024-03-11 11:18:42 +00:00
Donatas Abraitis
e4885819f5
Merge pull request #15512 from FRRouting/mergify/bp/dev/10.0/pr-15510
fix rip/ripng yang rpcs (backport #15510)
2024-03-09 20:54:00 +01:00
Igor Ryzhov
142124ed3c ripngd: fix "clear ipv6 ripng" command
mgmtd doesn't support YANG RPCs yet, so this command must go directly to
ripngd.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit c544b9e8e7)
2024-03-09 10:16:38 +00:00
Igor Ryzhov
cd8ced1dbf ripd: fix "clear ip rip" command
mgmtd doesn't support YANG RPCs yet, so this command must go directly to
ripd.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit 1ba97510e2)
2024-03-09 10:16:38 +00:00
Igor Ryzhov
2cab993239
Merge pull request #15508 from FRRouting/mergify/bp/dev/10.0/pr-15497
a couple of fixes for "show running-config" (backport #15497)
2024-03-09 00:07:11 +02:00
Igor Ryzhov
8824368726 ripngd: fix missing "exit" for "router ripng"
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit 1db1fbf7a6)
2024-03-08 13:12:50 +00:00
Igor Ryzhov
0cd3555cb8 ripd: fix missing "exit" for "router rip"
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit aaa6c7088e)
2024-03-08 13:12:49 +00:00
Igor Ryzhov
7b60258be5 lib: fix order of interfaces in the config
Add missing cli_cmp callback. Without it, interfaces are not sorted and
printed in order they were created.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit 18da736949)
2024-03-08 13:12:49 +00:00
Igor Ryzhov
68eb06de45
Merge pull request #15503 from FRRouting/mergify/bp/dev/10.0/pr-15498
mgmtd: change error message (backport #15498)
2024-03-07 18:08:01 +02:00
Igor Ryzhov
8caf17cdc4 mgmtd: change error message
Make the wording clearer about what's going on.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit bbaf34b117)
2024-03-07 07:26:36 +00:00
Donatas Abraitis
0f81bdcbeb
Merge pull request #15495 from FRRouting/mergify/bp/dev/10.0/pr-15487
lib: fix apply_finish callback in northbound (backport #15487)
2024-03-06 13:22:28 +02:00
Donatas Abraitis
cbfb7b219a
Merge pull request #15491 from FRRouting/mergify/bp/dev/10.0/pr-15222
bgpd:aggr summary-only remove suppressed from evpn (backport #15222)
2024-03-06 13:22:11 +02:00
Igor Ryzhov
0f2a785789 lib: fix apply_finish callback in northbound
When a node is top-level, we shouldn't stop the whole processing, we
should just skip this single node.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit 8287fbe453)
2024-03-06 06:44:47 +00:00
Chirag Shah
af2b6fbd4c tests:add topotest for EVPN aggregate prefix route
Toptotest covers to aggregate EVPN prefix routes.

Testing:

tests/topotests/bgp_evpn_vxlan_svd_topo1$ sudo -E python3 -m pytest -s -vv --cli-on-error
PASSED
test_bgp_evpn_vxlan_svd.py::test_pe_advertise_aggr_evpn_route
--------------------- live log call -------------------------------
2024-03-04 19:59:45,340 INFO: P1: checking if daemons are running
2024-03-04 19:59:45,444 INFO: PE1: checking if daemons are running
2024-03-04 19:59:45,578 INFO: PE2: checking if daemons are running
2024-03-04 19:59:45,680 INFO: host1: checking if daemons are running
2024-03-04 19:59:45,798 INFO: host2: checking if daemons are running
2024-03-04 19:59:45,896 INFO: topo: Checking BGP EVPN route contains non-aggregate prefixes
2024-03-04 19:59:45,992 INFO: topo: Configure BGP aggregate-address summary-only under ipv4-unicast
2024-03-04 19:59:46,120 INFO: topo: Checking BGP EVPN route contains aggregated prefix
PASSED

------- generated xml file: /tmp/topotests/topotests.xml -----
======= 10 passed, 1 skipped in 47.95s =====

Signed-off-by: Chirag Shah <chirag@nvidia.com>
(cherry picked from commit f345460b7e)
2024-03-05 20:43:14 +00:00
Chirag Shah
a3afaffffb bgpd:aggr summary-only remove suppressed from evpn
Ticket: #3534718 #3720960
Testing Done:

Config:
router bgp 65564 vrf sym_2
 bgp router-id 27.0.0.9
 !
 address-family ipv4 unicast
  redistribute static
 exit-address-family

vrf sym_2
 vni 8889
 ip route 63.2.1.0/24 blackhole
 ip route 63.2.1.2/32 blackhole
 ip route 63.2.1.3/32 blackhole
exit-vrf

tor-1:# vtysh -c "show bgp l2vpn evpn route" | grep -A3 63.2
*> [5]:[0]:[24]:[63.2.1.0] RD 27.0.0.9:19
                    27.0.0.9 (tor-1)
                                             0         32768 ?
                    ET:8 RT:28:8889 Rmac:44:38:39:ff:ff:29
--
*> [5]:[0]:[32]:[63.2.1.2] RD 27.0.0.9:19
                    27.0.0.9 (tor-1)
                                             0         32768 ?
                    ET:8 RT:28:8889 Rmac:44:38:39:ff:ff:29
*> [5]:[0]:[32]:[63.2.1.3] RD 27.0.0.9:19
                    27.0.0.9 (tor-1)
                                             0         32768 ?
                    ET:8 RT:28:8889 Rmac:44:38:39:ff:ff:29

tor-1(config)# router bgp 65564 vrf sym_2
tor-1(config-router)# address-family ipv4 unicast
tor-1(config-router-af)# aggregate-address 63.2.0.0/16 summary-only
tor-1(config-rou-f)# end

tor-1:# vtysh -c "show bgp l2vpn evpn route" | grep -A3 63.2.1
tor-1:# vtysh -c "show bgp l2vpn evpn route" | grep -A3 63.2
*> [5]:[0]:[16]:[63.2.0.0] RD 27.0.0.9:19
                    27.0.0.9 (tor-1)
                                             0         32768 ?
                    ET:8 RT:28:8889 Rmac:44:38:39:ff:ff:29

Signed-off-by: Chirag Shah <chirag@nvidia.com>
(cherry picked from commit 5cb7712b3e)
2024-03-05 20:43:14 +00:00
Donatas Abraitis
e7965eacc5
Merge pull request #15484 from FRRouting/mergify/bp/dev/10.0/pr-15479
doc: Fix one spelling `dissallowed` to `disallowed` (backport #15479)
2024-03-05 17:37:55 +02:00
Donatas Abraitis
0c62fc6824 doc: Fix one spelling dissallowed to disallowed
Closes: https://github.com/FRRouting/frr/issues/15465

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit e993ba1812)
2024-03-05 13:50:15 +00:00
Igor Ryzhov
5e27a213d8
Merge pull request #15478 from FRRouting/mergify/bp/dev/10.0/pr-15470
lib: fix __darr_in_vsprintf (backport #15470)
2024-03-05 11:23:37 +02:00
Igor Ryzhov
f23f58a6a4 lib: fix infinite loop in __darr_in_vsprintf
`darr_avail` returns the available capacity excluding the already
existing terminating NULL byte. Take this into account when using
`darr_avail`. Otherwise, if the error length is a power of 2, the
capacity is never enough and the function stucks in an infinite loop.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit cb6032d6b3)
2024-03-05 03:45:38 +00:00
Igor Ryzhov
e5da17897c lib: fix __darr_in_vsprintf
If the initial darr capacity is not enough for the output, the `ap` is
reused multiple times, which is wrong, because it may be altered by
`vsnprintf`. Make a copy of `ap` each time instead of reusing.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit ee0c1cc1e4)
2024-03-05 03:45:38 +00:00
Donatas Abraitis
a976189dd2
Merge pull request #15463 from FRRouting/mergify/bp/dev/10.0/pr-15461
fix warning if ripngd disabled (backport #15461)
2024-03-02 08:13:23 +02:00
Vincent JARDIN
db88f3dc82 mgmtd: fix warning if ripngd disabled
./configure [...] --disable-ripngd

could lead to:

mgmtd/mgmt_vty.c:614:5: warning: "HAVE_RIPNGD" is not defined, evaluates to 0 [-Wundef]
  614 | #if HAVE_RIPNGD
      |     ^~~~~~~~~~~

Signed-off-by: Vincent Jardin <vjardin@free.fr>
(cherry picked from commit 717b3350bb)
2024-03-01 21:13:04 +00:00