diff options
| -rw-r--r-- | bgpd/bgp_updgrp_adv.c | 24 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 3 | ||||
| -rw-r--r-- | doc/user/rpki.rst | 34 | ||||
| -rw-r--r-- | lib/keychain.c | 2 | ||||
| -rw-r--r-- | lib/sockopt.c | 2 | ||||
| -rw-r--r-- | lib/thread.c | 1 | ||||
| -rw-r--r-- | pimd/pim_nht.c | 72 | ||||
| -rw-r--r-- | pimd/pim_zebra.c | 156 | ||||
| -rw-r--r-- | pimd/pim_zebra.h | 5 | ||||
| -rw-r--r-- | ripd/rip_interface.c | 45 | ||||
| -rw-r--r-- | ripd/rip_memory.c | 1 | ||||
| -rw-r--r-- | ripd/rip_memory.h | 1 | ||||
| -rw-r--r-- | ripd/ripd.c | 4 | ||||
| -rwxr-xr-x | tools/frr | 6 | ||||
| -rw-r--r-- | zebra/zserv.c | 15 |
15 files changed, 168 insertions, 203 deletions
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 1f80470f59..f44e95a50a 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -662,6 +662,7 @@ void subgroup_announce_route(struct update_subgroup *subgrp) void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) { struct bgp *bgp; + struct attr attr; struct bgp_info *info, init_info; struct prefix p; struct peer *from; @@ -685,8 +686,23 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) bgp = peer->bgp; from = bgp->peer_self; - init_info.attr = NULL; + bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); + attr.local_pref = bgp->default_local_pref; + + if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) { + /* IPv6 global nexthop must be included. + */ + attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; + + /* If the peer is on shared nextwork and + * we have link-local nexthop set it. */ + if (peer->shared_network + && !IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_local)) + attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL; + } + init_info.attr = &attr; info = &init_info; + bgp_attr_intern(info->attr); memset(&p, 0, sizeof(p)); p.family = afi2family(afi); @@ -709,13 +725,9 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) { - /* IPv6 global nexthop must be included. - */ tmp_info.attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; - /* If the peer is on shared nextwork and - * we have link-local nexthop set it. */ if (peer->shared_network && !IN6_IS_ADDR_UNSPECIFIED( &peer->nexthop.v6_local)) @@ -728,6 +740,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) &rn->p, RMAP_BGP, &tmp_info); info = &tmp_info; + bgp_attr_intern(info->attr); if (ret != RMAP_DENYMATCH) break; @@ -776,6 +789,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE); } } + aspath_unintern(&info->attr->aspath); } /* diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index b5fb653bae..82da0245b5 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3120,6 +3120,9 @@ int bgp_delete(struct bgp *bgp) assert(bgp); THREAD_OFF(bgp->t_startup); + THREAD_OFF(bgp->t_maxmed_onstartup); + THREAD_OFF(bgp->t_update_delay); + THREAD_OFF(bgp->t_establish_wait); if (BGP_DEBUG(zebra, ZEBRA)) { if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) diff --git a/doc/user/rpki.rst b/doc/user/rpki.rst index 4f271dee74..f48ff2e6ba 100644 --- a/doc/user/rpki.rst +++ b/doc/user/rpki.rst @@ -67,32 +67,32 @@ Enabling RPKI to configure at least one reachable cache server. See section :ref:`configuring-rpki-rtr-cache-servers` for configuring a cache server. -.. index:: daemons.conf +.. index:: RPKI and daemons.conf - When first installing FRR with RPKI support from the pre-packaged binaries. - Remember to append :option:`-M rpki` in the :file:`/etc/frr/daemons.conf` - file to ``bgpd_options``, like so:: +When first installing FRR with RPKI support from the pre-packaged binaries. +Remember to add ``-M rpki`` to the variable ``bgpd_options`` in +:file:`/etc/frr/daemons.conf` , like so:: - bgpd_options=" --daemon -A 127.0.0.1 -M rpki" + bgpd_options=" --daemon -A 127.0.0.1 -M rpki" - instead of the default setting:: +instead of the default setting:: - bgpd_options=" --daemon -A 127.0.0.1" + bgpd_options=" --daemon -A 127.0.0.1" - Otherwise you will encounter an error when trying to enter RPKI - configuration mode due to the ``rpki`` module not being loaded when the BGP - daemon is initialized. +Otherwise you will encounter an error when trying to enter RPKI +configuration mode due to the ``rpki`` module not being loaded when the BGP +daemon is initialized. - Examples of the error:: +Examples of the error:: - router(config)# debug rpki - % [BGP] Unknown command: debug rpki + router(config)# debug rpki + % [BGP] Unknown command: debug rpki - router(config)# rpki - % [BGP] Unknown command: rpki + router(config)# rpki + % [BGP] Unknown command: rpki - Note that the RPKI commands will be available in vtysh when running ``find - rpki`` regardless of whether the module is loaded. +Note that the RPKI commands will be available in vtysh when running +``find rpki`` regardless of whether the module is loaded. .. _configuring-rpki-rtr-cache-servers: diff --git a/lib/keychain.c b/lib/keychain.c index c3e1a6d3c4..494f6f6430 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -172,7 +172,7 @@ struct key *key_match_for_accept(const struct keychain *keychain, if (key->accept.start == 0 || (key->accept.start <= now && (key->accept.end >= now || key->accept.end == -1))) - if (strncmp(key->string, auth_str, 16) == 0) + if (key->string && (strncmp(key->string, auth_str, 16) == 0)) return key; } return NULL; diff --git a/lib/sockopt.c b/lib/sockopt.c index 815be86c2e..e979bef174 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -75,7 +75,7 @@ static void *getsockopt_cmsg_data(struct msghdr *msgh, int level, int type) for (cmsg = ZCMSG_FIRSTHDR(msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(msgh, cmsg)) - if (cmsg->cmsg_level == level && cmsg->cmsg_type) + if (cmsg->cmsg_level == level && cmsg->cmsg_type == type) return (ptr = CMSG_DATA(cmsg)); return NULL; diff --git a/lib/thread.c b/lib/thread.c index 1c5e838772..898e9e9fce 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -782,6 +782,7 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m, { struct thread *thread = NULL; + assert(fd >= 0 && fd < m->fd_limit); pthread_mutex_lock(&m->mtx); { if (t_ptr diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 7d1940bec1..74dfed0455 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -300,59 +300,9 @@ static int pim_update_upstream_nh_helper(struct hash_backet *backet, void *arg) } } - if (rpf_result == PIM_RPF_CHANGED) { - struct pim_neighbor *nbr; + if (rpf_result == PIM_RPF_CHANGED) + pim_zebra_upstream_rpf_changed(pim, up, &old); - nbr = pim_neighbor_find(old.source_nexthop.interface, - old.rpf_addr.u.prefix4); - if (nbr) - pim_jp_agg_remove_group(nbr->upstream_jp_agg, up); - - /* - * We have detected a case where we might need to rescan - * the inherited o_list so do it. - */ - if (up->channel_oil && up->channel_oil->oil_inherited_rescan) { - pim_upstream_inherited_olist_decide(pim, up); - up->channel_oil->oil_inherited_rescan = 0; - } - - if (up->join_state == PIM_UPSTREAM_JOINED) { - /* - * If we come up real fast we can be here - * where the mroute has not been installed - * so install it. - */ - if (up->channel_oil && !up->channel_oil->installed) - pim_mroute_add(up->channel_oil, - __PRETTY_FUNCTION__); - - /* - * RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages - * - * Transitions from Joined State - * - * RPF'(S,G) changes not due to an Assert - * - * The upstream (S,G) state machine remains in Joined - * state. Send Join(S,G) to the new upstream - * neighbor, which is the new value of RPF'(S,G). - * Send Prune(S,G) to the old upstream neighbor, which - * is the old value of RPF'(S,G). Set the Join - * Timer (JT) to expire after t_periodic seconds. - */ - pim_jp_agg_switch_interface(&old, &up->rpf, up); - - pim_upstream_join_timer_restart(up, &old); - } /* up->join_state == PIM_UPSTREAM_JOINED */ - - /* - * FIXME can join_desired actually be changed by - * pim_rpf_update() returning PIM_RPF_CHANGED ? - */ - pim_upstream_update_join_desired(pim, up); - - } /* PIM_RPF_CHANGED */ if (PIM_DEBUG_PIM_NHT) { zlog_debug("%s: NHT upstream %s(%s) old ifp %s new ifp %s", @@ -367,25 +317,9 @@ static int pim_update_upstream_nh_helper(struct hash_backet *backet, void *arg) static int pim_update_upstream_nh(struct pim_instance *pim, struct pim_nexthop_cache *pnc) { - struct listnode *node; - struct interface *ifp; - hash_walk(pnc->upstream_hash, pim_update_upstream_nh_helper, pim); - FOR_ALL_INTERFACES (pim->vrf, ifp) - if (ifp->info) { - struct pim_interface *pim_ifp = ifp->info; - struct pim_iface_upstream_switch *us; - - for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, - node, us)) { - struct pim_rpf rpf; - rpf.source_nexthop.interface = ifp; - rpf.rpf_addr.u.prefix4 = us->address; - pim_joinprune_send(&rpf, us->us); - pim_jp_agg_clear_group(us->us); - } - } + pim_zebra_update_all_interfaces(pim); return 0; } diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index b947ca0625..ab6258ad36 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -425,13 +425,91 @@ static int pim_zebra_if_address_del(int command, struct zclient *client, return 0; } +void pim_zebra_update_all_interfaces(struct pim_instance *pim) +{ + struct interface *ifp; + + FOR_ALL_INTERFACES (pim->vrf, ifp) { + struct pim_interface *pim_ifp = ifp->info; + struct pim_iface_upstream_switch *us; + struct listnode *node; + + if (!pim_ifp) + continue; + + for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, node, + us)) { + struct pim_rpf rpf; + + rpf.source_nexthop.interface = ifp; + rpf.rpf_addr.u.prefix4 = us->address; + pim_joinprune_send(&rpf, us->us); + pim_jp_agg_clear_group(us->us); + } + } +} + +void pim_zebra_upstream_rpf_changed(struct pim_instance *pim, + struct pim_upstream *up, + struct pim_rpf *old) +{ + struct pim_neighbor *nbr; + + nbr = pim_neighbor_find(old->source_nexthop.interface, + old->rpf_addr.u.prefix4); + if (nbr) + pim_jp_agg_remove_group(nbr->upstream_jp_agg, up); + + /* + * We have detected a case where we might need + * to rescan the inherited o_list so do it. + */ + if (up->channel_oil->oil_inherited_rescan) { + pim_upstream_inherited_olist_decide(pim, up); + up->channel_oil->oil_inherited_rescan = 0; + } + + if (up->join_state == PIM_UPSTREAM_JOINED) { + /* + * If we come up real fast we can be here + * where the mroute has not been installed + * so install it. + */ + if (!up->channel_oil->installed) + pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__); + + /* + * RFC 4601: 4.5.7. Sending (S,G) + * Join/Prune Messages + * + * Transitions from Joined State + * + * RPF'(S,G) changes not due to an Assert + * + * The upstream (S,G) state machine remains + * in Joined state. Send Join(S,G) to the new + * upstream neighbor, which is the new value + * of RPF'(S,G). Send Prune(S,G) to the old + * upstream neighbor, which is the old value + * of RPF'(S,G). Set the Join Timer (JT) to + * expire after t_periodic seconds. + */ + pim_jp_agg_switch_interface(old, &up->rpf, up); + + pim_upstream_join_timer_restart(up, old); + } /* up->join_state == PIM_UPSTREAM_JOINED */ + + /* FIXME can join_desired actually be changed by + pim_rpf_update() + returning PIM_RPF_CHANGED ? */ + pim_upstream_update_join_desired(pim, up); +} + static void scan_upstream_rpf_cache(struct pim_instance *pim) { struct listnode *up_node; struct listnode *up_nextnode; - struct listnode *node; struct pim_upstream *up; - struct interface *ifp; for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) { enum pim_rpf_result rpf_result; @@ -450,80 +528,12 @@ static void scan_upstream_rpf_cache(struct pim_instance *pim) if (rpf_result == PIM_RPF_FAILURE) continue; - if (rpf_result == PIM_RPF_CHANGED) { - struct pim_neighbor *nbr; - - nbr = pim_neighbor_find(old.source_nexthop.interface, - old.rpf_addr.u.prefix4); - if (nbr) - pim_jp_agg_remove_group(nbr->upstream_jp_agg, - up); - - /* - * We have detected a case where we might need - * to rescan - * the inherited o_list so do it. - */ - if (up->channel_oil->oil_inherited_rescan) { - pim_upstream_inherited_olist_decide(pim, up); - up->channel_oil->oil_inherited_rescan = 0; - } - - if (up->join_state == PIM_UPSTREAM_JOINED) { - /* - * If we come up real fast we can be here - * where the mroute has not been installed - * so install it. - */ - if (!up->channel_oil->installed) - pim_mroute_add(up->channel_oil, - __PRETTY_FUNCTION__); - - /* - * RFC 4601: 4.5.7. Sending (S,G) - * Join/Prune Messages - * - * Transitions from Joined State - * - * RPF'(S,G) changes not due to an Assert - * - * The upstream (S,G) state machine remains - * in Joined state. Send Join(S,G) to the new - * upstream neighbor, which is the new value - * of RPF'(S,G). Send Prune(S,G) to the old - * upstream neighbor, which is the old value - * of RPF'(S,G). Set the Join Timer (JT) to - * expire after t_periodic seconds. - */ - pim_jp_agg_switch_interface(&old, &up->rpf, up); - - pim_upstream_join_timer_restart(up, &old); - } /* up->join_state == PIM_UPSTREAM_JOINED */ - - /* FIXME can join_desired actually be changed by - pim_rpf_update() - returning PIM_RPF_CHANGED ? */ - pim_upstream_update_join_desired(pim, up); - - } /* PIM_RPF_CHANGED */ + if (rpf_result == PIM_RPF_CHANGED) + pim_zebra_upstream_rpf_changed(pim, up, &old); } /* for (qpim_upstream_list) */ - FOR_ALL_INTERFACES (pim->vrf, ifp) - if (ifp->info) { - struct pim_interface *pim_ifp = ifp->info; - struct pim_iface_upstream_switch *us; - - for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, - node, us)) { - struct pim_rpf rpf; - - rpf.source_nexthop.interface = ifp; - rpf.rpf_addr.u.prefix4 = us->address; - pim_joinprune_send(&rpf, us->us); - pim_jp_agg_clear_group(us->us); - } - } + pim_zebra_update_all_interfaces(pim); } void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index) diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h index dd46fd40f9..c9ed89863c 100644 --- a/pimd/pim_zebra.h +++ b/pimd/pim_zebra.h @@ -46,4 +46,9 @@ void pim_forward_stop(struct pim_ifchannel *ch, bool install_it); void sched_rpf_cache_refresh(struct pim_instance *pim); struct zclient *pim_zebra_zclient_get(void); + +void pim_zebra_update_all_interfaces(struct pim_instance *pim); +void pim_zebra_upstream_rpf_changed(struct pim_instance *pim, + struct pim_upstream *up, + struct pim_rpf *old); #endif /* PIM_ZEBRA_H */ diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 5a3f341205..58247f1622 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -514,14 +514,12 @@ static void rip_interface_reset(struct rip_interface *ri) ri->v2_broadcast = 0; - if (ri->auth_str) { - free(ri->auth_str); - ri->auth_str = NULL; - } - if (ri->key_chain) { - free(ri->key_chain); - ri->key_chain = NULL; - } + if (ri->auth_str) + XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); + + if (ri->key_chain) + XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); + ri->list[RIP_FILTER_IN] = NULL; ri->list[RIP_FILTER_OUT] = NULL; @@ -825,7 +823,8 @@ static int rip_enable_if_add(const char *ifname) if (ret >= 0) return -1; - vector_set(rip_enable_interface, strdup(ifname)); + vector_set(rip_enable_interface, + XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname)); rip_enable_apply_all(); /* TODOVJ */ @@ -843,7 +842,7 @@ static int rip_enable_if_delete(const char *ifname) return -1; str = vector_slot(rip_enable_interface, index); - free(str); + XFREE(MTYPE_RIP_INTERFACE_STRING, str); vector_unset(rip_enable_interface, index); rip_enable_apply_all(); /* TODOVJ */ @@ -1062,7 +1061,7 @@ void rip_clean_network() /* rip_enable_interface. */ for (i = 0; i < vector_active(rip_enable_interface); i++) if ((str = vector_slot(rip_enable_interface, i)) != NULL) { - free(str); + XFREE(MTYPE_RIP_INTERFACE_STRING, str); vector_slot(rip_enable_interface, i) = NULL; } } @@ -1110,7 +1109,8 @@ static int rip_passive_nondefault_set(struct vty *vty, const char *ifname) if (rip_passive_nondefault_lookup(ifname) >= 0) return CMD_WARNING_CONFIG_FAILED; - vector_set(Vrip_passive_nondefault, strdup(ifname)); + vector_set(Vrip_passive_nondefault, + XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname)); rip_passive_interface_apply_all(); @@ -1127,7 +1127,7 @@ static int rip_passive_nondefault_unset(struct vty *vty, const char *ifname) return CMD_WARNING_CONFIG_FAILED; str = vector_slot(Vrip_passive_nondefault, i); - free(str); + XFREE(MTYPE_RIP_INTERFACE_STRING, str); vector_unset(Vrip_passive_nondefault, i); rip_passive_interface_apply_all(); @@ -1143,7 +1143,7 @@ void rip_passive_nondefault_clean(void) for (i = 0; i < vector_active(Vrip_passive_nondefault); i++) if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL) { - free(str); + XFREE(MTYPE_RIP_INTERFACE_STRING, str); vector_slot(Vrip_passive_nondefault, i) = NULL; } rip_passive_interface_apply_all(); @@ -1529,9 +1529,9 @@ DEFUN (ip_rip_authentication_string, } if (ri->auth_str) - free(ri->auth_str); + XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); - ri->auth_str = strdup(argv[idx_line]->arg); + ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING, argv[idx_line]->arg); return CMD_SUCCESS; } @@ -1552,9 +1552,7 @@ DEFUN (no_ip_rip_authentication_string, ri = ifp->info; if (ri->auth_str) - free(ri->auth_str); - - ri->auth_str = NULL; + XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); return CMD_SUCCESS; } @@ -1581,9 +1579,10 @@ DEFUN (ip_rip_authentication_key_chain, } if (ri->key_chain) - free(ri->key_chain); + XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); - ri->key_chain = strdup(argv[idx_line]->arg); + ri->key_chain = + XSTRDUP(MTYPE_RIP_INTERFACE_STRING, argv[idx_line]->arg); return CMD_SUCCESS; } @@ -1604,9 +1603,7 @@ DEFUN (no_ip_rip_authentication_key_chain, ri = ifp->info; if (ri->key_chain) - free(ri->key_chain); - - ri->key_chain = NULL; + XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); return CMD_SUCCESS; } diff --git a/ripd/rip_memory.c b/ripd/rip_memory.c index 4cdd3df048..1852410743 100644 --- a/ripd/rip_memory.c +++ b/ripd/rip_memory.c @@ -29,6 +29,7 @@ DEFINE_MGROUP(RIPD, "ripd") DEFINE_MTYPE(RIPD, RIP, "RIP structure") DEFINE_MTYPE(RIPD, RIP_INFO, "RIP route info") DEFINE_MTYPE(RIPD, RIP_INTERFACE, "RIP interface") +DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String") DEFINE_MTYPE(RIPD, RIP_PEER, "RIP peer") DEFINE_MTYPE(RIPD, RIP_OFFSET_LIST, "RIP offset list") DEFINE_MTYPE(RIPD, RIP_DISTANCE, "RIP distance") diff --git a/ripd/rip_memory.h b/ripd/rip_memory.h index 57abedd3aa..29013ecec3 100644 --- a/ripd/rip_memory.h +++ b/ripd/rip_memory.h @@ -28,6 +28,7 @@ DECLARE_MGROUP(RIPD) DECLARE_MTYPE(RIP) DECLARE_MTYPE(RIP_INFO) DECLARE_MTYPE(RIP_INTERFACE) +DECLARE_MTYPE(RIP_INTERFACE_STRING) DECLARE_MTYPE(RIP_PEER) DECLARE_MTYPE(RIP_OFFSET_LIST) DECLARE_MTYPE(RIP_DISTANCE) diff --git a/ripd/ripd.c b/ripd/ripd.c index 90dc7808eb..f7d6d3d929 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -828,7 +828,7 @@ static int rip_auth_simple_password(struct rte *rte, struct sockaddr_in *from, struct key *key; keychain = keychain_lookup(ri->key_chain); - if (keychain == NULL) + if (keychain == NULL || keychain->key == NULL) return 0; key = key_match_for_accept(keychain, auth_str); @@ -902,7 +902,7 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from, return 0; key = key_lookup_for_accept(keychain, md5->keyid); - if (key == NULL) + if (key == NULL || key->string == NULL) return 0; strncpy(auth_str, key->string, RIP_AUTH_MD5_SIZE); @@ -574,7 +574,11 @@ case "$1" in reload) # Just apply the commands that have changed, no restart necessary - [ ! -x "$RELOAD_SCRIPT" ] && echo "frr-reload script not available" && exit 0 + if [ ! -x "$RELOAD_SCRIPT" ]; then + echo "Please install frr-pythontools package. Required for reload" + exit 0 + fi + NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}" [ ! -r $NEW_CONFIG_FILE ] && echo "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1 echo "Applying only incremental changes to running configuration from frr.conf" diff --git a/zebra/zserv.c b/zebra/zserv.c index fa501b187d..f76c2fabd6 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -163,6 +163,9 @@ static void zserv_log_message(const char *errmsg, struct stream *msg, * Cancel any pending tasks for the client's thread. Then schedule a task on * the main thread to shut down the calling thread. * + * It is not safe to close the client socket in this function. The socket is + * owned by the main thread. + * * Must be called from the client pthread, never the main thread. */ static void zserv_client_fail(struct zserv *client) @@ -172,10 +175,7 @@ static void zserv_client_fail(struct zserv *client) atomic_store_explicit(&client->pthread->running, false, memory_order_relaxed); - if (client->sock > 0) { - close(client->sock); - client->sock = -1; - } + THREAD_OFF(client->t_read); THREAD_OFF(client->t_write); zserv_event(client, ZSERV_HANDLE_CLIENT_FAIL); @@ -576,6 +576,7 @@ static void zserv_client_free(struct zserv *client) unsigned long nroutes; close(client->sock); + nroutes = rib_score_proto(client->proto, client->instance); zlog_notice( "client %d disconnected. %lu %s routes removed from the rib", @@ -621,12 +622,6 @@ void zserv_close_client(struct zserv *client) zlog_debug("Closing client '%s'", zebra_route_string(client->proto)); - /* if file descriptor is still open, close it */ - if (client->sock > 0) { - close(client->sock); - client->sock = -1; - } - thread_cancel_event(zebrad.master, client); THREAD_OFF(client->t_cleanup); |
