]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra/ldpd: allow MPLS ECMP on unnumbered interfaces
authorRenato Westphal <renato@opensourcerouting.org>
Mon, 12 Dec 2016 20:28:31 +0000 (18:28 -0200)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 14 Dec 2016 18:21:08 +0000 (13:21 -0500)
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
(cherry picked from commit 7144dc12b55e05c9ae3d784dfb75817c9f881eb6)

ldpd/l2vpn.c
ldpd/lde.c
ldpd/lde.h
ldpd/lde_lib.c
ldpd/ldp_zebra.c
zebra/zebra_mpls.c
zebra/zebra_mpls.h
zebra/zserv.c

index db382e484f983209a3d26ef118289e55c4f62b62..851ff77b7317f435f36ecbdc81054256d796ea98 100644 (file)
@@ -195,7 +195,7 @@ l2vpn_pw_init(struct l2vpn_pw *pw)
        l2vpn_pw_reset(pw);
 
        l2vpn_pw_fec(pw, &fec);
-       lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0,
+       lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0,
            0, (void *)pw);
 }
 
@@ -205,7 +205,7 @@ l2vpn_pw_exit(struct l2vpn_pw *pw)
        struct fec       fec;
 
        l2vpn_pw_fec(pw, &fec);
-       lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0);
+       lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0);
 }
 
 static void
@@ -374,7 +374,7 @@ l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm)
        if (pw == NULL)
                return;
 
-       fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0);
+       fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0, 0);
        if (fnh == NULL)
                return;
 
@@ -409,7 +409,7 @@ l2vpn_sync_pws(int af, union ldpd_addr *addr)
                        if (fn == NULL)
                                continue;
                        fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)
-                           &pw->lsr_id, 0);
+                           &pw->lsr_id, 0, 0);
                        if (fnh == NULL)
                                continue;
 
index 904d0f8d9ac450366b82c757fc6d0d97aed55b1a..67ed982ec515b02bf6b272925496796301858e85 100644 (file)
@@ -432,14 +432,15 @@ lde_dispatch_parent(struct thread *thread)
                        switch (imsg.hdr.type) {
                        case IMSG_NETWORK_ADD:
                                lde_kernel_insert(&fec, kr.af, &kr.nexthop,
-                                   kr.priority, kr.flags & F_CONNECTED, NULL);
+                                   kr.ifindex, kr.priority,
+                                   kr.flags & F_CONNECTED, NULL);
                                break;
                        case IMSG_NETWORK_ADD_END:
                                lde_kernel_reevaluate(&fec);
                                break;
                        case IMSG_NETWORK_DEL:
                                lde_kernel_remove(&fec, kr.af, &kr.nexthop,
-                                   kr.priority);
+                                   kr.ifindex, kr.priority);
                                break;
                        }
                        break;
@@ -595,6 +596,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.prefix.v4 = fn->fec.u.ipv4.prefix;
                kr.prefixlen = fn->fec.u.ipv4.prefixlen;
                kr.nexthop.v4 = fnh->nexthop.v4;
+               kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
                kr.priority = fnh->priority;
@@ -612,6 +614,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.prefix.v6 = fn->fec.u.ipv6.prefix;
                kr.prefixlen = fn->fec.u.ipv6.prefixlen;
                kr.nexthop.v6 = fnh->nexthop.v6;
+               kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
                kr.priority = fnh->priority;
@@ -660,6 +663,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.prefix.v4 = fn->fec.u.ipv4.prefix;
                kr.prefixlen = fn->fec.u.ipv4.prefixlen;
                kr.nexthop.v4 = fnh->nexthop.v4;
+               kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
                kr.priority = fnh->priority;
@@ -677,6 +681,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.prefix.v6 = fn->fec.u.ipv6.prefix;
                kr.prefixlen = fn->fec.u.ipv6.prefixlen;
                kr.nexthop.v6 = fnh->nexthop.v6;
+               kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
                kr.priority = fnh->priority;
index cf8f2129af9173e15f2fc284c445e925fdaf85ca..5f5d37defb3118b3209037d01dc32309b3edef2d 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "openbsd-queue.h"
 #include "openbsd-tree.h"
+#include "if.h"
 
 enum fec_type {
        FEC_TYPE_IPV4,
@@ -100,6 +101,7 @@ struct fec_nh {
        LIST_ENTRY(fec_nh)       entry;
        int                      af;
        union ldpd_addr          nexthop;
+       ifindex_t                ifindex;
        uint32_t                 remote_label;
        uint8_t                  priority;
        uint8_t                  flags;
@@ -163,12 +165,12 @@ void               rt_dump(pid_t);
 void            fec_snap(struct lde_nbr *);
 void            fec_tree_clear(void);
 struct fec_nh  *fec_nh_find(struct fec_node *, int, union ldpd_addr *,
-                   uint8_t);
+                   ifindex_t, uint8_t);
 uint32_t        egress_label(enum fec_type);
 void            lde_kernel_insert(struct fec *, int, union ldpd_addr *,
-                   uint8_t, int, void *);
+                   ifindex_t, uint8_t, int, void *);
 void            lde_kernel_remove(struct fec *, int, union ldpd_addr *,
-                   uint8_t);
+                   ifindex_t, uint8_t);
 void            lde_kernel_reevaluate(struct fec *);
 void            lde_check_mapping(struct map *, struct lde_nbr *);
 void            lde_check_request(struct map *, struct lde_nbr *);
index 43e5f92f2fa2d808369a31d8c98c2fb8c014066e..14ac592af96221874a4f7343f4b6fcd33313bfde 100644 (file)
@@ -31,7 +31,7 @@ static int             lde_nbr_is_nexthop(struct fec_node *,
 static void             fec_free(void *);
 static struct fec_node *fec_add(struct fec *fec);
 static struct fec_nh   *fec_nh_add(struct fec_node *, int, union ldpd_addr *,
-                           uint8_t priority);
+                           ifindex_t, uint8_t);
 static void             fec_nh_del(struct fec_nh *);
 
 RB_GENERATE(fec_tree, fec, entry, fec_compare)
@@ -264,13 +264,14 @@ fec_add(struct fec *fec)
 
 struct fec_nh *
 fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
-    uint8_t priority)
+    ifindex_t ifindex, uint8_t priority)
 {
        struct fec_nh   *fnh;
 
        LIST_FOREACH(fnh, &fn->nexthops, entry)
                if (fnh->af == af &&
                    ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 &&
+                   fnh->ifindex == ifindex &&
                    fnh->priority == priority)
                        return (fnh);
 
@@ -279,7 +280,7 @@ fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
 
 static struct fec_nh *
 fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
-    uint8_t priority)
+    ifindex_t ifindex, uint8_t priority)
 {
        struct fec_nh   *fnh;
 
@@ -289,6 +290,7 @@ fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
 
        fnh->af = af;
        fnh->nexthop = *nexthop;
+       fnh->ifindex = ifindex;
        fnh->remote_label = NO_LABEL;
        fnh->priority = priority;
        LIST_INSERT_HEAD(&fn->nexthops, fnh, entry);
@@ -324,7 +326,7 @@ egress_label(enum fec_type fec_type)
 
 void
 lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
-    uint8_t priority, int connected, void *data)
+    ifindex_t ifindex, uint8_t priority, int connected, void *data)
 {
        struct fec_node         *fn;
        struct fec_nh           *fnh;
@@ -334,7 +336,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
        fn = (struct fec_node *)fec_find(&ft, fec);
        if (fn == NULL)
                fn = fec_add(fec);
-       fnh = fec_nh_find(fn, af, nexthop, priority);
+       fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
        if (fnh != NULL) {
                lde_send_change_klabel(fn, fnh);
                fnh->flags |= F_FEC_NH_NEW;
@@ -355,7 +357,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
                        lde_send_labelmapping(ln, fn, 1);
        }
 
-       fnh = fec_nh_add(fn, af, nexthop, priority);
+       fnh = fec_nh_add(fn, af, nexthop, ifindex, priority);
        fnh->flags |= F_FEC_NH_NEW;
        lde_send_change_klabel(fn, fnh);
 
@@ -383,7 +385,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
 
 void
 lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
-    uint8_t priority)
+    ifindex_t ifindex, uint8_t priority)
 {
        struct fec_node         *fn;
        struct fec_nh           *fnh;
@@ -392,7 +394,7 @@ lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
        if (fn == NULL)
                /* route lost */
                return;
-       fnh = fec_nh_find(fn, af, nexthop, priority);
+       fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
        if (fnh == NULL)
                /* route lost */
                return;
@@ -428,7 +430,7 @@ lde_kernel_reevaluate(struct fec *fec)
                        fnh->flags &= ~F_FEC_NH_NEW;
                else
                        lde_kernel_remove(fec, fnh->af, &fnh->nexthop,
-                           fnh->priority);
+                           fnh->ifindex, fnh->priority);
        }
 }
 
index 71c0a21dd47b976e56c8f8d8878020bc0fd54a81..a233cb72e77779a080fa5732f815493e02b44593 100644 (file)
@@ -100,10 +100,10 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
            kr->remote_label == NO_LABEL)
                return (0);
 
-       debug_zebra_out("prefix %s/%u nexthop %s labels %s/%s (%s)",
+       debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)",
            log_addr(kr->af, &kr->prefix), kr->prefixlen,
-           log_addr(kr->af, &kr->nexthop), log_label(kr->local_label),
-           log_label(kr->remote_label),
+           log_addr(kr->af, &kr->nexthop), kr->ifindex,
+           log_label(kr->local_label), log_label(kr->remote_label),
            (cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
 
        /* Reset stream. */
@@ -127,6 +127,7 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
        default:
                fatalx("kr_change: unknown af");
        }
+       stream_putl(s, kr->ifindex);
        stream_putc(s, kr->priority);
        stream_putl(s, kr->local_label);
        stream_putl(s, kr->remote_label);
@@ -426,19 +427,19 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
                switch (command) {
                case ZEBRA_REDISTRIBUTE_IPV4_ADD:
                case ZEBRA_REDISTRIBUTE_IPV6_ADD:
-                       debug_zebra_in("route add %s/%d nexthop %s (%s)",
-                           log_addr(kr.af, &kr.prefix), kr.prefixlen,
-                           log_addr(kr.af, &kr.nexthop),
-                           zebra_route_string(type));
+                       debug_zebra_in("route add %s/%d nexthop %s "
+                           "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
+                           kr.prefixlen, log_addr(kr.af, &kr.nexthop),
+                           kr.ifindex, zebra_route_string(type));
                        main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
                            sizeof(kr));
                        break;
                case ZEBRA_REDISTRIBUTE_IPV4_DEL:
                case ZEBRA_REDISTRIBUTE_IPV6_DEL:
-                       debug_zebra_in("route delete %s/%d nexthop %s (%s)",
-                           log_addr(kr.af, &kr.prefix), kr.prefixlen,
-                           log_addr(kr.af, &kr.nexthop),
-                           zebra_route_string(type));
+                       debug_zebra_in("route delete %s/%d nexthop %s "
+                           "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
+                           kr.prefixlen, log_addr(kr.af, &kr.nexthop),
+                           kr.ifindex, zebra_route_string(type));
                        main_imsg_compose_lde(IMSG_NETWORK_DEL, 0, &kr,
                            sizeof(kr));
                        break;
index 3333b7226af26c42380e9a6ba12b6f1c059668b9..b057a78788294b29b0cf51ba49f9151915dd6a57 100644 (file)
@@ -169,6 +169,7 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
   struct prefix_ipv4 p;
   struct route_node *rn;
   struct rib *match;
+  struct nexthop *match_nh;
 
   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
   if (!table)
@@ -189,17 +190,22 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
   /* Locate a valid connected route. */
   RNODE_FOREACH_RIB (rn, match)
     {
-      if ((match->type == ZEBRA_ROUTE_CONNECT) &&
-          !CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) &&
-          CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
-        break;
+      if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) ||
+         !CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+       continue;
+
+      for (match_nh = match->nexthop; match_nh; match_nh = match_nh->next)
+       {
+         if (match->type == ZEBRA_ROUTE_CONNECT ||
+             nexthop->ifindex == match_nh->ifindex)
+           {
+             nexthop->ifindex = match_nh->ifindex;
+             return 1;
+           }
+       }
     }
 
-  if (!match || !match->nexthop)
-    return 0;
-
-  nexthop->ifindex = match->nexthop->ifindex;
-  return 1;
+  return 0;
 }
 
 
@@ -268,6 +274,7 @@ nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe)
   switch (nexthop->type)
     {
       case NEXTHOP_TYPE_IPV4:
+      case NEXTHOP_TYPE_IPV4_IFINDEX:
         if (nhlfe_nexthop_active_ipv4 (nhlfe, nexthop))
           SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
         else
@@ -577,6 +584,7 @@ nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size)
   switch (nexthop->type)
     {
       case NEXTHOP_TYPE_IPV4:
+      case NEXTHOP_TYPE_IPV4_IFINDEX:
         inet_ntop (AF_INET, &nexthop->gate.ipv4, buf, size);
         break;
       case NEXTHOP_TYPE_IPV6:
@@ -609,8 +617,11 @@ nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
   switch (nhop->type)
     {
     case NEXTHOP_TYPE_IPV4:
+    case NEXTHOP_TYPE_IPV4_IFINDEX:
       cmp = memcmp(&(nhop->gate.ipv4), &(gate->ipv4),
                    sizeof(struct in_addr));
+      if (!cmp && nhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
+        cmp = !(nhop->ifindex == ifindex);
       break;
     case NEXTHOP_TYPE_IPV6:
     case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -686,7 +697,10 @@ nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
   switch (nexthop->type)
     {
     case NEXTHOP_TYPE_IPV4:
+    case NEXTHOP_TYPE_IPV4_IFINDEX:
       nexthop->gate.ipv4 = gate->ipv4;
+      if (ifindex)
+        nexthop->ifindex = ifindex;
       break;
     case NEXTHOP_TYPE_IPV6:
     case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -842,6 +856,7 @@ nhlfe_json (zebra_nhlfe_t *nhlfe)
   switch (nexthop->type)
     {
     case NEXTHOP_TYPE_IPV4:
+    case NEXTHOP_TYPE_IPV4_IFINDEX:
       json_object_string_add(json_nhlfe, "nexthop",
                              inet_ntoa (nexthop->gate.ipv4));
       break;
@@ -879,7 +894,10 @@ nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty)
   switch (nexthop->type)
     {
     case NEXTHOP_TYPE_IPV4:
+    case NEXTHOP_TYPE_IPV4_IFINDEX:
       vty_out (vty, "  via %s", inet_ntoa (nexthop->gate.ipv4));
+      if (nexthop->ifindex)
+        vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex));
       break;
     case NEXTHOP_TYPE_IPV6:
     case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -1258,7 +1276,8 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
  */
 int
 mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
-                struct prefix *prefix, union g_addr *gate, u_int8_t distance,
+                struct prefix *prefix, enum nexthop_types_t gtype,
+                union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
                 mpls_label_t out_label)
 {
   struct route_table *table;
@@ -1285,27 +1304,29 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
     return -1;
 
   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
-    switch (prefix->family)
-      {
-       case AF_INET:
-         if (nexthop->type != NEXTHOP_TYPE_IPV4 &&
-             nexthop->type != NEXTHOP_TYPE_IPV4_IFINDEX)
-           continue;
+    {
+      if (nexthop->type != gtype)
+       continue;
+      switch (gtype)
+       {
+       case NEXTHOP_TYPE_IPV4:
+       case NEXTHOP_TYPE_IPV4_IFINDEX:
          if (! IPV4_ADDR_SAME (&nexthop->gate.ipv4, &gate->ipv4))
            continue;
-         goto found;
-         break;
-       case AF_INET6:
-         if (nexthop->type != NEXTHOP_TYPE_IPV6 &&
-             nexthop->type != NEXTHOP_TYPE_IPV6_IFINDEX)
+         if (gtype == NEXTHOP_TYPE_IPV4_IFINDEX && nexthop->ifindex != ifindex)
            continue;
+         goto found;
+       case NEXTHOP_TYPE_IPV6:
+       case NEXTHOP_TYPE_IPV6_IFINDEX:
          if (! IPV6_ADDR_SAME (&nexthop->gate.ipv6, &gate->ipv6))
            continue;
+         if (gtype == NEXTHOP_TYPE_IPV6_IFINDEX && nexthop->ifindex != ifindex)
+           continue;
          goto found;
-         break;
        default:
          break;
-      }
+       }
+    }
   /* nexthop not found */
   return -1;
 
@@ -1811,6 +1832,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
               switch (nexthop->type)
                 {
                 case NEXTHOP_TYPE_IPV4:
+                case NEXTHOP_TYPE_IPV4_IFINDEX:
                   vty_out (vty, "%15s", inet_ntoa (nexthop->gate.ipv4));
                   break;
                 case NEXTHOP_TYPE_IPV6:
index 9f246895958dbfbc22608f9145e358f8db9b7372..a871fac6519b08bb6ca28ba1c194d3fc97c250f2 100644 (file)
@@ -169,7 +169,8 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
  */
 int
 mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
-                struct prefix *prefix, union g_addr *gate, u_int8_t distance,
+                struct prefix *prefix, enum nexthop_types_t gtype,
+                union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
                 mpls_label_t out_label);
 
 /*
index 61ea55f477e81db51f4fdf8beb8a5e25f657c63f..b7e45d8df1e944a92f04b5fefe4c4634e9f6ff36 100644 (file)
@@ -1665,6 +1665,7 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
   struct prefix prefix;
   enum nexthop_types_t gtype;
   union g_addr gate;
+  ifindex_t ifindex;
   mpls_label_t in_label, out_label;
   u_int8_t distance;
   struct zebra_vrf *zvrf;
@@ -1684,37 +1685,56 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
     case AF_INET:
       prefix.u.prefix4.s_addr = stream_get_ipv4 (s);
       prefix.prefixlen = stream_getc (s);
-      gtype = NEXTHOP_TYPE_IPV4;
       gate.ipv4.s_addr = stream_get_ipv4 (s);
       break;
     case AF_INET6:
       stream_get (&prefix.u.prefix6, s, 16);
       prefix.prefixlen = stream_getc (s);
-      gtype = NEXTHOP_TYPE_IPV6;
       stream_get (&gate.ipv6, s, 16);
       break;
     default:
       return;
     }
+  ifindex = stream_getl (s);
   distance = stream_getc (s);
   in_label = stream_getl (s);
   out_label = stream_getl (s);
 
+  switch (prefix.family)
+    {
+    case AF_INET:
+      if (ifindex)
+       gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
+      else
+       gtype = NEXTHOP_TYPE_IPV4;
+      break;
+    case AF_INET6:
+      if (ifindex)
+       gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
+      else
+       gtype = NEXTHOP_TYPE_IPV6;
+      break;
+    default:
+      return;
+    }
+
   if (! mpls_enabled)
     return;
 
   if (command == ZEBRA_MPLS_LABELS_ADD)
     {
       mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate,
-                       NULL, 0);
+                       NULL, ifindex);
       if (out_label != MPLS_IMP_NULL_LABEL)
-       mpls_ftn_update (1, zvrf, type, &prefix, &gate, distance, out_label);
+       mpls_ftn_update (1, zvrf, type, &prefix, gtype, &gate, ifindex,
+                        distance, out_label);
     }
   else if (command == ZEBRA_MPLS_LABELS_DELETE)
     {
-      mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, 0);
+      mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, ifindex);
       if (out_label != MPLS_IMP_NULL_LABEL)
-       mpls_ftn_update (0, zvrf, type, &prefix, &gate, distance, out_label);
+       mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex,
+                        distance, out_label);
     }
 }