diff options
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 254 |
1 files changed, 209 insertions, 45 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index 2cac71ac45..7308beaaf2 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -88,10 +88,11 @@ void zclient_free(struct zclient *zclient) XFREE(MTYPE_ZCLIENT, zclient); } -u_short *redist_check_instance(struct redist_proto *red, u_short instance) +unsigned short *redist_check_instance(struct redist_proto *red, + unsigned short instance) { struct listnode *node; - u_short *id; + unsigned short *id; if (!red->instances) return NULL; @@ -103,23 +104,23 @@ u_short *redist_check_instance(struct redist_proto *red, u_short instance) return NULL; } -void redist_add_instance(struct redist_proto *red, u_short instance) +void redist_add_instance(struct redist_proto *red, unsigned short instance) { - u_short *in; + unsigned short *in; red->enabled = 1; if (!red->instances) red->instances = list_new(); - in = XMALLOC(MTYPE_REDIST_INST, sizeof(u_short)); + in = XMALLOC(MTYPE_REDIST_INST, sizeof(unsigned short)); *in = instance; listnode_add(red->instances, in); } -void redist_del_instance(struct redist_proto *red, u_short instance) +void redist_del_instance(struct redist_proto *red, unsigned short instance) { - u_short *id; + unsigned short *id; id = redist_check_instance(red, instance); if (!id) @@ -294,9 +295,9 @@ void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id) stream_putw(s, command); } -int zclient_read_header(struct stream *s, int sock, u_int16_t *size, - u_char *marker, u_char *version, vrf_id_t *vrf_id, - u_int16_t *cmd) +int zclient_read_header(struct stream *s, int sock, uint16_t *size, + uint8_t *marker, uint8_t *version, vrf_id_t *vrf_id, + uint16_t *cmd) { if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE) return -1; @@ -423,7 +424,7 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id) continue; struct listnode *node; - u_short *id; + unsigned short *id; for (ALL_LIST_ELEMENTS_RO( zclient->mi_redist[afi][i] @@ -488,7 +489,7 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id) continue; struct listnode *node; - u_short *id; + unsigned short *id; for (ALL_LIST_ELEMENTS_RO( zclient->mi_redist[afi][i] @@ -594,8 +595,8 @@ int zclient_start(struct zclient *zclient) /* Initialize zebra client. Argument redist_default is unwanted redistribute route type. */ -void zclient_init(struct zclient *zclient, int redist_default, u_short instance, - struct zebra_privs_t *privs) +void zclient_init(struct zclient *zclient, int redist_default, + unsigned short instance, struct zebra_privs_t *privs) { int afi, i; @@ -730,7 +731,7 @@ int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p, * * XXX: No attention paid to alignment. */ -int zapi_ipv4_route(u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, +int zapi_ipv4_route(uint8_t cmd, struct zclient *zclient, struct prefix_ipv4 *p, struct zapi_ipv4 *api) { int i; @@ -765,7 +766,7 @@ int zapi_ipv4_route(u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, /* Put prefix information. */ psize = PSIZE(p->prefixlen); stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); + stream_write(s, (uint8_t *)&p->prefix, psize); /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { @@ -800,7 +801,7 @@ int zapi_ipv4_route(u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, return zclient_send_message(zclient); } -int zapi_ipv4_route_ipv6_nexthop(u_char cmd, struct zclient *zclient, +int zapi_ipv4_route_ipv6_nexthop(uint8_t cmd, struct zclient *zclient, struct prefix_ipv4 *p, struct zapi_ipv6 *api) { int i; @@ -835,7 +836,7 @@ int zapi_ipv4_route_ipv6_nexthop(u_char cmd, struct zclient *zclient, /* Put prefix information. */ psize = PSIZE(p->prefixlen); stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); + stream_write(s, (uint8_t *)&p->prefix, psize); /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { @@ -843,7 +844,7 @@ int zapi_ipv4_route_ipv6_nexthop(u_char cmd, struct zclient *zclient, for (i = 0; i < api->nexthop_num; i++) { stream_putc(s, NEXTHOP_TYPE_IPV6); - stream_write(s, (u_char *)api->nexthop[i], 16); + 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)) @@ -870,7 +871,7 @@ int zapi_ipv4_route_ipv6_nexthop(u_char cmd, struct zclient *zclient, return zclient_send_message(zclient); } -int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, +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; @@ -909,12 +910,12 @@ int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, /* Put prefix information. */ psize = PSIZE(p->prefixlen); stream_putc(s, p->prefixlen); - stream_write(s, (u_char *)&p->prefix, psize); + 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, (u_char *)&src_p->prefix, psize); + stream_write(s, (uint8_t *)&src_p->prefix, psize); } /* Nexthop, ifindex, distance and metric information. */ @@ -923,7 +924,7 @@ int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, for (i = 0; i < api->nexthop_num; i++) { stream_putc(s, NEXTHOP_TYPE_IPV6); - stream_write(s, (u_char *)api->nexthop[i], 16); + 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)) @@ -950,7 +951,7 @@ int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, return zclient_send_message(zclient); } -int zclient_route_send(u_char cmd, struct zclient *zclient, +int zclient_route_send(uint8_t cmd, struct zclient *zclient, struct zapi_route *api) { if (zapi_route_encode(cmd, zclient->obuf, api) < 0) @@ -958,7 +959,7 @@ int zclient_route_send(u_char cmd, struct zclient *zclient, return zclient_send_message(zclient); } -int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) +int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) { struct zapi_nexthop *api_nh; int i; @@ -979,12 +980,12 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) stream_putc(s, api->prefix.family); psize = PSIZE(api->prefix.prefixlen); stream_putc(s, api->prefix.prefixlen); - stream_write(s, (u_char *)&api->prefix.u.prefix, psize); + stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize); if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) { psize = PSIZE(api->src_prefix.prefixlen); stream_putc(s, api->src_prefix.prefixlen); - stream_write(s, (u_char *)&api->src_prefix.prefix, psize); + stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize); } /* Nexthops. */ @@ -1023,11 +1024,11 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) stream_putl(s, api_nh->ifindex); break; case NEXTHOP_TYPE_IPV6: - stream_write(s, (u_char *)&api_nh->gate.ipv6, + stream_write(s, (uint8_t *)&api_nh->gate.ipv6, 16); break; case NEXTHOP_TYPE_IPV6_IFINDEX: - stream_write(s, (u_char *)&api_nh->gate.ipv6, + stream_write(s, (uint8_t *)&api_nh->gate.ipv6, 16); stream_putl(s, api_nh->ifindex); break; @@ -1364,7 +1365,7 @@ stream_failure: * sending client */ int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi, - int type, u_short instance, vrf_id_t vrf_id) + int type, unsigned short instance, vrf_id_t vrf_id) { struct stream *s; @@ -1385,7 +1386,7 @@ int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi, static void zclient_stream_get_prefix(struct stream *s, struct prefix *p) { size_t plen = prefix_blen(p); - u_char c; + uint8_t c; p->prefixlen = 0; if (plen == 0) @@ -1597,7 +1598,7 @@ struct interface *zebra_interface_link_params_read(struct stream *s) void zebra_interface_if_set_value(struct stream *s, struct interface *ifp) { - u_char link_params_status = 0; + uint8_t link_params_status = 0; /* Read interface's index. */ if_set_index(ifp, stream_getl(s)); @@ -1700,7 +1701,7 @@ size_t zebra_interface_link_params_write(struct stream *s, static int memconstant(const void *s, int c, size_t n) { - const u_char *p = s; + const uint8_t *p = s; while (n-- > 0) if (*p++ != c) @@ -1717,7 +1718,7 @@ struct connected *zebra_interface_address_read(int type, struct stream *s, struct connected *ifc; struct prefix p, d, *dp; int plen; - u_char ifc_flags; + uint8_t ifc_flags; memset(&p, 0, sizeof(p)); memset(&d, 0, sizeof(d)); @@ -1882,14 +1883,14 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s, /* filter unwanted messages until the expected one arrives */ static int zclient_read_sync_response(struct zclient *zclient, - u_int16_t expected_cmd) + uint16_t expected_cmd) { struct stream *s; - u_int16_t size = -1; - u_char marker; - u_char version; + uint16_t size = -1; + uint8_t marker; + uint8_t version; vrf_id_t vrf_id; - u_int16_t cmd; + uint16_t cmd; fd_set readfds; int ret; @@ -1932,7 +1933,7 @@ int lm_label_manager_connect(struct zclient *zclient) { int ret; struct stream *s; - u_char result; + uint8_t result; if (zclient_debug) zlog_debug("Connecting to Label Manager"); @@ -1999,12 +2000,12 @@ int lm_label_manager_connect(struct zclient *zclient) * @param end To write last assigned chunk label to * @result 0 on success, -1 otherwise */ -int lm_get_label_chunk(struct zclient *zclient, u_char keep, +int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t chunk_size, uint32_t *start, uint32_t *end) { int ret; struct stream *s; - u_char response_keep; + uint8_t response_keep; if (zclient_debug) zlog_debug("Getting Label Chunk"); @@ -2122,6 +2123,168 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start, return 0; } +/** + * Connect to table manager in a syncronous way + * + * It first writes the request to zcient output buffer and then + * immediately reads the answer from the input buffer. + * + * @param zclient Zclient used to connect to table manager (zebra) + * @result Result of response + */ +int tm_table_manager_connect(struct zclient *zclient) +{ + int ret; + struct stream *s; + uint8_t result; + + if (zclient_debug) + zlog_debug("Connecting to Table Manager"); + + if (zclient->sock < 0) + return -1; + + /* send request */ + s = zclient->obuf; + stream_reset(s); + zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT); + + /* proto */ + stream_putc(s, zclient->redist_default); + /* instance */ + stream_putw(s, zclient->instance); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + ret = zclient_send_message(zclient); + if (ret < 0) + return -1; + + if (zclient_debug) + zlog_debug("%s: Table manager connect request sent", + __func__); + + /* read response */ + if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT) + != 0) + return -1; + + /* result */ + s = zclient->ibuf; + STREAM_GETC(s, result); + if (zclient_debug) + zlog_debug( + "%s: Table Manager connect response received, result %u", + __func__, result); + + return (int)result; +stream_failure: + return 0; +} + +/** + * Function to request a table chunk in a syncronous way + * + * 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) + * @param chunk_size Amount of table requested + * @param start to write first assigned chunk table RT ID to + * @param end To write last assigned chunk table RT ID to + * @result 0 on success, -1 otherwise + */ +int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size, + uint32_t *start, uint32_t *end) +{ + int ret; + struct stream *s; + + if (zclient_debug) + zlog_debug("Getting Table Chunk"); + + if (zclient->sock < 0) + return -1; + + /* send request */ + s = zclient->obuf; + stream_reset(s); + zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT); + /* chunk size */ + stream_putl(s, chunk_size); + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + ret = writen(zclient->sock, s->data, stream_get_endp(s)); + if (ret < 0) { + zlog_err("%s: can't write to zclient->sock", __func__); + close(zclient->sock); + zclient->sock = -1; + return -1; + } + if (ret == 0) { + zlog_err("%s: zclient->sock connection closed", __func__); + close(zclient->sock); + zclient->sock = -1; + return -1; + } + if (zclient_debug) + zlog_debug("%s: Table chunk request (%d bytes) sent", __func__, + ret); + + /* read response */ + if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0) + return -1; + + s = zclient->ibuf; + /* start and end table IDs */ + STREAM_GETL(s, *start); + STREAM_GETL(s, *end); + + if (zclient_debug) + zlog_debug("Table Chunk assign: %u - %u ", *start, *end); + +stream_failure: + return 0; +} + +/** + * Function to release a table chunk + * + * @param zclient Zclient used to connect to table manager (zebra) + * @param start First label of table + * @param end Last label of chunk + * @result 0 on success, -1 otherwise + */ +int tm_release_table_chunk(struct zclient *zclient, uint32_t start, + uint32_t end) +{ + struct stream *s; + + if (zclient_debug) + zlog_debug("Releasing Table Chunk"); + + if (zclient->sock < 0) + return -1; + + /* send request */ + s = zclient->obuf; + stream_reset(s); + zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT); + + /* start */ + stream_putl(s, start); + /* end */ + stream_putl(s, end); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return zclient_send_message(zclient); +} + + int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw) { struct stream *s; @@ -2144,7 +2307,7 @@ int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw) stream_put_in_addr(s, &pw->nexthop.ipv4); break; case AF_INET6: - stream_write(s, (u_char *)&pw->nexthop.ipv6, 16); + stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16); break; default: zlog_err("%s: unknown af", __func__); @@ -2247,7 +2410,8 @@ static int zclient_read(struct thread *thread) struct stream *ns; zlog_warn( "%s: message size %u exceeds buffer size %lu, expanding...", - __func__, length, (u_long)STREAM_SIZE(zclient->ibuf)); + __func__, length, + (unsigned long)STREAM_SIZE(zclient->ibuf)); ns = stream_new(length); stream_copy(ns, zclient->ibuf); stream_free(zclient->ibuf); @@ -2452,7 +2616,7 @@ static int zclient_read(struct thread *thread) } void zclient_redistribute(int command, struct zclient *zclient, afi_t afi, - int type, u_short instance, vrf_id_t vrf_id) + int type, unsigned short instance, vrf_id_t vrf_id) { if (instance) { |
