diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 03:03:58 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 03:03:58 +0200 |
commit | 16fc1eec45d247656a86329c1d27aafb535619ae (patch) | |
tree | 8b65b8d44449d094ff0d20ec56cf2afc2acb3962 | |
parent | Install aggregate routes we create in the RIB (diff) | |
download | frr-16fc1eec45d247656a86329c1d27aafb535619ae.tar.xz frr-16fc1eec45d247656a86329c1d27aafb535619ae.zip |
Add a no-as-set option to multipath-relax
-rw-r--r-- | bgpd/bgp_mpath.c | 105 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 42 | ||||
-rw-r--r-- | bgpd/bgpd.c | 8 | ||||
-rw-r--r-- | bgpd/bgpd.h | 1 |
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]; |