This is part of the core VPN and Encap SAFI changes. 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 <[email protected]> Reviewed-by: David Lamparter <[email protected]> --- bgpd/bgp_mplsvpn.c | 20 ++++- bgpd/bgp_route.c | 212 ++++++++++++++++++++++++++++++++++++++++------------- bgpd/bgp_route.h | 6 +- 3 files changed, 184 insertions(+), 54 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index a72d5ed..18627ad 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -294,7 +294,22 @@ DEFUN (vpnv4_network, "BGP tag\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. */ @@ -309,7 +324,7 @@ DEFUN (no_vpnv4_network, "BGP tag\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 @@ -722,6 +737,7 @@ void bgp_mplsvpn_init (void) { 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); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 316fa5a..9866e37 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3614,39 +3614,6 @@ bgp_static_update (struct bgp *bgp, struct prefix *p, } } -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 = bgp_info_new (); - new->type = ZEBRA_ROUTE_BGP; - new->sub_type = BGP_ROUTE_STATIC; - new->peer = bgp->peer_self; - new->attr = bgp_attr_default_intern (BGP_ORIGIN_IGP); - SET_FLAG (new->flags, BGP_INFO_VALID); - new->uptime = bgp_clock (); - 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 bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi) @@ -3695,9 +3662,12 @@ bgp_check_local_routes_rsclient (struct peer *rsclient, afi_t afi, safi_t safi) } } +/* + * Used for SAFI_MPLS_VPN and SAFI_ENCAP + */ static void -bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi, - safi_t safi, struct prefix_rd *prd, u_char *tag) +bgp_static_withdraw_safi (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 *ri; @@ -3723,6 +3693,131 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi, 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 = bgp_info_new (); + new->type = ZEBRA_ROUTE_BGP; + new->sub_type = BGP_ROUTE_STATIC; + new->peer = bgp->peer_self; + new->attr = attr_new; + SET_FLAG (new->flags, BGP_INFO_VALID); + new->uptime = bgp_clock (); + 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 route should be installed as valid. */ static int @@ -3893,8 +3988,8 @@ bgp_static_delete (struct bgp *bgp) for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) { bgp_static = rn->info; - bgp_static_withdraw_vpnv4 (bgp, &rm->p, - AFI_IP, SAFI_MPLS_VPN, + bgp_static_withdraw_safi (bgp, &rm->p, + AFI_IP, safi, (struct prefix_rd *)&rn->p, bgp_static->tag); bgp_static_free (bgp_static); @@ -3913,9 +4008,15 @@ bgp_static_delete (struct bgp *bgp) } } +/* + * 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 -bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str, - const char *tag_str) +bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str, + const char *rd_str, const char *tag_str, + const char *rmap_str) { int ret; struct prefix p; @@ -3951,10 +4052,10 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str, 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); if (prn->info == NULL) - prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN); + prn->info = bgp_table_init (AFI_IP, safi); else bgp_unlock_node (prn); table = prn->info; @@ -3970,11 +4071,24 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str, { /* New configuration. */ bgp_static = bgp_static_new (); - bgp_static->valid = 1; - memcpy (bgp_static->tag, tag, 3); + bgp_static->backdoor = 0; + 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; - 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; @@ -3982,8 +4096,8 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str, /* Configure static BGP network. */ int -bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str, - const char *rd_str, const char *tag_str) +bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str, + const char *rd_str, const char *tag_str) { int ret; struct bgp *bgp; @@ -4020,10 +4134,10 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str, 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); if (prn->info == NULL) - prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN); + prn->info = bgp_table_init (AFI_IP, safi); else bgp_unlock_node (prn); table = prn->info; @@ -4032,7 +4146,7 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str, 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_free (bgp_static); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 3d2eea5..3e7f6f5 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -209,10 +209,10 @@ extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static 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 *, - const char *, const char *); +extern int bgp_static_set_safi (safi_t safi, struct vty *vty, 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 *); /* this is primarily for MPLS-VPN */ -- 2.1.3 _______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
