| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #9964 +/- ##
=========================================
Coverage 19.91% 19.91%
- Complexity 20198 20199 +1
=========================================
Files 6373 6373
Lines 577230 577230
Branches 70696 70696
=========================================
+ Hits 114936 114952 +16
+ Misses 449736 449712 -24
- Partials 12558 12566 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness.
|
Sorry, something went wrong.
|
@weizhouapache a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
Sorry, something went wrong.
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 11599 |
Sorry, something went wrong.
|
@blueorangutan test ubuntu24 kvm-ubuntu24 |
Sorry, something went wrong.
|
@weizhouapache a [SL] Trillian-Jenkins test job (ubuntu24 mgmt + kvm-ubuntu24) has been kicked to run smoke tests |
Sorry, something went wrong.
|
[SF] Trillian test result (tid-11794)
|
Sorry, something went wrong.
|
@weizhouapache a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
Sorry, something went wrong.
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 11666 |
Sorry, something went wrong.
There was a problem hiding this comment.
code lgtm
need testing
Sorry, something went wrong.
Thanks for the test! Lets re-run the test and we can push this one for later. In which env did you test it? |
Sorry, something went wrong.
@wido with the old ipv4 config r-269-VM# show bgp summary IPv4 Unicast Summary (VRF default): BGP router identifier 10.200.0.12, local AS number 10010 vrf-id 0 BGP table version 3 RIB entries 5, using 960 bytes of memory Peers 1, using 724 KiB of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc 10.200.0.1 4 64999 8 8 0 0 0 00:00:05 2 3 N/A Total number of neighbors 1 with the new ipv4 config r-269-VM# show bgp summary IPv4 Unicast Summary (VRF default): BGP router identifier 10.200.0.12, local AS number 10010 vrf-id 0 BGP table version 1 RIB entries 1, using 192 bytes of memory Peers 1, using 724 KiB of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc 10.200.0.1 4 64999 5 3 0 0 0 00:00:07 (Policy) (Policy) N/A Total number of neighbors 1 r-269-VM# my bgp router (10.200.0.1) is also setup with frr. with the old config, show ip route has the line B>* 192.168.120.0/28 [20/0] via 10.200.0.12, eth1, weight 1, 00:00:00 this is missing with the new configuration |
Sorry, something went wrong.
|
Hi @wido @weizhouapache is this PR still in progress or is it ready for testing? |
Sorry, something went wrong.
I had Claude Fable take a look and it came back with a few small changes, nothing major. I also added tests. @weizhouapache In your tests, did you make sure the upstream router only sends 0.0.0.0/0 or ::/0 as routes? Anything else will be rejected by the VR. |
Sorry, something went wrong.
|
I updated this PR to add more tests and verify the FRR.conf looks as expected. |
Sorry, something went wrong.
@wido |
Sorry, something went wrong.
|
Tested this against a VR, IPv4 worked but ipv6 did not (same upstream router configured via FRR). I have validated the following changes, which fixes two issues
diff --git a/systemvm/debian/opt/cloud/bin/cs/CsBgpPeers.py b/systemvm/debian/opt/cloud/bin/cs/CsBgpPeers.py
index d90d31cba5f..849685610fd 100755
--- a/systemvm/debian/opt/cloud/bin/cs/CsBgpPeers.py
+++ b/systemvm/debian/opt/cloud/bin/cs/CsBgpPeers.py
@@ -81,6 +81,7 @@ class CsBgpPeers(CsDataBag):
self.frr_conf.add("hostname {}".format(CsHelper.get_hostname()))
self.frr_conf.add("service integrated-vtysh-config")
self.frr_conf.add("ip nht resolve-via-default")
+ self.frr_conf.add("ipv6 nht resolve-via-default")
return
def _access_list_set(self):
@@ -111,8 +112,6 @@ class CsBgpPeers(CsDataBag):
self.frr_conf.add(" bgp default ipv6-unicast")
for ip4_peer in self.peers[as_number]['ip4_peers']:
self.frr_conf.add(" neighbor {} remote-as {}".format(ip4_peer['ip4_address'], ip4_peer['peer_as_number']))
- self.frr_conf.add(" neighbor {} route-map upstream-v4-in in".format(ip4_peer['ip4_address']))
- self.frr_conf.add(" neighbor {} route-map upstream-v4-out out".format(ip4_peer['ip4_address']))
if 'peer_password' in ip4_peer:
self.frr_conf.add(" neighbor {} password {}".format(ip4_peer['ip4_address'], ip4_peer['peer_password']))
if 'details' in ip4_peer:
@@ -120,8 +119,6 @@ class CsBgpPeers(CsDataBag):
self.frr_conf.add(" neighbor {} ebgp-multihop {}".format(ip4_peer['ip4_address'], ip4_peer['details']['EBGP_MultiHop']))
for ip6_peer in self.peers[as_number]['ip6_peers']:
self.frr_conf.add(" neighbor {} remote-as {}".format(ip6_peer['ip6_address'], ip6_peer['peer_as_number']))
- self.frr_conf.add(" neighbor {} route-map upstream-v6-in in".format(ip6_peer['ip6_address']))
- self.frr_conf.add(" neighbor {} route-map upstream-v6-out out".format(ip6_peer['ip6_address']))
if 'peer_password' in ip6_peer:
self.frr_conf.add(" neighbor {} password {}".format(ip6_peer['ip6_address'], ip6_peer['peer_password']))
if 'details' in ip6_peer:
@@ -129,12 +126,18 @@ class CsBgpPeers(CsDataBag):
self.frr_conf.add(" neighbor {} ebgp-multihop {}".format(ip6_peer['ip6_address'], ip6_peer['details']['EBGP_MultiHop']))
if self.peers[as_number]['ip4_peers']:
self.frr_conf.add(" address-family ipv4 unicast")
+ for ip4_peer in self.peers[as_number]['ip4_peers']:
+ self.frr_conf.add(" neighbor {} route-map upstream-v4-in in".format(ip4_peer['ip4_address']))
+ self.frr_conf.add(" neighbor {} route-map upstream-v4-out out".format(ip4_peer['ip4_address']))
ip4_cidrs = set({ip4_peer['guest_ip4_cidr'] for ip4_peer in self.peers[as_number]['ip4_peers']})
for ip4_cidr in ip4_cidrs:
self.frr_conf.add(" network {}".format(ip4_cidr))
self.frr_conf.add(" exit-address-family")
if self.peers[as_number]['ip6_peers']:
self.frr_conf.add(" address-family ipv6 unicast")
+ for ip6_peer in self.peers[as_number]['ip6_peers']:
+ self.frr_conf.add(" neighbor {} route-map upstream-v6-in in".format(ip6_peer['ip6_address']))
+ self.frr_conf.add(" neighbor {} route-map upstream-v6-out out".format(ip6_peer['ip6_address']))
ip6_cidrs = set({ip6_peer['guest_ip6_cidr'] for ip6_peer in self.peers[as_number]['ip6_peers']})
for ip6_cidr in ip6_cidrs:
self.frr_conf.add(" network {}".format(ip6_cidr))
diff --git a/systemvm/test/TestCsBgpPeers.py b/systemvm/test/TestCsBgpPeers.py
index 2dddf7db0fd..64179575666 100644
--- a/systemvm/test/TestCsBgpPeers.py
+++ b/systemvm/test/TestCsBgpPeers.py
@@ -128,10 +128,15 @@ class TestCsBgpPeers(unittest.TestCase):
self.assertIn("router bgp 64512", config)
self.assertIn(" bgp router-id 100.64.0.10", config)
self.assertIn(" neighbor 100.64.0.1 remote-as 64496", config)
- self.assertIn(" neighbor 100.64.0.1 route-map upstream-v4-in in", config)
- self.assertIn(" neighbor 100.64.0.1 route-map upstream-v4-out out", config)
+ self.assertIn(" neighbor 100.64.0.1 route-map upstream-v4-in in", config)
+ self.assertIn(" neighbor 100.64.0.1 route-map upstream-v4-out out", config)
self.assertIn(" network 10.1.1.0/24", config)
self.assertNotIn(" bgp default ipv6-unicast", config)
+ # route-map must be applied inside the address-family block, not at
+ # router-bgp level, otherwise FRR silently binds it to IPv4 unicast
+ # regardless of the neighbor's actual AFI/SAFI.
+ self.assertNotIn(" neighbor 100.64.0.1 route-map upstream-v4-in in", config)
+ self.assertNotIn(" neighbor 100.64.0.1 route-map upstream-v4-out out", config)
def test_process_peers_ip6(self):
self.csbgppeers._process_dbag_item(self._peer(ip6_address='2001:db8::1',
@@ -141,9 +146,15 @@ class TestCsBgpPeers(unittest.TestCase):
config = self._frr_conf()
self.assertIn(" bgp default ipv6-unicast", config)
self.assertIn(" neighbor 2001:db8::1 remote-as 64496", config)
- self.assertIn(" neighbor 2001:db8::1 route-map upstream-v6-in in", config)
- self.assertIn(" neighbor 2001:db8::1 route-map upstream-v6-out out", config)
+ self.assertIn(" neighbor 2001:db8::1 route-map upstream-v6-in in", config)
+ self.assertIn(" neighbor 2001:db8::1 route-map upstream-v6-out out", config)
self.assertIn(" network 2001:db8:100::/64", config)
+ # Same guard as above, for the IPv6 address-family: FRR treats a
+ # bare "neighbor X route-map Y in/out" (outside an address-family
+ # block) as applying to IPv4 unicast, leaving IPv6 unicast with no
+ # policy at all (FRR then discards all updates by default).
+ self.assertNotIn(" neighbor 2001:db8::1 route-map upstream-v6-in in", config)
+ self.assertNotIn(" neighbor 2001:db8::1 route-map upstream-v6-out out", config)
def test_process_peers_password_and_multihop(self):
self.csbgppeers._process_dbag_item(self._peer(ip4_address='100.64.0.1',
@@ -197,6 +208,7 @@ class TestCsBgpPeers(unittest.TestCase):
"hostname r-1001-VM",
"service integrated-vtysh-config",
"ip nht resolve-via-default",
+ "ipv6 nht resolve-via-default",
"ip prefix-list all-v4 seq 1 permit any",
"ip prefix-list default-v4 seq 1 permit 0.0.0.0/0",
"ipv6 prefix-list all-v6 seq 1 permit any",
@@ -207,15 +219,15 @@ class TestCsBgpPeers(unittest.TestCase):
" bgp router-id 100.64.0.10",
" bgp default ipv6-unicast",
" neighbor 100.64.0.1 remote-as 64496",
- " neighbor 100.64.0.1 route-map upstream-v4-in in",
- " neighbor 100.64.0.1 route-map upstream-v4-out out",
" neighbor 2001:db8::1 remote-as 64496",
- " neighbor 2001:db8::1 route-map upstream-v6-in in",
- " neighbor 2001:db8::1 route-map upstream-v6-out out",
" address-family ipv4 unicast",
+ " neighbor 100.64.0.1 route-map upstream-v4-in in",
+ " neighbor 100.64.0.1 route-map upstream-v4-out out",
" network 10.1.1.0/24",
" exit-address-family",
" address-family ipv6 unicast",
+ " neighbor 2001:db8::1 route-map upstream-v6-in in",
+ " neighbor 2001:db8::1 route-map upstream-v6-out out",
" network 2001:db8:100::/64",
" exit-address-family",
"route-map upstream-v4-in permit 10",
|
Sorry, something went wrong.
Thanks for testing! I just want to check: Your upstream is only sending a ::/0 route, right? Not something else? |
Sorry, something went wrong.
|
I updated the test to make sure we have a real frr.conf in systemvm/test which the Python code tests against. This should be easier to read and understand what the output should be. |
Sorry, something went wrong.
@wido thanks for the update. Please find my frr config below: address-family ipv6 unicast redistribute connected <==== !! neighbor ACS-V6 activate neighbor ACS-V6 route-reflector-client exit-address-family |
Sorry, something went wrong.
Can you show me the routes you are advertising to the VR? Show bgp neighbor X advertised-routes |
Sorry, something went wrong.
@wido bgp-router# show bgp neighbor 10.200.0.200 advertised-routes
BGP table version is 44, local router ID is 10.200.0.1, vrf id 0
Default local pref 100, local AS 64999
Status codes: s suppressed, d damped, h history, * 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
*> fc00:2024:9:7::/64 <====== eth1 of the bgp-router (IPv4: 10.200.0.1/24)
:: 0 32768 ?
*> fd00:2026:9:1::/64 <====== guest network IPv6 cidr
:: 0 65000 i
*> fd01::/64 :: 0 32768 ? <====== eth0 of the bgp-router (default interface)
Total number of prefixes 3
|
Sorry, something went wrong.
Does it work? Because the route-map should only allow for a default route ::/0 to be advertised to the VR. You are sending non default routes. That’s a use-case which you won’t see in most cases. Why aren’t you sending a default route? In the VR, you will see these routes are not accepted. |
Sorry, something went wrong.
@wido any more work on this PR ? I think it is ready for merge, right ? |
Sorry, something went wrong.
Got it! But yes, this is ready for merge. In all real environments only a default route (::/0) should be received by the VR. |
Sorry, something went wrong.
It is best practice, and mandatory in newer version of FRR, that route-maps should be applied to BGP peers. This is to prevent that mistakes can propogate through a network and cause outages. This change changes the route-maps where the VR will only accept IPv4 and IPv4 default gateways (0.0.0.0/0 and ::/0) to be sent by the upstream router to the VR. The other way around this change makes sure that FRR will not allow announcing anything else than the locally defined subnets to the upstream BGP router.
There was a problem hiding this comment.
lgtm
verified OK
let's wait GHA to finish and then merge
Sorry, something went wrong.
- Filter comment lines (starting with #) when comparing generated vs expected FRR config - Apply filtering to both generated config and expected config file - Allows keeping license headers in test fixtures while ignoring them in tests - All 11 BGP peer tests pass
* origin/main: (156 commits) Upgrade Netris SDK version to 1.1.0 since 24.0 (apache#14365) feature: instance boot group and readiness rules (apache#13907) dont show unathorized notification for prelogin (apache#14054) .github: Upgrade docker/login-action to fix ASF Allowlist failure (apache#14276) virtual router: Add route-maps to BGP peers for Routed Mode (apache#9964) Add pre-commit hook to validate dependabot.yml (apache#14107) Add the ASF Allowlist check workflow (apache#14113) Revert "VMware to KVM: cold (VDDK) and warm (CBT) migration into Ceph/RBD and Linstor, plus importVm adoption of existing RBD root volumes and Linstor root/data volumes (apache#13656)" VMware to KVM: cold (VDDK) and warm (CBT) migration into Ceph/RBD and Linstor, plus importVm adoption of existing RBD root volumes and Linstor root/data volumes (apache#13656) engine-schema: upgrade path for 24.0.0 (apache#14033) xenserver/xcpng: do not bypass secondary storage when copy volumes between pools (apache#13750) backport: Incremental NAS backup support for KVM (apache#13074) (apache#13877) storage: KVM - enable RBD/Ceph volume encryption support (apache#13556) backup: remove the powered-off precondition for all backup providers (apache#14094) Nas backup: Fix mount/unmount error handling and timeout in LibvirtRestoreBackupCommandWrapper (apache#14006) kvm: apply rbd_default_data_pool when creating volumes from templates on RBD (apache#13361) server: copy template details to vm instance details when import VM (apache#12793) marvin: use pycryptodome instead of PyCrypt (apache#13594) Packaging: accept normalized Marvin archive names (apache#13793) SharedFS: fix NPE when accessing systemvm templates for unsupported hypervisors (apache#13930) ...
| Back | FazBrowse Home | New Git URL |
It is best practice, and mandatory in newer version of FRR, that route-maps should be applied to BGP peers. This is to prevent that mistakes can propogate through a network and cause outages.
This change changes the route-maps where the VR will only accept IPv4 and IPv4 default gateways (0.0.0.0/0 and ::/0) to be sent by the upstream router to the VR.
The other way around this change makes sure that FRR will not allow announcing anything else than the locally defined subnets to the upstream BGP router.