]> git.puffer.fish Git - mirror/frr.git/commitdiff
eigrpd: Diverse Fixes 526/head
authorRenato Westphal <renatowestphal@gmail.com>
Thu, 27 Apr 2017 17:55:23 +0000 (14:55 -0300)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Sat, 13 May 2017 17:08:00 +0000 (13:08 -0400)
* Correct the metric calculation as well as the default metrics;
* Do not show invalid routes in the "show ip eigrp topology".
* Add support to VRFs;
* When downloading a neighbor remove the related routes;
* Fix bugs in the parser of packages they were creating
Invalid default routes;
* Add and remove routes in the zebra;
* Add command "on router eigrp AS";
* Make "delay" and "bandwitch" commands work as well as
Display them in running config;
* Add "no" version of several commands;
* Fix a serious momory leaks;
* Fix segfault when there is no 'successor' route to a
Given prefix;
* Other minor corrections;

Signed-off-by: Renato Westphal <renatowestphal@gmail.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
eigrpd/eigrp_const.h
eigrpd/eigrp_dump.c
eigrpd/eigrp_dump.h
eigrpd/eigrp_neighbor.c
eigrpd/eigrp_network.c
eigrpd/eigrp_topology.c
eigrpd/eigrp_vty.c
eigrpd/eigrpd.c
eigrpd/eigrpd.h

index 9397717bef2353e0d492cc7fac261c65a0e71286..13eba207e20e1a293c5168e3bb3435e5e514a626 100644 (file)
@@ -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
 
 
 #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
index 21bef48ecb42ff4597de2b14fbac6ab29e52e892..97ef37d8a9a2ced22375da2fe59f5b0004ccd7a2 100644 (file)
@@ -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);
index 54e6338a33d447102f56dc62883c64149ecc6d97..bbc0d306d9cbe30cf196482439ebc0fba709df8c 100644 (file)
@@ -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);
 
index 003d3a7a7cda69f841baddbe5eb89f0f7e79997e..dfea5258f51ddd44e47329fb3ae6ae9f26f002ea 100644 (file)
@@ -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);
index dff7f2727798e77d9d22158edcf9796817d3a610..b8f21f1e86d930109319098e0eada997f16dea1d 100644 (file)
@@ -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;
 
index 4fcbef7f147d6fe38895d1c6fa49e6b8a2672850..cab56c19dbdf2fd3e33d2bdca21500cb019310e4 100644 (file)
@@ -218,14 +218,16 @@ eigrp_neighbor_entry_add(struct eigrp_prefix_entry *node,
 {
   struct list *l = list_new ();
 
+  listnode_add (l, entry);
+
   if (listnode_lookup (node->entries, entry) == NULL)
     {
       listnode_add_sort (node->entries, entry);
       entry->prefix = node;
+
+      eigrp_zebra_route_add (node->destination_ipv4, l);
     }
 
-  listnode_add (l, entry);
-  eigrp_zebra_route_add (node->destination_ipv4, l);
   list_delete (l);
 }
 
@@ -250,10 +252,9 @@ eigrp_prefix_entry_delete(struct list *topology,
       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);
     }
-
-  eigrp_zebra_route_delete (node->destination_ipv4);
 }
 
 /*
@@ -266,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);
     }
 }
index cc346405a57246ff6ba9c50f4d1dd93f2498bec4..c3413992cd771c2cabadaf1557f7afc061940980 100644 (file)
@@ -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;
+
+  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 write;
+  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);
 
 }
index c6af8986b7b6295e69232a7944e5ad96fa8a19bf..6c0033481dc2024f29f044cbbd3db0e4286c1823 100644 (file)
@@ -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 *);
@@ -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);
index 61d4ba752acd5b348dd7e60df5bdaeccf050d179..901d413c0cb02b1c41ddb935fcca0da02bdd4dc9 100644 (file)
@@ -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);