[PATCH] OSPF: Fix inverted path comparison for external
From: Mantas Mikulėnas <grawity@gmail.com> For an ordinary E1 or E2 route exported by another Bird2 router in the same area, it was consistently choosing a 10000+ metric path through another area, despite having a direct 10-metric path to the origin in the same backbone area. It seems that this was because the rule 16.2 metric comparison was backwards and always chose highest metric. Note - the patch is probably *not* 100% right; I am not very sure whether both checks are backwards or only the orta_pref() one. It's merely my first successful attempt at fixing the issue (which only affected Bird, not any other OSPFv2 implementation I have here). Regardless, it did happen to fix the issue I was having, and now Bird2 chooses the path I expect it to choose: Before: Table master4: 172.20.0.0/14 unicast [ospf4 10:09:35.865] * E2 (150/10080/100) [31.220.42.129] via 10.147.255.10 on homegw Type: OSPF-E2 univ OSPF.metric1: 10080 OSPF.metric2: 100 OSPF.tag: 0x00000000 OSPF.router_id: 31.220.42.129 After: Table master4: 172.20.0.0/14 unicast [ospf4 12:48:02.452] * E2 (150/30/100) [31.220.42.129] via 10.147.240.122 on gre-land Type: OSPF-E2 univ OSPF.metric1: 30 OSPF.metric2: 100 OSPF.tag: 0x00000000 OSPF.router_id: 31.220.42.129 --- proto/ospf/rt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index d7753ce0a..c6bf5699e 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -200,7 +200,7 @@ orta_compare_asbr(const struct ospf_proto *p, const orta *new, const orta *old) if (!p->rfc1583) { - r = epath_preferred(new) - epath_preferred(old); + r = epath_preferred(old) - epath_preferred(new); if (r) return r; } @@ -242,7 +242,7 @@ orta_compare_ext(const struct ospf_proto *p, const orta *new, const orta *old) /* 16.4 (6c) - if not RFC1583, prefer routes with preferred ASBR/next_hop */ if (!p->rfc1583) { - r = orta_pref(new) - orta_pref(old); + r = orta_pref(old) - orta_pref(new); if (r) return r; } -- 2.48.1
On Tue, Feb 18, 2025 at 12:51:09PM +0200, Mantas Mikulėnas via Bird-users wrote:
From: Mantas Mikulėnas <grawity@gmail.com>
For an ordinary E1 or E2 route exported by another Bird2 router in the same area, it was consistently choosing a 10000+ metric path through another area, despite having a direct 10-metric path to the origin in the same backbone area.
It seems that this was because the rule 16.2 metric comparison was backwards and always chose highest metric.
Hi I think the original code is right. orta_pref() / epath_preferred() does not return metric (higher -> worse), but it returns whether the path is preferred (0/1, higher -> better). Therefore there is: rt.c:245: r = orta_pref(new) - orta_pref(old); but rt.c:250: r = ((int) old->metric1) - ((int) new->metric1); The behavior you are describing:
it was consistently choosing a 10000+ metric path through another area, despite having a direct 10-metric path to the origin in the same backbone area.
It seems to me that it is in fact a peculiar behavior specified by RFC 2328 16.4.1:
When multiple intra-AS paths are available to ASBRs/forwarding addresses, the following rules indicate which paths are preferred. These rules apply when the same ASBR is reachable through multiple areas, or when trying to decide which of several AS-external-LSAs should be preferred.
o Intra-area paths using non-backbone areas are always the most preferred.
o The other paths, intra-area backbone paths and inter- area paths, are of equal preference.
Can you send me the output of 'show ospf state', so i could check that?
(which only affected Bird, not any other OSPFv2 implementation I have here).
Not sure why other implmenetations do not have the same behavior, perhaps they are RFC 1583 and not RFC 2328 OSPF versions, or they are configured with RFC1583Compatibility enabled? -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) "To err is human -- to blame it on a computer is even more so."
On Tue, Feb 18, 2025, 18:38 Ondrej Zajicek <santiago@crfreenet.org> wrote:
On Tue, Feb 18, 2025 at 12:51:09PM +0200, Mantas Mikulėnas via Bird-users wrote:
From: Mantas Mikulėnas <grawity@gmail.com>
For an ordinary E1 or E2 route exported by another Bird2 router in the same area, it was consistently choosing a 10000+ metric path through another area, despite having a direct 10-metric path to the origin in the same backbone area.
It seems that this was because the rule 16.2 metric comparison was backwards and always chose highest metric.
Hi
I think the original code is right. orta_pref() / epath_preferred() does not return metric (higher -> worse), but it returns whether the path is preferred (0/1, higher -> better). Therefore there is:
rt.c:245: r = orta_pref(new) - orta_pref(old);
but
rt.c:250: r = ((int) old->metric1) - ((int) new->metric1);
The behavior you are describing:
it was consistently choosing a 10000+ metric path through another area, despite having a direct 10-metric path to the origin in the same backbone area.
It seems to me that it is in fact a peculiar behavior specified by RFC 2328 16.4.1:
When multiple intra-AS paths are available to ASBRs/forwarding addresses, the following rules indicate which paths are preferred. These rules apply when the same ASBR is reachable through multiple areas, or when trying to decide which of several AS-external-LSAs should be preferred.
o Intra-area paths using non-backbone areas are always the most preferred.
o The other paths, intra-area backbone paths and inter- area paths, are of equal preference.
That is surprising to say the least... But I guess that is the problem then – I'd gone through the RFC to figure out why that was happening, but must have misunderstood this part. Doesn't it defeat the point of areas (and metrics for that matter), when a distant area happens to have 2+ slow links to the backbone?... (One of the ASBRs exporting this route happens to be an ABR for the separate area – is that something to be avoided?)
(which only affected Bird, not any other OSPFv2 implementation I have here).
Not sure why other implmenetations do not have the same behavior, perhaps they are RFC 1583 and not RFC 2328 OSPF versions, or they are configured with RFC1583Compatibility enabled?
I don't remember for sure if they don't – it was 2020 when I did most of the experiments (this is the second time I'm trying to figure it out). RouterOS 7.x doesn't seem to have such an option, but it being a relatively new implementation I can only guess it follows the updated RFC.
-- Elen sila lumenn' omentielvo
Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) "To err is human -- to blame it on a computer is even more so."
On Tue, Feb 18, 2025 at 07:27:10PM +0200, Mantas Mikulėnas wrote:
The behavior you are describing:
it was consistently choosing a 10000+ metric path through another area, despite having a direct 10-metric path to the origin in the same backbone area.
It seems to me that it is in fact a peculiar behavior specified by RFC 2328 16.4.1:
When multiple intra-AS paths are available to ASBRs/forwarding addresses, the following rules indicate which paths are preferred. These rules apply when the same ASBR is reachable through multiple areas, or when trying to decide which of several AS-external-LSAs should be preferred.
o Intra-area paths using non-backbone areas are always the most preferred.
o The other paths, intra-area backbone paths and inter- area paths, are of equal preference.
That is surprising to say the least... But I guess that is the problem then – I'd gone through the RFC to figure out why that was happening, but must have misunderstood this part.
Doesn't it defeat the point of areas (and metrics for that matter), when a distant area happens to have 2+ slow links to the backbone?... (One of the ASBRs exporting this route happens to be an ABR for the separate area – is that something to be avoided?)
This behavior is a workaround for a complex issue related to consistency of routing, where backbone routers have incomplete information due to aggregation of non-backbone areas. For details, see RFC 2178 G.7 (and RFC 2328 G.2). The intuitive idea is that a non-backbone area should be self-cointained, that is why intra-area paths are preferred to inter-area paths. This is kind of complicated by the fact that ABRs are members of both (or more) areas and unclear role of ASBRs who are also ABRs. Perhaps it could help to have ABRs on the other side of those slow links connecting an area to the backbone, and keeping those links a part of backbone? -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) "To err is human -- to blame it on a computer is even more so."
participants (2)
-
Mantas Mikulėnas -
Ondrej Zajicek