mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-15 07:49:55 +00:00
bgpd: make _vpnv4 static handling SAFI-agnostic
This changes the existing _vpnv4 functions for MPLS-VPN into SAFI-agnostic functions, renaming them from *_vpnv4 to *_safi. Also adds route-map support while at it. Signed-off-by: Lou Berger <lberger@labn.net> Reviewed-by: David Lamparter <equinox@opensourcerouting.org> (cherry picked from commit a76d9ca3584c1751a592457c167c1e146648ceb6) Conflicts: bgpd/bgp_route.c
This commit is contained in:
parent
bcd9fa7ff2
commit
137446f997
@ -340,7 +340,22 @@ DEFUN (vpnv4_network,
|
|||||||
"BGP tag\n"
|
"BGP tag\n"
|
||||||
"tag value\n")
|
"tag value\n")
|
||||||
{
|
{
|
||||||
return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
|
return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (vpnv4_network_route_map,
|
||||||
|
vpnv4_network_route_map_cmd,
|
||||||
|
"network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
|
||||||
|
"Specify a network to announce via BGP\n"
|
||||||
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
|
||||||
|
"Specify Route Distinguisher\n"
|
||||||
|
"VPN Route Distinguisher\n"
|
||||||
|
"BGP tag\n"
|
||||||
|
"tag value\n"
|
||||||
|
"route map\n"
|
||||||
|
"route map name\n")
|
||||||
|
{
|
||||||
|
return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For testing purpose, static route of MPLS-VPN. */
|
/* For testing purpose, static route of MPLS-VPN. */
|
||||||
@ -355,7 +370,7 @@ DEFUN (no_vpnv4_network,
|
|||||||
"BGP tag\n"
|
"BGP tag\n"
|
||||||
"tag value\n")
|
"tag value\n")
|
||||||
{
|
{
|
||||||
return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
|
return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1020,6 +1035,7 @@ void
|
|||||||
bgp_mplsvpn_init (void)
|
bgp_mplsvpn_init (void)
|
||||||
{
|
{
|
||||||
install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
|
install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
|
||||||
|
install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
|
||||||
install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
|
install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
|
||||||
|
|
||||||
|
|
||||||
|
210
bgpd/bgp_route.c
210
bgpd/bgp_route.c
@ -3476,36 +3476,6 @@ bgp_static_update (struct bgp *bgp, struct prefix *p,
|
|||||||
bgp_static_update_main (bgp, p, bgp_static, afi, safi);
|
bgp_static_update_main (bgp, p, bgp_static, afi, safi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
|
|
||||||
safi_t safi, struct prefix_rd *prd, u_char *tag)
|
|
||||||
{
|
|
||||||
struct bgp_node *rn;
|
|
||||||
struct bgp_info *new;
|
|
||||||
|
|
||||||
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
|
|
||||||
|
|
||||||
/* Make new BGP info. */
|
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
|
|
||||||
bgp_attr_default_intern(BGP_ORIGIN_IGP), rn);
|
|
||||||
|
|
||||||
SET_FLAG (new->flags, BGP_INFO_VALID);
|
|
||||||
new->extra = bgp_info_extra_new();
|
|
||||||
memcpy (new->extra->tag, tag, 3);
|
|
||||||
|
|
||||||
/* Aggregate address increment. */
|
|
||||||
bgp_aggregate_increment (bgp, p, new, afi, safi);
|
|
||||||
|
|
||||||
/* Register new BGP information. */
|
|
||||||
bgp_info_add (rn, new);
|
|
||||||
|
|
||||||
/* route_node_get lock */
|
|
||||||
bgp_unlock_node (rn);
|
|
||||||
|
|
||||||
/* Process change. */
|
|
||||||
bgp_process (bgp, rn, afi, safi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
|
bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
|
||||||
safi_t safi)
|
safi_t safi)
|
||||||
@ -3535,9 +3505,12 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
|
|||||||
bgp_unlock_node (rn);
|
bgp_unlock_node (rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used for SAFI_MPLS_VPN and SAFI_ENCAP
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
|
bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
|
||||||
safi_t safi, struct prefix_rd *prd, u_char *tag)
|
safi_t safi, struct prefix_rd *prd, u_char *tag)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
@ -3563,6 +3536,127 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
|
|||||||
bgp_unlock_node (rn);
|
bgp_unlock_node (rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
|
||||||
|
struct bgp_static *bgp_static, afi_t afi, safi_t safi)
|
||||||
|
{
|
||||||
|
struct bgp_node *rn;
|
||||||
|
struct bgp_info *new;
|
||||||
|
struct attr *attr_new;
|
||||||
|
struct attr attr = { 0 };
|
||||||
|
struct bgp_info *ri;
|
||||||
|
|
||||||
|
assert (bgp_static);
|
||||||
|
|
||||||
|
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, &bgp_static->prd);
|
||||||
|
|
||||||
|
bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
|
||||||
|
|
||||||
|
attr.nexthop = bgp_static->igpnexthop;
|
||||||
|
attr.med = bgp_static->igpmetric;
|
||||||
|
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
|
||||||
|
|
||||||
|
/* Apply route-map. */
|
||||||
|
if (bgp_static->rmap.name)
|
||||||
|
{
|
||||||
|
struct attr attr_tmp = attr;
|
||||||
|
struct bgp_info info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
info.peer = bgp->peer_self;
|
||||||
|
info.attr = &attr_tmp;
|
||||||
|
|
||||||
|
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
|
||||||
|
|
||||||
|
ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
|
||||||
|
|
||||||
|
bgp->peer_self->rmap_type = 0;
|
||||||
|
|
||||||
|
if (ret == RMAP_DENYMATCH)
|
||||||
|
{
|
||||||
|
/* Free uninterned attribute. */
|
||||||
|
bgp_attr_flush (&attr_tmp);
|
||||||
|
|
||||||
|
/* Unintern original. */
|
||||||
|
aspath_unintern (&attr.aspath);
|
||||||
|
bgp_attr_extra_free (&attr);
|
||||||
|
bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd,
|
||||||
|
bgp_static->tag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_new = bgp_attr_intern (&attr_tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attr_new = bgp_attr_intern (&attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
|
if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
|
||||||
|
&& ri->sub_type == BGP_ROUTE_STATIC)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ri)
|
||||||
|
{
|
||||||
|
if (attrhash_cmp (ri->attr, attr_new) &&
|
||||||
|
!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
|
||||||
|
{
|
||||||
|
bgp_unlock_node (rn);
|
||||||
|
bgp_attr_unintern (&attr_new);
|
||||||
|
aspath_unintern (&attr.aspath);
|
||||||
|
bgp_attr_extra_free (&attr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The attribute is changed. */
|
||||||
|
bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
|
||||||
|
|
||||||
|
/* Rewrite BGP route information. */
|
||||||
|
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
|
||||||
|
bgp_info_restore(rn, ri);
|
||||||
|
else
|
||||||
|
bgp_aggregate_decrement (bgp, p, ri, afi, safi);
|
||||||
|
bgp_attr_unintern (&ri->attr);
|
||||||
|
ri->attr = attr_new;
|
||||||
|
ri->uptime = bgp_clock ();
|
||||||
|
|
||||||
|
/* Process change. */
|
||||||
|
bgp_aggregate_increment (bgp, p, ri, afi, safi);
|
||||||
|
bgp_process (bgp, rn, afi, safi);
|
||||||
|
bgp_unlock_node (rn);
|
||||||
|
aspath_unintern (&attr.aspath);
|
||||||
|
bgp_attr_extra_free (&attr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Make new BGP info. */
|
||||||
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
|
||||||
|
rn);
|
||||||
|
SET_FLAG (new->flags, BGP_INFO_VALID);
|
||||||
|
new->extra = bgp_info_extra_new();
|
||||||
|
memcpy (new->extra->tag, bgp_static->tag, 3);
|
||||||
|
|
||||||
|
/* Aggregate address increment. */
|
||||||
|
bgp_aggregate_increment (bgp, p, new, afi, safi);
|
||||||
|
|
||||||
|
/* Register new BGP information. */
|
||||||
|
bgp_info_add (rn, new);
|
||||||
|
|
||||||
|
/* route_node_get lock */
|
||||||
|
bgp_unlock_node (rn);
|
||||||
|
|
||||||
|
/* Process change. */
|
||||||
|
bgp_process (bgp, rn, afi, safi);
|
||||||
|
|
||||||
|
/* Unintern original. */
|
||||||
|
aspath_unintern (&attr.aspath);
|
||||||
|
bgp_attr_extra_free (&attr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure static BGP network. When user don't run zebra, static
|
/* Configure static BGP network. When user don't run zebra, static
|
||||||
route should be installed as valid. */
|
route should be installed as valid. */
|
||||||
static int
|
static int
|
||||||
@ -3726,10 +3820,7 @@ bgp_static_add (struct bgp *bgp)
|
|||||||
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
|
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
|
||||||
{
|
{
|
||||||
bgp_static = rn->info;
|
bgp_static = rn->info;
|
||||||
bgp_static_update_vpnv4 (bgp, &rm->p,
|
bgp_static_update_safi (bgp, &rm->p, bgp_static, afi, safi);
|
||||||
AFI_IP, SAFI_MPLS_VPN,
|
|
||||||
(struct prefix_rd *)&rn->p,
|
|
||||||
bgp_static->tag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3763,8 +3854,8 @@ bgp_static_delete (struct bgp *bgp)
|
|||||||
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
|
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
|
||||||
{
|
{
|
||||||
bgp_static = rn->info;
|
bgp_static = rn->info;
|
||||||
bgp_static_withdraw_vpnv4 (bgp, &rm->p,
|
bgp_static_withdraw_safi (bgp, &rm->p,
|
||||||
AFI_IP, SAFI_MPLS_VPN,
|
AFI_IP, safi,
|
||||||
(struct prefix_rd *)&rn->p,
|
(struct prefix_rd *)&rn->p,
|
||||||
bgp_static->tag);
|
bgp_static->tag);
|
||||||
bgp_static_free (bgp_static);
|
bgp_static_free (bgp_static);
|
||||||
@ -3846,9 +3937,15 @@ bgp_purge_static_redist_routes (struct bgp *bgp)
|
|||||||
bgp_purge_af_static_redist_routes (bgp, afi, safi);
|
bgp_purge_af_static_redist_routes (bgp, afi, safi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gpz 110624
|
||||||
|
* Currently this is used to set static routes for VPN and ENCAP.
|
||||||
|
* I think it can probably be factored with bgp_static_set.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
|
bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
|
||||||
const char *tag_str)
|
const char *rd_str, const char *tag_str,
|
||||||
|
const char *rmap_str)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
@ -3884,10 +3981,10 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
|
prn = bgp_node_get (bgp->route[AFI_IP][safi],
|
||||||
(struct prefix *)&prd);
|
(struct prefix *)&prd);
|
||||||
if (prn->info == NULL)
|
if (prn->info == NULL)
|
||||||
prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
|
prn->info = bgp_table_init (AFI_IP, safi);
|
||||||
else
|
else
|
||||||
bgp_unlock_node (prn);
|
bgp_unlock_node (prn);
|
||||||
table = prn->info;
|
table = prn->info;
|
||||||
@ -3903,11 +4000,24 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
|
|||||||
{
|
{
|
||||||
/* New configuration. */
|
/* New configuration. */
|
||||||
bgp_static = bgp_static_new ();
|
bgp_static = bgp_static_new ();
|
||||||
bgp_static->valid = 1;
|
bgp_static->backdoor = 0;
|
||||||
memcpy (bgp_static->tag, tag, 3);
|
bgp_static->valid = 0;
|
||||||
|
bgp_static->igpmetric = 0;
|
||||||
|
bgp_static->igpnexthop.s_addr = 0;
|
||||||
|
memcpy(bgp_static->tag, tag, 3);
|
||||||
|
bgp_static->prd = prd;
|
||||||
|
|
||||||
|
if (rmap_str)
|
||||||
|
{
|
||||||
|
if (bgp_static->rmap.name)
|
||||||
|
free (bgp_static->rmap.name);
|
||||||
|
bgp_static->rmap.name = strdup (rmap_str);
|
||||||
|
bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);
|
||||||
|
}
|
||||||
rn->info = bgp_static;
|
rn->info = bgp_static;
|
||||||
|
|
||||||
bgp_static_update_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
|
bgp_static->valid = 1;
|
||||||
|
bgp_static_update_safi (bgp, &p, bgp_static, AFI_IP, safi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -3915,8 +4025,8 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
|
|||||||
|
|
||||||
/* Configure static BGP network. */
|
/* Configure static BGP network. */
|
||||||
int
|
int
|
||||||
bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
|
bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
|
||||||
const char *rd_str, const char *tag_str)
|
const char *rd_str, const char *tag_str)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
@ -3953,10 +4063,10 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
|
prn = bgp_node_get (bgp->route[AFI_IP][safi],
|
||||||
(struct prefix *)&prd);
|
(struct prefix *)&prd);
|
||||||
if (prn->info == NULL)
|
if (prn->info == NULL)
|
||||||
prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
|
prn->info = bgp_table_init (AFI_IP, safi);
|
||||||
else
|
else
|
||||||
bgp_unlock_node (prn);
|
bgp_unlock_node (prn);
|
||||||
table = prn->info;
|
table = prn->info;
|
||||||
@ -3965,7 +4075,7 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
|
|||||||
|
|
||||||
if (rn)
|
if (rn)
|
||||||
{
|
{
|
||||||
bgp_static_withdraw_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
|
bgp_static_withdraw_safi (bgp, &p, AFI_IP, safi, &prd, tag);
|
||||||
|
|
||||||
bgp_static = rn->info;
|
bgp_static = rn->info;
|
||||||
bgp_static_free (bgp_static);
|
bgp_static_free (bgp_static);
|
||||||
|
@ -145,6 +145,9 @@ struct bgp_static
|
|||||||
struct route_map *map;
|
struct route_map *map;
|
||||||
} rmap;
|
} rmap;
|
||||||
|
|
||||||
|
/* Route Distinguisher */
|
||||||
|
struct prefix_rd prd;
|
||||||
|
|
||||||
/* MPLS label. */
|
/* MPLS label. */
|
||||||
u_char tag[3];
|
u_char tag[3];
|
||||||
};
|
};
|
||||||
@ -253,10 +256,10 @@ extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static
|
|||||||
afi_t, safi_t);
|
afi_t, safi_t);
|
||||||
extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);
|
extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);
|
||||||
|
|
||||||
extern int bgp_static_set_vpnv4 (struct vty *vty, const char *,
|
extern int bgp_static_set_safi (safi_t safi, struct vty *vty, const char *,
|
||||||
const char *, const char *);
|
const char *, const char *, const char *);
|
||||||
|
|
||||||
extern int bgp_static_unset_vpnv4 (struct vty *, const char *,
|
extern int bgp_static_unset_safi (safi_t safi, struct vty *, const char *,
|
||||||
const char *, const char *);
|
const char *, const char *);
|
||||||
|
|
||||||
/* this is primarily for MPLS-VPN */
|
/* this is primarily for MPLS-VPN */
|
||||||
|
Loading…
Reference in New Issue
Block a user