summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eigrpd/eigrp_cli.c1
-rw-r--r--eigrpd/eigrp_cli.h70
-rw-r--r--eigrpd/eigrp_const.h8
-rw-r--r--eigrpd/eigrp_dump.c10
-rw-r--r--eigrpd/eigrp_dump.h10
-rw-r--r--eigrpd/eigrp_fsm.c54
-rw-r--r--eigrpd/eigrp_interface.c53
-rw-r--r--eigrpd/eigrp_interface.h5
-rw-r--r--eigrpd/eigrp_main.c2
-rw-r--r--eigrpd/eigrp_memory.c4
-rw-r--r--eigrpd/eigrp_memory.h4
-rw-r--r--eigrpd/eigrp_metric.c146
-rw-r--r--eigrpd/eigrp_metric.h63
-rw-r--r--eigrpd/eigrp_neighbor.c2
-rw-r--r--eigrpd/eigrp_neighbor.h2
-rw-r--r--eigrpd/eigrp_network.c70
-rw-r--r--eigrpd/eigrp_network.h5
-rw-r--r--eigrpd/eigrp_northbound.c1
-rw-r--r--eigrpd/eigrp_packet.c2
-rw-r--r--eigrpd/eigrp_packet.h178
-rw-r--r--eigrpd/eigrp_query.c12
-rw-r--r--eigrpd/eigrp_reply.c19
-rw-r--r--eigrpd/eigrp_routemap.c4
-rw-r--r--eigrpd/eigrp_siaquery.c10
-rw-r--r--eigrpd/eigrp_siareply.c10
-rw-r--r--eigrpd/eigrp_structs.h50
-rw-r--r--eigrpd/eigrp_topology.c126
-rw-r--r--eigrpd/eigrp_topology.h52
-rw-r--r--eigrpd/eigrp_types.h36
-rw-r--r--eigrpd/eigrp_update.c58
-rw-r--r--eigrpd/eigrp_vty.c24
-rw-r--r--eigrpd/eigrp_yang.h32
-rw-r--r--eigrpd/eigrp_zebra.c4
-rw-r--r--eigrpd/eigrpd.h77
-rw-r--r--eigrpd/subdir.am5
-rw-r--r--lib/zclient.c26
-rw-r--r--lib/zclient.h3
-rw-r--r--tests/topotests/lib/common_config.py16
-rw-r--r--tests/topotests/lib/ospf.py45
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py45
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py39
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_lan.py36
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_nssa.py35
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py53
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py49
-rw-r--r--zebra/zebra_dplane.c26
-rw-r--r--zebra/zebra_nhg.c6
-rw-r--r--zebra/zebra_rib.c101
48 files changed, 941 insertions, 748 deletions
diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c
index 3610b3a869..00d8ea8867 100644
--- a/eigrpd/eigrp_cli.c
+++ b/eigrpd/eigrp_cli.c
@@ -29,6 +29,7 @@
#include "eigrp_structs.h"
#include "eigrpd.h"
#include "eigrp_zebra.h"
+#include "eigrp_cli.h"
#ifndef VTYSH_EXTRACT_PL
#include "eigrpd/eigrp_cli_clippy.c"
diff --git a/eigrpd/eigrp_cli.h b/eigrpd/eigrp_cli.h
new file mode 100644
index 0000000000..c5f2fd8009
--- /dev/null
+++ b/eigrpd/eigrp_cli.h
@@ -0,0 +1,70 @@
+/*
+ * EIGRP CLI Functions.
+ * Copyright (C) 2019
+ * Authors:
+ * Donnie Savage
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _EIGRP_CLI_H_
+#define _EIGRP_CLI_H_
+
+/*Prototypes*/
+extern void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode);
+extern void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_passive_interface(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_maximum_paths(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_redistribute(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_hello_interval(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_summarize_address(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_authentication(struct vty *vty,
+ struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+extern void eigrp_cli_init(void);
+
+#endif /*EIGRP_CLI_H_ */
diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h
index d3d9bca82a..149cf00efc 100644
--- a/eigrpd/eigrp_const.h
+++ b/eigrpd/eigrp_const.h
@@ -122,10 +122,10 @@ enum metric_change { METRIC_DECREASE, METRIC_SAME, METRIC_INCREASE };
#define EIGRP_TOPOLOGY_TYPE_REMOTE_EXTERNAL 2 // Remote external network
/*EIGRP TT entry flags*/
-#define EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG (1 << 0)
-#define EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG (1 << 1)
-#define EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG (1 << 2)
-#define EIGRP_NEXTHOP_ENTRY_EXTERNAL_FLAG (1 << 3)
+#define EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG (1 << 0)
+#define EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG (1 << 1)
+#define EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG (1 << 2)
+#define EIGRP_ROUTE_DESCRIPTOR_EXTERNAL_FLAG (1 << 3)
/*EIGRP FSM state count, event count*/
#define EIGRP_FSM_STATE_MAX 5
diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c
index dfce2acad4..e1ad51a9db 100644
--- a/eigrpd/eigrp_dump.c
+++ b/eigrpd/eigrp_dump.c
@@ -236,7 +236,8 @@ void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp)
"Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply\n r - reply Status, s - sia Status\n\n");
}
-void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
+void show_ip_eigrp_prefix_descriptor(struct vty *vty,
+ struct eigrp_prefix_descriptor *tn)
{
struct list *successors = eigrp_topology_get_successor(tn);
@@ -251,14 +252,15 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
list_delete(&successors);
}
-void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp,
- struct eigrp_nexthop_entry *te, bool *first)
+void show_ip_eigrp_route_descriptor(struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_route_descriptor *te,
+ bool *first)
{
if (te->reported_distance == EIGRP_MAX_METRIC)
return;
if (*first) {
- show_ip_eigrp_prefix_entry(vty, te->prefix);
+ show_ip_eigrp_prefix_descriptor(vty, te->prefix);
*first = false;
}
diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h
index 348356bb3c..0d512fc63f 100644
--- a/eigrpd/eigrp_dump.h
+++ b/eigrpd/eigrp_dump.h
@@ -151,11 +151,11 @@ extern void show_ip_eigrp_interface_sub(struct vty *, struct eigrp *,
struct eigrp_interface *);
extern void show_ip_eigrp_neighbor_sub(struct vty *, struct eigrp_neighbor *,
int);
-extern void show_ip_eigrp_prefix_entry(struct vty *,
- struct eigrp_prefix_entry *);
-extern void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp,
- struct eigrp_nexthop_entry *ne,
- bool *first);
+extern void show_ip_eigrp_prefix_descriptor(struct vty *vty,
+ struct eigrp_prefix_descriptor *tn);
+extern void show_ip_eigrp_route_descriptor(struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_route_descriptor *ne,
+ bool *first);
extern void eigrp_debug_init(void);
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c
index a69a3eec0a..d2d435bf2d 100644
--- a/eigrpd/eigrp_fsm.c
+++ b/eigrpd/eigrp_fsm.c
@@ -77,6 +77,7 @@
#include "linklist.h"
#include "vty.h"
+#include "eigrpd/eigrp_types.h"
#include "eigrpd/eigrp_structs.h"
#include "eigrpd/eigrpd.h"
#include "eigrpd/eigrp_interface.h"
@@ -88,6 +89,7 @@
#include "eigrpd/eigrp_dump.h"
#include "eigrpd/eigrp_topology.h"
#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_metric.h"
/*
* Prototypes
@@ -262,13 +264,13 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
{
// Loading base information from message
// struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
- struct eigrp_nexthop_entry *entry = msg->entry;
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
+ struct eigrp_route_descriptor *entry = msg->entry;
uint8_t actual_state = prefix->state;
enum metric_change change;
if (entry == NULL) {
- entry = eigrp_nexthop_entry_new();
+ entry = eigrp_route_descriptor_new();
entry->adv_router = msg->adv_router;
entry->ei = msg->adv_router->ei;
entry->prefix = prefix;
@@ -286,7 +288,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
switch (actual_state) {
case EIGRP_FSM_STATE_PASSIVE: {
- struct eigrp_nexthop_entry *head =
+ struct eigrp_route_descriptor *head =
listnode_head(prefix->entries);
if (head->reported_distance < prefix->fdistance) {
@@ -307,7 +309,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
}
case EIGRP_FSM_STATE_ACTIVE_0: {
if (msg->packet_type == EIGRP_OPC_REPLY) {
- struct eigrp_nexthop_entry *head =
+ struct eigrp_route_descriptor *head =
listnode_head(prefix->entries);
listnode_delete(prefix->rij, entry->adv_router);
@@ -322,7 +324,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
return EIGRP_FSM_EVENT_LR_FCN;
} else if (msg->packet_type == EIGRP_OPC_QUERY
&& (entry->flags
- & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
+ & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_QACT;
}
@@ -332,14 +334,14 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
}
case EIGRP_FSM_STATE_ACTIVE_1: {
if (msg->packet_type == EIGRP_OPC_QUERY
- && (entry->flags & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
+ && (entry->flags & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_QACT;
} else if (msg->packet_type == EIGRP_OPC_REPLY) {
listnode_delete(prefix->rij, entry->adv_router);
if (change == METRIC_INCREASE
&& (entry->flags
- & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
+ & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
} else if (prefix->rij->count) {
return EIGRP_FSM_KEEP_STATE;
@@ -350,7 +352,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
} else if (msg->packet_type == EIGRP_OPC_UPDATE
&& change == METRIC_INCREASE
&& (entry->flags
- & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
+ & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
}
return EIGRP_FSM_KEEP_STATE;
@@ -359,7 +361,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
}
case EIGRP_FSM_STATE_ACTIVE_2: {
if (msg->packet_type == EIGRP_OPC_REPLY) {
- struct eigrp_nexthop_entry *head =
+ struct eigrp_route_descriptor *head =
listnode_head(prefix->entries);
listnode_delete(prefix->rij, entry->adv_router);
@@ -385,7 +387,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
if (change == METRIC_INCREASE
&& (entry->flags
- & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
+ & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
} else if (prefix->rij->count) {
return EIGRP_FSM_KEEP_STATE;
@@ -396,7 +398,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
} else if (msg->packet_type == EIGRP_OPC_UPDATE
&& change == METRIC_INCREASE
&& (entry->flags
- & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
+ & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
}
return EIGRP_FSM_KEEP_STATE;
@@ -434,9 +436,9 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
{
struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
struct list *successors = eigrp_topology_get_successor(prefix);
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_route_descriptor *ne;
assert(successors); // If this is NULL we have shit the bed, fun huh?
@@ -461,9 +463,9 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
{
struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
struct list *successors = eigrp_topology_get_successor(prefix);
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_route_descriptor *ne;
assert(successors); // If this is NULL somebody poked us in the eye.
@@ -487,8 +489,8 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
{
struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
- struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
+ struct eigrp_route_descriptor *ne = listnode_head(prefix->entries);
if (prefix->state == EIGRP_FSM_STATE_PASSIVE) {
if (!eigrp_metrics_is_same(prefix->reported_metric,
@@ -515,8 +517,8 @@ int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
{
struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
- struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
+ struct eigrp_route_descriptor *ne = listnode_head(prefix->entries);
prefix->fdistance = prefix->distance = prefix->rdistance = ne->distance;
prefix->reported_metric = ne->total_metric;
@@ -545,7 +547,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg)
{
struct list *successors = eigrp_topology_get_successor(msg->prefix);
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_route_descriptor *ne;
assert(successors); // Trump and his big hands
@@ -566,8 +568,8 @@ int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
{
struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
- struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
+ struct eigrp_route_descriptor *ne = listnode_head(prefix->entries);
prefix->state = EIGRP_FSM_STATE_PASSIVE;
prefix->distance = prefix->rdistance = ne->distance;
@@ -598,8 +600,8 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
{
struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
- struct eigrp_nexthop_entry *best_successor;
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
+ struct eigrp_route_descriptor *best_successor;
struct list *successors = eigrp_topology_get_successor(prefix);
assert(successors); // Routing without a stack
@@ -628,7 +630,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg)
{
struct list *successors = eigrp_topology_get_successor(msg->prefix);
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_route_descriptor *ne;
assert(successors); // Cats and no Dogs
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c
index dd43dd0478..74eff958da 100644
--- a/eigrpd/eigrp_interface.c
+++ b/eigrpd/eigrp_interface.c
@@ -55,6 +55,8 @@
#include "eigrpd/eigrp_memory.h"
#include "eigrpd/eigrp_fsm.h"
#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_types.h"
+#include "eigrpd/eigrp_metric.h"
struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp,
struct prefix *p)
@@ -229,8 +231,8 @@ void eigrp_del_if_params(struct eigrp_if_params *eip)
int eigrp_if_up(struct eigrp_interface *ei)
{
- struct eigrp_prefix_entry *pe;
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_prefix_descriptor *pe;
+ struct eigrp_route_descriptor *ne;
struct eigrp_metrics metric;
struct eigrp_interface *ei2;
struct listnode *node, *nnode;
@@ -263,14 +265,14 @@ int eigrp_if_up(struct eigrp_interface *ei)
/*Add connected entry to topology table*/
- ne = eigrp_nexthop_entry_new();
+ ne = eigrp_route_descriptor_new();
ne->ei = ei;
ne->reported_metric = metric;
ne->total_metric = metric;
ne->distance = eigrp_calculate_metrics(eigrp, metric);
ne->reported_distance = 0;
ne->adv_router = eigrp->neighbor_self;
- ne->flags = EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG;
+ ne->flags = EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG;
struct prefix dest_addr;
@@ -280,7 +282,7 @@ int eigrp_if_up(struct eigrp_interface *ei)
&dest_addr);
if (pe == NULL) {
- pe = eigrp_prefix_entry_new();
+ pe = eigrp_prefix_descriptor_new();
pe->serno = eigrp->serno;
pe->destination = (struct prefix *)prefix_ipv4_new();
prefix_copy(pe->destination, &dest_addr);
@@ -292,10 +294,10 @@ int eigrp_if_up(struct eigrp_interface *ei)
pe->state = EIGRP_FSM_STATE_PASSIVE;
pe->fdistance = eigrp_calculate_metrics(eigrp, metric);
pe->req_action |= EIGRP_FSM_NEED_UPDATE;
- eigrp_prefix_entry_add(eigrp->topology_table, pe);
+ eigrp_prefix_descriptor_add(eigrp->topology_table, pe);
listnode_add(eigrp->topology_changes_internalIPV4, pe);
- eigrp_nexthop_entry_add(eigrp, pe, ne);
+ eigrp_route_descriptor_add(eigrp, pe, ne);
for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) {
eigrp_update_send(ei2);
@@ -307,7 +309,7 @@ int eigrp_if_up(struct eigrp_interface *ei)
struct eigrp_fsm_action_message msg;
ne->prefix = pe;
- eigrp_nexthop_entry_add(eigrp, pe, ne);
+ eigrp_route_descriptor_add(eigrp, pe, ne);
msg.packet_type = EIGRP_OPC_UPDATE;
msg.eigrp = eigrp;
@@ -416,7 +418,7 @@ uint8_t eigrp_default_iftype(struct interface *ifp)
void eigrp_if_free(struct eigrp_interface *ei, int source)
{
struct prefix dest_addr;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
struct eigrp *eigrp = ei->eigrp;
if (source == INTERFACE_DOWN_BY_VTY) {
@@ -429,7 +431,8 @@ void eigrp_if_free(struct eigrp_interface *ei, int source)
pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table,
&dest_addr);
if (pe)
- eigrp_prefix_entry_delete(eigrp, eigrp->topology_table, pe);
+ eigrp_prefix_descriptor_delete(eigrp, eigrp->topology_table,
+ pe);
eigrp_if_down(ei);
@@ -494,33 +497,3 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp,
return NULL;
}
-
-uint32_t eigrp_bandwidth_to_scaled(uint32_t bandwidth)
-{
- uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth;
-
- temp_bandwidth = temp_bandwidth < EIGRP_MAX_METRIC ? temp_bandwidth
- : EIGRP_MAX_METRIC;
-
- return (uint32_t)temp_bandwidth;
-}
-
-uint32_t eigrp_scaled_to_bandwidth(uint32_t scaled)
-{
- uint64_t temp_scaled = scaled * (256ull * 10000000);
-
- temp_scaled =
- temp_scaled < EIGRP_MAX_METRIC ? temp_scaled : EIGRP_MAX_METRIC;
-
- return (uint32_t)temp_scaled;
-}
-
-uint32_t eigrp_delay_to_scaled(uint32_t delay)
-{
- return delay * 256;
-}
-
-uint32_t eigrp_scaled_to_delay(uint32_t scaled)
-{
- return scaled / 256;
-}
diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h
index 1e66dafde2..68ab5125e3 100644
--- a/eigrpd/eigrp_interface.h
+++ b/eigrpd/eigrp_interface.h
@@ -58,9 +58,4 @@ 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 uint32_t eigrp_bandwidth_to_scaled(uint32_t);
-extern uint32_t eigrp_scaled_to_bandwidth(uint32_t);
-extern uint32_t eigrp_delay_to_scaled(uint32_t);
-extern uint32_t eigrp_scaled_to_delay(uint32_t);
-
#endif /* ZEBRA_EIGRP_INTERFACE_H_ */
diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
index 6c44ce361c..b1a6498cbc 100644
--- a/eigrpd/eigrp_main.c
+++ b/eigrpd/eigrp_main.c
@@ -66,6 +66,8 @@
#include "eigrpd/eigrp_filter.h"
#include "eigrpd/eigrp_errors.h"
#include "eigrpd/eigrp_vrf.h"
+#include "eigrpd/eigrp_cli.h"
+#include "eigrpd/eigrp_yang.h"
//#include "eigrpd/eigrp_routemap.h"
/* eigprd privileges */
diff --git a/eigrpd/eigrp_memory.c b/eigrpd/eigrp_memory.c
index 85b14c28ce..57ca785340 100644
--- a/eigrpd/eigrp_memory.c
+++ b/eigrpd/eigrp_memory.c
@@ -37,6 +37,6 @@ DEFINE_MTYPE(EIGRPD, EIGRP_IPV4_INT_TLV, "EIGRP IPv4 TLV")
DEFINE_MTYPE(EIGRPD, EIGRP_SEQ_TLV, "EIGRP SEQ TLV")
DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_TLV, "EIGRP AUTH TLV")
DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_SHA256_TLV, "EIGRP SHA TLV")
-DEFINE_MTYPE(EIGRPD, EIGRP_PREFIX_ENTRY, "EIGRP Prefix")
-DEFINE_MTYPE(EIGRPD, EIGRP_NEXTHOP_ENTRY, "EIGRP Nexthop Entry")
+DEFINE_MTYPE(EIGRPD, EIGRP_PREFIX_DESCRIPTOR, "EIGRP Prefix")
+DEFINE_MTYPE(EIGRPD, EIGRP_ROUTE_DESCRIPTOR, "EIGRP Nexthop Entry")
DEFINE_MTYPE(EIGRPD, EIGRP_FSM_MSG, "EIGRP FSM Message")
diff --git a/eigrpd/eigrp_memory.h b/eigrpd/eigrp_memory.h
index e4d02c09d4..21ecba2aae 100644
--- a/eigrpd/eigrp_memory.h
+++ b/eigrpd/eigrp_memory.h
@@ -36,8 +36,8 @@ DECLARE_MTYPE(EIGRP_IPV4_INT_TLV)
DECLARE_MTYPE(EIGRP_SEQ_TLV)
DECLARE_MTYPE(EIGRP_AUTH_TLV)
DECLARE_MTYPE(EIGRP_AUTH_SHA256_TLV)
-DECLARE_MTYPE(EIGRP_PREFIX_ENTRY)
-DECLARE_MTYPE(EIGRP_NEXTHOP_ENTRY)
+DECLARE_MTYPE(EIGRP_PREFIX_DESCRIPTOR)
+DECLARE_MTYPE(EIGRP_ROUTE_DESCRIPTOR)
DECLARE_MTYPE(EIGRP_FSM_MSG)
#endif /* _FRR_EIGRP_MEMORY_H */
diff --git a/eigrpd/eigrp_metric.c b/eigrpd/eigrp_metric.c
new file mode 100644
index 0000000000..2b05db71d5
--- /dev/null
+++ b/eigrpd/eigrp_metric.c
@@ -0,0 +1,146 @@
+/*
+ * EIGRP Metric Math Functions.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_types.h"
+#include "eigrpd/eigrp_metric.h"
+
+eigrp_scaled_t eigrp_bandwidth_to_scaled(eigrp_bandwidth_t bandwidth)
+{
+ eigrp_bandwidth_t scaled = EIGRP_BANDWIDTH_MAX;
+
+ if (bandwidth != EIGRP_BANDWIDTH_MAX) {
+ scaled = (EIGRP_CLASSIC_SCALER * EIGRP_BANDWIDTH_SCALER);
+ scaled = scaled / bandwidth;
+
+ scaled = scaled ? scaled : EIGRP_BANDWIDTH_MIN;
+ }
+
+ scaled = (scaled < EIGRP_METRIC_MAX) ? scaled : EIGRP_METRIC_MAX;
+ return (eigrp_scaled_t)scaled;
+}
+
+eigrp_bandwidth_t eigrp_scaled_to_bandwidth(eigrp_scaled_t scaled)
+{
+ eigrp_bandwidth_t bandwidth = EIGRP_BANDWIDTH_MAX;
+
+ if (scaled != EIGRP_CLASSIC_MAX) {
+ bandwidth = (EIGRP_CLASSIC_SCALER * EIGRP_BANDWIDTH_SCALER);
+ bandwidth = scaled * bandwidth;
+ bandwidth = (bandwidth < EIGRP_METRIC_MAX)
+ ? bandwidth
+ : EIGRP_BANDWIDTH_MAX;
+ }
+
+ return bandwidth;
+}
+
+eigrp_scaled_t eigrp_delay_to_scaled(eigrp_delay_t delay)
+{
+ delay = delay ? delay : EIGRP_DELAY_MIN;
+ return delay * EIGRP_CLASSIC_SCALER;
+}
+
+eigrp_delay_t eigrp_scaled_to_delay(eigrp_scaled_t scaled)
+{
+ scaled = scaled / EIGRP_CLASSIC_SCALER;
+ scaled = scaled ? scaled : EIGRP_DELAY_MIN;
+
+ return scaled;
+}
+
+eigrp_metric_t eigrp_calculate_metrics(struct eigrp *eigrp,
+ struct eigrp_metrics metric)
+{
+ eigrp_metric_t composite = 0;
+
+ if (metric.delay == EIGRP_MAX_METRIC)
+ return EIGRP_METRIC_MAX;
+
+ /*
+ * EIGRP Composite =
+ * {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)}
+ */
+
+ if (eigrp->k_values[0])
+ composite += (eigrp->k_values[0] * metric.bandwidth);
+ if (eigrp->k_values[1])
+ composite += ((eigrp->k_values[1] * metric.bandwidth)
+ / (256 - metric.load));
+ if (eigrp->k_values[2])
+ composite += (eigrp->k_values[2] * metric.delay);
+ if (eigrp->k_values[3] && !eigrp->k_values[4])
+ composite *= eigrp->k_values[3];
+ if (!eigrp->k_values[3] && eigrp->k_values[4])
+ composite *= (eigrp->k_values[4] / metric.reliability);
+ if (eigrp->k_values[3] && eigrp->k_values[4])
+ composite *= ((eigrp->k_values[4] / metric.reliability)
+ + eigrp->k_values[3]);
+
+ composite =
+ (composite <= EIGRP_METRIC_MAX) ? composite : EIGRP_METRIC_MAX;
+
+ return composite;
+}
+
+eigrp_metric_t
+eigrp_calculate_total_metrics(struct eigrp *eigrp,
+ struct eigrp_route_descriptor *entry)
+{
+ struct eigrp_interface *ei = entry->ei;
+ eigrp_delay_t temp_delay;
+ eigrp_bandwidth_t bw;
+
+ entry->total_metric = entry->reported_metric;
+ temp_delay = entry->total_metric.delay
+ + eigrp_delay_to_scaled(ei->params.delay);
+
+ entry->total_metric.delay = temp_delay > EIGRP_METRIC_MAX_CLASSIC
+ ? EIGRP_METRIC_MAX_CLASSIC
+ : temp_delay;
+
+ bw = eigrp_bandwidth_to_scaled(ei->params.bandwidth);
+ entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw
+ ? bw
+ : entry->total_metric.bandwidth;
+
+ return eigrp_calculate_metrics(eigrp, entry->total_metric);
+}
+
+bool eigrp_metrics_is_same(struct eigrp_metrics metric1,
+ struct eigrp_metrics metric2)
+{
+ if ((metric1.bandwidth == metric2.bandwidth)
+ && (metric1.delay == metric2.delay)
+ && (metric1.hop_count == metric2.hop_count)
+ && (metric1.load == metric2.load)
+ && (metric1.reliability == metric2.reliability)
+ && (metric1.mtu[0] == metric2.mtu[0])
+ && (metric1.mtu[1] == metric2.mtu[1])
+ && (metric1.mtu[2] == metric2.mtu[2])) {
+ return true;
+ }
+
+ return false; /* if different */
+}
diff --git a/eigrpd/eigrp_metric.h b/eigrpd/eigrp_metric.h
new file mode 100644
index 0000000000..8e9cd66747
--- /dev/null
+++ b/eigrpd/eigrp_metric.h
@@ -0,0 +1,63 @@
+/*
+ * EIGRP Metric Math Functions.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ZEBRA_EIGRP_METRIC_H_
+#define _ZEBRA_EIGRP_METRIC_H_
+
+/* Constants */
+#define EIGRP_BANDWIDTH_MIN 0x1ull /* 1 */
+#define EIGRP_BANDWIDTH_SCALER 10000000ull /* Inversion value */
+#define EIGRP_BANDWIDTH_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */
+
+#define EIGRP_DELAY_MIN 0x1ull /* 1 */
+#define EIGRP_DELAY_PICO 1000000ull
+#define EIGRP_DELAY_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */
+
+#define EIGRP_MAX_LOAD 256
+#define EIGRP_MAX_HOPS 100
+
+#define EIGRP_INACCESSIBLE 0xFFFFFFFFFFFFFFFFull
+
+#define EIGRP_METRIC_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */
+#define EIGRP_METRIC_MAX_CLASSIC 0xffffffff
+#define EIGRP_METRIC_SCALER 65536 /* CLASSIC to WIDE conversion */
+
+#define EIGRP_CLASSIC_MAX 0xffffffff /* 4294967295 */
+#define EIGRP_CLASSIC_SCALER 256 /* IGRP to EIGRP conversion */
+
+
+/* Prototypes */
+extern eigrp_scaled_t eigrp_bandwidth_to_scaled(eigrp_bandwidth_t bw);
+extern eigrp_bandwidth_t eigrp_scaled_to_bandwidth(eigrp_scaled_t scale);
+extern eigrp_scaled_t eigrp_delay_to_scaled(eigrp_delay_t delay);
+extern eigrp_delay_t eigrp_scaled_to_delay(eigrp_scaled_t scale);
+
+extern eigrp_metric_t eigrp_calculate_metrics(struct eigrp *eigrp,
+ struct eigrp_metrics metric);
+extern eigrp_metric_t
+eigrp_calculate_total_metrics(struct eigrp *eigrp,
+ struct eigrp_route_descriptor *rd);
+extern bool eigrp_metrics_is_same(struct eigrp_metrics m1,
+ struct eigrp_metrics m2);
+
+#endif /* _ZEBRA_EIGRP_METRIC_H_ */
diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c
index 2d5bb0a7d1..1da2f7a108 100644
--- a/eigrpd/eigrp_neighbor.c
+++ b/eigrpd/eigrp_neighbor.c
@@ -343,7 +343,7 @@ void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty)
eigrp_nbr_delete(nbr);
}
-int eigrp_nbr_split_horizon_check(struct eigrp_nexthop_entry *ne,
+int eigrp_nbr_split_horizon_check(struct eigrp_route_descriptor *ne,
struct eigrp_interface *ei)
{
if (ne->distance == EIGRP_MAX_METRIC)
diff --git a/eigrpd/eigrp_neighbor.h b/eigrpd/eigrp_neighbor.h
index 1c308fa981..80ab1eded5 100644
--- a/eigrpd/eigrp_neighbor.h
+++ b/eigrpd/eigrp_neighbor.h
@@ -54,6 +54,6 @@ extern struct eigrp_neighbor *
eigrp_nbr_lookup_by_addr_process(struct eigrp *eigrp, struct in_addr addr);
extern void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty);
-extern int eigrp_nbr_split_horizon_check(struct eigrp_nexthop_entry *ne,
+extern int eigrp_nbr_split_horizon_check(struct eigrp_route_descriptor *ne,
struct eigrp_interface *ei);
#endif /* _ZEBRA_EIGRP_NEIGHBOR_H */
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c
index 51b4998959..69dcc20253 100644
--- a/eigrpd/eigrp_network.c
+++ b/eigrpd/eigrp_network.c
@@ -346,76 +346,6 @@ int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p)
return 1;
}
-uint32_t eigrp_calculate_metrics(struct eigrp *eigrp,
- struct eigrp_metrics metric)
-{
- uint64_t temp_metric;
- temp_metric = 0;
-
- if (metric.delay == EIGRP_MAX_METRIC)
- return EIGRP_MAX_METRIC;
-
- // EIGRP Metric =
- // {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)}
-
- if (eigrp->k_values[0])
- temp_metric += (eigrp->k_values[0] * metric.bandwidth);
- if (eigrp->k_values[1])
- temp_metric += ((eigrp->k_values[1] * metric.bandwidth)
- / (256 - metric.load));
- if (eigrp->k_values[2])
- temp_metric += (eigrp->k_values[2] * metric.delay);
- if (eigrp->k_values[3] && !eigrp->k_values[4])
- temp_metric *= eigrp->k_values[3];
- if (!eigrp->k_values[3] && eigrp->k_values[4])
- temp_metric *= (eigrp->k_values[4] / metric.reliability);
- if (eigrp->k_values[3] && eigrp->k_values[4])
- temp_metric *= ((eigrp->k_values[4] / metric.reliability)
- + eigrp->k_values[3]);
-
- if (temp_metric <= EIGRP_MAX_METRIC)
- return (uint32_t)temp_metric;
- else
- return EIGRP_MAX_METRIC;
-}
-
-uint32_t eigrp_calculate_total_metrics(struct eigrp *eigrp,
- struct eigrp_nexthop_entry *entry)
-{
- struct eigrp_interface *ei = entry->ei;
-
- entry->total_metric = entry->reported_metric;
- uint64_t temp_delay =
- (uint64_t)entry->total_metric.delay
- + (uint64_t)eigrp_delay_to_scaled(ei->params.delay);
- entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC
- ? EIGRP_MAX_METRIC
- : (uint32_t)temp_delay;
-
- uint32_t bw = eigrp_bandwidth_to_scaled(ei->params.bandwidth);
- entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw
- ? bw
- : entry->total_metric.bandwidth;
-
- return eigrp_calculate_metrics(eigrp, entry->total_metric);
-}
-
-uint8_t eigrp_metrics_is_same(struct eigrp_metrics metric1,
- struct eigrp_metrics metric2)
-{
- if ((metric1.bandwidth == metric2.bandwidth)
- && (metric1.delay == metric2.delay)
- && (metric1.hop_count == metric2.hop_count)
- && (metric1.load == metric2.load)
- && (metric1.reliability == metric2.reliability)
- && (metric1.mtu[0] == metric2.mtu[0])
- && (metric1.mtu[1] == metric2.mtu[1])
- && (metric1.mtu[2] == metric2.mtu[2]))
- return 1;
-
- return 0; // if different
-}
-
void eigrp_external_routes_refresh(struct eigrp *eigrp, int type)
{
}
diff --git a/eigrpd/eigrp_network.h b/eigrpd/eigrp_network.h
index 7839fc946b..eeb32ba356 100644
--- a/eigrpd/eigrp_network.h
+++ b/eigrpd/eigrp_network.h
@@ -43,11 +43,6 @@ extern int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p,
unsigned int ifindex);
extern void eigrp_adjust_sndbuflen(struct eigrp *, unsigned int);
-extern uint32_t eigrp_calculate_metrics(struct eigrp *, struct eigrp_metrics);
-extern uint32_t eigrp_calculate_total_metrics(struct eigrp *,
- struct eigrp_nexthop_entry *);
-extern uint8_t eigrp_metrics_is_same(struct eigrp_metrics,
- struct eigrp_metrics);
extern void eigrp_external_routes_refresh(struct eigrp *, int);
#endif /* EIGRP_NETWORK_H_ */
diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c
index 5b87f72640..482667f633 100644
--- a/eigrpd/eigrp_northbound.c
+++ b/eigrpd/eigrp_northbound.c
@@ -34,6 +34,7 @@
#include "eigrp_interface.h"
#include "eigrp_network.h"
#include "eigrp_zebra.h"
+#include "eigrp_cli.h"
/* Helper functions. */
static void redistribute_get_metrics(const struct lyd_node *dnode,
diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c
index f5f6ab5dff..252cd647a2 100644
--- a/eigrpd/eigrp_packet.c
+++ b/eigrpd/eigrp_packet.c
@@ -1144,7 +1144,7 @@ struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *s)
}
uint16_t eigrp_add_internalTLV_to_stream(struct stream *s,
- struct eigrp_prefix_entry *pe)
+ struct eigrp_prefix_descriptor *pe)
{
uint16_t length;
diff --git a/eigrpd/eigrp_packet.h b/eigrpd/eigrp_packet.h
index f354615fdb..cb69bc26b2 100644
--- a/eigrpd/eigrp_packet.h
+++ b/eigrpd/eigrp_packet.h
@@ -36,48 +36,51 @@
extern int eigrp_read(struct thread *);
extern int eigrp_write(struct thread *);
-extern struct eigrp_packet *eigrp_packet_new(size_t, struct eigrp_neighbor *);
-extern struct eigrp_packet *eigrp_packet_duplicate(struct eigrp_packet *,
- struct eigrp_neighbor *);
-extern void eigrp_packet_free(struct eigrp_packet *);
-extern void eigrp_packet_delete(struct eigrp_interface *);
-extern void eigrp_packet_header_init(int, struct eigrp *, struct stream *,
- uint32_t, uint32_t, uint32_t);
-extern void eigrp_packet_checksum(struct eigrp_interface *, struct stream *,
- uint16_t);
+extern struct eigrp_packet *eigrp_packet_new(size_t size,
+ struct eigrp_neighbor *nbr);
+extern struct eigrp_packet *eigrp_packet_duplicate(struct eigrp_packet *old,
+ struct eigrp_neighbor *nbr);
+extern void eigrp_packet_free(struct eigrp_packet *ep);
+extern void eigrp_packet_delete(struct eigrp_interface *ei);
+extern void eigrp_packet_header_init(int type, struct eigrp *eigrp,
+ struct stream *s, uint32_t flags,
+ uint32_t sequence, uint32_t ack);
+extern void eigrp_packet_checksum(struct eigrp_interface *ei, struct stream *s,
+ uint16_t length);
extern struct eigrp_fifo *eigrp_fifo_new(void);
-extern struct eigrp_packet *eigrp_fifo_next(struct eigrp_fifo *);
-extern struct eigrp_packet *eigrp_fifo_pop(struct eigrp_fifo *);
-extern void eigrp_fifo_push(struct eigrp_fifo *, struct eigrp_packet *);
-extern void eigrp_fifo_free(struct eigrp_fifo *);
-extern void eigrp_fifo_reset(struct eigrp_fifo *);
-
-extern void eigrp_send_packet_reliably(struct eigrp_neighbor *);
-
-extern struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *);
-extern uint16_t eigrp_add_internalTLV_to_stream(struct stream *,
- struct eigrp_prefix_entry *);
-extern uint16_t eigrp_add_authTLV_MD5_to_stream(struct stream *,
- struct eigrp_interface *);
-extern uint16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *,
- struct eigrp_interface *);
-
-extern int eigrp_unack_packet_retrans(struct thread *);
-extern int eigrp_unack_multicast_packet_retrans(struct thread *);
+extern struct eigrp_packet *eigrp_fifo_next(struct eigrp_fifo *fifo);
+extern struct eigrp_packet *eigrp_fifo_pop(struct eigrp_fifo *fifo);
+extern void eigrp_fifo_push(struct eigrp_fifo *fifo, struct eigrp_packet *ep);
+extern void eigrp_fifo_free(struct eigrp_fifo *fifo);
+extern void eigrp_fifo_reset(struct eigrp_fifo *fifo);
+
+extern void eigrp_send_packet_reliably(struct eigrp_neighbor *nbr);
+
+extern struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *s);
+extern uint16_t
+eigrp_add_internalTLV_to_stream(struct stream *s,
+ struct eigrp_prefix_descriptor *pe);
+extern uint16_t eigrp_add_authTLV_MD5_to_stream(struct stream *s,
+ struct eigrp_interface *ei);
+extern uint16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *s,
+ struct eigrp_interface *ei);
+
+extern int eigrp_unack_packet_retrans(struct thread *thread);
+extern int eigrp_unack_multicast_packet_retrans(struct thread *thread);
/*
* untill there is reason to have their own header, these externs are found in
* eigrp_hello.c
*/
extern void eigrp_sw_version_initialize(void);
-extern void eigrp_hello_send(struct eigrp_interface *, uint8_t,
- struct in_addr *);
-extern void eigrp_hello_send_ack(struct eigrp_neighbor *);
-extern void eigrp_hello_receive(struct eigrp *, struct ip *,
- struct eigrp_header *, struct stream *,
- struct eigrp_interface *, int);
-extern int eigrp_hello_timer(struct thread *);
+extern void eigrp_hello_send(struct eigrp_interface *ei, uint8_t flags,
+ struct in_addr *nbr_addr);
+extern void eigrp_hello_send_ack(struct eigrp_neighbor *nbr);
+extern void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
+ struct eigrp_header *eigrph, struct stream *s,
+ struct eigrp_interface *ei, int size);
+extern int eigrp_hello_timer(struct thread *thread);
/*
* These externs are found in eigrp_update.c
@@ -85,76 +88,83 @@ extern int eigrp_hello_timer(struct thread *);
extern bool eigrp_update_prefix_apply(struct eigrp *eigrp,
struct eigrp_interface *ei, int in,
struct prefix *prefix);
-extern void eigrp_update_send(struct eigrp_interface *);
-extern void eigrp_update_receive(struct eigrp *, struct ip *,
- struct eigrp_header *, struct stream *,
- struct eigrp_interface *, int);
-extern void eigrp_update_send_all(struct eigrp *, struct eigrp_interface *);
-extern void eigrp_update_send_init(struct eigrp_neighbor *);
-extern void eigrp_update_send_EOT(struct eigrp_neighbor *);
-extern int eigrp_update_send_GR_thread(struct thread *);
-extern void eigrp_update_send_GR(struct eigrp_neighbor *, enum GR_type,
- struct vty *);
-extern void eigrp_update_send_interface_GR(struct eigrp_interface *,
- enum GR_type, struct vty *);
-extern void eigrp_update_send_process_GR(struct eigrp *, enum GR_type,
- struct vty *);
+extern void eigrp_update_send(struct eigrp_interface *ei);
+extern void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
+ struct eigrp_header *eigrph, struct stream *s,
+ struct eigrp_interface *ei, int size);
+extern void eigrp_update_send_all(struct eigrp *eigrp,
+ struct eigrp_interface *exception);
+extern void eigrp_update_send_init(struct eigrp_neighbor *nbr);
+extern void eigrp_update_send_EOT(struct eigrp_neighbor *nbr);
+extern int eigrp_update_send_GR_thread(struct thread *thread);
+extern void eigrp_update_send_GR(struct eigrp_neighbor *nbr,
+ enum GR_type gr_type, struct vty *vty);
+extern void eigrp_update_send_interface_GR(struct eigrp_interface *ei,
+ enum GR_type gr_type,
+ struct vty *vty);
+extern void eigrp_update_send_process_GR(struct eigrp *eigrp,
+ enum GR_type gr_type, struct vty *vty);
/*
* These externs are found in eigrp_query.c
*/
-extern void eigrp_send_query(struct eigrp_interface *);
-extern void eigrp_query_receive(struct eigrp *, struct ip *,
- struct eigrp_header *, struct stream *,
- struct eigrp_interface *, int);
-extern uint32_t eigrp_query_send_all(struct eigrp *);
+extern void eigrp_send_query(struct eigrp_interface *ei);
+extern void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph,
+ struct eigrp_header *eigrph, struct stream *s,
+ struct eigrp_interface *ei, int size);
+extern uint32_t eigrp_query_send_all(struct eigrp *eigrp);
/*
* These externs are found in eigrp_reply.c
*/
-extern void eigrp_send_reply(struct eigrp_neighbor *,
- struct eigrp_prefix_entry *);
-extern void eigrp_reply_receive(struct eigrp *, struct ip *,
- struct eigrp_header *, struct stream *,
- struct eigrp_interface *, int);
+extern void eigrp_send_reply(struct eigrp_neighbor *nbr,
+ struct eigrp_prefix_descriptor *pe);
+extern void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
+ struct eigrp_header *eigrph, struct stream *s,
+ struct eigrp_interface *ei, int size);
/*
* These externs are found in eigrp_siaquery.c
*/
-extern void eigrp_send_siaquery(struct eigrp_neighbor *,
- struct eigrp_prefix_entry *);
-extern void eigrp_siaquery_receive(struct eigrp *, struct ip *,
- struct eigrp_header *, struct stream *,
- struct eigrp_interface *, int);
+extern void eigrp_send_siaquery(struct eigrp_neighbor *nbr,
+ struct eigrp_prefix_descriptor *pe);
+extern void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph,
+ struct eigrp_header *eigrph,
+ struct stream *s, struct eigrp_interface *ei,
+ int size);
/*
* These externs are found in eigrp_siareply.c
*/
-extern void eigrp_send_siareply(struct eigrp_neighbor *,
- struct eigrp_prefix_entry *);
-extern void eigrp_siareply_receive(struct eigrp *, struct ip *,
- struct eigrp_header *, struct stream *,
- struct eigrp_interface *, int);
+extern void eigrp_send_siareply(struct eigrp_neighbor *nbr,
+ struct eigrp_prefix_descriptor *pe);
+extern void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph,
+ struct eigrp_header *eigrph,
+ struct stream *s, struct eigrp_interface *ei,
+ int size);
extern struct TLV_MD5_Authentication_Type *eigrp_authTLV_MD5_new(void);
-extern void eigrp_authTLV_MD5_free(struct TLV_MD5_Authentication_Type *);
+extern void eigrp_authTLV_MD5_free(struct TLV_MD5_Authentication_Type *authTLV);
extern struct TLV_SHA256_Authentication_Type *eigrp_authTLV_SHA256_new(void);
-extern void eigrp_authTLV_SHA256_free(struct TLV_SHA256_Authentication_Type *);
-
-extern int eigrp_make_md5_digest(struct eigrp_interface *, struct stream *,
- uint8_t);
-extern int eigrp_check_md5_digest(struct stream *,
- struct TLV_MD5_Authentication_Type *,
- struct eigrp_neighbor *, uint8_t);
-extern int eigrp_make_sha256_digest(struct eigrp_interface *, struct stream *,
- uint8_t);
-extern int eigrp_check_sha256_digest(struct stream *,
- struct TLV_SHA256_Authentication_Type *,
- struct eigrp_neighbor *, uint8_t);
-
-
-extern void eigrp_IPv4_InternalTLV_free(struct TLV_IPv4_Internal_type *);
+extern void
+eigrp_authTLV_SHA256_free(struct TLV_SHA256_Authentication_Type *authTLV);
+
+extern int eigrp_make_md5_digest(struct eigrp_interface *ei, struct stream *s,
+ uint8_t flags);
+extern int eigrp_check_md5_digest(struct stream *s,
+ struct TLV_MD5_Authentication_Type *authTLV,
+ struct eigrp_neighbor *nbr, uint8_t flags);
+extern int eigrp_make_sha256_digest(struct eigrp_interface *ei,
+ struct stream *s, uint8_t flags);
+extern int
+eigrp_check_sha256_digest(struct stream *s,
+ struct TLV_SHA256_Authentication_Type *authTLV,
+ struct eigrp_neighbor *nbr, uint8_t flags);
+
+
+extern void
+eigrp_IPv4_InternalTLV_free(struct TLV_IPv4_Internal_type *IPv4_InternalTLV);
extern struct TLV_Sequence_Type *eigrp_SequenceTLV_new(void);
diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c
index 84dcf5e2d5..0ab7b59dbb 100644
--- a/eigrpd/eigrp_query.c
+++ b/eigrpd/eigrp_query.c
@@ -58,7 +58,7 @@ uint32_t eigrp_query_send_all(struct eigrp *eigrp)
{
struct eigrp_interface *iface;
struct listnode *node, *node2, *nnode2;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
uint32_t counter;
if (eigrp == NULL) {
@@ -118,7 +118,7 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph,
dest_addr.family = AF_INET;
dest_addr.u.prefix4 = tlv->destination;
dest_addr.prefixlen = tlv->prefix_length;
- struct eigrp_prefix_entry *dest =
+ struct eigrp_prefix_descriptor *dest =
eigrp_topology_table_lookup_ipv4(
eigrp->topology_table, &dest_addr);
@@ -126,9 +126,9 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph,
* know)*/
if (dest != NULL) {
struct eigrp_fsm_action_message msg;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(dest->entries,
- nbr);
+ struct eigrp_route_descriptor *entry =
+ eigrp_route_descriptor_lookup(
+ dest->entries, nbr);
msg.packet_type = EIGRP_OPC_QUERY;
msg.eigrp = eigrp;
msg.data_type = EIGRP_INT;
@@ -164,7 +164,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
uint16_t length = EIGRP_HEADER_LEN;
struct listnode *node, *nnode, *node2, *nnode2;
struct eigrp_neighbor *nbr;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
bool has_tlv = false;
bool new_packet = true;
uint16_t eigrp_mtu = EIGRP_PACKET_MTU(ei->ifp->mtu);
diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c
index 26bb27d7ac..d16482173c 100644
--- a/eigrpd/eigrp_reply.c
+++ b/eigrpd/eigrp_reply.c
@@ -61,20 +61,21 @@
#include "eigrpd/eigrp_memory.h"
#include "eigrpd/eigrp_errors.h"
-void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
+void eigrp_send_reply(struct eigrp_neighbor *nbr,
+ struct eigrp_prefix_descriptor *pe)
{
struct eigrp_packet *ep;
uint16_t length = EIGRP_HEADER_LEN;
struct eigrp_interface *ei = nbr->ei;
struct eigrp *eigrp = ei->eigrp;
- struct eigrp_prefix_entry *pe2;
+ struct eigrp_prefix_descriptor *pe2;
// TODO: Work in progress
/* Filtering */
/* get list from eigrp process */
- pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY,
- sizeof(struct eigrp_prefix_entry));
- memcpy(pe2, pe, sizeof(struct eigrp_prefix_entry));
+ pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_DESCRIPTOR,
+ 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)) {
@@ -122,7 +123,7 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
eigrp_send_packet_reliably(nbr);
}
- XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe2);
+ XFREE(MTYPE_EIGRP_PREFIX_DESCRIPTOR, pe2);
}
/*EIGRP REPLY read function*/
@@ -161,7 +162,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
dest_addr.family = AF_INET;
dest_addr.u.prefix4 = tlv->destination;
dest_addr.prefixlen = tlv->prefix_length;
- struct eigrp_prefix_entry *dest =
+ struct eigrp_prefix_descriptor *dest =
eigrp_topology_table_lookup_ipv4(eigrp->topology_table,
&dest_addr);
/*
@@ -177,8 +178,8 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
}
struct eigrp_fsm_action_message msg;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(dest->entries, nbr);
+ struct eigrp_route_descriptor *entry =
+ eigrp_route_descriptor_lookup(dest->entries, nbr);
if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_IN,
&dest_addr)) {
diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c
index e15f777954..5183e645e5 100644
--- a/eigrpd/eigrp_routemap.c
+++ b/eigrpd/eigrp_routemap.c
@@ -265,8 +265,8 @@ route_match_metric(void *rule, struct prefix *prefix, route_map_object_t type,
// uint32_t *metric;
// uint32_t check;
// struct rip_info *rinfo;
- // struct eigrp_nexthop_entry *te;
- // struct eigrp_prefix_entry *pe;
+ // struct eigrp_route_descriptor *te;
+ // struct eigrp_prefix_descriptor *pe;
// struct listnode *node, *node2, *nnode, *nnode2;
// struct eigrp *e;
//
diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c
index ff38325465..027700fe11 100644
--- a/eigrpd/eigrp_siaquery.c
+++ b/eigrpd/eigrp_siaquery.c
@@ -87,7 +87,7 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph,
dest_addr.family = AFI_IP;
dest_addr.u.prefix4 = tlv->destination;
dest_addr.prefixlen = tlv->prefix_length;
- struct eigrp_prefix_entry *dest =
+ struct eigrp_prefix_descriptor *dest =
eigrp_topology_table_lookup_ipv4(
eigrp->topology_table, &dest_addr);
@@ -95,9 +95,9 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph,
* know)*/
if (dest != NULL) {
struct eigrp_fsm_action_message msg;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(dest->entries,
- nbr);
+ struct eigrp_route_descriptor *entry =
+ eigrp_route_descriptor_lookup(
+ dest->entries, nbr);
msg.packet_type = EIGRP_OPC_SIAQUERY;
msg.eigrp = eigrp;
msg.data_type = EIGRP_INT;
@@ -114,7 +114,7 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph,
}
void eigrp_send_siaquery(struct eigrp_neighbor *nbr,
- struct eigrp_prefix_entry *pe)
+ struct eigrp_prefix_descriptor *pe)
{
struct eigrp_packet *ep;
uint16_t length = EIGRP_HEADER_LEN;
diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c
index d3dd123f90..590b224d68 100644
--- a/eigrpd/eigrp_siareply.c
+++ b/eigrpd/eigrp_siareply.c
@@ -86,7 +86,7 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph,
dest_addr.family = AFI_IP;
dest_addr.u.prefix4 = tlv->destination;
dest_addr.prefixlen = tlv->prefix_length;
- struct eigrp_prefix_entry *dest =
+ struct eigrp_prefix_descriptor *dest =
eigrp_topology_table_lookup_ipv4(
eigrp->topology_table, &dest_addr);
@@ -94,9 +94,9 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph,
* know)*/
if (dest != NULL) {
struct eigrp_fsm_action_message msg;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(dest->entries,
- nbr);
+ struct eigrp_route_descriptor *entry =
+ eigrp_route_descriptor_lookup(
+ dest->entries, nbr);
msg.packet_type = EIGRP_OPC_SIAQUERY;
msg.eigrp = eigrp;
msg.data_type = EIGRP_INT;
@@ -113,7 +113,7 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph,
}
void eigrp_send_siareply(struct eigrp_neighbor *nbr,
- struct eigrp_prefix_entry *pe)
+ struct eigrp_prefix_descriptor *pe)
{
struct eigrp_packet *ep;
uint16_t length = EIGRP_HEADER_LEN;
diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h
index 82bddaaae3..cddab57dd5 100644
--- a/eigrpd/eigrp_structs.h
+++ b/eigrpd/eigrp_structs.h
@@ -37,26 +37,6 @@
#include "eigrpd/eigrp_const.h"
#include "eigrpd/eigrp_macros.h"
-/* EIGRP master for system wide configuration and variables. */
-struct eigrp_master {
- /* EIGRP instance. */
- struct list *eigrp;
-
- /* EIGRP thread master. */
- struct thread_master *master;
-
- /* Zebra interface list. */
- struct list *iflist;
-
- /* EIGRP start time. */
- time_t start_time;
-
- /* Various EIGRP global configuration. */
- uint8_t options;
-
-#define EIGRP_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
-};
-
struct eigrp_metrics {
uint32_t delay;
uint32_t bandwidth;
@@ -68,6 +48,16 @@ struct eigrp_metrics {
uint8_t flags;
};
+struct eigrp_extdata {
+ uint32_t orig;
+ uint32_t as;
+ uint32_t tag;
+ uint32_t metric;
+ uint16_t reserved;
+ uint8_t protocol;
+ uint8_t flags;
+};
+
struct eigrp {
vrf_id_t vrf_id;
@@ -450,7 +440,7 @@ enum GR_type { EIGRP_GR_MANUAL, EIGRP_GR_FILTER };
//---------------------------------------------------------------------------------------------------------------------------------------------
/* EIGRP Topology table node structure */
-struct eigrp_prefix_entry {
+struct eigrp_prefix_descriptor {
struct list *entries, *rij;
uint32_t fdistance; // FD
uint32_t rdistance; // RD
@@ -473,8 +463,14 @@ struct eigrp_prefix_entry {
};
/* EIGRP Topology table record structure */
-struct eigrp_nexthop_entry {
- struct eigrp_prefix_entry *prefix;
+struct eigrp_route_descriptor {
+ uint16_t type;
+ uint16_t afi;
+
+ struct eigrp_prefix_descriptor *prefix;
+ struct eigrp_neighbor *adv_router;
+ struct in_addr nexthop;
+
uint32_t reported_distance; // distance reported by neighbor
uint32_t distance; // sum of reported distance and link cost to
// advertised neighbor
@@ -482,7 +478,9 @@ struct eigrp_nexthop_entry {
struct eigrp_metrics reported_metric;
struct eigrp_metrics total_metric;
- struct eigrp_neighbor *adv_router; // ip address of advertising neighbor
+ struct eigrp_metrics metric;
+ struct eigrp_extdata extdata;
+
uint8_t flags; // used for marking successor and FS
struct eigrp_interface *ei; // pointer for case of connected entry
@@ -501,8 +499,8 @@ struct eigrp_fsm_action_message {
uint8_t packet_type; // UPDATE, QUERY, SIAQUERY, SIAREPLY
struct eigrp *eigrp; // which thread sent mesg
struct eigrp_neighbor *adv_router; // advertising neighbor
- struct eigrp_nexthop_entry *entry;
- struct eigrp_prefix_entry *prefix;
+ struct eigrp_route_descriptor *entry;
+ struct eigrp_prefix_descriptor *prefix;
msg_data_t data_type; // internal or external tlv type
struct eigrp_metrics metrics;
enum metric_change change;
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
index 2dbee16694..1b7e9fc15b 100644
--- a/eigrpd/eigrp_topology.c
+++ b/eigrpd/eigrp_topology.c
@@ -39,6 +39,7 @@
#include "vty.h"
#include "lib_errors.h"
+#include "eigrpd/eigrp_types.h"
#include "eigrpd/eigrp_structs.h"
#include "eigrpd/eigrpd.h"
#include "eigrpd/eigrp_interface.h"
@@ -51,9 +52,10 @@
#include "eigrpd/eigrp_topology.h"
#include "eigrpd/eigrp_fsm.h"
#include "eigrpd/eigrp_memory.h"
+#include "eigrpd/eigrp_metric.h"
-static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *,
- struct eigrp_nexthop_entry *);
+static int eigrp_route_descriptor_cmp(struct eigrp_route_descriptor *rd1,
+ struct eigrp_route_descriptor *rd2);
/*
* Returns linkedlist used as topology table
@@ -70,14 +72,14 @@ struct route_table *eigrp_topology_new(void)
* Returns new created toplogy node
* cmp - assigned function for comparing topology entry
*/
-struct eigrp_prefix_entry *eigrp_prefix_entry_new(void)
+struct eigrp_prefix_descriptor *eigrp_prefix_descriptor_new(void)
{
- struct eigrp_prefix_entry *new;
- new = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY,
- sizeof(struct eigrp_prefix_entry));
+ struct eigrp_prefix_descriptor *new;
+ new = XCALLOC(MTYPE_EIGRP_PREFIX_DESCRIPTOR,
+ sizeof(struct eigrp_prefix_descriptor));
new->entries = list_new();
new->rij = list_new();
- new->entries->cmp = (int (*)(void *, void *))eigrp_nexthop_entry_cmp;
+ new->entries->cmp = (int (*)(void *, void *))eigrp_route_descriptor_cmp;
new->distance = new->fdistance = new->rdistance = EIGRP_MAX_METRIC;
new->destination = NULL;
@@ -87,8 +89,8 @@ struct eigrp_prefix_entry *eigrp_prefix_entry_new(void)
/*
* Topology entry comparison
*/
-static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *entry1,
- struct eigrp_nexthop_entry *entry2)
+static int eigrp_route_descriptor_cmp(struct eigrp_route_descriptor *entry1,
+ struct eigrp_route_descriptor *entry2)
{
if (entry1->distance < entry2->distance)
return -1;
@@ -102,12 +104,12 @@ static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *entry1,
* Returns new topology entry
*/
-struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void)
+struct eigrp_route_descriptor *eigrp_route_descriptor_new(void)
{
- struct eigrp_nexthop_entry *new;
+ struct eigrp_route_descriptor *new;
- new = XCALLOC(MTYPE_EIGRP_NEXTHOP_ENTRY,
- sizeof(struct eigrp_nexthop_entry));
+ new = XCALLOC(MTYPE_EIGRP_ROUTE_DESCRIPTOR,
+ sizeof(struct eigrp_route_descriptor));
new->reported_distance = EIGRP_MAX_METRIC;
new->distance = EIGRP_MAX_METRIC;
@@ -126,8 +128,8 @@ void eigrp_topology_free(struct eigrp *eigrp, struct route_table *table)
/*
* Adding topology node to topology table
*/
-void eigrp_prefix_entry_add(struct route_table *topology,
- struct eigrp_prefix_entry *pe)
+void eigrp_prefix_descriptor_add(struct route_table *topology,
+ struct eigrp_prefix_descriptor *pe)
{
struct route_node *rn;
@@ -146,9 +148,9 @@ void eigrp_prefix_entry_add(struct route_table *topology,
/*
* Adding topology entry to topology node
*/
-void eigrp_nexthop_entry_add(struct eigrp *eigrp,
- struct eigrp_prefix_entry *node,
- struct eigrp_nexthop_entry *entry)
+void eigrp_route_descriptor_add(struct eigrp *eigrp,
+ struct eigrp_prefix_descriptor *node,
+ struct eigrp_route_descriptor *entry)
{
struct list *l = list_new();
@@ -168,10 +170,11 @@ void eigrp_nexthop_entry_add(struct eigrp *eigrp,
/*
* Deleting topology node from topology table
*/
-void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table,
- struct eigrp_prefix_entry *pe)
+void eigrp_prefix_descriptor_delete(struct eigrp *eigrp,
+ struct route_table *table,
+ struct eigrp_prefix_descriptor *pe)
{
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_route_descriptor *ne;
struct listnode *node, *nnode;
struct route_node *rn;
@@ -189,7 +192,7 @@ void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table,
listnode_delete(eigrp->topology_changes_internalIPV4, pe);
for (ALL_LIST_ELEMENTS(pe->entries, node, nnode, ne))
- eigrp_nexthop_entry_delete(eigrp, pe, ne);
+ eigrp_route_descriptor_delete(eigrp, pe, ne);
list_delete(&pe->entries);
list_delete(&pe->rij);
eigrp_zebra_route_delete(eigrp, pe->destination);
@@ -198,20 +201,20 @@ void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table,
rn->info = NULL;
route_unlock_node(rn); // Lookup above
route_unlock_node(rn); // Initial creation
- XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe);
+ XFREE(MTYPE_EIGRP_PREFIX_DESCRIPTOR, pe);
}
/*
* Deleting topology entry from topology node
*/
-void eigrp_nexthop_entry_delete(struct eigrp *eigrp,
- struct eigrp_prefix_entry *node,
- struct eigrp_nexthop_entry *entry)
+void eigrp_route_descriptor_delete(struct eigrp *eigrp,
+ struct eigrp_prefix_descriptor *node,
+ struct eigrp_route_descriptor *entry)
{
if (listnode_lookup(node->entries, entry) != NULL) {
listnode_delete(node->entries, entry);
eigrp_zebra_route_delete(eigrp, node->destination);
- XFREE(MTYPE_EIGRP_NEXTHOP_ENTRY, entry);
+ XFREE(MTYPE_EIGRP_ROUTE_DESCRIPTOR, entry);
}
}
@@ -222,7 +225,7 @@ void eigrp_topology_delete_all(struct eigrp *eigrp,
struct route_table *topology)
{
struct route_node *rn;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
for (rn = route_top(topology); rn; rn = route_next(rn)) {
pe = rn->info;
@@ -230,15 +233,15 @@ void eigrp_topology_delete_all(struct eigrp *eigrp,
if (!pe)
continue;
- eigrp_prefix_entry_delete(eigrp, topology, pe);
+ eigrp_prefix_descriptor_delete(eigrp, topology, pe);
}
}
-struct eigrp_prefix_entry *
+struct eigrp_prefix_descriptor *
eigrp_topology_table_lookup_ipv4(struct route_table *table,
struct prefix *address)
{
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
struct route_node *rn;
rn = route_node_lookup(table, address);
@@ -259,14 +262,15 @@ eigrp_topology_table_lookup_ipv4(struct route_table *table,
* That way we can clean up all the list_new and list_delete's
* that we are doing. DBS
*/
-struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node)
+struct list *
+eigrp_topology_get_successor(struct eigrp_prefix_descriptor *table_node)
{
struct list *successors = list_new();
- struct eigrp_nexthop_entry *data;
+ struct eigrp_route_descriptor *data;
struct listnode *node1, *node2;
for (ALL_LIST_ELEMENTS(table_node->entries, node1, node2, data)) {
- if (data->flags & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) {
+ if (data->flags & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG) {
listnode_add(successors, data);
}
}
@@ -283,7 +287,7 @@ struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node)
}
struct list *
-eigrp_topology_get_successor_max(struct eigrp_prefix_entry *table_node,
+eigrp_topology_get_successor_max(struct eigrp_prefix_descriptor *table_node,
unsigned int maxpaths)
{
struct list *successors = eigrp_topology_get_successor(table_node);
@@ -300,10 +304,10 @@ eigrp_topology_get_successor_max(struct eigrp_prefix_entry *table_node,
return successors;
}
-struct eigrp_nexthop_entry *
-eigrp_prefix_entry_lookup(struct list *entries, struct eigrp_neighbor *nbr)
+struct eigrp_route_descriptor *
+eigrp_route_descriptor_lookup(struct list *entries, struct eigrp_neighbor *nbr)
{
- struct eigrp_nexthop_entry *data;
+ struct eigrp_route_descriptor *data;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS(entries, node, nnode, data)) {
if (data->adv_router == nbr) {
@@ -319,8 +323,8 @@ struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
struct eigrp_neighbor *nbr)
{
struct listnode *node2, *node22;
- struct eigrp_nexthop_entry *entry;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_route_descriptor *entry;
+ struct eigrp_prefix_descriptor *pe;
struct route_node *rn;
/* create new empty list for prefixes storage */
@@ -348,8 +352,8 @@ enum metric_change
eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg)
{
struct eigrp *eigrp = msg->eigrp;
- struct eigrp_prefix_entry *prefix = msg->prefix;
- struct eigrp_nexthop_entry *entry = msg->entry;
+ struct eigrp_prefix_descriptor *prefix = msg->prefix;
+ struct eigrp_route_descriptor *entry = msg->entry;
enum metric_change change = METRIC_SAME;
uint32_t new_reported_distance;
@@ -413,7 +417,7 @@ distance_done:
void eigrp_topology_update_all_node_flags(struct eigrp *eigrp)
{
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
struct route_node *rn;
if (!eigrp)
@@ -430,10 +434,10 @@ void eigrp_topology_update_all_node_flags(struct eigrp *eigrp)
}
void eigrp_topology_update_node_flags(struct eigrp *eigrp,
- struct eigrp_prefix_entry *dest)
+ struct eigrp_prefix_descriptor *dest)
{
struct listnode *node;
- struct eigrp_nexthop_entry *entry;
+ struct eigrp_route_descriptor *entry;
for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry)) {
if (entry->reported_distance < dest->fdistance) {
@@ -444,29 +448,29 @@ void eigrp_topology_update_node_flags(struct eigrp *eigrp,
&& entry->distance != EIGRP_MAX_METRIC) {
// is successor
entry->flags |=
- EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG;
+ EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG;
entry->flags &=
- ~EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG;
+ ~EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG;
} else {
// is feasible successor only
entry->flags |=
- EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG;
+ EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG;
entry->flags &=
- ~EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG;
+ ~EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG;
}
} else {
- entry->flags &= ~EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG;
- entry->flags &= ~EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG;
+ entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG;
+ entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG;
}
}
}
void eigrp_update_routing_table(struct eigrp *eigrp,
- struct eigrp_prefix_entry *prefix)
+ struct eigrp_prefix_descriptor *prefix)
{
struct list *successors;
struct listnode *node;
- struct eigrp_nexthop_entry *entry;
+ struct eigrp_route_descriptor *entry;
successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths);
@@ -474,13 +478,13 @@ void eigrp_update_routing_table(struct eigrp *eigrp,
eigrp_zebra_route_add(eigrp, prefix->destination, successors,
prefix->fdistance);
for (ALL_LIST_ELEMENTS_RO(successors, node, entry))
- entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG;
+ entry->flags |= EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG;
list_delete(&successors);
} else {
eigrp_zebra_route_delete(eigrp, prefix->destination);
for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry))
- entry->flags &= ~EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG;
+ entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG;
}
}
@@ -488,8 +492,8 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp,
struct eigrp_neighbor *nbr)
{
struct listnode *node2, *node22;
- struct eigrp_prefix_entry *pe;
- struct eigrp_nexthop_entry *entry;
+ struct eigrp_prefix_descriptor *pe;
+ struct eigrp_route_descriptor *entry;
struct route_node *rn;
for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
@@ -521,18 +525,18 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp,
void eigrp_update_topology_table_prefix(struct eigrp *eigrp,
struct route_table *table,
- struct eigrp_prefix_entry *prefix)
+ struct eigrp_prefix_descriptor *prefix)
{
struct listnode *node1, *node2;
- struct eigrp_nexthop_entry *entry;
+ struct eigrp_route_descriptor *entry;
for (ALL_LIST_ELEMENTS(prefix->entries, node1, node2, entry)) {
if (entry->distance == EIGRP_MAX_METRIC) {
- eigrp_nexthop_entry_delete(eigrp, prefix, entry);
+ eigrp_route_descriptor_delete(eigrp, prefix, entry);
}
}
if (prefix->distance == EIGRP_MAX_METRIC
&& prefix->nt != EIGRP_TOPOLOGY_TYPE_CONNECTED) {
- eigrp_prefix_entry_delete(eigrp, table, prefix);
+ eigrp_prefix_descriptor_delete(eigrp, table, prefix);
}
}
diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h
index 718cece403..26fa1a11b0 100644
--- a/eigrpd/eigrp_topology.h
+++ b/eigrpd/eigrp_topology.h
@@ -35,43 +35,47 @@
/* EIGRP Topology table related functions. */
extern struct route_table *eigrp_topology_new(void);
extern void eigrp_topology_init(struct route_table *table);
-extern struct eigrp_prefix_entry *eigrp_prefix_entry_new(void);
-extern struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void);
+extern struct eigrp_prefix_descriptor *eigrp_prefix_descriptor_new(void);
+extern struct eigrp_route_descriptor *eigrp_route_descriptor_new(void);
extern void eigrp_topology_free(struct eigrp *eigrp, struct route_table *table);
-extern void eigrp_prefix_entry_add(struct route_table *table,
- struct eigrp_prefix_entry *pe);
-extern void eigrp_nexthop_entry_add(struct eigrp *eigrp,
- struct eigrp_prefix_entry *pe,
- struct eigrp_nexthop_entry *ne);
-extern void eigrp_prefix_entry_delete(struct eigrp *eigrp,
- struct route_table *table,
- struct eigrp_prefix_entry *pe);
-extern void eigrp_nexthop_entry_delete(struct eigrp *eigrp,
- struct eigrp_prefix_entry *pe,
- struct eigrp_nexthop_entry *ne);
+extern void eigrp_prefix_descriptor_add(struct route_table *table,
+ struct eigrp_prefix_descriptor *pe);
+extern void eigrp_route_descriptor_add(struct eigrp *eigrp,
+ struct eigrp_prefix_descriptor *pe,
+ struct eigrp_route_descriptor *ne);
+extern void eigrp_prefix_descriptor_delete(struct eigrp *eigrp,
+ struct route_table *table,
+ struct eigrp_prefix_descriptor *pe);
+extern void eigrp_route_descriptor_delete(struct eigrp *eigrp,
+ struct eigrp_prefix_descriptor *pe,
+ struct eigrp_route_descriptor *ne);
extern void eigrp_topology_delete_all(struct eigrp *eigrp,
struct route_table *table);
-extern struct eigrp_prefix_entry *
+extern struct eigrp_prefix_descriptor *
eigrp_topology_table_lookup_ipv4(struct route_table *table, struct prefix *p);
-extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *pe);
extern struct list *
-eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe,
+eigrp_topology_get_successor(struct eigrp_prefix_descriptor *pe);
+extern struct list *
+eigrp_topology_get_successor_max(struct eigrp_prefix_descriptor *pe,
unsigned int maxpaths);
-extern struct eigrp_nexthop_entry *
-eigrp_prefix_entry_lookup(struct list *entries, struct eigrp_neighbor *neigh);
+extern struct eigrp_route_descriptor *
+eigrp_route_descriptor_lookup(struct list *entries,
+ struct eigrp_neighbor *neigh);
extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
struct eigrp_neighbor *n);
extern void eigrp_topology_update_all_node_flags(struct eigrp *eigrp);
-extern void eigrp_topology_update_node_flags(struct eigrp *eigrp,
- struct eigrp_prefix_entry *pe);
+extern void
+eigrp_topology_update_node_flags(struct eigrp *eigrp,
+ struct eigrp_prefix_descriptor *pe);
extern enum metric_change
eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg);
extern void eigrp_update_routing_table(struct eigrp *eigrp,
- struct eigrp_prefix_entry *pe);
+ struct eigrp_prefix_descriptor *pe);
extern void eigrp_topology_neighbor_down(struct eigrp *eigrp,
struct eigrp_neighbor *neigh);
-extern void eigrp_update_topology_table_prefix(struct eigrp *eigrp,
- struct route_table *table,
- struct eigrp_prefix_entry *pe);
+extern void
+eigrp_update_topology_table_prefix(struct eigrp *eigrp,
+ struct route_table *table,
+ struct eigrp_prefix_descriptor *pe);
#endif
diff --git a/eigrpd/eigrp_types.h b/eigrpd/eigrp_types.h
new file mode 100644
index 0000000000..bd6510733b
--- /dev/null
+++ b/eigrpd/eigrp_types.h
@@ -0,0 +1,36 @@
+/*
+ * EIGRP Definition of Data Types
+ * Copyright (C) 2018
+ * Authors:
+ * Donnie Savage
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ZEBRA_EIGRP_TYPES_H_
+#define _ZEBRA_EIGRP_TYPES_H_
+
+typedef uint64_t eigrp_bandwidth_t;
+typedef uint64_t eigrp_delay_t;
+typedef uint64_t eigrp_metric_t;
+typedef uint32_t eigrp_scaled_t;
+
+typedef uint32_t eigrp_system_metric_t;
+typedef uint32_t eigrp_system_delay_t;
+typedef uint32_t eigrp_system_bandwidth_t;
+
+#endif /* _ZEBRA_EIGRP_TYPES_H_ */
diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c
index cd30eb5ab5..91f3b3218b 100644
--- a/eigrpd/eigrp_update.c
+++ b/eigrpd/eigrp_update.c
@@ -49,6 +49,7 @@
#include "routemap.h"
#include "vty.h"
+#include "eigrpd/eigrp_types.h"
#include "eigrpd/eigrp_structs.h"
#include "eigrpd/eigrpd.h"
#include "eigrpd/eigrp_interface.h"
@@ -62,6 +63,7 @@
#include "eigrpd/eigrp_fsm.h"
#include "eigrpd/eigrp_network.h"
#include "eigrpd/eigrp_memory.h"
+#include "eigrpd/eigrp_metric.h"
bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei,
int in, struct prefix *prefix)
@@ -101,11 +103,12 @@ bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei,
* Function is used for removing received prefix
* from list of neighbor prefixes
*/
-static void remove_received_prefix_gr(struct list *nbr_prefixes,
- struct eigrp_prefix_entry *recv_prefix)
+static void
+remove_received_prefix_gr(struct list *nbr_prefixes,
+ struct eigrp_prefix_descriptor *recv_prefix)
{
struct listnode *node1, *node11;
- struct eigrp_prefix_entry *prefix = NULL;
+ struct eigrp_prefix_descriptor *prefix = NULL;
/* iterate over all prefixes in list */
for (ALL_LIST_ELEMENTS(nbr_prefixes, node1, node11, prefix)) {
@@ -136,7 +139,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp,
struct list *nbr_prefixes)
{
struct listnode *node1;
- struct eigrp_prefix_entry *prefix;
+ struct eigrp_prefix_descriptor *prefix;
struct eigrp_fsm_action_message fsm_msg;
/* iterate over all prefixes which weren't advertised by neighbor */
@@ -148,8 +151,8 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp,
/* set delay to MAX */
fsm_msg.metrics.delay = EIGRP_MAX_METRIC;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(prefix->entries, nbr);
+ struct eigrp_route_descriptor *entry =
+ eigrp_route_descriptor_lookup(prefix->entries, nbr);
fsm_msg.packet_type = EIGRP_OPC_UPDATE;
fsm_msg.eigrp = eigrp;
@@ -172,8 +175,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
{
struct eigrp_neighbor *nbr;
struct TLV_IPv4_Internal_type *tlv;
- struct eigrp_prefix_entry *pe;
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_prefix_descriptor *pe;
+ struct eigrp_route_descriptor *ne;
uint32_t flags;
uint16_t type;
uint16_t length;
@@ -304,7 +307,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
dest_addr.family = AF_INET;
dest_addr.u.prefix4 = tlv->destination;
dest_addr.prefixlen = tlv->prefix_length;
- struct eigrp_prefix_entry *dest =
+ struct eigrp_prefix_descriptor *dest =
eigrp_topology_table_lookup_ipv4(
eigrp->topology_table, &dest_addr);
@@ -317,9 +320,9 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
dest);
struct eigrp_fsm_action_message msg;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(dest->entries,
- nbr);
+ struct eigrp_route_descriptor *entry =
+ eigrp_route_descriptor_lookup(
+ dest->entries, nbr);
msg.packet_type = EIGRP_OPC_UPDATE;
msg.eigrp = eigrp;
@@ -331,7 +334,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
eigrp_fsm_event(&msg);
} else {
/*Here comes topology information save*/
- pe = eigrp_prefix_entry_new();
+ pe = eigrp_prefix_descriptor_new();
pe->serno = eigrp->serno;
pe->destination =
(struct prefix *)prefix_ipv4_new();
@@ -340,7 +343,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
pe->state = EIGRP_FSM_STATE_PASSIVE;
pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE;
- ne = eigrp_nexthop_entry_new();
+ ne = eigrp_route_descriptor_new();
ne->ei = ei;
ne->adv_router = nbr;
ne->reported_metric = tlv->metric;
@@ -361,11 +364,12 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
pe->fdistance = pe->distance = pe->rdistance =
ne->distance;
ne->prefix = pe;
- ne->flags = EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG;
+ ne->flags =
+ EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG;
- eigrp_prefix_entry_add(eigrp->topology_table,
- pe);
- eigrp_nexthop_entry_add(eigrp, pe, ne);
+ eigrp_prefix_descriptor_add(
+ eigrp->topology_table, pe);
+ eigrp_route_descriptor_add(eigrp, pe, ne);
pe->distance = pe->fdistance = pe->rdistance =
ne->distance;
pe->reported_metric = ne->total_metric;
@@ -527,8 +531,8 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
{
struct eigrp_packet *ep;
uint16_t length = EIGRP_HEADER_LEN;
- struct eigrp_nexthop_entry *te;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_route_descriptor *te;
+ struct eigrp_prefix_descriptor *pe;
struct listnode *node2, *nnode2;
struct eigrp_interface *ei = nbr->ei;
struct eigrp *eigrp = ei->eigrp;
@@ -600,7 +604,7 @@ void eigrp_update_send(struct eigrp_interface *ei)
{
struct eigrp_packet *ep;
struct listnode *node, *nnode;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
uint8_t has_tlv;
struct eigrp *eigrp = ei->eigrp;
struct prefix *dest_addr;
@@ -626,7 +630,7 @@ void eigrp_update_send(struct eigrp_interface *ei)
has_tlv = 0;
for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
nnode, pe)) {
- struct eigrp_nexthop_entry *ne;
+ struct eigrp_route_descriptor *ne;
if (!(pe->req_action & EIGRP_FSM_NEED_UPDATE))
continue;
@@ -707,7 +711,7 @@ void eigrp_update_send_all(struct eigrp *eigrp,
{
struct eigrp_interface *iface;
struct listnode *node, *node2, *nnode2;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) {
if (iface != exception) {
@@ -745,7 +749,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
{
struct eigrp_packet *ep;
uint16_t length = EIGRP_HEADER_LEN;
- struct eigrp_prefix_entry *pe;
+ struct eigrp_prefix_descriptor *pe;
struct prefix *dest_addr;
struct eigrp_interface *ei = nbr->ei;
struct eigrp *eigrp = ei->eigrp;
@@ -837,8 +841,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
/* prepare message for FSM */
struct eigrp_fsm_action_message fsm_msg;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(pe->entries, nbr);
+ struct eigrp_route_descriptor *entry =
+ eigrp_route_descriptor_lookup(pe->entries, nbr);
fsm_msg.packet_type = EIGRP_OPC_UPDATE;
fsm_msg.eigrp = eigrp;
@@ -956,7 +960,7 @@ int eigrp_update_send_GR_thread(struct thread *thread)
void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
struct vty *vty)
{
- struct eigrp_prefix_entry *pe2;
+ struct eigrp_prefix_descriptor *pe2;
struct list *prefixes;
struct route_node *rn;
struct eigrp_interface *ei = nbr->ei;
diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c
index 66dfbaa538..0809ac2cf0 100644
--- a/eigrpd/eigrp_vty.c
+++ b/eigrpd/eigrp_vty.c
@@ -59,25 +59,21 @@
#include "eigrpd/eigrp_vty_clippy.c"
#endif
-static void eigrp_vty_display_prefix_entry(struct vty *vty,
- struct eigrp *eigrp,
- struct eigrp_prefix_entry *pe,
+static void eigrp_vty_display_prefix_entry(struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_prefix_descriptor *pe,
bool all)
{
bool first = true;
- struct eigrp_nexthop_entry *te;
+ struct eigrp_route_descriptor *te;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(pe->entries, node, te)) {
if (all
- || (((te->flags
- & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)
- == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)
- || ((te->flags
- & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG)
- == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) {
- show_ip_eigrp_nexthop_entry(vty, eigrp, te,
- &first);
+ || (((te->flags & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)
+ == EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)
+ || ((te->flags & EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG)
+ == EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG))) {
+ show_ip_eigrp_route_descriptor(vty, eigrp, te, &first);
first = false;
}
}
@@ -104,7 +100,7 @@ static struct eigrp *eigrp_vty_get_eigrp(struct vty *vty, const char *vrf_name)
static void eigrp_topology_helper(struct vty *vty, struct eigrp *eigrp,
const char *all)
{
- struct eigrp_prefix_entry *tn;
+ struct eigrp_prefix_descriptor *tn;
struct route_node *rn;
show_ip_eigrp_topology_header(vty, eigrp);
@@ -168,7 +164,7 @@ DEFPY (show_ip_eigrp_topology,
"For a specific prefix\n")
{
struct eigrp *eigrp;
- struct eigrp_prefix_entry *tn;
+ struct eigrp_prefix_descriptor *tn;
struct route_node *rn;
struct prefix cmp;
diff --git a/eigrpd/eigrp_yang.h b/eigrpd/eigrp_yang.h
new file mode 100644
index 0000000000..a95e5310fb
--- /dev/null
+++ b/eigrpd/eigrp_yang.h
@@ -0,0 +1,32 @@
+/*
+ * EIGRP YANG Functions.
+ * Copyright (C) 2019
+ * Authors:
+ * Donnie Savage
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _EIGRP_YANG_H_
+#define _EIGRP_YANG_H_
+
+/*Prototypes*/
+
+/* eigrp_northbound.c */
+extern const struct frr_yang_module_info frr_eigrpd_info;
+
+#endif /*EIGRP_YANG_H_ */
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 0795fbd6df..e79123e6b4 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -41,6 +41,7 @@
#include "log.h"
#include "nexthop.h"
+#include "eigrpd/eigrp_types.h"
#include "eigrpd/eigrp_structs.h"
#include "eigrpd/eigrpd.h"
#include "eigrpd/eigrp_interface.h"
@@ -52,6 +53,7 @@
#include "eigrpd/eigrp_network.h"
#include "eigrpd/eigrp_topology.h"
#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_metric.h"
static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS);
static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS);
@@ -194,7 +196,7 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
- struct eigrp_nexthop_entry *te;
+ struct eigrp_route_descriptor *te;
struct listnode *node;
int count = 0;
diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h
index 6b4d45d1fc..01173768ba 100644
--- a/eigrpd/eigrpd.h
+++ b/eigrpd/eigrpd.h
@@ -37,6 +37,30 @@
#define EIGRP_MAJOR_VERSION 1
#define EIGRP_MINOR_VERSION 2
+#define EIGRP_TLV_32B_VERSION 1 /* Original 32bit scaled metrics */
+#define EIGRP_TLV_64B_VERSION 2 /* Current 64bit 'wide' metrics */
+#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 */
+
+struct eigrp_master {
+ /* EIGRP instance. */
+ struct list *eigrp;
+
+ /* EIGRP thread master. */
+ struct thread_master *master;
+
+ /* Zebra interface list. */
+ struct list *iflist;
+
+ /* EIGRP start time. */
+ time_t start_time;
+
+ /* Various EIGRP global configuration. */
+ uint8_t options;
+
+#define EIGRP_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
+};
+
/* Extern variables. */
extern struct zclient *zclient;
extern struct thread_master *master;
@@ -46,57 +70,10 @@ extern struct zebra_privs_t eigrpd_privs;
/* Prototypes */
extern void eigrp_master_init(void);
extern void eigrp_terminate(void);
-extern void eigrp_finish_final(struct eigrp *);
-extern void eigrp_finish(struct eigrp *);
+extern void eigrp_finish_final(struct eigrp *eigrp);
+extern void eigrp_finish(struct eigrp *eigrp);
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_cli.c */
-extern void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode);
-extern void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_passive_interface(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_maximum_paths(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_redistribute(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_hello_interval(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_summarize_address(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_authentication(struct vty *vty,
- struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
-extern void eigrp_cli_init(void);
-
-/* eigrp_northbound.c */
-extern const struct frr_yang_module_info frr_eigrpd_info;
+extern void eigrp_router_id_update(struct eigrp *eigrp);
#endif /* _ZEBRA_EIGRPD_H */
diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am
index 98f39440c3..13c9f7f8ae 100644
--- a/eigrpd/subdir.am
+++ b/eigrpd/subdir.am
@@ -25,6 +25,7 @@ eigrpd_libeigrp_a_SOURCES = \
eigrpd/eigrp_hello.c \
eigrpd/eigrp_interface.c \
eigrpd/eigrp_memory.c \
+ eigrpd/eigrp_metric.c \
eigrpd/eigrp_neighbor.c \
eigrpd/eigrp_network.c \
eigrpd/eigrp_northbound.c \
@@ -55,6 +56,7 @@ clippy_scan += \
# end
noinst_HEADERS += \
+ eigrpd/eigrp_cli.h \
eigrpd/eigrp_const.h \
eigrpd/eigrp_errors.h \
eigrpd/eigrp_filter.h \
@@ -62,13 +64,16 @@ noinst_HEADERS += \
eigrpd/eigrp_interface.h \
eigrpd/eigrp_macros.h \
eigrpd/eigrp_memory.h \
+ eigrpd/eigrp_metric.h \
eigrpd/eigrp_neighbor.h \
eigrpd/eigrp_network.h \
eigrpd/eigrp_packet.h \
eigrpd/eigrp_snmp.h \
eigrpd/eigrp_structs.h \
+ eigrpd/eigrp_types.h \
eigrpd/eigrp_vrf.h \
eigrpd/eigrp_vty.h \
+ eigrpd/eigrp_yang.h \
eigrpd/eigrp_zebra.h \
# end
diff --git a/lib/zclient.c b/lib/zclient.c
index cb4555650d..563673c6f3 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -40,6 +40,7 @@
#include "nexthop_group.h"
#include "lib_errors.h"
#include "srte.h"
+#include "printfrr.h"
DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
@@ -4121,3 +4122,28 @@ uint32_t zclient_get_nhg_start(uint32_t proto)
return ZEBRA_NHG_PROTO_SPACING * proto;
}
+
+char *zclient_dump_route_flags(uint32_t flags, char *buf, size_t len)
+{
+ if (flags == 0) {
+ snprintfrr(buf, len, "None ");
+ return buf;
+ }
+
+ snprintfrr(
+ buf, len, "%s%s%s%s%s%s%s%s%s%s",
+ CHECK_FLAG(flags, ZEBRA_FLAG_ALLOW_RECURSION) ? "Recursion "
+ : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) ? "Self " : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_IBGP) ? "iBGP " : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_SELECTED) ? "Selected " : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_FIB_OVERRIDE) ? "Override " : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE) ? "Evpn " : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_RR_USE_DISTANCE) ? "RR Distance "
+ : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_TRAPPED) ? "Trapped " : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOADED) ? "Offloaded " : "",
+ CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOAD_FAILED) ? "Offload Failed "
+ : "");
+ return buf;
+}
diff --git a/lib/zclient.h b/lib/zclient.h
index 910a4dbae5..44aa1fc091 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -479,6 +479,7 @@ struct zapi_route {
uint8_t type;
unsigned short instance;
+ /* If you add flags, update zclient_dump_route_flags */
uint32_t flags;
/*
* Cause Zebra to consider this routes nexthops recursively
@@ -580,6 +581,8 @@ struct zapi_route {
} opaque;
};
+extern char *zclient_dump_route_flags(uint32_t flags, char *buf, size_t len);
+
struct zapi_labels {
uint8_t message;
#define ZAPI_LABELS_FTN 0x01
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index 85e8c9caed..175d660d1e 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -1659,7 +1659,7 @@ def create_interfaces_cfg(tgen, topo, build=False):
interface_data.append("no ip ospf " " hello-interval")
else:
interface_data.append(
- "ip ospf " " hello-interval {}".format(intf_ospf_hello)
+ "ip ospf" " hello-interval {}".format(intf_ospf_hello)
)
if "dead_interval" in ospf_data:
@@ -1670,7 +1670,7 @@ def create_interfaces_cfg(tgen, topo, build=False):
interface_data.append("no ip ospf" " dead-interval")
else:
interface_data.append(
- "ip ospf " " dead-interval {}".format(intf_ospf_dead)
+ "ip ospf" " dead-interval {}".format(intf_ospf_dead)
)
if "network" in ospf_data:
@@ -3065,7 +3065,11 @@ def verify_rib(
errormsg = (
"[DUT: {}]: tag value {}"
" is not matched for"
- " route {} in RIB \n".format(dut, _tag, st_rt,)
+ " route {} in RIB \n".format(
+ dut,
+ _tag,
+ st_rt,
+ )
)
return errormsg
@@ -3082,7 +3086,11 @@ def verify_rib(
errormsg = (
"[DUT: {}]: metric value "
"{} is not matched for "
- "route {} in RIB \n".format(dut, metric, st_rt,)
+ "route {} in RIB \n".format(
+ dut,
+ metric,
+ st_rt,
+ )
)
return errormsg
diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py
index 23b647d094..3e368cd7d3 100644
--- a/tests/topotests/lib/ospf.py
+++ b/tests/topotests/lib/ospf.py
@@ -62,7 +62,7 @@ def create_router_ospf(tgen, topo, input_dict=None, build=False, load_config=Tru
"r1": {
"ospf": {
"router_id": "22.22.22.22",
- "area": [{ "id":0.0.0.0, "type": "nssa"}]
+ "area": [{ "id": "0.0.0.0", "type": "nssa"}]
}
}
@@ -327,7 +327,7 @@ def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config=
"links": {
"r2": {
"ospf": {
- "authentication": 'message-digest',
+ "authentication": "message-digest",
"authentication-key": "ospf",
"message-digest-key": "10"
}
@@ -376,6 +376,7 @@ def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config=
if data_ospf_area:
cmd = "ip ospf area {}".format(data_ospf_area)
config_data.append(cmd)
+
# interface ospf auth
if data_ospf_auth:
if data_ospf_auth == "null":
@@ -461,6 +462,32 @@ def clear_ospf(tgen, router):
logger.debug("Exiting lib API: clear_ospf()")
+def redistribute_ospf(tgen, topo, dut, route_type, **kwargs):
+ """
+ Redstribution of routes inside ospf.
+
+ Parameters
+ ----------
+ * `tgen`: Topogen object
+ * `topo` : json file data
+ * `dut`: device under test
+ * `route_type`: "static" or "connected" or ....
+ * `kwargs`: pass extra information (see below)
+
+ Usage
+ -----
+ redistribute_ospf(tgen, topo, "r0", "static", delete=True)
+ redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4")
+ """
+
+ ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": route_type}]}}}
+ for k, v in kwargs.items():
+ ospf_red[dut]["ospf"]["redistribute"][0][k] = v
+
+ result = create_router_ospf(tgen, topo, ospf_red)
+ assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+
################################
# Verification procs
################################
@@ -522,7 +549,7 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False):
logger.info("Verifying OSPF neighborship on router %s:", router)
show_ospf_json = run_frr_cmd(
- rnode, "show ip ospf neighbor all json", isjson=True
+ rnode, "show ip ospf neighbor all json", isjson=True
)
# Verifying output dictionary show_ospf_json is empty or not
@@ -844,19 +871,23 @@ def verify_ospf_rib(
if "routeType" not in ospf_rib_json[st_rt]:
errormsg = (
"[DUT: {}]: routeType missing"
- "for route {} in OSPF RIB \n".format(dut, st_rt)
+ " for route {} in OSPF RIB \n".format(
+ dut, st_rt
+ )
)
return errormsg
elif _rtype != ospf_rib_json[st_rt]["routeType"]:
errormsg = (
"[DUT: {}]: routeType mismatch"
- "for route {} in OSPF RIB \n".format(dut, st_rt)
+ " for route {} in OSPF RIB \n".format(
+ dut, st_rt
+ )
)
return errormsg
else:
logger.info(
- "DUT: {}]: Found routeType {}"
- "for route {}".format(dut, _rtype, st_rt)
+ "[DUT: {}]: Found routeType {}"
+ " for route {}".format(dut, _rtype, st_rt)
)
if tag:
if "tag" not in ospf_rib_json[st_rt]:
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
index 5ef6b9b0be..441368e8fa 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
@@ -65,6 +65,7 @@ from lib.ospf import (
verify_ospf_rib,
create_router_ospf,
verify_ospf_interface,
+ redistribute_ospf,
)
topo = None
@@ -184,38 +185,6 @@ def teardown_module(mod):
logger.info("=" * 40)
-def red_static(dut, config=True):
- """Local def for Redstribute static routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}}
- else:
- ospf_red = {
- dut: {"ospf": {"redistribute": [{"redist_type": "static", "delete": True}]}}
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase : Failed \n Error: {}".format(result)
-
-
-def red_connected(dut, config=True):
- """Local def for Redstribute connected routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "connected", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase: Failed \n Error: {}".format(result)
-
-
# ##################################
# Test cases start here.
# ##################################
@@ -264,7 +233,7 @@ def test_ospf_ecmp_tc16_p0(request):
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r0"
- red_static(dut)
+ redistribute_ospf(tgen, topo, dut, "static")
step("Verify that route in R2 in stalled with 8 next hops.")
nh = []
@@ -345,7 +314,7 @@ def test_ospf_ecmp_tc16_p0(request):
step(" Un configure static route on R0")
dut = "r0"
- red_static(dut, config=False)
+ redistribute_ospf(tgen, topo, dut, "static", delete=True)
# Wait for R0 to flush external LSAs.
sleep(10)
@@ -376,7 +345,7 @@ def test_ospf_ecmp_tc16_p0(request):
step("Re configure the static route in R0.")
dut = "r0"
- red_static(dut)
+ redistribute_ospf(tgen, topo, dut, "static")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh)
@@ -431,7 +400,7 @@ def test_ospf_ecmp_tc17_p0(request):
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r0"
- red_static(dut)
+ redistribute_ospf(tgen, topo, dut, "static")
step("Verify that route in R2 in stalled with 2 next hops.")
@@ -450,7 +419,7 @@ def test_ospf_ecmp_tc17_p0(request):
step(" Un configure static route on R0")
dut = "r0"
- red_static(dut, config=False)
+ redistribute_ospf(tgen, topo, dut, "static", delete=True)
# sleep till the route gets withdrawn
sleep(10)
@@ -480,7 +449,7 @@ def test_ospf_ecmp_tc17_p0(request):
step("Reconfigure the static route in R0.Change ECMP value to 2.")
dut = "r0"
- red_static(dut)
+ redistribute_ospf(tgen, topo, dut, "static")
step("Configure cost on R0 as 100")
r0_ospf_cost = {"r0": {"links": {"r1": {"ospf": {"cost": 100}}}}}
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
index 967bc44879..2da1dcd21a 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
@@ -66,6 +66,7 @@ from lib.ospf import (
verify_ospf_rib,
create_router_ospf,
verify_ospf_interface,
+ redistribute_ospf,
)
from ipaddress import IPv4Address
@@ -187,42 +188,6 @@ def teardown_module():
pass
-def red_static(dut, config=True):
- """Local def for Redstribute static routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "static", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase : Failed \n Error: {}".format(result)
-
-
-def red_connected(dut, config=True):
- """Local def for Redstribute connected routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "connected", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase: Failed \n Error: {}".format(result)
-
-
# ##################################
# Test cases start here.
# ##################################
@@ -275,7 +240,7 @@ def test_ospf_lan_ecmp_tc18_p0(request):
)
dut = rtr
- red_static(dut)
+ redistribute_ospf(tgen, topo, dut, "static")
step(
"Verify that route in R0 in stalled with 8 hops. "
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py
index 0f1115f815..dac32090bc 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py
@@ -183,42 +183,6 @@ def teardown_module():
pass
-def red_static(dut, config=True):
- """Local def for Redstribute static routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "static", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase : Failed \n Error: {}".format(result)
-
-
-def red_connected(dut, config=True):
- """Local def for Redstribute connected routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "connected", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase: Failed \n Error: {}".format(result)
-
-
# ##################################
# Test cases start here.
# ##################################
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py
index 82a34d046c..3644bff3dc 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py
@@ -30,6 +30,7 @@ from lib.ospf import (
verify_ospf_rib,
create_router_ospf,
verify_ospf_interface,
+ redistribute_ospf,
)
from lib.topojson import build_topo_from_json, build_config_from_json
from lib.topolog import logger
@@ -181,38 +182,6 @@ def teardown_module(mod):
logger.info("=" * 40)
-def red_static(dut, config=True):
- """Local def for Redstribute static routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}}
- else:
- ospf_red = {
- dut: {"ospf": {"redistribute": [{"redist_type": "static", "delete": True}]}}
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase : Failed \n Error: {}".format(result)
-
-
-def red_connected(dut, config=True):
- """Local def for Redstribute connected routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "connected", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase: Failed \n Error: {}".format(result)
-
-
# ##################################
# Test cases start here.
# ##################################
@@ -268,7 +237,7 @@ def test_ospf_learning_tc15_p0(request):
step("Redistribute static route in R2 ospf.")
dut = "r2"
- red_static(dut)
+ redistribute_ospf(tgen, topo, dut, "static")
step("Verify that Type 5 LSA is originated by R2.")
dut = "r0"
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
index 88667a6ac8..ceadb3975b 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
@@ -62,6 +62,7 @@ from lib.ospf import (
verify_ospf_rib,
create_router_ospf,
verify_ospf_database,
+ redistribute_ospf,
)
# Global variables
@@ -226,9 +227,7 @@ def test_ospf_routemaps_functionality_tc19_p0(request):
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- ospf_red_r1 = {"r0": {"ospf": {"redistribute": [{"redist_type": "static"}]}}}
- result = create_router_ospf(tgen, topo, ospf_red_r1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ redistribute_ospf(tgen, topo, "r0", "static")
dut = "r1"
lsid = NETWORK["ipv4"][0].split("/")[0]
@@ -240,13 +239,7 @@ def test_ospf_routemaps_functionality_tc19_p0(request):
result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- ospf_red_r1 = {
- "r0": {
- "ospf": {"redistribute": [{"redist_type": "static", "del_action": True}]}
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red_r1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ redistribute_ospf(tgen, topo, "r0", "static", delete=True)
step(
"Create prefix-list in R0 to permit 10.0.20.1/32 prefix &" " deny 10.0.20.2/32"
@@ -293,15 +286,7 @@ def test_ospf_routemaps_functionality_tc19_p0(request):
" ospf using route map rmap1"
)
- ospf_red_r1 = {
- "r0": {
- "ospf": {
- "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red_r1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4")
step("Change prefix rules to permit 10.0.20.2 and deny 10.0.20.1")
# Create ip prefix list
@@ -495,15 +480,7 @@ def test_ospf_routemaps_functionality_tc20_p0(request):
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Redistribute to ospf using route map ( non existent route map)")
- ospf_red_r1 = {
- "r0": {
- "ospf": {
- "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red_r1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4")
step(
"Verify that routes are not allowed in OSPF even tough no "
@@ -633,15 +610,7 @@ def test_ospf_routemaps_functionality_tc21_p0(request):
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- ospf_red_r0 = {
- "r0": {
- "ospf": {
- "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red_r0)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4")
# Create route map
routemaps = {
@@ -877,15 +846,7 @@ def test_ospf_routemaps_functionality_tc24_p0(request):
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- ospf_red_r0 = {
- "r0": {
- "ospf": {
- "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red_r0)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4")
# Create ip prefix list
pfx_list = {
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
index 434d7f8ef5..5aa2779aee 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
@@ -61,6 +61,7 @@ from lib.ospf import (
clear_ospf,
verify_ospf_rib,
create_router_ospf,
+ redistribute_ospf,
)
# Global variables
@@ -183,42 +184,6 @@ def teardown_module(mod):
logger.info("=" * 40)
-def red_static(dut, config=True):
- """Local def for Redstribute static routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "static", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase : Failed \n Error: {}".format(result)
-
-
-def red_connected(dut, config=True):
- """Local def for Redstribute connected routes inside ospf."""
- global topo
- tgen = get_topogen()
- if config:
- ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}}
- else:
- ospf_red = {
- dut: {
- "ospf": {
- "redistribute": [{"redist_type": "connected", "del_action": True}]
- }
- }
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase: Failed \n Error: {}".format(result)
-
-
# ##################################
# Test cases start here.
# ##################################
@@ -486,8 +451,8 @@ def test_ospf_redistribution_tc8_p1(request):
"advertised/exchaged via ospf"
)
for rtr in topo["routers"]:
- red_static(rtr)
- red_connected(rtr)
+ redistribute_ospf(tgen, topo, rtr, "static")
+ redistribute_ospf(tgen, topo, rtr, "connected")
for node in topo["routers"]:
input_dict = {
"r0": {
@@ -544,13 +509,7 @@ def test_ospf_redistribution_tc8_p1(request):
)
for rtr in topo["routers"]:
- ospf_red = {
- rtr: {"ospf": {"redistribute": [{"redist_type": "static", "delete": True}]}}
- }
- result = create_router_ospf(tgen, topo, ospf_red)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(
- tc_name, result
- )
+ redistribute_ospf(tgen, topo, rtr, "static", delete=True)
input_dict = {
"r0": {
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index da7f4cf64e..db2b9e002e 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -3684,7 +3684,7 @@ int dplane_show_helper(struct vty *vty, bool detailed)
int dplane_show_provs_helper(struct vty *vty, bool detailed)
{
struct zebra_dplane_provider *prov;
- uint64_t in, in_max, out, out_max;
+ uint64_t in, in_q, in_max, out, out_q, out_max;
vty_out(vty, "Zebra dataplane providers:\n");
@@ -3697,17 +3697,20 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed)
in = atomic_load_explicit(&prov->dp_in_counter,
memory_order_relaxed);
+ in_q = atomic_load_explicit(&prov->dp_in_queued,
+ memory_order_relaxed);
in_max = atomic_load_explicit(&prov->dp_in_max,
memory_order_relaxed);
out = atomic_load_explicit(&prov->dp_out_counter,
memory_order_relaxed);
+ out_q = atomic_load_explicit(&prov->dp_out_queued,
+ memory_order_relaxed);
out_max = atomic_load_explicit(&prov->dp_out_max,
memory_order_relaxed);
- vty_out(vty,
- "%s (%u): in: %" PRIu64 ", q_max: %" PRIu64
- ", out: %" PRIu64 ", q_max: %" PRIu64 "\n",
- prov->dp_name, prov->dp_id, in, in_max, out, out_max);
+ vty_out(vty, "%s (%u): in: %"PRIu64", q: %"PRIu64", q_max: %"PRIu64", out: %"PRIu64", q: %"PRIu64", q_max: %"PRIu64"\n",
+ prov->dp_name, prov->dp_id, in, in_q, in_max,
+ out, out_q, out_max);
DPLANE_LOCK();
prov = TAILQ_NEXT(prov, dp_prov_link);
@@ -3912,11 +3915,24 @@ uint32_t dplane_provider_out_ctx_queue_len(struct zebra_dplane_provider *prov)
void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov,
struct zebra_dplane_ctx *ctx)
{
+ uint64_t curr, high;
+
dplane_provider_lock(prov);
TAILQ_INSERT_TAIL(&(prov->dp_ctx_out_q), ctx,
zd_q_entries);
+ /* Maintain out-queue counters */
+ atomic_fetch_add_explicit(&(prov->dp_out_queued), 1,
+ memory_order_relaxed);
+ curr = atomic_load_explicit(&prov->dp_out_queued,
+ memory_order_relaxed);
+ high = atomic_load_explicit(&prov->dp_out_max,
+ memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&prov->dp_out_max, curr,
+ memory_order_relaxed);
+
dplane_provider_unlock(prov);
atomic_fetch_add_explicit(&(prov->dp_out_counter), 1,
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index 375be45df0..0a692feb35 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -2120,7 +2120,6 @@ static unsigned nexthop_active_check(struct route_node *rn,
struct interface *ifp;
route_map_result_t ret = RMAP_PERMITMATCH;
int family;
- char buf[SRCDEST2STR_BUFFER];
const struct prefix *p, *src_p;
struct zebra_vrf *zvrf;
@@ -2230,10 +2229,9 @@ static unsigned nexthop_active_check(struct route_node *rn,
zvrf, re->tag);
if (ret == RMAP_DENYMATCH) {
if (IS_ZEBRA_DEBUG_RIB) {
- srcdest_rnode2str(rn, buf, sizeof(buf));
zlog_debug(
- "%u:%s: Filtering out with NH out %s due to route map",
- re->vrf_id, buf,
+ "%u:%pRN: Filtering out with NH out %s due to route map",
+ re->vrf_id, rn,
ifindex2ifname(nexthop->ifindex,
nexthop->vrf_id));
}
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 1f92c43a69..7c86735545 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -38,6 +38,7 @@
#include "workqueue.h"
#include "nexthop_group_private.h"
#include "frr_pthread.h"
+#include "printfrr.h"
#include "zebra/zebra_router.h"
#include "zebra/connected.h"
@@ -148,6 +149,30 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn,
zlog(priority, "%s: (%u:%u):%s: %s", _func, vrf_id, table, buf, msgbuf);
}
+static char *_dump_re_status(const struct route_entry *re, char *buf,
+ size_t len)
+{
+ if (re->status == 0) {
+ snprintfrr(buf, len, "None ");
+ return buf;
+ }
+
+ snprintfrr(
+ buf, len, "%s%s%s%s%s%s%s",
+ CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED) ? "Removed " : "",
+ CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED) ? "Changed " : "",
+ CHECK_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED)
+ ? "Label Changed "
+ : "",
+ CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED) ? "Queued " : "",
+ CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED) ? "Installed "
+ : "",
+ CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED) ? "Failed " : "",
+ CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG) ? "Fib NHG "
+ : "");
+ return buf;
+}
+
#define rnode_debug(node, vrf_id, ...) \
_rnode_zlog(__func__, vrf_id, node, LOG_DEBUG, __VA_ARGS__)
#define rnode_info(node, ...) \
@@ -1080,12 +1105,20 @@ static void rib_process(struct route_node *rn)
}
RNODE_FOREACH_RE_SAFE (rn, re, next) {
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ char flags_buf[128];
+ char status_buf[128];
+
zlog_debug(
- "%s(%u:%u):%s: Examine re %p (%s) status %x flags %x dist %d metric %d",
+ "%s(%u:%u):%s: Examine re %p (%s) status: %sflags: %sdist %d metric %d",
VRF_LOGNAME(vrf), vrf_id, re->table, buf, re,
- zebra_route_string(re->type), re->status,
- re->flags, re->distance, re->metric);
+ zebra_route_string(re->type),
+ _dump_re_status(re, status_buf,
+ sizeof(status_buf)),
+ zclient_dump_route_flags(re->flags, flags_buf,
+ sizeof(flags_buf)),
+ re->distance, re->metric);
+ }
/* Currently selected re. */
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
@@ -1107,6 +1140,9 @@ static void rib_process(struct route_node *rn)
*/
if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) {
if (!nexthop_active_update(rn, re)) {
+ const struct prefix *p;
+ struct rib_table_info *info;
+
if (re->type == ZEBRA_ROUTE_TABLE) {
/* XXX: HERE BE DRAGONS!!!!!
* In all honesty, I have not yet
@@ -1136,6 +1172,11 @@ static void rib_process(struct route_node *rn)
ROUTE_ENTRY_REMOVED);
}
+ info = srcdest_rnode_table_info(rn);
+ srcdest_rnode_prefixes(rn, &p, NULL);
+ zsend_route_notify_owner(re, p,
+ ZAPI_ROUTE_FAIL_INSTALL,
+ info->afi, info->safi);
continue;
}
} else {
@@ -2791,6 +2832,8 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
bool is_srcdst = src_p && src_p->prefixlen;
char straddr[PREFIX_STRLEN];
char srcaddr[PREFIX_STRLEN];
+ char flags_buf[128];
+ char status_buf[128];
struct nexthop *nexthop;
struct vrf *vrf = vrf_lookup_by_id(re->vrf_id);
struct nexthop_group *nhg;
@@ -2804,9 +2847,12 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d",
straddr, (unsigned long)re->uptime, re->type, re->instance,
re->table);
- zlog_debug("%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u",
- straddr, re->metric, re->mtu, re->distance, re->flags,
- re->status);
+ zlog_debug(
+ "%s: metric == %u, mtu == %u, distance == %u, flags == %sstatus == %s",
+ straddr, re->metric, re->mtu, re->distance,
+ zclient_dump_route_flags(re->flags, flags_buf,
+ sizeof(flags_buf)),
+ _dump_re_status(re, status_buf, sizeof(status_buf)));
zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr,
nexthop_group_nexthop_num(&(re->nhe->nhg)),
nexthop_group_active_nexthop_num(&(re->nhe->nhg)));
@@ -2941,8 +2987,10 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
struct nhg_hash_entry *nhe = NULL;
struct route_table *table;
struct route_node *rn;
- struct route_entry *same = NULL;
+ struct route_entry *same = NULL, *first_same = NULL;
int ret = 0;
+ int same_count = 0;
+ rib_dest_t *dest;
if (!re || !re_nhe)
return -1;
@@ -3010,14 +3058,22 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
* for the install don't do a route replace.
*/
RNODE_FOREACH_RE (rn, same) {
- if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
+ if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)) {
+ same_count++;
continue;
+ }
/* Compare various route_entry properties */
- if (rib_compare_routes(re, same))
- break;
+ if (rib_compare_routes(re, same)) {
+ same_count++;
+
+ if (first_same == NULL)
+ first_same = same;
+ }
}
+ same = first_same;
+
/* If this route is kernel/connected route, notify the dataplane. */
if (RIB_SYSTEM_ROUTE(re)) {
/* Notify dataplane */
@@ -3027,8 +3083,9 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
/* Link new re to node.*/
if (IS_ZEBRA_DEBUG_RIB) {
rnode_debug(rn, re->vrf_id,
- "Inserting route rn %p, re %p (%s) existing %p",
- rn, re, zebra_route_string(re->type), same);
+ "Inserting route rn %p, re %p (%s) existing %p, same_count %d",
+ rn, re, zebra_route_string(re->type), same,
+ same_count);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
route_entry_dump(p, src_p, re);
@@ -3042,6 +3099,24 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
if (same)
rib_delnode(rn, same);
+ /* See if we can remove some RE entries that are queued for
+ * removal, but won't be considered in rib processing.
+ */
+ dest = rib_dest_from_rnode(rn);
+ RNODE_FOREACH_RE_SAFE (rn, re, same) {
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
+ /* If the route was used earlier, must retain it. */
+ if (dest && re == dest->selected_fib)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_RIB)
+ rnode_debug(rn, re->vrf_id, "rn %p, removing unneeded re %p",
+ rn, re);
+
+ rib_unlink(rn, re);
+ }
+ }
+
route_unlock_node(rn);
return ret;
}