summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-02-05 03:44:29 -0500
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-02-05 03:44:29 -0500
commit4a749e2cb20a0b473e7f1e7e17d8f2b8a4469aef (patch)
tree645311846435f7b34d51095a065ffe6e15bb0d2b /lib/zclient.c
parentaab09c104e38dff1b046e6af01b5eaafa52dd10c (diff)
bgpd, lib, pimd: Make nexthop_update decoding common
Create a zapi_nexthop_update_decode function that both pim and bgp use to decode the message from zebra. There probably could be further optimizations but I opted to keep the code as similiar as is possible between the originals because they both make some assumptions about code flow that I do not fully understand yet. The real goal here is that I want to create a new user of the nexthop tracking code from a higher level daemon and I see no need to re-implement this damn code again for a 3rd time. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index d3717d0cdd..cba9640f15 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1212,6 +1212,72 @@ stream_failure:
return false;
}
+struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
+{
+ struct nexthop *n = nexthop_new();
+
+ n->type = znh->type;
+ n->ifindex = znh->ifindex;
+ n->gate = znh->gate;
+
+ /*
+ * This function does not currently handle labels
+ */
+
+ return n;
+}
+
+bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
+{
+ uint32_t i;
+
+ memset(nhr, 0, sizeof(*nhr));
+
+ STREAM_GETW(s, nhr->prefix.family);
+ STREAM_GETC(s, nhr->prefix.prefixlen);
+ switch(nhr->prefix.family) {
+ case AF_INET:
+ STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
+ break;
+ case AF_INET6:
+ STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
+ break;
+ default:
+ break;
+ }
+
+ STREAM_GETC(s, nhr->distance);
+ STREAM_GETL(s, nhr->metric);
+ STREAM_GETC(s, nhr->nexthop_num);
+
+ for (i = 0; i < nhr->nexthop_num ; i++) {
+ STREAM_GETC(s, nhr->nexthops[i].type);
+ switch (nhr->nexthops[i].type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ STREAM_GET(&nhr->nexthops[i].gate.ipv4.s_addr,
+ s, IPV4_MAX_BYTELEN);
+ STREAM_GETL(s, nhr->nexthops[i].ifindex);
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ STREAM_GETL(s, nhr->nexthops[i].ifindex);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ STREAM_GET(&nhr->nexthops[i].gate.ipv6,
+ s, IPV6_MAX_BYTELEN);
+ STREAM_GETL(s, nhr->nexthops[i].ifindex);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ break;
+ }
+ }
+
+ 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