From 8bd9d9483f2c1b6110d5d48c8b9fe167bd9d08be Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 19 May 2015 17:40:41 -0700 Subject: [PATCH] bgpd: bgpd-ibgp-policy-out-allow-mods.patch BGPd: Allow route-map policy modifications to also affect route reflectors. By default, attribute modification via route-map policy out is ignored on reflected routes. This patch provides an option to allow this modification to occur. Once enabled, it affects all reflected routes. Signed-off-by: Dinesh G Dutt --- bgpd/bgp_route.c | 4 +-- bgpd/bgp_vty.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ bgpd/bgpd.c | 4 +++ bgpd/bgpd.h | 3 +- doc/bgpd.texi | 6 ++++ 5 files changed, 95 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index baa3087b28..d9936b23c4 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1089,8 +1089,8 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p, /* The route reflector is not allowed to modify the attributes of the reflected IBGP routes. */ - if (from->sort == BGP_PEER_IBGP - && peer->sort == BGP_PEER_IBGP) + if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP) && + !bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { bgp_attr_dup (&dummy_attr, attr); info.attr = &dummy_attr; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 9d7f0ba780..afd5d0c78a 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1586,6 +1586,83 @@ ALIAS (no_bgp_default_local_preference, "local preference (higher=more preferred)\n" "Configure default local preference value\n") +static void +peer_announce_routes_if_rmap_out (struct bgp *bgp) +{ + struct peer *peer; + struct listnode *node, *nnode; + struct bgp_filter *filter; + afi_t afi; + safi_t safi; + + /* Reannounce all routes to appropriate neighbors */ + for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) + { + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) + { + if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)) + { + /* check if there's an out route-map on this client */ + filter = &peer->filter[afi][safi]; + if (ROUTE_MAP_OUT_NAME(filter)) + { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: Announcing routes again for peer %s" + "(afi=%d, safi=%d", __func__, peer->host, afi, + safi); + + bgp_announce_route_all(peer); + } + } + } + } +} + +DEFUN (bgp_rr_allow_outbound_policy, + bgp_rr_allow_outbound_policy_cmd, + "bgp route-reflector allow-outbound-policy", + "BGP specific commands\n" + "Allow modifications made by out route-map\n" + "on ibgp neighbors\n") +{ + struct bgp *bgp; + u_int32_t local_pref; + int ret; + + bgp = vty->index; + + if (!bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) + { + bgp_flag_set(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); + peer_announce_routes_if_rmap_out(bgp); + } + + return CMD_SUCCESS; +} + +DEFUN (no_bgp_rr_allow_outbound_policy, + no_bgp_rr_allow_outbound_policy_cmd, + "no bgp route-reflector allow-outbound-policy", + NO_STR + "BGP specific commands\n" + "Allow modifications made by out route-map\n" + "on ibgp neighbors\n") +{ + struct bgp *bgp; + u_int32_t local_pref; + + bgp = vty->index; + + if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) + { + bgp_flag_unset(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); + peer_announce_routes_if_rmap_out(bgp); + } + + return CMD_SUCCESS; +} + static int peer_remote_as_vty (struct vty *vty, const char *peer_str, const char *as_str, afi_t afi, safi_t safi) @@ -9731,6 +9808,10 @@ bgp_vty_init (void) install_element (BGP_NODE, &no_bgp_default_local_preference_cmd); install_element (BGP_NODE, &no_bgp_default_local_preference_val_cmd); + /* bgp ibgp-allow-policy-mods command */ + install_element (BGP_NODE, &bgp_rr_allow_outbound_policy_cmd); + install_element (BGP_NODE, &no_bgp_rr_allow_outbound_policy_cmd); + /* "neighbor remote-as" commands. */ install_element (BGP_NODE, &neighbor_remote_as_cmd); install_element (BGP_NODE, &neighbor_interface_config_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 128e9d9cd9..1456beda73 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -5675,6 +5675,10 @@ bgp_config_write (struct vty *vty) 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_RR_ALLOW_OUTBOUND_POLICY)) { + vty_out (vty, " bgp route-reflector allow-outbound-policy%s", + VTY_NEWLINE); + } if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)) vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE); if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 752c637ef1..0ebbe2a0eb 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -130,7 +130,7 @@ struct bgp #define BGP_UPDATE_DELAY_MAX 3600 /* BGP flags. */ - u_int16_t flags; + u_int32_t flags; #define BGP_FLAG_ALWAYS_COMPARE_MED (1 << 0) #define BGP_FLAG_DETERMINISTIC_MED (1 << 1) #define BGP_FLAG_MED_MISSING_AS_WORST (1 << 2) @@ -146,6 +146,7 @@ struct bgp #define BGP_FLAG_GRACEFUL_RESTART (1 << 12) #define BGP_FLAG_ASPATH_CONFED (1 << 13) #define BGP_FLAG_ASPATH_MULTIPATH_RELAX (1 << 14) +#define BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY (1 << 15) /* BGP Per AF flags */ u_int16_t af_flags[AFI_MAX][SAFI_MAX]; diff --git a/doc/bgpd.texi b/doc/bgpd.texi index 5dd4ed616d..e0eb971252 100644 --- a/doc/bgpd.texi +++ b/doc/bgpd.texi @@ -430,6 +430,12 @@ Apply a route-map on the neighbor. @var{direct} must be @code{in} or @code{out}. @end deffn +@deffn {BGP} {bgp route-reflector allow-outbound-policy} {} +By default, attribute modification via route-map policy out is not reflected +on reflected routes. This option allows the modifications to be reflected as +well. Once enabled, it affects all reflected routes. +@end deffn + @c ----------------------------------------------------------------------- @node BGP Peer Group @section BGP Peer Group -- 2.39.5