diff options
| -rw-r--r-- | eigrpd/eigrp_const.h | 5 | ||||
| -rw-r--r-- | eigrpd/eigrp_fsm.c | 67 | ||||
| -rw-r--r-- | eigrpd/eigrp_topology.c | 32 | ||||
| -rw-r--r-- | eigrpd/eigrp_topology.h | 2 | ||||
| -rw-r--r-- | ospfd/ospf_spf.c | 6 | ||||
| -rw-r--r-- | pimd/pim_bfd.c | 42 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 23 | ||||
| -rw-r--r-- | pimd/pim_ifchannel.c | 3 | ||||
| -rw-r--r-- | tests/lib/cli/test_cli.c | 2 | ||||
| -rw-r--r-- | tests/ospf6d/test_lsdb.c | 2 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 7 |
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); } |
