diff options
Diffstat (limited to 'zebra/zebra_mpls.c')
| -rw-r--r-- | zebra/zebra_mpls.c | 2849 | 
1 files changed, 1373 insertions, 1476 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index ba500cac27..7e74edf333 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -46,11 +46,11 @@  #include "zebra/zebra_vrf.h"  #include "zebra/zebra_mpls.h" -DEFINE_MTYPE_STATIC(ZEBRA, LSP,			"MPLS LSP object") -DEFINE_MTYPE_STATIC(ZEBRA, SLSP,		"MPLS static LSP config") -DEFINE_MTYPE_STATIC(ZEBRA, NHLFE,		"MPLS nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE,		"MPLS static nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME,	"MPLS static nexthop ifname") +DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object") +DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config") +DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object") +DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object") +DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")  int mpls_enabled; @@ -58,78 +58,54 @@ int mpls_enabled;  extern struct zebra_t zebrad;  /* static function declarations */ -static unsigned int -label_hash (void *p); -static int -label_cmp (const void *p1, const void *p2); -static int -nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop); -static int -nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop); -static int -nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe); -static void -lsp_select_best_nhlfe (zebra_lsp_t *lsp); -static void -lsp_uninstall_from_kernel (struct hash_backet *backet, void *ctxt); -static void -lsp_schedule (struct hash_backet *backet, void *ctxt); -static wq_item_status -lsp_process (struct work_queue *wq, void *data); -static void -lsp_processq_del (struct work_queue *wq, void *data); -static void -lsp_processq_complete (struct work_queue *wq); -static int -lsp_processq_add (zebra_lsp_t *lsp); -static void * -lsp_alloc (void *p); -static char * -nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size); -static int -nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, -                  union g_addr *gate, char *ifname, ifindex_t ifindex); -static zebra_nhlfe_t * -nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -            enum nexthop_types_t gtype, union g_addr *gate, -            char *ifname, ifindex_t ifindex); -static zebra_nhlfe_t * -nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -           enum nexthop_types_t gtype, union g_addr *gate, -           char *ifname, ifindex_t ifindex, mpls_label_t out_label); -static int -nhlfe_del (zebra_nhlfe_t *snhlfe); -static int -mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp, -			enum lsp_types_t type); -static int -mpls_static_lsp_uninstall_all (struct zebra_vrf *zvrf, mpls_label_t in_label); -static void -nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty); -static void -lsp_print (zebra_lsp_t *lsp, void *ctxt); -static void * -slsp_alloc (void *p); -static int -snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, -              union g_addr *gate, char *ifname, ifindex_t ifindex); -static zebra_snhlfe_t * -snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -             union g_addr *gate, char *ifname, ifindex_t ifindex); -static zebra_snhlfe_t * -snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -            union g_addr *gate, char *ifname, ifindex_t ifindex, -            mpls_label_t out_label); -static int -snhlfe_del (zebra_snhlfe_t *snhlfe); -static int -snhlfe_del_all (zebra_slsp_t *slsp); -static char * -snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size); -static void -mpls_processq_init (struct zebra_t *zebra); - - +static unsigned int label_hash(void *p); +static int label_cmp(const void *p1, const void *p2); +static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop); +static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop); +static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe); +static void lsp_select_best_nhlfe(zebra_lsp_t *lsp); +static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt); +static void lsp_schedule(struct hash_backet *backet, void *ctxt); +static wq_item_status lsp_process(struct work_queue *wq, void *data); +static void lsp_processq_del(struct work_queue *wq, void *data); +static void lsp_processq_complete(struct work_queue *wq); +static int lsp_processq_add(zebra_lsp_t *lsp); +static void *lsp_alloc(void *p); +static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size); +static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, +			    union g_addr *gate, char *ifname, +			    ifindex_t ifindex); +static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				 enum nexthop_types_t gtype, union g_addr *gate, +				 char *ifname, ifindex_t ifindex); +static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				enum nexthop_types_t gtype, union g_addr *gate, +				char *ifname, ifindex_t ifindex, +				mpls_label_t out_label); +static int nhlfe_del(zebra_nhlfe_t *snhlfe); +static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, +				  enum lsp_types_t type); +static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf, +					 mpls_label_t in_label); +static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty); +static void lsp_print(zebra_lsp_t *lsp, void *ctxt); +static void *slsp_alloc(void *p); +static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, +			union g_addr *gate, char *ifname, ifindex_t ifindex); +static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, +				   enum nexthop_types_t gtype, +				   union g_addr *gate, char *ifname, +				   ifindex_t ifindex); +static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, +				  enum nexthop_types_t gtype, +				  union g_addr *gate, char *ifname, +				  ifindex_t ifindex, mpls_label_t out_label); +static int snhlfe_del(zebra_snhlfe_t *snhlfe); +static int snhlfe_del_all(zebra_slsp_t *slsp); +static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size); +static void mpls_processq_init(struct zebra_t *zebra);  /* Static functions */ @@ -137,24 +113,22 @@ mpls_processq_init (struct zebra_t *zebra);  /*   * Hash function for label.   */ -static unsigned int -label_hash (void *p) +static unsigned int label_hash(void *p)  { -  const zebra_ile_t *ile = p; +	const zebra_ile_t *ile = p; -  return (jhash_1word(ile->in_label, 0)); +	return (jhash_1word(ile->in_label, 0));  }  /*   * Compare 2 LSP hash entries based on in-label.   */ -static int -label_cmp (const void *p1, const void *p2) +static int label_cmp(const void *p1, const void *p2)  { -  const zebra_ile_t *ile1 = p1; -  const zebra_ile_t *ile2 = p2; +	const zebra_ile_t *ile1 = p1; +	const zebra_ile_t *ile2 = p2; -  return (ile1->in_label == ile2->in_label); +	return (ile1->in_label == ile2->in_label);  }  /* @@ -162,50 +136,49 @@ label_cmp (const void *p1, const void *p2)   * the passed flag.   * NOTE: Looking only for connected routes right now.   */ -static int -nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop) +static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop)  { -  struct route_table *table; -  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) -    return 0; - -  /* Lookup nexthop in IPv4 routing table. */ -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefixlen = IPV4_MAX_PREFIXLEN; -  p.prefix = nexthop->gate.ipv4; - -  rn = route_node_match (table, (struct prefix *) &p); -  if (!rn) -    return 0; - -  route_unlock_node (rn); - -  /* Locate a valid connected route. */ -  RNODE_FOREACH_RIB (rn, match) -    { -      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) +	struct route_table *table; +	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) +		return 0; + +	/* Lookup nexthop in IPv4 routing table. */ +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefixlen = IPV4_MAX_PREFIXLEN; +	p.prefix = nexthop->gate.ipv4; + +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn) +		return 0; + +	route_unlock_node(rn); + +	/* Locate a valid connected route. */ +	RNODE_FOREACH_RIB(rn, match)  	{ -	  if (match->type == ZEBRA_ROUTE_CONNECT || -	      nexthop->ifindex == match_nh->ifindex) -	    { -	      nexthop->ifindex = match_nh->ifindex; -	      return 1; -	    } +		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; +			} +		}  	} -    } -  return 0; +	return 0;  } @@ -214,44 +187,44 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)   * the passed flag.   * NOTE: Looking only for connected routes right now.   */ -static int -nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop) +static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop)  { -  struct route_table *table; -  struct prefix_ipv6 p; -  struct route_node *rn; -  struct rib *match; - -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT); -  if (!table) -    return 0; - -  /* Lookup nexthop in IPv6 routing table. */ -  memset (&p, 0, sizeof (struct prefix_ipv6)); -  p.family = AF_INET6; -  p.prefixlen = IPV6_MAX_PREFIXLEN; -  p.prefix = nexthop->gate.ipv6; - -  rn = route_node_match (table, (struct prefix *) &p); -  if (!rn) -    return 0; - -  route_unlock_node (rn); - -  /* 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 (!match || !match->nexthop) -    return 0; - -  nexthop->ifindex = match->nexthop->ifindex; -  return 1; +	struct route_table *table; +	struct prefix_ipv6 p; +	struct route_node *rn; +	struct rib *match; + +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return 0; + +	/* Lookup nexthop in IPv6 routing table. */ +	memset(&p, 0, sizeof(struct prefix_ipv6)); +	p.family = AF_INET6; +	p.prefixlen = IPV6_MAX_PREFIXLEN; +	p.prefix = nexthop->gate.ipv6; + +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn) +		return 0; + +	route_unlock_node(rn); + +	/* 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 (!match || !match->nexthop) +		return 0; + +	nexthop->ifindex = match->nexthop->ifindex; +	return 1;  } @@ -260,57 +233,52 @@ nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)   * or not.   * NOTE: Each NHLFE points to only 1 nexthop.   */ -static int -nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe) +static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)  { -  struct nexthop *nexthop; -  struct interface *ifp; - -  nexthop = nhlfe->nexthop; -  if (!nexthop) // unexpected -    return 0; - -  /* Check on nexthop based on type. */ -  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 -          UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -        break; - -      case NEXTHOP_TYPE_IPV6: -        if (nhlfe_nexthop_active_ipv6 (nhlfe, nexthop)) -          SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -        else -          UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -        break; - -      case NEXTHOP_TYPE_IPV6_IFINDEX: -        if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6)) -          { -            ifp = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT); -            if (ifp && if_is_operative(ifp)) -              SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -            else -              UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -          } -        else -          { -            if (nhlfe_nexthop_active_ipv6 (nhlfe, nexthop)) -              SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -            else -              UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -          } -        break; - -    default: -      break; -    } - -  return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); +	struct nexthop *nexthop; +	struct interface *ifp; + +	nexthop = nhlfe->nexthop; +	if (!nexthop) // unexpected +		return 0; + +	/* Check on nexthop based on type. */ +	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 +			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; + +	case NEXTHOP_TYPE_IPV6: +		if (nhlfe_nexthop_active_ipv6(nhlfe, nexthop)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		else +			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; + +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { +			ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); +			if (ifp && if_is_operative(ifp)) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +			else +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		} else { +			if (nhlfe_nexthop_active_ipv6(nhlfe, nexthop)) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +			else +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		} +		break; + +	default: +		break; +	} + +	return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);  }  /* @@ -319,759 +287,722 @@ nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe)   * marked. This is invoked when an LSP scheduled for processing (due   * to some change) is examined.   */ -static void -lsp_select_best_nhlfe (zebra_lsp_t *lsp) +static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)  { -  zebra_nhlfe_t *nhlfe; -  zebra_nhlfe_t *best; -  struct nexthop *nexthop; -  int changed = 0; - -  if (!lsp) -    return; - -  best = NULL; -  lsp->num_ecmp = 0; -  UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); - -  /* -   * First compute the best path, after checking nexthop status. We are only -   * concerned with non-deleted NHLFEs. -   */ -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      /* Clear selection flags. */ -      UNSET_FLAG (nhlfe->flags, -                  (NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH)); - -      if (!CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED) && -          nhlfe_nexthop_active (nhlfe)) -        { -          if (!best || (nhlfe->distance < best->distance)) -            best = nhlfe; -        } -    } - -  lsp->best_nhlfe = best; -  if (!lsp->best_nhlfe) -    return; - -  /* Mark best NHLFE as selected. */ -  SET_FLAG (lsp->best_nhlfe->flags, NHLFE_FLAG_SELECTED); - -  /* -   * If best path exists, see if there is ECMP. While doing this, note if a -   * new (uninstalled) NHLFE has been selected, an installed entry that is -   * still selected has a change or an installed entry is to be removed. -   */ -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      int nh_chg, nh_sel, nh_inst; - -      nexthop = nhlfe->nexthop; -      if (!nexthop) // unexpected -        continue; - -      if (!CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED) && -          CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) && -          (nhlfe->distance == lsp->best_nhlfe->distance)) -        { -          SET_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED); -          SET_FLAG (nhlfe->flags, NHLFE_FLAG_MULTIPATH); -          lsp->num_ecmp++; -        } - -      if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED) && -          !changed) -        { -          nh_chg = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -          nh_sel = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED); -          nh_inst = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); - -          if ((nh_sel && !nh_inst) || -              (nh_sel && nh_inst && nh_chg) || -              (nh_inst && !nh_sel)) -            changed = 1; -        } - -      /* We have finished examining, clear changed flag. */ -      UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -    } - -  if (changed) -    SET_FLAG (lsp->flags, LSP_FLAG_CHANGED); +	zebra_nhlfe_t *nhlfe; +	zebra_nhlfe_t *best; +	struct nexthop *nexthop; +	int changed = 0; + +	if (!lsp) +		return; + +	best = NULL; +	lsp->num_ecmp = 0; +	UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); + +	/* +	 * First compute the best path, after checking nexthop status. We are +	 * only +	 * concerned with non-deleted NHLFEs. +	 */ +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		/* Clear selection flags. */ +		UNSET_FLAG(nhlfe->flags, +			   (NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH)); + +		if (!CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED) +		    && nhlfe_nexthop_active(nhlfe)) { +			if (!best || (nhlfe->distance < best->distance)) +				best = nhlfe; +		} +	} + +	lsp->best_nhlfe = best; +	if (!lsp->best_nhlfe) +		return; + +	/* Mark best NHLFE as selected. */ +	SET_FLAG(lsp->best_nhlfe->flags, NHLFE_FLAG_SELECTED); + +	/* +	 * If best path exists, see if there is ECMP. While doing this, note if +	 * a +	 * new (uninstalled) NHLFE has been selected, an installed entry that is +	 * still selected has a change or an installed entry is to be removed. +	 */ +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		int nh_chg, nh_sel, nh_inst; + +		nexthop = nhlfe->nexthop; +		if (!nexthop) // unexpected +			continue; + +		if (!CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED) +		    && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) +		    && (nhlfe->distance == lsp->best_nhlfe->distance)) { +			SET_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED); +			SET_FLAG(nhlfe->flags, NHLFE_FLAG_MULTIPATH); +			lsp->num_ecmp++; +		} + +		if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) && !changed) { +			nh_chg = CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +			nh_sel = CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED); +			nh_inst = +				CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + +			if ((nh_sel && !nh_inst) +			    || (nh_sel && nh_inst && nh_chg) +			    || (nh_inst && !nh_sel)) +				changed = 1; +		} + +		/* We have finished examining, clear changed flag. */ +		UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +	} + +	if (changed) +		SET_FLAG(lsp->flags, LSP_FLAG_CHANGED);  }  /*   * Delete LSP forwarding entry from kernel, if installed. Called upon   * process exit.   */ -static void -lsp_uninstall_from_kernel (struct hash_backet *backet, void *ctxt) +static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt)  { -  zebra_lsp_t *lsp; +	zebra_lsp_t *lsp; -  lsp = (zebra_lsp_t *) backet->data; -  if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) -    kernel_del_lsp (lsp); +	lsp = (zebra_lsp_t *)backet->data; +	if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) +		kernel_del_lsp(lsp);  }  /*   * Schedule LSP forwarding entry for processing. Called upon changes   * that may impact LSPs such as nexthop / connected route changes.   */ -static void -lsp_schedule (struct hash_backet *backet, void *ctxt) +static void lsp_schedule(struct hash_backet *backet, void *ctxt)  { -  zebra_lsp_t *lsp; +	zebra_lsp_t *lsp; -  lsp = (zebra_lsp_t *) backet->data; -  lsp_processq_add (lsp); +	lsp = (zebra_lsp_t *)backet->data; +	lsp_processq_add(lsp);  }  /*   * Process a LSP entry that is in the queue. Recalculate best NHLFE and   * any multipaths and update or delete from the kernel, as needed.   */ -static wq_item_status -lsp_process (struct work_queue *wq, void *data) +static wq_item_status lsp_process(struct work_queue *wq, void *data)  { -  zebra_lsp_t *lsp; -  zebra_nhlfe_t *oldbest, *newbest; -  char buf[BUFSIZ], buf2[BUFSIZ]; - -  lsp = (zebra_lsp_t *)data; -  if (!lsp) // unexpected -    return WQ_SUCCESS; - -  oldbest = lsp->best_nhlfe; - -  /* Select best NHLFE(s) */ -  lsp_select_best_nhlfe (lsp); - -  newbest = lsp->best_nhlfe; - -  if (IS_ZEBRA_DEBUG_MPLS) -    { -      if (oldbest) -        nhlfe2str (oldbest, buf, BUFSIZ); -      if (newbest) -        nhlfe2str (newbest, buf2, BUFSIZ); -      zlog_debug ("Process LSP in-label %u oldbest %s newbest %s " -                  "flags 0x%x ecmp# %d", -                  lsp->ile.in_label, oldbest ? buf : "NULL", -                  newbest ? buf2 : "NULL", lsp->flags, lsp->num_ecmp); -    } - -  if (!CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) -    { -      /* Not already installed */ -      if (newbest) -        kernel_add_lsp (lsp); -    } -  else -    { -      /* Installed, may need an update and/or delete. */ -      if (!newbest) -        kernel_del_lsp (lsp); -      else if (CHECK_FLAG (lsp->flags, LSP_FLAG_CHANGED)) -        kernel_upd_lsp (lsp); -    } - -  return WQ_SUCCESS; +	zebra_lsp_t *lsp; +	zebra_nhlfe_t *oldbest, *newbest; +	char buf[BUFSIZ], buf2[BUFSIZ]; + +	lsp = (zebra_lsp_t *)data; +	if (!lsp) // unexpected +		return WQ_SUCCESS; + +	oldbest = lsp->best_nhlfe; + +	/* Select best NHLFE(s) */ +	lsp_select_best_nhlfe(lsp); + +	newbest = lsp->best_nhlfe; + +	if (IS_ZEBRA_DEBUG_MPLS) { +		if (oldbest) +			nhlfe2str(oldbest, buf, BUFSIZ); +		if (newbest) +			nhlfe2str(newbest, buf2, BUFSIZ); +		zlog_debug( +			"Process LSP in-label %u oldbest %s newbest %s " +			"flags 0x%x ecmp# %d", +			lsp->ile.in_label, oldbest ? buf : "NULL", +			newbest ? buf2 : "NULL", lsp->flags, lsp->num_ecmp); +	} + +	if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) { +		/* Not already installed */ +		if (newbest) +			kernel_add_lsp(lsp); +	} else { +		/* Installed, may need an update and/or delete. */ +		if (!newbest) +			kernel_del_lsp(lsp); +		else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) +			kernel_upd_lsp(lsp); +	} + +	return WQ_SUCCESS;  }  /*   * Callback upon processing completion of a LSP forwarding entry.   */ -static void -lsp_processq_del (struct work_queue *wq, void *data) +static void lsp_processq_del(struct work_queue *wq, void *data)  { -  struct zebra_vrf *zvrf; -  zebra_lsp_t *lsp; -  struct hash *lsp_table; -  zebra_nhlfe_t *nhlfe, *nhlfe_next; - -  zvrf = vrf_info_lookup(VRF_DEFAULT); -  assert (zvrf); - -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) // unexpected -    return; - -  lsp = (zebra_lsp_t *)data; -  if (!lsp) // unexpected -    return; - -  /* Clear flag, remove any NHLFEs marked for deletion. If no NHLFEs exist, -   * delete LSP entry also. -   */ -  UNSET_FLAG (lsp->flags, LSP_FLAG_SCHEDULED); - -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) -    { -      nhlfe_next = nhlfe->next; -      if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED)) -        nhlfe_del (nhlfe); -    } - -  if (!lsp->nhlfe_list) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("Free LSP in-label %u flags 0x%x", -                    lsp->ile.in_label, lsp->flags); - -      lsp = hash_release(lsp_table, &lsp->ile); -      if (lsp) -        XFREE(MTYPE_LSP, lsp); -    } +	struct zebra_vrf *zvrf; +	zebra_lsp_t *lsp; +	struct hash *lsp_table; +	zebra_nhlfe_t *nhlfe, *nhlfe_next; + +	zvrf = vrf_info_lookup(VRF_DEFAULT); +	assert(zvrf); + +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) // unexpected +		return; + +	lsp = (zebra_lsp_t *)data; +	if (!lsp) // unexpected +		return; + +	/* Clear flag, remove any NHLFEs marked for deletion. If no NHLFEs +	 * exist, +	 * delete LSP entry also. +	 */ +	UNSET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED); + +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) { +		nhlfe_next = nhlfe->next; +		if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED)) +			nhlfe_del(nhlfe); +	} + +	if (!lsp->nhlfe_list) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug("Free LSP in-label %u flags 0x%x", +				   lsp->ile.in_label, lsp->flags); + +		lsp = hash_release(lsp_table, &lsp->ile); +		if (lsp) +			XFREE(MTYPE_LSP, lsp); +	}  }  /*   * Callback upon finishing the processing of all scheduled   * LSP forwarding entries.   */ -static void -lsp_processq_complete (struct work_queue *wq) +static void lsp_processq_complete(struct work_queue *wq)  { -  /* Nothing to do for now. */ +	/* Nothing to do for now. */  }  /*   * Add LSP forwarding entry to queue for subsequent processing.   */ -static int -lsp_processq_add (zebra_lsp_t *lsp) +static int lsp_processq_add(zebra_lsp_t *lsp)  { -  /* If already scheduled, exit. */ -  if (CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED)) -    return 0; +	/* If already scheduled, exit. */ +	if (CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) +		return 0; -  work_queue_add (zebrad.lsp_process_q, lsp); -  SET_FLAG (lsp->flags, LSP_FLAG_SCHEDULED); -  return 0; +	work_queue_add(zebrad.lsp_process_q, lsp); +	SET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED); +	return 0;  }  /*   * Callback to allocate LSP forwarding table entry.   */ -static void * -lsp_alloc (void *p) +static void *lsp_alloc(void *p)  { -  const zebra_ile_t *ile = p; -  zebra_lsp_t *lsp; +	const zebra_ile_t *ile = p; +	zebra_lsp_t *lsp; -  lsp = XCALLOC (MTYPE_LSP, sizeof(zebra_lsp_t)); -  lsp->ile = *ile; +	lsp = XCALLOC(MTYPE_LSP, sizeof(zebra_lsp_t)); +	lsp->ile = *ile; -  if (IS_ZEBRA_DEBUG_MPLS) -    zlog_debug ("Alloc LSP in-label %u", lsp->ile.in_label); +	if (IS_ZEBRA_DEBUG_MPLS) +		zlog_debug("Alloc LSP in-label %u", lsp->ile.in_label); -  return ((void *)lsp); +	return ((void *)lsp);  }  /*   * Create printable string for NHLFE entry.   */ -static char * -nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size) +static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)  { -  struct nexthop *nexthop; - -  buf[0] = '\0'; -  nexthop = nhlfe->nexthop; -  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: -        inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, size); -        break; -      default: -        break; -    } - -  return buf; +	struct nexthop *nexthop; + +	buf[0] = '\0'; +	nexthop = nhlfe->nexthop; +	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: +		inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size); +		break; +	default: +		break; +	} + +	return buf;  }  /*   * Check if NHLFE matches with search info passed.   */ -static int -nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, -                  union g_addr *gate, char *ifname, ifindex_t ifindex) +static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, +			    union g_addr *gate, char *ifname, ifindex_t ifindex)  { -  struct nexthop *nhop; -  int cmp = 1; - -  nhop = nhlfe->nexthop; -  if (!nhop) -    return 1; - -  if (nhop->type != gtype) -    return 1; - -  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: -      cmp = memcmp(&(nhop->gate.ipv6), &(gate->ipv6), -		   sizeof(struct in6_addr)); -      if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -        cmp = !(nhop->ifindex == ifindex); -      break; -    default: -      break; -    } - -  return cmp; +	struct nexthop *nhop; +	int cmp = 1; + +	nhop = nhlfe->nexthop; +	if (!nhop) +		return 1; + +	if (nhop->type != gtype) +		return 1; + +	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: +		cmp = memcmp(&(nhop->gate.ipv6), &(gate->ipv6), +			     sizeof(struct in6_addr)); +		if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) +			cmp = !(nhop->ifindex == ifindex); +		break; +	default: +		break; +	} + +	return cmp;  }  /*   * Locate NHLFE that matches with passed info.   */ -static zebra_nhlfe_t * -nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -            enum nexthop_types_t gtype, union g_addr *gate, -            char *ifname, ifindex_t ifindex) +static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				 enum nexthop_types_t gtype, union g_addr *gate, +				 char *ifname, ifindex_t ifindex)  { -  zebra_nhlfe_t *nhlfe; +	zebra_nhlfe_t *nhlfe; -  if (!lsp) -    return NULL; +	if (!lsp) +		return NULL; -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      if (nhlfe->type != lsp_type) -        continue; -      if (!nhlfe_nhop_match (nhlfe, gtype, gate, ifname, ifindex)) -        break; -    } +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		if (nhlfe->type != lsp_type) +			continue; +		if (!nhlfe_nhop_match(nhlfe, gtype, gate, ifname, ifindex)) +			break; +	} -  return nhlfe; +	return nhlfe;  }  /*   * Add NHLFE. Base entry must have been created and duplicate   * check done.   */ -static zebra_nhlfe_t * -nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -           enum nexthop_types_t gtype, union g_addr *gate, -           char *ifname, ifindex_t ifindex, mpls_label_t out_label) +static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				enum nexthop_types_t gtype, union g_addr *gate, +				char *ifname, ifindex_t ifindex, +				mpls_label_t out_label)  { -  zebra_nhlfe_t *nhlfe; -  struct nexthop *nexthop; - -  if (!lsp) -    return NULL; - -  nhlfe = XCALLOC(MTYPE_NHLFE, sizeof(zebra_nhlfe_t)); -  if (!nhlfe) -    return NULL; - -  nhlfe->lsp = lsp; -  nhlfe->type = lsp_type; -  nhlfe->distance = lsp_distance (lsp_type); - -  nexthop = nexthop_new(); -  if (!nexthop) -    { -      XFREE (MTYPE_NHLFE, nhlfe); -      return NULL; -    } -  nexthop_add_labels (nexthop, lsp_type, 1, &out_label); - -  nexthop->type = gtype; -  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: -      nexthop->gate.ipv6 = gate->ipv6; -      if (ifindex) -        nexthop->ifindex = ifindex; -      break; -    default: -      nexthop_free(nexthop); -      XFREE (MTYPE_NHLFE, nhlfe); -      return NULL; -      break; -    } - -  nhlfe->nexthop = nexthop; -  if (lsp->nhlfe_list) -    lsp->nhlfe_list->prev = nhlfe; -  nhlfe->next = lsp->nhlfe_list; -  lsp->nhlfe_list = nhlfe; - -  return nhlfe; +	zebra_nhlfe_t *nhlfe; +	struct nexthop *nexthop; + +	if (!lsp) +		return NULL; + +	nhlfe = XCALLOC(MTYPE_NHLFE, sizeof(zebra_nhlfe_t)); +	if (!nhlfe) +		return NULL; + +	nhlfe->lsp = lsp; +	nhlfe->type = lsp_type; +	nhlfe->distance = lsp_distance(lsp_type); + +	nexthop = nexthop_new(); +	if (!nexthop) { +		XFREE(MTYPE_NHLFE, nhlfe); +		return NULL; +	} +	nexthop_add_labels(nexthop, lsp_type, 1, &out_label); + +	nexthop->type = gtype; +	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: +		nexthop->gate.ipv6 = gate->ipv6; +		if (ifindex) +			nexthop->ifindex = ifindex; +		break; +	default: +		nexthop_free(nexthop); +		XFREE(MTYPE_NHLFE, nhlfe); +		return NULL; +		break; +	} + +	nhlfe->nexthop = nexthop; +	if (lsp->nhlfe_list) +		lsp->nhlfe_list->prev = nhlfe; +	nhlfe->next = lsp->nhlfe_list; +	lsp->nhlfe_list = nhlfe; + +	return nhlfe;  }  /*   * Delete NHLFE. Entry must be present on list.   */ -static int -nhlfe_del (zebra_nhlfe_t *nhlfe) +static int nhlfe_del(zebra_nhlfe_t *nhlfe)  { -  zebra_lsp_t *lsp; +	zebra_lsp_t *lsp; -  if (!nhlfe) -    return -1; +	if (!nhlfe) +		return -1; -  lsp = nhlfe->lsp; -  if (!lsp) -    return -1; +	lsp = nhlfe->lsp; +	if (!lsp) +		return -1; -  /* Free nexthop. */ -  if (nhlfe->nexthop) -    nexthop_free(nhlfe->nexthop); +	/* Free nexthop. */ +	if (nhlfe->nexthop) +		nexthop_free(nhlfe->nexthop); -  /* Unlink from LSP */ -  if (nhlfe->next) -    nhlfe->next->prev = nhlfe->prev; -  if (nhlfe->prev) -    nhlfe->prev->next = nhlfe->next; -  else -    lsp->nhlfe_list = nhlfe->next; +	/* Unlink from LSP */ +	if (nhlfe->next) +		nhlfe->next->prev = nhlfe->prev; +	if (nhlfe->prev) +		nhlfe->prev->next = nhlfe->next; +	else +		lsp->nhlfe_list = nhlfe->next; -  if (nhlfe == lsp->best_nhlfe) -    lsp->best_nhlfe = NULL; +	if (nhlfe == lsp->best_nhlfe) +		lsp->best_nhlfe = NULL; -  XFREE (MTYPE_NHLFE, nhlfe); +	XFREE(MTYPE_NHLFE, nhlfe); -  return 0; +	return 0;  } -static int -mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp, -			enum lsp_types_t type) +static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, +				  enum lsp_types_t type)  { -  zebra_nhlfe_t *nhlfe, *nhlfe_next; -  int schedule_lsp = 0; -  char buf[BUFSIZ]; - -  /* Mark NHLFEs for delete or directly delete, as appropriate. */ -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) -    { -      nhlfe_next = nhlfe->next; - -      /* Skip non-static NHLFEs */ -      if (nhlfe->type != type) -        continue; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          nhlfe2str (nhlfe, buf, BUFSIZ); -          zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x", -                      lsp->ile.in_label, type, buf, nhlfe->flags); -        } - -      if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) -        { -          UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -          SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED); -          schedule_lsp = 1; -        } -      else -        { -          nhlfe_del (nhlfe); -        } -    } - -  /* Queue LSP for processing, if needed, else delete. */ -  if (schedule_lsp) -    { -      if (lsp_processq_add (lsp)) -        return -1; -    } -  else if (!lsp->nhlfe_list && -           !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED)) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("Free LSP in-label %u flags 0x%x", -                    lsp->ile.in_label, lsp->flags); - -      lsp = hash_release(lsp_table, &lsp->ile); -      if (lsp) -        XFREE(MTYPE_LSP, lsp); -    } - -  return 0; +	zebra_nhlfe_t *nhlfe, *nhlfe_next; +	int schedule_lsp = 0; +	char buf[BUFSIZ]; + +	/* Mark NHLFEs for delete or directly delete, as appropriate. */ +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) { +		nhlfe_next = nhlfe->next; + +		/* Skip non-static NHLFEs */ +		if (nhlfe->type != type) +			continue; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			nhlfe2str(nhlfe, buf, BUFSIZ); +			zlog_debug( +				"Del LSP in-label %u type %d nexthop %s flags 0x%x", +				lsp->ile.in_label, type, buf, nhlfe->flags); +		} + +		if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) { +			UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +			SET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); +			schedule_lsp = 1; +		} else { +			nhlfe_del(nhlfe); +		} +	} + +	/* Queue LSP for processing, if needed, else delete. */ +	if (schedule_lsp) { +		if (lsp_processq_add(lsp)) +			return -1; +	} else if (!lsp->nhlfe_list +		   && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug("Free LSP in-label %u flags 0x%x", +				   lsp->ile.in_label, lsp->flags); + +		lsp = hash_release(lsp_table, &lsp->ile); +		if (lsp) +			XFREE(MTYPE_LSP, lsp); +	} + +	return 0;  }  /*   * Uninstall all static NHLFEs for a particular LSP forwarding entry.   * If no other NHLFEs exist, the entry would be deleted.   */ -static int -mpls_static_lsp_uninstall_all (struct zebra_vrf *zvrf, mpls_label_t in_label) +static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf, +					 mpls_label_t in_label)  { -  struct hash *lsp_table; -  zebra_ile_t tmp_ile; -  zebra_lsp_t *lsp; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return -1; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  lsp = hash_lookup (lsp_table, &tmp_ile); -  if (!lsp || !lsp->nhlfe_list) -    return 0; - -  return mpls_lsp_uninstall_all (lsp_table, lsp, ZEBRA_LSP_STATIC); +	struct hash *lsp_table; +	zebra_ile_t tmp_ile; +	zebra_lsp_t *lsp; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return -1; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	lsp = hash_lookup(lsp_table, &tmp_ile); +	if (!lsp || !lsp->nhlfe_list) +		return 0; + +	return mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_STATIC);  } -static json_object * -nhlfe_json (zebra_nhlfe_t *nhlfe) +static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe)  { -  char buf[BUFSIZ]; -  json_object *json_nhlfe = NULL; -  struct nexthop *nexthop = nhlfe->nexthop; - -  json_nhlfe = json_object_new_object(); -  json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type)); -  json_object_int_add(json_nhlfe, "outLabel", nexthop->nh_label->label[0]); -  json_object_int_add(json_nhlfe, "distance", nhlfe->distance); - -  if (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED)) -    json_object_boolean_true_add(json_nhlfe, "installed"); - -  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; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      json_object_string_add(json_nhlfe, "nexthop", -                             inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); - -      if (nexthop->ifindex) -        json_object_string_add(json_nhlfe, "interface", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT)); -      break; -    default: -      break; -    } -  return json_nhlfe; +	char buf[BUFSIZ]; +	json_object *json_nhlfe = NULL; +	struct nexthop *nexthop = nhlfe->nexthop; + +	json_nhlfe = json_object_new_object(); +	json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type)); +	json_object_int_add(json_nhlfe, "outLabel", +			    nexthop->nh_label->label[0]); +	json_object_int_add(json_nhlfe, "distance", nhlfe->distance); + +	if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) +		json_object_boolean_true_add(json_nhlfe, "installed"); + +	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; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		json_object_string_add( +			json_nhlfe, "nexthop", +			inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); + +		if (nexthop->ifindex) +			json_object_string_add( +				json_nhlfe, "interface", +				ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); +		break; +	default: +		break; +	} +	return json_nhlfe;  }  /*   * Print the NHLFE for a LSP forwarding entry.   */ -static void -nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty) +static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty)  { -  struct nexthop *nexthop; -  char buf[BUFSIZ]; - -  nexthop = nhlfe->nexthop; -  if (!nexthop || !nexthop->nh_label) // unexpected -    return; - -  vty_out(vty, " type: %s remote label: %s distance: %d%s", -          nhlfe_type2str(nhlfe->type), -          label2str(nexthop->nh_label->label[0], buf, BUFSIZ), -          nhlfe->distance, VTY_NEWLINE); -  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, VRF_DEFAULT)); -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      vty_out (vty, "  via %s", -               inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -      if (nexthop->ifindex) -        vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT)); -      break; -    default: -      break; -    } -  vty_out(vty, "%s", CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) ? -          " (installed)" : ""); -  vty_out(vty, "%s", VTY_NEWLINE); +	struct nexthop *nexthop; +	char buf[BUFSIZ]; + +	nexthop = nhlfe->nexthop; +	if (!nexthop || !nexthop->nh_label) // unexpected +		return; + +	vty_out(vty, " type: %s remote label: %s distance: %d%s", +		nhlfe_type2str(nhlfe->type), +		label2str(nexthop->nh_label->label[0], buf, BUFSIZ), +		nhlfe->distance, VTY_NEWLINE); +	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, VRF_DEFAULT)); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		vty_out(vty, "  via %s", +			inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); +		if (nexthop->ifindex) +			vty_out(vty, " dev %s", +				ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); +		break; +	default: +		break; +	} +	vty_out(vty, "%s", +		CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) ? " (installed)" +							       : ""); +	vty_out(vty, "%s", VTY_NEWLINE);  }  /*   * Print an LSP forwarding entry.   */ -static void -lsp_print (zebra_lsp_t *lsp, void *ctxt) +static void lsp_print(zebra_lsp_t *lsp, void *ctxt)  { -  zebra_nhlfe_t *nhlfe; -  struct vty *vty; +	zebra_nhlfe_t *nhlfe; +	struct vty *vty; -  vty = (struct vty *) ctxt; +	vty = (struct vty *)ctxt; -  vty_out(vty, "Local label: %u%s%s", -          lsp->ile.in_label, -          CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)" : "", -          VTY_NEWLINE); +	vty_out(vty, "Local label: %u%s%s", lsp->ile.in_label, +		CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)" +							   : "", +		VTY_NEWLINE); -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    nhlfe_print (nhlfe, vty); +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) +		nhlfe_print(nhlfe, vty);  }  /*   * JSON objects for an LSP forwarding entry.   */ -static json_object * -lsp_json (zebra_lsp_t *lsp) +static json_object *lsp_json(zebra_lsp_t *lsp)  { -  zebra_nhlfe_t *nhlfe = NULL; -  json_object *json = json_object_new_object(); -  json_object *json_nhlfe_list = json_object_new_array(); +	zebra_nhlfe_t *nhlfe = NULL; +	json_object *json = json_object_new_object(); +	json_object *json_nhlfe_list = json_object_new_array(); -  json_object_int_add(json, "inLabel", lsp->ile.in_label); +	json_object_int_add(json, "inLabel", lsp->ile.in_label); -  if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) -    json_object_boolean_true_add(json, "installed"); +	if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) +		json_object_boolean_true_add(json, "installed"); -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe)); +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) +		json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe)); -  json_object_object_add(json, "nexthops", json_nhlfe_list); -  return json; +	json_object_object_add(json, "nexthops", json_nhlfe_list); +	return json;  }  /* Return a sorted linked list of the hash contents */ -static struct list * -hash_get_sorted_list (struct hash *hash, void *cmp) +static struct list *hash_get_sorted_list(struct hash *hash, void *cmp)  { -  unsigned int i; -  struct hash_backet *hb; -  struct list *sorted_list = list_new(); +	unsigned int i; +	struct hash_backet *hb; +	struct list *sorted_list = list_new(); -  sorted_list->cmp = (int (*)(void *, void *)) cmp; +	sorted_list->cmp = (int (*)(void *, void *))cmp; -  for (i = 0; i < hash->size; i++) -    for (hb = hash->index[i]; hb; hb = hb->next) -        listnode_add_sort(sorted_list, hb->data); +	for (i = 0; i < hash->size; i++) +		for (hb = hash->index[i]; hb; hb = hb->next) +			listnode_add_sort(sorted_list, hb->data); -  return sorted_list; +	return sorted_list;  }  /*   * Compare two LSPs based on their label values.   */ -static int -lsp_cmp (zebra_lsp_t *lsp1, zebra_lsp_t *lsp2) +static int lsp_cmp(zebra_lsp_t *lsp1, zebra_lsp_t *lsp2)  { -  if (lsp1->ile.in_label < lsp2->ile.in_label) -    return -1; +	if (lsp1->ile.in_label < lsp2->ile.in_label) +		return -1; -  if (lsp1->ile.in_label > lsp2->ile.in_label) -    return 1; +	if (lsp1->ile.in_label > lsp2->ile.in_label) +		return 1; -  return 0; +	return 0;  }  /*   * Callback to allocate static LSP.   */ -static void * -slsp_alloc (void *p) +static void *slsp_alloc(void *p)  { -  const zebra_ile_t *ile = p; -  zebra_slsp_t *slsp; +	const zebra_ile_t *ile = p; +	zebra_slsp_t *slsp; -  slsp = XCALLOC (MTYPE_SLSP, sizeof(zebra_slsp_t)); -  slsp->ile = *ile; -  return ((void *)slsp); +	slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t)); +	slsp->ile = *ile; +	return ((void *)slsp);  }  /*   * Compare two static LSPs based on their label values.   */ -static int -slsp_cmp (zebra_slsp_t *slsp1, zebra_slsp_t *slsp2) +static int slsp_cmp(zebra_slsp_t *slsp1, zebra_slsp_t *slsp2)  { -  if (slsp1->ile.in_label < slsp2->ile.in_label) -    return -1; +	if (slsp1->ile.in_label < slsp2->ile.in_label) +		return -1; -  if (slsp1->ile.in_label > slsp2->ile.in_label) -    return 1; +	if (slsp1->ile.in_label > slsp2->ile.in_label) +		return 1; -  return 0; +	return 0;  }  /*   * Check if static NHLFE matches with search info passed.   */ -static int -snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, -              union g_addr *gate, char *ifname, ifindex_t ifindex) +static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, +			union g_addr *gate, char *ifname, ifindex_t ifindex)  { -  int cmp = 1; - -  if (snhlfe->gtype != gtype) -    return 1; - -  switch (snhlfe->gtype) -    { -    case NEXTHOP_TYPE_IPV4: -      cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4), -		   sizeof(struct in_addr)); -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6), -		   sizeof(struct in6_addr)); -      if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX) -        cmp = !(snhlfe->ifindex == ifindex); -      break; -    default: -      break; -    } - -  return cmp; +	int cmp = 1; + +	if (snhlfe->gtype != gtype) +		return 1; + +	switch (snhlfe->gtype) { +	case NEXTHOP_TYPE_IPV4: +		cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4), +			     sizeof(struct in_addr)); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6), +			     sizeof(struct in6_addr)); +		if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX) +			cmp = !(snhlfe->ifindex == ifindex); +		break; +	default: +		break; +	} + +	return cmp;  }  /*   * Locate static NHLFE that matches with passed info.   */ -static zebra_snhlfe_t * -snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -             union g_addr *gate, char *ifname, ifindex_t ifindex) +static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, +				   enum nexthop_types_t gtype, +				   union g_addr *gate, char *ifname, +				   ifindex_t ifindex)  { -  zebra_snhlfe_t *snhlfe; +	zebra_snhlfe_t *snhlfe; -  if (!slsp) -    return NULL; +	if (!slsp) +		return NULL; -  for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) -    { -      if (!snhlfe_match (snhlfe, gtype, gate, ifname, ifindex)) -        break; -    } +	for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) { +		if (!snhlfe_match(snhlfe, gtype, gate, ifname, ifindex)) +			break; +	} -  return snhlfe; +	return snhlfe;  } @@ -1079,140 +1010,132 @@ snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,   * Add static NHLFE. Base LSP config entry must have been created   * and duplicate check done.   */ -static zebra_snhlfe_t * -snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -            union g_addr *gate, char *ifname, ifindex_t ifindex, -            mpls_label_t out_label) +static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, +				  enum nexthop_types_t gtype, +				  union g_addr *gate, char *ifname, +				  ifindex_t ifindex, mpls_label_t out_label)  { -  zebra_snhlfe_t *snhlfe; - -  if (!slsp) -    return NULL; - -  snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t)); -  snhlfe->slsp = slsp; -  snhlfe->out_label = out_label; -  snhlfe->gtype = gtype; -  switch (gtype) -    { -    case NEXTHOP_TYPE_IPV4: -      snhlfe->gate.ipv4 = gate->ipv4; -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      snhlfe->gate.ipv6 = gate->ipv6; -      if (ifindex) -        snhlfe->ifindex = ifindex; -      break; -    default: -      XFREE (MTYPE_SNHLFE, snhlfe); -      return NULL; -    } - -  if (slsp->snhlfe_list) -    slsp->snhlfe_list->prev = snhlfe; -  snhlfe->next = slsp->snhlfe_list; -  slsp->snhlfe_list = snhlfe; - -  return snhlfe; +	zebra_snhlfe_t *snhlfe; + +	if (!slsp) +		return NULL; + +	snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t)); +	snhlfe->slsp = slsp; +	snhlfe->out_label = out_label; +	snhlfe->gtype = gtype; +	switch (gtype) { +	case NEXTHOP_TYPE_IPV4: +		snhlfe->gate.ipv4 = gate->ipv4; +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		snhlfe->gate.ipv6 = gate->ipv6; +		if (ifindex) +			snhlfe->ifindex = ifindex; +		break; +	default: +		XFREE(MTYPE_SNHLFE, snhlfe); +		return NULL; +	} + +	if (slsp->snhlfe_list) +		slsp->snhlfe_list->prev = snhlfe; +	snhlfe->next = slsp->snhlfe_list; +	slsp->snhlfe_list = snhlfe; + +	return snhlfe;  }  /*   * Delete static NHLFE. Entry must be present on list.   */ -static int -snhlfe_del (zebra_snhlfe_t *snhlfe) +static int snhlfe_del(zebra_snhlfe_t *snhlfe)  { -  zebra_slsp_t *slsp; +	zebra_slsp_t *slsp; -  if (!snhlfe) -    return -1; +	if (!snhlfe) +		return -1; -  slsp = snhlfe->slsp; -  if (!slsp) -    return -1; +	slsp = snhlfe->slsp; +	if (!slsp) +		return -1; -  if (snhlfe->next) -    snhlfe->next->prev = snhlfe->prev; -  if (snhlfe->prev) -    snhlfe->prev->next = snhlfe->next; -  else -    slsp->snhlfe_list = snhlfe->next; +	if (snhlfe->next) +		snhlfe->next->prev = snhlfe->prev; +	if (snhlfe->prev) +		snhlfe->prev->next = snhlfe->next; +	else +		slsp->snhlfe_list = snhlfe->next; -  snhlfe->prev = snhlfe->next = NULL; -  if (snhlfe->ifname) -    XFREE (MTYPE_SNHLFE_IFNAME, snhlfe->ifname); -  XFREE (MTYPE_SNHLFE, snhlfe); +	snhlfe->prev = snhlfe->next = NULL; +	if (snhlfe->ifname) +		XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname); +	XFREE(MTYPE_SNHLFE, snhlfe); -  return 0; +	return 0;  }  /*   * Delete all static NHLFE entries for this LSP (in label).   */ -static int -snhlfe_del_all (zebra_slsp_t *slsp) +static int snhlfe_del_all(zebra_slsp_t *slsp)  { -  zebra_snhlfe_t *snhlfe, *snhlfe_next; +	zebra_snhlfe_t *snhlfe, *snhlfe_next; -  if (!slsp) -    return -1; +	if (!slsp) +		return -1; -  for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe_next) -    { -      snhlfe_next = snhlfe->next; -      snhlfe_del (snhlfe); -    } +	for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe_next) { +		snhlfe_next = snhlfe->next; +		snhlfe_del(snhlfe); +	} -  return 0; +	return 0;  }  /*   * Create printable string for NHLFE configuration.   */ -static char * -snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size) +static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size)  { -  buf[0] = '\0'; -  switch (snhlfe->gtype) -    { -      case NEXTHOP_TYPE_IPV4: -        inet_ntop (AF_INET, &snhlfe->gate.ipv4, buf, size); -        break; -      case NEXTHOP_TYPE_IPV6: -      case NEXTHOP_TYPE_IPV6_IFINDEX: -        inet_ntop (AF_INET6, &snhlfe->gate.ipv6, buf, size); -        if (snhlfe->ifindex) -          strcat (buf, ifindex2ifname (snhlfe->ifindex, VRF_DEFAULT)); -        break; -      default: -        break; -    } - -  return buf; +	buf[0] = '\0'; +	switch (snhlfe->gtype) { +	case NEXTHOP_TYPE_IPV4: +		inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size); +		if (snhlfe->ifindex) +			strcat(buf, +			       ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT)); +		break; +	default: +		break; +	} + +	return buf;  }  /*   * Initialize work queue for processing changed LSPs.   */ -static void -mpls_processq_init (struct zebra_t *zebra) +static void mpls_processq_init(struct zebra_t *zebra)  { -  zebra->lsp_process_q = work_queue_new (zebra->master, "LSP processing"); -  if (!zebra->lsp_process_q) -    { -      zlog_err ("%s: could not initialise work queue!", __func__); -      return; -    } - -  zebra->lsp_process_q->spec.workfunc = &lsp_process; -  zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del; -  zebra->lsp_process_q->spec.errorfunc = NULL; -  zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete; -  zebra->lsp_process_q->spec.max_retries = 0; -  zebra->lsp_process_q->spec.hold = 10; -} +	zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing"); +	if (!zebra->lsp_process_q) { +		zlog_err("%s: could not initialise work queue!", __func__); +		return; +	} +	zebra->lsp_process_q->spec.workfunc = &lsp_process; +	zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del; +	zebra->lsp_process_q->spec.errorfunc = NULL; +	zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete; +	zebra->lsp_process_q->spec.max_retries = 0; +	zebra->lsp_process_q->spec.hold = 10; +}  /* Public functions */ @@ -1220,136 +1143,132 @@ mpls_processq_init (struct zebra_t *zebra)  /*   * String to label conversion, labels separated by '/'.   */ -int -mpls_str2label (const char *label_str, u_int8_t *num_labels, -                mpls_label_t *labels) +int mpls_str2label(const char *label_str, u_int8_t *num_labels, +		   mpls_label_t *labels)  { -  char *endp; -  int i; +	char *endp; +	int i; -  *num_labels = 0; -  for (i = 0; i < MPLS_MAX_LABELS; i++) -    { -      u_int32_t label; +	*num_labels = 0; +	for (i = 0; i < MPLS_MAX_LABELS; i++) { +		u_int32_t label; -      label = strtoul(label_str, &endp, 0); +		label = strtoul(label_str, &endp, 0); -      /* validity checks */ -      if (endp == label_str) -        return -1; +		/* validity checks */ +		if (endp == label_str) +			return -1; -      if (!IS_MPLS_UNRESERVED_LABEL(label)) -        return -1; +		if (!IS_MPLS_UNRESERVED_LABEL(label)) +			return -1; -      labels[i] = label; -      if (*endp == '\0') -        { -          *num_labels = i + 1; -          return 0; -        } +		labels[i] = label; +		if (*endp == '\0') { +			*num_labels = i + 1; +			return 0; +		} -      /* Check separator. */ -      if (*endp != '/') -        return -1; +		/* Check separator. */ +		if (*endp != '/') +			return -1; -      label_str = endp + 1; -    } +		label_str = endp + 1; +	} -  /* Too many labels. */ -  return -1; +	/* Too many labels. */ +	return -1;  }  /*   * Label to string conversion, labels in string separated by '/'.   */ -char * -mpls_label2str (u_int8_t num_labels, mpls_label_t *labels, -                char *buf, int len) +char *mpls_label2str(u_int8_t num_labels, mpls_label_t *labels, char *buf, +		     int len)  { -  buf[0] = '\0'; -  if (num_labels == 1) -    snprintf (buf, len, "%u", labels[0]); -  else if (num_labels == 2) -    snprintf (buf, len, "%u/%u", labels[0], labels[1]); -  return buf; +	buf[0] = '\0'; +	if (num_labels == 1) +		snprintf(buf, len, "%u", labels[0]); +	else if (num_labels == 2) +		snprintf(buf, len, "%u/%u", labels[0], labels[1]); +	return buf;  }  /*   * Install/uninstall a FEC-To-NHLFE (FTN) binding.   */ -int -mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type, -		 struct prefix *prefix, enum nexthop_types_t gtype, -		 union g_addr *gate, ifindex_t ifindex, u_int8_t distance, -		 mpls_label_t out_label) +int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type, +		    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; -  struct route_node *rn; -  struct rib *rib; -  struct nexthop *nexthop; - -  /* Lookup table.  */ -  table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf_id (zvrf)); -  if (! table) -    return -1; - -  /* Lookup existing route */ -  rn = route_node_get (table, prefix); -  RNODE_FOREACH_RIB (rn, rib) -    { -       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -         continue; -       if (rib->distance == distance) -         break; -    } - -  if (rib == NULL) -    return -1; - -  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -    { -      switch (nexthop->type) +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct nexthop *nexthop; + +	/* Lookup table.  */ +	table = zebra_vrf_table(family2afi(prefix->family), SAFI_UNICAST, +				zvrf_id(zvrf)); +	if (!table) +		return -1; + +	/* Lookup existing route */ +	rn = route_node_get(table, prefix); +	RNODE_FOREACH_RIB(rn, rib)  	{ -	case NEXTHOP_TYPE_IPV4: -	case NEXTHOP_TYPE_IPV4_IFINDEX: -	  if (gtype != NEXTHOP_TYPE_IPV4 && gtype != NEXTHOP_TYPE_IPV4_IFINDEX) -	    continue; -	  if (! IPV4_ADDR_SAME (&nexthop->gate.ipv4, &gate->ipv4)) -	    continue; -	  if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX && -	      nexthop->ifindex != ifindex) -	    continue; -	  goto found; -	case NEXTHOP_TYPE_IPV6: -	case NEXTHOP_TYPE_IPV6_IFINDEX: -	  if (gtype != NEXTHOP_TYPE_IPV6 && gtype != NEXTHOP_TYPE_IPV6_IFINDEX) -	    continue; -	  if (! IPV6_ADDR_SAME (&nexthop->gate.ipv6, &gate->ipv6)) -	    continue; -	  if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX && -	      nexthop->ifindex != ifindex) -	    continue; -	  goto found; -	default: -	  break; +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +			continue; +		if (rib->distance == distance) +			break;  	} -    } -  /* nexthop not found */ -  return -1; - - found: -  if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE) -    nexthop_add_labels (nexthop, type, 1, &out_label); -  else if (!add && nexthop->nh_label_type == type) -    nexthop_del_labels (nexthop); -  else -    return 0; - -  SET_FLAG (rib->status, RIB_ENTRY_CHANGED); -  SET_FLAG (rib->status, RIB_ENTRY_LABELS_CHANGED); -  rib_queue_add (rn); - -  return 0; + +	if (rib == NULL) +		return -1; + +	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { +		switch (nexthop->type) { +		case NEXTHOP_TYPE_IPV4: +		case NEXTHOP_TYPE_IPV4_IFINDEX: +			if (gtype != NEXTHOP_TYPE_IPV4 +			    && gtype != NEXTHOP_TYPE_IPV4_IFINDEX) +				continue; +			if (!IPV4_ADDR_SAME(&nexthop->gate.ipv4, &gate->ipv4)) +				continue; +			if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX +			    && nexthop->ifindex != ifindex) +				continue; +			goto found; +		case NEXTHOP_TYPE_IPV6: +		case NEXTHOP_TYPE_IPV6_IFINDEX: +			if (gtype != NEXTHOP_TYPE_IPV6 +			    && gtype != NEXTHOP_TYPE_IPV6_IFINDEX) +				continue; +			if (!IPV6_ADDR_SAME(&nexthop->gate.ipv6, &gate->ipv6)) +				continue; +			if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX +			    && nexthop->ifindex != ifindex) +				continue; +			goto found; +		default: +			break; +		} +	} +	/* nexthop not found */ +	return -1; + +found: +	if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE) +		nexthop_add_labels(nexthop, type, 1, &out_label); +	else if (!add && nexthop->nh_label_type == type) +		nexthop_del_labels(nexthop); +	else +		return 0; + +	SET_FLAG(rib->status, RIB_ENTRY_CHANGED); +	SET_FLAG(rib->status, RIB_ENTRY_LABELS_CHANGED); +	rib_queue_add(rn); + +	return 0;  }  /* @@ -1357,198 +1276,185 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,   * a new LSP entry or a new NHLFE for an existing in-label or an update of   * the out-label for an existing NHLFE (update case).   */ -int -mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type, -		  mpls_label_t in_label, mpls_label_t out_label, -		  enum nexthop_types_t gtype, union g_addr *gate, -		  char *ifname, ifindex_t ifindex) +int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type, +		     mpls_label_t in_label, mpls_label_t out_label, +		     enum nexthop_types_t gtype, union g_addr *gate, +		     char *ifname, ifindex_t ifindex)  { -  struct hash *lsp_table; -  zebra_ile_t tmp_ile; -  zebra_lsp_t *lsp; -  zebra_nhlfe_t *nhlfe; -  char buf[BUFSIZ]; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return -1; - -  /* If entry is present, exit. */ -  tmp_ile.in_label = in_label; -  lsp = hash_get (lsp_table, &tmp_ile, lsp_alloc); -  if (!lsp) -    return -1; -  nhlfe = nhlfe_find (lsp, type, gtype, gate, ifname, ifindex); -  if (nhlfe) -    { -      struct nexthop *nh = nhlfe->nexthop; - -      assert (nh); -      assert (nh->nh_label); - -      /* Clear deleted flag (in case it was set) */ -      UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED); -      if (nh->nh_label->label[0] == out_label) -        /* No change */ -        return 0; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          nhlfe2str (nhlfe, buf, BUFSIZ); -          zlog_debug ("LSP in-label %u type %d nexthop %s " -                      "out-label changed to %u (old %u)", -                      in_label, type, buf, -                      out_label, nh->nh_label->label[0]); -        } - -      /* Update out label, trigger processing. */ -      nh->nh_label->label[0] = out_label; -    } -  else -    { -      /* Add LSP entry to this nexthop */ -      nhlfe = nhlfe_add (lsp, type, gtype, gate, -                         ifname, ifindex, out_label); -      if (!nhlfe) -        return -1; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          nhlfe2str (nhlfe, buf, BUFSIZ); -          zlog_debug ("Add LSP in-label %u type %d nexthop %s " -                      "out-label %u", in_label, type, buf, out_label); -        } - -      lsp->addr_family = NHLFE_FAMILY (nhlfe); -    } - -  /* Mark NHLFE, queue LSP for processing. */ -  SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); -  if (lsp_processq_add (lsp)) -    return -1; - -  return 0; +	struct hash *lsp_table; +	zebra_ile_t tmp_ile; +	zebra_lsp_t *lsp; +	zebra_nhlfe_t *nhlfe; +	char buf[BUFSIZ]; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return -1; + +	/* If entry is present, exit. */ +	tmp_ile.in_label = in_label; +	lsp = hash_get(lsp_table, &tmp_ile, lsp_alloc); +	if (!lsp) +		return -1; +	nhlfe = nhlfe_find(lsp, type, gtype, gate, ifname, ifindex); +	if (nhlfe) { +		struct nexthop *nh = nhlfe->nexthop; + +		assert(nh); +		assert(nh->nh_label); + +		/* Clear deleted flag (in case it was set) */ +		UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); +		if (nh->nh_label->label[0] == out_label) +			/* No change */ +			return 0; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			nhlfe2str(nhlfe, buf, BUFSIZ); +			zlog_debug( +				"LSP in-label %u type %d nexthop %s " +				"out-label changed to %u (old %u)", +				in_label, type, buf, out_label, +				nh->nh_label->label[0]); +		} + +		/* Update out label, trigger processing. */ +		nh->nh_label->label[0] = out_label; +	} else { +		/* Add LSP entry to this nexthop */ +		nhlfe = nhlfe_add(lsp, type, gtype, gate, ifname, ifindex, +				  out_label); +		if (!nhlfe) +			return -1; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			nhlfe2str(nhlfe, buf, BUFSIZ); +			zlog_debug( +				"Add LSP in-label %u type %d nexthop %s " +				"out-label %u", +				in_label, type, buf, out_label); +		} + +		lsp->addr_family = NHLFE_FAMILY(nhlfe); +	} + +	/* Mark NHLFE, queue LSP for processing. */ +	SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +	if (lsp_processq_add(lsp)) +		return -1; + +	return 0;  }  /*   * Uninstall a particular NHLFE in the forwarding table. If this is   * the only NHLFE, the entire LSP forwarding entry has to be deleted.   */ -int -mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type, -		    mpls_label_t in_label, enum nexthop_types_t gtype, -		    union g_addr *gate, char *ifname, ifindex_t ifindex) +int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type, +		       mpls_label_t in_label, enum nexthop_types_t gtype, +		       union g_addr *gate, char *ifname, ifindex_t ifindex)  { -  struct hash *lsp_table; -  zebra_ile_t tmp_ile; -  zebra_lsp_t *lsp; -  zebra_nhlfe_t *nhlfe; -  char buf[BUFSIZ]; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return -1; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  lsp = hash_lookup (lsp_table, &tmp_ile); -  if (!lsp) -    return 0; -  nhlfe = nhlfe_find (lsp, type, gtype, gate, ifname, ifindex); -  if (!nhlfe) -    return 0; - -  if (IS_ZEBRA_DEBUG_MPLS) -    { -      nhlfe2str (nhlfe, buf, BUFSIZ); -      zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x", -                  in_label, type, buf, nhlfe->flags); -    } - -  /* Mark NHLFE for delete or directly delete, as appropriate. */ -  if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) -    { -      UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -      SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED); -      if (lsp_processq_add (lsp)) -        return -1; -    } -  else -    { -      nhlfe_del (nhlfe); - -      /* Free LSP entry if no other NHLFEs and not scheduled. */ -      if (!lsp->nhlfe_list && -          !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED)) -        { -          if (IS_ZEBRA_DEBUG_MPLS) -            zlog_debug ("Free LSP in-label %u flags 0x%x", -                        lsp->ile.in_label, lsp->flags); - -          lsp = hash_release(lsp_table, &lsp->ile); -          if (lsp) -            XFREE(MTYPE_LSP, lsp); -        } -    } -  return 0; +	struct hash *lsp_table; +	zebra_ile_t tmp_ile; +	zebra_lsp_t *lsp; +	zebra_nhlfe_t *nhlfe; +	char buf[BUFSIZ]; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return -1; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	lsp = hash_lookup(lsp_table, &tmp_ile); +	if (!lsp) +		return 0; +	nhlfe = nhlfe_find(lsp, type, gtype, gate, ifname, ifindex); +	if (!nhlfe) +		return 0; + +	if (IS_ZEBRA_DEBUG_MPLS) { +		nhlfe2str(nhlfe, buf, BUFSIZ); +		zlog_debug("Del LSP in-label %u type %d nexthop %s flags 0x%x", +			   in_label, type, buf, nhlfe->flags); +	} + +	/* Mark NHLFE for delete or directly delete, as appropriate. */ +	if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) { +		UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +		SET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); +		if (lsp_processq_add(lsp)) +			return -1; +	} else { +		nhlfe_del(nhlfe); + +		/* Free LSP entry if no other NHLFEs and not scheduled. */ +		if (!lsp->nhlfe_list +		    && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) { +			if (IS_ZEBRA_DEBUG_MPLS) +				zlog_debug("Free LSP in-label %u flags 0x%x", +					   lsp->ile.in_label, lsp->flags); + +			lsp = hash_release(lsp_table, &lsp->ile); +			if (lsp) +				XFREE(MTYPE_LSP, lsp); +		} +	} +	return 0;  }  /*   * Uninstall all LDP NHLFEs for a particular LSP forwarding entry.   * If no other NHLFEs exist, the entry would be deleted.   */ -void -mpls_ldp_lsp_uninstall_all (struct hash_backet *backet, void *ctxt) +void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt)  { -  zebra_lsp_t *lsp; -  struct hash *lsp_table; +	zebra_lsp_t *lsp; +	struct hash *lsp_table; -  lsp = (zebra_lsp_t *) backet->data; -  if (!lsp || !lsp->nhlfe_list) -    return; +	lsp = (zebra_lsp_t *)backet->data; +	if (!lsp || !lsp->nhlfe_list) +		return; -  lsp_table = ctxt; -  if (!lsp_table) -    return; +	lsp_table = ctxt; +	if (!lsp_table) +		return; -  mpls_lsp_uninstall_all (lsp_table, lsp, ZEBRA_LSP_LDP); +	mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_LDP);  }  /*   * Uninstall all LDP FEC-To-NHLFE (FTN) bindings of the given address-family.   */ -void -mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi) +void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct nexthop *nexthop; -  int update; - -  /* Process routes of interested address-families. */ -  table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf)); -  if (!table) -    return; - -  for (rn = route_top (table); rn; rn = route_next (rn)) -    { -      update = 0; -      RNODE_FOREACH_RIB (rn, rib) -	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -	  if (nexthop->nh_label_type == ZEBRA_LSP_LDP) -	    { -	      nexthop_del_labels (nexthop); -	      SET_FLAG (rib->status, RIB_ENTRY_CHANGED); -	      SET_FLAG (rib->status, RIB_ENTRY_LABELS_CHANGED); -	      update = 1; -	    } - -      if (update) -	rib_queue_add (rn); -    } +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct nexthop *nexthop; +	int update; + +	/* Process routes of interested address-families. */ +	table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf)); +	if (!table) +		return; + +	for (rn = route_top(table); rn; rn = route_next(rn)) { +		update = 0; +		RNODE_FOREACH_RIB(rn, rib) +		for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) +			if (nexthop->nh_label_type == ZEBRA_LSP_LDP) { +				nexthop_del_labels(nexthop); +				SET_FLAG(rib->status, RIB_ENTRY_CHANGED); +				SET_FLAG(rib->status, RIB_ENTRY_LABELS_CHANGED); +				update = 1; +			} + +		if (update) +			rib_queue_add(rn); +	}  }  #if defined(HAVE_CUMULUS) @@ -1558,54 +1464,52 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)   * be consistent - i.e., all paths either do a swap or do PHP. This is due   * to current HW restrictions.   */ -int -zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label, -                     mpls_label_t out_label, enum nexthop_types_t gtype, -                     union g_addr *gate, char *ifname, ifindex_t ifindex) +int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, +				    mpls_label_t in_label, +				    mpls_label_t out_label, +				    enum nexthop_types_t gtype, +				    union g_addr *gate, char *ifname, +				    ifindex_t ifindex)  { -  struct hash *slsp_table; -  zebra_ile_t tmp_ile; -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; - -  /* Lookup table. */ -  slsp_table = zvrf->slsp_table; -  if (!slsp_table) -    return 0; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  slsp = hash_lookup (slsp_table, &tmp_ile); -  if (!slsp) -    return 1; - -  snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex); -  if (snhlfe) -    { -      if (snhlfe->out_label == out_label) -        return 1; - -      /* If not only NHLFE, cannot allow label change. */ -      if (snhlfe != slsp->snhlfe_list || -          snhlfe->next) -        return 0; -    } -  else -    { -      /* If other NHLFEs exist, label operation must match. */ -      if (slsp->snhlfe_list) -        { -          int cur_op, new_op; - -          cur_op = (slsp->snhlfe_list->out_label == MPLS_IMP_NULL_LABEL); -          new_op = (out_label == MPLS_IMP_NULL_LABEL); -          if (cur_op != new_op) -            return 0; -        } -    } - -  /* Label values are good. */ -  return 1; +	struct hash *slsp_table; +	zebra_ile_t tmp_ile; +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; + +	/* Lookup table. */ +	slsp_table = zvrf->slsp_table; +	if (!slsp_table) +		return 0; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	slsp = hash_lookup(slsp_table, &tmp_ile); +	if (!slsp) +		return 1; + +	snhlfe = snhlfe_find(slsp, gtype, gate, ifname, ifindex); +	if (snhlfe) { +		if (snhlfe->out_label == out_label) +			return 1; + +		/* If not only NHLFE, cannot allow label change. */ +		if (snhlfe != slsp->snhlfe_list || snhlfe->next) +			return 0; +	} else { +		/* If other NHLFEs exist, label operation must match. */ +		if (slsp->snhlfe_list) { +			int cur_op, new_op; + +			cur_op = (slsp->snhlfe_list->out_label +				  == MPLS_IMP_NULL_LABEL); +			new_op = (out_label == MPLS_IMP_NULL_LABEL); +			if (cur_op != new_op) +				return 0; +		} +	} + +	/* Label values are good. */ +	return 1;  }  #endif /* HAVE_CUMULUS */ @@ -1616,64 +1520,62 @@ zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,   * Note: The label operation (swap or PHP) is common for the LSP entry (all   * NHLFEs).   */ -int -zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label, -                     mpls_label_t out_label, enum nexthop_types_t gtype, -                     union g_addr *gate, char *ifname, ifindex_t ifindex) +int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, +			      mpls_label_t out_label, +			      enum nexthop_types_t gtype, union g_addr *gate, +			      char *ifname, ifindex_t ifindex)  { -  struct hash *slsp_table; -  zebra_ile_t tmp_ile; -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; -  char buf[BUFSIZ]; - -  /* Lookup table. */ -  slsp_table = zvrf->slsp_table; -  if (!slsp_table) -    return -1; - -  /* If entry is present, exit. */ -  tmp_ile.in_label = in_label; -  slsp = hash_get (slsp_table, &tmp_ile, slsp_alloc); -  if (!slsp) -    return -1; -  snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex); -  if (snhlfe) -    { -      if (snhlfe->out_label == out_label) -        /* No change */ -        return 0; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          snhlfe2str (snhlfe, buf, BUFSIZ); -          zlog_debug ("Upd static LSP in-label %u nexthop %s " -                      "out-label %u (old %u)", -                      in_label, buf, out_label, snhlfe->out_label); -        } -      snhlfe->out_label = out_label; -    } -  else -    { -      /* Add static LSP entry to this nexthop */ -      snhlfe = snhlfe_add (slsp, gtype, gate, ifname, ifindex, out_label); -      if (!snhlfe) -        return -1; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          snhlfe2str (snhlfe, buf, BUFSIZ); -          zlog_debug ("Add static LSP in-label %u nexthop %s out-label %u", -                      in_label, buf, out_label); -        } -    } - -  /* (Re)Install LSP in the main table. */ -  if (mpls_lsp_install (zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype, -      gate, ifname, ifindex)) -    return -1; - -  return 0; +	struct hash *slsp_table; +	zebra_ile_t tmp_ile; +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; +	char buf[BUFSIZ]; + +	/* Lookup table. */ +	slsp_table = zvrf->slsp_table; +	if (!slsp_table) +		return -1; + +	/* If entry is present, exit. */ +	tmp_ile.in_label = in_label; +	slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc); +	if (!slsp) +		return -1; +	snhlfe = snhlfe_find(slsp, gtype, gate, ifname, ifindex); +	if (snhlfe) { +		if (snhlfe->out_label == out_label) +			/* No change */ +			return 0; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			snhlfe2str(snhlfe, buf, BUFSIZ); +			zlog_debug( +				"Upd static LSP in-label %u nexthop %s " +				"out-label %u (old %u)", +				in_label, buf, out_label, snhlfe->out_label); +		} +		snhlfe->out_label = out_label; +	} else { +		/* Add static LSP entry to this nexthop */ +		snhlfe = snhlfe_add(slsp, gtype, gate, ifname, ifindex, +				    out_label); +		if (!snhlfe) +			return -1; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			snhlfe2str(snhlfe, buf, BUFSIZ); +			zlog_debug( +				"Add static LSP in-label %u nexthop %s out-label %u", +				in_label, buf, out_label); +		} +	} + +	/* (Re)Install LSP in the main table. */ +	if (mpls_lsp_install(zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype, +			     gate, ifname, ifindex)) +		return -1; + +	return 0;  }  /* @@ -1683,71 +1585,66 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,   * NOTE: Delete of the only NHLFE will also end up deleting the entire   * LSP configuration.   */ -int -zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label, -                           enum nexthop_types_t gtype, union g_addr *gate, -                           char *ifname, ifindex_t ifindex) +int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, +			      enum nexthop_types_t gtype, union g_addr *gate, +			      char *ifname, ifindex_t ifindex)  { -  struct hash *slsp_table; -  zebra_ile_t tmp_ile; -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; - -  /* Lookup table. */ -  slsp_table = zvrf->slsp_table; -  if (!slsp_table) -    return -1; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  slsp = hash_lookup (slsp_table, &tmp_ile); -  if (!slsp) -    return 0; - -  /* Is it delete of entire LSP or a specific NHLFE? */ -  if (gtype == NEXTHOP_TYPE_BLACKHOLE) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("Del static LSP in-label %u", in_label); - -      /* Uninstall entire LSP from the main table. */ -      mpls_static_lsp_uninstall_all (zvrf, in_label); - -      /* Delete all static NHLFEs */ -      snhlfe_del_all (slsp); -    } -  else -    { -      /* Find specific NHLFE, exit if not found. */ -      snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex); -      if (!snhlfe) -        return 0; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          char buf[BUFSIZ]; -          snhlfe2str (snhlfe, buf, BUFSIZ); -          zlog_debug ("Del static LSP in-label %u nexthop %s", -                      in_label, buf); -        } - -      /* Uninstall LSP from the main table. */ -      mpls_lsp_uninstall (zvrf, ZEBRA_LSP_STATIC, in_label, gtype, gate, -			  ifname, ifindex); - -      /* Delete static LSP NHLFE */ -      snhlfe_del (snhlfe); -    } - -  /* Remove entire static LSP entry if no NHLFE - valid in either case above. */ -  if (!slsp->snhlfe_list) -    { -      slsp = hash_release(slsp_table, &tmp_ile); -      if (slsp) -        XFREE(MTYPE_SLSP, slsp); -    } - -  return 0; +	struct hash *slsp_table; +	zebra_ile_t tmp_ile; +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; + +	/* Lookup table. */ +	slsp_table = zvrf->slsp_table; +	if (!slsp_table) +		return -1; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	slsp = hash_lookup(slsp_table, &tmp_ile); +	if (!slsp) +		return 0; + +	/* Is it delete of entire LSP or a specific NHLFE? */ +	if (gtype == NEXTHOP_TYPE_BLACKHOLE) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug("Del static LSP in-label %u", in_label); + +		/* Uninstall entire LSP from the main table. */ +		mpls_static_lsp_uninstall_all(zvrf, in_label); + +		/* Delete all static NHLFEs */ +		snhlfe_del_all(slsp); +	} else { +		/* Find specific NHLFE, exit if not found. */ +		snhlfe = snhlfe_find(slsp, gtype, gate, ifname, ifindex); +		if (!snhlfe) +			return 0; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			char buf[BUFSIZ]; +			snhlfe2str(snhlfe, buf, BUFSIZ); +			zlog_debug("Del static LSP in-label %u nexthop %s", +				   in_label, buf); +		} + +		/* Uninstall LSP from the main table. */ +		mpls_lsp_uninstall(zvrf, ZEBRA_LSP_STATIC, in_label, gtype, +				   gate, ifname, ifindex); + +		/* Delete static LSP NHLFE */ +		snhlfe_del(snhlfe); +	} + +	/* Remove entire static LSP entry if no NHLFE - valid in either case +	 * above. */ +	if (!slsp->snhlfe_list) { +		slsp = hash_release(slsp_table, &tmp_ile); +		if (slsp) +			XFREE(MTYPE_SLSP, slsp); +	} + +	return 0;  }  /* @@ -1755,150 +1652,154 @@ zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,   * Called upon changes that may affect one or more of them such as   * interface or nexthop state changes.   */ -void -zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf) +void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return; -  hash_iterate(zvrf->lsp_table, lsp_schedule, NULL); +	if (!zvrf) +		return; +	hash_iterate(zvrf->lsp_table, lsp_schedule, NULL);  }  /*   * Display MPLS label forwarding table for a specific LSP   * (VTY command handler).   */ -void -zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label, -                      u_char use_json) +void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf, +			  mpls_label_t label, u_char use_json)  { -  struct hash *lsp_table; -  zebra_lsp_t *lsp; -  zebra_ile_t tmp_ile; -  json_object *json = NULL; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = label; -  lsp = hash_lookup (lsp_table, &tmp_ile); -  if (!lsp) -    return; - -  if (use_json) -    { -      json = lsp_json(lsp); -      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); -      json_object_free(json); -    } -  else -    lsp_print (lsp, (void *)vty); +	struct hash *lsp_table; +	zebra_lsp_t *lsp; +	zebra_ile_t tmp_ile; +	json_object *json = NULL; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = label; +	lsp = hash_lookup(lsp_table, &tmp_ile); +	if (!lsp) +		return; + +	if (use_json) { +		json = lsp_json(lsp); +		vty_out(vty, "%s%s", json_object_to_json_string_ext( +					     json, JSON_C_TO_STRING_PRETTY), +			VTY_NEWLINE); +		json_object_free(json); +	} else +		lsp_print(lsp, (void *)vty);  }  /*   * Display MPLS label forwarding table (VTY command handler).   */ -void -zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf, -                            u_char use_json) +void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, +				u_char use_json)  { -  char buf[BUFSIZ]; -  json_object *json = NULL; -  zebra_lsp_t *lsp = NULL; -  zebra_nhlfe_t *nhlfe = NULL; -  struct nexthop *nexthop = NULL; -  struct listnode *node = NULL; -  struct list *lsp_list = hash_get_sorted_list(zvrf->lsp_table, lsp_cmp); - -  if (use_json) -    { -      json  = json_object_new_object(); - -      for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) -        json_object_object_add(json, label2str(lsp->ile.in_label, buf, BUFSIZ), -                               lsp_json(lsp)); - -      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); -      json_object_free(json); -    } -  else -    { -      vty_out (vty, " Inbound                            Outbound%s", VTY_NEWLINE); -      vty_out (vty, "   Label     Type          Nexthop     Label%s", VTY_NEWLINE); -      vty_out (vty, "--------  -------  ---------------  --------%s", VTY_NEWLINE); - -      for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) -        { -          for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -            { -              vty_out (vty, "%8d  %7s  ", lsp->ile.in_label, nhlfe_type2str(nhlfe->type)); -              nexthop = nhlfe->nexthop; - -              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: -                case NEXTHOP_TYPE_IPV6_IFINDEX: -                  vty_out (vty, "%15s", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -                  break; -                default: -                  break; -                } - -              vty_out (vty, "  %8d%s", nexthop->nh_label->label[0], VTY_NEWLINE); -            } -        } - -      vty_out (vty, "%s", VTY_NEWLINE); -    } - -  list_delete (lsp_list); +	char buf[BUFSIZ]; +	json_object *json = NULL; +	zebra_lsp_t *lsp = NULL; +	zebra_nhlfe_t *nhlfe = NULL; +	struct nexthop *nexthop = NULL; +	struct listnode *node = NULL; +	struct list *lsp_list = hash_get_sorted_list(zvrf->lsp_table, lsp_cmp); + +	if (use_json) { +		json = json_object_new_object(); + +		for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) +			json_object_object_add( +				json, label2str(lsp->ile.in_label, buf, BUFSIZ), +				lsp_json(lsp)); + +		vty_out(vty, "%s%s", json_object_to_json_string_ext( +					     json, JSON_C_TO_STRING_PRETTY), +			VTY_NEWLINE); +		json_object_free(json); +	} else { +		vty_out(vty, " Inbound                            Outbound%s", +			VTY_NEWLINE); +		vty_out(vty, "   Label     Type          Nexthop     Label%s", +			VTY_NEWLINE); +		vty_out(vty, "--------  -------  ---------------  --------%s", +			VTY_NEWLINE); + +		for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) { +			for (nhlfe = lsp->nhlfe_list; nhlfe; +			     nhlfe = nhlfe->next) { +				vty_out(vty, "%8d  %7s  ", lsp->ile.in_label, +					nhlfe_type2str(nhlfe->type)); +				nexthop = nhlfe->nexthop; + +				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: +				case NEXTHOP_TYPE_IPV6_IFINDEX: +					vty_out(vty, "%15s", +						inet_ntop(AF_INET6, +							  &nexthop->gate.ipv6, +							  buf, BUFSIZ)); +					break; +				default: +					break; +				} + +				vty_out(vty, "  %8d%s", +					nexthop->nh_label->label[0], +					VTY_NEWLINE); +			} +		} + +		vty_out(vty, "%s", VTY_NEWLINE); +	} + +	list_delete(lsp_list);  }  /*   * Display MPLS LSP configuration of all static LSPs (VTY command handler).   */ -int -zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) +int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)  { -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; -  struct listnode *node; -  struct list *slsp_list = hash_get_sorted_list(zvrf->slsp_table, slsp_cmp); - -  for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) -      { -        for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) -          { -	    char buf[INET6_ADDRSTRLEN]; -            char lstr[30]; - -            snhlfe2str (snhlfe, buf, BUFSIZ); -	    switch (snhlfe->out_label) { -	      case MPLS_V4_EXP_NULL_LABEL: -	      case MPLS_V6_EXP_NULL_LABEL: -		strlcpy(lstr, "explicit-null", sizeof(lstr)); -		break; -	      case MPLS_IMP_NULL_LABEL: -		strlcpy(lstr, "implicit-null", sizeof(lstr)); -		break; -	      default: -		sprintf(lstr, "%u", snhlfe->out_label); -		break; -	    } - -            vty_out (vty, "mpls lsp %u %s %s%s", -                     slsp->ile.in_label, buf, lstr, VTY_NEWLINE); -          } -      } +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; +	struct listnode *node; +	struct list *slsp_list = +		hash_get_sorted_list(zvrf->slsp_table, slsp_cmp); + +	for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) { +		for (snhlfe = slsp->snhlfe_list; snhlfe; +		     snhlfe = snhlfe->next) { +			char buf[INET6_ADDRSTRLEN]; +			char lstr[30]; + +			snhlfe2str(snhlfe, buf, BUFSIZ); +			switch (snhlfe->out_label) { +			case MPLS_V4_EXP_NULL_LABEL: +			case MPLS_V6_EXP_NULL_LABEL: +				strlcpy(lstr, "explicit-null", sizeof(lstr)); +				break; +			case MPLS_IMP_NULL_LABEL: +				strlcpy(lstr, "implicit-null", sizeof(lstr)); +				break; +			default: +				sprintf(lstr, "%u", snhlfe->out_label); +				break; +			} + +			vty_out(vty, "mpls lsp %u %s %s%s", slsp->ile.in_label, +				buf, lstr, VTY_NEWLINE); +		} +	} -  list_delete (slsp_list); -  return (zvrf->slsp_table->count ? 1 : 0); +	list_delete(slsp_list); +	return (zvrf->slsp_table->count ? 1 : 0);  }  /* @@ -1906,42 +1807,38 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)   * entries from the kernel.   * NOTE: Currently supported only for default VRF.   */ -void -zebra_mpls_close_tables (struct zebra_vrf *zvrf) +void zebra_mpls_close_tables(struct zebra_vrf *zvrf)  { -  hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL); -  hash_clean(zvrf->lsp_table, NULL); -  hash_free(zvrf->lsp_table); -  hash_clean(zvrf->slsp_table, NULL); -  hash_free(zvrf->slsp_table); +	hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL); +	hash_clean(zvrf->lsp_table, NULL); +	hash_free(zvrf->lsp_table); +	hash_clean(zvrf->slsp_table, NULL); +	hash_free(zvrf->slsp_table);  }  /*   * Allocate MPLS tables for this VRF and do other initialization.   * NOTE: Currently supported only for default VRF.   */ -void -zebra_mpls_init_tables (struct zebra_vrf *zvrf) +void zebra_mpls_init_tables(struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return; -  zvrf->slsp_table = hash_create(label_hash, label_cmp); -  zvrf->lsp_table = hash_create(label_hash, label_cmp); -  zvrf->mpls_flags = 0; +	if (!zvrf) +		return; +	zvrf->slsp_table = hash_create(label_hash, label_cmp); +	zvrf->lsp_table = hash_create(label_hash, label_cmp); +	zvrf->mpls_flags = 0;  }  /*   * Global MPLS initialization.   */ -void -zebra_mpls_init (void) +void zebra_mpls_init(void)  { -  if (mpls_kernel_init () < 0) -    { -      zlog_warn ("Disabling MPLS support (no kernel support)"); -      return; -    } - -  mpls_enabled = 1; -  mpls_processq_init (&zebrad); +	if (mpls_kernel_init() < 0) { +		zlog_warn("Disabling MPLS support (no kernel support)"); +		return; +	} + +	mpls_enabled = 1; +	mpls_processq_init(&zebrad);  }  | 
