summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_interface.c7
-rw-r--r--bgpd/bgp_attr.c8
-rw-r--r--bgpd/bgp_label.h2
-rw-r--r--bgpd/bgp_route.c25
-rw-r--r--eigrpd/eigrp_dump.c8
-rw-r--r--eigrpd/eigrp_filter.c4
-rw-r--r--eigrpd/eigrp_fsm.c10
-rw-r--r--eigrpd/eigrp_hello.c5
-rw-r--r--eigrpd/eigrp_interface.c43
-rw-r--r--eigrpd/eigrp_interface.h6
-rw-r--r--eigrpd/eigrp_main.c1
-rw-r--r--eigrpd/eigrp_neighbor.c70
-rw-r--r--eigrpd/eigrp_neighbor.h7
-rw-r--r--eigrpd/eigrp_network.c21
-rw-r--r--eigrpd/eigrp_network.h1
-rw-r--r--eigrpd/eigrp_northbound.c6
-rw-r--r--eigrpd/eigrp_packet.c26
-rw-r--r--eigrpd/eigrp_query.c12
-rw-r--r--eigrpd/eigrp_reply.c3
-rw-r--r--eigrpd/eigrp_routemap.c3
-rw-r--r--eigrpd/eigrp_structs.h16
-rw-r--r--eigrpd/eigrp_topology.c23
-rw-r--r--eigrpd/eigrp_update.c28
-rw-r--r--eigrpd/eigrp_vty.c16
-rw-r--r--eigrpd/eigrp_zebra.c5
-rw-r--r--eigrpd/eigrp_zebra.h1
-rw-r--r--eigrpd/eigrpd.c63
-rw-r--r--eigrpd/eigrpd.h10
-rw-r--r--lib/if.c4
-rw-r--r--lib/if.h2
-rw-r--r--ospf6d/ospf6_flood.c1
-rw-r--r--ospf6d/ospf6_gr.c1
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json4
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json4
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json4
-rw-r--r--tests/topotests/bgp_bmp/bmp1import/bmp-withdraw-loc-rib-step2.json4
-rwxr-xr-xtests/topotests/lib/exa-receive.py19
-rwxr-xr-xtests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py22
-rw-r--r--tests/topotests/ripng_aggregate_address/__init__.py0
-rw-r--r--tests/topotests/ripng_aggregate_address/r2/frr.conf14
-rw-r--r--tests/topotests/ripng_aggregate_address/r3/frr.conf23
-rw-r--r--tests/topotests/ripng_aggregate_address/test_ripng_aggregate_address.py106
-rw-r--r--tests/topotests/simple_snmp_test/r1/bgpd.conf5
-rw-r--r--tests/topotests/simple_snmp_test/r1/frr.conf77
-rw-r--r--tests/topotests/simple_snmp_test/r1/isisd.conf48
-rw-r--r--tests/topotests/simple_snmp_test/r1/ospf6d.conf12
-rw-r--r--tests/topotests/simple_snmp_test/r1/ospfd.conf11
-rw-r--r--tests/topotests/simple_snmp_test/r1/ripd.conf8
-rw-r--r--tests/topotests/simple_snmp_test/r1/zebra.conf23
-rwxr-xr-xtests/topotests/simple_snmp_test/test_simple_snmp.py52
-rw-r--r--yang/frr-isisd.yang103
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 */
diff --git a/lib/if.c b/lib/if.c
index 68724a65e9..43e3363b34 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -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);
}
diff --git a/lib/if.h b/lib/if.h
index 897f2be239..fce6705c23 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -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";
}
}