]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Add route-map support to ip import-table
authorDon Slice <dslice@cumulusnetworks.com>
Wed, 11 May 2016 15:47:02 +0000 (08:47 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 13 May 2016 00:22:53 +0000 (20:22 -0400)
Added the ability to supply a route-map to the ip import-table command,
which greatly improves filtering between the kernel prefixes in a
non-default table that are imported into the zebra rib.

Ticket:CM-8168
Signed-off-by: Donald Slice
Reviewed By: Donald Sharp

zebra/redistribute.c
zebra/redistribute.h
zebra/redistribute_null.c
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_routemap.c
zebra/zebra_routemap.h
zebra/zebra_vty.c
zebra/zserv.h

index 03310ad3f05be42b73792ce56fe45b4e23d7e01d..4d94ddf62251c461fd7ded51ec2149bea1b08fb6 100644 (file)
@@ -36,6 +36,7 @@
 #include "zebra/zserv.h"
 #include "zebra/zebra_ns.h"
 #include "zebra/zebra_vrf.h"
+#include "zebra/zebra_routemap.h"
 #include "zebra/redistribute.h"
 #include "zebra/debug.h"
 #include "zebra/router-id.h"
@@ -559,52 +560,64 @@ zebra_interface_vrf_update_add (struct interface *ifp, vrf_id_t old_vrf_id)
 }
 
 int
-zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
+zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name)
 {
   struct rib *newrib;
   struct prefix_ipv4 p4;
   struct nexthop *nhop;
   struct in_addr *gate;
+  route_map_result_t ret = RMAP_MATCH;
 
-  if (rn->p.family == AF_INET)
+  if (rmap_name)
+    ret = zebra_import_table_route_map_check (AFI_IP, rib->type, &rn->p, rib->nexthop, rib->vrf_id,
+                                              rib->tag, rmap_name);
+
+  if (ret == RMAP_MATCH)
     {
-      p4.family = AF_INET;
-      p4.prefixlen = rn->p.prefixlen;
-      p4.prefix = rn->p.u.prefix4;
+      if (rn->p.family == AF_INET)
+        {
+          p4.family = AF_INET;
+          p4.prefixlen = rn->p.prefixlen;
+          p4.prefix = rn->p.u.prefix4;
 
-      if (rib->nexthop_num == 1)
-       {
-         nhop = rib->nexthop;
-         if (nhop->type == NEXTHOP_TYPE_IFINDEX)
-           gate = NULL;
-         else
-           gate = &nhop->gate.ipv4;
-
-         rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
-                      gate, &nhop->src.ipv4,
-                      nhop->ifindex, rib->vrf_id, zebrad.rtm_table_default,
-                      rib->metric,
-                      zebra_import_table_distance[AFI_IP][rib->table],
-                      SAFI_UNICAST);
-       }
-      else if (rib->nexthop_num > 1)
-       {
-         newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
-         newrib->type = ZEBRA_ROUTE_TABLE;
-         newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
-         newrib->flags = rib->flags;
-         newrib->metric = rib->metric;
-         newrib->table = zebrad.rtm_table_default;
-         newrib->nexthop_num = 0;
-         newrib->uptime = time(NULL);
-         newrib->instance = rib->table;
-
-         /* Assuming these routes are never recursive */
-         for (nhop = rib->nexthop; nhop; nhop = nhop->next)
-           rib_copy_nexthops(newrib, nhop);
-
-         rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
-       }
+          if (rib->nexthop_num == 1)
+           {
+             nhop = rib->nexthop;
+             if (nhop->type == NEXTHOP_TYPE_IFINDEX)
+               gate = NULL;
+             else
+               gate = &nhop->gate.ipv4;
+
+             rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
+                           gate, &nhop->src.ipv4,
+                          nhop->ifindex, rib->vrf_id, zebrad.rtm_table_default,
+                          rib->metric,
+                          zebra_import_table_distance[AFI_IP][rib->table],
+                          SAFI_UNICAST);
+           }
+          else if (rib->nexthop_num > 1)
+           {
+             newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
+             newrib->type = ZEBRA_ROUTE_TABLE;
+             newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
+             newrib->flags = rib->flags;
+             newrib->metric = rib->metric;
+             newrib->table = zebrad.rtm_table_default;
+             newrib->nexthop_num = 0;
+             newrib->uptime = time(NULL);
+             newrib->instance = rib->table;
+
+             /* Assuming these routes are never recursive */
+             for (nhop = rib->nexthop; nhop; nhop = nhop->next)
+               rib_copy_nexthops(newrib, nhop);
+
+             rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
+           }
+        }
+    }
+  else
+    {
+      zebra_del_import_table_entry (rn, rib);
     }
   /* DD: Add IPv6 code */
   return 0;
@@ -631,7 +644,7 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
 
 /* Assuming no one calls this with the main routing table */
 int
-zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
+zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, const char *rmap_name, int add)
 {
   struct route_table *table;
   struct rib *rib;
@@ -657,6 +670,15 @@ zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
 
   if (add)
     {
+      if (rmap_name)
+        zebra_add_import_table_route_map (afi, rmap_name, table_id);
+      else
+        {
+          rmap_name = zebra_get_import_table_route_map (afi, table_id);
+          if (rmap_name)
+            zebra_del_import_table_route_map (afi, table_id);
+        }
+
       SET_FLAG(zebra_import_table_used[table_id], afi);
       zebra_import_table_distance[afi][table_id] = distance;
     }
@@ -664,6 +686,10 @@ zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
     {
       UNSET_FLAG(zebra_import_table_used[table_id], (u_char)afi);
       zebra_import_table_distance[afi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT;
+
+      rmap_name = zebra_get_import_table_route_map (afi, table_id);
+      if (rmap_name)
+        zebra_del_import_table_route_map (afi, table_id);
     }
 
   for (rn = route_top(table); rn; rn = route_next(rn))
@@ -688,7 +714,7 @@ zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
          ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
        {
          if (add)
-           zebra_add_import_table_entry (rn, rib);
+           zebra_add_import_table_entry (rn, rib, rmap_name);
          else
            zebra_del_import_table_entry (rn, rib);
        }
@@ -703,6 +729,7 @@ zebra_import_table_config (struct vty *vty)
   afi_t afi;
   int write = 0;
   char afi_str[AFI_MAX][6] = {"", "ip", "ipv6"};
+  const char *rmap_name;
 
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
     {
@@ -712,14 +739,19 @@ zebra_import_table_config (struct vty *vty)
            {
              if (zebra_import_table_distance[afi][i] != ZEBRA_TABLE_DISTANCE_DEFAULT)
                {
-                 vty_out(vty, "%s import-table %d distance %d%s", afi_str[afi],
-                         i, zebra_import_table_distance[afi][i], VTY_NEWLINE);
+                 vty_out(vty, "%s import-table %d distance %d", afi_str[afi],
+                         i, zebra_import_table_distance[afi][i]);
                }
              else
                {
-                 vty_out(vty, "%s import-table %d%s", afi_str[afi], i,
-                         VTY_NEWLINE);
+                 vty_out(vty, "%s import-table %d", afi_str[afi], i);
                }
+
+             rmap_name = zebra_get_import_table_route_map (afi, i);
+              if (rmap_name)
+               vty_out(vty, " route-map %s", rmap_name);
+
+             vty_out(vty, "%s", VTY_NEWLINE);
              write = 1;
            }
        }
@@ -727,3 +759,53 @@ zebra_import_table_config (struct vty *vty)
 
   return write;
 }
+
+void
+zebra_import_table_rm_update ()
+{
+  afi_t afi;
+  int i;
+  struct route_table *table;
+  struct rib *rib;
+  struct route_node *rn;
+  const char *rmap_name;
+
+  for (afi = AFI_IP; afi < AFI_MAX; afi++)
+    {
+      for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++)
+       {
+         if (is_zebra_import_table_enabled(afi, i))
+           {
+              rmap_name = zebra_get_import_table_route_map (afi, i);
+              if (!rmap_name)
+                return;
+
+              table = zebra_vrf_other_route_table(afi, i, VRF_DEFAULT);
+              for (rn = route_top(table); rn; rn = route_next(rn))
+                {
+                  /* For each entry in the non-default routing table,
+                   * add the entry in the main table
+                   */
+                  if (!rn->info)
+                    continue;
+
+                  RNODE_FOREACH_RIB (rn, rib)
+                    {
+                      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
+                        continue;
+                      break;
+                    }
+
+                 if (!rib)
+                   continue;
+
+                 if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
+                   ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
+                   zebra_add_import_table_entry (rn, rib, rmap_name);
+                }
+           }
+       }
+    }
+
+  return;
+}
index 702fff43f989332923d2e6b3f4ebbf774d1acee8..5e3cf1bfd3fc2b305d428b69210f1a701129e9bf 100644 (file)
@@ -51,17 +51,20 @@ extern void zebra_interface_address_delete_update (struct interface *,
                                                   struct connected *c);
 extern void zebra_interface_vrf_update_del (struct interface *, vrf_id_t new_vrf_id);
 extern void zebra_interface_vrf_update_add (struct interface *, vrf_id_t old_vrf_id);
+
 extern int zebra_import_table (afi_t afi, u_int32_t table_id,
-                              u_int32_t metric, int add);
+                              u_int32_t distance, const char *rmap_name, int add);
 
 extern int zebra_add_import_table_entry (struct route_node *rn,
-                                        struct rib *rib);
+                                        struct rib *rib, const char *rmap_name);
 extern int zebra_del_import_table_entry (struct route_node *rn,
                                         struct rib *rib);
 extern int is_zebra_import_table_enabled(afi_t, u_int32_t table_id);
 
 extern int zebra_import_table_config(struct vty *);
 
+extern void zebra_import_table_rm_update(void);
+
 extern int is_default (struct prefix *);
 
 #endif /* _ZEBRA_REDISTRIBUTE_H */
index 17248cdf55cd9716077258323a761c03c043c84a..40cb8de18d1680a5c30ef0a64e8d87a2ba1188db 100644 (file)
@@ -65,11 +65,11 @@ void zebra_interface_vrf_update_del (struct interface *a, vrf_id_t new_vrf_id)
 void zebra_interface_vrf_update_add (struct interface *a, vrf_id_t old_vrf_id)
 { return; }
 
-int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t metric,
-                       int add)
+int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance,
+                       const char *rmap_name, int add)
 { return 0; }
 
-int zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
+int zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name)
 { return 0; }
 
 int zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
@@ -80,3 +80,6 @@ int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
 
 int zebra_import_table_config(struct vty *vty)
 { return 0; }
+
+void zebra_import_table_rm_update()
+{ return; }
index 7430532364567541f5d9d44f8453d42df8b44724..e34293d55279fc90c30e7c8fd3f3c6ed76cfbba1 100644 (file)
@@ -43,6 +43,7 @@
 #include "zebra/zserv.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/redistribute.h"
+#include "zebra/zebra_routemap.h"
 #include "zebra/debug.h"
 #include "zebra/zebra_fpm.h"
 #include "zebra/zebra_rnh.h"
@@ -2130,6 +2131,7 @@ rib_link (struct route_node *rn, struct rib *rib, int process)
   rib_dest_t *dest;
   char buf[INET6_ADDRSTRLEN];
   afi_t afi;
+  const char *rmap_name;
 
   assert (rib && rn);
   
@@ -2160,7 +2162,10 @@ rib_link (struct route_node *rn, struct rib *rib, int process)
   afi = (rn->p.family == AF_INET) ? AFI_IP :
     (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
   if (is_zebra_import_table_enabled (afi, rib->table))
-    zebra_add_import_table_entry(rn, rib);
+    {
+      rmap_name = zebra_get_import_table_route_map (afi, rib->table);
+      zebra_add_import_table_entry(rn, rib, rmap_name);
+    }
   else
     if (process)
       rib_queue_add (rn);
index 0d6728d111a552c60a1627a4720bbc1ba48cbed6..8b76ea65c982e78ecb07c227e2f24bfeb2a8e654 100644 (file)
@@ -46,6 +46,7 @@
 #include "zebra/redistribute.h"
 #include "zebra/debug.h"
 #include "zebra/zebra_rnh.h"
+#include "zebra/zebra_routemap.h"
 #include "zebra/interface.h"
 
 static void free_state(vrf_id_t vrf_id, struct rib *rib, struct route_node *rn);
index f083693e4e52a78045a7423c29df056f43988e27..db3e5eaba103ae5c9738d413379e9102b32f0c14 100644 (file)
@@ -32,6 +32,7 @@
 #include "vrf.h"
 
 #include "zebra/zserv.h"
+#include "zebra/redistribute.h"
 #include "zebra/debug.h"
 #include "zebra/zebra_rnh.h"
 #include "zebra/zebra_routemap.h"
@@ -41,6 +42,7 @@ static struct thread *zebra_t_rmap_update = NULL;
 char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];    /* "any" == ZEBRA_ROUTE_MAX */
 /* NH Tracking route map */
 char *nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];      /* "any" == ZEBRA_ROUTE_MAX */
+char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
 
 struct nh_rmap_obj
 {
@@ -1610,6 +1612,7 @@ zebra_route_map_update_timer (struct thread *thread)
     zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing",
                 VRF_DEFAULT);
 
+  zebra_import_table_rm_update ();
   rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
   zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
   zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
@@ -1664,6 +1667,47 @@ zebra_route_map_check (int family, int rib_type, struct prefix *p,
   return (ret);
 }
 
+char *
+zebra_get_import_table_route_map (afi_t afi, uint32_t table)
+{
+  return zebra_import_table_routemap[afi][table];
+}
+
+void
+zebra_add_import_table_route_map (afi_t afi, const char *rmap_name, uint32_t table)
+{
+  zebra_import_table_routemap[afi][table] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap_name);
+}
+
+void
+zebra_del_import_table_route_map (afi_t afi, uint32_t table)
+{
+  XFREE (MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][table]);
+}
+
+route_map_result_t
+zebra_import_table_route_map_check (int family, int rib_type, struct prefix *p,
+                struct nexthop *nexthop, vrf_id_t vrf_id, u_short tag, const char *rmap_name)
+{
+  struct route_map *rmap = NULL;
+  route_map_result_t ret = RMAP_DENYMATCH;
+  struct nh_rmap_obj nh_obj;
+
+  nh_obj.nexthop = nexthop;
+  nh_obj.vrf_id = vrf_id;
+  nh_obj.source_protocol = rib_type;
+  nh_obj.metric = 0;
+  nh_obj.tag = tag;
+
+  if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX)
+    rmap = route_map_lookup_by_name (rmap_name);
+  if (rmap) {
+      ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
+  }
+
+  return (ret);
+}
+
 route_map_result_t
 zebra_nht_route_map_check (int family, int client_proto, struct prefix *p,
                           struct rib * rib, struct nexthop *nexthop)
index 044960128092677d3d09b37ca31b73532c269bc2..5eb3740909d2de117da547ce8cf37383f7cfdae9 100644 (file)
 #define __ZEBRA_ROUTEMAP_H__
 
 extern void zebra_routemap_config_write_protocol(struct vty *vty);
+extern char *zebra_get_import_table_route_map (afi_t afi, uint32_t table);
+extern void zebra_add_import_table_route_map (afi_t afi, const char *rmap_name, uint32_t table);
+extern void zebra_del_import_table_route_map (afi_t afi, uint32_t table);
+
+extern void zebra_route_map_write_delay_timer(struct vty *);
+
+extern route_map_result_t zebra_import_table_route_map_check (int family, int rib_type,
+                                                struct prefix *p,
+                                                struct nexthop *nexthop,
+                                                 vrf_id_t vrf_id,
+                                                 u_short tag,
+                                                 const char *rmap_name);
+extern route_map_result_t zebra_route_map_check (int family, int rib_type,
+                                                struct prefix *p,
+                                                struct nexthop *nexthop,
+                                                 vrf_id_t vrf_id,
+                                                 u_short tag);
+extern route_map_result_t zebra_nht_route_map_check (int family,
+                                                    int client_proto,
+                                                    struct prefix *p,
+                                                    struct rib *,
+                                                    struct nexthop *nexthop);
+
 
 #endif
index 1b5de1dc5d42ad3c51c5b9a641f13ffcb862f701..97cfc16f4837787f9f8dbbab2c74d6d3c66b8853 100644 (file)
@@ -5646,13 +5646,9 @@ DEFUN (ip_zebra_import_table_distance,
       return CMD_WARNING;
     }
 
-  if (is_zebra_import_table_enabled(AFI_IP, table_id))
-    return CMD_SUCCESS;
-
   if (argc > 1)
     VTY_GET_INTEGER_RANGE("distance", distance, argv[1], 1, 255);
-
-  return (zebra_import_table(AFI_IP, table_id, distance, 1));
+  return (zebra_import_table(AFI_IP, table_id, distance, NULL, 1));
 
 }
 
@@ -5663,9 +5659,61 @@ ALIAS (ip_zebra_import_table_distance,
        "import routes from non-main kernel table\n"
        "kernel routing table id\n")
 
+DEFUN (ip_zebra_import_table_distance_routemap,
+       ip_zebra_import_table_distance_routemap_cmd,
+       "ip import-table <1-252> distance <1-255> route-map WORD",
+       IP_STR
+       "import routes from non-main kernel table\n"
+       "kernel routing table id\n"
+       "Distance for imported routes\n"
+       "Default distance value\n"
+       "route-map for filtering\n"
+       "route-map name\n")
+{
+  u_int32_t table_id = 0;
+  int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
+  const char *rmap_name;
+
+  if (argc)
+    VTY_GET_INTEGER("table", table_id, argv[0]);
+
+  if (!is_zebra_valid_kernel_table(table_id))
+    {
+      vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s",
+             table_id, VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (is_zebra_main_routing_table(table_id))
+    {
+      vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
+             table_id, VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if (argc > 2)
+    {
+      VTY_GET_INTEGER_RANGE("distance", distance, argv[1], 1, 255);
+      rmap_name =  XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[2]);
+    }
+  else
+    rmap_name = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
+
+  return (zebra_import_table(AFI_IP, table_id, distance, rmap_name, 1));
+}
+
+ALIAS (ip_zebra_import_table_distance_routemap,
+       ip_zebra_import_table_routemap_cmd,
+       "ip import-table <1-252> route-map WORD",
+       IP_STR
+       "import routes from non-main kernel table\n"
+       "kernel routing table id\n"
+       "route-map for filtering\n"
+       "route-map name\n")
+
 DEFUN (no_ip_zebra_import_table,
        no_ip_zebra_import_table_cmd,
-       "no ip import-table <1-252>",
+       "no ip import-table <1-252> {route-map NAME}",
        NO_STR
        IP_STR
        "import routes from non-main kernel table\n"
@@ -5693,12 +5741,12 @@ DEFUN (no_ip_zebra_import_table,
   if (!is_zebra_import_table_enabled(AFI_IP, table_id))
     return CMD_SUCCESS;
 
-  return (zebra_import_table(AFI_IP, table_id, 0, 0));
+  return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
 }
 
 ALIAS (no_ip_zebra_import_table,
        no_ip_zebra_import_table_distance_cmd,
-       "no ip import-table <1-252> distance <1-255>",
+       "no ip import-table <1-252> distance <1-255> {route-map NAME}",
        IP_STR
        "import routes from non-main kernel table to main table"
        "kernel routing table id\n"
@@ -5786,6 +5834,8 @@ zebra_vty_init (void)
   install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_cmd);
   install_element (CONFIG_NODE, &ip_zebra_import_table_cmd);
   install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
+  install_element (CONFIG_NODE, &ip_zebra_import_table_routemap_cmd);
+  install_element (CONFIG_NODE, &ip_zebra_import_table_distance_routemap_cmd);
   install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
   install_element (CONFIG_NODE, &no_ip_zebra_import_table_distance_cmd);
 
index e055672990b53958db87c4b9ed1d89ff4b93ef66..16700ee52363d346eaeff5b30349fe6bff8e13f2 100644 (file)
@@ -171,16 +171,4 @@ extern void zserv_create_header(struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
 extern void zserv_nexthop_num_warn(const char *, const struct prefix *, const u_char);
 extern int zebra_server_send_message(struct zserv *client);
 
-extern void zebra_route_map_write_delay_timer(struct vty *);
-extern route_map_result_t zebra_route_map_check (int family, int rib_type,
-                                                struct prefix *p,
-                                                struct nexthop *nexthop,
-                                                 vrf_id_t vrf_id,
-                                                 u_short tag);
-extern route_map_result_t zebra_nht_route_map_check (int family,
-                                                    int client_proto,
-                                                    struct prefix *p,
-                                                    struct rib *,
-                                                    struct nexthop *nexthop);
-
 #endif /* _ZEBRA_ZEBRA_H */