diff options
51 files changed, 609 insertions, 368 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 2e0a51dd8c..c99dadd083 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -366,12 +366,19 @@ DEFPY (babel_set_hello_interval, { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; + unsigned int old_interval; babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); + old_interval = babel_ifp->hello_interval; babel_ifp->hello_interval = no ? BABEL_DEFAULT_HELLO_INTERVAL : hello_interval; + + if (old_interval != babel_ifp->hello_interval){ + set_timeout(&babel_ifp->hello_timeout, babel_ifp->hello_interval); + send_hello(ifp); + } return CMD_SUCCESS; } diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index f280add12a..9f8f1f6c69 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -5028,7 +5028,13 @@ void bgp_packet_mpunreach_prefix(struct stream *s, const struct prefix *p, { uint8_t wlabel[4] = {0x80, 0x00, 0x00}; - if (safi == SAFI_LABELED_UNICAST) { + /* [RFC3107] also made it possible to withdraw a binding without + * specifying the label explicitly, by setting the Compatibility field + * to 0x800000. However, some implementations set it to 0x000000. In + * order to ensure backwards compatibility, it is RECOMMENDED by this + * document that the Compatibility field be set to 0x800000. + */ + if (safi == SAFI_LABELED_UNICAST || safi == SAFI_MPLS_VPN) { label = (mpls_label_t *)wlabel; num_labels = 1; } diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h index 2ffd5b699d..ff002c2071 100644 --- a/bgpd/bgp_label.h +++ b/bgpd/bgp_label.h @@ -7,8 +7,6 @@ #define _BGP_LABEL_H #define BGP_LABEL_BYTES 3 -#define BGP_LABEL_BITS 24 -#define BGP_WITHDRAW_LABEL 0x800000 #define BGP_PREVENT_VRF_2_VRF_LEAK 0xFFFFFFFE struct bgp_dest; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index dd81f92548..003a9a4d4d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6533,24 +6533,24 @@ static void clearing_clear_one_pi(struct bgp_table *table, struct bgp_dest *dest */ static void set_clearing_resume_info(struct bgp_clearing_info *cinfo, const struct bgp_table *table, - const struct bgp_dest *dest, bool inner_p) + const struct prefix *p, bool inner_p) { if (bgp_debug_neighbor_events(NULL)) zlog_debug("%s: %sinfo for %s/%s %pFX", __func__, inner_p ? "inner " : "", afi2str(table->afi), - safi2str(table->safi), &dest->rn->p); + safi2str(table->safi), p); SET_FLAG(cinfo->flags, BGP_CLEARING_INFO_FLAG_RESUME); if (inner_p) { cinfo->inner_afi = table->afi; cinfo->inner_safi = table->safi; - cinfo->inner_pfx = dest->rn->p; + memcpy(&cinfo->inner_pfx, p, sizeof(struct prefix)); SET_FLAG(cinfo->flags, BGP_CLEARING_INFO_FLAG_INNER); } else { cinfo->last_afi = table->afi; cinfo->last_safi = table->safi; - cinfo->last_pfx = dest->rn->p; + memcpy(&cinfo->last_pfx, p, sizeof(struct prefix)); } } @@ -6625,6 +6625,7 @@ static int walk_batch_table_helper(struct bgp_clearing_info *cinfo, struct bgp_dest *dest; bool force = (cinfo->bgp->process_queue == NULL); uint32_t examined = 0, processed = 0; + struct prefix pfx; /* Locate starting dest, possibly using "resume" info */ dest = clearing_dest_helper(table, cinfo, inner_p); @@ -6641,6 +6642,9 @@ static int walk_batch_table_helper(struct bgp_clearing_info *cinfo, examined++; cinfo->curr_counter++; + /* Save dest's prefix */ + memcpy(&pfx, &dest->rn->p, sizeof(struct prefix)); + ain = dest->adj_in; while (ain) { ain_next = ain->next; @@ -6671,14 +6675,13 @@ static int walk_batch_table_helper(struct bgp_clearing_info *cinfo, if (cinfo->curr_counter >= bm->peer_clearing_batch_max_dests) { /* Capture info about last dest seen and break */ if (bgp_debug_neighbor_events(NULL)) - zlog_debug("%s: %s/%s: pfx %pFX reached limit %u", - __func__, afi2str(table->afi), - safi2str(table->safi), &dest->rn->p, + zlog_debug("%s: %s/%s: pfx %pFX reached limit %u", __func__, + afi2str(table->afi), safi2str(table->safi), &pfx, cinfo->curr_counter); /* Reset the counter */ cinfo->curr_counter = 0; - set_clearing_resume_info(cinfo, table, dest, inner_p); + set_clearing_resume_info(cinfo, table, &pfx, inner_p); ret = -1; break; } @@ -6706,6 +6709,7 @@ static int clear_batch_rib_helper(struct bgp_clearing_info *cinfo) safi_t safi; struct bgp_dest *dest; struct bgp_table *table, *outer_table; + struct prefix pfx; /* Maybe resume afi/safi iteration */ if (CHECK_FLAG(cinfo->flags, BGP_CLEARING_INFO_FLAG_RESUME)) { @@ -6762,6 +6766,9 @@ static int clear_batch_rib_helper(struct bgp_clearing_info *cinfo) continue; } + /* Capture last prefix */ + memcpy(&pfx, &dest->rn->p, sizeof(struct prefix)); + /* This will resume the "inner" walk if necessary */ ret = walk_batch_table_helper(cinfo, table, true /*inner*/); if (ret != 0) { @@ -6769,7 +6776,7 @@ static int clear_batch_rib_helper(struct bgp_clearing_info *cinfo) * capture the resume info we need * from the outer afi/safi and dest */ - set_clearing_resume_info(cinfo, outer_table, dest, + set_clearing_resume_info(cinfo, outer_table, &pfx, false); break; } diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 2ebabd0efa..d59adc8234 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -81,11 +81,11 @@ static int config_write_debug(struct vty *vty) static int eigrp_neighbor_packet_queue_sum(struct eigrp_interface *ei) { struct eigrp_neighbor *nbr; - struct listnode *node, *nnode; int sum; + sum = 0; - for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { sum += nbr->retrans_queue->count; } @@ -152,7 +152,7 @@ void show_ip_eigrp_interface_sub(struct vty *vty, struct eigrp *eigrp, vty_out(vty, "%-16s ", IF_NAME(ei)); vty_out(vty, "%-11u", ei->params.bandwidth); vty_out(vty, "%-11u", ei->params.delay); - vty_out(vty, "%-7u", ei->nbrs->count); + vty_out(vty, "%-7zu", eigrp_nbr_hash_count(&ei->nbr_hash_head)); vty_out(vty, "%u %c %-10u", 0, '/', eigrp_neighbor_packet_queue_sum(ei)); vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0); @@ -228,7 +228,7 @@ void show_ip_eigrp_prefix_descriptor(struct vty *vty, vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P'); - vty_out(vty, "%pFX, ", tn->destination); + vty_out(vty, "%pFX, ", &tn->destination); vty_out(vty, "%u successors, ", (successors) ? successors->count : 0); vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance, tn->serno); diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c index eceef6b8a7..d6f2ddf7f4 100644 --- a/eigrpd/eigrp_filter.c +++ b/eigrpd/eigrp_filter.c @@ -42,6 +42,7 @@ #include "eigrpd/eigrp_const.h" #include "eigrpd/eigrp_filter.h" #include "eigrpd/eigrp_packet.h" +#include "eigrpd/eigrp_interface.h" /* * Distribute-list update functions. @@ -126,10 +127,9 @@ void eigrp_distribute_update(struct distribute_ctx *ctx, /*struct eigrp_if_info * info = ifp->info; ei = info->eigrp_interface;*/ - struct listnode *node, *nnode; struct eigrp_interface *ei2; /* Find proper interface */ - for (ALL_LIST_ELEMENTS(e->eiflist, node, nnode, ei2)) { + frr_each (eigrp_interface_hash, &e->eifs, ei2) { if (strcmp(ei2->ifp->name, ifp->name) == 0) { ei = ei2; break; diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index 6d8061e572..99b090eeb6 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -403,12 +403,10 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg) { enum eigrp_fsm_events event = eigrp_get_fsm_event(msg); - zlog_info( - "EIGRP AS: %d State: %s Event: %s Network: %pI4 Packet Type: %s Reply RIJ Count: %d change: %s", - msg->eigrp->AS, prefix_state2str(msg->prefix->state), - fsm_state2str(event), &msg->prefix->destination->u.prefix4, - packet_type2str(msg->packet_type), msg->prefix->rij->count, - change2str(msg->change)); + zlog_info("EIGRP AS: %d State: %s Event: %s Network: %pFX Packet Type: %s Reply RIJ Count: %d change: %s", + msg->eigrp->AS, prefix_state2str(msg->prefix->state), fsm_state2str(event), + &msg->prefix->destination, packet_type2str(msg->packet_type), + msg->prefix->rij->count, change2str(msg->change)); (*(NSM[msg->prefix->state][event].func))(msg); return 1; diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index ee0e2451a2..fe80651b9b 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -496,7 +496,6 @@ static uint16_t eigrp_sequence_encode(struct eigrp *eigrp, struct stream *s) { uint16_t length = EIGRP_TLV_SEQ_BASE_LEN; struct eigrp_interface *ei; - struct listnode *node, *node2, *nnode2; struct eigrp_neighbor *nbr; size_t backup_end, size_end; int found; @@ -509,8 +508,8 @@ static uint16_t eigrp_sequence_encode(struct eigrp *eigrp, struct stream *s) stream_putc(s, IPV4_MAX_BYTELEN); found = 0; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (nbr->multicast_queue->count > 0) { length += (uint16_t)stream_put_ipv4( s, nbr->src.s_addr); diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index fb8f47e723..8bf0e130b1 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -45,6 +45,16 @@ DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IF, "EIGRP interface"); +int eigrp_interface_cmp(const struct eigrp_interface *a, const struct eigrp_interface *b) +{ + return if_cmp_func(a->ifp, b->ifp); +} + +uint32_t eigrp_interface_hash(const struct eigrp_interface *ei) +{ + return ei->ifp->ifindex; +} + struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, struct prefix *p) { @@ -61,12 +71,12 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, prefix_copy(&ei->address, p); ifp->info = ei; - listnode_add(eigrp->eiflist, ei); + eigrp_interface_hash_add(&eigrp->eifs, ei); ei->type = EIGRP_IFTYPE_BROADCAST; /* Initialize neighbor list. */ - ei->nbrs = list_new(); + eigrp_nbr_hash_init(&ei->nbr_hash_head); ei->crypt_seqnum = frr_sequence32_next(); @@ -102,10 +112,10 @@ int eigrp_if_delete_hook(struct interface *ifp) if (!ei) return 0; - list_delete(&ei->nbrs); + eigrp_nbr_hash_fini(&ei->nbr_hash_head); eigrp = ei->eigrp; - listnode_delete(eigrp->eiflist, ei); + eigrp_interface_hash_del(&eigrp->eifs, ei); eigrp_fifo_free(ei->obuf); @@ -238,7 +248,6 @@ int eigrp_if_up(struct eigrp_interface *ei) struct eigrp_route_descriptor *ne; struct eigrp_metrics metric; struct eigrp_interface *ei2; - struct listnode *node, *nnode; struct eigrp *eigrp; if (ei == NULL) @@ -285,8 +294,7 @@ int eigrp_if_up(struct eigrp_interface *ei) if (pe == NULL) { pe = eigrp_prefix_descriptor_new(); pe->serno = eigrp->serno; - pe->destination = (struct prefix *)prefix_ipv4_new(); - prefix_copy(pe->destination, &dest_addr); + prefix_copy(&pe->destination, &dest_addr); pe->af = AF_INET; pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED; @@ -300,9 +308,8 @@ int eigrp_if_up(struct eigrp_interface *ei) eigrp_route_descriptor_add(eigrp, pe, ne); - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei2) eigrp_update_send(ei2); - } pe->req_action &= ~EIGRP_FSM_NEED_UPDATE; listnode_delete(eigrp->topology_changes_internalIPV4, pe); @@ -327,9 +334,6 @@ int eigrp_if_up(struct eigrp_interface *ei) int eigrp_if_down(struct eigrp_interface *ei) { - struct listnode *node, *nnode; - struct eigrp_neighbor *nbr; - if (ei == NULL) return 0; @@ -340,9 +344,9 @@ int eigrp_if_down(struct eigrp_interface *ei) /*Set infinite metrics to routes learned by this interface and start * query process*/ - for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) { - eigrp_nbr_delete(nbr); - } + while (eigrp_nbr_hash_count(&ei->nbr_hash_head) > 0) + eigrp_nbr_delete(eigrp_nbr_hash_first(&ei->nbr_hash_head)); + return 1; } @@ -436,8 +440,6 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) pe); eigrp_if_down(ei); - - listnode_delete(ei->eigrp->eiflist, ei); } /* Simulate down/up on the interface. This is needed, for example, when @@ -457,10 +459,9 @@ struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp, struct interface *ifp, struct in_addr address) { - struct listnode *node; struct eigrp_interface *ei; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { if (ifp && ei->ifp != ifp) continue; @@ -486,10 +487,10 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp, const char *if_name) { struct eigrp_interface *ei; - struct listnode *node; /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + // XXX + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* compare int name with eigrp interface's name */ if (strcmp(ei->ifp->name, if_name) == 0) { return ei; diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h index 76f9c1bcb6..effafeaea5 100644 --- a/eigrpd/eigrp_interface.h +++ b/eigrpd/eigrp_interface.h @@ -43,4 +43,10 @@ extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *, /* Simulate down/up on the interface. */ extern void eigrp_if_reset(struct interface *); +extern int eigrp_interface_cmp(const struct eigrp_interface *a, const struct eigrp_interface *b); +extern uint32_t eigrp_interface_hash(const struct eigrp_interface *ei); + +DECLARE_HASH(eigrp_interface_hash, struct eigrp_interface, eif_item, eigrp_interface_cmp, + eigrp_interface_hash); + #endif /* ZEBRA_EIGRP_INTERFACE_H_ */ diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index 319ac92533..089e18439f 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -98,6 +98,7 @@ static void sigint(void) keychain_terminate(); + route_map_finish(); eigrp_terminate(); exit(0); diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index 25209c3bb3..ac3cbd04b2 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -41,6 +41,21 @@ DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_NEIGHBOR, "EIGRP neighbor"); +int eigrp_nbr_comp(const struct eigrp_neighbor *a, const struct eigrp_neighbor *b) +{ + if (a->src.s_addr == b->src.s_addr) + return 0; + else if (a->src.s_addr < b->src.s_addr) + return -1; + + return 1; +} + +uint32_t eigrp_nbr_hash(const struct eigrp_neighbor *a) +{ + return a->src.s_addr; +} + struct eigrp_neighbor *eigrp_nbr_new(struct eigrp_interface *ei) { struct eigrp_neighbor *nbr; @@ -80,17 +95,18 @@ struct eigrp_neighbor *eigrp_nbr_get(struct eigrp_interface *ei, struct eigrp_header *eigrph, struct ip *iph) { - struct eigrp_neighbor *nbr; - struct listnode *node, *nnode; + struct eigrp_neighbor lookup, *nbr; - for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) { - if (iph->ip_src.s_addr == nbr->src.s_addr) { - return nbr; - } + lookup.src = iph->ip_src; + lookup.ei = ei; + + nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup); + if (nbr) { + return nbr; } nbr = eigrp_nbr_add(ei, eigrph, iph); - listnode_add(ei->nbrs, nbr); + eigrp_nbr_hash_add(&ei->nbr_hash_head, nbr); return nbr; } @@ -110,16 +126,12 @@ struct eigrp_neighbor *eigrp_nbr_get(struct eigrp_interface *ei, struct eigrp_neighbor *eigrp_nbr_lookup_by_addr(struct eigrp_interface *ei, struct in_addr *addr) { - struct eigrp_neighbor *nbr; - struct listnode *node, *nnode; + struct eigrp_neighbor lookup, *nbr; - for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) { - if (addr->s_addr == nbr->src.s_addr) { - return nbr; - } - } + lookup.src = *addr; + nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup); - return NULL; + return nbr; } /** @@ -138,17 +150,15 @@ struct eigrp_neighbor *eigrp_nbr_lookup_by_addr_process(struct eigrp *eigrp, struct in_addr nbr_addr) { struct eigrp_interface *ei; - struct listnode *node, *node2, *nnode2; - struct eigrp_neighbor *nbr; + struct eigrp_neighbor lookup, *nbr; /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* iterate over all neighbors on eigrp interface */ - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { - /* compare if neighbor address is same as arg address */ - if (nbr->src.s_addr == nbr_addr.s_addr) { - return nbr; - } + lookup.src = nbr_addr; + nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup); + if (nbr) { + return nbr; } } @@ -170,7 +180,7 @@ void eigrp_nbr_delete(struct eigrp_neighbor *nbr) EVENT_OFF(nbr->t_holddown); if (nbr->ei) - listnode_delete(nbr->ei->nbrs, nbr); + eigrp_nbr_hash_del(&nbr->ei->nbr_hash_head, nbr); XFREE(MTYPE_EIGRP_NEIGHBOR, nbr); } @@ -278,18 +288,12 @@ void eigrp_nbr_state_update(struct eigrp_neighbor *nbr) int eigrp_nbr_count_get(struct eigrp *eigrp) { struct eigrp_interface *iface; - struct listnode *node, *node2, *nnode2; - struct eigrp_neighbor *nbr; uint32_t counter; counter = 0; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) { - for (ALL_LIST_ELEMENTS(iface->nbrs, node2, nnode2, nbr)) { - if (nbr->state == EIGRP_NEIGHBOR_UP) { - counter++; - } - } - } + frr_each (eigrp_interface_hash, &eigrp->eifs, iface) + counter += eigrp_nbr_hash_count(&iface->nbr_hash_head); + return counter; } diff --git a/eigrpd/eigrp_neighbor.h b/eigrpd/eigrp_neighbor.h index 2ccc89cf3a..8a13ccfe67 100644 --- a/eigrpd/eigrp_neighbor.h +++ b/eigrpd/eigrp_neighbor.h @@ -26,8 +26,6 @@ extern void eigrp_nbr_delete(struct eigrp_neighbor *neigh); extern void holddown_timer_expired(struct event *thread); -extern int eigrp_neighborship_check(struct eigrp_neighbor *neigh, - struct TLV_Parameter_Type *tlv); extern void eigrp_nbr_state_update(struct eigrp_neighbor *neigh); extern void eigrp_nbr_state_set(struct eigrp_neighbor *neigh, uint8_t state); extern uint8_t eigrp_nbr_state_get(struct eigrp_neighbor *neigh); @@ -41,4 +39,9 @@ extern void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty); extern int eigrp_nbr_split_horizon_check(struct eigrp_route_descriptor *ne, struct eigrp_interface *ei); + +extern int eigrp_nbr_comp(const struct eigrp_neighbor *a, const struct eigrp_neighbor *b); +extern uint32_t eigrp_nbr_hash(const struct eigrp_neighbor *a); + +DECLARE_HASH(eigrp_nbr_hash, struct eigrp_neighbor, nbr_hash_item, eigrp_nbr_comp, eigrp_nbr_hash); #endif /* _ZEBRA_EIGRP_NEIGHBOR_H */ diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 5ca5a18a97..fc334cf97d 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -219,6 +219,21 @@ int eigrp_network_set(struct eigrp *eigrp, struct prefix *p) return 1; } +static void eigrp_network_delete_all(struct eigrp *eigrp, struct route_table *table) +{ + struct route_node *rn; + + for (rn = route_top(table); rn; rn = route_next(rn)) { + prefix_free((struct prefix **)&rn->info); + } +} + +void eigrp_network_free(struct eigrp *eigrp, struct route_table *table) +{ + eigrp_network_delete_all(eigrp, table); + route_table_finish(table); +} + /* Check whether interface matches given network * returns: 1, true. 0, false */ @@ -262,7 +277,6 @@ static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p, void eigrp_if_update(struct interface *ifp) { - struct listnode *node, *nnode; struct route_node *rn; struct eigrp *eigrp; @@ -270,7 +284,7 @@ void eigrp_if_update(struct interface *ifp) * In the event there are multiple eigrp autonymnous systems running, * we need to check eac one and add the interface as approperate */ - for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) { + frr_each (eigrp_master_hash, &eigrp_om->eigrp, eigrp) { if (ifp->vrf->vrf_id != eigrp->vrf_id) continue; @@ -289,7 +303,6 @@ void eigrp_if_update(struct interface *ifp) int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p) { struct route_node *rn; - struct listnode *node, *nnode; struct eigrp_interface *ei; struct prefix *pref; @@ -307,7 +320,7 @@ int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p) route_unlock_node(rn); /* initial reference */ /* Find interfaces that not configured already. */ - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { bool found = false; for (rn = route_top(eigrp->networks); rn; rn = route_next(rn)) { diff --git a/eigrpd/eigrp_network.h b/eigrpd/eigrp_network.h index ac5c47f6f9..1baf26b0c0 100644 --- a/eigrpd/eigrp_network.h +++ b/eigrpd/eigrp_network.h @@ -19,6 +19,7 @@ extern int eigrp_sock_init(struct vrf *vrf); extern int eigrp_if_ipmulticast(struct eigrp *, struct prefix *, unsigned int); extern int eigrp_network_set(struct eigrp *eigrp, struct prefix *p); extern int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p); +extern void eigrp_network_free(struct eigrp *eigrp, struct route_table *table); extern void eigrp_hello_timer(struct event *thread); extern void eigrp_if_update(struct interface *); diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c index 4aeb635c05..90af47e9e2 100644 --- a/eigrpd/eigrp_northbound.c +++ b/eigrpd/eigrp_northbound.c @@ -43,13 +43,11 @@ static void redistribute_get_metrics(const struct lyd_node *dnode, em->reliability = yang_dnode_get_uint32(dnode, "reliability"); } -static struct eigrp_interface *eigrp_interface_lookup(const struct eigrp *eigrp, - const char *ifname) +static struct eigrp_interface *eigrp_interface_lookup(struct eigrp *eigrp, const char *ifname) { struct eigrp_interface *eif; - struct listnode *ln; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, ln, eif)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, eif) { if (strcmp(ifname, eif->ifp->name)) continue; diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index 963d229bc1..7560514cec 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -532,8 +532,8 @@ void eigrp_read(struct event *thread) return; /* Self-originated packet should be discarded silently. */ - if (eigrp_if_lookup_by_local_addr(eigrp, NULL, iph->ip_src) - || (IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) { + if (eigrp_if_lookup_by_local_addr(eigrp, ifp, iph->ip_src) || + (IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) { if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) zlog_debug( "eigrp_read[%pI4]: Dropping self-originated packet", @@ -1129,7 +1129,7 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s, uint16_t length; stream_putw(s, EIGRP_TLV_IPv4_INT); - switch (pe->destination->prefixlen) { + switch (pe->destination.prefixlen) { case 0: case 1: case 2: @@ -1176,8 +1176,8 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s, stream_putw(s, length); break; default: - flog_err(EC_LIB_DEVELOPMENT, "%s: Unexpected prefix length: %d", - __func__, pe->destination->prefixlen); + flog_err(EC_LIB_DEVELOPMENT, "%s: Unexpected prefix length: %d", __func__, + pe->destination.prefixlen); return 0; } stream_putl(s, 0x00000000); @@ -1194,15 +1194,15 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s, stream_putc(s, pe->reported_metric.tag); stream_putc(s, pe->reported_metric.flags); - stream_putc(s, pe->destination->prefixlen); + stream_putc(s, pe->destination.prefixlen); - stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 24) & 0xFF); - if (pe->destination->prefixlen > 8) - stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 16) & 0xFF); - if (pe->destination->prefixlen > 16) - stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 8) & 0xFF); - if (pe->destination->prefixlen > 24) - stream_putc(s, ntohl(pe->destination->u.prefix4.s_addr) & 0xFF); + stream_putc(s, (ntohl(pe->destination.u.prefix4.s_addr) >> 24) & 0xFF); + if (pe->destination.prefixlen > 8) + stream_putc(s, (ntohl(pe->destination.u.prefix4.s_addr) >> 16) & 0xFF); + if (pe->destination.prefixlen > 16) + stream_putc(s, (ntohl(pe->destination.u.prefix4.s_addr) >> 8) & 0xFF); + if (pe->destination.prefixlen > 24) + stream_putc(s, ntohl(pe->destination.u.prefix4.s_addr) & 0xFF); return length; } diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index 0e206cded6..d4f00fb139 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -41,7 +41,7 @@ uint32_t eigrp_query_send_all(struct eigrp *eigrp) { struct eigrp_interface *iface; - struct listnode *node, *node2, *nnode2; + struct listnode *node2, *nnode2; struct eigrp_prefix_descriptor *pe; uint32_t counter; @@ -51,7 +51,7 @@ uint32_t eigrp_query_send_all(struct eigrp *eigrp) } counter = 0; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, iface) { eigrp_send_query(iface); counter++; } @@ -146,7 +146,7 @@ void eigrp_send_query(struct eigrp_interface *ei) { struct eigrp_packet *ep = NULL; uint16_t length = EIGRP_HEADER_LEN; - struct listnode *node, *nnode, *node2, *nnode2; + struct listnode *node, *nnode; struct eigrp_neighbor *nbr; struct eigrp_prefix_descriptor *pe; bool has_tlv = false; @@ -177,7 +177,7 @@ void eigrp_send_query(struct eigrp_interface *ei) length += eigrp_add_internalTLV_to_stream(ep->s, pe); has_tlv = true; - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (nbr->state == EIGRP_NEIGHBOR_UP) listnode_add(pe->rij, nbr); } @@ -197,7 +197,7 @@ void eigrp_send_query(struct eigrp_interface *ei) ep->sequence_number = ei->eigrp->sequence_number; ei->eigrp->sequence_number++; - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { struct eigrp_packet *dup; if (nbr->state != EIGRP_NEIGHBOR_UP) @@ -237,7 +237,7 @@ void eigrp_send_query(struct eigrp_interface *ei) ep->sequence_number = ei->eigrp->sequence_number; ei->eigrp->sequence_number++; - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { struct eigrp_packet *dup; if (nbr->state != EIGRP_NEIGHBOR_UP) diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index aae89e832b..a444f3a5a9 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -61,8 +61,7 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, sizeof(struct eigrp_prefix_descriptor)); memcpy(pe2, pe, sizeof(struct eigrp_prefix_descriptor)); - if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT, - pe2->destination)) { + if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT, &pe2->destination)) { zlog_info("REPLY SEND: Setting Metric to max"); pe2->reported_metric.delay = EIGRP_MAX_METRIC; } diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c index 420cb6cb41..605a1ae4b8 100644 --- a/eigrpd/eigrp_routemap.c +++ b/eigrpd/eigrp_routemap.c @@ -43,7 +43,6 @@ void eigrp_if_rmap_update(struct if_rmap *if_rmap) { struct interface *ifp; struct eigrp_interface *ei, *ei2; - struct listnode *node, *nnode; struct route_map *rmap; struct eigrp *e; @@ -53,7 +52,7 @@ void eigrp_if_rmap_update(struct if_rmap *if_rmap) ei = NULL; e = eigrp_lookup(); - for (ALL_LIST_ELEMENTS(e->eiflist, node, nnode, ei2)) { + frr_each (eigrp_interface_hash, &e->eifs, ei2) { if (strcmp(ei2->ifp->name, ifp->name) == 0) { ei = ei2; break; diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index 8735c48661..c24067bc33 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -43,7 +43,11 @@ struct eigrp_extdata { uint8_t flags; }; +PREDECL_HASH(eigrp_interface_hash); +PREDECL_HASH(eigrp_master_hash); struct eigrp { + struct eigrp_master_hash_item eigrp_item; + vrf_id_t vrf_id; uint16_t AS; /* Autonomous system number */ @@ -59,7 +63,7 @@ struct eigrp { struct in_addr router_id; /* Configured automatically. */ struct in_addr router_id_static; /* Configured manually. */ - struct list *eiflist; /* eigrp interfaces */ + struct eigrp_interface_hash_head eifs; uint8_t passive_interface_default; /* passive-interface default */ int fd; @@ -133,8 +137,12 @@ enum { MEMBER_ALLROUTERS = 0, MEMBER_MAX, }; +PREDECL_HASH(eigrp_nbr_hash); + /*EIGRP interface structure*/ struct eigrp_interface { + struct eigrp_interface_hash_item eif_item; + struct eigrp_if_params params; /*multicast group refcnts */ @@ -162,7 +170,7 @@ struct eigrp_interface { struct prefix address; /* Interface prefix */ /* Neighbor information. */ - struct list *nbrs; /* EIGRP Neighbor List */ + struct eigrp_nbr_hash_head nbr_hash_head; /* Threads. */ struct event *t_hello; /* timer */ @@ -208,6 +216,8 @@ enum Packet_part_type { /* Neighbor Data Structure */ struct eigrp_neighbor { + struct eigrp_nbr_hash_item nbr_hash_item; + /* This neighbor's parent eigrp interface. */ struct eigrp_interface *ei; @@ -437,7 +447,7 @@ struct eigrp_prefix_descriptor { uint8_t af; // address family uint8_t req_action; // required action - struct prefix *destination; + struct prefix destination; // If network type is REMOTE_EXTERNAL, pointer will have reference to // its external TLV diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index f17be8f4b7..e59dcacb7c 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -68,7 +68,6 @@ struct eigrp_prefix_descriptor *eigrp_prefix_descriptor_new(void) new->rij = list_new(); new->entries->cmp = (int (*)(void *, void *))eigrp_route_descriptor_cmp; new->distance = new->fdistance = new->rdistance = EIGRP_MAX_METRIC; - new->destination = NULL; return new; } @@ -120,12 +119,11 @@ void eigrp_prefix_descriptor_add(struct route_table *topology, { struct route_node *rn; - rn = route_node_get(topology, pe->destination); + rn = route_node_get(topology, &pe->destination); if (rn->info) { if (IS_DEBUG_EIGRP_EVENT) - zlog_debug( - "%s: %pFX Should we have found this entry in the topo table?", - __func__, pe->destination); + zlog_debug("%s: %pFX Should we have found this entry in the topo table?", + __func__, &pe->destination); route_unlock_node(rn); } @@ -147,8 +145,7 @@ void eigrp_route_descriptor_add(struct eigrp *eigrp, listnode_add_sort(node->entries, entry); entry->prefix = node; - eigrp_zebra_route_add(eigrp, node->destination, - l, node->fdistance); + eigrp_zebra_route_add(eigrp, &node->destination, l, node->fdistance); } list_delete(&l); @@ -168,7 +165,7 @@ void eigrp_prefix_descriptor_delete(struct eigrp *eigrp, if (!eigrp) return; - rn = route_node_lookup(table, pe->destination); + rn = route_node_lookup(table, &pe->destination); if (!rn) return; @@ -182,8 +179,7 @@ void eigrp_prefix_descriptor_delete(struct eigrp *eigrp, eigrp_route_descriptor_delete(eigrp, pe, ne); list_delete(&pe->entries); list_delete(&pe->rij); - eigrp_zebra_route_delete(eigrp, pe->destination); - prefix_free(&pe->destination); + eigrp_zebra_route_delete(eigrp, &pe->destination); rn->info = NULL; route_unlock_node(rn); // Lookup above @@ -200,7 +196,7 @@ void eigrp_route_descriptor_delete(struct eigrp *eigrp, { if (listnode_lookup(node->entries, entry) != NULL) { listnode_delete(node->entries, entry); - eigrp_zebra_route_delete(eigrp, node->destination); + eigrp_zebra_route_delete(eigrp, &node->destination); XFREE(MTYPE_EIGRP_ROUTE_DESCRIPTOR, entry); } } @@ -462,14 +458,13 @@ void eigrp_update_routing_table(struct eigrp *eigrp, successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths); if (successors) { - eigrp_zebra_route_add(eigrp, prefix->destination, successors, - prefix->fdistance); + eigrp_zebra_route_add(eigrp, &prefix->destination, successors, prefix->fdistance); for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) entry->flags |= EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG; list_delete(&successors); } else { - eigrp_zebra_route_delete(eigrp, prefix->destination); + eigrp_zebra_route_delete(eigrp, &prefix->destination); for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry)) entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG; } diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index 74f573d9d8..7348231c3b 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -128,8 +128,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, /* iterate over all prefixes which weren't advertised by neighbor */ for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) { - zlog_debug("GR receive: Neighbor not advertised %pFX", - prefix->destination); + zlog_debug("GR receive: Neighbor not advertised %pFX", &prefix->destination); fsm_msg.metrics = prefix->reported_metric; /* set delay to MAX */ @@ -320,9 +319,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /*Here comes topology information save*/ pe = eigrp_prefix_descriptor_new(); pe->serno = eigrp->serno; - pe->destination = - (struct prefix *)prefix_ipv4_new(); - prefix_copy(pe->destination, &dest_addr); + prefix_copy(&pe->destination, &dest_addr); pe->af = AF_INET; pe->state = EIGRP_FSM_STATE_PASSIVE; pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE; @@ -482,11 +479,10 @@ static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr, static void eigrp_update_send_to_all_nbrs(struct eigrp_interface *ei, struct eigrp_packet *ep) { - struct listnode *node, *nnode; struct eigrp_neighbor *nbr; bool packet_sent = false; - for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { struct eigrp_packet *ep_dup; if (nbr->state != EIGRP_NEIGHBOR_UP) @@ -567,7 +563,7 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) } } /* Get destination address from prefix */ - dest_addr = pe->destination; + dest_addr = &pe->destination; /* Check if any list fits */ if (eigrp_update_prefix_apply( @@ -595,7 +591,7 @@ void eigrp_update_send(struct eigrp_interface *ei) uint32_t seq_no = eigrp->sequence_number; uint16_t eigrp_mtu = EIGRP_PACKET_MTU(ei->ifp->mtu); - if (ei->nbrs->count == 0) + if (eigrp_nbr_hash_count(&ei->nbr_hash_head) == 0) return; uint16_t length = EIGRP_HEADER_LEN; @@ -651,7 +647,7 @@ void eigrp_update_send(struct eigrp_interface *ei) has_tlv = 0; } /* Get destination address from prefix */ - dest_addr = pe->destination; + dest_addr = &pe->destination; if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT, dest_addr)) { @@ -694,10 +690,10 @@ void eigrp_update_send_all(struct eigrp *eigrp, struct eigrp_interface *exception) { struct eigrp_interface *iface; - struct listnode *node, *node2, *nnode2; + struct listnode *node2, *nnode2; struct eigrp_prefix_descriptor *pe; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, iface) { if (iface != exception) { eigrp_update_send(iface); } @@ -799,7 +795,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) /* * Filtering */ - dest_addr = pe->destination; + dest_addr = &pe->destination; if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT, dest_addr)) { @@ -1001,11 +997,10 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type, void eigrp_update_send_interface_GR(struct eigrp_interface *ei, enum GR_type gr_type, struct vty *vty) { - struct listnode *node; struct eigrp_neighbor *nbr; /* iterate over all neighbors on eigrp interface */ - for (ALL_LIST_ELEMENTS_RO(ei->nbrs, node, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { /* send GR to neighbor */ eigrp_update_send_GR(nbr, gr_type, vty); } @@ -1027,11 +1022,10 @@ void eigrp_update_send_interface_GR(struct eigrp_interface *ei, void eigrp_update_send_process_GR(struct eigrp *eigrp, enum GR_type gr_type, struct vty *vty) { - struct listnode *node; struct eigrp_interface *ei; /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* send GR to all neighbors on interface */ eigrp_update_send_interface_GR(ei, gr_type, vty); } diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 88510e75af..e68b85d801 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -195,12 +195,11 @@ static void eigrp_interface_helper(struct vty *vty, struct eigrp *eigrp, const char *ifname, const char *detail) { struct eigrp_interface *ei; - struct listnode *node; if (!ifname) show_ip_eigrp_interface_header(vty, eigrp); - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { if (!ifname || strcmp(ei->ifp->name, ifname) == 0) { show_ip_eigrp_interface_sub(vty, eigrp, ei); if (detail) @@ -252,14 +251,13 @@ static void eigrp_neighbors_helper(struct vty *vty, struct eigrp *eigrp, const char *ifname, const char *detail) { struct eigrp_interface *ei; - struct listnode *node, *node2, *nnode2; struct eigrp_neighbor *nbr; show_ip_eigrp_neighbor_header(vty, eigrp); - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { if (!ifname || strcmp(ei->ifp->name, ifname) == 0) { - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (detail || (nbr->state == EIGRP_NEIGHBOR_UP)) show_ip_eigrp_neighbor_sub(vty, nbr, !!detail); @@ -320,7 +318,6 @@ DEFPY (clear_ip_eigrp_neighbors, { struct eigrp *eigrp; struct eigrp_interface *ei; - struct listnode *node, *node2, *nnode2; struct eigrp_neighbor *nbr; /* Check if eigrp process is enabled */ @@ -331,12 +328,12 @@ DEFPY (clear_ip_eigrp_neighbors, } /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* send Goodbye Hello */ eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); /* iterate over all neighbors on eigrp interface */ - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (nbr->state != EIGRP_NEIGHBOR_DOWN) { zlog_debug( "Neighbor %pI4 (%s) is down: manually cleared", @@ -376,7 +373,6 @@ DEFPY (clear_ip_eigrp_neighbors_int, { struct eigrp *eigrp; struct eigrp_interface *ei; - struct listnode *node2, *nnode2; struct eigrp_neighbor *nbr; /* Check if eigrp process is enabled */ @@ -397,7 +393,7 @@ DEFPY (clear_ip_eigrp_neighbors_int, eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); /* iterate over all neighbors on eigrp interface */ - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (nbr->state != EIGRP_NEIGHBOR_DOWN) { zlog_debug( "Neighbor %pI4 (%s) is down: manually cleared", diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index a0eff683db..5b0c64ffd0 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -105,6 +105,11 @@ void eigrp_zebra_init(void) zclient->zebra_connected = eigrp_zebra_connected; } +void eigrp_zebra_stop(void) +{ + zclient_stop(zclient); + zclient_free(zclient); +} /* Zebra route add and delete treatment. */ static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS) diff --git a/eigrpd/eigrp_zebra.h b/eigrpd/eigrp_zebra.h index 927d562ab2..723e71b7f0 100644 --- a/eigrpd/eigrp_zebra.h +++ b/eigrpd/eigrp_zebra.h @@ -17,6 +17,7 @@ #include "vrf.h" extern void eigrp_zebra_init(void); +extern void eigrp_zebra_stop(void); extern void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p, struct list *successors, uint32_t distance); diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index c7dd96bfff..543a54da13 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -55,6 +55,15 @@ struct eigrp_master *eigrp_om; extern struct zclient *zclient; extern struct in_addr router_id_zebra; +int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b) +{ + return a->vrf_id - b->vrf_id; +} + +uint32_t eigrp_master_hash_hash(const struct eigrp *a) +{ + return a->vrf_id; +} /* * void eigrp_router_id_update(struct eigrp *eigrp) @@ -111,7 +120,7 @@ void eigrp_master_init(void) memset(&eigrp_master, 0, sizeof(eigrp_master)); eigrp_om = &eigrp_master; - eigrp_om->eigrp = list_new(); + eigrp_master_hash_init(&eigrp_om->eigrp); monotime(&tv); eigrp_om->start_time = tv.tv_sec; @@ -139,7 +148,7 @@ static struct eigrp *eigrp_new(uint16_t as, vrf_id_t vrf_id) eigrp->k_values[5] = EIGRP_K6_DEFAULT; /* init internal data structures */ - eigrp->eiflist = list_new(); + eigrp_interface_hash_init(&eigrp->eifs); eigrp->passive_interface_default = EIGRP_IF_ACTIVE; eigrp->networks = eigrp_topology_new(); @@ -206,7 +215,7 @@ struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id) eigrp = eigrp_lookup(vrf_id); if (eigrp == NULL) { eigrp = eigrp_new(as, vrf_id); - listnode_add(eigrp_om->eigrp, eigrp); + eigrp_master_hash_add(&eigrp_om->eigrp, eigrp); } return eigrp; @@ -216,7 +225,6 @@ struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id) void eigrp_terminate(void) { struct eigrp *eigrp; - struct listnode *node, *nnode; /* shutdown already in progress */ if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN)) @@ -224,9 +232,16 @@ void eigrp_terminate(void) SET_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN); - for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) + while (eigrp_master_hash_count(&eigrp_om->eigrp)) { + eigrp = eigrp_master_hash_first(&eigrp_om->eigrp); eigrp_finish(eigrp); + } + + eigrp_master_hash_fini(&eigrp_om->eigrp); + + eigrp_zebra_stop(); + vrf_terminate(); frr_fini(); } @@ -234,16 +249,6 @@ void eigrp_finish(struct eigrp *eigrp) { eigrp_finish_final(eigrp); - /* eigrp being shut-down? If so, was this the last eigrp instance? */ - if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN) - && (listcount(eigrp_om->eigrp) == 0)) { - if (zclient) { - zclient_stop(zclient); - zclient_free(zclient); - } - exit(0); - } - return; } @@ -252,44 +257,48 @@ void eigrp_finish_final(struct eigrp *eigrp) { struct eigrp_interface *ei; struct eigrp_neighbor *nbr; - struct listnode *node, *nnode, *node2, *nnode2; - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { - for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) + while (eigrp_interface_hash_count(&eigrp->eifs)) { + ei = eigrp_interface_hash_first(&eigrp->eifs); + while (eigrp_nbr_hash_count(&ei->nbr_hash_head)) { + nbr = eigrp_nbr_hash_first(&ei->nbr_hash_head); eigrp_nbr_delete(nbr); - eigrp_if_free(ei, INTERFACE_DOWN_BY_FINAL); + } + eigrp_if_delete_hook(ei->ifp); } EVENT_OFF(eigrp->t_write); EVENT_OFF(eigrp->t_read); close(eigrp->fd); - list_delete(&eigrp->eiflist); + eigrp_interface_hash_fini(&eigrp->eifs); list_delete(&eigrp->oi_write_q); eigrp_topology_free(eigrp, eigrp->topology_table); + eigrp_network_free(eigrp, eigrp->networks); eigrp_nbr_delete(eigrp->neighbor_self); list_delete(&eigrp->topology_changes_externalIPV4); list_delete(&eigrp->topology_changes_internalIPV4); - listnode_delete(eigrp_om->eigrp, eigrp); + eigrp_master_hash_del(&eigrp_om->eigrp, eigrp); stream_free(eigrp->ibuf); distribute_list_delete(&eigrp->distribute_ctx); + + QOBJ_UNREG(eigrp); + XFREE(MTYPE_EIGRP_TOP, eigrp); } /*Look for existing eigrp process*/ struct eigrp *eigrp_lookup(vrf_id_t vrf_id) { - struct eigrp *eigrp; - struct listnode *node, *nnode; + struct eigrp *eigrp, lookup; - for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) - if (eigrp->vrf_id == vrf_id) - return eigrp; + lookup.vrf_id = vrf_id; + eigrp = eigrp_master_hash_find(&eigrp_om->eigrp, &lookup); - return NULL; + return eigrp; } diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h index a6a4e39a59..15d2bb54ee 100644 --- a/eigrpd/eigrpd.h +++ b/eigrpd/eigrpd.h @@ -30,9 +30,11 @@ DECLARE_MGROUP(EIGRPD); #define EIGRP_TLV_MTR_VERSION 3 /* MTR TLVs with 32bit metric *Not Supported */ #define EIGRP_TLV_SAF_VERSION 4 /* SAF TLVs with 64bit metric *Not Supported */ +//PREDECL_HASH(eigrp_master_hash); + struct eigrp_master { /* EIGRP instance. */ - struct list *eigrp; + struct eigrp_master_hash_head eigrp; /* EIGRP thread master. */ struct event_loop *master; @@ -64,4 +66,10 @@ extern struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id); extern struct eigrp *eigrp_lookup(vrf_id_t vrf_id); extern void eigrp_router_id_update(struct eigrp *eigrp); +extern int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b); +extern uint32_t eigrp_master_hash_hash(const struct eigrp *a); + +DECLARE_HASH(eigrp_master_hash, struct eigrp, eigrp_item, eigrp_master_hash_cmp, + eigrp_master_hash_hash); + #endif /* _ZEBRA_EIGRPD_H */ @@ -44,7 +44,6 @@ static void if_set_name(struct interface *ifp, const char *name); static struct interface *if_lookup_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id); static struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex); -static int if_cmp_func(const struct interface *, const struct interface *); static int if_cmp_index_func(const struct interface *ifp1, const struct interface *ifp2); RB_GENERATE(if_name_head, interface, name_entry, if_cmp_func); @@ -136,8 +135,7 @@ int if_cmp_name_func(const char *p1, const char *p2) return 0; } -static int if_cmp_func(const struct interface *ifp1, - const struct interface *ifp2) +int if_cmp_func(const struct interface *ifp1, const struct interface *ifp2) { return if_cmp_name_func(ifp1->name, ifp2->name); } @@ -309,6 +309,8 @@ struct interface { QOBJ_FIELDS; }; +extern int if_cmp_func(const struct interface *a, const struct interface *b); + RB_HEAD(if_name_head, interface); RB_PROTOTYPE(if_name_head, interface, name_entry, if_cmp_func) RB_HEAD(if_index_head, interface); diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 04ff35083f..261eed30ea 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -1061,6 +1061,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, zlog_debug( "%s, Not moving to HELPER role, So dicarding GraceLSA", __func__); + ospf6_lsa_delete(new); return; } } diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c index 64eb90d5f2..27b8df0828 100644 --- a/ospf6d/ospf6_gr.c +++ b/ospf6d/ospf6_gr.c @@ -371,6 +371,7 @@ void ospf6_gr_check_lsdb_consistency(struct ospf6 *ospf6, snprintfrr(reason, sizeof(reason), "detected inconsistent LSA %s [area %pI4]", lsa->name, &area->area_id); + ospf6_lsa_unlock(&lsa); ospf6_gr_restart_exit(ospf6, reason); return; } diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json index 1e5040ba60..20510a1e00 100644 --- a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json @@ -6,7 +6,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "172.31.0.15/32", "is_filtered": false, - "label": 0, + "label": 524288, "peer_asn": 65501, "peer_bgp_id": "192.168.0.1", "peer_distinguisher": "0:0", @@ -20,7 +20,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "2001::1111/128", "is_filtered": false, - "label": 0, + "label": 524288, "peer_asn": 65501, "peer_bgp_id": "192.168.0.1", "peer_distinguisher": "0:0", diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json index 9eb221d4d0..a34a0005e7 100644 --- a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json @@ -6,7 +6,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "2001::1111/128", "ipv6": true, - "label": 0, + "label": 524288, "peer_asn": 65502, "peer_bgp_id": "192.168.0.2", "peer_distinguisher": "0:0", @@ -21,7 +21,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "172.31.0.15/32", "ipv6": false, - "label": 0, + "label": 524288, "peer_asn": 65502, "peer_bgp_id": "192.168.0.2", "peer_distinguisher": "0:0", diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json index eea7501b22..92b8f52517 100644 --- a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json +++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json @@ -6,7 +6,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "2001::1111/128", "ipv6": true, - "label": 0, + "label": 524288, "peer_asn": 65502, "peer_bgp_id": "192.168.0.2", "peer_distinguisher": "0:0", @@ -21,7 +21,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "172.31.0.15/32", "ipv6": false, - "label": 0, + "label": 524288, "peer_asn": 65502, "peer_bgp_id": "192.168.0.2", "peer_distinguisher": "0:0", diff --git a/tests/topotests/bgp_bmp/bmp1import/bmp-withdraw-loc-rib-step2.json b/tests/topotests/bgp_bmp/bmp1import/bmp-withdraw-loc-rib-step2.json index 1e5040ba60..20510a1e00 100644 --- a/tests/topotests/bgp_bmp/bmp1import/bmp-withdraw-loc-rib-step2.json +++ b/tests/topotests/bgp_bmp/bmp1import/bmp-withdraw-loc-rib-step2.json @@ -6,7 +6,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "172.31.0.15/32", "is_filtered": false, - "label": 0, + "label": 524288, "peer_asn": 65501, "peer_bgp_id": "192.168.0.1", "peer_distinguisher": "0:0", @@ -20,7 +20,7 @@ "bmp_log_type": "withdraw", "ip_prefix": "2001::1111/128", "is_filtered": false, - "label": 0, + "label": 524288, "peer_asn": 65501, "peer_bgp_id": "192.168.0.1", "peer_distinguisher": "0:0", diff --git a/tests/topotests/lib/exa-receive.py b/tests/topotests/lib/exa-receive.py index 2ea3a75a5f..9035b6ab15 100755 --- a/tests/topotests/lib/exa-receive.py +++ b/tests/topotests/lib/exa-receive.py @@ -19,8 +19,23 @@ parser.add_argument( parser.add_argument("peer", type=int, help="The peer number") args = parser.parse_args() -savepath = os.path.join(args.logdir, "peer{}-received.log".format(args.peer)) -routesavefile = open(savepath, "w") +# Ensure log directory exists +logdir = args.logdir +if not os.path.exists(logdir): + try: + # Create a new log directory + os.makedirs(logdir) + except OSError as e: + print(f"Error in creating log directory: {e}") + exit(1) + +savepath = os.path.join(logdir, f"peer{args.peer}-received.log") + +try: + routesavefile = open(savepath, "w") +except IOError as e: + print(f"Error in opening log file: {e}") + exit(1) while True: try: diff --git a/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py index ba705e3dfc..a5715e6d88 100755 --- a/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py +++ b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py @@ -17,14 +17,14 @@ test_ospf6_gr_topo1.py: | 1.1.1.1 | +---------+ |eth-rt2 - | + |area 1 |eth-rt1 +---------+ | RT2 | | 2.2.2.2 | +---------+ |eth-rt3 - | + |area 0 |eth-rt2 +---------+ | RT3 | @@ -33,14 +33,14 @@ test_ospf6_gr_topo1.py: eth-rt4| |eth-rt6 | | +---------+ +--------+ - | | + |area 0 |area 0 |eth-rt3 |eth-rt3 +---------+ +---------+ | RT4 | | RT6 | | 4.4.4.4 | | 6.6.6.6 | +---------+ +---------+ |eth-rt5 |eth-rt7 - | | + |area 2 |area 3 |eth-rt4 |eth-rt6 +---------+ +---------+ | RT5 | | RT7 | @@ -153,7 +153,7 @@ def router_compare_json_output(rname, command, reference, tries): expected = json.loads(open(filename).read()) test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) - _, diff = topotest.run_and_expect(test_func, None, count=tries, wait=0.5) + _, diff = topotest.run_and_expect(test_func, None, count=tries, wait=1) assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) assert diff is None, assertmsg @@ -206,12 +206,12 @@ def check_routers(initial_convergence=False, exiting=None, restarting=None): # processing it. Let's give it a few seconds to allow this to happen # under load. if initial_convergence == True: - tries = 240 + tries = 120 else: if restarting != None: - tries = 40 + tries = 20 else: - tries = 10 + tries = 15 router_compare_json_output( rname, "show ipv6 route ospf json", "show_ipv6_route.json", tries ) @@ -219,7 +219,7 @@ def check_routers(initial_convergence=False, exiting=None, restarting=None): # Check that all adjacencies are up and running (except when there's # an OSPF instance that is shutting down). if exiting == None: - tries = 240 + tries = 120 router_compare_json_output( rname, "show ipv6 ospf neighbor json", @@ -231,9 +231,9 @@ def check_routers(initial_convergence=False, exiting=None, restarting=None): # In the restarting router, wait up to one minute for the LSDB to converge. if exiting != rname: if initial_convergence == True or restarting == rname: - tries = 240 + tries = 120 else: - tries = 10 + tries = 15 router_compare_json_output( rname, "show ipv6 ospf database json", diff --git a/tests/topotests/ripng_aggregate_address/__init__.py b/tests/topotests/ripng_aggregate_address/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/ripng_aggregate_address/__init__.py diff --git a/tests/topotests/ripng_aggregate_address/r2/frr.conf b/tests/topotests/ripng_aggregate_address/r2/frr.conf new file mode 100644 index 0000000000..fb9d6702c4 --- /dev/null +++ b/tests/topotests/ripng_aggregate_address/r2/frr.conf @@ -0,0 +1,14 @@ +! +int lo + ipv6 address 2001:db8:2::1/64 +! +int r2-eth0 + ipv6 address 2001:db8::2/64 +! +router ripng + redistribute connected + network 2001:db8::/64 + network 2001:db8:2::1/64 + timers basic 5 15 10 +exit + diff --git a/tests/topotests/ripng_aggregate_address/r3/frr.conf b/tests/topotests/ripng_aggregate_address/r3/frr.conf new file mode 100644 index 0000000000..d9b542af8e --- /dev/null +++ b/tests/topotests/ripng_aggregate_address/r3/frr.conf @@ -0,0 +1,23 @@ +! +int lo + ipv6 address 2001:db8:3::1/64 +! +int r3-eth0 + ipv6 address 2001:db8::3/64 +! +debug ripng events +debug ripng packet +debug ripng zebra +router ripng + aggregate-address 33::/64 + redistribute connected + redistribute static + network 2001:db8::/64 + network 2001:db8:3::1/64 + timers basic 5 15 10 +exit + +ipv6 route 33::1/128 lo +ipv6 route 33::2/128 lo +ipv6 route 33::3/128 lo +ipv6 route 33::4/128 lo diff --git a/tests/topotests/ripng_aggregate_address/test_ripng_aggregate_address.py b/tests/topotests/ripng_aggregate_address/test_ripng_aggregate_address.py new file mode 100644 index 0000000000..05980a0e13 --- /dev/null +++ b/tests/topotests/ripng_aggregate_address/test_ripng_aggregate_address.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2025 by +# Donald Sharp <sharpd@nvidia.com> +# + +""" +Test if aggregate-address for ripng basic functionality works. +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, get_topogen + +pytestmark = [pytest.mark.ripngd] + + +def setup_module(mod): + topodef = {"s1": ( "r2", "r3")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(): + tgen = get_topogen() + tgen.stop_topology() + + +def test_ripng_aggregate_address(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r3 = tgen.gears["r3"] + r2 = tgen.gears["r2"] + + def _show_routes(nh_num): + output = json.loads(r2.vtysh_cmd("show ipv6 route ripng json")) + expected = { + "33::/64": [ + { + "metric": 2, + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_show_routes, 2) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "No aggregate address received" + + # Turn it off + r3.vtysh_cmd("conf\nrouter ripng\nno aggregate-address 33::/64") + + def _show_routes_removed(nh_num): + output = json.loads(r2.vtysh_cmd("show ipv6 route ripng json")) + expected = { + "33::1/128": [ + { + "metric": 2, + } + ], + "33::2/128": [ + { + "metric": 2, + } + ], + "33::3/128": [ + { + "metric": 2, + } + ], + "33::4/128": [ + { + "metric": 2, + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_show_routes_removed, 2) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Non aggregate routes are not present" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/simple_snmp_test/r1/bgpd.conf b/tests/topotests/simple_snmp_test/r1/bgpd.conf deleted file mode 100644 index bcdf1c4f7e..0000000000 --- a/tests/topotests/simple_snmp_test/r1/bgpd.conf +++ /dev/null @@ -1,5 +0,0 @@ -! -router bgp 100 - bgp router-id 1.1.1.1 - -agentx diff --git a/tests/topotests/simple_snmp_test/r1/frr.conf b/tests/topotests/simple_snmp_test/r1/frr.conf new file mode 100644 index 0000000000..0b66a1f7b2 --- /dev/null +++ b/tests/topotests/simple_snmp_test/r1/frr.conf @@ -0,0 +1,77 @@ +hostname r1 +log timestamp precision 6 +agentx +! +interface lo + ip address 1.1.1.1/32 + ip router isis ISIS1 + ipv6 address 2000:1:1:1::1/128 + ipv6 router isis ISIS1 + isis circuit-type level-1 + isis passive + no isis hello padding +exit +! +interface r1-eth0 + ip address 192.168.12.12/24 + ip ospf area 0.0.0.0 + ip router isis ISIS1 + ipv6 address 2000:1:1:12::12/64 + ipv6 ospf6 area 0.0.0.0 + ipv6 router isis ISIS1 + isis circuit-type level-1 + isis hello-interval 1 + isis network point-to-point + no isis hello padding +exit +! +interface r1-eth1 + ip address 192.168.13.13/24 + ip ospf area 0.0.0.0 + ip router isis ISIS1 + ipv6 address 2000:1:1:13::13/64 + ipv6 ospf6 area 0.0.0.0 + ipv6 router isis ISIS1 + isis circuit-type level-1 + isis hello-interval 1 + isis network point-to-point + no isis hello padding +exit +! +interface r1-eth2 + ip address 192.168.14.14/24 + ip ospf area 0.0.0.0 + ip router isis ISIS1 + ipv6 address 2000:1:1:14::14/64 + ipv6 ospf6 area 0.0.0.0 + ipv6 router isis ISIS1 + isis circuit-type level-1 + isis hello-interval 1 + isis network point-to-point + no isis hello padding +exit +! +router rip + network 0.0.0.0/0 + redistribute local +exit +! +router bgp 100 + bgp router-id 1.1.1.1 +exit +! +router ospf + redistribute local +exit +! +router ospf6 + redistribute local +exit +! +router isis ISIS1 + is-type level-1 + net 01.1111.0000.0000.0001.00 + topology ipv6-unicast +exit +! +end diff --git a/tests/topotests/simple_snmp_test/r1/isisd.conf b/tests/topotests/simple_snmp_test/r1/isisd.conf deleted file mode 100644 index c53d2509e2..0000000000 --- a/tests/topotests/simple_snmp_test/r1/isisd.conf +++ /dev/null @@ -1,48 +0,0 @@ -log stdout debugging -! -! debug isis route-events -! debug isis events -! -agentx -! -interface r1-eth0 - ip router isis ISIS1 - ipv6 router isis ISIS1 - isis circuit-type level-1 - no isis hello padding - isis hello-interval 1 - isis hello-multiplier 10 - isis network point-to-point -! -interface r1-eth1 - ip router isis ISIS1 - ipv6 router isis ISIS1 - isis circuit-type level-1 - no isis hello padding - isis hello-interval 1 - isis hello-multiplier 10 - isis network point-to-point -! -interface r1-eth2 - ip router isis ISIS1 - ipv6 router isis ISIS1 - isis circuit-type level-1 - no isis hello padding - isis hello-interval 1 - isis hello-multiplier 10 - isis network point-to-point -! -interface lo - ip router isis ISIS1 - ipv6 router isis ISIS1 - isis circuit-type level-1 - isis passive - no isis hello padding -! -router isis ISIS1 - net 01.1111.0000.0000.0001.00 - is-type level-1 - topology ipv6-unicast -! -line vty -! diff --git a/tests/topotests/simple_snmp_test/r1/ospf6d.conf b/tests/topotests/simple_snmp_test/r1/ospf6d.conf deleted file mode 100644 index e81151710b..0000000000 --- a/tests/topotests/simple_snmp_test/r1/ospf6d.conf +++ /dev/null @@ -1,12 +0,0 @@ -agentx - -int r1-eth0 - ipv6 ospf6 area 0.0.0.0 - -int r1-eth1 - ipv6 ospf6 area 0.0.0.0 -int r1-eth2 - ipv6 ospf6 area 0.0.0.0 - -router ospf6 - redistribute local
\ No newline at end of file diff --git a/tests/topotests/simple_snmp_test/r1/ospfd.conf b/tests/topotests/simple_snmp_test/r1/ospfd.conf deleted file mode 100644 index cc0d9e52c2..0000000000 --- a/tests/topotests/simple_snmp_test/r1/ospfd.conf +++ /dev/null @@ -1,11 +0,0 @@ -agentx - -int r1-eth0 - ip ospf area 0.0.0.0 -int r1-eth1 - ip ospf area 0.0.0.0 -int r1-eth2 - ip ospf area 0.0.0.0 - -router ospf - redistribute local
\ No newline at end of file diff --git a/tests/topotests/simple_snmp_test/r1/ripd.conf b/tests/topotests/simple_snmp_test/r1/ripd.conf deleted file mode 100644 index 71cdb058cf..0000000000 --- a/tests/topotests/simple_snmp_test/r1/ripd.conf +++ /dev/null @@ -1,8 +0,0 @@ -! -! -router rip - network 0.0.0.0/0 - redistribute local -! -agentx -!
\ No newline at end of file diff --git a/tests/topotests/simple_snmp_test/r1/zebra.conf b/tests/topotests/simple_snmp_test/r1/zebra.conf deleted file mode 100644 index 6483a661ce..0000000000 --- a/tests/topotests/simple_snmp_test/r1/zebra.conf +++ /dev/null @@ -1,23 +0,0 @@ -log file zebra.log -! -agentx -! -interface r1-eth0 - ip address 192.168.12.12/24 - ipv6 address 2000:1:1:12::12/64 -! -interface r1-eth1 - ip address 192.168.13.13/24 - ipv6 address 2000:1:1:13::13/64 -! -interface r1-eth2 - ip address 192.168.14.14/24 - ipv6 address 2000:1:1:14::14/64 -! -! -interface lo - ip address 1.1.1.1/32 - ipv6 address 2000:1:1:1::1/128 -! -! -line vty diff --git a/tests/topotests/simple_snmp_test/test_simple_snmp.py b/tests/topotests/simple_snmp_test/test_simple_snmp.py index c74ffcc2db..24c6a5cb53 100755 --- a/tests/topotests/simple_snmp_test/test_simple_snmp.py +++ b/tests/topotests/simple_snmp_test/test_simple_snmp.py @@ -59,41 +59,21 @@ def setup_module(mod): # For all registered routers, load the zebra configuration file for rname, router in router_list.items(): - router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, "{}/zebra.conf".format(rname)), - "-M snmp", - ) - router.load_config( - TopoRouter.RD_ISIS, - os.path.join(CWD, "{}/isisd.conf".format(rname)), - "-M snmp", - ) - router.load_config( - TopoRouter.RD_BGP, - os.path.join(CWD, "{}/bgpd.conf".format(rname)), - "-M snmp", - ) - router.load_config( - TopoRouter.RD_RIP, - os.path.join(CWD, "{}/ripd.conf".format(rname)), - "-M snmp", - ) - router.load_config( - TopoRouter.RD_OSPF, - os.path.join(CWD, "{}/ospfd.conf".format(rname)), - "-M snmp", - ) - router.load_config( - TopoRouter.RD_OSPF6, - os.path.join(CWD, "{}/ospf6d.conf".format(rname)), - "-M snmp", - ) - router.load_config( - TopoRouter.RD_SNMP, - os.path.join(CWD, "{}/snmpd.conf".format(rname)), - "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap", + router.load_frr_config( + os.path.join(CWD, "{}/frr.conf".format(rname)), + [ + (TopoRouter.RD_ZEBRA, "-M snmp"), + (TopoRouter.RD_ISIS, "-M snmp"), + (TopoRouter.RD_BGP, "-M snmp"), + (TopoRouter.RD_RIP, "-M snmp"), + (TopoRouter.RD_OSPF, "-M snmp"), + (TopoRouter.RD_OSPF6, "-M snmp"), + ], ) + router.load_config(TopoRouter.RD_SNMP, + os.path.join(CWD, "{}/snmpd.conf".format(rname)), + "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap") + # After loading the configurations, this function loads configured daemons. tgen.start_router() @@ -138,8 +118,8 @@ def test_r1_bgp_version(): ) assert r1_snmp.test_oid("ISIS-MIB::isisSysVersion", "one(1)") - # rip is not auto-loading agentx from mgmtd - # assert r1_snmp.test_oid("RIPv2-MIB::rip2GlobalQueries", "0") + + assert r1_snmp.test_oid("RIPv2-MIB::rip2GlobalQueries", "0") assert r1_snmp.test_oid("OSPF-MIB::ospfVersionNumber", "version2(2)") assert r1_snmp.test_oid("OSPFV3-MIB::ospfv3VersionNumber", "version3(3)") diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index 228faa4f10..54ef505b1f 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -65,20 +65,28 @@ module frr-isisd { description "Group SRGB and SRLB in a container so that they can be displayed and configured together"; + reference + "ISO/IEC 10589:2002."; } revision 2020-04-06 { description "Group LSP timers in a container so that they can be displayed and configured together"; + reference + "ISO/IEC 10589:2002."; } revision 2019-12-17 { description "Changed default area is-type to level-1-2"; + reference + "ISO/IEC 10589:2002."; } revision 2019-09-09 { description "Changed interface references to use frr-interface:interface-ref typedef"; + reference + "ISO/IEC 10589:2002."; } revision 2018-07-26 { description @@ -134,6 +142,8 @@ module frr-isisd { "Add padding to hello packets during adjacency formation only."; } } + description + "Type for hello padding configuration."; } typedef network-type { @@ -159,6 +169,8 @@ module frr-isisd { "Loopback circuit network-type. Only valid as a state."; } } + description + "Type of network for an IS-IS interface."; } typedef lsp-id { @@ -268,14 +280,20 @@ module frr-isisd { "This enum describes transition metric style"; } } + description + "Enumeration for IS-IS metric styles."; } typedef access-list-ref { type string; + description + "Reference to a access list."; } typedef prefix-list-ref { type string; + description + "Reference to a prefix list."; } grouping redistribute-attributes { @@ -344,6 +362,9 @@ module frr-isisd { } grouping isis-area-password { + description + "Grouping for IS-IS area password configuration."; + uses isis-password; leaf authenticate-snp { @@ -371,6 +392,9 @@ module frr-isisd { } grouping global-config-lfa { + description + "Grouping for LFA configuration."; + container lfa { description "LFA configuration."; @@ -441,6 +465,9 @@ module frr-isisd { } grouping global-config-remote-lfa { + description + "Grouping for Remote LFA configuration."; + container remote-lfa { description "Remote LFA configuration."; @@ -454,6 +481,9 @@ module frr-isisd { } grouping interface-config-lfa { + description + "Grouping for LFA configuration on an interface."; + container lfa { description "LFA configuration."; @@ -472,19 +502,22 @@ module frr-isisd { } grouping interface-config-remote-lfa { + description + "Grouping for remote LFA configuration."; + container remote-lfa { description "Remote LFA configuration."; leaf enable { type boolean; - default false; - description - "Enables remote LFA computation using LDP tunnels."; must ". = 'false' or ../../lfa/enable = 'true'" { error-message "Remote LFA depends on classic LFA being configured in the interface."; } + default false; + description + "Enables remote LFA computation using LDP tunnels."; } leaf maximum-metric { @@ -498,15 +531,18 @@ module frr-isisd { } grouping interface-config-ti-lfa { + description + "Grouping for TI-LFA configuration."; + container ti-lfa { description "TI-LFA configuration."; leaf enable { + type boolean; must ". = 'false' or ../../lfa/enable = 'false'" { error-message "Can't enable both classic LFA and TI-LFA in the same interface."; } - type boolean; default false; description "Enables TI-LFA computation."; @@ -560,6 +596,9 @@ module frr-isisd { } container bfd-monitoring { + description + "Container for BFD monitoring configuration."; + leaf enabled { type boolean; default "false"; @@ -742,6 +781,9 @@ module frr-isisd { container password { presence "Present if a password is set for this IS interface."; uses isis-password; + + description + "Container for the password of this IS interface."; } leaf disable-three-way-handshake { @@ -1035,6 +1077,9 @@ module frr-isisd { description "This container lists the information of adjacency SID."; list adjacency-sid { + description + "List of adjacency SIDs."; + leaf af { type uint8; description @@ -1070,6 +1115,9 @@ module frr-isisd { description "This container lists the information of LAN adjacency SID."; list lan-adjacency-sid { + description + "List of LAN adjacency SIDs."; + leaf af { type uint8; description @@ -1456,6 +1504,8 @@ module frr-isisd { leaf level { type level; must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))"; + description + "Specifies the level to which the default route should be distributed."; } uses redistribute-default; @@ -1468,6 +1518,8 @@ module frr-isisd { leaf level { type level; must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))"; + description + "Specifies the level to which the default route should be distributed."; } uses redistribute-default; @@ -1496,11 +1548,14 @@ module frr-isisd { } choice protocol-type { + description + "Choice of routing protocol type."; + case protocol-table { when "./protocol = \"table\""; list table { - key "table"; when "../protocol = \"table\""; + key "table"; description "Routing table number"; @@ -1540,11 +1595,16 @@ module frr-isisd { } choice protocol-type { + description + "Choice of routing protocol type."; + case protocol-table { - when "./protocol = \"table\""; list table { - key "table"; when "../protocol = \"table\""; + key "table"; + + description + "List of routing tables for the 'table' protocol."; leaf table { type uint16 { @@ -1556,6 +1616,7 @@ module frr-isisd { uses redistribute-attributes; } + when "./protocol = \"table\""; } case protocol-other { uses redistribute-attributes; @@ -1575,6 +1636,8 @@ module frr-isisd { leaf overload { type boolean; default "false"; + description + "If set to true, the router will advertise itself as overloaded to its neighbors."; } } @@ -1585,6 +1648,8 @@ module frr-isisd { leaf overload { type boolean; default "false"; + description + "If set to true, the router will advertise itself as overloaded to its neighbors."; } } @@ -1595,6 +1660,8 @@ module frr-isisd { leaf overload { type boolean; default "false"; + description + "If set to true, the router will advertise itself as overloaded to its neighbors."; } } @@ -1605,6 +1672,8 @@ module frr-isisd { leaf overload { type boolean; default "false"; + description + "If set to true, the router will advertise itself as overloaded to its neighbors."; } } @@ -1615,6 +1684,8 @@ module frr-isisd { leaf overload { type boolean; default "false"; + description + "If set to true, the router will advertise itself as overloaded to its neighbors."; } } @@ -1625,6 +1696,8 @@ module frr-isisd { leaf overload { type boolean; default "false"; + description + "If set to true, the router will advertise itself as overloaded to its neighbors."; } } } @@ -1730,9 +1803,6 @@ module frr-isisd { "Use Flex-algo Prefix Metric"; } leaf metric-type { - default "igp"; - description - "Set the Flex-Algo metric-type"; type enumeration { enum "igp" { value 0; @@ -1750,6 +1820,9 @@ module frr-isisd { "RFC 5305 Sec 3.7 Traffic Engineering Default Metric"; } } + default "igp"; + description + "Set the Flex-Algo metric-type"; } leaf priority { type uint32 { @@ -1799,15 +1872,15 @@ module frr-isisd { description "Global blocks to be advertised."; leaf lower-bound { - must "../upper-bound > ."; type uint32; + must "../upper-bound > ."; default "16000"; description "Lower value in the label range."; } leaf upper-bound { - must ". > ../lower-bound"; type uint32; + must ". > ../lower-bound"; default "23999"; description "Upper value in the label range."; @@ -1817,15 +1890,15 @@ module frr-isisd { description "Local blocks to be advertised."; leaf lower-bound { - must "../upper-bound > ."; type uint32; + must "../upper-bound > ."; default "15000"; description "Lower value in the label range."; } leaf upper-bound { - must ". > ../lower-bound"; type uint32; + must ". > ../lower-bound"; default "15999"; description "Upper value in the label range."; @@ -2053,9 +2126,9 @@ module frr-isisd { } leaf interface { type string; + default "sr0"; description "Dummy interface used to install SRv6 SIDs into the Linux data plane."; - default "sr0"; } } |
