summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_mplsvpn.c
diff options
context:
space:
mode:
authorG. Paul Ziemba <paulz@labn.net>2018-04-11 19:58:03 +0200
committerG. Paul Ziemba <paulz@labn.net>2018-04-11 21:14:27 +0200
commit513bf8d6c987fea03cb75a2e533cf55ade538a85 (patch)
treee7f767d1b5eb70b2ee1f3e2c3f7aec8cee4df99b /bgpd/bgp_mplsvpn.c
parentMerge pull request #2050 from chipitsine/master (diff)
downloadfrr-513bf8d6c987fea03cb75a2e533cf55ade538a85.tar.xz
frr-513bf8d6c987fea03cb75a2e533cf55ade538a85.zip
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 <paulz@labn.net>
Diffstat (limited to 'bgpd/bgp_mplsvpn.c')
-rw-r--r--bgpd/bgp_mplsvpn.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 13a283a05..57cee775b 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));