]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/zclient.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / zclient.c
index cc91705ee227c8fd1565328cf050b230e635895a..d2a6c75548f41698834c1ec3efacc1f6eff85e9a 100644 (file)
@@ -58,8 +58,8 @@ int zclient_debug = 0;
 struct zclient_options zclient_options_default = {.receive_notify = false};
 
 /* Allocate zclient structure. */
-struct zclient *zclient_new_notify(struct thread_master *master,
-                                  struct zclient_options *opt)
+struct zclient *zclient_new(struct thread_master *master,
+                           struct zclient_options *opt)
 {
        struct zclient *zclient;
        zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
@@ -133,7 +133,7 @@ void redist_del_instance(struct redist_proto *red, unsigned short instance)
        XFREE(MTYPE_REDIST_INST, id);
        if (!red->instances->count) {
                red->enabled = 0;
-               list_delete_and_null(&red->instances);
+               list_delete(&red->instances);
        }
 }
 
@@ -199,7 +199,7 @@ void zclient_reset(struct zclient *zclient)
  * @param zclient a pointer to zclient structure
  * @return socket fd just to make sure that connection established
  * @see zclient_init
- * @see zclient_new_notify
+ * @see zclient_new
  */
 int zclient_socket_connect(struct zclient *zclient)
 {
@@ -221,9 +221,9 @@ int zclient_socket_connect(struct zclient *zclient)
        ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
        if (ret < 0) {
                if (zclient_debug)
-                       zlog_warn("%s connect failure: %d(%s)",
-                                 __PRETTY_FUNCTION__, errno,
-                                 safe_strerror(errno));
+                       zlog_debug("%s connect failure: %d(%s)",
+                                  __PRETTY_FUNCTION__, errno,
+                                  safe_strerror(errno));
                close(sock);
                return -1;
        }
@@ -249,7 +249,8 @@ static int zclient_flush_data(struct thread *thread)
                return -1;
        switch (buffer_flush_available(zclient->wb, zclient->sock)) {
        case BUFFER_ERROR:
-               zlog_warn(
+               flog_err(
+                       EC_LIB_ZAPI_SOCKET,
                        "%s: buffer_flush_available failed on zclient fd %d, closing",
                        __func__, zclient->sock);
                return zclient_failed(zclient);
@@ -273,8 +274,9 @@ int zclient_send_message(struct zclient *zclient)
                             STREAM_DATA(zclient->obuf),
                             stream_get_endp(zclient->obuf))) {
        case BUFFER_ERROR:
-               zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
-                         __func__, zclient->sock);
+               flog_err(EC_LIB_ZAPI_SOCKET,
+                        "%s: buffer_write failed to zclient fd %d, closing",
+                        __func__, zclient->sock);
                return zclient_failed(zclient);
                break;
        case BUFFER_EMPTY:
@@ -313,9 +315,10 @@ int zclient_read_header(struct stream *s, int sock, uint16_t *size,
        STREAM_GETW(s, *cmd);
 
        if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
-               flog_err(LIB_ERR_ZAPI_MISSMATCH,
-                         "%s: socket %d version mismatch, marker %d, version %d",
-                         __func__, sock, *marker, *version);
+               flog_err(
+                       EC_LIB_ZAPI_MISSMATCH,
+                       "%s: socket %d version mismatch, marker %d, version %d",
+                       __func__, sock, *marker, *version);
                return -1;
        }
 
@@ -575,8 +578,8 @@ int zclient_start(struct zclient *zclient)
        }
 
        if (set_nonblocking(zclient->sock) < 0)
-               zlog_warn("%s: set_nonblocking(%d) failed", __func__,
-                         zclient->sock);
+               flog_err(EC_LIB_ZAPI_SOCKET, "%s: set_nonblocking(%d) failed",
+                        __func__, zclient->sock);
 
        /* Clear fail count. */
        zclient->fail = 0;
@@ -676,11 +679,11 @@ int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p,
  * "xdr_encode"-like interface that allows daemon (client) to send
  * a message to zebra server for a route that needs to be
  * added/deleted to the kernel. Info about the route is specified
- * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
+ * by the caller in a struct zapi_route. zapi_route_encode() then writes
  * the info down the zclient socket using the stream_* functions.
  *
  * The corresponding read ("xdr_decode") function on the server
- * side is zread_ipv4_add()/zread_ipv4_delete().
+ * side is zapi_route_decode().
  *
  *  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -707,21 +710,16 @@ int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p,
  * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
  * nexthop.
  *
- * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
- * infrastructure was built around the traditional (32-bit "gate OR
- * ifindex") nexthop data unit. A special encoding can be used to feed
- * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
- * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
- * fields as follows:
+ * The original struct zapi_route_*() infrastructure was built around
+ * the traditional (32-bit "gate OR ifindex") nexthop data unit.
+ * A special encoding can be used to feed onlink (64-bit "gate AND ifindex")
+ * nexthops into zapi_route_encode() using the same zapi_route structure.
+ * This is done by setting zapi_route fields as follows:
  *  - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
  *  - .nexthop_num == .ifindex_num
  *  - .nexthop and .ifindex are filled with gate and ifindex parts of
  *    each compound nexthop, both in the same order
  *
- * zapi_ipv4_route() will produce two nexthop data units for each such
- * interleaved 64-bit nexthop. On the zserv side of the socket it will be
- * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure.
- *
  * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
  * byte value.
  *
@@ -734,226 +732,6 @@ int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p,
  *
  * XXX: No attention paid to alignment.
  */
-int zapi_ipv4_route(uint8_t cmd, struct zclient *zclient, struct prefix_ipv4 *p,
-                   struct zapi_ipv4 *api)
-{
-       int i;
-       int psize;
-       struct stream *s;
-
-       /* Reset stream. */
-       s = zclient->obuf;
-       stream_reset(s);
-
-       /* Some checks for labeled-unicast. The current expectation is that each
-        * nexthop is accompanied by a label in the case of labeled-unicast.
-        */
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
-           && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
-               /* We expect prefixes installed with labels and the number to
-                * match
-                * the number of nexthops.
-                */
-               assert(api->label_num == api->nexthop_num);
-       }
-
-       zclient_create_header(s, cmd, api->vrf_id);
-
-       /* Put type and nexthop. */
-       stream_putc(s, api->type);
-       stream_putw(s, api->instance);
-       stream_putl(s, api->flags);
-       stream_putc(s, api->message);
-       stream_putw(s, api->safi);
-
-       /* Put prefix information. */
-       psize = PSIZE(p->prefixlen);
-       stream_putc(s, p->prefixlen);
-       stream_write(s, (uint8_t *)&p->prefix, psize);
-
-       /* Nexthop, ifindex, distance and metric information. */
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
-               stream_putc(s, api->nexthop_num + api->ifindex_num);
-
-               for (i = 0; i < api->nexthop_num; i++) {
-                       stream_putc(s, NEXTHOP_TYPE_IPV4);
-                       stream_put_in_addr(s, api->nexthop[i]);
-                       /* For labeled-unicast, each nexthop is followed by
-                        * label. */
-                       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
-                               stream_putl(s, api->label[i]);
-               }
-               for (i = 0; i < api->ifindex_num; i++) {
-                       stream_putc(s, NEXTHOP_TYPE_IFINDEX);
-                       stream_putl(s, api->ifindex[i]);
-               }
-       }
-
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
-               stream_putc(s, api->distance);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
-               stream_putl(s, api->metric);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
-               stream_putl(s, api->tag);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
-               stream_putl(s, api->mtu);
-
-       /* Put length at the first point of the stream. */
-       stream_putw_at(s, 0, stream_get_endp(s));
-
-       return zclient_send_message(zclient);
-}
-
-int zapi_ipv4_route_ipv6_nexthop(uint8_t cmd, struct zclient *zclient,
-                                struct prefix_ipv4 *p, struct zapi_ipv6 *api)
-{
-       int i;
-       int psize;
-       struct stream *s;
-
-       /* Reset stream. */
-       s = zclient->obuf;
-       stream_reset(s);
-
-       /* Some checks for labeled-unicast. The current expectation is that each
-        * nexthop is accompanied by a label in the case of labeled-unicast.
-        */
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
-           && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
-               /* We expect prefixes installed with labels and the number to
-                * match
-                * the number of nexthops.
-                */
-               assert(api->label_num == api->nexthop_num);
-       }
-
-       zclient_create_header(s, cmd, api->vrf_id);
-
-       /* Put type and nexthop. */
-       stream_putc(s, api->type);
-       stream_putw(s, api->instance);
-       stream_putl(s, api->flags);
-       stream_putc(s, api->message);
-       stream_putw(s, api->safi);
-
-       /* Put prefix information. */
-       psize = PSIZE(p->prefixlen);
-       stream_putc(s, p->prefixlen);
-       stream_write(s, (uint8_t *)&p->prefix, psize);
-
-       /* Nexthop, ifindex, distance and metric information. */
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
-               stream_putc(s, api->nexthop_num + api->ifindex_num);
-
-               for (i = 0; i < api->nexthop_num; i++) {
-                       stream_putc(s, NEXTHOP_TYPE_IPV6);
-                       stream_write(s, (uint8_t *)api->nexthop[i], 16);
-                       /* For labeled-unicast, each nexthop is followed by
-                        * label. */
-                       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
-                               stream_putl(s, api->label[i]);
-               }
-               for (i = 0; i < api->ifindex_num; i++) {
-                       stream_putc(s, NEXTHOP_TYPE_IFINDEX);
-                       stream_putl(s, api->ifindex[i]);
-               }
-       }
-
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
-               stream_putc(s, api->distance);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
-               stream_putl(s, api->metric);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
-               stream_putl(s, api->tag);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
-               stream_putl(s, api->mtu);
-
-       /* Put length at the first point of the stream. */
-       stream_putw_at(s, 0, stream_get_endp(s));
-
-       return zclient_send_message(zclient);
-}
-
-int zapi_ipv6_route(uint8_t cmd, struct zclient *zclient, struct prefix_ipv6 *p,
-                   struct prefix_ipv6 *src_p, struct zapi_ipv6 *api)
-{
-       int i;
-       int psize;
-       struct stream *s;
-
-       /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL
-        */
-       assert(!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
-
-       /* Reset stream. */
-       s = zclient->obuf;
-       stream_reset(s);
-
-       /* Some checks for labeled-unicast. The current expectation is that each
-        * nexthop is accompanied by a label in the case of labeled-unicast.
-        */
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
-           && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
-               /* We expect prefixes installed with labels and the number to
-                * match
-                * the number of nexthops.
-                */
-               assert(api->label_num == api->nexthop_num);
-       }
-
-       zclient_create_header(s, cmd, api->vrf_id);
-
-       /* Put type and nexthop. */
-       stream_putc(s, api->type);
-       stream_putw(s, api->instance);
-       stream_putl(s, api->flags);
-       stream_putc(s, api->message);
-       stream_putw(s, api->safi);
-
-       /* Put prefix information. */
-       psize = PSIZE(p->prefixlen);
-       stream_putc(s, p->prefixlen);
-       stream_write(s, (uint8_t *)&p->prefix, psize);
-
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
-               psize = PSIZE(src_p->prefixlen);
-               stream_putc(s, src_p->prefixlen);
-               stream_write(s, (uint8_t *)&src_p->prefix, psize);
-       }
-
-       /* Nexthop, ifindex, distance and metric information. */
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
-               stream_putc(s, api->nexthop_num + api->ifindex_num);
-
-               for (i = 0; i < api->nexthop_num; i++) {
-                       stream_putc(s, NEXTHOP_TYPE_IPV6);
-                       stream_write(s, (uint8_t *)api->nexthop[i], 16);
-                       /* For labeled-unicast, each nexthop is followed by
-                        * label. */
-                       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
-                               stream_putl(s, api->label[i]);
-               }
-               for (i = 0; i < api->ifindex_num; i++) {
-                       stream_putc(s, NEXTHOP_TYPE_IFINDEX);
-                       stream_putl(s, api->ifindex[i]);
-               }
-       }
-
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
-               stream_putc(s, api->distance);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
-               stream_putl(s, api->metric);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
-               stream_putl(s, api->tag);
-       if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
-               stream_putl(s, api->mtu);
-
-       /* Put length at the first point of the stream. */
-       stream_putw_at(s, 0, stream_get_endp(s));
-
-       return zclient_send_message(zclient);
-}
-
 int zclient_route_send(uint8_t cmd, struct zclient *zclient,
                       struct zapi_route *api)
 {
@@ -996,9 +774,9 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
                        char buf[PREFIX2STR_BUFFER];
 
                        prefix2str(&api->prefix, buf, sizeof(buf));
-                       zlog_warn(
-                               "%s: prefix %s: can't encode %u nexthops "
-                               "(maximum is %u)",
+                       flog_err(
+                               EC_LIB_ZAPI_ENCODE,
+                               "%s: prefix %s: can't encode %u nexthops (maximum is %u)",
                                __func__, buf, api->nexthop_num, MULTIPATH_NUM);
                        return -1;
                }
@@ -1033,11 +811,6 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
                                             16);
                                stream_putl(s, api_nh->ifindex);
                                break;
-                       default:
-                               zlog_warn(
-                                       "%s: Specified Nexthop type %d does not exist",
-                                       __PRETTY_FUNCTION__, api_nh->type);
-                               return -1;
                        }
 
                        /* MPLS labels for BGP-LU or Segment Routing */
@@ -1046,12 +819,12 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
                                        char buf[PREFIX2STR_BUFFER];
                                        prefix2str(&api->prefix, buf,
                                                   sizeof(buf));
-                                       flog_err(LIB_ERR_ZAPI_ENCODE,
-                                                 "%s: prefix %s: can't encode "
-                                                 "%u labels (maximum is %u)",
-                                                 __func__, buf,
-                                                 api_nh->label_num,
-                                                 MPLS_MAX_LABELS);
+                                       flog_err(EC_LIB_ZAPI_ENCODE,
+                                                "%s: prefix %s: can't encode "
+                                                "%u labels (maximum is %u)",
+                                                __func__, buf,
+                                                api_nh->label_num,
+                                                MPLS_MAX_LABELS);
                                        return -1;
                                }
 
@@ -1096,8 +869,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
        /* Type, flags, message. */
        STREAM_GETC(s, api->type);
        if (api->type > ZEBRA_ROUTE_MAX) {
-               zlog_warn("%s: Specified route type: %d is not a legal value\n",
-                         __PRETTY_FUNCTION__, api->type);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "%s: Specified route type: %d is not a legal value\n",
+                        __PRETTY_FUNCTION__, api->type);
                return -1;
        }
 
@@ -1112,7 +886,8 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
        switch (api->prefix.family) {
        case AF_INET:
                if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
-                       zlog_warn(
+                       flog_err(
+                               EC_LIB_ZAPI_ENCODE,
                                "%s: V4 prefixlen is %d which should not be more than 32",
                                __PRETTY_FUNCTION__, api->prefix.prefixlen);
                        return -1;
@@ -1120,15 +895,17 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
                break;
        case AF_INET6:
                if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
-                       zlog_warn(
+                       flog_err(
+                               EC_LIB_ZAPI_ENCODE,
                                "%s: v6 prefixlen is %d which should not be more than 128",
                                __PRETTY_FUNCTION__, api->prefix.prefixlen);
                        return -1;
                }
                break;
        default:
-               zlog_warn("%s: Specified family %d is not v4 or v6",
-                         __PRETTY_FUNCTION__, api->prefix.family);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "%s: Specified family %d is not v4 or v6",
+                        __PRETTY_FUNCTION__, api->prefix.family);
                return -1;
        }
        STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
@@ -1137,7 +914,8 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
                api->src_prefix.family = AF_INET6;
                STREAM_GETC(s, api->src_prefix.prefixlen);
                if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
-                       zlog_warn(
+                       flog_err(
+                               EC_LIB_ZAPI_ENCODE,
                                "%s: SRC Prefix prefixlen received: %d is too large",
                                __PRETTY_FUNCTION__, api->src_prefix.prefixlen);
                        return -1;
@@ -1147,7 +925,8 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
 
                if (api->prefix.family != AF_INET6
                    || api->src_prefix.prefixlen == 0) {
-                       zlog_warn(
+                       flog_err(
+                               EC_LIB_ZAPI_ENCODE,
                                "%s: SRC prefix specified in some manner that makes no sense",
                                __PRETTY_FUNCTION__);
                        return -1;
@@ -1158,8 +937,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
        if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
                STREAM_GETW(s, api->nexthop_num);
                if (api->nexthop_num > MULTIPATH_NUM) {
-                       zlog_warn("%s: invalid number of nexthops (%u)",
-                                 __func__, api->nexthop_num);
+                       flog_err(EC_LIB_ZAPI_ENCODE,
+                                "%s: invalid number of nexthops (%u)",
+                                __func__, api->nexthop_num);
                        return -1;
                }
 
@@ -1191,11 +971,6 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
                                STREAM_GET(&api_nh->gate.ipv6, s, 16);
                                STREAM_GETL(s, api_nh->ifindex);
                                break;
-                       default:
-                               zlog_warn(
-                                       "%s: Specified nexthop type %d does not exist",
-                                       __PRETTY_FUNCTION__, api_nh->type);
-                               return -1;
                        }
 
                        /* MPLS labels for BGP-LU or Segment Routing */
@@ -1203,9 +978,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
                                STREAM_GETC(s, api_nh->label_num);
 
                                if (api_nh->label_num > MPLS_MAX_LABELS) {
-                                       zlog_warn(
-                                               "%s: invalid number of MPLS "
-                                               "labels (%u)",
+                                       flog_err(
+                                               EC_LIB_ZAPI_ENCODE,
+                                               "%s: invalid number of MPLS labels (%u)",
                                                __func__, api_nh->label_num);
                                        return -1;
                                }
@@ -1442,6 +1217,7 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
        STREAM_GETC(s, nhr->nexthop_num);
 
        for (i = 0; i < nhr->nexthop_num; i++) {
+               STREAM_GETL(s, nhr->nexthops[i].vrf_id);
                STREAM_GETC(s, nhr->nexthops[i].type);
                switch (nhr->nexthops[i].type) {
                case NEXTHOP_TYPE_IPV4:
@@ -1464,8 +1240,9 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
                }
                STREAM_GETC(s, nhr->nexthops[i].label_num);
                if (nhr->nexthops[i].label_num > MPLS_MAX_LABELS) {
-                       zlog_warn("%s: invalid number of MPLS labels (%u)",
-                                 __func__, nhr->nexthops[i].label_num);
+                       flog_err(EC_LIB_ZAPI_ENCODE,
+                                "%s: invalid number of MPLS labels (%u)",
+                                __func__, nhr->nexthops[i].label_num);
                        return false;
                }
                if (nhr->nexthops[i].label_num)
@@ -1591,6 +1368,9 @@ static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
        vrf = vrf_get(vrf_id, vrfname_tmp);
        vrf->data.l.table_id = data.l.table_id;
        memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
+       /* overwrite default vrf */
+       if (vrf_id == VRF_DEFAULT)
+               vrf_set_default_name(vrfname_tmp, false);
        vrf_enable(vrf);
 }
 
@@ -1621,7 +1401,7 @@ struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
        stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
 
        /* Lookup/create interface by name. */
-       ifp = if_get_by_name(ifname_tmp, vrf_id, 0);
+       ifp = if_get_by_name(ifname_tmp, vrf_id);
 
        zebra_interface_if_set_value(s, ifp);
 
@@ -1646,8 +1426,9 @@ struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
        /* Lookup this by interface index. */
        ifp = if_lookup_by_name(ifname_tmp, vrf_id);
        if (ifp == NULL) {
-               zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d",
-                         ifname_tmp, vrf_id);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "INTERFACE_STATE: Cannot find IF %s in VRF %d",
+                        ifname_tmp, vrf_id);
                return NULL;
        }
 
@@ -1672,10 +1453,11 @@ static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
                for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
                        iflp->unrsv_bw[i] = stream_getf(s);
                if (i < bwclassnum)
-                       flog_err(LIB_ERR_ZAPI_MISSMATCH,
-                                 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
-                                 " - outdated library?",
-                                 __func__, bwclassnum, MAX_CLASS_TYPE);
+                       flog_err(
+                               EC_LIB_ZAPI_MISSMATCH,
+                               "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
+                               " - outdated library?",
+                               __func__, bwclassnum, MAX_CLASS_TYPE);
        }
        iflp->admin_grp = stream_getl(s);
        iflp->rmt_as = stream_getl(s);
@@ -1704,9 +1486,9 @@ struct interface *zebra_interface_link_params_read(struct stream *s)
        struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
 
        if (ifp == NULL) {
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "%s: unknown ifindex %u, shouldn't happen", __func__,
-                         ifindex);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "%s: unknown ifindex %u, shouldn't happen", __func__,
+                        ifindex);
                return NULL;
        }
 
@@ -1855,9 +1637,10 @@ struct connected *zebra_interface_address_read(int type, struct stream *s,
        /* Lookup index. */
        ifp = if_lookup_by_index(ifindex, vrf_id);
        if (ifp == NULL) {
-               zlog_warn("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
-                         (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
-                         ifindex, vrf_id);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
+                        (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
+                        ifindex, vrf_id);
                return NULL;
        }
 
@@ -1892,9 +1675,9 @@ struct connected *zebra_interface_address_read(int type, struct stream *s,
                                /* carp interfaces on OpenBSD with 0.0.0.0/0 as
                                 * "peer" */
                                char buf[PREFIX_STRLEN];
-                               zlog_warn(
-                                       "warning: interface %s address %s "
-                                       "with peer flag set, but no peer address!",
+                               flog_err(
+                                       EC_LIB_ZAPI_ENCODE,
+                                       "warning: interface %s address %s with peer flag set, but no peer address!",
                                        ifp->name,
                                        prefix2str(ifc->address, buf,
                                                   sizeof buf));
@@ -1947,10 +1730,11 @@ zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
        /* Lookup index. */
        ifp = if_lookup_by_index(ifindex, vrf_id);
        if (ifp == NULL) {
-               zlog_warn("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
-                         (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
-                                                                   : "DELETE",
-                         ifindex, vrf_id);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
+                        (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
+                                                                  : "DELETE",
+                        ifindex, vrf_id);
                return NULL;
        }
 
@@ -1986,18 +1770,19 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s,
                                                  vrf_id_t vrf_id,
                                                  vrf_id_t *new_vrf_id)
 {
-       unsigned int ifindex;
+       char ifname[INTERFACE_NAMSIZ];
        struct interface *ifp;
        vrf_id_t new_id;
 
-       /* Get interface index. */
-       ifindex = stream_getl(s);
+       /* Read interface name. */
+       stream_get(ifname, s, INTERFACE_NAMSIZ);
 
        /* Lookup interface. */
-       ifp = if_lookup_by_index(ifindex, vrf_id);
+       ifp = if_lookup_by_name(ifname, vrf_id);
        if (ifp == NULL) {
-               zlog_warn("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
-                         ifindex, vrf_id);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
+                        ifname, vrf_id);
                return NULL;
        }
 
@@ -2041,8 +1826,8 @@ static int zclient_read_sync_response(struct zclient *zclient,
                                   size);
        }
        if (ret != 0) {
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                        "%s: Invalid Sync Message Reply", __func__);
+               flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
+                        __func__);
                return -1;
        }
 
@@ -2055,24 +1840,29 @@ static int zclient_read_sync_response(struct zclient *zclient,
  * immediately reads the answer from the input buffer.
  *
  * @param zclient Zclient used to connect to label manager (zebra)
+ * @param async Synchronous (0) or asynchronous (1) operation
  * @result Result of response
  */
-int lm_label_manager_connect(struct zclient *zclient)
+int lm_label_manager_connect(struct zclient *zclient, int async)
 {
        int ret;
        struct stream *s;
        uint8_t result;
+       uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
+                              ZEBRA_LABEL_MANAGER_CONNECT;
 
        if (zclient_debug)
                zlog_debug("Connecting to Label Manager (LM)");
 
-       if (zclient->sock < 0)
+       if (zclient->sock < 0) {
+               zlog_debug("%s: invalid zclient socket", __func__);
                return -1;
+       }
 
        /* send request */
        s = zclient->obuf;
        stream_reset(s);
-       zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT);
+       zclient_create_header(s, cmd, VRF_DEFAULT);
 
        /* proto */
        stream_putc(s, zclient->redist_default);
@@ -2084,13 +1874,13 @@ int lm_label_manager_connect(struct zclient *zclient)
 
        ret = writen(zclient->sock, s->data, stream_get_endp(s));
        if (ret < 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock");
+               flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
        }
        if (ret == 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET, "Zclient sock closed");
+               flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
@@ -2098,8 +1888,11 @@ int lm_label_manager_connect(struct zclient *zclient)
        if (zclient_debug)
                zlog_debug("LM connect request sent (%d bytes)", ret);
 
+       if (async)
+               return 0;
+
        /* read response */
-       if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT)
+       if (zclient_read_sync_response(zclient, cmd)
            != 0)
                return -1;
 
@@ -2111,13 +1904,15 @@ int lm_label_manager_connect(struct zclient *zclient)
 
        /* sanity */
        if (proto != zclient->redist_default)
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "Wrong proto (%u) in LM connect response. Should be %u",
-                         proto, zclient->redist_default);
+               flog_err(
+                       EC_LIB_ZAPI_ENCODE,
+                       "Wrong proto (%u) in LM connect response. Should be %u",
+                       proto, zclient->redist_default);
        if (instance != zclient->instance)
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "Wrong instId (%u) in LM connect response. Should be %u",
-                         instance, zclient->instance);
+               flog_err(
+                       EC_LIB_ZAPI_ENCODE,
+                       "Wrong instId (%u) in LM connect response. Should be %u",
+                       instance, zclient->instance);
 
        /* result code */
        result = stream_getc(s);
@@ -2206,15 +2001,13 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
 
        ret = writen(zclient->sock, s->data, stream_get_endp(s));
        if (ret < 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET,
-                         "Can't write to zclient sock");
+               flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
        }
        if (ret == 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET,
-                         "Zclient sock closed");
+               flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
@@ -2235,13 +2028,13 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
 
        /* sanities */
        if (proto != zclient->redist_default)
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "Wrong proto (%u) in get chunk response. Should be %u",
-                         proto, zclient->redist_default);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "Wrong proto (%u) in get chunk response. Should be %u",
+                        proto, zclient->redist_default);
        if (instance != zclient->instance)
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "Wrong instId (%u) in get chunk response Should be %u",
-                         instance, zclient->instance);
+               flog_err(EC_LIB_ZAPI_ENCODE,
+                        "Wrong instId (%u) in get chunk response Should be %u",
+                        instance, zclient->instance);
 
        /* keep */
        response_keep = stream_getc(s);
@@ -2251,15 +2044,16 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
 
        /* not owning this response */
        if (keep != response_keep) {
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
-                         *start, *end, keep, response_keep);
+               flog_err(
+                       EC_LIB_ZAPI_ENCODE,
+                       "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
+                       *start, *end, keep, response_keep);
        }
        /* sanity */
        if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
            || *end > MPLS_LABEL_UNRESERVED_MAX) {
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "Invalid Label chunk: %u - %u", *start, *end);
+               flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
+                        *start, *end);
                return -1;
        }
 
@@ -2309,14 +2103,13 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
 
        ret = writen(zclient->sock, s->data, stream_get_endp(s));
        if (ret < 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock");
+               flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
        }
        if (ret == 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET,
-                         "Zclient sock connection closed");
+               flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
@@ -2419,15 +2212,15 @@ int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
 
        ret = writen(zclient->sock, s->data, stream_get_endp(s));
        if (ret < 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET,
-                         "%s: can't write to zclient->sock", __func__);
+               flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
+                        __func__);
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
        }
        if (ret == 0) {
-               flog_err(LIB_ERR_ZAPI_SOCKET,
-                         "%s: zclient->sock connection closed", __func__);
+               flog_err(EC_LIB_ZAPI_SOCKET,
+                        "%s: zclient->sock connection closed", __func__);
                close(zclient->sock);
                zclient->sock = -1;
                return -1;
@@ -2513,8 +2306,7 @@ int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
                stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
                break;
        default:
-               flog_err(LIB_ERR_ZAPI_ENCODE,
-                         "%s: unknown af", __func__);
+               flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
                return -1;
        }
 
@@ -2616,23 +2408,25 @@ static int zclient_read(struct thread *thread)
        command = stream_getw(zclient->ibuf);
 
        if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
-               flog_err(LIB_ERR_ZAPI_MISSMATCH,
-                         "%s: socket %d version mismatch, marker %d, version %d",
-                         __func__, zclient->sock, marker, version);
+               flog_err(
+                       EC_LIB_ZAPI_MISSMATCH,
+                       "%s: socket %d version mismatch, marker %d, version %d",
+                       __func__, zclient->sock, marker, version);
                return zclient_failed(zclient);
        }
 
        if (length < ZEBRA_HEADER_SIZE) {
-               flog_err(LIB_ERR_ZAPI_MISSMATCH,
-                         "%s: socket %d message length %u is less than %d ",
-                         __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
+               flog_err(EC_LIB_ZAPI_MISSMATCH,
+                        "%s: socket %d message length %u is less than %d ",
+                        __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
                return zclient_failed(zclient);
        }
 
        /* Length check. */
        if (length > STREAM_SIZE(zclient->ibuf)) {
                struct stream *ns;
-               zlog_warn(
+               flog_err(
+                       EC_LIB_ZAPI_ENCODE,
                        "%s: message size %u exceeds buffer size %lu, expanding...",
                        __func__, length,
                        (unsigned long)STREAM_SIZE(zclient->ibuf));