* [pve-devel] [PATCH 2/4] frr: port patches to latest stable version, add topotests
2025-03-07 12:29 [pve-devel] [PATCH 1/4] frr: bump from 8.5.2 to 10.2.1 Gabriel Goller
@ 2025-03-07 12:29 ` Gabriel Goller
2025-03-07 12:29 ` [pve-devel] [PATCH 3/4] frr: add the dummy_as_loopback patch series, enable it by default Gabriel Goller
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Gabriel Goller @ 2025-03-07 12:29 UTC (permalink / raw)
To: pve-devel; +Cc: Thomas Lamprecht
These patches enable the bgp daemon per default and implement the
bgp-evpn autort feature. Also add the topotest for the autort feature.
Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
---
...atch => 0001-enable-bgp-bfd-daemons.patch} | 17 +-
...on-for-RT-auto-derivation-to-force-A.patch | 77 ++--
.../0003-tests-add-bgp-evpn-autort-test.patch | 332 ++++++++++++++++++
debian/patches/series | 3 +-
4 files changed, 381 insertions(+), 48 deletions(-)
rename debian/patches/pve/{0001-enable-bgp-daemon.patch => 0001-enable-bgp-bfd-daemons.patch} (52%)
create mode 100644 debian/patches/pve/0003-tests-add-bgp-evpn-autort-test.patch
diff --git a/debian/patches/pve/0001-enable-bgp-daemon.patch b/debian/patches/pve/0001-enable-bgp-bfd-daemons.patch
similarity index 52%
rename from debian/patches/pve/0001-enable-bgp-daemon.patch
rename to debian/patches/pve/0001-enable-bgp-bfd-daemons.patch
index e1c65b3fe3be..5f86ec1b3c77 100644
--- a/debian/patches/pve/0001-enable-bgp-daemon.patch
+++ b/debian/patches/pve/0001-enable-bgp-bfd-daemons.patch
@@ -1,17 +1,18 @@
-From f098e90f4d690e771f63f48e0540a470faa91892 Mon Sep 17 00:00:00 2001
+From e608bc29e66291f7eafb9a9e17b13cc49ae0b726 Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Wed, 25 Nov 2020 12:41:32 +0100
-Subject: [PATCH] enable bgp && bfd daemons
+Subject: [PATCH 1/6] enable bgp && bfd daemons
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
+Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
---
tools/etc/frr/daemons | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
-diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons
-index b1526888e..27bc120a7 100644
---- a/tools/etc/frr/daemons
-+++ b/tools/etc/frr/daemons
+Index: b/tools/etc/frr/daemons
+===================================================================
+--- a/tools/etc/frr/daemons 2025-03-07 11:09:47.197423679 +0100
++++ b/tools/etc/frr/daemons 2025-03-07 11:09:47.194423675 +0100
@@ -14,7 +14,7 @@
#
# The watchfrr, zebra and staticd daemons are always started.
@@ -21,7 +22,7 @@ index b1526888e..27bc120a7 100644
ospfd=no
ospf6d=no
ripd=no
-@@ -27,7 +27,7 @@ eigrpd=no
+@@ -28,7 +28,7 @@
babeld=no
sharpd=no
pbrd=no
@@ -30,6 +31,4 @@ index b1526888e..27bc120a7 100644
fabricd=no
vrrpd=no
pathd=no
---
-2.30.2
diff --git a/debian/patches/pve/0002-bgpd-add-an-option-for-RT-auto-derivation-to-force-A.patch b/debian/patches/pve/0002-bgpd-add-an-option-for-RT-auto-derivation-to-force-A.patch
index 8d1759cef339..436dfc0fde35 100644
--- a/debian/patches/pve/0002-bgpd-add-an-option-for-RT-auto-derivation-to-force-A.patch
+++ b/debian/patches/pve/0002-bgpd-add-an-option-for-RT-auto-derivation-to-force-A.patch
@@ -1,55 +1,59 @@
-From f5658ed4cecb3ad81cb838fb90467930943ab2ef Mon Sep 17 00:00:00 2001
+From dbbe4040299d2a02179cc390d9d7e2aab59833da Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Mon, 22 May 2023 19:31:28 +0200
-Subject: [PATCH] bgpd : add an option for RT auto-derivation to force AS
+Subject: [PATCH 2/6] bgpd : add an option for RT auto-derivation to force AS
Allow to define a custom AS for autort AS:VNI
Usefull for evpn with ebgp, where we can't auto-derivated from the router AS,
as route-target AS:VNI need to be the same on the each peer
+Link: https://github.com/FRRouting/frr/pull/7535
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
+ [ GG: ported to latest stable 10.2.1 ]
+Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
---
- bgpd/bgp_evpn.c | 12 ++++++++++--
- bgpd/bgp_evpn_vty.c | 47 +++++++++++++++++++++++++++++++++------------
+ bgpd/bgp_evpn.c | 13 +++++++++++--
+ bgpd/bgp_evpn_vty.c | 46 +++++++++++++++++++++++++++++++++------------
bgpd/bgpd.h | 3 +++
3 files changed, 48 insertions(+), 14 deletions(-)
-diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
-index 28ea443c6..d44c6bd5d 100644
---- a/bgpd/bgp_evpn.c
-+++ b/bgpd/bgp_evpn.c
-@@ -591,7 +591,11 @@ static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl,
+Index: b/bgpd/bgp_evpn.c
+===================================================================
+--- a/bgpd/bgp_evpn.c 2025-03-07 11:09:47.315423809 +0100
++++ b/bgpd/bgp_evpn.c 2025-03-07 11:09:47.312423806 +0100
+@@ -622,7 +622,12 @@
if (bgp->advertise_autort_rfc8365)
- vni |= EVPN_AUTORT_VXLAN;
-- encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
+ SET_FLAG(vni, EVPN_AUTORT_VXLAN);
+- encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true);
++
+ if (bgp->autort_as) {
-+ encode_route_target_as((bgp->autort_as & 0xFFFF), vni, &eval);
-+ } else {
-+ encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
++ encode_route_target_as((bgp->autort_as & 0xFFFF), vni, &eval, true);
++ }else {
++ encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true);
+ }
ecomadd = ecommunity_new();
ecommunity_add_val(ecomadd, &eval, false, false);
-@@ -5174,7 +5178,11 @@ void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl,
+@@ -5490,7 +5495,11 @@
if (bgp->advertise_autort_rfc8365)
- vni |= EVPN_AUTORT_VXLAN;
+ SET_FLAG(vni, EVPN_AUTORT_VXLAN);
-- encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
+- encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true);
+ if (bgp->autort_as) {
-+ encode_route_target_as((bgp->autort_as & 0xFFFF), vni, &eval);
-+ } else {
-+ encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
++ encode_route_target_as((bgp->autort_as & 0xFFFF), vni, &eval, true);
++ }else {
++ encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true);
+ }
ecom_auto = ecommunity_new();
ecommunity_add_val(ecom_auto, &eval, false, false);
-diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
-index 6b63c6e3a..11012f3b8 100644
---- a/bgpd/bgp_evpn_vty.c
-+++ b/bgpd/bgp_evpn_vty.c
-@@ -3649,32 +3649,52 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
+Index: b/bgpd/bgp_evpn_vty.c
+===================================================================
+--- a/bgpd/bgp_evpn_vty.c 2025-03-07 11:09:47.315423809 +0100
++++ b/bgpd/bgp_evpn_vty.c 2025-03-07 11:09:47.313423807 +0100
+@@ -3744,32 +3744,51 @@
return CMD_SUCCESS;
}
@@ -59,11 +63,11 @@ index 6b63c6e3a..11012f3b8 100644
+DEFPY (bgp_evpn_advertise_autort,
+ bgp_evpn_advertise_autort_cmd,
+ "autort [rfc8365-compatible]$rfc8365 [as (1-65536)$as]",
++ NO_STR
"Auto-derivation of RT\n"
- "Auto-derivation of RT using RFC8365\n")
+ "Auto-derivation of RT using RFC8365\n"
-+ "Auto-derivation AS\n"
-+ "ASN\n")
++ "Auto-derivation AS\n")
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
@@ -92,8 +96,7 @@ index 6b63c6e3a..11012f3b8 100644
"Auto-derivation of RT\n"
- "Auto-derivation of RT using RFC8365\n")
+ "Auto-derivation of RT using RFC8365\n"
-+ "Auto-derivation AS\n"
-+ "ASN\n")
++ "Auto-derivation AS\n")
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
@@ -112,7 +115,7 @@ index 6b63c6e3a..11012f3b8 100644
return CMD_SUCCESS;
}
-@@ -7121,6 +7141,9 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
+@@ -7286,6 +7305,9 @@
if (bgp->advertise_autort_rfc8365)
vty_out(vty, " autort rfc8365-compatible\n");
@@ -122,7 +125,7 @@ index 6b63c6e3a..11012f3b8 100644
if (bgp->advertise_gw_macip)
vty_out(vty, " advertise-default-gw\n");
-@@ -7354,8 +7377,8 @@ void bgp_ethernetvpn_init(void)
+@@ -7528,8 +7550,8 @@
install_element(BGP_EVPN_NODE, &evpnrt5_network_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_all_vni_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_all_vni_cmd);
@@ -133,11 +136,11 @@ index 6b63c6e3a..11012f3b8 100644
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_default_gw_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_svi_ip_cmd);
-diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
-index 72b5b50fb..452062e3d 100644
---- a/bgpd/bgpd.h
-+++ b/bgpd/bgpd.h
-@@ -685,6 +685,9 @@ struct bgp {
+Index: b/bgpd/bgpd.h
+===================================================================
+--- a/bgpd/bgpd.h 2025-03-07 11:09:47.315423809 +0100
++++ b/bgpd/bgpd.h 2025-03-07 11:09:47.313423807 +0100
+@@ -745,6 +745,9 @@
/* EVPN - use RFC 8365 to auto-derive RT */
int advertise_autort_rfc8365;
@@ -147,6 +150,4 @@ index 72b5b50fb..452062e3d 100644
/*
* Flooding mechanism for BUM packets for VxLAN-EVPN.
*/
---
-2.30.2
diff --git a/debian/patches/pve/0003-tests-add-bgp-evpn-autort-test.patch b/debian/patches/pve/0003-tests-add-bgp-evpn-autort-test.patch
new file mode 100644
index 000000000000..4fa8a0a72681
--- /dev/null
+++ b/debian/patches/pve/0003-tests-add-bgp-evpn-autort-test.patch
@@ -0,0 +1,332 @@
+From 641f5b043f8aeb81b66882d6b86d62572e95af1d Mon Sep 17 00:00:00 2001
+From: Alexandre Derumier <aderumier@odiso.com>
+Date: Sat, 21 Nov 2020 01:28:42 +0100
+Subject: [PATCH 3/6] tests: add bgp evpn autort test
+
+Link: https://github.com/FRRouting/frr/pull/7535
+Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
+ [ GG: ported to latest master ]
+Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
+---
+ tests/topotests/bgp_evpn_autort/__init__.py | 0
+ tests/topotests/bgp_evpn_autort/r1/bgpd.conf | 12 +
+ tests/topotests/bgp_evpn_autort/r1/zebra.conf | 6 +
+ tests/topotests/bgp_evpn_autort/r2/bgpd.conf | 12 +
+ tests/topotests/bgp_evpn_autort/r2/zebra.conf | 6 +
+ .../bgp_evpn_autort/test_bgp_evpn_autort.py | 246 ++++++++++++++++++
+ 6 files changed, 282 insertions(+)
+ create mode 100644 tests/topotests/bgp_evpn_autort/__init__.py
+ create mode 100644 tests/topotests/bgp_evpn_autort/r1/bgpd.conf
+ create mode 100644 tests/topotests/bgp_evpn_autort/r1/zebra.conf
+ create mode 100644 tests/topotests/bgp_evpn_autort/r2/bgpd.conf
+ create mode 100644 tests/topotests/bgp_evpn_autort/r2/zebra.conf
+ create mode 100644 tests/topotests/bgp_evpn_autort/test_bgp_evpn_autort.py
+
+Index: b/tests/topotests/bgp_evpn_autort/r1/bgpd.conf
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ b/tests/topotests/bgp_evpn_autort/r1/bgpd.conf 2025-03-07 11:09:47.441423948 +0100
+@@ -0,0 +1,12 @@
++router bgp 65000
++ no bgp ebgp-requires-policy
++ neighbor 192.168.255.2 remote-as 65001
++ address-family ipv4 unicast
++ neighbor 192.168.255.2 activate
++ exit-address-family
++ !
++ address-family l2vpn evpn
++ neighbor 192.168.255.2 activate
++ advertise-all-vni
++ exit-address-family
++!
+Index: b/tests/topotests/bgp_evpn_autort/r1/zebra.conf
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ b/tests/topotests/bgp_evpn_autort/r1/zebra.conf 2025-03-07 11:09:47.441423948 +0100
+@@ -0,0 +1,6 @@
++!
++interface r1-eth0
++ ip address 192.168.255.1/24
++!
++ip forwarding
++!
+Index: b/tests/topotests/bgp_evpn_autort/r2/bgpd.conf
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ b/tests/topotests/bgp_evpn_autort/r2/bgpd.conf 2025-03-07 11:09:47.441423948 +0100
+@@ -0,0 +1,12 @@
++router bgp 65001
++ no bgp ebgp-requires-policy
++ neighbor 192.168.255.1 remote-as 65000
++ address-family ipv4 unicast
++ neighbor 192.168.255.1 activate
++ exit-address-family
++ !
++ address-family l2vpn evpn
++ neighbor 192.168.255.1 activate
++ advertise-all-vni
++ exit-address-family
++!
+Index: b/tests/topotests/bgp_evpn_autort/r2/zebra.conf
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ b/tests/topotests/bgp_evpn_autort/r2/zebra.conf 2025-03-07 11:09:47.441423948 +0100
+@@ -0,0 +1,6 @@
++!
++interface r2-eth0
++ ip address 192.168.255.2/24
++!
++ip forwarding
++!
+Index: b/tests/topotests/bgp_evpn_autort/test_bgp_evpn_autort.py
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ b/tests/topotests/bgp_evpn_autort/test_bgp_evpn_autort.py 2025-03-07 11:09:47.441423948 +0100
+@@ -0,0 +1,246 @@
++#!/usr/bin/env python
++
++#
++# bgp_evpn_autort.py
++# Part of NetDEF Topology Tests
++#
++# Copyright (c) 2019 by
++# Alexandre Derumier <aderumier@odiso.com>
++#
++# Permission to use, copy, modify, and/or distribute this software
++# for any purpose with or without fee is hereby granted, provided
++# that the above copyright notice and this permission notice appear
++# in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
++# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
++# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
++# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
++# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
++# OF THIS SOFTWARE.
++#
++
++"""
++bgp_evpn_autort.py:
++
++"""
++
++import os
++import sys
++import json
++import time
++import pytest
++import functools
++
++CWD = os.path.dirname(os.path.realpath(__file__))
++sys.path.append(os.path.join(CWD, "../"))
++
++# pylint: disable=C0413
++from lib import topotest
++from lib.topogen import Topogen, TopoRouter, get_topogen
++from lib.topolog import logger
++from mininet.topo import Topo
++
++
++def build_topo(tgen):
++ "Build function"
++
++ for routern in range(1, 3):
++ tgen.add_router("r{}".format(routern))
++
++ switch = tgen.add_switch("s1")
++ switch.add_link(tgen.gears["r1"])
++ switch.add_link(tgen.gears["r2"])
++
++
++def setup_module(mod):
++ tgen = Topogen(build_topo, mod.__name__)
++ tgen.start_topology()
++
++ router_list = tgen.routers()
++
++ for i, (rname, router) in enumerate(router_list.items(), 1):
++ router.load_config(
++ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
++ )
++ router.load_config(
++ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
++ )
++
++ tgen.start_router()
++
++ router = tgen.gears["r2"]
++
++ cmds_r2 = [ # config routing 101
++ "ip link add name bridge-101 up type bridge stp_state 0",
++ "ip link set bridge-101 master {}-vrf-101",
++ "ip link set dev bridge-101 up",
++ "ip link add name vxlan-101 type vxlan id 101 dstport 4789 dev r2-eth0 local 192.168.255.2",
++ "ip link set dev vxlan-101 master bridge-101",
++ "ip link set vxlan-101 up type bridge_slave learning off flood off mcast_flood off",
++ ]
++
++ for cmd in cmds_r2:
++ logger.info("cmd to r2: " + cmd.format("r2"))
++ output = router.run(cmd.format("r2"))
++ logger.info("result: " + output)
++
++
++def teardown_module(mod):
++ tgen = get_topogen()
++ tgen.stop_topology()
++
++
++def test_bgp_evpn_autort():
++ tgen = get_topogen()
++
++ if tgen.routers_have_failure():
++ pytest.skip(tgen.errors)
++
++ def _verify_vni_65000(router):
++ output = json.loads(router.vtysh_cmd("sh bgp l2vpn evpn vni 101 json"))
++ expected = {
++ "vni":101,
++ "type":"L2",
++ "inKernel":"True",
++ "rd":"192.168.255.2:2",
++ "originatorIp":"192.168.255.2",
++ "mcastGroup":"0.0.0.0",
++ "advertiseGatewayMacip":"Disabled",
++ "advertiseSviMacIp":"Disabled",
++ "importRts":[
++ "65000:101"
++ ],
++ "exportRts":[
++ "65000:101"
++ ]
++ }
++ return topotest.json_cmp(output, expected)
++
++ def _verify_vni_65001(router):
++ output = json.loads(router.vtysh_cmd("sh bgp l2vpn evpn vni 101 json"))
++ expected = {
++ "vni":101,
++ "type":"L2",
++ "inKernel":"True",
++ "rd":"192.168.255.2:2",
++ "originatorIp":"192.168.255.2",
++ "mcastGroup":"0.0.0.0",
++ "advertiseGatewayMacip":"Disabled",
++ "advertiseSviMacIp":"Disabled",
++ "importRts":[
++ "65001:101"
++ ],
++ "exportRts":[
++ "65001:101"
++ ]
++ }
++ return topotest.json_cmp(output, expected)
++
++ def _verify_vni_65001_rfc8365(router):
++ output = json.loads(router.vtysh_cmd("sh bgp l2vpn evpn vni 101 json"))
++ expected = {
++ "vni":101,
++ "type":"L2",
++ "inKernel":"True",
++ "rd":"192.168.255.2:2",
++ "originatorIp":"192.168.255.2",
++ "mcastGroup":"0.0.0.0",
++ "advertiseGatewayMacip":"Disabled",
++ "advertiseSviMacIp":"Disabled",
++ "importRts":[
++ "65001:268435557"
++ ],
++ "exportRts":[
++ "65001:268435557"
++ ]
++ }
++ return topotest.json_cmp(output, expected)
++
++ def _remove_autort_as(router):
++ router.vtysh_cmd(
++ """
++ configure terminal
++ router bgp 65001
++ address-family l2vpn evpn
++ no autort as 65000
++ """
++ )
++
++ def _add_autort_as(router):
++ router.vtysh_cmd(
++ """
++ configure terminal
++ router bgp 65001
++ address-family l2vpn evpn
++ autort as 65000
++ """
++ )
++
++ def _add_autort_rfc8365(router):
++ router.vtysh_cmd(
++ """
++ configure terminal
++ router bgp 65001
++ address-family l2vpn evpn
++ autort rfc8365-compatible
++ """
++ )
++
++ def _remove_autort_rfc8365(router):
++ router.vtysh_cmd(
++ """
++ configure terminal
++ router bgp 65001
++ address-family l2vpn evpn
++ no autort rfc8365-compatible
++ """
++ )
++
++ router = tgen.gears["r2"]
++
++ test_func = functools.partial(_verify_vni_65001, router)
++ success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5)
++
++ assert result is None, 'wrong auto route-target "{}"'.format(
++ router
++ )
++
++ _add_autort_as(router)
++
++ test_func = functools.partial(_verify_vni_65000, router)
++ success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5)
++
++ assert result is None, 'wrong auto route-target "{}"'.format(router)
++
++ _remove_autort_as(router)
++
++ test_func = functools.partial(_verify_vni_65001, router)
++ success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5)
++
++ assert result is None, 'wrong auto route-target "{}"'.format(
++ router
++ )
++
++ _add_autort_rfc8365(router)
++
++ test_func = functools.partial(_verify_vni_65001_rfc8365, router)
++ success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5)
++
++ assert result is None, 'wrong auto route-target "{}"'.format(router)
++
++ _remove_autort_rfc8365(router)
++
++ test_func = functools.partial(_verify_vni_65001, router)
++ success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5)
++
++ assert result is None, 'wrong auto route-target "{}"'.format(
++ router
++ )
++
++
++if __name__ == "__main__":
++ args = ["-s"] + sys.argv[1:]
++ sys.exit(pytest.main(args))
+
diff --git a/debian/patches/series b/debian/patches/series
index 50b22cc725f5..f3edeff1f445 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,3 @@
-pve/0001-enable-bgp-daemon.patch
+pve/0001-enable-bgp-bfd-daemons.patch
pve/0002-bgpd-add-an-option-for-RT-auto-derivation-to-force-A.patch
+pve/0003-tests-add-bgp-evpn-autort-test.patch
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH 3/4] frr: add the dummy_as_loopback patch series, enable it by default
2025-03-07 12:29 [pve-devel] [PATCH 1/4] frr: bump from 8.5.2 to 10.2.1 Gabriel Goller
2025-03-07 12:29 ` [pve-devel] [PATCH 2/4] frr: port patches to latest stable version, add topotests Gabriel Goller
@ 2025-03-07 12:29 ` Gabriel Goller
2025-03-07 12:29 ` [pve-devel] [PATCH 4/4] debian: update changelog Gabriel Goller
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Gabriel Goller @ 2025-03-07 12:29 UTC (permalink / raw)
To: pve-devel; +Cc: Thomas Lamprecht
Add the patches for the dummy_as_loopback series, which area already
merged upstream, but not yet released. Also enable it by default.
Link: https://github.com/FRRouting/frr/pull/18242
Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
---
...A_IF_DUMMY-flag-for-dummy-interfaces.patch | 125 +++++++++++
...on-to-treat-dummy-interfaces-as-loop.patch | 203 ++++++++++++++++++
...dummy_as_loopback-option-per-default.patch | 26 +++
debian/patches/series | 3 +
4 files changed, 357 insertions(+)
create mode 100644 debian/patches/pve/0004-zebra-add-ZEBRA_IF_DUMMY-flag-for-dummy-interfaces.patch
create mode 100644 debian/patches/pve/0005-fabricd-add-option-to-treat-dummy-interfaces-as-loop.patch
create mode 100644 debian/patches/pve/0006-fabricd-enable-dummy_as_loopback-option-per-default.patch
diff --git a/debian/patches/pve/0004-zebra-add-ZEBRA_IF_DUMMY-flag-for-dummy-interfaces.patch b/debian/patches/pve/0004-zebra-add-ZEBRA_IF_DUMMY-flag-for-dummy-interfaces.patch
new file mode 100644
index 000000000000..e2acfcc82e5a
--- /dev/null
+++ b/debian/patches/pve/0004-zebra-add-ZEBRA_IF_DUMMY-flag-for-dummy-interfaces.patch
@@ -0,0 +1,125 @@
+From 7cf60fd0bdaa45311eea886cee6d1f290a4ac2d2 Mon Sep 17 00:00:00 2001
+From: Gabriel Goller <g.goller@proxmox.com>
+Date: Tue, 25 Feb 2025 10:13:34 +0100
+Subject: [PATCH 4/6] zebra: add ZEBRA_IF_DUMMY flag for dummy interfaces
+
+Introduce ZEBRA_IF_DUMMY interface flag to identify Linux dummy interfaces [0].
+These interfaces behave similarly to loopback interfaces and can be
+specially handled by daemons.
+
+[0]: https://github.com/torvalds/linux/blob/master/drivers/net/dummy.c
+
+Link: https://github.com/FRRouting/frr/pull/18242
+Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
+---
+ lib/if.h | 1 +
+ zebra/if_netlink.c | 3 +++
+ zebra/interface.c | 7 +++++++
+ zebra/interface.h | 6 +++++-
+ zebra/zebra_nb_state.c | 3 +++
+ 5 files changed, 19 insertions(+), 1 deletion(-)
+
+Index: b/lib/if.h
+===================================================================
+--- a/lib/if.h 2025-03-07 11:09:47.571424092 +0100
++++ b/lib/if.h 2025-03-07 11:09:47.568424088 +0100
+@@ -242,6 +242,7 @@
+ #define ZEBRA_INTERFACE_SUB (1 << 1)
+ #define ZEBRA_INTERFACE_LINKDETECTION (1 << 2)
+ #define ZEBRA_INTERFACE_VRF_LOOPBACK (1 << 3)
++#define ZEBRA_INTERFACE_DUMMY (1 << 4)
+
+ /* Interface flags. */
+ uint64_t flags;
+Index: b/zebra/if_netlink.c
+===================================================================
+--- a/zebra/if_netlink.c 2025-03-07 11:09:47.571424092 +0100
++++ b/zebra/if_netlink.c 2025-03-07 11:09:47.568424088 +0100
+@@ -221,6 +221,8 @@
+ *zif_type = ZEBRA_IF_BOND;
+ else if (strcmp(kind, "gre") == 0)
+ *zif_type = ZEBRA_IF_GRE;
++ else if (strcmp(kind, "dummy") == 0)
++ *zif_type = ZEBRA_IF_DUMMY;
+ }
+
+ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb,
+@@ -576,6 +578,7 @@
+ case ZEBRA_IF_MACVLAN:
+ case ZEBRA_IF_VETH:
+ case ZEBRA_IF_BOND:
++ case ZEBRA_IF_DUMMY:
+ break;
+ }
+ }
+Index: b/zebra/interface.c
+===================================================================
+--- a/zebra/interface.c 2025-03-07 11:09:47.571424092 +0100
++++ b/zebra/interface.c 2025-03-07 11:09:47.568424088 +0100
+@@ -584,6 +584,9 @@
+
+ zebra_interface_add_update(ifp);
+
++ if (IS_ZEBRA_IF_DUMMY(ifp))
++ SET_FLAG(ifp->status, ZEBRA_INTERFACE_DUMMY);
++
+ if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
+ SET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
+
+@@ -1646,6 +1649,7 @@
+ case ZEBRA_IF_MACVLAN:
+ case ZEBRA_IF_VETH:
+ case ZEBRA_IF_BOND:
++ case ZEBRA_IF_DUMMY:
+ break;
+ }
+ }
+@@ -2398,6 +2402,9 @@
+ case ZEBRA_IF_GRE:
+ return "GRE";
+
++ case ZEBRA_IF_DUMMY:
++ return "dummy";
++
+ default:
+ return "Unknown";
+ }
+Index: b/zebra/interface.h
+===================================================================
+--- a/zebra/interface.h 2025-03-07 11:09:47.571424092 +0100
++++ b/zebra/interface.h 2025-03-07 11:09:47.569424090 +0100
+@@ -39,7 +39,8 @@
+ ZEBRA_IF_MACVLAN, /* MAC VLAN interface*/
+ ZEBRA_IF_VETH, /* VETH interface*/
+ ZEBRA_IF_BOND, /* Bond */
+- ZEBRA_IF_GRE, /* GRE interface */
++ ZEBRA_IF_GRE, /* GRE interface */
++ ZEBRA_IF_DUMMY, /* Dummy interface */
+ };
+
+ /* Zebra "slave" interface type */
+@@ -246,6 +247,9 @@
+ #define IS_ZEBRA_IF_GRE(ifp) \
+ (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_GRE)
+
++#define IS_ZEBRA_IF_DUMMY(ifp) \
++ (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_DUMMY)
++
+ #define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) \
+ (((struct zebra_if *)(ifp->info))->zif_slave_type \
+ == ZEBRA_IF_SLAVE_BRIDGE)
+Index: b/zebra/zebra_nb_state.c
+===================================================================
+--- a/zebra/zebra_nb_state.c 2025-03-07 11:09:47.571424092 +0100
++++ b/zebra/zebra_nb_state.c 2025-03-07 11:09:47.569424090 +0100
+@@ -87,6 +87,9 @@
+ case ZEBRA_IF_GRE:
+ type = "frr-zebra:zif-gre";
+ break;
++ case ZEBRA_IF_DUMMY:
++ type = "frr-zebra:zif-dummy";
++ break;
+ }
+
+ if (!type)
+
diff --git a/debian/patches/pve/0005-fabricd-add-option-to-treat-dummy-interfaces-as-loop.patch b/debian/patches/pve/0005-fabricd-add-option-to-treat-dummy-interfaces-as-loop.patch
new file mode 100644
index 000000000000..331beed378ec
--- /dev/null
+++ b/debian/patches/pve/0005-fabricd-add-option-to-treat-dummy-interfaces-as-loop.patch
@@ -0,0 +1,203 @@
+From 99aab947f7b89b31f08ba9ccf755ff60af9005a8 Mon Sep 17 00:00:00 2001
+From: Gabriel Goller <g.goller@proxmox.com>
+Date: Tue, 25 Feb 2025 10:24:58 +0100
+Subject: [PATCH 5/6] fabricd: add option to treat dummy interfaces as loopback
+ interfaces
+
+Enable dummy-interfaces to be used as router-id interfaces in openfabric
+networks. This allows multiple openfabric routers with different
+router-ids on a single node when using IP unnumbered setup (interfaces
+without IPs configured). Previously we were limited by having a single
+loopback interface, allowing only one openfabric router per node.
+
+Link: https://github.com/FRRouting/frr/pull/18242
+Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
+---
+ doc/manpages/frr-fabricd.rst | 4 ++++
+ doc/user/fabricd.rst | 17 ++++++++++++-----
+ isisd/isis_circuit.c | 9 +++++----
+ isisd/isis_main.c | 16 +++++++++++++---
+ isisd/isisd.c | 19 +++++++++++++++++++
+ isisd/isisd.h | 4 ++++
+ 6 files changed, 57 insertions(+), 12 deletions(-)
+
+Index: b/doc/manpages/frr-fabricd.rst
+===================================================================
+--- a/doc/manpages/frr-fabricd.rst 2025-03-07 11:09:47.700424235 +0100
++++ b/doc/manpages/frr-fabricd.rst 2025-03-07 11:09:47.698424233 +0100
+@@ -21,6 +21,10 @@
+
+ .. include:: common-options.rst
+
++.. option:: --dummy_as_loopback
++
++ Treat dummy interfaces as loopback interfaces.
++
+ FILES
+ =====
+
+Index: b/doc/user/fabricd.rst
+===================================================================
+--- a/doc/user/fabricd.rst 2025-03-07 11:09:47.700424235 +0100
++++ b/doc/user/fabricd.rst 2025-03-07 11:09:47.698424233 +0100
+@@ -15,11 +15,18 @@
+ Configuring fabricd
+ ===================
+
+-There are no *fabricd* specific options. Common options can be specified
+-(:ref:`common-invocation-options`) to *fabricd*. *fabricd* needs to acquire
+-interface information from *zebra* in order to function. Therefore *zebra* must
+-be running before invoking *fabricd*. Also, if *zebra* is restarted then *fabricd*
+-must be too.
++*fabricd* accepts all common invocations (:ref:`common-invocation-options`) and
++the following specific options.
++
++.. program:: fabricd
++
++.. option:: --dummy_as_loopback
++
++ Treat dummy interfaces as loopback interfaces.
++
++*fabricd* needs to acquire interface information from *zebra* in order to
++function. Therefore *zebra* must be running before invoking *fabricd*. Also, if
++*zebra* is restarted then *fabricd* must be too.
+
+ Like other daemons, *fabricd* configuration is done in an OpenFabric specific
+ configuration file :file:`fabricd.conf`.
+Index: b/isisd/isis_circuit.c
+===================================================================
+--- a/isisd/isis_circuit.c 2025-03-07 11:09:47.700424235 +0100
++++ b/isisd/isis_circuit.c 2025-03-07 11:09:47.698424233 +0100
+@@ -491,16 +491,17 @@
+ {
+ struct connected *conn;
+
+- if (if_is_broadcast(ifp)) {
++ if (if_is_loopback(ifp) || (isis_option_check(ISIS_OPT_DUMMY_AS_LOOPBACK) &&
++ CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_DUMMY))) {
++ circuit->circ_type = CIRCUIT_T_LOOPBACK;
++ circuit->is_passive = 1;
++ } else if (if_is_broadcast(ifp)) {
+ if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P)
+ circuit->circ_type = CIRCUIT_T_P2P;
+ else
+ circuit->circ_type = CIRCUIT_T_BROADCAST;
+ } else if (if_is_pointopoint(ifp)) {
+ circuit->circ_type = CIRCUIT_T_P2P;
+- } else if (if_is_loopback(ifp)) {
+- circuit->circ_type = CIRCUIT_T_LOOPBACK;
+- circuit->is_passive = 1;
+ } else {
+ /* It's normal in case of loopback etc. */
+ if (IS_DEBUG_EVENTS)
+Index: b/isisd/isis_main.c
+===================================================================
+--- a/isisd/isis_main.c 2025-03-07 11:09:47.700424235 +0100
++++ b/isisd/isis_main.c 2025-03-07 11:09:47.698424233 +0100
+@@ -80,9 +80,12 @@
+ .cap_num_p = array_size(_caps_p),
+ .cap_num_i = 0};
+
++#define OPTION_DUMMY_AS_LOOPBACK 2000
++
+ /* isisd options */
+ static const struct option longopts[] = {
+ {"int_num", required_argument, NULL, 'I'},
++ {"dummy_as_loopback", no_argument, NULL, OPTION_DUMMY_AS_LOOPBACK},
+ {0}};
+
+ /* Master of threads. */
+@@ -269,15 +272,16 @@
+ {
+ int opt;
+ int instance = 1;
++ bool dummy_as_loopback = false;
+
+ #ifdef FABRICD
+ frr_preinit(&fabricd_di, argc, argv);
+ #else
+ frr_preinit(&isisd_di, argc, argv);
+ #endif
+- frr_opt_add(
+- "I:", longopts,
+- " -I, --int_num Set instance number (label-manager)\n");
++ frr_opt_add("I:", longopts,
++ " -I, --int_num Set instance number (label-manager).\n"
++ " --dummy_as_loopback Treat dummy interfaces like loopback interfaces.\n");
+
+ /* Command line argument treatment. */
+ while (1) {
+@@ -295,6 +299,9 @@
+ zlog_err("Instance %i out of range (1..%u)",
+ instance, (unsigned short)-1);
+ break;
++ case OPTION_DUMMY_AS_LOOPBACK:
++ dummy_as_loopback = true;
++ break;
+ default:
+ frr_help_exit(1);
+ }
+@@ -311,6 +318,9 @@
+ /* thread master */
+ isis_master_init(frr_init());
+ master = im->master;
++ if (dummy_as_loopback)
++ isis_option_set(ISIS_OPT_DUMMY_AS_LOOPBACK);
++
+ /*
+ * initializations
+ */
+Index: b/isisd/isisd.c
+===================================================================
+--- a/isisd/isisd.c 2025-03-07 11:09:47.700424235 +0100
++++ b/isisd/isisd.c 2025-03-07 11:09:47.698424233 +0100
+@@ -116,6 +116,25 @@
+ int clear_isis_neighbor_common(struct vty *, const char *id,
+ const char *vrf_name, bool all_vrf);
+
++
++/* ISIS global flag manipulation. */
++int isis_option_set(int flag)
++{
++ switch (flag) {
++ case ISIS_OPT_DUMMY_AS_LOOPBACK:
++ SET_FLAG(im->options, flag);
++ break;
++ default:
++ return -1;
++ }
++ return 0;
++}
++
++int isis_option_check(int flag)
++{
++ return CHECK_FLAG(im->options, flag);
++}
++
+ /* Link ISIS instance to VRF. */
+ void isis_vrf_link(struct isis *isis, struct vrf *vrf)
+ {
+Index: b/isisd/isisd.h
+===================================================================
+--- a/isisd/isisd.h 2025-03-07 11:09:47.700424235 +0100
++++ b/isisd/isisd.h 2025-03-07 11:09:47.698424233 +0100
+@@ -74,7 +74,9 @@
+ struct list *isis;
+ /* ISIS thread master. */
+ struct event_loop *master;
++ /* Various global options */
+ uint8_t options;
++#define ISIS_OPT_DUMMY_AS_LOOPBACK (1 << 0)
+ };
+ #define F_ISIS_UNIT_TEST 0x01
+
+@@ -269,6 +271,8 @@
+ void isis_terminate(void);
+ void isis_master_init(struct event_loop *master);
+ void isis_master_terminate(void);
++int isis_option_set(int flag);
++int isis_option_check(int flag);
+ void isis_vrf_link(struct isis *isis, struct vrf *vrf);
+ void isis_vrf_unlink(struct isis *isis, struct vrf *vrf);
+ struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id);
+
diff --git a/debian/patches/pve/0006-fabricd-enable-dummy_as_loopback-option-per-default.patch b/debian/patches/pve/0006-fabricd-enable-dummy_as_loopback-option-per-default.patch
new file mode 100644
index 000000000000..f7d8ee07225e
--- /dev/null
+++ b/debian/patches/pve/0006-fabricd-enable-dummy_as_loopback-option-per-default.patch
@@ -0,0 +1,26 @@
+From d1fecf9795c0b9df3889760e1f08bf93c5c8a933 Mon Sep 17 00:00:00 2001
+From: Gabriel Goller <g.goller@proxmox.com>
+Date: Thu, 6 Mar 2025 13:27:55 +0100
+Subject: [PATCH 6/6] fabricd: enable dummy_as_loopback option per default
+
+This allows dummy interfaces to be treated as loopback interfaces in
+openfabric fabrics.
+
+Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
+---
+ tools/etc/frr/daemons | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: b/tools/etc/frr/daemons
+===================================================================
+--- a/tools/etc/frr/daemons 2025-03-07 11:09:47.835424384 +0100
++++ b/tools/etc/frr/daemons 2025-03-07 11:09:47.833424382 +0100
+@@ -57,7 +57,7 @@
+ pbrd_options=" -A 127.0.0.1"
+ staticd_options="-A 127.0.0.1"
+ bfdd_options=" -A 127.0.0.1"
+-fabricd_options="-A 127.0.0.1"
++fabricd_options="-A 127.0.0.1 --dummy_as_loopback"
+ vrrpd_options=" -A 127.0.0.1"
+ pathd_options=" -A 127.0.0.1"
+
diff --git a/debian/patches/series b/debian/patches/series
index f3edeff1f445..c59ef31dfe6c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,6 @@
pve/0001-enable-bgp-bfd-daemons.patch
pve/0002-bgpd-add-an-option-for-RT-auto-derivation-to-force-A.patch
pve/0003-tests-add-bgp-evpn-autort-test.patch
+pve/0004-zebra-add-ZEBRA_IF_DUMMY-flag-for-dummy-interfaces.patch
+pve/0005-fabricd-add-option-to-treat-dummy-interfaces-as-loop.patch
+pve/0006-fabricd-enable-dummy_as_loopback-option-per-default.patch
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 10+ messages in thread