From 0d9e7f455e0c5cb4bfac9d0b955adcc529d56431 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 22 Jan 2018 18:16:59 -0500 Subject: [PATCH 1/4] lib: Cleanup some zclient clutter. The zclient code can be cleaned up a tiny bit and hopefully improve it's indentation some. Signed-off-by: Donald Sharp --- lib/zclient.c | 78 +++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index d4a7b45b97..b5372a32ee 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -389,25 +389,28 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id) vrf_id); /* Flush all redistribute request. */ - if (vrf_id == VRF_DEFAULT) - for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - if (zclient->mi_redist[afi][i].enabled) { - struct listnode *node; - u_short *id; + if (vrf_id == VRF_DEFAULT) { + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (!zclient->mi_redist[afi][i].enabled) + continue; - for (ALL_LIST_ELEMENTS_RO( - zclient->mi_redist[afi][i] - .instances, - node, id)) - if (!(i == zclient->redist_default - && *id == zclient->instance)) - zebra_redistribute_send( - ZEBRA_REDISTRIBUTE_ADD, - zclient, afi, i, - *id, - VRF_DEFAULT); - } + struct listnode *node; + u_short *id; + + for (ALL_LIST_ELEMENTS_RO( + zclient->mi_redist[afi][i] + .instances, node, id)) + if (!(i == zclient->redist_default + && *id == zclient->instance)) + zebra_redistribute_send( + ZEBRA_REDISTRIBUTE_ADD, + zclient, afi, i, + *id, + VRF_DEFAULT); + } + } + } /* Flush all redistribute request. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) @@ -451,25 +454,28 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id) vrf_id); /* Flush all redistribute request. */ - if (vrf_id == VRF_DEFAULT) - for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - if (zclient->mi_redist[afi][i].enabled) { - struct listnode *node; - u_short *id; + if (vrf_id == VRF_DEFAULT) { + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (!zclient->mi_redist[afi][i].enabled) + continue; - for (ALL_LIST_ELEMENTS_RO( - zclient->mi_redist[afi][i] - .instances, - node, id)) - if (!(i == zclient->redist_default - && *id == zclient->instance)) - zebra_redistribute_send( - ZEBRA_REDISTRIBUTE_DELETE, - zclient, afi, i, - *id, - VRF_DEFAULT); - } + struct listnode *node; + u_short *id; + + for (ALL_LIST_ELEMENTS_RO( + zclient->mi_redist[afi][i] + .instances, node, id)) + if (!(i == zclient->redist_default + && *id == zclient->instance)) + zebra_redistribute_send( + ZEBRA_REDISTRIBUTE_DELETE, + zclient, afi, i, + *id, + VRF_DEFAULT); + } + } + } /* Flush all redistribute request. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) From 09eef679fb19ef0a731f4a72009eed071847da19 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 22 Jan 2018 18:18:38 -0500 Subject: [PATCH 2/4] lib: Unset bitmap when not using it The zclient->redist bitmap for vrf's was being set again for the zclient_send_dereg_requests function. This should be a unset on tear down. Signed-off-by: Donald Sharp --- lib/zclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index b5372a32ee..9045b5b6ce 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -450,8 +450,8 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id) /* Set unwanted redistribute route. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) - vrf_bitmap_set(zclient->redist[afi][zclient->redist_default], - vrf_id); + vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default], + vrf_id); /* Flush all redistribute request. */ if (vrf_id == VRF_DEFAULT) { From daeda3d7ff34ec1c4f26f987ec361364f5ef7b66 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 22 Jan 2018 18:22:09 -0500 Subject: [PATCH 3/4] pimd: No need to assert on the redist_default zclient_init sets the redist_default to the appropriate value, testing it with an assert doesn't really provide us with much of anything useful. Signed-off-by: Donald Sharp --- pimd/pim_zebra.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 6e82558766..2970dcee5e 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -765,8 +765,6 @@ void pim_zebra_init(void) zlog_info("zclient_init cleared redistribution request"); } - zassert(zclient->redist_default == ZEBRA_ROUTE_PIM); - /* Request all redistribution */ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { if (i == zclient->redist_default) From 3c1925406846d0e2d981086ea4d3c9fb09dc8b4a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 22 Jan 2018 18:36:03 -0500 Subject: [PATCH 4/4] bgpd, lib, pimd: Abstract commands for nexthop tracking Abstract the code that sends the zapi message into zebra for the turn on/off of nexthop tracking for a prefix. Signed-off-by: Donald Sharp --- bgpd/bgp_nht.c | 29 +++++------------------------ lib/zclient.c | 27 +++++++++++++++++++++++++++ lib/zclient.h | 3 +++ pimd/pim_nht.c | 28 +--------------------------- 4 files changed, 36 insertions(+), 51 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 247884d294..a963838f5f 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -572,12 +572,11 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p) */ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) { - struct stream *s; struct prefix *p; + bool exact_match = false; int ret; - /* Check socket. */ - if (!zclient || zclient->sock < 0) + if (!zclient) return; /* Don't try to register if Zebra doesn't know of this instance. */ @@ -585,32 +584,14 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) return; p = &(bnc->node->p); - s = zclient->obuf; - stream_reset(s); - zclient_create_header(s, command, bnc->bgp->vrf_id); if ((command == ZEBRA_NEXTHOP_REGISTER || command == ZEBRA_IMPORT_ROUTE_REGISTER) && (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED) || CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))) - stream_putc(s, 1); - else - stream_putc(s, 0); + exact_match = true; - stream_putw(s, PREFIX_FAMILY(p)); - stream_putc(s, p->prefixlen); - switch (PREFIX_FAMILY(p)) { - case AF_INET: - stream_put_in_addr(s, &p->u.prefix4); - break; - case AF_INET6: - stream_put(s, &(p->u.prefix6), 16); - break; - default: - break; - } - stream_putw_at(s, 0, stream_get_endp(s)); - - ret = zclient_send_message(zclient); + ret = zclient_send_rnh(zclient, command, p, + exact_match, bnc->bgp->vrf_id); /* TBD: handle the failure */ if (ret < 0) zlog_warn("sendmsg_nexthop: zclient_send_message() failed"); diff --git a/lib/zclient.c b/lib/zclient.c index 9045b5b6ce..9d863a3b26 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -614,6 +614,33 @@ static int zclient_connect(struct thread *t) return zclient_start(zclient); } +int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p, + bool exact_match, 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_putw(s, PREFIX_FAMILY(p)); + stream_putc(s, p->prefixlen); + switch (PREFIX_FAMILY(p)) { + case AF_INET: + stream_put_in_addr(s, &p->u.prefix4); + break; + case AF_INET6: + stream_put(s, &(p->u.prefix6), 16); + break; + default: + break; + } + stream_putw_at(s, 0, stream_get_endp(s)); + + return zclient_send_message(zclient); +} + /* * "xdr_encode"-like interface that allows daemon (client) to send * a message to zebra server for a route that needs to be diff --git a/lib/zclient.h b/lib/zclient.h index 00ad692718..847c2904d0 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -478,6 +478,9 @@ extern int zapi_ipv4_route_ipv6_nexthop(u_char, struct zclient *, struct zapi_ipv6 *) __attribute__((deprecated)); extern int zclient_route_send(u_char, struct zclient *, struct zapi_route *); +extern int zclient_send_rnh(struct zclient *zclient, int command, + struct prefix *p, bool exact_match, + vrf_id_t vrf_id); extern int zapi_route_encode(u_char, struct stream *, struct zapi_route *); extern int zapi_route_decode(struct stream *, struct zapi_route *); bool zapi_route_notify_decode(struct stream *s, struct prefix *p, diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 089639c77e..ccef796724 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -47,40 +47,14 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient, struct pim_nexthop_cache *pnc, int command) { - struct stream *s; struct prefix *p; int ret; - /* Check socket. */ - if (!zclient || zclient->sock < 0) - return; - p = &(pnc->rpf.rpf_addr); - s = zclient->obuf; - stream_reset(s); - zclient_create_header(s, command, pim->vrf_id); - /* get update for all routes for a prefix */ - stream_putc(s, 0); - - stream_putw(s, PREFIX_FAMILY(p)); - stream_putc(s, p->prefixlen); - switch (PREFIX_FAMILY(p)) { - case AF_INET: - stream_put_in_addr(s, &p->u.prefix4); - break; - case AF_INET6: - stream_put(s, &(p->u.prefix6), 16); - break; - default: - break; - } - stream_putw_at(s, 0, stream_get_endp(s)); - - ret = zclient_send_message(zclient); + ret = zclient_send_rnh(zclient, command, p, false, pim->vrf_id); if (ret < 0) zlog_warn("sendmsg_nexthop: zclient_send_message() failed"); - if (PIM_DEBUG_PIM_NHT) { char buf[PREFIX2STR_BUFFER]; prefix2str(p, buf, sizeof(buf));