summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-08-19 21:25:12 -0300
committerRenato Westphal <renato@opensourcerouting.org>2017-08-23 17:45:17 -0300
commitbb1b9c47ca090ce4484e1f8061f17b5c33f578ee (patch)
tree0b6f114b78a84f0dffeb7de41a685d33e152879e /lib/zclient.c
parent81c11e3feafcd20e32cb2d437f39603d645e6880 (diff)
lib: updates to zapi_route
This patch introduces the following changes to the zapi_route structure and associated code: * Use a fixed-size array to store the nexthops instead of a pointer. This makes the zapi_route() function much easier to use when we have multiple nexthops to send. It's also much more efficient to put everything on the stack rather than allocating an array in the heap every time we need to send a route to zebra; * Use the new 'zapi_nexthop' structure. This will allow the client daemons to send labeled routes without having to allocate memory for the labels (the 'nexthop' structure was designed to be memory efficient and doesn't have room for MPLS labels, only a pointer). Also, 'zapi_nexthop' is more compact and more clean from an API perspective; * Embed the route prefix inside the zapi_route structure. Since the route's prefix is sent along with its nexthops and attributes, it makes sense to pack everything inside the same structure. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c84
1 files changed, 37 insertions, 47 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index f8bbdd85c9..53e8569b77 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -892,16 +892,12 @@ int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
return zclient_send_message(zclient);
}
-int zapi_route(u_char cmd, struct zclient *zclient, struct prefix *p,
- struct prefix_ipv6 *src_p, struct zapi_route *api)
+int zapi_route(u_char cmd, struct zclient *zclient, struct zapi_route *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);
+ struct zapi_nexthop *api_nh;
/* Reset stream. */
s = zclient->obuf;
@@ -917,69 +913,63 @@ int zapi_route(u_char cmd, struct zclient *zclient, struct prefix *p,
stream_putw(s, api->safi);
/* Put prefix information. */
- psize = PSIZE(p->prefixlen);
- stream_putc(s, p->prefixlen);
- stream_write(s, (u_char *)&p->u.prefix, psize);
+ psize = PSIZE(api->prefix.prefixlen);
+ stream_putc(s, api->prefix.prefixlen);
+ stream_write(s, (u_char *)&api->prefix.u.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);
+ psize = PSIZE(api->src_prefix.prefixlen);
+ stream_putc(s, api->src_prefix.prefixlen);
+ stream_write(s, (u_char *)&api->src_prefix.prefix, psize);
}
/* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
+ /* limit the number of nexthops if necessary */
+ if (api->nexthop_num > MULTIPATH_NUM) {
+ char buf[PREFIX2STR_BUFFER];
+
+ prefix2str(&api->prefix, buf, sizeof(buf));
+ zlog_warn(
+ "%s: prefix %s: encoding %u nexthops out of %u",
+ __func__, buf, MULTIPATH_NUM, api->nexthop_num);
+ api->nexthop_num = MULTIPATH_NUM;
+ }
+
stream_putc(s, api->nexthop_num);
for (i = 0; i < api->nexthop_num; i++) {
- stream_putc(s, api->nexthop[i]->type);
- switch (api->nexthop[i]->type) {
+ api_nh = &api->nexthops[i];
+
+ stream_putc(s, api_nh->type);
+ switch (api_nh->type) {
case NEXTHOP_TYPE_BLACKHOLE:
break;
case NEXTHOP_TYPE_IPV4:
- stream_put_in_addr(s,
- &api->nexthop[i]->gate.ipv4);
-
- /* For labeled-unicast, each nexthop is followed
- * by label. */
- if (CHECK_FLAG(api->message,
- ZAPI_MESSAGE_LABEL))
- stream_putl(
- s,
- api->nexthop[i]
- ->nh_label->label[0]);
+ stream_put_in_addr(s, &api_nh->gate.ipv4);
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
- stream_put_in_addr(s,
- &api->nexthop[i]->gate.ipv4);
- stream_putl(s, api->nexthop[i]->ifindex);
+ stream_put_in_addr(s, &api_nh->gate.ipv4);
+ stream_putl(s, api_nh->ifindex);
break;
case NEXTHOP_TYPE_IFINDEX:
- stream_putl(s, api->nexthop[i]->ifindex);
+ stream_putl(s, api_nh->ifindex);
break;
case NEXTHOP_TYPE_IPV6:
- stream_write(
- s,
- (u_char *)&api->nexthop[i]->gate.ipv6,
- 16);
-
- /* For labeled-unicast, each nexthop is followed
- * by label. */
- if (CHECK_FLAG(api->message,
- ZAPI_MESSAGE_LABEL))
- stream_putl(
- s,
- api->nexthop[i]
- ->nh_label->label[0]);
+ stream_write(s, (u_char *)&api_nh->gate.ipv6,
+ 16);
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
- stream_write(
- s,
- (u_char *)&api->nexthop[i]->gate.ipv6,
- 16);
- stream_putl(s, api->nexthop[i]->ifindex);
+ stream_write(s, (u_char *)&api_nh->gate.ipv6,
+ 16);
+ stream_putl(s, api_nh->ifindex);
break;
}
+
+ /* For labeled-unicast, each nexthop is followed
+ * by label. */
+ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
+ stream_putl(s, api_nh->label);
}
}