]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_rnh.c
lib, zebra: Add SR-TE policy infrastructure to zebra
[mirror_frr.git] / zebra / zebra_rnh.c
index d1a5cf2a9d332fcdef28d7546b60301cde054f7a..cdc00f6026504ded3828c23bf7b55a8c4ea228ce 100644 (file)
@@ -46,6 +46,7 @@
 #include "zebra/debug.h"
 #include "zebra/zebra_rnh.h"
 #include "zebra/zebra_routemap.h"
+#include "zebra/zebra_srte.h"
 #include "zebra/interface.h"
 #include "zebra/zebra_memory.h"
 #include "zebra/zebra_errors.h"
@@ -57,8 +58,6 @@ static void free_state(vrf_id_t vrf_id, struct route_entry *re,
 static void copy_state(struct rnh *rnh, const struct route_entry *re,
                       struct route_node *rn);
 static int compare_state(struct route_entry *r1, struct route_entry *r2);
-static int send_client(struct rnh *rnh, struct zserv *client,
-                      enum rnh_type type, vrf_id_t vrf_id);
 static void print_rnh(struct route_node *rn, struct vty *vty);
 static int zebra_client_cleanup_rnh(struct zserv *client);
 
@@ -305,7 +304,7 @@ void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
         * We always need to respond with known information,
         * currently multiple daemons expect this behavior
         */
-       send_client(rnh, client, type, vrf_id);
+       zebra_send_rnh_update(rnh, client, type, vrf_id, 0);
 }
 
 void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client,
@@ -531,8 +530,9 @@ static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi,
                }
                /* state changed, notify clients */
                for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) {
-                       send_client(rnh, client,
-                                   RNH_IMPORT_CHECK_TYPE, zvrf->vrf->vrf_id);
+                       zebra_send_rnh_update(rnh, client,
+                                             RNH_IMPORT_CHECK_TYPE,
+                                             zvrf->vrf->vrf_id, 0);
                }
        }
 }
@@ -594,7 +594,8 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
                                        zebra_route_string(client->proto));
                }
 
-               send_client(rnh, client, RNH_NEXTHOP_TYPE, zvrf->vrf->vrf_id);
+               zebra_send_rnh_update(rnh, client, RNH_NEXTHOP_TYPE,
+                                     zvrf->vrf->vrf_id, 0);
        }
 
        if (re)
@@ -1040,22 +1041,10 @@ static bool compare_valid_nexthops(struct route_entry *r1,
         * backups will be in the 'fib' list.
         */
        nhg1 = rib_get_fib_backup_nhg(r1);
-       if (nhg1 == zebra_nhg_get_backup_nhg(r1->nhe))
-               nhg1 = NULL;
-
        nhg2 = rib_get_fib_backup_nhg(r2);
-       if (nhg2 == zebra_nhg_get_backup_nhg(r2->nhe))
-               nhg2 = NULL;
-
-       if (nhg1)
-               nh1 = nhg1->nexthop;
-       else
-               nh1 = NULL;
 
-       if (nhg2)
-               nh2 = nhg2->nexthop;
-       else
-               nh2 = NULL;
+       nh1 = nhg1->nexthop;
+       nh2 = nhg2->nexthop;
 
        while (1) {
                /* Find each backup list's next valid nexthop */
@@ -1119,8 +1108,9 @@ static int compare_state(struct route_entry *r1, struct route_entry *r2)
        return 0;
 }
 
-static int send_client(struct rnh *rnh, struct zserv *client,
-                      enum rnh_type type, vrf_id_t vrf_id)
+int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
+                         enum rnh_type type, vrf_id_t vrf_id,
+                         uint32_t srte_color)
 {
        struct stream *s = NULL;
        struct route_entry *re;
@@ -1129,6 +1119,7 @@ static int send_client(struct rnh *rnh, struct zserv *client,
        struct nexthop *nh;
        struct route_node *rn;
        int ret;
+       uint32_t message = 0;
        int cmd = (type == RNH_IMPORT_CHECK_TYPE) ? ZEBRA_IMPORT_CHECK_UPDATE
                                                  : ZEBRA_NEXTHOP_UPDATE;
 
@@ -1140,6 +1131,11 @@ static int send_client(struct rnh *rnh, struct zserv *client,
 
        zclient_create_header(s, cmd, vrf_id);
 
+       /* Message flags. */
+       if (srte_color)
+               SET_FLAG(message, ZAPI_MESSAGE_SRTE);
+       stream_putl(s, message);
+
        stream_putw(s, rn->p.family);
        switch (rn->p.family) {
        case AF_INET:
@@ -1156,6 +1152,9 @@ static int send_client(struct rnh *rnh, struct zserv *client,
                         __func__, rn->p.family);
                goto failure;
        }
+       if (srte_color)
+               stream_putl(s, srte_color);
+
        if (re) {
                struct zapi_nexthop znh;
                struct nexthop_group *nhg;
@@ -1172,7 +1171,7 @@ static int send_client(struct rnh *rnh, struct zserv *client,
                for (ALL_NEXTHOPS_PTR(nhg, nh))
                        if (rnh_nexthop_valid(re, nh)) {
                                zapi_nexthop_from_nexthop(&znh, nh);
-                               ret = zapi_nexthop_encode(s, &znh, 0/*flags*/);
+                               ret = zapi_nexthop_encode(s, &znh, 0, message);
                                if (ret < 0)
                                        goto failure;
 
@@ -1180,15 +1179,16 @@ static int send_client(struct rnh *rnh, struct zserv *client,
                        }
 
                nhg = rib_get_fib_backup_nhg(re);
-               if (nhg == zebra_nhg_get_backup_nhg(re->nhe))
-                       nhg = NULL;
-
                if (nhg) {
                        for (ALL_NEXTHOPS_PTR(nhg, nh))
                                if (rnh_nexthop_valid(re, nh)) {
                                        zapi_nexthop_from_nexthop(&znh, nh);
-                                       zapi_nexthop_encode(s, &znh,
-                                                           0 /* flags */);
+                                       ret = zapi_nexthop_encode(
+                                               s, &znh, 0 /* flags */,
+                                               0 /* message */);
+                                       if (ret < 0)
+                                               goto failure;
+
                                        num++;
                                }
                }