summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eigrpd/eigrp_const.h5
-rw-r--r--eigrpd/eigrp_fsm.c67
-rw-r--r--eigrpd/eigrp_topology.c32
-rw-r--r--eigrpd/eigrp_topology.h2
-rw-r--r--ospfd/ospf_spf.c6
-rw-r--r--pimd/pim_bfd.c42
-rw-r--r--pimd/pim_cmd.c23
-rw-r--r--pimd/pim_ifchannel.c3
-rw-r--r--tests/lib/cli/test_cli.c2
-rw-r--r--tests/ospf6d/test_lsdb.c2
-rw-r--r--vtysh/vtysh.c7
11 files changed, 111 insertions, 80 deletions
diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h
index a6282665e4..a008891a51 100644
--- a/eigrpd/eigrp_const.h
+++ b/eigrpd/eigrp_const.h
@@ -94,6 +94,11 @@
#define EIGRP_MULTICAST_ADDRESS 0xe000000A /*224.0.0.10*/
#define EIGRP_MAX_METRIC 0xffffffffU /*4294967295*/
+enum metric_change {
+ METRIC_DECREASE,
+ METRIC_SAME,
+ METRIC_INCREASE
+};
#define DEFAULT_ROUTE ZEBRA_ROUTE_MAX
#define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE)
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c
index 852362e192..8e2a26447e 100644
--- a/eigrpd/eigrp_fsm.c
+++ b/eigrpd/eigrp_fsm.c
@@ -185,6 +185,7 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
struct eigrp_prefix_entry *prefix = msg->prefix;
struct eigrp_neighbor_entry *entry = msg->entry;
u_char actual_state = prefix->state;
+ enum metric_change change;
if (entry == NULL) {
entry = eigrp_neighbor_entry_new();
@@ -194,19 +195,18 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
msg->entry = entry;
}
- // Dividing by actual state of prefix's FSM
+ /*
+ * Calculate resultant metrics and insert to correct position
+ * in entries list
+ */
+ change = eigrp_topology_update_distance(msg);
+
switch (actual_state) {
case EIGRP_FSM_STATE_PASSIVE: {
- // Calculate resultant metrics and insert to correct position in
- // entries list
- eigrp_topology_update_distance(msg);
-
struct eigrp_neighbor_entry *head =
(struct eigrp_neighbor_entry *)
entry->prefix->entries->head->data;
- // zlog_info ("flag: %d rdist: %u dist: %u pfdist: %u pdist:
- // %u", head->flags, head->reported_distance, head->distance,
- // prefix->fdistance, prefix->distance);
+
if (head->reported_distance < prefix->fdistance) {
return EIGRP_FSM_KEEP_STATE;
}
@@ -215,34 +215,31 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
* move to active state
* dependently if it was query from successor
*/
- else {
- if (msg->packet_type == EIGRP_OPC_QUERY) {
- return EIGRP_FSM_EVENT_Q_FCN;
- } else {
- return EIGRP_FSM_EVENT_NQ_FCN;
- }
+ if (msg->packet_type == EIGRP_OPC_QUERY) {
+ return EIGRP_FSM_EVENT_Q_FCN;
+ } else {
+ return EIGRP_FSM_EVENT_NQ_FCN;
}
break;
}
case EIGRP_FSM_STATE_ACTIVE_0: {
- eigrp_topology_update_distance(msg);
-
if (msg->packet_type == EIGRP_OPC_REPLY) {
+ struct eigrp_neighbor_entry *head =
+ (struct eigrp_neighbor_entry *)
+ entry->prefix->entries->head->data;
+
listnode_delete(prefix->rij, entry->adv_router);
- if (prefix->rij->count) {
+ if (prefix->rij->count)
return EIGRP_FSM_KEEP_STATE;
- } else {
- zlog_info("All reply received\n");
- if (((struct eigrp_neighbor_entry *)
- prefix->entries->head->data)
- ->reported_distance
- < prefix->fdistance) {
- return EIGRP_FSM_EVENT_LR_FCS;
- }
- return EIGRP_FSM_EVENT_LR_FCN;
+ zlog_info("All reply received\n");
+ if (head->reported_distance
+ < prefix->fdistance) {
+ return EIGRP_FSM_EVENT_LR_FCS;
}
+
+ return EIGRP_FSM_EVENT_LR_FCN;
} else if (msg->packet_type == EIGRP_OPC_QUERY
&& (entry->flags
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
@@ -254,15 +251,13 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
break;
}
case EIGRP_FSM_STATE_ACTIVE_1: {
- int change = eigrp_topology_update_distance(msg);
-
if (msg->packet_type == EIGRP_OPC_QUERY
&& (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_QACT;
} else if (msg->packet_type == EIGRP_OPC_REPLY) {
listnode_delete(prefix->rij, entry->adv_router);
- if (change == 1
+ if (change == METRIC_INCREASE
&& (entry->flags
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
@@ -282,17 +277,17 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
break;
}
case EIGRP_FSM_STATE_ACTIVE_2: {
- eigrp_topology_update_distance(msg);
-
if (msg->packet_type == EIGRP_OPC_REPLY) {
+ struct eigrp_neighbor_entry *head =
+ (struct eigrp_neighbor_entry *)
+ prefix->entries->head->data;
+
listnode_delete(prefix->rij, entry->adv_router);
if (prefix->rij->count) {
return EIGRP_FSM_KEEP_STATE;
} else {
zlog_info("All reply received\n");
- if (((struct eigrp_neighbor_entry *)
- prefix->entries->head->data)
- ->reported_distance
+ if (head->reported_distance
< prefix->fdistance) {
return EIGRP_FSM_EVENT_LR_FCS;
}
@@ -305,12 +300,10 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
break;
}
case EIGRP_FSM_STATE_ACTIVE_3: {
- int change = eigrp_topology_update_distance(msg);
-
if (msg->packet_type == EIGRP_OPC_REPLY) {
listnode_delete(prefix->rij, entry->adv_router);
- if (change == 1
+ if (change == METRIC_INCREASE
&& (entry->flags
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
index ae1396ebaf..50d83430a8 100644
--- a/eigrpd/eigrp_topology.c
+++ b/eigrpd/eigrp_topology.c
@@ -374,42 +374,42 @@ struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
return prefixes;
}
-int eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg)
+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_neighbor_entry *entry = msg->entry;
- int change = 0;
+ enum metric_change change = METRIC_SAME;
assert(entry);
struct TLV_IPv4_External_type *ext_data = NULL;
struct TLV_IPv4_Internal_type *int_data = NULL;
if (msg->data_type == EIGRP_TLV_IPv4_INT) {
+ u_int32_t new_reported_distance;
+
int_data = msg->data.ipv4_int_type;
if (eigrp_metrics_is_same(int_data->metric,
entry->reported_metric)) {
- return 0; // No change
+ return change; // No change
}
- change = entry->reported_distance
- < eigrp_calculate_metrics(
- eigrp, int_data->metric)
- ? 1
- : entry->reported_distance
- > eigrp_calculate_metrics(
- eigrp,
- int_data->metric)
- ? 2
- : 3; // Increase : Decrease : No
- // change
+
+ new_reported_distance = eigrp_calculate_metrics(eigrp,
+ int_data->metric);
+
+ if (entry->reported_distance < new_reported_distance)
+ change = METRIC_INCREASE;
+ else
+ change = METRIC_DECREASE;
+
entry->reported_metric = int_data->metric;
- entry->reported_distance =
+ entry->reported_distance = new_reported_distance;
eigrp_calculate_metrics(eigrp, int_data->metric);
entry->distance = eigrp_calculate_total_metrics(eigrp, entry);
} else {
ext_data = msg->data.ipv4_ext_data;
if (eigrp_metrics_is_same(ext_data->metric,
entry->reported_metric))
- return 0;
+ return change;
}
/*
* Move to correct position in list according to new distance
diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h
index 1340c82101..0c9b5c60c6 100644
--- a/eigrpd/eigrp_topology.h
+++ b/eigrpd/eigrp_topology.h
@@ -60,7 +60,7 @@ extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *,
struct eigrp_neighbor *);
extern void eigrp_topology_update_all_node_flags(struct eigrp *);
extern void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *);
-extern int eigrp_topology_update_distance(struct eigrp_fsm_action_message *);
+extern enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *);
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
extern void eigrp_topology_neighbor_down(struct eigrp *,
struct eigrp_neighbor *);
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 7437d26da3..891088ecc2 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -136,8 +136,10 @@ static void ospf_canonical_nexthops_free(struct vertex *root)
/* Free child nexthops pointing back to this root vertex */
for (ALL_LIST_ELEMENTS(child->parents, n2, nn2, vp))
- if (vp->parent == root && vp->nexthop)
+ if (vp->parent == root && vp->nexthop) {
vertex_nexthop_free(vp->nexthop);
+ vp->nexthop = NULL;
+ }
}
}
@@ -401,8 +403,6 @@ static void ospf_spf_flush_parents(struct vertex *w)
/* delete the existing nexthops */
for (ALL_LIST_ELEMENTS(w->parents, ln, nn, vp)) {
list_delete_node(w->parents, ln);
- if (vp->nexthop)
- vertex_nexthop_free(vp->nexthop);
vertex_parent_free(vp);
}
}
diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c
index 1dfb558f46..bba26662bd 100644
--- a/pimd/pim_bfd.c
+++ b/pimd/pim_bfd.c
@@ -295,31 +295,39 @@ static int pim_bfd_nbr_replay(int command, struct zclient *zclient,
struct listnode *node;
struct listnode *neigh_node;
struct listnode *neigh_nextnode;
+ struct vrf *vrf = NULL;
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
- pim_ifp = ifp->info;
+ RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf->vrf_id), node, ifp)) {
+ pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
+ if (!pim_ifp)
+ continue;
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node,
- neigh_nextnode, neigh)) {
- if (!neigh->bfd_info)
+ if (pim_ifp->pim_sock_fd < 0)
continue;
- if (PIM_DEBUG_PIM_TRACE) {
- char str[INET_ADDRSTRLEN];
- pim_inet4_dump("<bfd_nbr?>", neigh->source_addr,
- str, sizeof(str));
- zlog_debug("%s: Replaying Pim Neigh %s to BFD",
- __PRETTY_FUNCTION__, str);
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list,
+ neigh_node, neigh_nextnode,
+ neigh)) {
+ if (!neigh->bfd_info)
+ continue;
+ if (PIM_DEBUG_PIM_TRACE) {
+ char str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<bfd_nbr?>",
+ neigh->source_addr,
+ str, sizeof(str));
+ zlog_debug("%s: Replaying Pim Neigh %s to BFD vrf_id %u",
+ __PRETTY_FUNCTION__, str,
+ vrf->vrf_id);
+ }
+ pim_bfd_reg_dereg_nbr(neigh,
+ ZEBRA_BFD_DEST_UPDATE);
}
- pim_bfd_reg_dereg_nbr(neigh, ZEBRA_BFD_DEST_UPDATE);
}
}
return 0;
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index b65eeaba01..db24aef423 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -7329,8 +7329,14 @@ DEFUN (ip_pim_bfd,
struct pim_interface *pim_ifp = ifp->info;
struct bfd_info *bfd_info = NULL;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp) {
+ if (!pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM on interface\n");
+ return CMD_WARNING;
+ }
+ }
+ pim_ifp = ifp->info;
+
bfd_info = pim_ifp->bfd_info;
if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
@@ -7351,8 +7357,10 @@ DEFUN (no_ip_pim_bfd,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp) {
+ vty_out(vty, "Pim not enabled on this interface\n");
+ return CMD_WARNING;
+ }
if (pim_ifp->bfd_info) {
pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
@@ -7380,7 +7388,14 @@ DEFUN (ip_pim_bfd_param,
u_int32_t tx_val;
u_int8_t dm_val;
int ret;
+ struct pim_interface *pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ if (!pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM on interface\n");
+ return CMD_WARNING;
+ }
+ }
if ((ret = bfd_validate_param(
vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index c91efbd8b6..39f5f2cc4b 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -553,6 +553,9 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
"%s: could not attach upstream (S,G)=%s on interface %s",
__PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name);
+ if (ch->parent)
+ listnode_delete(ch->parent->sources, ch);
+
pim_ifchannel_remove_children(ch);
if (ch->sources)
list_delete(ch->sources);
diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c
index 8f062d8b5e..4cc15ba23f 100644
--- a/tests/lib/cli/test_cli.c
+++ b/tests/lib/cli/test_cli.c
@@ -41,7 +41,7 @@ DUMMY_DEFUN(cmd13, "alt a X:X::X:X");
DUMMY_DEFUN(cmd14,
"pat g { foo A.B.C.D$foo|foo|bar X:X::X:X$bar| baz } [final]");
-#include "tests/lib/cli/test_cli_clippy.c"
+#include "lib/cli/test_cli_clippy.c"
DEFPY(magic_test, magic_test_cmd,
"magic (0-100) {ipv4net A.B.C.D/M|X:X::X:X$ipv6}",
diff --git a/tests/ospf6d/test_lsdb.c b/tests/ospf6d/test_lsdb.c
index 310c4a7323..633e88e769 100644
--- a/tests/ospf6d/test_lsdb.c
+++ b/tests/ospf6d/test_lsdb.c
@@ -29,7 +29,7 @@
#include "ospf6d/ospf6_lsdb.h"
#include "tests/lib/cli/common_cli.h"
-#include "tests/ospf6d/test_lsdb_clippy.c"
+#include "ospf6d/test_lsdb_clippy.c"
static struct ospf6_lsdb *lsdb;
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 6255726c47..f971c171bc 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -250,6 +250,13 @@ static int vtysh_client_execute(struct vtysh_client *head_client,
static void vtysh_client_config(struct vtysh_client *head_client, char *line)
{
+ /* watchfrr currently doesn't load any config, and has some hardcoded
+ * settings that show up in "show run". skip it here (for now at
+ * least) so we don't get that mangled up in config-write.
+ */
+ if (head_client->flag == VTYSH_WATCHFRR)
+ return;
+
vtysh_client_run_all(head_client, line, 1, NULL,
vtysh_config_parse_line, NULL);
}