From ab5990d8b9756d880f7e3f21772362d9c161b3e0 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 5 Oct 2018 09:28:41 -0400 Subject: [PATCH 1/3] zebra: Add counting to nexthop register/unregister events Add a bit of code to note how many register/unregister nht events we have had. Signed-off-by: Donald Sharp --- zebra/zapi_msg.c | 4 ++++ zebra/zserv.c | 4 ++++ zebra/zserv.h | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 7ea0a4d47d..42b0a81510 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1056,6 +1056,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS) STREAM_GETC(s, p.prefixlen); l += 4; if (p.family == AF_INET) { + client->v4_nh_watch_add_cnt++; if (p.prefixlen > IPV4_MAX_BITLEN) { zlog_debug( "%s: Specified prefix hdr->length %d is too large for a v4 address", @@ -1065,6 +1066,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS) STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN); l += IPV4_MAX_BYTELEN; } else if (p.family == AF_INET6) { + client->v6_nh_watch_add_cnt++; if (p.prefixlen > IPV6_MAX_BITLEN) { zlog_debug( "%s: Specified prefix hdr->length %d is to large for a v6 address", @@ -1139,6 +1141,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS) STREAM_GETC(s, p.prefixlen); l += 4; if (p.family == AF_INET) { + client->v4_nh_watch_rem_cnt++; if (p.prefixlen > IPV4_MAX_BITLEN) { zlog_debug( "%s: Specified prefix hdr->length %d is to large for a v4 address", @@ -1148,6 +1151,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS) STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN); l += IPV4_MAX_BYTELEN; } else if (p.family == AF_INET6) { + client->v6_nh_watch_rem_cnt++; if (p.prefixlen > IPV6_MAX_BITLEN) { zlog_debug( "%s: Specified prefix hdr->length %d is to large for a v6 address", diff --git a/zebra/zserv.c b/zebra/zserv.c index 8cc462577a..3c3bf4077b 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -940,6 +940,10 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) client->ifdel_cnt); vty_out(vty, "BFD peer %-12d%-12d%-12d\n", client->bfd_peer_add_cnt, client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt); + vty_out(vty, "NHT v4 %-12d%-12d%-12d\n", + client->v4_nh_watch_add_cnt, 0, client->v4_nh_watch_rem_cnt); + vty_out(vty, "NHT v6 %-12d%-12d%-12d\n", + client->v6_nh_watch_add_cnt, 0, client->v6_nh_watch_rem_cnt); vty_out(vty, "Interface Up Notifications: %d\n", client->ifup_cnt); vty_out(vty, "Interface Down Notifications: %d\n", client->ifdown_cnt); vty_out(vty, "VNI add notifications: %d\n", client->vniadd_cnt); diff --git a/zebra/zserv.h b/zebra/zserv.h index 987c67635d..f21ea17fe8 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -133,6 +133,10 @@ struct zserv { uint32_t macipdel_cnt; uint32_t prefixadd_cnt; uint32_t prefixdel_cnt; + uint32_t v4_nh_watch_add_cnt; + uint32_t v4_nh_watch_rem_cnt; + uint32_t v6_nh_watch_add_cnt; + uint32_t v6_nh_watch_rem_cnt; time_t nh_reg_time; time_t nh_dereg_time; From bb4ef1aec80227d318e48ed65c261b812e356f1b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 5 Oct 2018 09:43:28 -0400 Subject: [PATCH 2/3] bgpd: Add some debugs to note when we are not talking to zebra Allow some debug notification when we are unable to talk to zebra due to the connection not being there yet. Signed-off-by: Donald Sharp --- bgpd/bgp_evpn.c | 13 ++++++++++--- bgpd/bgp_nht.c | 6 +++++- bgpd/bgp_zebra.c | 23 +++++++++++++++++++---- bgpd/bgpd.c | 13 ++++++++++--- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 574ece8cc5..c91a2ab6bd 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -558,9 +558,12 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, return 0; /* Don't try to register if Zebra doesn't know of this instance. */ - if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: No zebra instance to talk to, not installing remote macip", + __PRETTY_FUNCTION__); return 0; - + } s = zclient->obuf; stream_reset(s); @@ -616,8 +619,12 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, return 0; /* Don't try to register if Zebra doesn't know of this instance. */ - if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: No zebra instance to talk to, not installing remote vtep", + __PRETTY_FUNCTION__); return 0; + } s = zclient->obuf; stream_reset(s); diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index e764860bcc..2e7f17fdae 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -587,8 +587,12 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) return; /* Don't try to register if Zebra doesn't know of this instance. */ - if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bnc->bgp)) + if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bnc->bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: No zebra instance to talk to, not installing NHT entry", + __PRETTY_FUNCTION__); return; + } p = &(bnc->node->p); if ((command == ZEBRA_NEXTHOP_REGISTER diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 81a5be9d0c..0b79a9ee18 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -68,8 +68,11 @@ static inline int bgp_install_info_to_zebra(struct bgp *bgp) if (zclient->sock <= 0) return 0; - if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + zlog_debug("%s: No zebra instance to talk to, not installing information", + __PRETTY_FUNCTION__); return 0; + } return 1; } @@ -1895,8 +1898,12 @@ int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ - if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: No zebra instance to talk to, cannot advertise subnet", + __PRETTY_FUNCTION__); return 0; + } s = zclient->obuf; stream_reset(s); @@ -1918,8 +1925,12 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni) return 0; /* Don't try to register if Zebra doesn't know of this instance. */ - if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: No zebra instance to talk to, not installing gw_macip", + __PRETTY_FUNCTION__); return 0; + } s = zclient->obuf; stream_reset(s); @@ -1942,8 +1953,12 @@ int bgp_zebra_vxlan_flood_control(struct bgp *bgp, return 0; /* Don't try to register if Zebra doesn't know of this instance. */ - if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: No zebra instance to talk to, not installing all vni", + __PRETTY_FUNCTION__); return 0; + } s = zclient->obuf; stream_reset(s); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index be092e9501..19384eec2f 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3072,9 +3072,12 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, true); listnode_add(bm->bgp, bgp); - if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: Registering BGP instance %s to zebra", + __PRETTY_FUNCTION__, name); bgp_zebra_instance_register(bgp); - + } return 0; } @@ -3218,8 +3221,12 @@ int bgp_delete(struct bgp *bgp) } /* Deregister from Zebra, if needed */ - if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) + if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: deregistering this bgp %s instance from zebra", + __PRETTY_FUNCTION__, bgp->name); bgp_zebra_instance_deregister(bgp); + } /* Remove visibility via the master list - there may however still be * routes to be processed still referencing the struct bgp. From 1ee0a2df0d7f7052485b455966757be2a5562a1d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 5 Oct 2018 11:31:29 -0400 Subject: [PATCH 3/3] bgpd: Allow registration of nexthops after zebra connection If we attempt to register nexthops before we have the zebra connection, they will not be installed. After we have noticed that we are up, re-install them. Signed-off-by: Donald Sharp --- bgpd/bgp_nexthop.c | 5 ++++- bgpd/bgp_nht.c | 36 ++++++++++++++++++++++++++++++++++-- bgpd/bgp_nht.h | 6 ++++++ bgpd/bgp_zebra.c | 2 ++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 5ed6fd6ebe..2ef792e129 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -628,7 +628,10 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail) if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) vty_out(vty, " Must be Connected\n"); - } + if (!CHECK_FLAG(bnc->flags, + BGP_NEXTHOP_REGISTERED)) + vty_out(vty, " Is not Registered\n"); + } tbuf = time(NULL) - (bgp_clock() - bnc->last_update); vty_out(vty, " Last update: %s", ctime(&tbuf)); vty_out(vty, "\n"); diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 2e7f17fdae..8aa7798af4 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -240,8 +240,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); } if (bgp_route->inst_type == BGP_INSTANCE_TYPE_VIEW) { - bnc->flags |= BGP_NEXTHOP_REGISTERED; - bnc->flags |= BGP_NEXTHOP_VALID; + SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED); + SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); } else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)) register_zebra_rnh(bnc, is_bgp_static_route); if (pi && pi->nexthop != bnc) { @@ -594,6 +594,11 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) return; } + if (!bgp_zebra_num_connects()) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: We have not connected yet, cannot send nexthops", + __PRETTY_FUNCTION__); + } p = &(bnc->node->p); if ((command == ZEBRA_NEXTHOP_REGISTER || command == ZEBRA_IMPORT_ROUTE_REGISTER) @@ -806,3 +811,30 @@ void path_nh_map(struct bgp_path_info *path, struct bgp_nexthop_cache *bnc, path->nexthop->path_count++; } } + +/* + * This function is called to register nexthops to zebra + * as that we may have tried to install the nexthops + * before we actually have a zebra connection + */ +void bgp_nht_register_nexthops(struct bgp *bgp) +{ + struct bgp_node *rn; + struct bgp_nexthop_cache *bnc; + afi_t afi; + + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + if (!bgp->nexthop_cache_table[afi]) + continue; + + for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn; + rn = bgp_route_next(rn)) { + bnc = bgp_nexthop_get_node_info(rn); + + if (!bnc) + continue; + + register_zebra_rnh(bnc, 0); + } + } +} diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h index 0cc045a065..96dd915596 100644 --- a/bgpd/bgp_nht.h +++ b/bgpd/bgp_nht.h @@ -81,5 +81,11 @@ extern void bgp_cleanup_nexthops(struct bgp *bgp); */ extern void path_nh_map(struct bgp_path_info *path, struct bgp_nexthop_cache *bnc, bool make); +/* + * When we actually have the connection to + * the zebra daemon, we need to reregister + * any nexthops we may have sitting around + */ +extern void bgp_nht_register_nexthops(struct bgp *bgp); #endif /* _BGP_NHT_H */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 0b79a9ee18..50b790eb11 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1837,6 +1837,8 @@ void bgp_zebra_instance_register(struct bgp *bgp) */ if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) bgp_zebra_advertise_all_vni(bgp, 1); + + bgp_nht_register_nexthops(bgp); } /* Deregister this instance with Zebra. Invoked upon the instance