From 513bf8d6c987fea03cb75a2e533cf55ade538a85 Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Wed, 11 Apr 2018 10:58:03 -0700 Subject: [PATCH] bgpd: bugfix vpn->vrf leak: unicast-originated routes are local non-LSP In general, routes leaked from the vpn rib to a vrf include any labels that might have been attached to the vpn route. VRF routes that have labels attached require a label-switched path and therefore require nexthops with labels in order to be marked valid by the nexthop-tracking logic. However, some routes in the vpn RIB originated in vrfs local to this router. Even though they may have labels, we must omit the labels when leaking to a vrf because traffic using those resulting routes will be carried by this router via IP routing and not label switching. The nexthops of these routes do not need to indicate a label-switched path, and thus the routes should be marked valid even when their nexthops do not have labels. This changeset omits labels from vpn->vrf leaked routes when the ultimate source of the vpn route was a local vrf. Signed-off-by: G. Paul Ziemba --- bgpd/bgp_mplsvpn.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 13a283a058..57cee775b2 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -891,6 +891,8 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */ mpls_label_t *pLabels = NULL; int num_labels = 0; int nexthop_self_flag = 1; + struct bgp_info *bi_ultimate = NULL; + int origin_local = 0; int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF); @@ -982,13 +984,40 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */ /* * ensure labels are copied + * + * However, there is a special case: if the route originated in + * another local VRF (as opposed to arriving via VPN), then the + * nexthop is reached by hairpinning through this router (me) + * using IP forwarding only (no LSP). Therefore, the route + * imported to the VRF should not have labels attached. Note + * that nexthop tracking is also involved: eliminating the + * labels for these routes enables the non-labeled nexthops + * from the originating VRF to be considered valid for this route. */ - if (info_vpn->extra && info_vpn->extra->num_labels) { + + /* work back to original route */ + for (bi_ultimate = info_vpn; + bi_ultimate->extra && bi_ultimate->extra->parent; + bi_ultimate = bi_ultimate->extra->parent) + ; + + /* if original route was unicast, then it did not arrive over vpn */ + if (bi_ultimate->net) { + struct bgp_table *table; + + table = bgp_node_table(bi_ultimate->net); + if (table && (table->safi == SAFI_UNICAST)) + origin_local = 1; + } + + /* copy labels */ + if (!origin_local && info_vpn->extra && info_vpn->extra->num_labels) { num_labels = info_vpn->extra->num_labels; if (num_labels > BGP_MAX_LABELS) num_labels = BGP_MAX_LABELS; pLabels = info_vpn->extra->label; } + if (debug) { char buf_prefix[PREFIX_STRLEN]; prefix2str(p, buf_prefix, sizeof(buf_prefix)); -- 2.39.5