fix: remove only duplicate proxy cidr from prefix_trie#2175
Conversation
5c5d28f to
2c1dc82
Compare
| routes.into_iter().collect() | ||
| } else { | ||
| // Collect proxy_cidrs from routes | ||
| let mut proxy_cidrs = peer_mgr.list_proxy_cidrs().await; |
There was a problem hiding this comment.
原先的 list_proxy_cidrs 性能应该显著高于全量的 list_routes,proxy_cidrs 本身也是一个 BTreeSet 可以去重。为什么要改呢
There was a problem hiding this comment.
确实,我单纯是想退回那个 pr 前的逻辑,之前用的是 list_routes,倒是没有考虑性能问题,那我把这个撤销,只留下修补那个最长匹配的修改
There was a problem hiding this comment.
说起来这个 prefix_trie::PrefixSet 好像天生也能实现去重 + 最长匹配,不过我没细看
There was a problem hiding this comment.
应该是,但我之前有个 pr 把远程过来的 cidr 只要是本地 cidr 的子网那就都扔了,这个是不对的,我现在改成完全相等的才去掉,这样能自动最长匹配
There was a problem hiding this comment.
Pull request overview
Refactors how proxy CIDRs are derived from peer routing state so that duplicate proxy CIDRs announced by another peer don’t end up being treated as separate proxy routes, aligning behavior with the prior fixes around overlapped/duplicate CIDR handling.
Changes:
- Changes route-table building to skip only exact duplicate remote proxy CIDRs (and relies on LPM for overlaps).
- Removes
list_proxy_cidrs{,_v6}from the routing traits/manager and instead derives proxy CIDRs fromlist_routes(). - Updates tests to reflect the new semantics around overlapped/duplicate proxy CIDRs.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| easytier/src/tests/three_node.rs | Removes proxy-route “wait” steps in the loop-prevention test scenario. |
| easytier/src/peers/route_trait.rs | Removes list_proxy_cidrs{,_v6} from the Route trait and the mock implementation. |
| easytier/src/peers/peer_ospf_route.rs | Updates proxy CIDR filtering logic (duplicates only), populates per-peer route.proxy_cidrs via the CIDR→peer maps, and adjusts an overlap-related unit test expectation. |
| easytier/src/peers/peer_manager.rs | Removes proxy CIDR listing helpers now that the trait methods are gone. |
| easytier/src/instance/proxy_cidrs_monitor.rs | Derives proxy CIDRs by scanning list_routes() output instead of calling the removed CIDR helpers. |
Comments suppressed due to low confidence (2)
easytier/src/peers/peer_ospf_route.rs:1646
- The skip condition was changed to only filter exact duplicate CIDRs (
local_proxy_cidrs.contains(&cidr)), but the debug message still says the remote CIDR is "covered by" the local CIDR. This is misleading now that subset/overlap filtering is no longer performed; please update the log message (and/or surrounding comment) to reflect that only exact duplicates are skipped.
if *peer_id != my_peer_id && local_proxy_cidrs.contains(&cidr) {
tracing::debug!(
?peer_id,
?my_peer_id,
?local_proxy_cidrs,
?cidr,
"skip remote proxy cidr covered by local announced proxy cidr while building route table"
);
easytier/src/tests/three_node.rs:1049
- This test removed the waits that ensured the proxy-route state had converged before exercising the loop scenario. With the new "duplicate CIDR" behavior, it would be better to explicitly assert the expected route-table outcome (e.g., that a peer does not learn a remote proxy route for an identical CIDR) or otherwise wait for route-table stabilization; otherwise the ping/metric loop can pass trivially if routing info hasn’t propagated yet, reducing the test’s effectiveness and making it timing-sensitive.
// 从 inst1 (net_a) 发起对 10.1.2.5 的 ping 测试
// 这应该失败,并且不会产生环路
let now = std::time::Instant::now();
while now.elapsed().as_secs() < 10 {
ping_test("net_a", "10.1.2.5", None).await;
tokio::time::sleep(Duration::from_secs(1)).await;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
0221407 to
b46569b
Compare
f3c1876 to
a478f55
Compare
There was a problem hiding this comment.
Pull request overview
Adjusts proxy CIDR handling in the OSPF route table builder so that only duplicate remote proxy CIDRs are excluded, allowing overlapped (more specific) prefixes to be selected by longest-prefix-match (LPM) in the data plane.
Changes:
- Refactors CIDR containment logic into an
IpCidrExt::covers()helper and simplifies string-based subset checks. - Changes local proxy CIDR collection to a
HashSetand updates filtering to skip only exact-duplicate remote CIDRs (vs. skipping subsets). - Updates the overlapped-proxy-CIDR test to assert LPM behavior (remote /24 wins over local /16).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| p.first_address() <= c.first_address() && c.last_address() <= p.last_address() | ||
| } | ||
| _ => false, // mixed v4/v6 | ||
| pub trait IpCidrExt { |
| if *peer_id != my_peer_id && local_proxy_cidrs.contains(&cidr) { | ||
| tracing::debug!( | ||
| ?peer_id, | ||
| ?my_peer_id, |
There was a problem hiding this comment.
你意思是不用最长匹配吗?按原来的做法即便远程来的子网更小也是本地优先
There was a problem hiding this comment.
local_proxy_cidrs 不是 hashset 么,是怎么做到最长匹配的呀
There was a problem hiding this comment.
local_proxy_cidrs 是判断 peer 的路由是不是恰好和本地的某个路由相等,所以 hashset 就够了,如果不是恰好相等——可能重合,可能 peer 的完全包含于本地的 cidr,等等——那么就留下 peer 的 cidr, 加入 new_cidr_prefix_trie,然后让 new_cidr_prefix_trie 去做最长匹配
supersedes fix: filter overlapped proxy cidrs in ProxyCidrsMonitor #2079supersedes fix(peer_route): exclude local peer's own proxy CIDRs from system route installation #2149