summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:03:58 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:03:58 +0200
commit16fc1eec45d247656a86329c1d27aafb535619ae (patch)
tree8b65b8d44449d094ff0d20ec56cf2afc2acb3962
parentInstall aggregate routes we create in the RIB (diff)
downloadfrr-16fc1eec45d247656a86329c1d27aafb535619ae.tar.xz
frr-16fc1eec45d247656a86329c1d27aafb535619ae.zip
Add a no-as-set option to multipath-relax
-rw-r--r--bgpd/bgp_mpath.c105
-rw-r--r--bgpd/bgp_vty.c42
-rw-r--r--bgpd/bgpd.c8
-rw-r--r--bgpd/bgpd.h1
4 files changed, 105 insertions, 51 deletions
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 2d080a12b..27f39c589 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -660,71 +660,76 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
bgp_attr_dup (&attr, new_best->attr);
- /* aggregate attribute from multipath constituents */
- aspath = aspath_dup (attr.aspath);
- origin = attr.origin;
- community = attr.community ? community_dup (attr.community) : NULL;
- ae = attr.extra;
- ecomm = (ae && ae->ecommunity) ? ecommunity_dup (ae->ecommunity) : NULL;
-
- for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
- mpinfo = bgp_info_mpath_next (mpinfo))
+ if (new_best->peer &&
+ !bgp_flag_check (new_best->peer->bgp, BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET))
{
- asmerge = aspath_aggregate (aspath, mpinfo->attr->aspath);
- aspath_free (aspath);
- aspath = asmerge;
- if (origin < mpinfo->attr->origin)
- origin = mpinfo->attr->origin;
+ /* aggregate attribute from multipath constituents */
+ aspath = aspath_dup (attr.aspath);
+ origin = attr.origin;
+ community = attr.community ? community_dup (attr.community) : NULL;
+ ae = attr.extra;
+ ecomm = (ae && ae->ecommunity) ? ecommunity_dup (ae->ecommunity) : NULL;
- if (mpinfo->attr->community)
+ for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
+ mpinfo = bgp_info_mpath_next (mpinfo))
{
- if (community)
+ asmerge = aspath_aggregate (aspath, mpinfo->attr->aspath);
+ aspath_free (aspath);
+ aspath = asmerge;
+
+ if (origin < mpinfo->attr->origin)
+ origin = mpinfo->attr->origin;
+
+ if (mpinfo->attr->community)
{
- commerge = community_merge (community, mpinfo->attr->community);
- community = community_uniq_sort (commerge);
- community_free (commerge);
+ if (community)
+ {
+ commerge = community_merge (community, mpinfo->attr->community);
+ community = community_uniq_sort (commerge);
+ community_free (commerge);
+ }
+ else
+ community = community_dup (mpinfo->attr->community);
}
- else
- community = community_dup (mpinfo->attr->community);
- }
- ae = mpinfo->attr->extra;
- if (ae && ae->ecommunity)
- {
- if (ecomm)
+ ae = mpinfo->attr->extra;
+ if (ae && ae->ecommunity)
{
- ecommerge = ecommunity_merge (ecomm, ae->ecommunity);
- ecomm = ecommunity_uniq_sort (ecommerge);
- ecommunity_free (&ecommerge);
+ if (ecomm)
+ {
+ ecommerge = ecommunity_merge (ecomm, ae->ecommunity);
+ ecomm = ecommunity_uniq_sort (ecommerge);
+ ecommunity_free (&ecommerge);
+ }
+ else
+ ecomm = ecommunity_dup (ae->ecommunity);
}
- else
- ecomm = ecommunity_dup (ae->ecommunity);
}
- }
- attr.aspath = aspath;
- attr.origin = origin;
- if (community)
- {
- attr.community = community;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
- }
- if (ecomm)
- {
- ae = bgp_attr_extra_get (&attr);
- ae->ecommunity = ecomm;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
- }
+ attr.aspath = aspath;
+ attr.origin = origin;
+ if (community)
+ {
+ attr.community = community;
+ attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
+ }
+ if (ecomm)
+ {
+ ae = bgp_attr_extra_get (&attr);
+ ae->ecommunity = ecomm;
+ attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
+ }
- /* Zap multipath attr nexthop so we set nexthop to self */
- attr.nexthop.s_addr = 0;
+ /* Zap multipath attr nexthop so we set nexthop to self */
+ attr.nexthop.s_addr = 0;
#ifdef HAVE_IPV6
- if (attr.extra)
- memset (&attr.extra->mp_nexthop_global, 0, sizeof (struct in6_addr));
+ if (attr.extra)
+ memset (&attr.extra->mp_nexthop_global, 0, sizeof (struct in6_addr));
#endif /* HAVE_IPV6 */
- /* TODO: should we set ATOMIC_AGGREGATE and AGGREGATOR? */
+ /* TODO: should we set ATOMIC_AGGREGATE and AGGREGATOR? */
+ }
new_attr = bgp_attr_intern (&attr);
bgp_attr_extra_free (&attr);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index e2a5707e0..701996e11 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1588,6 +1588,7 @@ DEFUN (bgp_bestpath_aspath_multipath_relax,
bgp = vty->index;
bgp_flag_set (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+ bgp_flag_unset (bgp, BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET);
return CMD_SUCCESS;
}
@@ -1604,6 +1605,43 @@ DEFUN (no_bgp_bestpath_aspath_multipath_relax,
bgp = vty->index;
bgp_flag_unset (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+ bgp_flag_unset (bgp, BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET);
+ return CMD_SUCCESS;
+}
+
+/* "bgp bestpath as-path multipath-relax no-as-set" configuration. */
+DEFUN (bgp_bestpath_aspath_multipath_relax_no_as_set,
+ bgp_bestpath_aspath_multipath_relax_no_as_set_cmd,
+ "bgp bestpath as-path multipath-relax no-as-set",
+ "BGP specific commands\n"
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Allow load sharing across routes that have different AS paths (but same length)\n"
+ "Do not generate an AS_SET\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+ bgp_flag_set (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+ bgp_flag_set (bgp, BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_bestpath_aspath_multipath_relax_no_as_set,
+ no_bgp_bestpath_aspath_multipath_relax_no_as_set_cmd,
+ "no bgp bestpath as-path multipath-relax no-as-set",
+ NO_STR
+ "BGP specific commands\n"
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Allow load sharing across routes that have different AS paths (but same length)\n"
+ "Do not generate an AS_SET\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+ bgp_flag_unset (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+ bgp_flag_unset (bgp, BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET);
return CMD_SUCCESS;
}
@@ -11419,6 +11457,10 @@ bgp_vty_init (void)
install_element (BGP_NODE, &bgp_bestpath_aspath_multipath_relax_cmd);
install_element (BGP_NODE, &no_bgp_bestpath_aspath_multipath_relax_cmd);
+ /* "bgp bestpath as-path multipath-relax no-as-set" commands */
+ install_element (BGP_NODE, &bgp_bestpath_aspath_multipath_relax_no_as_set_cmd);
+ install_element (BGP_NODE, &no_bgp_bestpath_aspath_multipath_relax_no_as_set_cmd);
+
/* "bgp log-neighbor-changes" commands */
install_element (BGP_NODE, &bgp_log_neighbor_changes_cmd);
install_element (BGP_NODE, &no_bgp_log_neighbor_changes_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index aed6debfc..d1eefc451 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -6366,9 +6366,15 @@ bgp_config_write (struct vty *vty)
vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
+
if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
- vty_out (vty, " bgp bestpath as-path multipath-relax%s", VTY_NEWLINE);
+ if (bgp_flag_check (bgp, BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET)) {
+ vty_out (vty, " bgp bestpath as-path multipath-relax no-as-set%s", VTY_NEWLINE);
+ } else {
+ vty_out (vty, " bgp bestpath as-path multipath-relax%s", VTY_NEWLINE);
+ }
}
+
if (bgp_flag_check (bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
vty_out (vty, " bgp route-reflector allow-outbound-policy%s",
VTY_NEWLINE);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 68e8f10d5..357b8389d 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -238,6 +238,7 @@ struct bgp
#define BGP_FLAG_ASPATH_MULTIPATH_RELAX (1 << 14)
#define BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY (1 << 15)
#define BGP_FLAG_DISABLE_NH_CONNECTED_CHK (1 << 16)
+#define BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET (1 << 17)
/* BGP Per AF flags */
u_int16_t af_flags[AFI_MAX][SAFI_MAX];