Browse Source

bgpd: Add new configuration cli for eBGP and iBGP multipath.
There is support to configure this for each (AFI,SAFI), but
currently this configuration is only present for IPv4 unicast:

maximum-paths [ibgp] <1-255>
no maximum-paths [ibgp] [<1-255>]

* bgpd/Makefile.am
* Add bgp_mpath.h and bgp_mpath.c to build
* bgpd/bgp_mpath.h
* New file for bgp multipath declarations
* define BGP_DEFAULT_MAXPATHS
* bgpd/bgp_mpath.c
* bgp_maximum_paths_set(): Configure maximum paths for the given
afi, safi and bgp instance
* bgp_maximum_paths_unset(): Return maximum paths configuration to
the default setting for the given afi, safi and bgp instance
* bgpd/bgp_vty.c
* Define command strings for above CLI
* bgp_config_write_maxpaths(): Outputs configuration for the given
afi, safi and bgp instance
* Install command elements for IPv4 unicast
* bgpd/bgp_zebra.h
* bgp_config_write_maxpaths(): External declaration
* bgpd/bgpd.c
* bgp_create(): Initialize bgp instance to default maximum paths setting
* bgp_config_write_family(): Output maximum paths configuration
for the given address family
* bgp_config_write(): Output maximum paths configuration for
IPv4 unicast address family
* bgpd/bgpd.h
* struct bgp: Add storage for maximum paths configuration for
each afi, safi

Josh Bailey 8 years ago
parent
commit
165b5fff9d
7 changed files with 294 additions and 2 deletions
  1. 2 2
      bgpd/Makefile.am
  2. 83 0
      bgpd/bgp_mpath.c
  3. 34 0
      bgpd/bgp_mpath.h
  4. 158 0
      bgpd/bgp_vty.c
  5. 2 0
      bgpd/bgp_zebra.h
  6. 9 0
      bgpd/bgpd.c
  7. 6 0
      bgpd/bgpd.h

+ 2 - 2
bgpd/Makefile.am

@@ -15,14 +15,14 @@ libbgp_a_SOURCES = \
 	bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
 	bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
 	bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c bgp_nexthop.c \
-	bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c
+	bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c
 
 noinst_HEADERS = \
 	bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
 	bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
 	bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
 	bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
-	bgp_advertise.h bgp_snmp.h bgp_vty.h
+	bgp_advertise.h bgp_snmp.h bgp_vty.h bgp_mpath.h
 
 bgpd_SOURCES = bgp_main.c
 bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@

+ 83 - 0
bgpd/bgp_mpath.c

@@ -0,0 +1,83 @@
+/* $QuaggaId: Format:%an, %ai, %h$ $
+ *
+ * BGP Multipath
+ * Copyright (C) 2010 Google Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "command.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_mpath.h"
+
+/*
+ * bgp_maximum_paths_set
+ *
+ * Record maximum-paths configuration for BGP instance
+ */
+int
+bgp_maximum_paths_set (struct bgp *bgp, afi_t afi, safi_t safi,
+                       int peertype, u_int16_t maxpaths)
+{
+  if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
+    return -1;
+
+  switch (peertype)
+    {
+    case BGP_PEER_IBGP:
+      bgp->maxpaths[afi][safi].maxpaths_ibgp = maxpaths;
+      break;
+    case BGP_PEER_EBGP:
+      bgp->maxpaths[afi][safi].maxpaths_ebgp = maxpaths;
+      break;
+    default:
+      return -1;
+    }
+
+  return 0;
+}
+
+/*
+ * bgp_maximum_paths_unset
+ *
+ * Remove maximum-paths configuration from BGP instance
+ */
+int
+bgp_maximum_paths_unset (struct bgp *bgp, afi_t afi, safi_t safi,
+                         int peertype)
+{
+  if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
+    return -1;
+
+  switch (peertype)
+    {
+    case BGP_PEER_IBGP:
+      bgp->maxpaths[afi][safi].maxpaths_ibgp = BGP_DEFAULT_MAXPATHS;
+      break;
+    case BGP_PEER_EBGP:
+      bgp->maxpaths[afi][safi].maxpaths_ebgp = BGP_DEFAULT_MAXPATHS;
+      break;
+    default:
+      return -1;
+    }
+
+  return 0;
+}

+ 34 - 0
bgpd/bgp_mpath.h

@@ -0,0 +1,34 @@
+/* $QuaggaId: Format:%an, %ai, %h$ $
+ *
+ * BGP Multipath
+ * Copyright (C) 2010 Google Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _QUAGGA_BGP_MPATH_H
+#define _QUAGGA_BGP_MPATH_H
+
+/* BGP default maximum-paths */
+#define BGP_DEFAULT_MAXPATHS 1
+
+/* Functions to support maximum-paths configuration */
+extern int bgp_maximum_paths_set (struct bgp *, afi_t, safi_t, int, u_int16_t);
+extern int bgp_maximum_paths_unset (struct bgp *, afi_t, safi_t, int);
+
+#endif /* _QUAGGA_BGP_MPATH_H */

+ 158 - 0
bgpd/bgp_vty.c

@@ -48,6 +48,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/bgp_zebra.h"
 #include "bgpd/bgp_table.h"
 #include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_mpath.h"
 
 extern struct in_addr router_id_zebra;
 
@@ -650,6 +651,149 @@ DEFUN (no_bgp_confederation_peers,
   return CMD_SUCCESS;
 }
 
+/* Maximum-paths configuration */
+DEFUN (bgp_maxpaths,
+       bgp_maxpaths_cmd,
+       "maximum-paths <1-255>",
+       "Forward packets over multiple paths\n"
+       "Number of paths\n")
+{
+  struct bgp *bgp;
+  u_int16_t maxpaths;
+  int ret;
+
+  bgp = vty->index;
+
+  VTY_GET_INTEGER_RANGE ("maximum-paths", maxpaths, argv[0], 1, 255);
+
+  ret = bgp_maximum_paths_set (bgp, bgp_node_afi (vty), bgp_node_safi(vty),
+			       BGP_PEER_EBGP, maxpaths);
+  if (ret < 0)
+    {
+      vty_out (vty,
+	       "%% Failed to set maximum-paths %u for afi %u, safi %u%s",
+	       maxpaths, bgp_node_afi (vty), bgp_node_safi(vty), VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (bgp_maxpaths_ibgp,
+       bgp_maxpaths_ibgp_cmd,
+       "maximum-paths ibgp <1-255>",
+       "Forward packets over multiple paths\n"
+       "iBGP-multipath\n"
+       "Number of paths\n")
+{
+  struct bgp *bgp;
+  u_int16_t maxpaths;
+  int ret;
+
+  bgp = vty->index;
+
+  VTY_GET_INTEGER_RANGE ("maximum-paths", maxpaths, argv[0], 1, 255);
+
+  ret = bgp_maximum_paths_set (bgp, bgp_node_afi (vty), bgp_node_safi(vty),
+			       BGP_PEER_IBGP, maxpaths);
+  if (ret < 0)
+    {
+      vty_out (vty,
+	       "%% Failed to set maximum-paths ibgp %u for afi %u, safi %u%s",
+	       maxpaths, bgp_node_afi (vty), bgp_node_safi(vty), VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_maxpaths,
+       no_bgp_maxpaths_cmd,
+       "no maximum-paths",
+       NO_STR
+       "Forward packets over multiple paths\n"
+       "Number of paths\n")
+{
+  struct bgp *bgp;
+  int ret;
+
+  bgp = vty->index;
+
+  ret = bgp_maximum_paths_unset (bgp, bgp_node_afi (vty), bgp_node_safi(vty),
+				 BGP_PEER_EBGP);
+  if (ret < 0)
+    {
+      vty_out (vty,
+	       "%% Failed to unset maximum-paths for afi %u, safi %u%s",
+	       bgp_node_afi (vty), bgp_node_safi(vty), VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return CMD_SUCCESS;
+}
+
+ALIAS (no_bgp_maxpaths,
+       no_bgp_maxpaths_arg_cmd,
+       "no maximum-paths <1-255>",
+       NO_STR
+       "Forward packets over multiple paths\n"
+       "Number of paths\n")
+
+DEFUN (no_bgp_maxpaths_ibgp,
+       no_bgp_maxpaths_ibgp_cmd,
+       "no maximum-paths ibgp",
+       NO_STR
+       "Forward packets over multiple paths\n"
+       "iBGP-multipath\n"
+       "Number of paths\n")
+{
+  struct bgp *bgp;
+  int ret;
+
+  bgp = vty->index;
+
+  ret = bgp_maximum_paths_unset (bgp, bgp_node_afi (vty), bgp_node_safi(vty),
+				 BGP_PEER_IBGP);
+  if (ret < 0)
+    {
+      vty_out (vty,
+	       "%% Failed to unset maximum-paths ibgp for afi %u, safi %u%s",
+	       bgp_node_afi (vty), bgp_node_safi(vty), VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return CMD_SUCCESS;
+}
+
+ALIAS (no_bgp_maxpaths_ibgp,
+       no_bgp_maxpaths_ibgp_arg_cmd,
+       "no maximum-paths ibgp <1-255>",
+       NO_STR
+       "Forward packets over multiple paths\n"
+       "iBGP-multipath\n"
+       "Number of paths\n")
+
+int
+bgp_config_write_maxpaths (struct vty *vty, struct bgp *bgp, afi_t afi,
+			   safi_t safi, int *write)
+{
+  if (bgp->maxpaths[afi][safi].maxpaths_ebgp != BGP_DEFAULT_MAXPATHS)
+    {
+      bgp_config_write_family_header (vty, afi, safi, write);
+      vty_out (vty, " maximum-paths %d%s",
+	       bgp->maxpaths[afi][safi].maxpaths_ebgp, VTY_NEWLINE);
+    }
+
+  if (bgp->maxpaths[afi][safi].maxpaths_ibgp != BGP_DEFAULT_MAXPATHS)
+    {
+      bgp_config_write_family_header (vty, afi, safi, write);
+      vty_out (vty, " maximum-paths ibgp %d%s",
+	       bgp->maxpaths[afi][safi].maxpaths_ibgp, VTY_NEWLINE);
+    }
+
+  return 0;
+}
+
 /* BGP timers.  */
 
 DEFUN (bgp_timers,
@@ -9062,6 +9206,20 @@ bgp_vty_init (void)
   install_element (BGP_NODE, &bgp_confederation_peers_cmd);
   install_element (BGP_NODE, &no_bgp_confederation_peers_cmd);
 
+  /* "maximum-paths" commands. */
+  install_element (BGP_NODE, &bgp_maxpaths_cmd);
+  install_element (BGP_NODE, &no_bgp_maxpaths_cmd);
+  install_element (BGP_NODE, &no_bgp_maxpaths_arg_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_maxpaths_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_arg_cmd);
+  install_element (BGP_NODE, &bgp_maxpaths_ibgp_cmd);
+  install_element (BGP_NODE, &no_bgp_maxpaths_ibgp_cmd);
+  install_element (BGP_NODE, &no_bgp_maxpaths_ibgp_arg_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_maxpaths_ibgp_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_ibgp_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_ibgp_arg_cmd);
+
   /* "timers bgp" commands. */
   install_element (BGP_NODE, &bgp_timers_cmd);
   install_element (BGP_NODE, &no_bgp_timers_cmd);

+ 2 - 0
bgpd/bgp_zebra.h

@@ -23,6 +23,8 @@ Boston, MA 02111-1307, USA.  */
 
 extern void bgp_zebra_init (void);
 extern int bgp_if_update_all (void);
+extern int bgp_config_write_maxpaths (struct vty *, struct bgp *, afi_t,
+				      safi_t, int *);
 extern int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t,
 				   int *);
 extern void bgp_zebra_announce (struct prefix *, struct bgp_info *, struct bgp *);

+ 9 - 0
bgpd/bgpd.c

@@ -57,6 +57,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/bgp_advertise.h"
 #include "bgpd/bgp_network.h"
 #include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_mpath.h"
 #ifdef HAVE_SNMP
 #include "bgpd/bgp_snmp.h"
 #endif /* HAVE_SNMP */
@@ -1947,6 +1948,8 @@ bgp_create (as_t *as, const char *name)
 	bgp->route[afi][safi] = bgp_table_init (afi, safi);
 	bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
 	bgp->rib[afi][safi] = bgp_table_init (afi, safi);
+	bgp->maxpaths[afi][safi].maxpaths_ebgp = BGP_DEFAULT_MAXPATHS;
+	bgp->maxpaths[afi][safi].maxpaths_ibgp = BGP_DEFAULT_MAXPATHS;
       }
 
   bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
@@ -5117,6 +5120,9 @@ bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
 	    }
 	}
     }
+
+  bgp_config_write_maxpaths (vty, bgp, afi, safi, &write);
+
   if (write)
     vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
 
@@ -5290,6 +5296,9 @@ bgp_config_write (struct vty *vty)
 	    bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
 	}
 
+      /* maximum-paths */
+      bgp_config_write_maxpaths (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
+
       /* Distance configuration. */
       bgp_config_write_distance (vty, bgp);
       

+ 6 - 0
bgpd/bgpd.h

@@ -162,6 +162,12 @@ struct bgp
   /* BGP graceful restart */
   u_int32_t restart_time;
   u_int32_t stalepath_time;
+
+  /* Maximum-paths configuration */
+  struct bgp_maxpaths_cfg {
+    u_int16_t maxpaths_ebgp;
+    u_int16_t maxpaths_ibgp;
+  } maxpaths[AFI_MAX][SAFI_MAX];
 };
 
 /* BGP peer-group support. */