]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zapi_msg.c
Merge pull request #3031 from pacovn/static_analysis__Wcomma
[mirror_frr.git] / zebra / zapi_msg.c
index c16fa70857d5ac162291e5e406e1a80a5b0e5b3d..55c5b934fc2f773a28f5a084d2742950f20c4d4c 100644 (file)
@@ -62,6 +62,7 @@
 #include "zebra/zebra_pbr.h"
 #include "zebra/table_manager.h"
 #include "zebra/zapi_msg.h"
+#include "zebra/zebra_errors.h"
 
 /* Encoding helpers -------------------------------------------------------- */
 
@@ -1022,6 +1023,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
        unsigned short l = 0;
        uint8_t flags = 0;
        uint16_t type = cmd2type[hdr->command];
+       bool exist;
 
        if (IS_ZEBRA_DEBUG_NHT)
                zlog_debug(
@@ -1041,7 +1043,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
                l += 4;
                if (p.family == AF_INET) {
                        if (p.prefixlen > IPV4_MAX_BITLEN) {
-                               zlog_warn(
+                               zlog_debug(
                                        "%s: Specified prefix hdr->length %d is too large for a v4 address",
                                        __PRETTY_FUNCTION__, p.prefixlen);
                                return;
@@ -1050,7 +1052,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
                        l += IPV4_MAX_BYTELEN;
                } else if (p.family == AF_INET6) {
                        if (p.prefixlen > IPV6_MAX_BITLEN) {
-                               zlog_warn(
+                               zlog_debug(
                                        "%s: Specified prefix hdr->length %d is to large for a v6 address",
                                        __PRETTY_FUNCTION__, p.prefixlen);
                                return;
@@ -1058,12 +1060,16 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
                        STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
                        l += IPV6_MAX_BYTELEN;
                } else {
-                       zlog_err(
+                       flog_err(
+                               EC_ZEBRA_UNKNOWN_FAMILY,
                                "rnh_register: Received unknown family type %d\n",
                                p.family);
                        return;
                }
-               rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type);
+               rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type, &exist);
+               if (!rnh)
+                       return;
+
                if (type == RNH_NEXTHOP_TYPE) {
                        if (flags
                            && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
@@ -1083,7 +1089,9 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
 
                zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
                /* Anything not AF_INET/INET6 has been filtered out above */
-               zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p);
+               if (!exist)
+                       zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type,
+                                          &p);
        }
 
 stream_failure:
@@ -1119,7 +1127,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
                l += 4;
                if (p.family == AF_INET) {
                        if (p.prefixlen > IPV4_MAX_BITLEN) {
-                               zlog_warn(
+                               zlog_debug(
                                        "%s: Specified prefix hdr->length %d is to large for a v4 address",
                                        __PRETTY_FUNCTION__, p.prefixlen);
                                return;
@@ -1128,7 +1136,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
                        l += IPV4_MAX_BYTELEN;
                } else if (p.family == AF_INET6) {
                        if (p.prefixlen > IPV6_MAX_BITLEN) {
-                               zlog_warn(
+                               zlog_debug(
                                        "%s: Specified prefix hdr->length %d is to large for a v6 address",
                                        __PRETTY_FUNCTION__, p.prefixlen);
                                return;
@@ -1136,7 +1144,8 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
                        STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
                        l += IPV6_MAX_BYTELEN;
                } else {
-                       zlog_err(
+                       flog_err(
+                               EC_ZEBRA_UNKNOWN_FAMILY,
                                "rnh_register: Received unknown family type %d\n",
                                p.family);
                        return;
@@ -1172,7 +1181,8 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS)
         * registration
         */
        if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
-               zlog_err(
+               flog_err(
+                       EC_ZEBRA_IRDP_LEN_MISMATCH,
                        "fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode",
                        hdr->length);
                return;
@@ -1183,7 +1193,8 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS)
                memset(&p, 0, sizeof(p));
                STREAM_GETW(s, p.family);
                if (p.family != AF_INET && p.family != AF_INET6) {
-                       zlog_err(
+                       flog_err(
+                               EC_ZEBRA_UNKNOWN_FAMILY,
                                "fec_register: Received unknown family type %d\n",
                                p.family);
                        return;
@@ -1192,7 +1203,7 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS)
                if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
                    || (p.family == AF_INET6
                        && p.prefixlen > IPV6_MAX_BITLEN)) {
-                       zlog_warn(
+                       zlog_debug(
                                "%s: Specified prefix hdr->length: %d is to long for %d",
                                __PRETTY_FUNCTION__, p.prefixlen, p.family);
                        return;
@@ -1230,7 +1241,8 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS)
         * fec unregistration
         */
        if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
-               zlog_err(
+               flog_err(
+                       EC_ZEBRA_IRDP_LEN_MISMATCH,
                        "fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode",
                        hdr->length);
                return;
@@ -1244,7 +1256,8 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS)
                memset(&p, 0, sizeof(p));
                STREAM_GETW(s, p.family);
                if (p.family != AF_INET && p.family != AF_INET6) {
-                       zlog_err(
+                       flog_err(
+                               EC_ZEBRA_UNKNOWN_FAMILY,
                                "fec_unregister: Received unknown family type %d\n",
                                p.family);
                        return;
@@ -1253,7 +1266,7 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS)
                if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
                    || (p.family == AF_INET6
                        && p.prefixlen > IPV6_MAX_BITLEN)) {
-                       zlog_warn(
+                       zlog_debug(
                                "%s: Received prefix hdr->length %d which is greater than %d can support",
                                __PRETTY_FUNCTION__, p.prefixlen, p.family);
                        return;
@@ -1306,7 +1319,8 @@ void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
                char buff[PREFIX2STR_BUFFER];
 
                prefix2str(p, buff, sizeof(buff));
-               zlog_warn(
+               flog_warn(
+                       EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
                        "%s: Prefix %s has %d nexthops, but we can only use the first %d",
                        caller, buff, nexthop_num, multipath_num);
        }
@@ -1469,7 +1483,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
                        }
 
                        if (!nexthop) {
-                               zlog_warn(
+                               flog_warn(
+                                       EC_ZEBRA_NEXTHOP_CREATION_FAILED,
                                        "%s: Nexthops Specified: %d but we failed to properly create one",
                                        __PRETTY_FUNCTION__, api.nexthop_num);
                                nexthops_free(re->ng.nexthop);
@@ -1509,7 +1524,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
 
        afi = family2afi(api.prefix.family);
        if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
-               zlog_warn("%s: Received SRC Prefix but afi is not v6",
+               flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+                         "%s: Received SRC Prefix but afi is not v6",
                          __PRETTY_FUNCTION__);
                nexthops_free(re->ng.nexthop);
                XFREE(MTYPE_RE, re);
@@ -1551,7 +1567,8 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
 
        afi = family2afi(api.prefix.family);
        if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
-               zlog_warn("%s: Received a src prefix while afi is not v6",
+               flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+                         "%s: Received a src prefix while afi is not v6",
                          __PRETTY_FUNCTION__);
                return;
        }
@@ -1565,7 +1582,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
 
        rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
                   api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
-                  false);
+                  api.distance, false);
 
        /* Stats */
        switch (api.prefix.family) {
@@ -1578,202 +1595,6 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
        }
 }
 
-/* This function support multiple nexthop. */
-/*
- * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update re and
- * add kernel route.
- */
-static void zread_ipv4_add(ZAPI_HANDLER_ARGS)
-{
-       int i;
-       struct route_entry *re;
-       struct prefix p;
-       uint8_t message;
-       struct in_addr nhop_addr;
-       uint8_t nexthop_num;
-       uint8_t nexthop_type;
-       struct stream *s;
-       ifindex_t ifindex;
-       safi_t safi;
-       int ret;
-       enum lsp_types_t label_type = ZEBRA_LSP_NONE;
-       mpls_label_t label;
-       struct nexthop *nexthop;
-       enum blackhole_type bh_type = BLACKHOLE_NULL;
-
-       /* Get input stream.  */
-       s = msg;
-
-       /* Allocate new re. */
-       re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
-
-       /* Type, flags, message. */
-       STREAM_GETC(s, re->type);
-       if (re->type > ZEBRA_ROUTE_MAX) {
-               zlog_warn("%s: Specified route type %d is not a legal value\n",
-                         __PRETTY_FUNCTION__, re->type);
-               XFREE(MTYPE_RE, re);
-               return;
-       }
-       STREAM_GETW(s, re->instance);
-       STREAM_GETL(s, re->flags);
-       STREAM_GETC(s, message);
-       STREAM_GETW(s, safi);
-       re->uptime = time(NULL);
-
-       /* IPv4 prefix. */
-       memset(&p, 0, sizeof(struct prefix_ipv4));
-       p.family = AF_INET;
-       STREAM_GETC(s, p.prefixlen);
-       if (p.prefixlen > IPV4_MAX_BITLEN) {
-               zlog_warn(
-                       "%s: Specified prefix length %d is greater than what v4 can be",
-                       __PRETTY_FUNCTION__, p.prefixlen);
-               XFREE(MTYPE_RE, re);
-               return;
-       }
-       STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
-
-       /* VRF ID */
-       re->vrf_id = zvrf_id(zvrf);
-
-       /* Nexthop parse. */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) {
-               STREAM_GETC(s, nexthop_num);
-               zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
-                                      nexthop_num);
-
-               if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
-                       label_type = lsp_type_from_re_type(client->proto);
-
-               for (i = 0; i < nexthop_num; i++) {
-                       STREAM_GETC(s, nexthop_type);
-
-                       switch (nexthop_type) {
-                       case NEXTHOP_TYPE_IFINDEX:
-                               STREAM_GETL(s, ifindex);
-                               route_entry_nexthop_ifindex_add(re, ifindex,
-                                                               re->vrf_id);
-                               break;
-                       case NEXTHOP_TYPE_IPV4:
-                               STREAM_GET(&nhop_addr.s_addr, s,
-                                          IPV4_MAX_BYTELEN);
-                               nexthop = route_entry_nexthop_ipv4_add(
-                                       re, &nhop_addr, NULL, re->vrf_id);
-                               /*
-                                * For labeled-unicast, each nexthop is followed
-                                * by the label.
-                                */
-                               if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) {
-                                       STREAM_GETL(s, label);
-                                       nexthop_add_labels(nexthop, label_type,
-                                                          1, &label);
-                               }
-                               break;
-                       case NEXTHOP_TYPE_IPV4_IFINDEX:
-                               STREAM_GET(&nhop_addr.s_addr, s,
-                                          IPV4_MAX_BYTELEN);
-                               STREAM_GETL(s, ifindex);
-                               route_entry_nexthop_ipv4_ifindex_add(
-                                       re, &nhop_addr, NULL, ifindex,
-                                       re->vrf_id);
-                               break;
-                       case NEXTHOP_TYPE_IPV6:
-                               zlog_warn(
-                                       "%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops",
-                                       __PRETTY_FUNCTION__);
-                               nexthops_free(re->ng.nexthop);
-                               XFREE(MTYPE_RE, re);
-                               return;
-                       case NEXTHOP_TYPE_BLACKHOLE:
-                               route_entry_nexthop_blackhole_add(re, bh_type);
-                               break;
-                       default:
-                               zlog_warn(
-                                       "%s: Specified nexthop type: %d does not exist",
-                                       __PRETTY_FUNCTION__, nexthop_type);
-                               nexthops_free(re->ng.nexthop);
-                               XFREE(MTYPE_RE, re);
-                               return;
-                       }
-               }
-       }
-
-       /* Distance. */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
-               STREAM_GETC(s, re->distance);
-
-       /* Metric. */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
-               STREAM_GETL(s, re->metric);
-
-       /* Tag */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
-               STREAM_GETL(s, re->tag);
-       else
-               re->tag = 0;
-
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
-               STREAM_GETL(s, re->mtu);
-       else
-               re->mtu = 0;
-
-       /* Table */
-       re->table = zvrf->table_id;
-
-       ret = rib_add_multipath(AFI_IP, safi, &p, NULL, re);
-
-       /* Stats */
-       if (ret > 0)
-               client->v4_route_add_cnt++;
-       else if (ret < 0)
-               client->v4_route_upd8_cnt++;
-
-       return;
-
-stream_failure:
-       nexthops_free(re->ng.nexthop);
-       XFREE(MTYPE_RE, re);
-}
-
-/* Zebra server IPv4 prefix delete function. */
-static void zread_ipv4_delete(ZAPI_HANDLER_ARGS)
-{
-       struct stream *s;
-       struct zapi_ipv4 api;
-       struct prefix p;
-       uint32_t table_id;
-
-       s = msg;
-
-       /* Type, flags, message. */
-       STREAM_GETC(s, api.type);
-       STREAM_GETW(s, api.instance);
-       STREAM_GETL(s, api.flags);
-       STREAM_GETC(s, api.message);
-       STREAM_GETW(s, api.safi);
-
-       /* IPv4 prefix. */
-       memset(&p, 0, sizeof(struct prefix));
-       p.family = AF_INET;
-       STREAM_GETC(s, p.prefixlen);
-       if (p.prefixlen > IPV4_MAX_BITLEN) {
-               zlog_warn("%s: Passed in prefixlen %d is impossible",
-                         __PRETTY_FUNCTION__, p.prefixlen);
-               return;
-       }
-       STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
-
-       table_id = zvrf->table_id;
-
-       rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, NULL, NULL, table_id, 0, false);
-       client->v4_route_del_cnt++;
-
-stream_failure:
-       return;
-}
-
 /* MRIB Nexthop lookup for IPv4. */
 static void zread_ipv4_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS)
 {
@@ -1788,417 +1609,6 @@ stream_failure:
        return;
 }
 
-/* Zebra server IPv6 prefix add function. */
-static void zread_ipv4_route_ipv6_nexthop_add(ZAPI_HANDLER_ARGS)
-{
-       unsigned int i;
-       struct stream *s;
-       struct in6_addr nhop_addr;
-       struct route_entry *re;
-       uint8_t message;
-       uint8_t nexthop_num;
-       uint8_t nexthop_type;
-       struct prefix p;
-       safi_t safi;
-       static struct in6_addr nexthops[MULTIPATH_NUM];
-       static unsigned int ifindices[MULTIPATH_NUM];
-       int ret;
-       static mpls_label_t labels[MULTIPATH_NUM];
-       enum lsp_types_t label_type = ZEBRA_LSP_NONE;
-       mpls_label_t label;
-       struct nexthop *nexthop;
-       enum blackhole_type bh_type = BLACKHOLE_NULL;
-
-       /* Get input stream.  */
-       s = msg;
-
-       memset(&nhop_addr, 0, sizeof(struct in6_addr));
-
-       /* Allocate new re. */
-       re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
-
-       /* Type, flags, message. */
-       STREAM_GETC(s, re->type);
-       if (re->type > ZEBRA_ROUTE_MAX) {
-               zlog_warn("%s: Specified route type: %d is not a legal value\n",
-                         __PRETTY_FUNCTION__, re->type);
-               XFREE(MTYPE_RE, re);
-               return;
-       }
-       STREAM_GETW(s, re->instance);
-       STREAM_GETL(s, re->flags);
-       STREAM_GETC(s, message);
-       STREAM_GETW(s, safi);
-       re->uptime = time(NULL);
-
-       /* IPv4 prefix. */
-       memset(&p, 0, sizeof(struct prefix_ipv4));
-       p.family = AF_INET;
-       STREAM_GETC(s, p.prefixlen);
-       if (p.prefixlen > IPV4_MAX_BITLEN) {
-               zlog_warn(
-                       "%s: Prefix Length %d is greater than what a v4 address can use",
-                       __PRETTY_FUNCTION__, p.prefixlen);
-               XFREE(MTYPE_RE, re);
-               return;
-       }
-       STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
-
-       /* VRF ID */
-       re->vrf_id = zvrf_id(zvrf);
-
-       /*
-        * We need to give nh-addr, nh-ifindex with the same next-hop object
-        * to the re to ensure that IPv6 multipathing works; need to coalesce
-        * these. Clients should send the same number of paired set of
-        * next-hop-addr/next-hop-ifindices.
-        */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) {
-               unsigned int nh_count = 0;
-               unsigned int if_count = 0;
-               unsigned int max_nh_if = 0;
-
-               STREAM_GETC(s, nexthop_num);
-               zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
-                                      nexthop_num);
-
-               if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
-                       label_type = lsp_type_from_re_type(client->proto);
-
-               for (i = 0; i < nexthop_num; i++) {
-                       STREAM_GETC(s, nexthop_type);
-
-                       switch (nexthop_type) {
-                       case NEXTHOP_TYPE_IPV6:
-                               STREAM_GET(&nhop_addr, s, 16);
-                               if (nh_count < MULTIPATH_NUM) {
-                                       /*
-                                        * For labeled-unicast, each nexthop is
-                                        * followed by the label.
-                                        */
-                                       if (CHECK_FLAG(message,
-                                                      ZAPI_MESSAGE_LABEL)) {
-                                               STREAM_GETL(s, label);
-                                               labels[nh_count] = label;
-                                       }
-                                       nexthops[nh_count] = nhop_addr;
-                                       nh_count++;
-                               }
-                               break;
-                       case NEXTHOP_TYPE_IFINDEX:
-                               if (if_count < multipath_num)
-                                       STREAM_GETL(s, ifindices[if_count++]);
-                               break;
-                       case NEXTHOP_TYPE_BLACKHOLE:
-                               route_entry_nexthop_blackhole_add(re, bh_type);
-                               break;
-                       default:
-                               zlog_warn(
-                                       "%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
-                                       __PRETTY_FUNCTION__);
-                               nexthops_free(re->ng.nexthop);
-                               XFREE(MTYPE_RE, re);
-                               return;
-                       }
-               }
-
-               max_nh_if = (nh_count > if_count) ? nh_count : if_count;
-               for (i = 0; i < max_nh_if; i++) {
-                       if ((i < nh_count)
-                           && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) {
-                               if ((i < if_count) && ifindices[i])
-                                       nexthop =
-                                               route_entry_nexthop_ipv6_ifindex_add(
-                                                       re, &nexthops[i],
-                                                       ifindices[i],
-                                                       re->vrf_id);
-                               else
-                                       nexthop = route_entry_nexthop_ipv6_add(
-                                               re, &nexthops[i], re->vrf_id);
-
-                               if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
-                                       nexthop_add_labels(nexthop, label_type,
-                                                          1, &labels[i]);
-                       } else {
-                               if ((i < if_count) && ifindices[i])
-                                       route_entry_nexthop_ifindex_add(
-                                               re, ifindices[i], re->vrf_id);
-                       }
-               }
-       }
-
-       /* Distance. */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
-               STREAM_GETC(s, re->distance);
-
-       /* Metric. */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
-               STREAM_GETL(s, re->metric);
-
-       /* Tag */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
-               STREAM_GETL(s, re->tag);
-       else
-               re->tag = 0;
-
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
-               STREAM_GETL(s, re->mtu);
-       else
-               re->mtu = 0;
-
-       /* Table */
-       re->table = zvrf->table_id;
-
-       ret = rib_add_multipath(AFI_IP6, safi, &p, NULL, re);
-       /* Stats */
-       if (ret > 0)
-               client->v4_route_add_cnt++;
-       else if (ret < 0)
-               client->v4_route_upd8_cnt++;
-
-       return;
-
-stream_failure:
-       nexthops_free(re->ng.nexthop);
-       XFREE(MTYPE_RE, re);
-}
-
-static void zread_ipv6_add(ZAPI_HANDLER_ARGS)
-{
-       unsigned int i;
-       struct stream *s;
-       struct in6_addr nhop_addr;
-       ifindex_t ifindex;
-       struct route_entry *re;
-       uint8_t message;
-       uint8_t nexthop_num;
-       uint8_t nexthop_type;
-       struct prefix p;
-       struct prefix_ipv6 src_p, *src_pp;
-       safi_t safi;
-       static struct in6_addr nexthops[MULTIPATH_NUM];
-       static unsigned int ifindices[MULTIPATH_NUM];
-       int ret;
-       static mpls_label_t labels[MULTIPATH_NUM];
-       enum lsp_types_t label_type = ZEBRA_LSP_NONE;
-       mpls_label_t label;
-       struct nexthop *nexthop;
-       enum blackhole_type bh_type = BLACKHOLE_NULL;
-
-       /* Get input stream.  */
-       s = msg;
-
-       memset(&nhop_addr, 0, sizeof(struct in6_addr));
-
-       /* Allocate new re. */
-       re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
-
-       /* Type, flags, message. */
-       STREAM_GETC(s, re->type);
-       if (re->type > ZEBRA_ROUTE_MAX) {
-               zlog_warn("%s: Specified route type: %d is not a legal value\n",
-                         __PRETTY_FUNCTION__, re->type);
-               XFREE(MTYPE_RE, re);
-               return;
-       }
-       STREAM_GETW(s, re->instance);
-       STREAM_GETL(s, re->flags);
-       STREAM_GETC(s, message);
-       STREAM_GETW(s, safi);
-       re->uptime = time(NULL);
-
-       /* IPv6 prefix. */
-       memset(&p, 0, sizeof(p));
-       p.family = AF_INET6;
-       STREAM_GETC(s, p.prefixlen);
-       if (p.prefixlen > IPV6_MAX_BITLEN) {
-               zlog_warn(
-                       "%s: Specified prefix length %d is to large for v6 prefix",
-                       __PRETTY_FUNCTION__, p.prefixlen);
-               XFREE(MTYPE_RE, re);
-               return;
-       }
-       STREAM_GET(&p.u.prefix6, s, PSIZE(p.prefixlen));
-
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) {
-               memset(&src_p, 0, sizeof(src_p));
-               src_p.family = AF_INET6;
-               STREAM_GETC(s, src_p.prefixlen);
-               if (src_p.prefixlen > IPV6_MAX_BITLEN) {
-                       zlog_warn(
-                               "%s: Specified src prefix length %d is to large for v6 prefix",
-                               __PRETTY_FUNCTION__, src_p.prefixlen);
-                       XFREE(MTYPE_RE, re);
-                       return;
-               }
-               STREAM_GET(&src_p.prefix, s, PSIZE(src_p.prefixlen));
-               src_pp = &src_p;
-       } else
-               src_pp = NULL;
-
-       /* VRF ID */
-       re->vrf_id = zvrf_id(zvrf);
-
-       /*
-        * We need to give nh-addr, nh-ifindex with the same next-hop object
-        * to the re to ensure that IPv6 multipathing works; need to coalesce
-        * these. Clients should send the same number of paired set of
-        * next-hop-addr/next-hop-ifindices.
-        */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) {
-               unsigned int nh_count = 0;
-               unsigned int if_count = 0;
-               unsigned int max_nh_if = 0;
-
-               STREAM_GETC(s, nexthop_num);
-               zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
-                                      nexthop_num);
-
-               if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
-                       label_type = lsp_type_from_re_type(client->proto);
-
-               for (i = 0; i < nexthop_num; i++) {
-                       STREAM_GETC(s, nexthop_type);
-
-                       switch (nexthop_type) {
-                       case NEXTHOP_TYPE_IPV6:
-                               STREAM_GET(&nhop_addr, s, 16);
-                               if (nh_count < MULTIPATH_NUM) {
-                                       /*
-                                        * For labeled-unicast, each nexthop is
-                                        * followed by label.
-                                        */
-                                       if (CHECK_FLAG(message,
-                                                      ZAPI_MESSAGE_LABEL)) {
-                                               STREAM_GETL(s, label);
-                                               labels[nh_count] = label;
-                                       }
-                                       nexthops[nh_count++] = nhop_addr;
-                               }
-                               break;
-                       case NEXTHOP_TYPE_IPV6_IFINDEX:
-                               STREAM_GET(&nhop_addr, s, 16);
-                               STREAM_GETL(s, ifindex);
-                               route_entry_nexthop_ipv6_ifindex_add(
-                                       re, &nhop_addr, ifindex, re->vrf_id);
-                               break;
-                       case NEXTHOP_TYPE_IFINDEX:
-                               if (if_count < multipath_num)
-                                       STREAM_GETL(s, ifindices[if_count++]);
-                               break;
-                       case NEXTHOP_TYPE_BLACKHOLE:
-                               route_entry_nexthop_blackhole_add(re, bh_type);
-                               break;
-                       default:
-                               zlog_warn(
-                                       "%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
-                                       __PRETTY_FUNCTION__);
-                               nexthops_free(re->ng.nexthop);
-                               XFREE(MTYPE_RE, re);
-                               return;
-                       }
-               }
-
-               max_nh_if = (nh_count > if_count) ? nh_count : if_count;
-               for (i = 0; i < max_nh_if; i++) {
-                       if ((i < nh_count)
-                           && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) {
-                               if ((i < if_count) && ifindices[i])
-                                       nexthop =
-                                               route_entry_nexthop_ipv6_ifindex_add(
-                                                       re, &nexthops[i],
-                                                       ifindices[i],
-                                                       re->vrf_id);
-                               else
-                                       nexthop = route_entry_nexthop_ipv6_add(
-                                               re, &nexthops[i], re->vrf_id);
-                               if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
-                                       nexthop_add_labels(nexthop, label_type,
-                                                          1, &labels[i]);
-                       } else {
-                               if ((i < if_count) && ifindices[i])
-                                       route_entry_nexthop_ifindex_add(
-                                               re, ifindices[i], re->vrf_id);
-                       }
-               }
-       }
-
-       /* Distance. */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
-               STREAM_GETC(s, re->distance);
-
-       /* Metric. */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
-               STREAM_GETL(s, re->metric);
-
-       /* Tag */
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
-               STREAM_GETL(s, re->tag);
-       else
-               re->tag = 0;
-
-       if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
-               STREAM_GETL(s, re->mtu);
-       else
-               re->mtu = 0;
-
-       re->table = zvrf->table_id;
-
-       ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re);
-       /* Stats */
-       if (ret > 0)
-               client->v6_route_add_cnt++;
-       else if (ret < 0)
-               client->v6_route_upd8_cnt++;
-
-       return;
-
-stream_failure:
-       nexthops_free(re->ng.nexthop);
-       XFREE(MTYPE_RE, re);
-}
-
-/* Zebra server IPv6 prefix delete function. */
-static void zread_ipv6_delete(ZAPI_HANDLER_ARGS)
-{
-       struct stream *s;
-       struct zapi_ipv6 api;
-       struct prefix p;
-       struct prefix_ipv6 src_p, *src_pp;
-
-       s = msg;
-
-       /* Type, flags, message. */
-       STREAM_GETC(s, api.type);
-       STREAM_GETW(s, api.instance);
-       STREAM_GETL(s, api.flags);
-       STREAM_GETC(s, api.message);
-       STREAM_GETW(s, api.safi);
-
-       /* IPv4 prefix. */
-       memset(&p, 0, sizeof(struct prefix));
-       p.family = AF_INET6;
-       STREAM_GETC(s, p.prefixlen);
-       STREAM_GET(&p.u.prefix6, s, PSIZE(p.prefixlen));
-
-       if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
-               memset(&src_p, 0, sizeof(struct prefix_ipv6));
-               src_p.family = AF_INET6;
-               STREAM_GETC(s, src_p.prefixlen);
-               STREAM_GET(&src_p.prefix, s, PSIZE(src_p.prefixlen));
-               src_pp = &src_p;
-       } else
-               src_pp = NULL;
-
-       rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
-
-       client->v6_route_del_cnt++;
-
-stream_failure:
-       return;
-}
-
 /* Register zebra server router-id information.  Send current router-id */
 static void zread_router_id_add(ZAPI_HANDLER_ARGS)
 {
@@ -2245,7 +1655,7 @@ static void zread_hello(ZAPI_HANDLER_ARGS)
                client->notify_owner = true;
 
        /* accept only dynamic routing protocols */
-       if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) {
+       if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_CONNECT)) {
                zlog_notice(
                        "client %d says hello and bids fair to announce only %s routes vrf=%u",
                        client->sock, zebra_route_string(proto),
@@ -2298,7 +1708,7 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
                STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
                STREAM_GETC(s, prefix.prefixlen);
                if (prefix.prefixlen > IPV4_MAX_BITLEN) {
-                       zlog_warn(
+                       zlog_debug(
                                "%s: Specified prefix length %d is greater than a v4 address can support",
                                __PRETTY_FUNCTION__, prefix.prefixlen);
                        return;
@@ -2309,7 +1719,7 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
                STREAM_GET(&prefix.u.prefix6, s, 16);
                STREAM_GETC(s, prefix.prefixlen);
                if (prefix.prefixlen > IPV6_MAX_BITLEN) {
-                       zlog_warn(
+                       zlog_debug(
                                "%s: Specified prefix length %d is greater than a v6 address can support",
                                __PRETTY_FUNCTION__, prefix.prefixlen);
                        return;
@@ -2317,8 +1727,8 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
                STREAM_GET(&gate.ipv6, s, 16);
                break;
        default:
-               zlog_warn("%s: Specified AF %d is not supported for this call",
-                         __PRETTY_FUNCTION__, prefix.family);
+               zlog_debug("%s: Specified AF %d is not supported for this call",
+                          __PRETTY_FUNCTION__, prefix.family);
                return;
        }
        STREAM_GETL(s, ifindex);
@@ -2376,7 +1786,8 @@ static void zread_table_manager_connect(struct zserv *client,
 
        /* accept only dynamic routing protocols */
        if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
-               zlog_err("client %d has wrong protocol %s", client->sock,
+               flog_err(EC_ZEBRA_TM_WRONG_PROTO,
+                        "client %d has wrong protocol %s", client->sock,
                         zebra_route_string(proto));
                zsend_table_manager_connect_response(client, vrf_id, 1);
                return;
@@ -2415,7 +1826,8 @@ static void zread_label_manager_connect(struct zserv *client,
 
        /* accept only dynamic routing protocols */
        if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
-               zlog_err("client %d has wrong protocol %s", client->sock,
+               flog_err(EC_ZEBRA_TM_WRONG_PROTO,
+                        "client %d has wrong protocol %s", client->sock,
                         zebra_route_string(proto));
                zsend_label_manager_connect_response(client, vrf_id, 1);
                return;
@@ -2444,14 +1856,16 @@ static int msg_client_id_mismatch(const char *op, struct zserv *client,
                                  uint8_t proto, unsigned int instance)
 {
        if (proto != client->proto) {
-               zlog_err("%s: msg vs client proto mismatch, client=%u msg=%u",
+               flog_err(EC_ZEBRA_PROTO_OR_INSTANCE_MISMATCH,
+                        "%s: msg vs client proto mismatch, client=%u msg=%u",
                         op, client->proto, proto);
                /* TODO: fail when BGP sets proto and instance */
                /* return 1; */
        }
 
        if (instance != client->instance) {
-               zlog_err(
+               flog_err(
+                       EC_ZEBRA_PROTO_OR_INSTANCE_MISMATCH,
                        "%s: msg vs client instance mismatch, client=%u msg=%u",
                        op, client->instance, instance);
                /* TODO: fail when BGP sets proto and instance */
@@ -2486,7 +1900,8 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
 
        lmc = assign_label_chunk(client->proto, client->instance, keep, size);
        if (!lmc)
-               zlog_err(
+               flog_err(
+                       EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK,
                        "Unable to assign Label Chunk of size %u to %s instance %u",
                        size, zebra_route_string(client->proto),
                        client->instance);
@@ -2544,7 +1959,8 @@ static void zread_label_manager_request(ZAPI_HANDLER_ARGS)
                else {
                        /* Sanity: don't allow 'unidentified' requests */
                        if (!client->proto) {
-                               zlog_err(
+                               flog_err(
+                                       EC_ZEBRA_LM_ALIENS,
                                        "Got label request from an unidentified client");
                                return;
                        }
@@ -2572,7 +1988,8 @@ static void zread_get_table_chunk(struct zserv *client, struct stream *msg,
 
        tmc = assign_table_chunk(client->proto, client->instance, size);
        if (!tmc)
-               zlog_err("%s: Unable to assign Table Chunk of size %u",
+               flog_err(EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
+                        "%s: Unable to assign Table Chunk of size %u",
                         __func__, size);
        else
                zlog_debug("Assigned Table Chunk %u - %u", tmc->start,
@@ -2610,7 +2027,8 @@ static void zread_table_manager_request(ZAPI_HANDLER_ARGS)
        else {
                /* Sanity: don't allow 'unidentified' requests */
                if (!client->proto) {
-                       zlog_err(
+                       flog_err(
+                               EC_ZEBRA_TM_ALIENS,
                                "Got table request from an unidentified client");
                        return;
                }
@@ -2664,7 +2082,8 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS)
        switch (hdr->command) {
        case ZEBRA_PW_ADD:
                if (pw) {
-                       zlog_warn("%s: pseudowire %s already exists [%s]",
+                       flog_warn(EC_ZEBRA_PSEUDOWIRE_EXISTS,
+                                 "%s: pseudowire %s already exists [%s]",
                                  __func__, ifname,
                                  zserv_command_string(hdr->command));
                        return;
@@ -2674,7 +2093,8 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS)
                break;
        case ZEBRA_PW_DELETE:
                if (!pw) {
-                       zlog_warn("%s: pseudowire %s not found [%s]", __func__,
+                       flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+                                 "%s: pseudowire %s not found [%s]", __func__,
                                  ifname, zserv_command_string(hdr->command));
                        return;
                }
@@ -2684,7 +2104,8 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS)
        case ZEBRA_PW_SET:
        case ZEBRA_PW_UNSET:
                if (!pw) {
-                       zlog_warn("%s: pseudowire %s not found [%s]", __func__,
+                       flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+                                 "%s: pseudowire %s not found [%s]", __func__,
                                  ifname, zserv_command_string(hdr->command));
                        return;
                }
@@ -2997,11 +2418,6 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
        [ZEBRA_INTERFACE_DELETE] = zread_interface_delete,
        [ZEBRA_ROUTE_ADD] = zread_route_add,
        [ZEBRA_ROUTE_DELETE] = zread_route_del,
-       [ZEBRA_IPV4_ROUTE_ADD] = zread_ipv4_add,
-       [ZEBRA_IPV4_ROUTE_DELETE] = zread_ipv4_delete,
-       [ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD] = zread_ipv4_route_ipv6_nexthop_add,
-       [ZEBRA_IPV6_ROUTE_ADD] = zread_ipv6_add,
-       [ZEBRA_IPV6_ROUTE_DELETE] = zread_ipv6_delete,
        [ZEBRA_REDISTRIBUTE_ADD] = zebra_redistribute_add,
        [ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete,
        [ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add,
@@ -3015,6 +2431,9 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
        [ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register,
        [ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register,
        [ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister,
+#if HAVE_BFDD > 0
+       [ZEBRA_BFD_DEST_REPLAY] = zebra_ptm_bfd_dst_replay,
+#endif /* HAVE_BFDD */
        [ZEBRA_VRF_UNREGISTER] = zread_vrf_unregister,
        [ZEBRA_VRF_LABEL] = zread_vrf_label,
        [ZEBRA_BFD_CLIENT_REGISTER] = zebra_ptm_bfd_client_register,
@@ -3070,12 +2489,13 @@ static void zserv_write_incoming(struct stream *orig, uint16_t command)
        copy = stream_dup(orig);
        stream_set_getp(copy, 0);
 
-       zserv_privs.change(ZPRIVS_RAISE);
        snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
-       fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+
+       frr_elevate_privs(&zserv_privs) {
+               fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+       }
        stream_flush(copy, fd);
        close(fd);
-       zserv_privs.change(ZPRIVS_LOWER);
        stream_free(copy);
 }
 #endif
@@ -3097,8 +2517,8 @@ void zserv_handle_commands(struct zserv *client, struct stream *msg)
        zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
        if (!zvrf) {
                if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
-                       zlog_warn("ZAPI message specifies unknown VRF: %d",
-                                 hdr.vrf_id);
+                       zlog_debug("ZAPI message specifies unknown VRF: %d",
+                                  hdr.vrf_id);
                return;
        }