diff options
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 468 |
1 files changed, 127 insertions, 341 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index 0815e77d4e..24546f3c45 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -66,7 +66,8 @@ static int zclient_debug; /* Allocate zclient structure. */ struct zclient *zclient_new(struct thread_master *master, - struct zclient_options *opt) + struct zclient_options *opt, + zclient_handler *const *handlers, size_t n_handlers) { struct zclient *zclient; size_t stream_size = @@ -79,6 +80,9 @@ struct zclient *zclient_new(struct thread_master *master, zclient->wb = buffer_new(0); zclient->master = master; + zclient->handlers = handlers; + zclient->n_handlers = n_handlers; + zclient->receive_notify = opt->receive_notify; zclient->synchronous = opt->synchronous; @@ -450,7 +454,7 @@ enum zclient_send_status zclient_send_localsid(struct zclient *zclient, p.prefix = *sid; api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_BGP; + api.type = zclient->redist_default; api.instance = 0; api.safi = SAFI_UNICAST; memcpy(&api.prefix, &p, sizeof(p)); @@ -765,15 +769,17 @@ static int zclient_connect(struct thread *t) enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command, const struct prefix *p, - bool exact_match, vrf_id_t vrf_id) + bool connected, + bool resolve_via_def, vrf_id_t vrf_id) { struct stream *s; s = zclient->obuf; stream_reset(s); zclient_create_header(s, command, vrf_id); - stream_putc(s, (exact_match) ? 1 : 0); - + stream_putc(s, (connected) ? 1 : 0); + stream_putc(s, (resolve_via_def) ? 1 : 0); + stream_putw(s, SAFI_UNICAST); stream_putw(s, PREFIX_FAMILY(p)); stream_putc(s, p->prefixlen); switch (PREFIX_FAMILY(p)) { @@ -1105,6 +1111,33 @@ stream_failure: return -1; } +int zapi_srv6_locator_encode(struct stream *s, const struct srv6_locator *l) +{ + stream_putw(s, strlen(l->name)); + stream_put(s, l->name, strlen(l->name)); + stream_putw(s, l->prefix.prefixlen); + stream_put(s, &l->prefix.prefix, sizeof(l->prefix.prefix)); + return 0; +} + +int zapi_srv6_locator_decode(struct stream *s, struct srv6_locator *l) +{ + uint16_t len = 0; + + STREAM_GETW(s, len); + if (len > SRV6_LOCNAME_SIZE) + goto stream_failure; + + STREAM_GET(l->name, s, len); + STREAM_GETW(s, l->prefix.prefixlen); + STREAM_GET(&l->prefix.prefix, s, sizeof(l->prefix.prefix)); + l->prefix.family = AF_INET6; + return 0; + +stream_failure: + return -1; +} + static int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg) { int i; @@ -1299,7 +1332,13 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) stream_putl(s, api->tableid); if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) { - assert(api->opaque.length <= ZAPI_MESSAGE_OPAQUE_LENGTH); + if (api->opaque.length > ZAPI_MESSAGE_OPAQUE_LENGTH) { + flog_err( + EC_LIB_ZAPI_ENCODE, + "%s: opaque length %u is greater than allowed value", + __func__, api->opaque.length); + return -1; + } stream_putw(s, api->opaque.length); stream_write(s, api->opaque.data, api->opaque.length); @@ -1537,7 +1576,13 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) { STREAM_GETW(s, api->opaque.length); - assert(api->opaque.length <= ZAPI_MESSAGE_OPAQUE_LENGTH); + if (api->opaque.length > ZAPI_MESSAGE_OPAQUE_LENGTH) { + flog_err( + EC_LIB_ZAPI_ENCODE, + "%s: opaque length %u is greater than allowed value", + __func__, api->opaque.length); + return -1; + } STREAM_GET(api->opaque.data, s, api->opaque.length); } @@ -1886,6 +1931,7 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr) memset(nhr, 0, sizeof(*nhr)); STREAM_GETL(s, nhr->message); + STREAM_GETW(s, nhr->safi); STREAM_GETW(s, nhr->prefix.family); STREAM_GETC(s, nhr->prefix.prefixlen); switch (nhr->prefix.family) { @@ -2057,7 +2103,7 @@ stream_failure: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Harware Address Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Hardware Address if HW lenght different from 0 | + * | Hardware Address if HW length different from 0 | * | ... max INTERFACE_HWADDR_MAX | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Link_params? | Whether a link-params follows: 1 or 0. @@ -2067,7 +2113,7 @@ stream_failure: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -static int zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id) +static int zclient_vrf_add(ZAPI_CALLBACK_ARGS) { struct vrf *vrf; char vrfname_tmp[VRF_NAMSIZ + 1] = {}; @@ -2099,7 +2145,7 @@ stream_failure: return -1; } -static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id) +static int zclient_vrf_delete(ZAPI_CALLBACK_ARGS) { struct vrf *vrf; @@ -2112,29 +2158,32 @@ static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id) * no point in attempting to delete it. */ if (!vrf) - return; + return 0; vrf_delete(vrf); + return 0; } -static int zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id) +static int zclient_interface_add(ZAPI_CALLBACK_ARGS) { struct interface *ifp; char ifname_tmp[INTERFACE_NAMSIZ + 1] = {}; struct stream *s = zclient->ibuf; + struct vrf *vrf; /* Read interface name. */ STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ); /* Lookup/create interface by name. */ - if (!vrf_get(vrf_id, NULL)) { + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) { zlog_debug( "Rx'd interface add from Zebra, but VRF %u does not exist", vrf_id); return -1; } - ifp = if_get_by_name(ifname_tmp, vrf_id); + ifp = if_get_by_name(ifname_tmp, vrf_id, vrf->name); zebra_interface_if_set_value(s, ifp); @@ -2175,7 +2224,7 @@ stream_failure: return NULL; } -static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id) +static int zclient_interface_delete(ZAPI_CALLBACK_ARGS) { struct interface *ifp; struct stream *s = zclient->ibuf; @@ -2183,13 +2232,13 @@ static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id) ifp = zebra_interface_state_read(s, vrf_id); if (ifp == NULL) - return; + return 0; if_destroy_via_zapi(ifp); - return; + return 0; } -static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id) +static int zclient_interface_up(ZAPI_CALLBACK_ARGS) { struct interface *ifp; struct stream *s = zclient->ibuf; @@ -2197,12 +2246,13 @@ static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id) ifp = zebra_interface_state_read(s, vrf_id); if (!ifp) - return; + return 0; if_up_via_zapi(ifp); + return 0; } -static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id) +static int zclient_interface_down(ZAPI_CALLBACK_ARGS) { struct interface *ifp; struct stream *s = zclient->ibuf; @@ -2210,12 +2260,13 @@ static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id) ifp = zebra_interface_state_read(s, vrf_id); if (!ifp) - return; + return 0; if_down_via_zapi(ifp); + return 0; } -static void zclient_handle_error(ZAPI_CALLBACK_ARGS) +static int zclient_handle_error(ZAPI_CALLBACK_ARGS) { enum zebra_error_types error; struct stream *s = zclient->ibuf; @@ -2224,6 +2275,7 @@ static void zclient_handle_error(ZAPI_CALLBACK_ARGS) if (zclient->handle_error) (*zclient->handle_error)(error); + return 0; } static int link_params_set_value(struct stream *s, struct if_link_params *iflp) @@ -2396,7 +2448,7 @@ size_t zebra_interface_link_params_write(struct stream *s, } /* - * format of message for address additon is: + * format of message for address addition is: * 0 * 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ @@ -2661,9 +2713,9 @@ static int zclient_read_sync_response(struct zclient *zclient, return 0; } /** - * Connect to label manager in a syncronous way + * Connect to label manager in a synchronous way * - * It first writes the request to zcient output buffer and then + * It first writes the request to zclient output buffer and then * immediately reads the answer from the input buffer. * * @param zclient Zclient used to connect to label manager (zebra) @@ -2756,7 +2808,7 @@ stream_failure: } /** - * Function to request a srv6-locator chunk in an Asyncronous way + * Function to request a srv6-locator chunk in an asynchronous way * * @param zclient Zclient used to connect to table manager (zebra) * @param locator_name Name of SRv6-locator @@ -2866,9 +2918,9 @@ enum zclient_send_status zclient_send_get_label_chunk(struct zclient *zclient, } /** - * Function to request a label chunk in a syncronous way + * Function to request a label chunk in a synchronous way * - * It first writes the request to zlcient output buffer and then + * It first writes the request to zclient output buffer and then * immediately reads the answer from the input buffer. * * @param zclient Zclient used to connect to label manager (zebra) @@ -3043,9 +3095,9 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start, } /** - * Connect to table manager in a syncronous way + * Connect to table manager in a synchronous way * - * It first writes the request to zcient output buffer and then + * It first writes the request to zclient output buffer and then * immediately reads the answer from the input buffer. * * @param zclient Zclient used to connect to table manager (zebra) @@ -3102,7 +3154,7 @@ stream_failure: } /** - * Function to request a table chunk in a syncronous way + * Function to request a table chunk in a synchronous way * * It first writes the request to zclient output buffer and then * immediately reads the answer from the input buffer. @@ -3430,6 +3482,14 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl) if (zapi_nexthop_decode(s, znh, 0, 0) < 0) return -1; + + if (znh->type == NEXTHOP_TYPE_BLACKHOLE) { + flog_warn( + EC_LIB_ZAPI_ENCODE, + "%s: Prefix %pFX has a blackhole nexthop which we cannot use for a label", + __func__, &zl->route.prefix); + return -1; + } } if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) { @@ -3451,6 +3511,14 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl) if (zapi_nexthop_decode(s, znh, 0, 0) < 0) return -1; + + if (znh->type == NEXTHOP_TYPE_BLACKHOLE) { + flog_warn( + EC_LIB_ZAPI_ENCODE, + "%s: Prefix %pFX has a backup blackhole nexthop which we cannot use for a label", + __func__, &zl->route.prefix); + return -1; + } } } @@ -3525,7 +3593,7 @@ stream_failure: return -1; } -static void zclient_capability_decode(ZAPI_CALLBACK_ARGS) +static int zclient_capability_decode(ZAPI_CALLBACK_ARGS) { struct zclient_capabilities cap; struct stream *s = zclient->ibuf; @@ -3552,7 +3620,7 @@ static void zclient_capability_decode(ZAPI_CALLBACK_ARGS) (*zclient->zebra_capabilities)(&cap); stream_failure: - return; + return 0; } enum zclient_send_status zclient_send_mlag_register(struct zclient *client, @@ -3591,24 +3659,6 @@ enum zclient_send_status zclient_send_mlag_data(struct zclient *client, return zclient_send_message(client); } -static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS) -{ - if (zclient->mlag_process_up) - (*zclient->mlag_process_up)(); -} - -static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS) -{ - if (zclient->mlag_process_down) - (*zclient->mlag_process_down)(); -} - -static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS) -{ - if (zclient->mlag_handle_msg) - (*zclient->mlag_handle_msg)(zclient->ibuf, length); -} - /* * Send an OPAQUE message, contents opaque to zebra. The message header * is a message subtype. @@ -3798,6 +3848,24 @@ stream_failure: return -1; } +static zclient_handler *const lib_handlers[] = { + /* fundamentals */ + [ZEBRA_CAPABILITIES] = zclient_capability_decode, + [ZEBRA_ERROR] = zclient_handle_error, + + /* VRF & interface code is shared in lib */ + [ZEBRA_VRF_ADD] = zclient_vrf_add, + [ZEBRA_VRF_DELETE] = zclient_vrf_delete, + [ZEBRA_INTERFACE_ADD] = zclient_interface_add, + [ZEBRA_INTERFACE_DELETE] = zclient_interface_delete, + [ZEBRA_INTERFACE_UP] = zclient_interface_up, + [ZEBRA_INTERFACE_DOWN] = zclient_interface_down, + + /* BFD */ + [ZEBRA_BFD_DEST_REPLAY] = zclient_bfd_session_reply, + [ZEBRA_INTERFACE_BFD_DEST_UPDATE] = zclient_bfd_session_update, +}; + /* Zebra client message read function. */ static int zclient_read(struct thread *thread) { @@ -3897,290 +3965,10 @@ static int zclient_read(struct thread *thread) zlog_debug("zclient %p command %s VRF %u", zclient, zserv_command_string(command), vrf_id); - switch (command) { - case ZEBRA_CAPABILITIES: - zclient_capability_decode(command, zclient, length, vrf_id); - break; - case ZEBRA_ROUTER_ID_UPDATE: - if (zclient->router_id_update) - (*zclient->router_id_update)(command, zclient, length, - vrf_id); - break; - case ZEBRA_VRF_ADD: - zclient_vrf_add(zclient, vrf_id); - break; - case ZEBRA_VRF_DELETE: - zclient_vrf_delete(zclient, vrf_id); - break; - case ZEBRA_INTERFACE_ADD: - zclient_interface_add(zclient, vrf_id); - break; - case ZEBRA_INTERFACE_DELETE: - zclient_interface_delete(zclient, vrf_id); - break; - case ZEBRA_INTERFACE_ADDRESS_ADD: - if (zclient->interface_address_add) - (*zclient->interface_address_add)(command, zclient, - length, vrf_id); - break; - case ZEBRA_INTERFACE_ADDRESS_DELETE: - if (zclient->interface_address_delete) - (*zclient->interface_address_delete)(command, zclient, - length, vrf_id); - break; - case ZEBRA_INTERFACE_BFD_DEST_UPDATE: - if (zclient->interface_bfd_dest_update) - (*zclient->interface_bfd_dest_update)(command, zclient, - length, vrf_id); - break; - case ZEBRA_INTERFACE_NBR_ADDRESS_ADD: - if (zclient->interface_nbr_address_add) - (*zclient->interface_nbr_address_add)(command, zclient, - length, vrf_id); - break; - case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE: - if (zclient->interface_nbr_address_delete) - (*zclient->interface_nbr_address_delete)( - command, zclient, length, vrf_id); - break; - case ZEBRA_INTERFACE_UP: - zclient_interface_up(zclient, vrf_id); - break; - case ZEBRA_INTERFACE_DOWN: - zclient_interface_down(zclient, vrf_id); - break; - case ZEBRA_INTERFACE_VRF_UPDATE: - if (zclient->interface_vrf_update) - (*zclient->interface_vrf_update)(command, zclient, - length, vrf_id); - break; - case ZEBRA_NEXTHOP_UPDATE: - if (zclient_debug) - zlog_debug("zclient rcvd nexthop update"); - if (zclient->nexthop_update) - (*zclient->nexthop_update)(command, zclient, length, - vrf_id); - break; - case ZEBRA_IMPORT_CHECK_UPDATE: - if (zclient_debug) - zlog_debug("zclient rcvd import check update"); - if (zclient->import_check_update) - (*zclient->import_check_update)(command, zclient, - length, vrf_id); - break; - case ZEBRA_BFD_DEST_REPLAY: - if (zclient->bfd_dest_replay) - (*zclient->bfd_dest_replay)(command, zclient, length, - vrf_id); - break; - case ZEBRA_REDISTRIBUTE_ROUTE_ADD: - if (zclient->redistribute_route_add) - (*zclient->redistribute_route_add)(command, zclient, - length, vrf_id); - break; - case ZEBRA_REDISTRIBUTE_ROUTE_DEL: - if (zclient->redistribute_route_del) - (*zclient->redistribute_route_del)(command, zclient, - length, vrf_id); - break; - case ZEBRA_INTERFACE_LINK_PARAMS: - if (zclient->interface_link_params) - (*zclient->interface_link_params)(command, zclient, - length, vrf_id); - break; - case ZEBRA_FEC_UPDATE: - if (zclient_debug) - zlog_debug("zclient rcvd fec update"); - if (zclient->fec_update) - (*zclient->fec_update)(command, zclient, length); - break; - case ZEBRA_LOCAL_ES_ADD: - if (zclient->local_es_add) - (*zclient->local_es_add)(command, zclient, length, - vrf_id); - break; - case ZEBRA_LOCAL_ES_DEL: - if (zclient->local_es_del) - (*zclient->local_es_del)(command, zclient, length, - vrf_id); - break; - case ZEBRA_LOCAL_ES_EVI_ADD: - if (zclient->local_es_evi_add) - (*zclient->local_es_evi_add)(command, zclient, length, - vrf_id); - break; - case ZEBRA_LOCAL_ES_EVI_DEL: - if (zclient->local_es_evi_del) - (*zclient->local_es_evi_del)(command, zclient, length, - vrf_id); - break; - case ZEBRA_VNI_ADD: - if (zclient->local_vni_add) - (*zclient->local_vni_add)(command, zclient, length, - vrf_id); - break; - case ZEBRA_VNI_DEL: - if (zclient->local_vni_del) - (*zclient->local_vni_del)(command, zclient, length, - vrf_id); - break; - case ZEBRA_L3VNI_ADD: - if (zclient->local_l3vni_add) - (*zclient->local_l3vni_add)(command, zclient, length, - vrf_id); - break; - case ZEBRA_L3VNI_DEL: - if (zclient->local_l3vni_del) - (*zclient->local_l3vni_del)(command, zclient, length, - vrf_id); - break; - case ZEBRA_MACIP_ADD: - if (zclient->local_macip_add) - (*zclient->local_macip_add)(command, zclient, length, - vrf_id); - break; - case ZEBRA_MACIP_DEL: - if (zclient->local_macip_del) - (*zclient->local_macip_del)(command, zclient, length, - vrf_id); - break; - case ZEBRA_IP_PREFIX_ROUTE_ADD: - if (zclient->local_ip_prefix_add) - (*zclient->local_ip_prefix_add)(command, zclient, - length, vrf_id); - break; - case ZEBRA_IP_PREFIX_ROUTE_DEL: - if (zclient->local_ip_prefix_del) - (*zclient->local_ip_prefix_del)(command, zclient, - length, vrf_id); - break; - case ZEBRA_PW_STATUS_UPDATE: - if (zclient->pw_status_update) - (*zclient->pw_status_update)(command, zclient, length, - vrf_id); - break; - case ZEBRA_ROUTE_NOTIFY_OWNER: - if (zclient->route_notify_owner) - (*zclient->route_notify_owner)(command, zclient, length, - vrf_id); - break; - case ZEBRA_RULE_NOTIFY_OWNER: - if (zclient->rule_notify_owner) - (*zclient->rule_notify_owner)(command, zclient, length, - vrf_id); - break; - case ZEBRA_NHG_NOTIFY_OWNER: - if (zclient->nhg_notify_owner) - (*zclient->nhg_notify_owner)(command, zclient, length, - vrf_id); - break; - case ZEBRA_GET_LABEL_CHUNK: - if (zclient->label_chunk) - (*zclient->label_chunk)(command, zclient, length, - vrf_id); - break; - case ZEBRA_IPSET_NOTIFY_OWNER: - if (zclient->ipset_notify_owner) - (*zclient->ipset_notify_owner)(command, zclient, length, - vrf_id); - break; - case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER: - if (zclient->ipset_entry_notify_owner) - (*zclient->ipset_entry_notify_owner)(command, - zclient, length, - vrf_id); - break; - case ZEBRA_IPTABLE_NOTIFY_OWNER: - if (zclient->iptable_notify_owner) - (*zclient->iptable_notify_owner)(command, - zclient, length, - vrf_id); - break; - case ZEBRA_VXLAN_SG_ADD: - if (zclient->vxlan_sg_add) - (*zclient->vxlan_sg_add)(command, zclient, length, - vrf_id); - break; - case ZEBRA_VXLAN_SG_DEL: - if (zclient->vxlan_sg_del) - (*zclient->vxlan_sg_del)(command, zclient, length, - vrf_id); - break; - case ZEBRA_MLAG_PROCESS_UP: - zclient_mlag_process_up(command, zclient, length, vrf_id); - break; - case ZEBRA_MLAG_PROCESS_DOWN: - zclient_mlag_process_down(command, zclient, length, vrf_id); - break; - case ZEBRA_MLAG_FORWARD_MSG: - zclient_mlag_handle_msg(command, zclient, length, vrf_id); - break; - case ZEBRA_SRV6_LOCATOR_ADD: - if (zclient->srv6_locator_add) - (*zclient->srv6_locator_add)(command, zclient, length, - vrf_id); - break; - case ZEBRA_SRV6_LOCATOR_DELETE: - if (zclient->srv6_locator_delete) - (*zclient->srv6_locator_delete)(command, zclient, - length, vrf_id); - break; - case ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK: - if (zclient->process_srv6_locator_chunk) - (*zclient->process_srv6_locator_chunk)(command, zclient, - length, vrf_id); - break; - case ZEBRA_ERROR: - zclient_handle_error(command, zclient, length, vrf_id); - break; - case ZEBRA_OPAQUE_MESSAGE: - if (zclient->opaque_msg_handler) - (*zclient->opaque_msg_handler)(command, zclient, length, - vrf_id); - break; - case ZEBRA_OPAQUE_REGISTER: - if (zclient->opaque_register_handler) - (*zclient->opaque_register_handler)(command, zclient, - length, vrf_id); - break; - case ZEBRA_OPAQUE_UNREGISTER: - if (zclient->opaque_unregister_handler) - (*zclient->opaque_unregister_handler)(command, zclient, - length, vrf_id); - break; - case ZEBRA_SR_POLICY_NOTIFY_STATUS: - if (zclient->sr_policy_notify_status) - (*zclient->sr_policy_notify_status)(command, zclient, - length, vrf_id); - break; - case ZEBRA_CLIENT_CLOSE_NOTIFY: - if (zclient->zebra_client_close_notify) - (*zclient->zebra_client_close_notify)(command, zclient, - length, vrf_id); - break; - case ZEBRA_NHRP_NEIGH_ADDED: - if (zclient->neighbor_added) - (*zclient->neighbor_added)(command, zclient, length, - vrf_id); - break; - case ZEBRA_NHRP_NEIGH_REMOVED: - if (zclient->neighbor_removed) - (*zclient->neighbor_removed)(command, zclient, length, - vrf_id); - break; - case ZEBRA_NHRP_NEIGH_GET: - if (zclient->neighbor_get) - (*zclient->neighbor_get)(command, zclient, length, - vrf_id); - break; - case ZEBRA_GRE_UPDATE: - if (zclient->gre_update) - (*zclient->gre_update)(command, zclient, - length, vrf_id); - break; - default: - break; - } + if (command < array_size(lib_handlers) && lib_handlers[command]) + lib_handlers[command](command, zclient, length, vrf_id); + if (command < zclient->n_handlers && zclient->handlers[command]) + zclient->handlers[command](command, zclient, length, vrf_id); if (zclient->sock < 0) /* Connection was closed during packet processing. */ @@ -4459,11 +4247,9 @@ static int zclient_neigh_ip_read_entry(struct stream *s, struct ipaddr *add) return -1; } -int zclient_neigh_ip_encode(struct stream *s, - uint16_t cmd, - union sockunion *in, - union sockunion *out, - struct interface *ifp) +int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in, + union sockunion *out, struct interface *ifp, + int ndm_state) { int ret = 0; @@ -4478,7 +4264,7 @@ int zclient_neigh_ip_encode(struct stream *s, stream_putc(s, AF_UNSPEC); stream_putl(s, ifp->ifindex); if (out) - stream_putl(s, ZEBRA_NEIGH_STATE_REACHABLE); + stream_putl(s, ndm_state); else stream_putl(s, ZEBRA_NEIGH_STATE_FAILED); return ret; |
