From 165b5fff9dde5536d9cb1f850b36c17bf5654f0f Mon Sep 17 00:00:00 2001 From: Josh Bailey Date: Wed, 20 Jul 2011 20:43:22 -0700 Subject: 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 --- bgpd/Makefile.am | 4 +- bgpd/bgp_mpath.c | 83 +++++++++++++++++++++++++++++ bgpd/bgp_mpath.h | 34 ++++++++++++ bgpd/bgp_vty.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ bgpd/bgp_zebra.h | 2 + bgpd/bgpd.c | 9 ++++ bgpd/bgpd.h | 6 +++ 7 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 bgpd/bgp_mpath.c create mode 100644 bgpd/bgp_mpath.h (limited to 'bgpd') diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am index 1b17d386..3051555b 100644 --- a/bgpd/Makefile.am +++ b/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@ diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c new file mode 100644 index 00000000..56c703f6 --- /dev/null +++ b/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 + +#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; +} diff --git a/bgpd/bgp_mpath.h b/bgpd/bgp_mpath.h new file mode 100644 index 00000000..f0ac8367 --- /dev/null +++ b/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 */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index e7e7dba1..2c44efc2 100644 --- a/bgpd/bgp_vty.c +++ b/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); diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index bd953864..5172cb8a 100644 --- a/bgpd/bgp_zebra.h +++ b/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 *); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index ee0cc5da..e86fca34 100644 --- a/bgpd/bgpd.c +++ b/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); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 4da19e71..bd03f653 100644 --- a/bgpd/bgpd.h +++ b/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. */ -- cgit v1.2.1