summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_spf.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2020-11-28 21:35:18 +0100
committerDonald Sharp <sharpd@nvidia.com>2020-11-28 21:35:18 +0100
commitd615c345f289921f8db0735285890834d43c175b (patch)
treef904b36fa6f84bdca127ac797a1a03823145c177 /ospfd/ospf_spf.c
parenteigrpd: Remove unneeeded if state types (diff)
downloadfrr-d615c345f289921f8db0735285890834d43c175b.tar.xz
frr-d615c345f289921f8db0735285890834d43c175b.zip
ospfd: Restore POINTOMULTIPOINT to working order
Commit: 1d376ff539508f336cb5872c5592b780e3db180b removed the code to find nexthops for the POINTOMULTIPOINT and replaced it with a generic bit of code that was supposed to handle both POINTOPOINT and POINTOMULTIPOINT the problem is that the ospf rfc states that the network mask on point to multipoint should be /32 which will not allow you to properly do a prefix match on it against the network. Restore original behavior as much as possible and leave the new POINTOPOINT code alone. Fixes: #7624 Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'ospfd/ospf_spf.c')
-rw-r--r--ospfd/ospf_spf.c81
1 files changed, 58 insertions, 23 deletions
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 78814cb28..ad9e6f547 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -583,6 +583,21 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
struct router_lsa_link *l2 = NULL;
if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT) {
+ struct ospf_interface *oi = NULL;
+ struct in_addr nexthop = {.s_addr = 0};
+
+ oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos);
+ if (!oi) {
+ zlog_debug(
+ "%s: OI not found in LSA: lsa_pos: %d link_id:%s link_data:%s",
+ __func__, lsa_pos,
+ inet_ntop(AF_INET, &l->link_id,
+ buf1, BUFSIZ),
+ inet_ntop(AF_INET,
+ &l->link_data, buf2,
+ BUFSIZ));
+ return 0;
+ }
/*
* If the destination is a router which connects
@@ -629,17 +644,12 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
* as described above using a reverse lookup to
* figure out the nexthop.
*/
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
+ struct ospf_neighbor *nbr_w = NULL;
- struct in_addr nexthop = {.s_addr = 0};
- struct ospf_interface *oi = NULL;
- struct ospf_neighbor *nbr_w = NULL;
-
- /* Calculating node is root node, link is P2P */
- if (area->spf_root_node) {
- oi = ospf_if_lookup_by_lsa_pos(area,
- lsa_pos);
- if (oi->type
- == OSPF_IFTYPE_POINTOPOINT) {
+ /* Calculating node is root node, link
+ * is P2P */
+ if (area->spf_root_node) {
nbr_w = ospf_nbr_lookup_by_routerid(
oi->nbrs, &l->link_id);
if (nbr_w) {
@@ -647,20 +657,45 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
nexthop = nbr_w->src;
}
}
- }
- /* Reverse lookup */
- if (!added) {
+ /* Reverse lookup */
+ if (!added) {
+ while ((l2 = ospf_get_next_link(
+ w, v, l2))) {
+ if (match_stub_prefix(
+ v->lsa,
+ l->link_data,
+ l2->link_data)) {
+ added = 1;
+ nexthop =
+ l2->link_data;
+ break;
+ }
+ }
+ }
+ } else if (oi->type
+ == OSPF_IFTYPE_POINTOMULTIPOINT) {
+ struct prefix_ipv4 la;
+
+ la.family = AF_INET;
+ la.prefixlen = oi->address->prefixlen;
+
+ /*
+ * V links to W on PtMP interface;
+ * find the interface address on W
+ */
while ((l2 = ospf_get_next_link(w, v,
l2))) {
- if (match_stub_prefix(
- v->lsa,
- l->link_data,
- l2->link_data)) {
- added = 1;
- nexthop = l2->link_data;
- break;
- }
+ la.prefix = l2->link_data;
+
+ if (prefix_cmp((struct prefix
+ *)&la,
+ oi->address)
+ != 0)
+ continue;
+ added = 1;
+ nexthop = l2->link_data;
+ break;
}
}
@@ -672,8 +707,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
return 1;
} else
zlog_info(
- "%s: could not determine nexthop for link",
- __func__);
+ "%s: could not determine nexthop for link %s",
+ __func__, oi->ifp->name);
} /* end point-to-point link from V to W */
else if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK) {
/*