zebra: For rnh handling use actual resolved nexthop

For nexthop handling use the actual resolved nexthop.
Nexthops are stored as a `special` list:

Suppose we have 3 way ecmp A, B, C:
nhop A  -> resolves to nhop D
  |
nhop B
  |
nhop C -> resolves to nhop E

A and C are typically NEXTHOP_TYPE_IPV4( or 6 ) if they recursively resolve
We do not necessarily store the ifindex that this resolves to.

Current nexthop code only loops over A,B and C and uses those for
the zebra_rnh.c handling.  So interested parties might receive non-fully
resolved nexthops( and they assume they are! ).

Let's convert the looping to go over all nexthops and only deal with
the resolved ones, so we will look at and use D,B and E.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2018-12-12 08:02:08 -05:00
parent 27dcf6d901
commit 72366a6e97

View File

@ -528,8 +528,7 @@ static void zebra_rnh_process_pbr_tables(int family,
*/
static bool rnh_nexthop_valid(const struct nexthop *nh)
{
return ((CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
|| CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
return (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
&& CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE));
}
@ -581,8 +580,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, int family,
/* Just being SELECTED isn't quite enough - must
* have an installed nexthop to be useful.
*/
for (nexthop = re->ng.nexthop; nexthop;
nexthop = nexthop->next) {
for (ALL_NEXTHOPS(re->ng, nexthop)) {
if (rnh_nexthop_valid(nexthop))
break;
}
@ -915,7 +913,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
num = 0;
nump = stream_get_endp(s);
stream_putc(s, 0);
for (nh = re->ng.nexthop; nh; nh = nh->next)
for (ALL_NEXTHOPS(re->ng, nh))
if (rnh_nexthop_valid(nh)) {
stream_putl(s, nh->vrf_id);
stream_putc(s, nh->type);