diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-02-05 03:44:29 -0500 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-02-05 03:44:29 -0500 |
| commit | 4a749e2cb20a0b473e7f1e7e17d8f2b8a4469aef (patch) | |
| tree | 645311846435f7b34d51095a065ffe6e15bb0d2b /lib/zclient.c | |
| parent | aab09c104e38dff1b046e6af01b5eaafa52dd10c (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.c | 66 |
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 |
