diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h index 9397717bef..13eba207e2 100644 --- a/eigrpd/eigrp_const.h +++ b/eigrpd/eigrp_const.h @@ -89,8 +89,8 @@ #define EIGRP_HELLO_INTERVAL_DEFAULT 5 #define EIGRP_HOLD_INTERVAL_DEFAULT 15 -#define EIGRP_BANDWIDTH_DEFAULT 10000000 -#define EIGRP_DELAY_DEFAULT 1000 +#define EIGRP_BANDWIDTH_DEFAULT 100000 +#define EIGRP_DELAY_DEFAULT 10 #define EIGRP_RELIABILITY_DEFAULT 255 #define EIGRP_LOAD_DEFAULT 1 @@ -103,6 +103,7 @@ #define INTERFACE_DOWN_BY_ZEBRA 1 #define INTERFACE_DOWN_BY_VTY 2 +#define INTERFACE_DOWN_BY_FINAL 3 #define EIGRP_HELLO_NORMAL 0x00 #define EIGRP_HELLO_GRACEFUL_SHUTDOWN 0x01 diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 21bef48ecb..97ef37d8a9 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -317,8 +317,18 @@ show_ip_eigrp_prefix_entry (struct vty *vty, struct eigrp_prefix_entry *tn) } void -show_ip_eigrp_neighbor_entry (struct vty *vty, struct eigrp *eigrp, struct eigrp_neighbor_entry *te) +show_ip_eigrp_neighbor_entry (struct vty *vty, struct eigrp *eigrp, + struct eigrp_neighbor_entry *te, int *first) { + if (te->reported_distance == EIGRP_MAX_METRIC) + return; + + if (*first) + { + show_ip_eigrp_prefix_entry (vty, te->prefix); + *first = 0; + } + if (te->adv_router == eigrp->neighbor_self) vty_out (vty, "%-7s%s, %s%s", " ", "via Connected", eigrp_if_name_string (te->ei), VTY_NEWLINE); diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h index 54e6338a33..bbc0d306d9 100644 --- a/eigrpd/eigrp_dump.h +++ b/eigrpd/eigrp_dump.h @@ -158,7 +158,7 @@ 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_neighbor_entry (struct vty *, struct eigrp *, struct eigrp_neighbor_entry *); +extern void show_ip_eigrp_neighbor_entry (struct vty *, struct eigrp *, struct eigrp_neighbor_entry *, int *); extern void eigrp_debug_init (void); diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index f200351c10..dfea5258f5 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -187,7 +187,8 @@ void eigrp_nbr_delete (struct eigrp_neighbor *nbr) { eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN); - eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr); + if (nbr->ei) + eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr); /* Cancel all events. *//* Thread lookup cost would be negligible. */ thread_cancel_event (master, nbr); @@ -195,7 +196,8 @@ eigrp_nbr_delete (struct eigrp_neighbor *nbr) eigrp_fifo_free (nbr->retrans_queue); THREAD_OFF (nbr->t_holddown); - listnode_delete (nbr->ei->nbrs,nbr); + if (nbr->ei) + listnode_delete (nbr->ei->nbrs,nbr); XFREE (MTYPE_EIGRP_NEIGHBOR, nbr); } diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index dff7f27277..b8f21f1e86 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -425,11 +425,11 @@ eigrp_calculate_total_metrics(struct eigrp *eigrp, { entry->total_metric = entry->reported_metric; uint64_t temp_delay = (uint64_t) entry->total_metric.delay - + (uint64_t) EIGRP_IF_PARAM (entry->ei, delay); + + (uint64_t) eigrp_delay_to_scaled (EIGRP_IF_PARAM (entry->ei, delay)); entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC ? EIGRP_MAX_METRIC : (u_int32_t) temp_delay; - u_int32_t bw = EIGRP_IF_PARAM (entry->ei,bandwidth); + u_int32_t bw = eigrp_bandwidth_to_scaled (EIGRP_IF_PARAM (entry->ei,bandwidth)); entry->total_metric.bandwith = entry->total_metric.bandwith > bw ? bw : entry->total_metric.bandwith; diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 25beb63e80..cab56c19db 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -216,11 +216,19 @@ void eigrp_neighbor_entry_add(struct eigrp_prefix_entry *node, struct eigrp_neighbor_entry *entry) { - if (listnode_lookup(node->entries, entry) == NULL) + struct list *l = list_new (); + + listnode_add (l, entry); + + if (listnode_lookup (node->entries, entry) == NULL) { - listnode_add_sort(node->entries, entry); + listnode_add_sort (node->entries, entry); entry->prefix = node; + + eigrp_zebra_route_add (node->destination_ipv4, l); } + + list_delete (l); } /* @@ -236,15 +244,16 @@ eigrp_prefix_entry_delete(struct list *topology, * Emergency removal of the node from this list. * Whatever it is. */ - listnode_delete(eigrp->topology_changes_internalIPV4, node); + listnode_delete (eigrp->topology_changes_internalIPV4, node); - if (listnode_lookup(topology, node) != NULL) + if (listnode_lookup (topology, node) != NULL) { - list_delete_all_node(node->entries); - list_free(node->entries); - list_free(node->rij); - listnode_delete(topology, node); - XFREE(MTYPE_EIGRP_PREFIX_ENTRY,node); + list_delete_all_node (node->entries); + list_free (node->entries); + list_free (node->rij); + listnode_delete (topology, node); + eigrp_zebra_route_delete (node->destination_ipv4); + XFREE (MTYPE_EIGRP_PREFIX_ENTRY,node); } } @@ -258,6 +267,7 @@ eigrp_neighbor_entry_delete(struct eigrp_prefix_entry *node, if (listnode_lookup(node->entries, entry) != NULL) { listnode_delete(node->entries, entry); + eigrp_zebra_route_delete (node->destination_ipv4); XFREE(MTYPE_EIGRP_NEIGHBOR_ENTRY,entry); } } diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index 5c942bd4d5..463f3800fa 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -454,26 +454,6 @@ eigrp_update_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header * pe->req_action |= EIGRP_FSM_NEED_UPDATE; listnode_add(eigrp->topology_changes_internalIPV4, pe); - - /* - * This code is a guess. I am not actually - * sure that we should be doing this here. - * But for the moment it installs routes - * into the rib. Which is good? - */ - struct eigrp_fsm_action_message *msg; - msg = XCALLOC(MTYPE_EIGRP_FSM_MSG, - sizeof(struct eigrp_fsm_action_message)); - - msg->packet_type = EIGRP_OPC_UPDATE; - msg->eigrp = eigrp; - msg->data_type =EIGRP_TLV_IPv4_INT; - msg->adv_router = nbr; - msg->data.ipv4_int_type = tlv; - msg->entry = ne; - msg->prefix = pe; - int event = eigrp_get_fsm_event(msg); - eigrp_fsm_event(msg, event); } eigrp_IPv4_InternalTLV_free (tlv); } diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index cc346405a5..c3413992cd 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -127,9 +127,33 @@ config_write_interfaces (struct vty *vty, struct eigrp *eigrp) static int eigrp_write_interface (struct vty *vty) { - int write=0; + struct listnode *node; + struct interface *ifp; - return write; + for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) { + vty_out (vty, "interface %s%s", ifp->name, + VTY_NEWLINE); + + if (ifp->desc) + vty_out (vty, " description %s%s", ifp->desc, + VTY_NEWLINE); + + if (IF_DEF_PARAMS (ifp)->bandwidth != EIGRP_BANDWIDTH_DEFAULT) + vty_out (vty, " bandwidth %u%s", IF_DEF_PARAMS (ifp)->bandwidth, + VTY_NEWLINE); + if (IF_DEF_PARAMS (ifp)->delay != EIGRP_DELAY_DEFAULT) + vty_out (vty, " delay %u%s", IF_DEF_PARAMS (ifp)->delay, VTY_NEWLINE); + if (IF_DEF_PARAMS (ifp)->v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) + vty_out (vty, " ip hello-interval eigrp %u%s", + IF_DEF_PARAMS (ifp)->v_hello, VTY_NEWLINE); + if (IF_DEF_PARAMS (ifp)->v_wait != EIGRP_HOLD_INTERVAL_DEFAULT) + vty_out (vty, " ip hold-time eigrp %u%s", + IF_DEF_PARAMS (ifp)->v_wait, VTY_NEWLINE); + + vty_out (vty, "!%s", VTY_NEWLINE); + } + + return 0; } /** @@ -206,7 +230,17 @@ DEFUN (no_router_eigrp, { vty->node = CONFIG_NODE; - /*TODO: */ + struct eigrp *eigrp; + + eigrp = eigrp_lookup (); + if (eigrp->AS != atoi (argv[3]->arg)) + { + vty_out (vty, "%% Attempting to deconfigure non-existent AS%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + eigrp_finish_final (eigrp); return CMD_SUCCESS; } @@ -416,43 +450,7 @@ DEFUN (no_eigrp_neighbor, DEFUN (show_ip_eigrp_topology, show_ip_eigrp_topology_cmd, - "show ip eigrp topology", - SHOW_STR - IP_STR - "IP-EIGRP show commands\n" - "IP-EIGRP topology\n") -{ - struct eigrp *eigrp; - struct listnode *node, *nnode, *node2, *nnode2; - struct eigrp_prefix_entry *tn; - struct eigrp_neighbor_entry *te; - - eigrp = eigrp_lookup (); - if (eigrp == NULL) - { - vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } - - show_ip_eigrp_topology_header (vty, eigrp); - - for (ALL_LIST_ELEMENTS (eigrp->topology_table, node, nnode, tn)) - { - show_ip_eigrp_prefix_entry (vty,tn); - for (ALL_LIST_ELEMENTS (tn->entries, node2, nnode2, te)) - { - if (((te->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)|| - ((te->flags & EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG)) - show_ip_eigrp_neighbor_entry (vty, eigrp, te); - } - } - - return CMD_SUCCESS; -} - -DEFUN (show_ip_eigrp_topology_all_links, - show_ip_eigrp_topology_all_links_cmd, - "show ip eigrp topology all-links", + "show ip eigrp topology [all-links]", SHOW_STR IP_STR "IP-EIGRP show commands\n" @@ -460,9 +458,10 @@ DEFUN (show_ip_eigrp_topology_all_links, "Show all links in topology table\n") { struct eigrp *eigrp; - struct listnode *node, *nnode, *node2, *nnode2; + struct listnode *node, *node2; struct eigrp_prefix_entry *tn; struct eigrp_neighbor_entry *te; + int first; eigrp = eigrp_lookup (); if (eigrp == NULL) @@ -473,12 +472,18 @@ DEFUN (show_ip_eigrp_topology_all_links, show_ip_eigrp_topology_header (vty, eigrp); - for (ALL_LIST_ELEMENTS (eigrp->topology_table, node, nnode, tn)) + for (ALL_LIST_ELEMENTS_RO (eigrp->topology_table, node, tn)) { - show_ip_eigrp_prefix_entry (vty,tn); - for (ALL_LIST_ELEMENTS (tn->entries, node2, nnode2, te)) + first = 1; + for (ALL_LIST_ELEMENTS_RO (tn->entries, node2, te)) { - show_ip_eigrp_neighbor_entry (vty, eigrp, te); + if (argc == 5 || + (((te->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)|| + ((te->flags & EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG))) + { + show_ip_eigrp_neighbor_entry (vty, eigrp, te, &first); + first = 0; + } } } @@ -611,6 +616,7 @@ DEFUN (eigrp_if_delay, delay = atoi (argv[1]->arg); IF_DEF_PARAMS (ifp)->delay = delay; + eigrp_if_reset (ifp); return CMD_SUCCESS; } @@ -634,6 +640,7 @@ DEFUN (no_eigrp_if_delay, } IF_DEF_PARAMS (ifp)->delay = EIGRP_DELAY_DEFAULT; + eigrp_if_reset (ifp); return CMD_SUCCESS; } @@ -658,23 +665,20 @@ DEFUN (eigrp_if_bandwidth, bandwidth = atoi (argv[1]->arg); IF_DEF_PARAMS (ifp)->bandwidth = bandwidth; + eigrp_if_reset (ifp); return CMD_SUCCESS; } DEFUN (no_eigrp_if_bandwidth, no_eigrp_if_bandwidth_cmd, - "bandwidth (1-10000000)", + "no bandwidth [(1-10000000)]", + NO_STR "Set bandwidth informational parameter\n" "Bandwidth in kilobits\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - u_int32_t bandwidth; struct eigrp *eigrp; - struct eigrp_interface *ei; - struct listnode *node, *nnode, *node2, *nnode2; - struct eigrp_prefix_entry *pe; - struct eigrp_neighbor_entry *ne; eigrp = eigrp_lookup (); if (eigrp == NULL) @@ -683,25 +687,8 @@ DEFUN (no_eigrp_if_bandwidth, return CMD_SUCCESS; } - bandwidth = atoi (argv[1]->arg); - - IF_DEF_PARAMS (ifp)->bandwidth = bandwidth; - - for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei)) - { - if (ei->ifp == ifp) - break; - } - - for (ALL_LIST_ELEMENTS (eigrp->topology_table, node, nnode, pe)) - { - for (ALL_LIST_ELEMENTS (pe->entries, node2, nnode2, ne)) - { - if (ne->ei == ei) - break; - /*TODO: */ - } - } + IF_DEF_PARAMS (ifp)->bandwidth = EIGRP_BANDWIDTH_DEFAULT; + eigrp_if_reset (ifp); return CMD_SUCCESS; } @@ -734,7 +721,7 @@ DEFUN (eigrp_if_ip_hellointerval, DEFUN (no_eigrp_if_ip_hellointerval, no_eigrp_if_ip_hellointerval_cmd, - "no ip hello-interval eigrp (1-65535)", + "no ip hello-interval eigrp [(1-65535)]", NO_STR "Interface Internet Protocol config commands\n" "Configures EIGRP hello interval\n" @@ -743,6 +730,8 @@ DEFUN (no_eigrp_if_ip_hellointerval, { VTY_DECLVAR_CONTEXT(interface, ifp); struct eigrp *eigrp; + struct eigrp_interface *ei; + struct listnode *node, *nnode; eigrp = eigrp_lookup (); if (eigrp == NULL) @@ -753,6 +742,16 @@ DEFUN (no_eigrp_if_ip_hellointerval, IF_DEF_PARAMS (ifp)->v_hello = EIGRP_HELLO_INTERVAL_DEFAULT; + for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei)) + { + if (ei->ifp == ifp) + { + THREAD_TIMER_OFF (ei->t_hello); + thread_add_timer (master, eigrp_hello_timer, ei, 1, &ei->t_hello); + break; + } + } + return CMD_SUCCESS; } @@ -760,7 +759,7 @@ DEFUN (eigrp_if_ip_holdinterval, eigrp_if_ip_holdinterval_cmd, "ip hold-time eigrp (1-65535)", "Interface Internet Protocol config commands\n" - "Configures EIGRP hello interval\n" + "Configures EIGRP IPv4 hold time\n" "Enhanced Interior Gateway Routing Protocol (EIGRP)\n" "Seconds before neighbor is considered down\n") { @@ -837,8 +836,6 @@ DEFUN (no_eigrp_ip_summary_address, return CMD_SUCCESS; } - - DEFUN (no_eigrp_if_ip_holdinterval, no_eigrp_if_ip_holdinterval_cmd, "no ip hold-time eigrp", @@ -1014,7 +1011,7 @@ DEFUN (no_eigrp_authentication_keychain, DEFUN (eigrp_redistribute_source_metric, eigrp_redistribute_source_metric_cmd, "redistribute " FRR_REDIST_STR_EIGRPD - " metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)", + " [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]", REDIST_STR FRR_REDIST_HELP_STR_EIGRPD "Metric for redistributed routes\n" @@ -1482,8 +1479,6 @@ eigrp_vty_show_init (void) install_element (VIEW_NODE, &show_ip_eigrp_topology_cmd); - install_element (VIEW_NODE, &show_ip_eigrp_topology_all_links_cmd); - install_element (VIEW_NODE, &show_ip_eigrp_topology_detail_cmd); } diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 627d564a78..befb39dba1 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -444,8 +444,13 @@ eigrp_zebra_route_add (struct prefix_ipv4 *p, struct list *successors) /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO (successors, node, te)) { - stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr (s, &te->adv_router->src); + if (te->adv_router->src.s_addr) + { + stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr (s, &te->adv_router->src); + } + else + stream_putc (s, NEXTHOP_TYPE_IFINDEX); stream_putl (s, te->ei->ifp->ifindex); } diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 40885c8a46..6c0033481d 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -61,7 +61,6 @@ static struct eigrp_master eigrp_master; struct eigrp_master *eigrp_om; -static void eigrp_finish_final(struct eigrp *); static void eigrp_delete(struct eigrp *); static struct eigrp *eigrp_new(const char *); static void eigrp_add(struct eigrp *); @@ -188,7 +187,7 @@ eigrp_new (const char *AS) eigrp->topology_table = eigrp_topology_new(); eigrp->neighbor_self = eigrp_nbr_new(NULL); - inet_aton("127.0.0.1", &eigrp->neighbor_self->src); + inet_aton("0.0.0.0", &eigrp->neighbor_self->src); eigrp->variance = EIGRP_VARIANCE_DEFAULT; eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT; @@ -262,26 +261,39 @@ eigrp_terminate (void) void eigrp_finish (struct eigrp *eigrp) { - eigrp_finish_final(eigrp); /* eigrp being shut-down? If so, was this the last eigrp instance? */ if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN) && (listcount(eigrp_om->eigrp) == 0)) - exit(0); + { + if (zclient) + zclient_free (zclient); + + exit(0); + } return; } /* Final cleanup of eigrp instance */ -static void +void eigrp_finish_final (struct eigrp *eigrp) { + struct eigrp_interface *ei; + struct eigrp_neighbor *nbr; + struct listnode *node, *nnode, *node2, *nnode2; - close(eigrp->fd); + for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei)) + { + for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr)) + eigrp_nbr_delete (nbr); + eigrp_if_free (ei, INTERFACE_DOWN_BY_FINAL); + } - if (zclient) - zclient_free(zclient); + THREAD_OFF (eigrp->t_write); + THREAD_OFF (eigrp->t_read); + close (eigrp->fd); list_delete(eigrp->eiflist); list_delete(eigrp->oi_write_q); diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h index 61d4ba752a..901d413c0c 100644 --- a/eigrpd/eigrpd.h +++ b/eigrpd/eigrpd.h @@ -46,6 +46,7 @@ extern struct eigrp_master *eigrp_om; /* 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 struct eigrp *eigrp_get (const char *); extern struct eigrp *eigrp_lookup (void); diff --git a/lib/command.c b/lib/command.c index 03092ed184..2b8eee8de3 100644 --- a/lib/command.c +++ b/lib/command.c @@ -2117,16 +2117,8 @@ DEFUN (config_terminal_length, "Number of lines on screen (0 for no pausing)\n") { int idx_number = 2; - int lines; - char *endptr = NULL; - lines = strtol (argv[idx_number]->arg, &endptr, 10); - if (lines < 0 || lines > 512 || *endptr != '\0') - { - vty_out (vty, "length is malformed%s", VTY_NEWLINE); - return CMD_WARNING; - } - vty->lines = lines; + vty->lines = atoi (argv[idx_number]->arg); return CMD_SUCCESS; } @@ -2150,16 +2142,8 @@ DEFUN (service_terminal_length, "Number of lines of VTY (0 means no line control)\n") { int idx_number = 2; - int lines; - char *endptr = NULL; - lines = strtol (argv[idx_number]->arg, &endptr, 10); - if (lines < 0 || lines > 512 || *endptr != '\0') - { - vty_out (vty, "length is malformed%s", VTY_NEWLINE); - return CMD_WARNING; - } - host.lines = lines; + host.lines = atoi (argv[idx_number]->arg); return CMD_SUCCESS; }