DESC_ENTRY(ZEBRA_VXLAN_SG_ADD),
DESC_ENTRY(ZEBRA_VXLAN_SG_DEL),
DESC_ENTRY(ZEBRA_VXLAN_SG_REPLAY),
+ DESC_ENTRY(ZEBRA_ERROR),
};
#undef DESC_ENTRY
return false;
}
+bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
+{
+ memset(error, 0, sizeof(*error));
+
+ STREAM_GET(error, s, sizeof(*error));
+
+ if (zclient_debug)
+ zlog_debug("%s: type: %s", __func__,
+ zebra_error_type2str(*error));
+
+ return true;
+stream_failure:
+ return false;
+}
+
/*
* send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
* for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
if_down_via_zapi(ifp);
}
+static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
+{
+ enum zebra_error_types error;
+ struct stream *s = zclient->ibuf;
+
+ zapi_error_decode(s, &error);
+
+ if (zclient->handle_error)
+ (*zclient->handle_error)(error);
+}
+
static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
{
case ZEBRA_MLAG_FORWARD_MSG:
zclient_mlag_handle_msg(command, zclient, length, vrf_id);
break;
+ case ZEBRA_ERROR:
+ zclient_handle_error(command, zclient, length, vrf_id);
default:
break;
}
ZEBRA_MLAG_CLIENT_REGISTER,
ZEBRA_MLAG_CLIENT_UNREGISTER,
ZEBRA_MLAG_FORWARD_MSG,
+ ZEBRA_ERROR,
} zebra_message_types_t;
+enum zebra_error_types {
+ ZEBRA_UNKNOWN_ERROR, /* Error of unknown type */
+ ZEBRA_NO_VRF, /* Vrf in header was not found */
+ ZEBRA_INVALID_MSG_TYPE, /* No handler found for msg type */
+};
+
+static inline const char *zebra_error_type2str(enum zebra_error_types type)
+{
+ const char *ret = "UNKNOWN";
+
+ switch (type) {
+ case ZEBRA_UNKNOWN_ERROR:
+ ret = "ZEBRA_UNKNOWN_ERROR";
+ break;
+ case ZEBRA_NO_VRF:
+ ret = "ZEBRA_NO_VRF";
+ break;
+ case ZEBRA_INVALID_MSG_TYPE:
+ ret = "ZEBRA_INVALID_MSG_TYPE";
+ break;
+ }
+
+ return ret;
+}
+
struct redist_proto {
uint8_t enabled;
struct list *instances;
int (*mlag_process_up)(void);
int (*mlag_process_down)(void);
int (*mlag_handle_msg)(struct stream *msg, int len);
+ int (*handle_error)(enum zebra_error_types error);
};
/* Zebra API message flag. */
extern bool zapi_nexthop_update_decode(struct stream *s,
struct zapi_route *nhr);
+/* Decode the zebra error message */
+extern bool zapi_error_decode(struct stream *s, enum zebra_error_types *error);
+
static inline void zapi_route_set_blackhole(struct zapi_route *api,
enum blackhole_type bh_type)
{
return 1;
}
+/*
+ * Zebra error addition adds error type.
+ *
+ *
+ * 0 1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | enum zebra_error_types |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+static void zserv_encode_error(struct stream *s, enum zebra_error_types error)
+{
+ stream_put(s, &error, sizeof(error));
+
+ /* Write packet size. */
+ stream_putw_at(s, 0, stream_get_endp(s));
+}
+
/* Send handlers ----------------------------------------------------------- */
/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
return;
}
+static void zsend_error_msg(struct zserv *client, enum zebra_error_types error,
+ struct zmsghdr *bad_hdr)
+{
+
+ struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+
+ zclient_create_header(s, ZEBRA_ERROR, bad_hdr->vrf_id);
+
+ zserv_encode_error(s, error);
+
+ client->error_cnt++;
+ zserv_send_message(client, s);
+}
+
+static void zserv_error_no_vrf(ZAPI_HANDLER_ARGS)
+{
+ if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
+ zlog_debug("ZAPI message specifies unknown VRF: %d",
+ hdr->vrf_id);
+
+ return zsend_error_msg(client, ZEBRA_NO_VRF, hdr);
+}
+
+static void zserv_error_invalid_msg_type(ZAPI_HANDLER_ARGS)
+{
+ zlog_info("Zebra received unknown command %d", hdr->command);
+
+ return zsend_error_msg(client, ZEBRA_INVALID_MSG_TYPE, hdr);
+}
+
void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_ROUTER_ID_ADD] = zread_router_id_add,
[ZEBRA_ROUTER_ID_DELETE] = zread_router_id_delete,
/* lookup vrf */
zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
- if (!zvrf) {
- if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
- zlog_debug("ZAPI message specifies unknown VRF: %d",
- hdr.vrf_id);
- return;
- }
+ if (!zvrf)
+ return zserv_error_no_vrf(client, &hdr, msg, zvrf);
if (hdr.command >= array_size(zserv_handlers)
|| zserv_handlers[hdr.command] == NULL)
- zlog_info("Zebra received unknown command %d", hdr.command);
- else
- zserv_handlers[hdr.command](client, &hdr, msg, zvrf);
+ return zserv_error_invalid_msg_type(client, &hdr, msg, zvrf);
+
+ zserv_handlers[hdr.command](client, &hdr, msg, zvrf);
}
uint32_t v6_nh_watch_rem_cnt;
uint32_t vxlan_sg_add_cnt;
uint32_t vxlan_sg_del_cnt;
+ uint32_t error_cnt;
time_t nh_reg_time;
time_t nh_dereg_time;