diff options
author | Donald Sharp <sharpd@nvidia.com> | 2020-11-28 21:35:18 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@nvidia.com> | 2020-11-28 21:35:18 +0100 |
commit | d615c345f289921f8db0735285890834d43c175b (patch) | |
tree | f904b36fa6f84bdca127ac797a1a03823145c177 /ospfd/ospf_spf.c | |
parent | eigrpd: Remove unneeeded if state types (diff) | |
download | frr-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.c | 81 |
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) { /* |