]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_rnh.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / zebra / zebra_rnh.c
index df4435b6190006499cdd9893edf76e1e4829627e..b1fbe8a6536de6dbdf2bf91b6f520ec8664a7266 100644 (file)
@@ -213,10 +213,14 @@ void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
                           zebra_route_string(client->proto),
                           rnh_str(rnh, buf, sizeof(buf)), type);
        }
-       if (!listnode_lookup(rnh->client_list, client)) {
+       if (!listnode_lookup(rnh->client_list, client))
                listnode_add(rnh->client_list, client);
-               send_client(rnh, client, type, vrf_id);
-       }
+
+       /*
+        * We always need to respond with known information,
+        * currently multiple daemons expect this behavior
+        */
+       send_client(rnh, client, type, vrf_id);
 }
 
 void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client,
@@ -517,6 +521,17 @@ static void zebra_rnh_process_pbr_tables(int family,
        }
 }
 
+/*
+ * Utility to determine whether a candidate nexthop is useable. We make this
+ * check in a couple of places, so this is a single home for the logic we
+ * use.
+ */
+static bool rnh_nexthop_valid(const struct nexthop *nh)
+{
+       return (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
+               && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE));
+}
+
 /*
  * Determine appropriate route (route entry) resolving a tracked
  * nexthop.
@@ -529,6 +544,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, int family,
        struct route_table *route_table;
        struct route_node *rn;
        struct route_entry *re;
+       struct nexthop *nexthop;
 
        *prn = NULL;
 
@@ -561,12 +577,22 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, int family,
                        if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
                                continue;
 
+                       /* Just being SELECTED isn't quite enough - must
+                        * have an installed nexthop to be useful.
+                        */
+                       for (ALL_NEXTHOPS(re->ng, nexthop)) {
+                               if (rnh_nexthop_valid(nexthop))
+                                       break;
+                       }
+
+                       if (nexthop == NULL)
+                               continue;
+
                        if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) {
                                if ((re->type == ZEBRA_ROUTE_CONNECT)
                                    || (re->type == ZEBRA_ROUTE_STATIC))
                                        break;
                                if (re->type == ZEBRA_ROUTE_NHRP) {
-                                       struct nexthop *nexthop;
 
                                        for (nexthop = re->ng.nexthop; nexthop;
                                             nexthop = nexthop->next)
@@ -887,10 +913,9 @@ 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)
-                       if ((CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
-                            || CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
-                           && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)) {
+               for (ALL_NEXTHOPS(re->ng, nh))
+                       if (rnh_nexthop_valid(nh)) {
+                               stream_putl(s, nh->vrf_id);
                                stream_putc(s, nh->type);
                                switch (nh->type) {
                                case NEXTHOP_TYPE_IPV4: