bgpd: Add route-map support for set ip next-hop unchanged

In the data center, where load balancers are announced as VIPs, and eBGP
is used as the routing protocol, this feature is required to ensure that
VIP announcements can be made from anywhere the operator sees fit.

Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2015-05-19 18:03:49 -07:00
parent f9dfba8dcb
commit 316e074deb
5 changed files with 40 additions and 3 deletions

View File

@ -126,6 +126,7 @@ struct attr
#define BATTR_RMAP_NEXTHOP_CHANGED (1 << 0)
#define BATTR_RMAP_NEXTHOP_PEER_ADDRESS (1 << 1)
#define BATTR_REFLECTED (1 << 2)
#define BATTR_RMAP_NEXTHOP_UNCHANGED (1 << 3)
/* Router Reflector related structure. */
struct cluster_list

View File

@ -1493,6 +1493,8 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
info.peer = peer;
info.attr = attr;
/* don't confuse inbound and outbound setting */
RESET_FLAG(attr->rmap_change_flags);
/*
* The route reflector is not allowed to modify the attributes
@ -1530,6 +1532,8 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
* Also see earlier comments in this function.
*/
if (!(CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_NEXTHOP_CHANGED) ||
CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_NEXTHOP_UNCHANGED) ||
CHECK_FLAG(riattr->rmap_change_flags, BATTR_RMAP_NEXTHOP_UNCHANGED) ||
transparent ||
CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)))
{

View File

@ -1079,6 +1079,7 @@ struct rmap_ip_nexthop_set
{
struct in_addr *address;
int peer_address;
int unchanged;
};
static route_map_result_t
@ -1094,7 +1095,12 @@ route_set_ip_nexthop (void *rule, struct prefix *prefix,
bgp_info = object;
peer = bgp_info->peer;
if (rins->peer_address)
if (rins->unchanged)
{
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_NEXTHOP_UNCHANGED);
}
else if (rins->peer_address)
{
if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
@ -1138,10 +1144,13 @@ route_set_ip_nexthop_compile (const char *arg)
struct rmap_ip_nexthop_set *rins;
struct in_addr *address = NULL;
int peer_address = 0;
int unchanged = 0;
int ret;
if (strcmp (arg, "peer-address") == 0)
peer_address = 1;
else if (strcmp (arg, "unchanged") == 0)
unchanged = 1;
else
{
address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
@ -1158,6 +1167,7 @@ route_set_ip_nexthop_compile (const char *arg)
rins->address = address;
rins->peer_address = peer_address;
rins->unchanged = unchanged;
return rins;
}
@ -3645,6 +3655,17 @@ DEFUN (set_ip_nexthop_peer,
return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
}
DEFUN (set_ip_nexthop_unchanged,
set_ip_nexthop_unchanged_cmd,
"set ip next-hop unchanged",
SET_STR
IP_STR
"Next hop address\n"
"Don't modify existing Next hop address\n")
{
return bgp_route_set_add (vty, vty->index, "ip next-hop", "unchanged");
}
DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
no_set_ip_nexthop_peer_cmd,
"no set ip next-hop peer-address",
@ -4693,6 +4714,7 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &set_ip_nexthop_cmd);
install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
install_element (RMAP_NODE, &set_ip_nexthop_unchanged_cmd);
install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
install_element (RMAP_NODE, &set_local_pref_cmd);

View File

@ -70,6 +70,7 @@ typedef struct
#define BPACKET_ATTRVEC_FLAGS_RMAP_CHANGED (1 << 1)
#define BPACKET_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS (1 << 2)
#define BPACKET_ATTRVEC_FLAGS_REFLECTED (1 << 3)
#define BPACKET_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED (1 << 4)
typedef struct bpacket_attr_vec_arr
{

View File

@ -439,7 +439,9 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
CHECK_FLAG(vec->flags,
BPACKET_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS)))
stream_put_in_addr_at (s, vec->offset + 1, &paf->peer->nexthop.v4);
else if (paf->peer->sort == BGP_PEER_EBGP &&
else if (!CHECK_FLAG(vec->flags,
BPACKET_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED) &&
paf->peer->sort == BGP_PEER_EBGP &&
!peer_af_flag_check (paf->peer, paf->afi, paf->safi,
PEER_FLAG_NEXTHOP_UNCHANGED))
{
@ -515,7 +517,9 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
BPACKET_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS)))
stream_put_in6_addr_at (s, vec->offset + 1,
&paf->peer->nexthop.v6_global);
else if (paf->peer->sort == BGP_PEER_EBGP &&
else if (!CHECK_FLAG(vec->flags,
BPACKET_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED) &&
paf->peer->sort == BGP_PEER_EBGP &&
!peer_af_flag_check (paf->peer, paf->afi, paf->safi,
PEER_FLAG_NEXTHOP_UNCHANGED))
{
@ -1097,6 +1101,11 @@ bpacket_vec_arr_inherit_attr_flags (struct bpacket_attr_vec_arr *vecarr,
if (CHECK_FLAG (attr->rmap_change_flags, BATTR_REFLECTED))
SET_FLAG (vecarr->entries[BGP_ATTR_VEC_NH].flags,
BPACKET_ATTRVEC_FLAGS_REFLECTED);
if (CHECK_FLAG (attr->rmap_change_flags,
BATTR_RMAP_NEXTHOP_UNCHANGED))
SET_FLAG (vecarr->entries[BGP_ATTR_VEC_NH].flags,
BPACKET_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED);
}
/* Reset the Attributes vector array. The vector array is used to override