[cmaster-next] [PATCH 3/3] zebra/ldpd: allow MPLS ECMP on unnumbered interfaces

Donald Sharp sharpd at cumulusnetworks.com
Wed Dec 14 13:24:44 EST 2016


Series applied to master, thanks!

donald

On Mon, Dec 12, 2016 at 5:31 PM, Renato Westphal
<renato at opensourcerouting.org> wrote:
> Signed-off-by: Renato Westphal <renato at opensourcerouting.org>
> ---
>  ldpd/l2vpn.c       |  8 +++----
>  ldpd/lde.c         |  9 ++++++--
>  ldpd/lde.h         |  8 ++++---
>  ldpd/lde_lib.c     | 20 ++++++++--------
>  ldpd/ldp_zebra.c   | 23 +++++++++---------
>  zebra/zebra_mpls.c | 68 ++++++++++++++++++++++++++++++++++++------------------
>  zebra/zebra_mpls.h |  3 ++-
>  zebra/zserv.c      | 32 ++++++++++++++++++++-----
>  8 files changed, 112 insertions(+), 59 deletions(-)
>
> diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c
> index db382e4..851ff77 100644
> --- a/ldpd/l2vpn.c
> +++ b/ldpd/l2vpn.c
> @@ -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;
>
> diff --git a/ldpd/lde.c b/ldpd/lde.c
> index 904d0f8..67ed982 100644
> --- a/ldpd/lde.c
> +++ b/ldpd/lde.c
> @@ -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;
> diff --git a/ldpd/lde.h b/ldpd/lde.h
> index cf8f212..5f5d37d 100644
> --- a/ldpd/lde.h
> +++ b/ldpd/lde.h
> @@ -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 *);
> diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
> index 43e5f92..14ac592 100644
> --- a/ldpd/lde_lib.c
> +++ b/ldpd/lde_lib.c
> @@ -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);
>         }
>  }
>
> diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
> index 71c0a21..a233cb7 100644
> --- a/ldpd/ldp_zebra.c
> +++ b/ldpd/ldp_zebra.c
> @@ -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;
> diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
> index 3333b72..b057a78 100644
> --- a/zebra/zebra_mpls.c
> +++ b/zebra/zebra_mpls.c
> @@ -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:
> diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
> index 9f24689..a871fac 100644
> --- a/zebra/zebra_mpls.h
> +++ b/zebra/zebra_mpls.h
> @@ -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);
>
>  /*
> diff --git a/zebra/zserv.c b/zebra/zserv.c
> index 83d7d0f..aca33df 100644
> --- a/zebra/zserv.c
> +++ b/zebra/zserv.c
> @@ -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);
>      }
>  }
>
> --
> 1.9.1
>
>
> _______________________________________________
> cmaster-next mailing list
> cmaster-next at lists.nox.tf
> https://lists.nox.tf/listinfo/cmaster-next




More information about the dev mailing list