]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: bugfix vpn->vrf leak: unicast-originated routes are local non-LSP
authorG. Paul Ziemba <paulz@labn.net>
Wed, 11 Apr 2018 17:58:03 +0000 (10:58 -0700)
committerG. Paul Ziemba <paulz@labn.net>
Wed, 11 Apr 2018 19:14:27 +0000 (12:14 -0700)
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>
bgpd/bgp_mplsvpn.c

index 13a283a058c33ef514debd577d75c50ebe633054..57cee775b20bf17fdbe85b9ab98a3423bb098822 100644 (file)
@@ -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));