diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2020-05-26 18:21:43 +0200 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2020-05-26 18:21:43 +0200 |
commit | c1632ad0f39f7221d649a9e469cacc38105528e2 (patch) | |
tree | 02567e33e3d6c06954ef35cd65aceb19e18b2c3a /proto/ospf/rt.c | |
parent | 1ca7665fa4a9858a6d4c591ccff5b61e5e6aed13 (diff) |
OSPF: Fix handling of unnumbered PtPs
This issue has a long history. In 2012, we changed data field for
unnumbered PtP links from iface id (specified by RFC) to IP address based
on reports of bugs in Quagga that required it, and we used out-of-band
information to distinquish unnumberred PtPs with the same local IP
address.
Then with OSPF graceful restart implementation, we found that we can no
longer use out-of-band information, and we need to use only LSAdb info
for routing table calculation, but i forgot to finish handling of this
case, so multiple unnumbered PtPs with the same local IP addresses were
broken.
Considering that even recent Mikrotik RouterOS has broken next hop
calculation that depends on IP address in PtP link data field, we
cannot just switch back to the iface id for unnumbered PtP links.
The patch makes two changes: First, it goes back to use out-of-band
(position) info for distinguishing local interfaces in SPF when graceful
restart is not enabled, while still uses LSAdb-only approach for SPF
calculation when graceful restart is enabled.
Second, it adds OSPF interface option 'ptp address', which controls
whether IP address or iface id is used in data field. It is enabled
by default except for unnumbered PtP links with enabled graceful
restart.
Thanks to Kenth Eriksson for the bugreport and Joakim Tjernlund for
suggestions.
Diffstat (limited to 'proto/ospf/rt.c')
-rw-r--r-- | proto/ospf/rt.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index b5787b54..b3e49a11 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -395,12 +395,10 @@ px_pos_to_ifa(struct ospf_area *oa, int pos) static inline struct ospf_iface * rt_find_iface2(struct ospf_area *oa, uint data) { - ip_addr addr = ipa_from_u32(data); - /* We should handle it differently for unnumbered PTP links */ struct ospf_iface *ifa; WALK_LIST(ifa, oa->po->iface_list) - if ((ifa->oa == oa) && ifa->addr && (ipa_equal(ifa->addr->ip, addr))) + if ((ifa->oa == oa) && ifa->addr && (ospf_iface_get_data(ifa) == data)) return ifa; return NULL; @@ -420,7 +418,13 @@ rt_find_iface3(struct ospf_area *oa, uint lif) static struct ospf_iface * rt_find_iface(struct ospf_area *oa, int pos, uint data, uint lif) { - if (0) + /* + * We can use both position based lookup (which is more reliable) and data/lif + * based lookup (which works even during graceful restart). We will prefer the + * first approach, but use the second one for GR-enabled instances. + */ + + if (oa->po->gr_mode != OSPF_GR_ABLE) return rt_pos_to_ifa(oa, pos); else return ospf_is_v2(oa->po) ? rt_find_iface2(oa, data) : rt_find_iface3(oa, lif); |