diff options
Diffstat (limited to 'bgpd/rfapi/rfapi_rib.c')
| -rw-r--r-- | bgpd/rfapi/rfapi_rib.c | 4144 | 
1 files changed, 2042 insertions, 2102 deletions
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 8fb2fe44ed..0cf5c205a5 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -59,8 +59,8 @@  /* forward decl */  #if DEBUG_NHL -static void -rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl); +static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, +			      struct skiplist *sl);  #endif  /* @@ -122,329 +122,294 @@ rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl);  /*   * iterate over RIB to count responses, compare with running counters   */ -void -rfapiRibCheckCounts ( -  int		checkstats,	/* validate rfd & global counts */ -  unsigned int	offset)		/* number of ri's held separately */ +void rfapiRibCheckCounts( +	int checkstats,      /* validate rfd & global counts */ +	unsigned int offset) /* number of ri's held separately */  { -  struct rfapi_descriptor *rfd; -  struct listnode *node; - -  struct bgp *bgp = bgp_get_default (); - -  uint32_t t_pfx_active = 0; -  uint32_t t_pfx_deleted = 0; - -  uint32_t t_ri_active = 0; -  uint32_t t_ri_deleted = 0; -  uint32_t t_ri_pend = 0; - -  unsigned int alloc_count; - -  /* -   * loop over NVEs -   */ -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -    { - -      afi_t afi; -      uint32_t pfx_active = 0; -      uint32_t pfx_deleted = 0; - -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          struct route_node *rn; - -          for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) -            { - -              struct skiplist *sl = rn->info; -              struct skiplist *dsl = rn->aggregate; -              uint32_t ri_active = 0; -              uint32_t ri_deleted = 0; - -              if (sl) -                { -                  ri_active = skiplist_count (sl); -                  assert (ri_active); -                  t_ri_active += ri_active; -                  ++pfx_active; -                  ++t_pfx_active; -                } - -              if (dsl) -                { -                  ri_deleted = skiplist_count (dsl); -                  t_ri_deleted += ri_deleted; -                  ++pfx_deleted; -                  ++t_pfx_deleted; -                } -            } -          for (rn = route_top (rfd->rib_pending[afi]); rn; -               rn = route_next (rn)) -            { - -              struct list *l = rn->info;        /* sorted by cost */ -              struct skiplist *sl = rn->aggregate; -              uint32_t ri_pend_cost = 0; -              uint32_t ri_pend_uniq = 0; - -              if (sl) -                { -                  ri_pend_uniq = skiplist_count (sl); -                } - -              if (l && (l != (void *) 1)) -                { -                  ri_pend_cost = l->count; -                  t_ri_pend += l->count; -                } - -              assert (ri_pend_uniq == ri_pend_cost); -            } -        } - -      if (checkstats) -        { -          if (pfx_active != rfd->rib_prefix_count) -            { -              vnc_zlog_debug_verbose ("%s: rfd %p actual pfx count %u != running %u", -                          __func__, rfd, pfx_active, rfd->rib_prefix_count); -              assert (0); -            } -        } -    } - -  if (checkstats && bgp && bgp->rfapi) -    { -      if (t_pfx_active != bgp->rfapi->rib_prefix_count_total) -        { -          vnc_zlog_debug_verbose ("%s: actual total pfx count %u != running %u", -                      __func__, t_pfx_active, -                      bgp->rfapi->rib_prefix_count_total); -          assert (0); -        } -    } - -  /* -   * Check against memory allocation count -   */ -  alloc_count = mtype_stats_alloc (MTYPE_RFAPI_INFO); -  assert (t_ri_active + t_ri_deleted + t_ri_pend + offset == alloc_count); +	struct rfapi_descriptor *rfd; +	struct listnode *node; + +	struct bgp *bgp = bgp_get_default(); + +	uint32_t t_pfx_active = 0; +	uint32_t t_pfx_deleted = 0; + +	uint32_t t_ri_active = 0; +	uint32_t t_ri_deleted = 0; +	uint32_t t_ri_pend = 0; + +	unsigned int alloc_count; + +	/* +	 * loop over NVEs +	 */ +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { + +		afi_t afi; +		uint32_t pfx_active = 0; +		uint32_t pfx_deleted = 0; + +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			struct route_node *rn; + +			for (rn = route_top(rfd->rib[afi]); rn; +			     rn = route_next(rn)) { + +				struct skiplist *sl = rn->info; +				struct skiplist *dsl = rn->aggregate; +				uint32_t ri_active = 0; +				uint32_t ri_deleted = 0; + +				if (sl) { +					ri_active = skiplist_count(sl); +					assert(ri_active); +					t_ri_active += ri_active; +					++pfx_active; +					++t_pfx_active; +				} + +				if (dsl) { +					ri_deleted = skiplist_count(dsl); +					t_ri_deleted += ri_deleted; +					++pfx_deleted; +					++t_pfx_deleted; +				} +			} +			for (rn = route_top(rfd->rib_pending[afi]); rn; +			     rn = route_next(rn)) { + +				struct list *l = rn->info; /* sorted by cost */ +				struct skiplist *sl = rn->aggregate; +				uint32_t ri_pend_cost = 0; +				uint32_t ri_pend_uniq = 0; + +				if (sl) { +					ri_pend_uniq = skiplist_count(sl); +				} + +				if (l && (l != (void *)1)) { +					ri_pend_cost = l->count; +					t_ri_pend += l->count; +				} + +				assert(ri_pend_uniq == ri_pend_cost); +			} +		} + +		if (checkstats) { +			if (pfx_active != rfd->rib_prefix_count) { +				vnc_zlog_debug_verbose( +					"%s: rfd %p actual pfx count %u != running %u", +					__func__, rfd, pfx_active, +					rfd->rib_prefix_count); +				assert(0); +			} +		} +	} + +	if (checkstats && bgp && bgp->rfapi) { +		if (t_pfx_active != bgp->rfapi->rib_prefix_count_total) { +			vnc_zlog_debug_verbose( +				"%s: actual total pfx count %u != running %u", +				__func__, t_pfx_active, +				bgp->rfapi->rib_prefix_count_total); +			assert(0); +		} +	} + +	/* +	 * Check against memory allocation count +	 */ +	alloc_count = mtype_stats_alloc(MTYPE_RFAPI_INFO); +	assert(t_ri_active + t_ri_deleted + t_ri_pend + offset == alloc_count);  } -static struct rfapi_info * -rfapi_info_new () +static struct rfapi_info *rfapi_info_new()  { -  return XCALLOC (MTYPE_RFAPI_INFO, sizeof (struct rfapi_info)); +	return XCALLOC(MTYPE_RFAPI_INFO, sizeof(struct rfapi_info));  } -void -rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p) +void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p)  { -  while (p) -    { -      struct rfapi_un_option *next; - -      next = p->next; -      XFREE (MTYPE_RFAPI_UN_OPTION, p); -      p = next; -    } +	while (p) { +		struct rfapi_un_option *next; + +		next = p->next; +		XFREE(MTYPE_RFAPI_UN_OPTION, p); +		p = next; +	}  } -void -rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p) +void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p)  { -  while (p) -    { -      struct rfapi_vn_option *next; - -      next = p->next; -      XFREE (MTYPE_RFAPI_VN_OPTION, p); -      p = next; -    } +	while (p) { +		struct rfapi_vn_option *next; + +		next = p->next; +		XFREE(MTYPE_RFAPI_VN_OPTION, p); +		p = next; +	}  } -static void -rfapi_info_free (struct rfapi_info *goner) +static void rfapi_info_free(struct rfapi_info *goner)  { -  if (goner) -    { -      if (goner->tea_options) -        { -          rfapiFreeBgpTeaOptionChain (goner->tea_options); -          goner->tea_options = NULL; -        } -      if (goner->un_options) -        { -          rfapiFreeRfapiUnOptionChain (goner->un_options); -          goner->un_options = NULL; -        } -      if (goner->vn_options) -        { -          rfapiFreeRfapiVnOptionChain (goner->vn_options); -          goner->vn_options = NULL; -        } -      if (goner->timer) -        { -          struct rfapi_rib_tcb *tcb; - -          tcb = ((struct thread *) goner->timer)->arg; -          thread_cancel ((struct thread *) goner->timer); -          XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -          goner->timer = NULL; -        } -      XFREE (MTYPE_RFAPI_INFO, goner); -    } +	if (goner) { +		if (goner->tea_options) { +			rfapiFreeBgpTeaOptionChain(goner->tea_options); +			goner->tea_options = NULL; +		} +		if (goner->un_options) { +			rfapiFreeRfapiUnOptionChain(goner->un_options); +			goner->un_options = NULL; +		} +		if (goner->vn_options) { +			rfapiFreeRfapiVnOptionChain(goner->vn_options); +			goner->vn_options = NULL; +		} +		if (goner->timer) { +			struct rfapi_rib_tcb *tcb; + +			tcb = ((struct thread *)goner->timer)->arg; +			thread_cancel((struct thread *)goner->timer); +			XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +			goner->timer = NULL; +		} +		XFREE(MTYPE_RFAPI_INFO, goner); +	}  }  /*   * Timer control block for recently-deleted and expired routes   */ -struct rfapi_rib_tcb -{ -  struct rfapi_descriptor *rfd; -  struct skiplist *sl; -  struct rfapi_info *ri; -  struct route_node *rn; -  int flags; +struct rfapi_rib_tcb { +	struct rfapi_descriptor *rfd; +	struct skiplist *sl; +	struct rfapi_info *ri; +	struct route_node *rn; +	int flags;  #define RFAPI_RIB_TCB_FLAG_DELETED	0x00000001  };  /*   * remove route from rib   */ -static int -rfapiRibExpireTimer (struct thread *t) +static int rfapiRibExpireTimer(struct thread *t)  { -  struct rfapi_rib_tcb *tcb = t->arg; - -  RFAPI_RIB_CHECK_COUNTS (1, 0); - -  /* -   * Forget reference to thread. Otherwise rfapi_info_free() will -   * attempt to free thread pointer as an option chain -   */ -  tcb->ri->timer = NULL; - -  /* "deleted" skiplist frees ri, "active" doesn't */ -  assert (!skiplist_delete (tcb->sl, &tcb->ri->rk, NULL)); -  if (!tcb->sl->del) -    { -      /* -       * XXX in this case, skiplist has no delete function: we must -       * therefore delete rfapi_info explicitly. -       */ -      rfapi_info_free (tcb->ri); -    } - -  if (skiplist_empty (tcb->sl)) -    { -      if (CHECK_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED)) -        tcb->rn->aggregate = NULL; -      else -        { -          struct bgp *bgp = bgp_get_default (); -          tcb->rn->info = NULL; -          RFAPI_RIB_PREFIX_COUNT_DECR (tcb->rfd, bgp->rfapi); -        } -      skiplist_free (tcb->sl); -      route_unlock_node (tcb->rn); -    } - -  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); - -  RFAPI_RIB_CHECK_COUNTS (1, 0); - -  return 0; +	struct rfapi_rib_tcb *tcb = t->arg; + +	RFAPI_RIB_CHECK_COUNTS(1, 0); + +	/* +	 * Forget reference to thread. Otherwise rfapi_info_free() will +	 * attempt to free thread pointer as an option chain +	 */ +	tcb->ri->timer = NULL; + +	/* "deleted" skiplist frees ri, "active" doesn't */ +	assert(!skiplist_delete(tcb->sl, &tcb->ri->rk, NULL)); +	if (!tcb->sl->del) { +		/* +		 * XXX in this case, skiplist has no delete function: we must +		 * therefore delete rfapi_info explicitly. +		 */ +		rfapi_info_free(tcb->ri); +	} + +	if (skiplist_empty(tcb->sl)) { +		if (CHECK_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED)) +			tcb->rn->aggregate = NULL; +		else { +			struct bgp *bgp = bgp_get_default(); +			tcb->rn->info = NULL; +			RFAPI_RIB_PREFIX_COUNT_DECR(tcb->rfd, bgp->rfapi); +		} +		skiplist_free(tcb->sl); +		route_unlock_node(tcb->rn); +	} + +	XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); + +	RFAPI_RIB_CHECK_COUNTS(1, 0); + +	return 0;  }  static void -rfapiRibStartTimer ( -  struct rfapi_descriptor	*rfd, -  struct rfapi_info		*ri, -  struct route_node		*rn, /* route node attached to */ -  int				deleted) +rfapiRibStartTimer(struct rfapi_descriptor *rfd, struct rfapi_info *ri, +		   struct route_node *rn, /* route node attached to */ +		   int deleted)  { -  struct thread *t = ri->timer; -  struct rfapi_rib_tcb *tcb = NULL; -  char buf_prefix[BUFSIZ]; - -  if (t) -    { -      tcb = t->arg; -      thread_cancel (t); -      ri->timer = NULL; -    } -  else -    { -      tcb = -        XCALLOC (MTYPE_RFAPI_RECENT_DELETE, sizeof (struct rfapi_rib_tcb)); -    } -  tcb->rfd = rfd; -  tcb->ri = ri; -  tcb->rn = rn; -  if (deleted) -    { -      tcb->sl = (struct skiplist *) rn->aggregate; -      SET_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); -    } -  else -    { -      tcb->sl = (struct skiplist *) rn->info; -      UNSET_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); -    } - -  prefix2str (&rn->p, buf_prefix, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: rfd %p pfx %s life %u", __func__, rfd, buf_prefix, -              ri->lifetime); -  ri->timer = thread_add_timer (bm->master, rfapiRibExpireTimer, -                                tcb, ri->lifetime); -  assert (ri->timer); +	struct thread *t = ri->timer; +	struct rfapi_rib_tcb *tcb = NULL; +	char buf_prefix[BUFSIZ]; + +	if (t) { +		tcb = t->arg; +		thread_cancel(t); +		ri->timer = NULL; +	} else { +		tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE, +			      sizeof(struct rfapi_rib_tcb)); +	} +	tcb->rfd = rfd; +	tcb->ri = ri; +	tcb->rn = rn; +	if (deleted) { +		tcb->sl = (struct skiplist *)rn->aggregate; +		SET_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); +	} else { +		tcb->sl = (struct skiplist *)rn->info; +		UNSET_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); +	} + +	prefix2str(&rn->p, buf_prefix, BUFSIZ); +	vnc_zlog_debug_verbose("%s: rfd %p pfx %s life %u", __func__, rfd, +			       buf_prefix, ri->lifetime); +	ri->timer = thread_add_timer(bm->master, rfapiRibExpireTimer, tcb, +				     ri->lifetime); +	assert(ri->timer);  } -extern void -rfapi_rib_key_init (struct prefix        *prefix, /* may be NULL */ -                    struct prefix_rd     *rd,     /* may be NULL */ -                    struct prefix        *aux,    /* may be NULL */ -                    struct rfapi_rib_key *rk) -   +extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */ +			       struct prefix_rd *rd,  /* may be NULL */ +			       struct prefix *aux,    /* may be NULL */ +			       struct rfapi_rib_key *rk) +  { -  memset((void *)rk, 0, sizeof(struct rfapi_rib_key)); -  if (prefix) -    rk->vn = *prefix; -  if (rd) -    rk->rd = *rd; -  if (aux) -    rk->aux_prefix = *aux; +	memset((void *)rk, 0, sizeof(struct rfapi_rib_key)); +	if (prefix) +		rk->vn = *prefix; +	if (rd) +		rk->rd = *rd; +	if (aux) +		rk->aux_prefix = *aux;  }  /*   * Compares two <struct rfapi_rib_key>s   */ -int -rfapi_rib_key_cmp (void *k1, void *k2) +int rfapi_rib_key_cmp(void *k1, void *k2)  { -  struct rfapi_rib_key *a = (struct rfapi_rib_key *) k1; -  struct rfapi_rib_key *b = (struct rfapi_rib_key *) k2; -  int ret; +	struct rfapi_rib_key *a = (struct rfapi_rib_key *)k1; +	struct rfapi_rib_key *b = (struct rfapi_rib_key *)k2; +	int ret; -  if (!a || !b) -    return (a - b); +	if (!a || !b) +		return (a - b); -  ret = vnc_prefix_cmp (&a->vn, &b->vn); -  if (ret) -    return ret; +	ret = vnc_prefix_cmp(&a->vn, &b->vn); +	if (ret) +		return ret; -  ret = vnc_prefix_cmp(&a->rd, &b->rd); -  if (ret) -    return ret; +	ret = vnc_prefix_cmp(&a->rd, &b->rd); +	if (ret) +		return ret; -  ret = vnc_prefix_cmp (&a->aux_prefix, &b->aux_prefix); +	ret = vnc_prefix_cmp(&a->aux_prefix, &b->aux_prefix); -  return ret; +	return ret;  } @@ -459,295 +424,298 @@ rfapi_rib_key_cmp (void *k1, void *k2)   * thoroughly, but it's not clear that the extra compuation would   * be worth it.   */ -static int -bgp_tea_options_cmp (struct bgp_tea_options *a, struct bgp_tea_options *b) +static int bgp_tea_options_cmp(struct bgp_tea_options *a, +			       struct bgp_tea_options *b)  { -  int rc; - -  if (!a || !b) -    { -      return (a - b); -    } - -  if (a->type != b->type) -    return (a->type - b->type); -  if (a->length != b->length) -    return (a->length = b->length); -  if ((rc = memcmp (a->value, b->value, a->length))) -    return rc; -  if (!a->next != !b->next) -    {                           /* logical xor */ -      return (a->next - b->next); -    } -  if (a->next) -    return bgp_tea_options_cmp (a->next, b->next); -  return 0; +	int rc; + +	if (!a || !b) { +		return (a - b); +	} +	if (a->type != b->type) +		return (a->type - b->type); +	if (a->length != b->length) +		return (a->length = b->length); +	if ((rc = memcmp(a->value, b->value, a->length))) +		return rc; +	if (!a->next != !b->next) { /* logical xor */ +		return (a->next - b->next); +	} +	if (a->next) +		return bgp_tea_options_cmp(a->next, b->next); +	return 0;  } -static int -rfapi_info_cmp (struct rfapi_info *a, struct rfapi_info *b) +static int rfapi_info_cmp(struct rfapi_info *a, struct rfapi_info *b)  { -  int rc; +	int rc; -  if (!a || !b) -    return (a - b); +	if (!a || !b) +		return (a - b); -  if ((rc = rfapi_rib_key_cmp (&a->rk, &b->rk))) -    return rc; +	if ((rc = rfapi_rib_key_cmp(&a->rk, &b->rk))) +		return rc; -  if ((rc = vnc_prefix_cmp (&a->un, &b->un))) -    return rc; +	if ((rc = vnc_prefix_cmp(&a->un, &b->un))) +		return rc; -  if (a->cost != b->cost) -    return (a->cost - b->cost); +	if (a->cost != b->cost) +		return (a->cost - b->cost); -  if (a->lifetime != b->lifetime) -    return (a->lifetime - b->lifetime); +	if (a->lifetime != b->lifetime) +		return (a->lifetime - b->lifetime); -  if ((rc = bgp_tea_options_cmp (a->tea_options, b->tea_options))) -    return rc; +	if ((rc = bgp_tea_options_cmp(a->tea_options, b->tea_options))) +		return rc; -  return 0; +	return 0;  } -void -rfapiRibClear (struct rfapi_descriptor *rfd) +void rfapiRibClear(struct rfapi_descriptor *rfd)  { -  struct bgp *bgp; -  afi_t afi; +	struct bgp *bgp; +	afi_t afi; -  if (rfd->bgp) -    bgp = rfd->bgp; -  else -    bgp = bgp_get_default (); +	if (rfd->bgp) +		bgp = rfd->bgp; +	else +		bgp = bgp_get_default();  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); +	vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd);  #endif -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      struct route_node *pn; -      struct route_node *rn; - -      if (rfd->rib_pending[afi]) -        { -          for (pn = route_top (rfd->rib_pending[afi]); pn; -               pn = route_next (pn)) -            { -              if (pn->aggregate) -                { -                  /*  -                   * free references into the rfapi_info structures before -                   * freeing the structures themselves -                   */ -                  skiplist_free ((struct skiplist *) (pn->aggregate)); -                  pn->aggregate = NULL; -                  route_unlock_node (pn);       /* skiplist deleted */ -                } -              /*  -               * free the rfapi_info structures -               */ -              if (pn->info) -                { -                  if (pn->info != (void *) 1) -                    { -                      list_delete ((struct list *) (pn->info)); -                    } -                  pn->info = NULL; -                  route_unlock_node (pn);       /* linklist or 1 deleted */ -                } -            } -        } -      if (rfd->rib[afi]) -        { -          for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) -            { -              if (rn->info) -                { - -                  struct rfapi_info *ri; - -                  while (0 == -                         skiplist_first ((struct skiplist *) rn->info, NULL, -                                         (void **) &ri)) -                    { - -                      rfapi_info_free (ri); -                      skiplist_delete_first ((struct skiplist *) rn->info); -                    } -                  skiplist_free ((struct skiplist *) rn->info); -                  rn->info = NULL; -                  route_unlock_node (rn); -                  RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); -                } -              if (rn->aggregate) -                { - -                  struct rfapi_info *ri_del; - -                  /* delete skiplist & contents */ -                  while (!skiplist_first ((struct skiplist *) (rn->aggregate), -                                          NULL, (void **) &ri_del)) -                    { - -                      /* sl->del takes care of ri_del */ -                      skiplist_delete_first ( -			(struct skiplist *) (rn->aggregate)); -                    } -                  skiplist_free ((struct skiplist *) (rn->aggregate)); - -                  rn->aggregate = NULL; -                  route_unlock_node (rn); -                } -            } -        } -    } -  if (rfd->updated_responses_queue) -    { -      work_queue_free (rfd->updated_responses_queue); -      rfd->updated_responses_queue = NULL; -    } +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		struct route_node *pn; +		struct route_node *rn; + +		if (rfd->rib_pending[afi]) { +			for (pn = route_top(rfd->rib_pending[afi]); pn; +			     pn = route_next(pn)) { +				if (pn->aggregate) { +					/* +					 * free references into the rfapi_info +					 * structures before +					 * freeing the structures themselves +					 */ +					skiplist_free( +						(struct skiplist +							 *)(pn->aggregate)); +					pn->aggregate = NULL; +					route_unlock_node( +						pn); /* skiplist deleted */ +				} +				/* +				 * free the rfapi_info structures +				 */ +				if (pn->info) { +					if (pn->info != (void *)1) { +						list_delete( +							(struct list +								 *)(pn->info)); +					} +					pn->info = NULL; +					route_unlock_node( +						pn); /* linklist or 1 deleted */ +				} +			} +		} +		if (rfd->rib[afi]) { +			for (rn = route_top(rfd->rib[afi]); rn; +			     rn = route_next(rn)) { +				if (rn->info) { + +					struct rfapi_info *ri; + +					while (0 == skiplist_first( +							    (struct skiplist *) +								    rn->info, +							    NULL, +							    (void **)&ri)) { + +						rfapi_info_free(ri); +						skiplist_delete_first( +							(struct skiplist *) +								rn->info); +					} +					skiplist_free( +						(struct skiplist *)rn->info); +					rn->info = NULL; +					route_unlock_node(rn); +					RFAPI_RIB_PREFIX_COUNT_DECR(rfd, +								    bgp->rfapi); +				} +				if (rn->aggregate) { + +					struct rfapi_info *ri_del; + +					/* delete skiplist & contents */ +					while (!skiplist_first( +						(struct skiplist +							 *)(rn->aggregate), +						NULL, (void **)&ri_del)) { + +						/* sl->del takes care of ri_del +						 */ +						skiplist_delete_first(( +							struct skiplist +								*)(rn->aggregate)); +					} +					skiplist_free( +						(struct skiplist +							 *)(rn->aggregate)); + +					rn->aggregate = NULL; +					route_unlock_node(rn); +				} +			} +		} +	} +	if (rfd->updated_responses_queue) { +		work_queue_free(rfd->updated_responses_queue); +		rfd->updated_responses_queue = NULL; +	}  }  /*   * Release all dynamically-allocated memory that is part of an HD's RIB   */ -void -rfapiRibFree (struct rfapi_descriptor *rfd) +void rfapiRibFree(struct rfapi_descriptor *rfd)  { -  afi_t afi; +	afi_t afi; -  /* -   * NB rfd is typically detached from master list, so is not included -   * in the count performed by RFAPI_RIB_CHECK_COUNTS -   */ +	/* +	 * NB rfd is typically detached from master list, so is not included +	 * in the count performed by RFAPI_RIB_CHECK_COUNTS +	 */ -  /* -   * Free routes attached to radix trees -   */ -  rfapiRibClear (rfd); +	/* +	 * Free routes attached to radix trees +	 */ +	rfapiRibClear(rfd); -  /* Now the uncounted rfapi_info's are freed, so the check should succeed */ -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	/* Now the uncounted rfapi_info's are freed, so the check should succeed +	 */ +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  /* -   * Free radix trees -   */ -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      route_table_finish (rfd->rib_pending[afi]); -      rfd->rib_pending[afi] = NULL; +	/* +	 * Free radix trees +	 */ +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		route_table_finish(rfd->rib_pending[afi]); +		rfd->rib_pending[afi] = NULL; -      route_table_finish (rfd->rib[afi]); -      rfd->rib[afi] = NULL; +		route_table_finish(rfd->rib[afi]); +		rfd->rib[afi] = NULL; -      /* NB route_table_finish frees only prefix nodes, not chained info */ -      route_table_finish (rfd->rsp_times[afi]); -      rfd->rib[afi] = NULL; -    } +		/* NB route_table_finish frees only prefix nodes, not chained +		 * info */ +		route_table_finish(rfd->rsp_times[afi]); +		rfd->rib[afi] = NULL; +	}  }  /*   * Copies struct bgp_info to struct rfapi_info, except for rk fields and un   */ -static void -rfapiRibBi2Ri( -  struct bgp_info   *bi, -  struct rfapi_info *ri, -  uint32_t          lifetime) +static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri, +			  uint32_t lifetime)  { -  struct bgp_attr_encap_subtlv *pEncap; - -  ri->cost = rfapiRfpCost (bi->attr); -  ri->lifetime = lifetime; - -  /* This loop based on rfapiRouteInfo2NextHopEntry() */ -  for (pEncap = bi->attr->extra->vnc_subtlvs; pEncap; pEncap = pEncap->next) -    { -      struct bgp_tea_options *hop; - -      switch (pEncap->type) -        { -        case BGP_VNC_SUBTLV_TYPE_LIFETIME: -          /* use configured lifetime, not attr lifetime */ -          break; - -        case BGP_VNC_SUBTLV_TYPE_RFPOPTION: -          hop = XCALLOC (MTYPE_BGP_TEA_OPTIONS, -                         sizeof (struct bgp_tea_options)); -          assert (hop); -          hop->type = pEncap->value[0]; -          hop->length = pEncap->value[1]; -          hop->value = XCALLOC (MTYPE_BGP_TEA_OPTIONS_VALUE, -                                pEncap->length - 2); -          assert (hop->value); -          memcpy (hop->value, pEncap->value + 2, pEncap->length - 2); -          if (hop->length > pEncap->length - 2) -            { -              zlog_warn ("%s: VNC subtlv length mismatch: " -                         "RFP option says %d, attr says %d " -                         "(shrinking)", -                         __func__, hop->length, pEncap->length - 2); -              hop->length = pEncap->length - 2; -            } -          hop->next = ri->tea_options; -          ri->tea_options = hop; -          break; - -        default: -          break; -        } -    } - -  rfapi_un_options_free (ri->un_options);   /* maybe free old version */ -  ri->un_options = rfapi_encap_tlv_to_un_option (bi->attr); - -  /* -   * VN options -   */ -  if (bi->extra &&  -      decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) -    { -      /* ethernet route */ - -      struct rfapi_vn_option *vo; - -      vo = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); -      assert (vo); - -      vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; - -      /* copy from RD already stored in bi, so we don't need it_node */ -      memcpy (&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val+2, -	ETHER_ADDR_LEN); - -      if (bi->attr && bi->attr->extra) -        { -          (void) rfapiEcommunityGetLNI (bi->attr->extra->ecommunity, -                                        &vo->v.l2addr.logical_net_id); -          (void) rfapiEcommunityGetEthernetTag (bi->attr->extra->ecommunity, -                                                &vo->v.l2addr.tag_id); -        } - -      /* local_nve_id comes from RD */ -      vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; - -      /* label comes from MP_REACH_NLRI label */ -      vo->v.l2addr.label = decode_label (bi->extra->tag); - -      rfapi_vn_options_free (ri->vn_options);   /* maybe free old version */ -      ri->vn_options = vo; -    } - -  /* -   * If there is an auxiliary IP address (L2 can have it), copy it -   */ -  if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) -    { -      ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; -    } +	struct bgp_attr_encap_subtlv *pEncap; + +	ri->cost = rfapiRfpCost(bi->attr); +	ri->lifetime = lifetime; + +	/* This loop based on rfapiRouteInfo2NextHopEntry() */ +	for (pEncap = bi->attr->extra->vnc_subtlvs; pEncap; +	     pEncap = pEncap->next) { +		struct bgp_tea_options *hop; + +		switch (pEncap->type) { +		case BGP_VNC_SUBTLV_TYPE_LIFETIME: +			/* use configured lifetime, not attr lifetime */ +			break; + +		case BGP_VNC_SUBTLV_TYPE_RFPOPTION: +			hop = XCALLOC(MTYPE_BGP_TEA_OPTIONS, +				      sizeof(struct bgp_tea_options)); +			assert(hop); +			hop->type = pEncap->value[0]; +			hop->length = pEncap->value[1]; +			hop->value = XCALLOC(MTYPE_BGP_TEA_OPTIONS_VALUE, +					     pEncap->length - 2); +			assert(hop->value); +			memcpy(hop->value, pEncap->value + 2, +			       pEncap->length - 2); +			if (hop->length > pEncap->length - 2) { +				zlog_warn( +					"%s: VNC subtlv length mismatch: " +					"RFP option says %d, attr says %d " +					"(shrinking)", +					__func__, hop->length, +					pEncap->length - 2); +				hop->length = pEncap->length - 2; +			} +			hop->next = ri->tea_options; +			ri->tea_options = hop; +			break; + +		default: +			break; +		} +	} + +	rfapi_un_options_free(ri->un_options); /* maybe free old version */ +	ri->un_options = rfapi_encap_tlv_to_un_option(bi->attr); + +	/* +	 * VN options +	 */ +	if (bi->extra +	    && decode_rd_type(bi->extra->vnc.import.rd.val) +		       == RD_TYPE_VNC_ETH) { +		/* ethernet route */ + +		struct rfapi_vn_option *vo; + +		vo = XCALLOC(MTYPE_RFAPI_VN_OPTION, +			     sizeof(struct rfapi_vn_option)); +		assert(vo); + +		vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; + +		/* copy from RD already stored in bi, so we don't need it_node +		 */ +		memcpy(&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val + 2, +		       ETHER_ADDR_LEN); + +		if (bi->attr && bi->attr->extra) { +			(void)rfapiEcommunityGetLNI( +				bi->attr->extra->ecommunity, +				&vo->v.l2addr.logical_net_id); +			(void)rfapiEcommunityGetEthernetTag( +				bi->attr->extra->ecommunity, +				&vo->v.l2addr.tag_id); +		} + +		/* local_nve_id comes from RD */ +		vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; + +		/* label comes from MP_REACH_NLRI label */ +		vo->v.l2addr.label = decode_label(bi->extra->tag); + +		rfapi_vn_options_free( +			ri->vn_options); /* maybe free old version */ +		ri->vn_options = vo; +	} + +	/* +	 * If there is an auxiliary IP address (L2 can have it), copy it +	 */ +	if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) { +		ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; +	}  }  /* @@ -768,94 +736,86 @@ rfapiRibBi2Ri(   *	0	OK to include route in response   *	!0	do not include route in response   */ -int -rfapiRibPreloadBi( -  struct route_node *rfd_rib_node,	/* NULL = don't preload or filter */ -  struct prefix     *pfx_vn, -  struct prefix     *pfx_un, -  uint32_t          lifetime, -  struct bgp_info   *bi) +int rfapiRibPreloadBi( +	struct route_node *rfd_rib_node, /* NULL = don't preload or filter */ +	struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime, +	struct bgp_info *bi)  { -  struct rfapi_descriptor *rfd; -  struct skiplist         *slRibPt = NULL; -  struct rfapi_info       *ori = NULL; -  struct rfapi_rib_key    rk; -  struct route_node       *trn; -  afi_t                   afi; - -  if (!rfd_rib_node) -    return 0; - -  afi  = family2afi(rfd_rib_node->p.family); - -  rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); - -  memset((void *)&rk, 0, sizeof(rk)); -  rk.vn = *pfx_vn; -  rk.rd = bi->extra->vnc.import.rd; - -  /* -   * If there is an auxiliary IP address (L2 can have it), copy it -   */ -  if (bi->extra->vnc.import.aux_prefix.family) -    { -      rk.aux_prefix = bi->extra->vnc.import.aux_prefix; -    } - -  /* -   * is this route already in NVE's RIB? -   */ -  slRibPt = (struct skiplist *) rfd_rib_node->info; - -  if (slRibPt && !skiplist_search (slRibPt, &rk, (void **) &ori)) -    { - -      if ((ori->rsp_counter == rfd->rsp_counter) && -        (ori->last_sent_time == rfd->rsp_time)) -	{ -	  return -1;	/* duplicate in this response */ +	struct rfapi_descriptor *rfd; +	struct skiplist *slRibPt = NULL; +	struct rfapi_info *ori = NULL; +	struct rfapi_rib_key rk; +	struct route_node *trn; +	afi_t afi; + +	if (!rfd_rib_node) +		return 0; + +	afi = family2afi(rfd_rib_node->p.family); + +	rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); + +	memset((void *)&rk, 0, sizeof(rk)); +	rk.vn = *pfx_vn; +	rk.rd = bi->extra->vnc.import.rd; + +	/* +	 * If there is an auxiliary IP address (L2 can have it), copy it +	 */ +	if (bi->extra->vnc.import.aux_prefix.family) { +		rk.aux_prefix = bi->extra->vnc.import.aux_prefix; +	} + +	/* +	 * is this route already in NVE's RIB? +	 */ +	slRibPt = (struct skiplist *)rfd_rib_node->info; + +	if (slRibPt && !skiplist_search(slRibPt, &rk, (void **)&ori)) { + +		if ((ori->rsp_counter == rfd->rsp_counter) +		    && (ori->last_sent_time == rfd->rsp_time)) { +			return -1; /* duplicate in this response */ +		} + +		/* found: update contents of existing route in RIB */ +		ori->un = *pfx_un; +		rfapiRibBi2Ri(bi, ori, lifetime); +	} else { +		/* not found: add new route to RIB */ +		ori = rfapi_info_new(); +		ori->rk = rk; +		ori->un = *pfx_un; +		rfapiRibBi2Ri(bi, ori, lifetime); + +		if (!slRibPt) { +			slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL); +			rfd_rib_node->info = slRibPt; +			route_lock_node(rfd_rib_node); +			RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfd->bgp->rfapi); +		} +		skiplist_insert(slRibPt, &ori->rk, ori);  	} -      /* found: update contents of existing route in RIB */ -      ori->un = *pfx_un; -      rfapiRibBi2Ri(bi, ori, lifetime); -    } -  else -    { -      /* not found: add new route to RIB */ -      ori = rfapi_info_new (); -      ori->rk = rk; -      ori->un = *pfx_un; -      rfapiRibBi2Ri(bi, ori, lifetime); - -      if (!slRibPt) -        { -          slRibPt = skiplist_new (0, rfapi_rib_key_cmp, NULL); -          rfd_rib_node->info = slRibPt; -          route_lock_node (rfd_rib_node); -          RFAPI_RIB_PREFIX_COUNT_INCR (rfd, rfd->bgp->rfapi); -        } -      skiplist_insert (slRibPt, &ori->rk, ori); -    } - -  ori->last_sent_time = rfapi_time (NULL); - -  /* -   * poke timer -   */ -  RFAPI_RIB_CHECK_COUNTS (0, 0); -  rfapiRibStartTimer (rfd, ori, rfd_rib_node, 0); -  RFAPI_RIB_CHECK_COUNTS (0, 0); - -  /* -   * Update last sent time for prefix -   */ -  trn = route_node_get (rfd->rsp_times[afi], &rfd_rib_node->p); /* locks trn */ -  trn->info = (void *) (uintptr_t) bgp_clock (); -  if (trn->lock > 1) -    route_unlock_node (trn); - -  return 0; +	ori->last_sent_time = rfapi_time(NULL); + +	/* +	 * poke timer +	 */ +	RFAPI_RIB_CHECK_COUNTS(0, 0); +	rfapiRibStartTimer(rfd, ori, rfd_rib_node, 0); +	RFAPI_RIB_CHECK_COUNTS(0, 0); + +	/* +	 * Update last sent time for prefix +	 */ +	trn = route_node_get(rfd->rsp_times[afi], +			     &rfd_rib_node->p); /* locks trn */ +	trn->info = (void *)(uintptr_t)bgp_clock(); +	if (trn->lock > 1) +		route_unlock_node(trn); + +	return 0;  }  /* @@ -882,617 +842,638 @@ rfapiRibPreloadBi(   *   * Clear pending node   */ -static void -process_pending_node ( -  struct bgp *bgp, -  struct rfapi_descriptor	*rfd, -  afi_t				afi, -  struct route_node		*pn,			/* pending node */ -  struct rfapi_next_hop_entry	**head, -  struct rfapi_next_hop_entry	**tail) +static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, +				 afi_t afi, +				 struct route_node *pn, /* pending node */ +				 struct rfapi_next_hop_entry **head, +				 struct rfapi_next_hop_entry **tail)  { -  struct listnode		*node = NULL; -  struct listnode		*nnode = NULL; -  struct rfapi_info		*ri = NULL;		/* happy valgrind */ -  struct rfapi_ip_prefix	hp = { 0 };		/* pfx to put in NHE */ -  struct route_node		*rn = NULL; -  struct skiplist		*slRibPt = NULL;	/* rib list */ -  struct skiplist		*slPendPt = NULL; -  struct list			*lPendCost = NULL; -  struct list			*delete_list = NULL; -  int				printedprefix = 0; -  char				buf_prefix[BUFSIZ]; -  int				rib_node_started_nonempty = 0; -  int				sendingsomeroutes = 0; +	struct listnode *node = NULL; +	struct listnode *nnode = NULL; +	struct rfapi_info *ri = NULL;    /* happy valgrind */ +	struct rfapi_ip_prefix hp = {0}; /* pfx to put in NHE */ +	struct route_node *rn = NULL; +	struct skiplist *slRibPt = NULL; /* rib list */ +	struct skiplist *slPendPt = NULL; +	struct list *lPendCost = NULL; +	struct list *delete_list = NULL; +	int printedprefix = 0; +	char buf_prefix[BUFSIZ]; +	int rib_node_started_nonempty = 0; +	int sendingsomeroutes = 0;  #if DEBUG_PROCESS_PENDING_NODE -  unsigned int count_rib_initial = 0; -  unsigned int count_pend_vn_initial = 0; -  unsigned int count_pend_cost_initial = 0; +	unsigned int count_rib_initial = 0; +	unsigned int count_pend_vn_initial = 0; +	unsigned int count_pend_cost_initial = 0;  #endif -  assert (pn); -  prefix2str (&pn->p, buf_prefix, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: afi=%d, %s pn->info=%p", -              __func__, afi, buf_prefix, pn->info); +	assert(pn); +	prefix2str(&pn->p, buf_prefix, BUFSIZ); +	vnc_zlog_debug_verbose("%s: afi=%d, %s pn->info=%p", __func__, afi, +			       buf_prefix, pn->info); -  if (AFI_L2VPN != afi) -    { -      rfapiQprefix2Rprefix (&pn->p, &hp); -    } +	if (AFI_L2VPN != afi) { +		rfapiQprefix2Rprefix(&pn->p, &hp); +	} -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  /* -   * Find corresponding RIB node -   */ -  rn = route_node_get (rfd->rib[afi], &pn->p);  /* locks rn */ +	/* +	 * Find corresponding RIB node +	 */ +	rn = route_node_get(rfd->rib[afi], &pn->p); /* locks rn */ -  /* -   * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info, -   * skiplist.del = NULL -   */ -  slRibPt = (struct skiplist *) rn->info; -  if (slRibPt) -    rib_node_started_nonempty = 1; +	/* +	 * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info, +	 * skiplist.del = NULL +	 */ +	slRibPt = (struct skiplist *)rn->info; +	if (slRibPt) +		rib_node_started_nonempty = 1; -  slPendPt = (struct skiplist *) (pn->aggregate); -  lPendCost = (struct list *) (pn->info); +	slPendPt = (struct skiplist *)(pn->aggregate); +	lPendCost = (struct list *)(pn->info);  #if DEBUG_PROCESS_PENDING_NODE -  /* debugging */ -  if (slRibPt) -    count_rib_initial = skiplist_count (slRibPt); +	/* debugging */ +	if (slRibPt) +		count_rib_initial = skiplist_count(slRibPt); -  if (slPendPt) -    count_pend_vn_initial = skiplist_count (slPendPt); +	if (slPendPt) +		count_pend_vn_initial = skiplist_count(slPendPt); -  if (lPendCost && lPendCost != (struct list *) 1) -    count_pend_cost_initial = lPendCost->count; +	if (lPendCost && lPendCost != (struct list *)1) +		count_pend_cost_initial = lPendCost->count;  #endif -  /* -   * Handle special case: delete all routes at prefix -   */ -  if (lPendCost == (struct list *) 1) -    { -      vnc_zlog_debug_verbose ("%s: lPendCost=1 => delete all", __func__); -      if (slRibPt && !skiplist_empty (slRibPt)) -        { -          delete_list = list_new (); -          while (0 == skiplist_first (slRibPt, NULL, (void **) &ri)) -            { - -              char buf[BUFSIZ]; -              char buf2[BUFSIZ]; - -              listnode_add (delete_list, ri); -              vnc_zlog_debug_verbose ("%s: after listnode_add, delete_list->count=%d", -                          __func__, delete_list->count); -              rfapiFreeBgpTeaOptionChain (ri->tea_options); -              ri->tea_options = NULL; - -              if (ri->timer) -                { -                  struct rfapi_rib_tcb *tcb; - -                  tcb = ((struct thread *) ri->timer)->arg; -                  thread_cancel (ri->timer); -                  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -                  ri->timer = NULL; -                } - -              prefix2str (&ri->rk.vn, buf, BUFSIZ); -              prefix2str (&ri->un, buf2, BUFSIZ); -              vnc_zlog_debug_verbose -                ("%s:   put dl pfx=%s vn=%s un=%s cost=%d life=%d vn_options=%p", -                 __func__, buf_prefix, buf, buf2, ri->cost, ri->lifetime, -                 ri->vn_options); - -              skiplist_delete_first (slRibPt); -            } - -          assert (skiplist_empty (slRibPt)); - -          skiplist_free (slRibPt); -          rn->info = slRibPt = NULL; -          route_unlock_node (rn); - -          lPendCost = pn->info = NULL; -          route_unlock_node (pn); - -          goto callback; -        } -      if (slRibPt) -        { -          skiplist_free (slRibPt); -          rn->info = NULL; -          route_unlock_node (rn); -        } - -      assert (!slPendPt); -      if (slPendPt) -        {                       /* TBD I think we can toss this block */ -          skiplist_free (slPendPt); -          pn->aggregate = NULL; -          route_unlock_node (pn); -        } - -      pn->info = NULL; -      route_unlock_node (pn); - -      route_unlock_node (rn);   /* route_node_get() */ - -      if (rib_node_started_nonempty) -        { -          RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); -        } - -      RFAPI_RIB_CHECK_COUNTS (1, 0); - -      return; -    } - -  vnc_zlog_debug_verbose ("%s:   lPendCost->count=%d, slRibPt->count=%d", -              __func__, -              (lPendCost ? (int) lPendCost->count : -1), -              (slRibPt ? (int) slRibPt->count : -1)); - -  /* -   * Iterate over routes at RIB Node. -   * If not found at Pending Node, delete from RIB Node and add to deletelist -   * If found at Pending Node -   *      If identical rfapi_info, delete from Pending Node -   */ -  if (slRibPt) -    { -      void *cursor = NULL; -      struct rfapi_info *ori; - -      /* -       * Iterate over RIB List -       * -       */ -      while (!skiplist_next (slRibPt, NULL, (void **) &ori, &cursor)) -        { - -          if (skiplist_search (slPendPt, &ori->rk, (void **) &ri)) -            { -              /* -               * Not in Pending list, so it should be deleted -               */ -              if (!delete_list) -                delete_list = list_new (); -              listnode_add (delete_list, ori); -              rfapiFreeBgpTeaOptionChain (ori->tea_options); -              ori->tea_options = NULL; -              if (ori->timer) -                { -                  struct rfapi_rib_tcb *tcb; - -                  tcb = ((struct thread *) ori->timer)->arg; -                  thread_cancel (ori->timer); -                  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -                  ori->timer = NULL; -                } +	/* +	 * Handle special case: delete all routes at prefix +	 */ +	if (lPendCost == (struct list *)1) { +		vnc_zlog_debug_verbose("%s: lPendCost=1 => delete all", +				       __func__); +		if (slRibPt && !skiplist_empty(slRibPt)) { +			delete_list = list_new(); +			while (0 +			       == skiplist_first(slRibPt, NULL, (void **)&ri)) { + +				char buf[BUFSIZ]; +				char buf2[BUFSIZ]; + +				listnode_add(delete_list, ri); +				vnc_zlog_debug_verbose( +					"%s: after listnode_add, delete_list->count=%d", +					__func__, delete_list->count); +				rfapiFreeBgpTeaOptionChain(ri->tea_options); +				ri->tea_options = NULL; + +				if (ri->timer) { +					struct rfapi_rib_tcb *tcb; + +					tcb = ((struct thread *)ri->timer)->arg; +					thread_cancel(ri->timer); +					XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +					ri->timer = NULL; +				} + +				prefix2str(&ri->rk.vn, buf, BUFSIZ); +				prefix2str(&ri->un, buf2, BUFSIZ); +				vnc_zlog_debug_verbose( +					"%s:   put dl pfx=%s vn=%s un=%s cost=%d life=%d vn_options=%p", +					__func__, buf_prefix, buf, buf2, +					ri->cost, ri->lifetime, ri->vn_options); + +				skiplist_delete_first(slRibPt); +			} + +			assert(skiplist_empty(slRibPt)); + +			skiplist_free(slRibPt); +			rn->info = slRibPt = NULL; +			route_unlock_node(rn); + +			lPendCost = pn->info = NULL; +			route_unlock_node(pn); + +			goto callback; +		} +		if (slRibPt) { +			skiplist_free(slRibPt); +			rn->info = NULL; +			route_unlock_node(rn); +		} + +		assert(!slPendPt); +		if (slPendPt) { /* TBD I think we can toss this block */ +			skiplist_free(slPendPt); +			pn->aggregate = NULL; +			route_unlock_node(pn); +		} + +		pn->info = NULL; +		route_unlock_node(pn); + +		route_unlock_node(rn); /* route_node_get() */ + +		if (rib_node_started_nonempty) { +			RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); +		} + +		RFAPI_RIB_CHECK_COUNTS(1, 0); + +		return; +	} + +	vnc_zlog_debug_verbose("%s:   lPendCost->count=%d, slRibPt->count=%d", +			       __func__, +			       (lPendCost ? (int)lPendCost->count : -1), +			       (slRibPt ? (int)slRibPt->count : -1)); + +	/* +	 * Iterate over routes at RIB Node. +	 * If not found at Pending Node, delete from RIB Node and add to +	 * deletelist +	 * If found at Pending Node +	 *      If identical rfapi_info, delete from Pending Node +	 */ +	if (slRibPt) { +		void *cursor = NULL; +		struct rfapi_info *ori; + +		/* +		 * Iterate over RIB List +		 * +		 */ +		while (!skiplist_next(slRibPt, NULL, (void **)&ori, &cursor)) { + +			if (skiplist_search(slPendPt, &ori->rk, (void **)&ri)) { +				/* +				 * Not in Pending list, so it should be deleted +				 */ +				if (!delete_list) +					delete_list = list_new(); +				listnode_add(delete_list, ori); +				rfapiFreeBgpTeaOptionChain(ori->tea_options); +				ori->tea_options = NULL; +				if (ori->timer) { +					struct rfapi_rib_tcb *tcb; + +					tcb = ((struct thread *)ori->timer) +						      ->arg; +					thread_cancel(ori->timer); +					XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +					ori->timer = NULL; +				}  #if DEBUG_PROCESS_PENDING_NODE -              /* deleted from slRibPt below, after we're done iterating */ -              vnc_zlog_debug_verbose -                ("%s:   slRibPt ri %p not matched in pending list, delete", -                 __func__, ori); +				/* deleted from slRibPt below, after we're done +				 * iterating */ +				vnc_zlog_debug_verbose( +					"%s:   slRibPt ri %p not matched in pending list, delete", +					__func__, ori);  #endif -            } -          else -            { -              /* -               * Found in pending list. If same lifetime, cost, options, -               * then remove from pending list because the route -               * hasn't changed. -               */ -              if (!rfapi_info_cmp (ori, ri)) -                { -                  skiplist_delete (slPendPt, &ri->rk, NULL); -                  assert (lPendCost); -                  if (lPendCost) -                    { -                      /* linear walk: might need optimization */ -                      listnode_delete (lPendCost, ri);  /* XXX doesn't free data! bug? */ -                      rfapi_info_free (ri);     /* grr... */ -                    } -                } +			} else { +				/* +				 * Found in pending list. If same lifetime, +				 * cost, options, +				 * then remove from pending list because the +				 * route +				 * hasn't changed. +				 */ +				if (!rfapi_info_cmp(ori, ri)) { +					skiplist_delete(slPendPt, &ri->rk, +							NULL); +					assert(lPendCost); +					if (lPendCost) { +						/* linear walk: might need +						 * optimization */ +						listnode_delete(lPendCost, +								ri); /* XXX +									doesn't +									free +									data! +									bug? */ +						rfapi_info_free( +							ri); /* grr... */ +					} +				}  #if DEBUG_PROCESS_PENDING_NODE -              vnc_zlog_debug_verbose ("%s:   slRibPt ri %p matched in pending list, %s", -                          __func__, ori, -                          (same ? "same info" : "different info")); +				vnc_zlog_debug_verbose( +					"%s:   slRibPt ri %p matched in pending list, %s", +					__func__, ori, +					(same ? "same info" +					      : "different info"));  #endif -            } -        } -      /* -       * Go back and delete items from RIB -       */ -      if (delete_list) -        { -          for (ALL_LIST_ELEMENTS_RO (delete_list, node, ri)) -            { -              vnc_zlog_debug_verbose ("%s:   deleting ri %p from slRibPt", __func__, ri); -              assert (!skiplist_delete (slRibPt, &ri->rk, NULL)); -            } -          if (skiplist_empty (slRibPt)) -            { -              skiplist_free (slRibPt); -              slRibPt = rn->info = NULL; -              route_unlock_node (rn); -            } -        } -    } - -  RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - -  /* -   * Iterate over routes at Pending Node -   * -   * If {vn} found at RIB Node, update RIB Node route contents to match PN -   * If {vn} NOT found at RIB Node, add copy to RIB Node -   */ -  if (lPendCost) -    { -      for (ALL_LIST_ELEMENTS_RO (lPendCost, node, ri)) -        { - -          struct rfapi_info *ori; - -          if (slRibPt && !skiplist_search (slRibPt, &ri->rk, (void **) &ori)) -            { - -              /* found: update contents of existing route in RIB */ -              ori->un = ri->un; -              ori->cost = ri->cost; -              ori->lifetime = ri->lifetime; -              rfapiFreeBgpTeaOptionChain (ori->tea_options); -              ori->tea_options = rfapiOptionsDup (ri->tea_options); -              ori->last_sent_time = rfapi_time (NULL); - -              rfapiFreeRfapiVnOptionChain (ori->vn_options); -              ori->vn_options = rfapiVnOptionsDup (ri->vn_options); - -              rfapiFreeRfapiUnOptionChain (ori->un_options); -              ori->un_options = rfapiUnOptionsDup (ri->un_options); - -              vnc_zlog_debug_verbose -                ("%s:   matched lPendCost item %p in slRibPt, rewrote", -                 __func__, ri); - -            } -          else -            { - -	      char	buf_rd[BUFSIZ]; - -              /* not found: add new route to RIB */ -              ori = rfapi_info_new (); -              ori->rk = ri->rk; -              ori->un = ri->un; -              ori->cost = ri->cost; -              ori->lifetime = ri->lifetime; -              ori->tea_options = rfapiOptionsDup (ri->tea_options); -              ori->last_sent_time = rfapi_time (NULL); -              ori->vn_options = rfapiVnOptionsDup (ri->vn_options); -              ori->un_options = rfapiUnOptionsDup (ri->un_options); - -              if (!slRibPt) -                { -                  slRibPt = skiplist_new (0, rfapi_rib_key_cmp, NULL); -                  rn->info = slRibPt; -                  route_lock_node (rn); -                } -              skiplist_insert (slRibPt, &ori->rk, ori); +			} +		} +		/* +		 * Go back and delete items from RIB +		 */ +		if (delete_list) { +			for (ALL_LIST_ELEMENTS_RO(delete_list, node, ri)) { +				vnc_zlog_debug_verbose( +					"%s:   deleting ri %p from slRibPt", +					__func__, ri); +				assert(!skiplist_delete(slRibPt, &ri->rk, +							NULL)); +			} +			if (skiplist_empty(slRibPt)) { +				skiplist_free(slRibPt); +				slRibPt = rn->info = NULL; +				route_unlock_node(rn); +			} +		} +	} + +	RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + +	/* +	 * Iterate over routes at Pending Node +	 * +	 * If {vn} found at RIB Node, update RIB Node route contents to match PN +	 * If {vn} NOT found at RIB Node, add copy to RIB Node +	 */ +	if (lPendCost) { +		for (ALL_LIST_ELEMENTS_RO(lPendCost, node, ri)) { + +			struct rfapi_info *ori; + +			if (slRibPt +			    && !skiplist_search(slRibPt, &ri->rk, +						(void **)&ori)) { + +				/* found: update contents of existing route in +				 * RIB */ +				ori->un = ri->un; +				ori->cost = ri->cost; +				ori->lifetime = ri->lifetime; +				rfapiFreeBgpTeaOptionChain(ori->tea_options); +				ori->tea_options = +					rfapiOptionsDup(ri->tea_options); +				ori->last_sent_time = rfapi_time(NULL); + +				rfapiFreeRfapiVnOptionChain(ori->vn_options); +				ori->vn_options = +					rfapiVnOptionsDup(ri->vn_options); + +				rfapiFreeRfapiUnOptionChain(ori->un_options); +				ori->un_options = +					rfapiUnOptionsDup(ri->un_options); + +				vnc_zlog_debug_verbose( +					"%s:   matched lPendCost item %p in slRibPt, rewrote", +					__func__, ri); + +			} else { + +				char buf_rd[BUFSIZ]; + +				/* not found: add new route to RIB */ +				ori = rfapi_info_new(); +				ori->rk = ri->rk; +				ori->un = ri->un; +				ori->cost = ri->cost; +				ori->lifetime = ri->lifetime; +				ori->tea_options = +					rfapiOptionsDup(ri->tea_options); +				ori->last_sent_time = rfapi_time(NULL); +				ori->vn_options = +					rfapiVnOptionsDup(ri->vn_options); +				ori->un_options = +					rfapiUnOptionsDup(ri->un_options); + +				if (!slRibPt) { +					slRibPt = skiplist_new( +						0, rfapi_rib_key_cmp, NULL); +					rn->info = slRibPt; +					route_lock_node(rn); +				} +				skiplist_insert(slRibPt, &ori->rk, ori);  #if DEBUG_RIB_SL_RD -	      prefix_rd2str(&ori->rk.rd, buf_rd, sizeof(buf_rd)); +				prefix_rd2str(&ori->rk.rd, buf_rd, +					      sizeof(buf_rd));  #else -	      buf_rd[0] = 0; +				buf_rd[0] = 0;  #endif -              vnc_zlog_debug_verbose ("%s:   nomatch lPendCost item %p in slRibPt, added (rd=%s)", -                          __func__, ri, buf_rd); -            } - -          /* -           * poke timer -           */ -          RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); -          rfapiRibStartTimer (rfd, ori, rn, 0); -          RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); -        } -    } +				vnc_zlog_debug_verbose( +					"%s:   nomatch lPendCost item %p in slRibPt, added (rd=%s)", +					__func__, ri, buf_rd); +			} + +			/* +			 * poke timer +			 */ +			RFAPI_RIB_CHECK_COUNTS( +				0, (delete_list ? delete_list->count : 0)); +			rfapiRibStartTimer(rfd, ori, rn, 0); +			RFAPI_RIB_CHECK_COUNTS( +				0, (delete_list ? delete_list->count : 0)); +		} +	}  callback: -  /* -   * Construct NHL as concatenation of pending list + delete list -   */ - - -  RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - -  if (lPendCost) -    { - -      char buf[BUFSIZ]; -      char buf2[BUFSIZ]; - -      vnc_zlog_debug_verbose ("%s: lPendCost->count now %d", __func__, lPendCost->count); -      vnc_zlog_debug_verbose ("%s: For prefix %s (a)", __func__, buf_prefix); -      printedprefix = 1; - -      for (ALL_LIST_ELEMENTS (lPendCost, node, nnode, ri)) -        { - -          struct rfapi_next_hop_entry *new; -          struct route_node *trn; - -          new = -            XCALLOC (MTYPE_RFAPI_NEXTHOP, -                     sizeof (struct rfapi_next_hop_entry)); -          assert (new); - -          if (ri->rk.aux_prefix.family) -            { -              rfapiQprefix2Rprefix (&ri->rk.aux_prefix, &new->prefix); -            } -          else -            { -              new->prefix = hp; -              if (AFI_L2VPN == afi) -                { -                  /* hp is 0; need to set length to match AF of vn */ -                  new->prefix.length = -                    (ri->rk.vn.family == AF_INET) ? 32 : 128; -                } -            } -          new->prefix.cost = ri->cost; -          new->lifetime = ri->lifetime; -          rfapiQprefix2Raddr (&ri->rk.vn, &new->vn_address); -          rfapiQprefix2Raddr (&ri->un, &new->un_address); -          /* free option chain from ri */ -          rfapiFreeBgpTeaOptionChain (ri->tea_options); - -          ri->tea_options = NULL;	/* option chain was transferred to NHL */ - -          new->vn_options = ri->vn_options; -          ri->vn_options = NULL;        /* option chain was transferred to NHL */ - -          new->un_options = ri->un_options; -          ri->un_options = NULL;        /* option chain was transferred to NHL */ - -          if (*tail) -            (*tail)->next = new; -          *tail = new; -          if (!*head) -            { -              *head = new; -            } -          sendingsomeroutes = 1; - -          ++rfd->stat_count_nh_reachable; -          ++bgp->rfapi->stat.count_updated_response_updates; - -          /* -           * update this NVE's timestamp for this prefix -           */ -          trn = route_node_get (rfd->rsp_times[afi], &pn->p);   /* locks trn */ -          trn->info = (void *) (uintptr_t) bgp_clock (); -          if (trn->lock > 1) -            route_unlock_node (trn); - -          rfapiRfapiIpAddr2Str (&new->vn_address, buf, BUFSIZ); -          rfapiRfapiIpAddr2Str (&new->un_address, buf2, BUFSIZ); -          vnc_zlog_debug_verbose ("%s:   add vn=%s un=%s cost=%d life=%d", __func__, -                      buf, buf2, new->prefix.cost, new->lifetime); -        } -    } - -  RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - -  if (delete_list) -    { - -      char buf[BUFSIZ]; -      char buf2[BUFSIZ]; - -      if (!printedprefix) -        { -          vnc_zlog_debug_verbose ("%s: For prefix %s (d)", __func__, buf_prefix); -        } -      vnc_zlog_debug_verbose ("%s: delete_list has %d elements", -                  __func__, delete_list->count); - -      RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -      if (!CHECK_FLAG (bgp->rfapi_cfg->flags, -                       BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) -        { - -          for (ALL_LIST_ELEMENTS (delete_list, node, nnode, ri)) -            { - -              struct rfapi_next_hop_entry *new; -              struct rfapi_info *ri_del; - -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -              new = XCALLOC (MTYPE_RFAPI_NEXTHOP, -                             sizeof (struct rfapi_next_hop_entry)); -              assert (new); - -              if (ri->rk.aux_prefix.family) -                { -                  rfapiQprefix2Rprefix (&ri->rk.aux_prefix, &new->prefix); -                } -              else -                { -                  new->prefix = hp; -                  if (AFI_L2VPN == afi) -                    { -                      /* hp is 0; need to set length to match AF of vn */ -                      new->prefix.length = -                        (ri->rk.vn.family == AF_INET) ? 32 : 128; -                    } -                } - -              new->prefix.cost = ri->cost; -              new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; -              rfapiQprefix2Raddr (&ri->rk.vn, &new->vn_address); -              rfapiQprefix2Raddr (&ri->un, &new->un_address); - -              new->vn_options = ri->vn_options; -              ri->vn_options = NULL;    /* option chain was transferred to NHL */ - -              new->un_options = ri->un_options; -              ri->un_options = NULL;    /* option chain was transferred to NHL */ - -              if (*tail) -                (*tail)->next = new; -              *tail = new; -              if (!*head) -                { -                  *head = new; -                } -              ++rfd->stat_count_nh_removal; -              ++bgp->rfapi->stat.count_updated_response_deletes; - -              rfapiRfapiIpAddr2Str (&new->vn_address, buf, BUFSIZ); -              rfapiRfapiIpAddr2Str (&new->un_address, buf2, BUFSIZ); -              vnc_zlog_debug_verbose ("%s:   DEL vn=%s un=%s cost=%d life=%d", __func__, -                          buf, buf2, new->prefix.cost, new->lifetime); - -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -              /* -               * Update/add to list of recent deletions at this prefix -               */ -              if (!rn->aggregate) -                { -                  rn->aggregate = skiplist_new (0, rfapi_rib_key_cmp, -                                                (void (*)(void *)) -                                                rfapi_info_free); -                  route_lock_node (rn); -                } -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - -              /* sanity check lifetime */ -              if (ri->lifetime > RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) -                ri->lifetime = RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; - -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -              /* cancel normal expire timer */ -              if (ri->timer) -                { -                  struct rfapi_rib_tcb *tcb; - -                  tcb = ((struct thread *) ri->timer)->arg; -                  thread_cancel ((struct thread *) ri->timer); -                  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -                  ri->timer = NULL; -                } -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - -              /* -               * Look in "recently-deleted" list -               */ -              if (skiplist_search ((struct skiplist *) (rn->aggregate), -                                   &ri->rk, (void **) &ri_del)) -                { - -                  int rc; - -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  /* -                   * NOT in "recently-deleted" list -                   */ -                  list_delete_node (delete_list, node); /* does not free ri */ -                  rc = skiplist_insert ((struct skiplist *) (rn->aggregate), -                                        &ri->rk, ri); -                  assert (!rc); - -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  rfapiRibStartTimer (rfd, ri, rn, 1); -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  ri->last_sent_time = rfapi_time (NULL); +	/* +	 * Construct NHL as concatenation of pending list + delete list +	 */ + + +	RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + +	if (lPendCost) { + +		char buf[BUFSIZ]; +		char buf2[BUFSIZ]; + +		vnc_zlog_debug_verbose("%s: lPendCost->count now %d", __func__, +				       lPendCost->count); +		vnc_zlog_debug_verbose("%s: For prefix %s (a)", __func__, +				       buf_prefix); +		printedprefix = 1; + +		for (ALL_LIST_ELEMENTS(lPendCost, node, nnode, ri)) { + +			struct rfapi_next_hop_entry *new; +			struct route_node *trn; + +			new = XCALLOC(MTYPE_RFAPI_NEXTHOP, +				      sizeof(struct rfapi_next_hop_entry)); +			assert(new); + +			if (ri->rk.aux_prefix.family) { +				rfapiQprefix2Rprefix(&ri->rk.aux_prefix, +						     &new->prefix); +			} else { +				new->prefix = hp; +				if (AFI_L2VPN == afi) { +					/* hp is 0; need to set length to match +					 * AF of vn */ +					new->prefix.length = +						(ri->rk.vn.family == AF_INET) +							? 32 +							: 128; +				} +			} +			new->prefix.cost = ri->cost; +			new->lifetime = ri->lifetime; +			rfapiQprefix2Raddr(&ri->rk.vn, &new->vn_address); +			rfapiQprefix2Raddr(&ri->un, &new->un_address); +			/* free option chain from ri */ +			rfapiFreeBgpTeaOptionChain(ri->tea_options); + +			ri->tea_options = +				NULL; /* option chain was transferred to NHL */ + +			new->vn_options = ri->vn_options; +			ri->vn_options = +				NULL; /* option chain was transferred to NHL */ + +			new->un_options = ri->un_options; +			ri->un_options = +				NULL; /* option chain was transferred to NHL */ + +			if (*tail) +				(*tail)->next = new; +			*tail = new; +			if (!*head) { +				*head = new; +			} +			sendingsomeroutes = 1; + +			++rfd->stat_count_nh_reachable; +			++bgp->rfapi->stat.count_updated_response_updates; + +			/* +			 * update this NVE's timestamp for this prefix +			 */ +			trn = route_node_get(rfd->rsp_times[afi], +					     &pn->p); /* locks trn */ +			trn->info = (void *)(uintptr_t)bgp_clock(); +			if (trn->lock > 1) +				route_unlock_node(trn); + +			rfapiRfapiIpAddr2Str(&new->vn_address, buf, BUFSIZ); +			rfapiRfapiIpAddr2Str(&new->un_address, buf2, BUFSIZ); +			vnc_zlog_debug_verbose( +				"%s:   add vn=%s un=%s cost=%d life=%d", +				__func__, buf, buf2, new->prefix.cost, +				new->lifetime); +		} +	} + +	RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + +	if (delete_list) { + +		char buf[BUFSIZ]; +		char buf2[BUFSIZ]; + +		if (!printedprefix) { +			vnc_zlog_debug_verbose("%s: For prefix %s (d)", +					       __func__, buf_prefix); +		} +		vnc_zlog_debug_verbose("%s: delete_list has %d elements", +				       __func__, delete_list->count); + +		RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +		if (!CHECK_FLAG(bgp->rfapi_cfg->flags, +				BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) { + +			for (ALL_LIST_ELEMENTS(delete_list, node, nnode, ri)) { + +				struct rfapi_next_hop_entry *new; +				struct rfapi_info *ri_del; + +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +				new = XCALLOC( +					MTYPE_RFAPI_NEXTHOP, +					sizeof(struct rfapi_next_hop_entry)); +				assert(new); + +				if (ri->rk.aux_prefix.family) { +					rfapiQprefix2Rprefix(&ri->rk.aux_prefix, +							     &new->prefix); +				} else { +					new->prefix = hp; +					if (AFI_L2VPN == afi) { +						/* hp is 0; need to set length +						 * to match AF of vn */ +						new->prefix.length = +							(ri->rk.vn.family +							 == AF_INET) +								? 32 +								: 128; +					} +				} + +				new->prefix.cost = ri->cost; +				new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; +				rfapiQprefix2Raddr(&ri->rk.vn, +						   &new->vn_address); +				rfapiQprefix2Raddr(&ri->un, &new->un_address); + +				new->vn_options = ri->vn_options; +				ri->vn_options = NULL; /* option chain was +							  transferred to NHL */ + +				new->un_options = ri->un_options; +				ri->un_options = NULL; /* option chain was +							  transferred to NHL */ + +				if (*tail) +					(*tail)->next = new; +				*tail = new; +				if (!*head) { +					*head = new; +				} +				++rfd->stat_count_nh_removal; +				++bgp->rfapi->stat +					  .count_updated_response_deletes; + +				rfapiRfapiIpAddr2Str(&new->vn_address, buf, +						     BUFSIZ); +				rfapiRfapiIpAddr2Str(&new->un_address, buf2, +						     BUFSIZ); +				vnc_zlog_debug_verbose( +					"%s:   DEL vn=%s un=%s cost=%d life=%d", +					__func__, buf, buf2, new->prefix.cost, +					new->lifetime); + +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +				/* +				 * Update/add to list of recent deletions at +				 * this prefix +				 */ +				if (!rn->aggregate) { +					rn->aggregate = skiplist_new( +						0, rfapi_rib_key_cmp, +						(void (*)(void *)) +							rfapi_info_free); +					route_lock_node(rn); +				} +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + +				/* sanity check lifetime */ +				if (ri->lifetime +				    > RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) +					ri->lifetime = +						RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; + +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +				/* cancel normal expire timer */ +				if (ri->timer) { +					struct rfapi_rib_tcb *tcb; + +					tcb = ((struct thread *)ri->timer)->arg; +					thread_cancel( +						(struct thread *)ri->timer); +					XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +					ri->timer = NULL; +				} +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + +				/* +				 * Look in "recently-deleted" list +				 */ +				if (skiplist_search( +					    (struct skiplist *)(rn->aggregate), +					    &ri->rk, (void **)&ri_del)) { + +					int rc; + +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					/* +					 * NOT in "recently-deleted" list +					 */ +					list_delete_node( +						delete_list, +						node); /* does not free ri */ +					rc = skiplist_insert( +						(struct skiplist +							 *)(rn->aggregate), +						&ri->rk, ri); +					assert(!rc); + +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					rfapiRibStartTimer(rfd, ri, rn, 1); +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					ri->last_sent_time = rfapi_time(NULL);  #if DEBUG_RIB_SL_RD -		  { -		    char buf_rd[BUFSIZ]; -		    prefix_rd2str(&ri->rk.rd, buf_rd, sizeof(buf_rd)); -		    vnc_zlog_debug_verbose("%s: move route to recently deleted list, rd=%s", -			__func__, buf_rd); -		  } +					{ +						char buf_rd[BUFSIZ]; +						prefix_rd2str(&ri->rk.rd, +							      buf_rd, +							      sizeof(buf_rd)); +						vnc_zlog_debug_verbose( +							"%s: move route to recently deleted list, rd=%s", +							__func__, buf_rd); +					}  #endif -                } -              else -                { -                  /* -                   * IN "recently-deleted" list -                   */ -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  rfapiRibStartTimer (rfd, ri_del, rn, 1); -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  ri->last_sent_time = rfapi_time (NULL); - -                } -            } -        } -      else -        { -          vnc_zlog_debug_verbose ("%s: response removal disabled, omitting removals", -                      __func__); -        } - -      delete_list->del = (void (*)(void *)) rfapi_info_free; -      list_delete (delete_list); -    } - -  RFAPI_RIB_CHECK_COUNTS (0, 0); - -  /* -   * Reset pending lists. The final route_unlock_node() will probably -   * cause the pending node to be released. -   */ -  if (slPendPt) -    { -      skiplist_free (slPendPt); -      pn->aggregate = NULL; -      route_unlock_node (pn); -    } -  if (lPendCost) -    { -      list_delete (lPendCost); -      pn->info = NULL; -      route_unlock_node (pn); -    } -  RFAPI_RIB_CHECK_COUNTS (0, 0); - -  if (rib_node_started_nonempty) -    { -      if (!rn->info) -        { -          RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); -        } -    } -  else -    { -      if (rn->info) -        { -          RFAPI_RIB_PREFIX_COUNT_INCR (rfd, bgp->rfapi); -        } -    } - -  if (sendingsomeroutes) -    rfapiMonitorTimersRestart (rfd, &pn->p); - -  route_unlock_node (rn);       /* route_node_get() */ - -  RFAPI_RIB_CHECK_COUNTS (1, 0); +				} else { +					/* +					 * IN "recently-deleted" list +					 */ +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					rfapiRibStartTimer(rfd, ri_del, rn, 1); +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					ri->last_sent_time = rfapi_time(NULL); +				} +			} +		} else { +			vnc_zlog_debug_verbose( +				"%s: response removal disabled, omitting removals", +				__func__); +		} + +		delete_list->del = (void (*)(void *))rfapi_info_free; +		list_delete(delete_list); +	} + +	RFAPI_RIB_CHECK_COUNTS(0, 0); + +	/* +	 * Reset pending lists. The final route_unlock_node() will probably +	 * cause the pending node to be released. +	 */ +	if (slPendPt) { +		skiplist_free(slPendPt); +		pn->aggregate = NULL; +		route_unlock_node(pn); +	} +	if (lPendCost) { +		list_delete(lPendCost); +		pn->info = NULL; +		route_unlock_node(pn); +	} +	RFAPI_RIB_CHECK_COUNTS(0, 0); + +	if (rib_node_started_nonempty) { +		if (!rn->info) { +			RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); +		} +	} else { +		if (rn->info) { +			RFAPI_RIB_PREFIX_COUNT_INCR(rfd, bgp->rfapi); +		} +	} + +	if (sendingsomeroutes) +		rfapiMonitorTimersRestart(rfd, &pn->p); + +	route_unlock_node(rn); /* route_node_get() */ + +	RFAPI_RIB_CHECK_COUNTS(1, 0);  }  /* @@ -1503,97 +1484,95 @@ callback:   * Do callback   *   */ -static void -rib_do_callback_onepass (struct rfapi_descriptor *rfd, afi_t afi) +static void rib_do_callback_onepass(struct rfapi_descriptor *rfd, afi_t afi)  { -  struct bgp *bgp = bgp_get_default (); -  struct rfapi_next_hop_entry *head = NULL; -  struct rfapi_next_hop_entry *tail = NULL; -  struct route_node *rn; +	struct bgp *bgp = bgp_get_default(); +	struct rfapi_next_hop_entry *head = NULL; +	struct rfapi_next_hop_entry *tail = NULL; +	struct route_node *rn;  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: rfd=%p, afi=%d", __func__, rfd, afi); +	vnc_zlog_debug_verbose("%s: rfd=%p, afi=%d", __func__, rfd, afi);  #endif -  if (!rfd->rib_pending[afi]) -    return; +	if (!rfd->rib_pending[afi]) +		return; -  assert (bgp->rfapi); +	assert(bgp->rfapi); -  for (rn = route_top (rfd->rib_pending[afi]); rn; rn = route_next (rn)) -    { -      process_pending_node (bgp, rfd, afi, rn, &head, &tail); -    } +	for (rn = route_top(rfd->rib_pending[afi]); rn; rn = route_next(rn)) { +		process_pending_node(bgp, rfd, afi, rn, &head, &tail); +	} -  if (head) -    { -      rfapi_response_cb_t *f; +	if (head) { +		rfapi_response_cb_t *f;  #if DEBUG_NHL -      vnc_zlog_debug_verbose ("%s: response callback NHL follows:", __func__); -      rfapiPrintNhl (NULL, head); +		vnc_zlog_debug_verbose("%s: response callback NHL follows:", +				       __func__); +		rfapiPrintNhl(NULL, head);  #endif -      if (rfd->response_cb) -        f = rfd->response_cb; -      else -        f = bgp->rfapi->rfp_methods.response_cb; - -      bgp->rfapi->flags |= RFAPI_INCALLBACK; -      vnc_zlog_debug_verbose ("%s: invoking updated response callback", __func__); -      (*f) (head, rfd->cookie); -      bgp->rfapi->flags &= ~RFAPI_INCALLBACK; -      ++bgp->rfapi->response_updated_count; -    } +		if (rfd->response_cb) +			f = rfd->response_cb; +		else +			f = bgp->rfapi->rfp_methods.response_cb; + +		bgp->rfapi->flags |= RFAPI_INCALLBACK; +		vnc_zlog_debug_verbose("%s: invoking updated response callback", +				       __func__); +		(*f)(head, rfd->cookie); +		bgp->rfapi->flags &= ~RFAPI_INCALLBACK; +		++bgp->rfapi->response_updated_count; +	}  } -static wq_item_status -rfapiRibDoQueuedCallback (struct work_queue *wq, void *data) +static wq_item_status rfapiRibDoQueuedCallback(struct work_queue *wq, +					       void *data)  { -  struct rfapi_descriptor *rfd; -  afi_t afi; -  uint32_t queued_flag; +	struct rfapi_descriptor *rfd; +	afi_t afi; +	uint32_t queued_flag; -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  rfd = ((struct rfapi_updated_responses_queue *) data)->rfd; -  afi = ((struct rfapi_updated_responses_queue *) data)->afi; +	rfd = ((struct rfapi_updated_responses_queue *)data)->rfd; +	afi = ((struct rfapi_updated_responses_queue *)data)->afi; -  /* Make sure the HD wasn't closed after the work item was scheduled */ -  if (rfapi_check (rfd)) -    return WQ_SUCCESS; +	/* Make sure the HD wasn't closed after the work item was scheduled */ +	if (rfapi_check(rfd)) +		return WQ_SUCCESS; -  rib_do_callback_onepass (rfd, afi); +	rib_do_callback_onepass(rfd, afi); -  queued_flag = RFAPI_QUEUED_FLAG (afi); +	queued_flag = RFAPI_QUEUED_FLAG(afi); -  UNSET_FLAG (rfd->flags, queued_flag); +	UNSET_FLAG(rfd->flags, queued_flag); -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  return WQ_SUCCESS; +	return WQ_SUCCESS;  } -static void -rfapiRibQueueItemDelete (struct work_queue *wq, void *data) +static void rfapiRibQueueItemDelete(struct work_queue *wq, void *data)  { -  XFREE (MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, data); +	XFREE(MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, data);  } -static void -updated_responses_queue_init (struct rfapi_descriptor *rfd) +static void updated_responses_queue_init(struct rfapi_descriptor *rfd)  { -  if (rfd->updated_responses_queue) -    return; - -  rfd->updated_responses_queue = work_queue_new (bm->master, -                                                 "rfapi updated responses"); -  assert (rfd->updated_responses_queue); - -  rfd->updated_responses_queue->spec.workfunc = rfapiRibDoQueuedCallback; -  rfd->updated_responses_queue->spec.del_item_data = rfapiRibQueueItemDelete; -  rfd->updated_responses_queue->spec.max_retries = 0; -  rfd->updated_responses_queue->spec.hold = 1; +	if (rfd->updated_responses_queue) +		return; + +	rfd->updated_responses_queue = +		work_queue_new(bm->master, "rfapi updated responses"); +	assert(rfd->updated_responses_queue); + +	rfd->updated_responses_queue->spec.workfunc = rfapiRibDoQueuedCallback; +	rfd->updated_responses_queue->spec.del_item_data = +		rfapiRibQueueItemDelete; +	rfd->updated_responses_queue->spec.max_retries = 0; +	rfd->updated_responses_queue->spec.hold = 1;  }  /* @@ -1608,217 +1587,200 @@ updated_responses_queue_init (struct rfapi_descriptor *rfd)   *   * Based on rfapiNhlAddNodeRoutes()   */ -void -rfapiRibUpdatePendingNode ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_import_table	*it,        /* needed for L2 */ -  struct route_node		*it_node, -  uint32_t			lifetime) +void rfapiRibUpdatePendingNode( +	struct bgp *bgp, struct rfapi_descriptor *rfd, +	struct rfapi_import_table *it, /* needed for L2 */ +	struct route_node *it_node, uint32_t lifetime)  { -  struct prefix			*prefix; -  struct bgp_info		*bi; -  struct route_node		*pn; -  afi_t				afi; -  uint32_t			queued_flag; -  int				count = 0; -  char				buf[BUFSIZ]; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  if (CHECK_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_CALLBACK_DISABLE)) -    return; - -  vnc_zlog_debug_verbose ("%s: callbacks are not disabled", __func__); - -  RFAPI_RIB_CHECK_COUNTS (1, 0); - -  prefix = &it_node->p; -  afi = family2afi (prefix->family); -  prefix2str (prefix, buf, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: prefix=%s", __func__, buf); - -  pn = route_node_get (rfd->rib_pending[afi], prefix); -  assert (pn); - -  vnc_zlog_debug_verbose ("%s: pn->info=%p, pn->aggregate=%p", __func__, pn->info, -              pn->aggregate); - -  if (pn->aggregate) -    { -      /*  -       * free references into the rfapi_info structures before -       * freeing the structures themselves -       */ -      skiplist_free ((struct skiplist *) (pn->aggregate)); -      pn->aggregate = NULL; -      route_unlock_node (pn);   /* skiplist deleted */ -    } - - -  /*  -   * free the rfapi_info structures -   */ -  if (pn->info) -    { -      if (pn->info != (void *) 1) -        { -          list_delete ((struct list *) (pn->info)); -        } -      pn->info = NULL; -      route_unlock_node (pn);   /* linklist or 1 deleted */ -    } - -  /* -   * The BIs in the import table are already sorted by cost -   */ -  for (bi = it_node->info; bi; bi = bi->next) -    { - -      struct rfapi_info *ri; -      struct prefix pfx_nh; - -      if (!bi->attr) -        { -          /* shouldn't happen */ -          /* TBD increment error stats counter */ -          continue; -        } -      if (!bi->extra) -        { -          /* shouldn't happen */ -          /* TBD increment error stats counter */ -          continue; -        } - -      rfapiNexthop2Prefix (bi->attr, &pfx_nh); - -      /* -       * Omit route if nexthop is self -       */ -      if (CHECK_FLAG -          (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) -        { - -          struct prefix pfx_vn; - -          rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn); -          if (prefix_same (&pfx_vn, &pfx_nh)) -            continue; -        } - -      ri = rfapi_info_new (); -      ri->rk.vn = pfx_nh; -      ri->rk.rd = bi->extra->vnc.import.rd; -      /* -       * If there is an auxiliary IP address (L2 can have it), copy it -       */ -      if (bi->extra->vnc.import.aux_prefix.family) -        { -          ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; -        } - -      if (rfapiGetUnAddrOfVpnBi (bi, &ri->un)) -        { -          rfapi_info_free (ri); -          continue; -        } - -      if (!pn->aggregate) -        { -          pn->aggregate = skiplist_new (0, rfapi_rib_key_cmp, NULL); -          route_lock_node (pn); -        } - -      /* -       * If we have already added this nexthop, the insert will fail. -       * Note that the skiplist key is a pointer INTO the rfapi_info -       * structure which will be added to the "info" list. -       * The skiplist entry VALUE is not used for anything but -       * might be useful during debugging. -       */ -      if (skiplist_insert ((struct skiplist *) pn->aggregate, &ri->rk, ri)) -        { - -          /* -           * duplicate -           */ -          rfapi_info_free (ri); -          continue; -        } - -      rfapiRibBi2Ri(bi, ri, lifetime); - -      if (!pn->info) -        { -          pn->info = list_new (); -          ((struct list *)(pn->info))->del = (void (*)(void *))rfapi_info_free; -          route_lock_node (pn); -        } - -      listnode_add ((struct list *) (pn->info), ri); -    } - -  if (pn->info) -    { -      count = ((struct list *) (pn->info))->count; -    } - -  if (!count) -    { -      assert (!pn->info); -      assert (!pn->aggregate); -      pn->info = (void *) 1;    /* magic value means this node has no routes */ -      route_lock_node (pn); -    } - -  route_unlock_node (pn);       /* route_node_get */ - -  queued_flag = RFAPI_QUEUED_FLAG (afi); - -  if (!CHECK_FLAG (rfd->flags, queued_flag)) -    { - -      struct rfapi_updated_responses_queue *urq; - -      urq = XCALLOC (MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, -                     sizeof (struct rfapi_updated_responses_queue)); -      assert (urq); -      if (!rfd->updated_responses_queue) -        updated_responses_queue_init (rfd); - -      SET_FLAG (rfd->flags, queued_flag); -      urq->rfd = rfd; -      urq->afi = afi; -      work_queue_add (rfd->updated_responses_queue, urq); -    } -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	struct prefix *prefix; +	struct bgp_info *bi; +	struct route_node *pn; +	afi_t afi; +	uint32_t queued_flag; +	int count = 0; +	char buf[BUFSIZ]; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	if (CHECK_FLAG(bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_CALLBACK_DISABLE)) +		return; + +	vnc_zlog_debug_verbose("%s: callbacks are not disabled", __func__); + +	RFAPI_RIB_CHECK_COUNTS(1, 0); + +	prefix = &it_node->p; +	afi = family2afi(prefix->family); +	prefix2str(prefix, buf, BUFSIZ); +	vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf); + +	pn = route_node_get(rfd->rib_pending[afi], prefix); +	assert(pn); + +	vnc_zlog_debug_verbose("%s: pn->info=%p, pn->aggregate=%p", __func__, +			       pn->info, pn->aggregate); + +	if (pn->aggregate) { +		/* +		 * free references into the rfapi_info structures before +		 * freeing the structures themselves +		 */ +		skiplist_free((struct skiplist *)(pn->aggregate)); +		pn->aggregate = NULL; +		route_unlock_node(pn); /* skiplist deleted */ +	} + + +	/* +	 * free the rfapi_info structures +	 */ +	if (pn->info) { +		if (pn->info != (void *)1) { +			list_delete((struct list *)(pn->info)); +		} +		pn->info = NULL; +		route_unlock_node(pn); /* linklist or 1 deleted */ +	} + +	/* +	 * The BIs in the import table are already sorted by cost +	 */ +	for (bi = it_node->info; bi; bi = bi->next) { + +		struct rfapi_info *ri; +		struct prefix pfx_nh; + +		if (!bi->attr) { +			/* shouldn't happen */ +			/* TBD increment error stats counter */ +			continue; +		} +		if (!bi->extra) { +			/* shouldn't happen */ +			/* TBD increment error stats counter */ +			continue; +		} + +		rfapiNexthop2Prefix(bi->attr, &pfx_nh); + +		/* +		 * Omit route if nexthop is self +		 */ +		if (CHECK_FLAG(bgp->rfapi_cfg->flags, +			       BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) { + +			struct prefix pfx_vn; + +			rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn); +			if (prefix_same(&pfx_vn, &pfx_nh)) +				continue; +		} + +		ri = rfapi_info_new(); +		ri->rk.vn = pfx_nh; +		ri->rk.rd = bi->extra->vnc.import.rd; +		/* +		 * If there is an auxiliary IP address (L2 can have it), copy it +		 */ +		if (bi->extra->vnc.import.aux_prefix.family) { +			ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; +		} + +		if (rfapiGetUnAddrOfVpnBi(bi, &ri->un)) { +			rfapi_info_free(ri); +			continue; +		} + +		if (!pn->aggregate) { +			pn->aggregate = +				skiplist_new(0, rfapi_rib_key_cmp, NULL); +			route_lock_node(pn); +		} + +		/* +		 * If we have already added this nexthop, the insert will fail. +		 * Note that the skiplist key is a pointer INTO the rfapi_info +		 * structure which will be added to the "info" list. +		 * The skiplist entry VALUE is not used for anything but +		 * might be useful during debugging. +		 */ +		if (skiplist_insert((struct skiplist *)pn->aggregate, &ri->rk, +				    ri)) { + +			/* +			 * duplicate +			 */ +			rfapi_info_free(ri); +			continue; +		} + +		rfapiRibBi2Ri(bi, ri, lifetime); + +		if (!pn->info) { +			pn->info = list_new(); +			((struct list *)(pn->info))->del = +				(void (*)(void *))rfapi_info_free; +			route_lock_node(pn); +		} + +		listnode_add((struct list *)(pn->info), ri); +	} + +	if (pn->info) { +		count = ((struct list *)(pn->info))->count; +	} + +	if (!count) { +		assert(!pn->info); +		assert(!pn->aggregate); +		pn->info = (void *)1; /* magic value means this node has no +					 routes */ +		route_lock_node(pn); +	} + +	route_unlock_node(pn); /* route_node_get */ + +	queued_flag = RFAPI_QUEUED_FLAG(afi); + +	if (!CHECK_FLAG(rfd->flags, queued_flag)) { + +		struct rfapi_updated_responses_queue *urq; + +		urq = XCALLOC(MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, +			      sizeof(struct rfapi_updated_responses_queue)); +		assert(urq); +		if (!rfd->updated_responses_queue) +			updated_responses_queue_init(rfd); + +		SET_FLAG(rfd->flags, queued_flag); +		urq->rfd = rfd; +		urq->afi = afi; +		work_queue_add(rfd->updated_responses_queue, urq); +	} +	RFAPI_RIB_CHECK_COUNTS(1, 0);  } -void -rfapiRibUpdatePendingNodeSubtree ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_import_table	*it, -  struct route_node		*it_node, -  struct route_node		*omit_subtree,    /* may be NULL */ -  uint32_t			lifetime) +void rfapiRibUpdatePendingNodeSubtree( +	struct bgp *bgp, struct rfapi_descriptor *rfd, +	struct rfapi_import_table *it, struct route_node *it_node, +	struct route_node *omit_subtree, /* may be NULL */ +	uint32_t lifetime)  { -  if (it_node->l_left && (it_node->l_left != omit_subtree)) -    { -      if (it_node->l_left->info) -        rfapiRibUpdatePendingNode (bgp, rfd, it, it_node->l_left, lifetime); -      rfapiRibUpdatePendingNodeSubtree (bgp, rfd, it, it_node->l_left, -                                        omit_subtree, lifetime); -    } - -  if (it_node->l_right && (it_node->l_right != omit_subtree)) -    { -      if (it_node->l_right->info) -        rfapiRibUpdatePendingNode (bgp, rfd, it, it_node->l_right, lifetime); -      rfapiRibUpdatePendingNodeSubtree (bgp, rfd, it, it_node->l_right, -                                        omit_subtree, lifetime); -    } +	if (it_node->l_left && (it_node->l_left != omit_subtree)) { +		if (it_node->l_left->info) +			rfapiRibUpdatePendingNode(bgp, rfd, it, it_node->l_left, +						  lifetime); +		rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_left, +						 omit_subtree, lifetime); +	} + +	if (it_node->l_right && (it_node->l_right != omit_subtree)) { +		if (it_node->l_right->info) +			rfapiRibUpdatePendingNode(bgp, rfd, it, +						  it_node->l_right, lifetime); +		rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_right, +						 omit_subtree, lifetime); +	}  }  /* @@ -1827,72 +1789,72 @@ rfapiRibUpdatePendingNodeSubtree (   *	0	allow prefix to be included in response   *	!0	don't allow prefix to be included in response   */ -int -rfapiRibFTDFilterRecentPrefix( -  struct rfapi_descriptor	*rfd, -  struct route_node             *it_rn,                /* import table node */ -  struct prefix                 *pfx_target_original)  /* query target */ +int rfapiRibFTDFilterRecentPrefix( +	struct rfapi_descriptor *rfd, +	struct route_node *it_rn,	   /* import table node */ +	struct prefix *pfx_target_original) /* query target */  { -  struct bgp			*bgp = rfd->bgp; -  afi_t                         afi = family2afi(it_rn->p.family); -  time_t                        prefix_time; -  struct route_node             *trn; - -  /* -   * Not in FTD mode, so allow prefix -   */ -  if (bgp->rfapi_cfg->rfp_cfg.download_type != RFAPI_RFP_DOWNLOAD_FULL) -    return 0; - -  /* -   * TBD -   * This matches behavior of now-obsolete rfapiRibFTDFilterRecent(), -   * but we need to decide if that is correct. -   */ -  if (it_rn->p.family == AF_ETHERNET) -    return 0; +	struct bgp *bgp = rfd->bgp; +	afi_t afi = family2afi(it_rn->p.family); +	time_t prefix_time; +	struct route_node *trn; + +	/* +	 * Not in FTD mode, so allow prefix +	 */ +	if (bgp->rfapi_cfg->rfp_cfg.download_type != RFAPI_RFP_DOWNLOAD_FULL) +		return 0; + +	/* +	 * TBD +	 * This matches behavior of now-obsolete rfapiRibFTDFilterRecent(), +	 * but we need to decide if that is correct. +	 */ +	if (it_rn->p.family == AF_ETHERNET) +		return 0;  #if DEBUG_FTD_FILTER_RECENT -  { -    char   buf_pfx[BUFSIZ]; +	{ +		char buf_pfx[BUFSIZ]; -    prefix2str(&it_rn->p, buf_pfx, BUFSIZ); -    vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx); -  } +		prefix2str(&it_rn->p, buf_pfx, BUFSIZ); +		vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx); +	}  #endif -  /* -   * prefix covers target address, so allow prefix -   */ -  if (prefix_match (&it_rn->p, pfx_target_original)) -    { +	/* +	 * prefix covers target address, so allow prefix +	 */ +	if (prefix_match(&it_rn->p, pfx_target_original)) {  #if DEBUG_FTD_FILTER_RECENT -      vnc_zlog_debug_verbose("%s: prefix covers target, allowed", __func__); +		vnc_zlog_debug_verbose("%s: prefix covers target, allowed", +				       __func__);  #endif -      return 0; -    } +		return 0; +	} -  /* -   * check this NVE's timestamp for this prefix -   */ -  trn = route_node_get (rfd->rsp_times[afi], &it_rn->p);  /* locks trn */ -  prefix_time = (time_t) trn->info; -  if (trn->lock > 1) -    route_unlock_node (trn); +	/* +	 * check this NVE's timestamp for this prefix +	 */ +	trn = route_node_get(rfd->rsp_times[afi], &it_rn->p); /* locks trn */ +	prefix_time = (time_t)trn->info; +	if (trn->lock > 1) +		route_unlock_node(trn);  #if DEBUG_FTD_FILTER_RECENT -  vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu", -    __func__, prefix_time, rfd->ftd_last_allowed_time); +	vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu", +			       __func__, prefix_time, +			       rfd->ftd_last_allowed_time);  #endif -  /* -   * haven't sent this prefix, which doesn't cover target address, -   * to NVE since ftd_advertisement_interval, so OK to send now. -   */ -  if (prefix_time <= rfd->ftd_last_allowed_time) -    return 0; +	/* +	 * haven't sent this prefix, which doesn't cover target address, +	 * to NVE since ftd_advertisement_interval, so OK to send now. +	 */ +	if (prefix_time <= rfd->ftd_last_allowed_time) +		return 0; -  return 1; +	return 1;  }  /* @@ -1903,651 +1865,629 @@ rfapiRibFTDFilterRecentPrefix(   * value of nexthop chain.   */  struct rfapi_next_hop_entry * -rfapiRibPreload ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_next_hop_entry	*response, -  int				use_eth_resolution) +rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, +		struct rfapi_next_hop_entry *response, int use_eth_resolution)  { -  struct rfapi_next_hop_entry *nhp; -  struct rfapi_next_hop_entry *nhp_next; -  struct rfapi_next_hop_entry *head = NULL; -  struct rfapi_next_hop_entry *tail = NULL; -  time_t new_last_sent_time; - -  vnc_zlog_debug_verbose ("%s: loading response=%p, use_eth_resolution=%d", -              __func__, response, use_eth_resolution); - -  new_last_sent_time = rfapi_time (NULL); - -  for (nhp = response; nhp; nhp = nhp_next) -    { - -      struct prefix pfx; -      struct rfapi_rib_key rk; -      afi_t afi; -      struct rfapi_info *ri; -      int need_insert; -      struct route_node *rn; -      int rib_node_started_nonempty = 0; -      struct route_node *trn; -      int allowed = 0; - -      /* save in case we delete nhp */ -      nhp_next = nhp->next; - -      if (nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME) -        { -          /* -           * weird, shouldn't happen -           */ -          vnc_zlog_debug_verbose -            ("%s: got nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME", -             __func__); -          continue; -        } - - -      if (use_eth_resolution) -        { -          /* get the prefix of the ethernet address in the L2 option */ -          struct rfapi_l2address_option *pL2o; -          struct rfapi_vn_option *vo; - -          /* -           * Look for VN option of type RFAPI_VN_OPTION_TYPE_L2ADDR -           */ -          for (pL2o = NULL, vo = nhp->vn_options; vo; vo = vo->next) -            { -              if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) -                { -                  pL2o = &vo->v.l2addr; -                  break; -                } -            } - -          if (!pL2o) -            { -              /* -               * not supposed to happen -               */ -              vnc_zlog_debug_verbose ("%s: missing L2 info", __func__); -              continue; -            } - -          afi = AFI_L2VPN; -          rfapiL2o2Qprefix (pL2o, &pfx); -        } -      else -        { -          rfapiRprefix2Qprefix (&nhp->prefix, &pfx); -          afi = family2afi (pfx.family); -        } - -      /* -       * TBD for ethernet, rib must know the right way to distinguish -       * duplicate routes -       * -       * Current approach: prefix is key to radix tree; then -       * each prefix has a set of routes with unique VN addrs -       */ - -      /* -       * Look up prefix in RIB -       */ -      rn = route_node_get (rfd->rib[afi], &pfx);        /* locks rn */ - -      if (rn->info) -        { -          rib_node_started_nonempty = 1; -        } -      else -        { -          rn->info = skiplist_new (0, rfapi_rib_key_cmp, NULL); -          route_lock_node (rn); -        } - -      /* -       * Look up route at prefix -       */ -      need_insert = 0; -      memset ((void *) &rk, 0, sizeof (rk)); -      assert (!rfapiRaddr2Qprefix (&nhp->vn_address, &rk.vn)); - -      if (use_eth_resolution) -        { -          /* copy what came from aux_prefix to rk.aux_prefix */ -          rfapiRprefix2Qprefix (&nhp->prefix, &rk.aux_prefix); -          if (RFAPI_0_PREFIX (&rk.aux_prefix) -              && RFAPI_HOST_PREFIX (&rk.aux_prefix)) -            { -              /* mark as "none" if nhp->prefix is 0/32 or 0/128 */ -              rk.aux_prefix.family = 0; -            } -        } +	struct rfapi_next_hop_entry *nhp; +	struct rfapi_next_hop_entry *nhp_next; +	struct rfapi_next_hop_entry *head = NULL; +	struct rfapi_next_hop_entry *tail = NULL; +	time_t new_last_sent_time; + +	vnc_zlog_debug_verbose("%s: loading response=%p, use_eth_resolution=%d", +			       __func__, response, use_eth_resolution); + +	new_last_sent_time = rfapi_time(NULL); + +	for (nhp = response; nhp; nhp = nhp_next) { + +		struct prefix pfx; +		struct rfapi_rib_key rk; +		afi_t afi; +		struct rfapi_info *ri; +		int need_insert; +		struct route_node *rn; +		int rib_node_started_nonempty = 0; +		struct route_node *trn; +		int allowed = 0; + +		/* save in case we delete nhp */ +		nhp_next = nhp->next; + +		if (nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME) { +			/* +			 * weird, shouldn't happen +			 */ +			vnc_zlog_debug_verbose( +				"%s: got nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME", +				__func__); +			continue; +		} + + +		if (use_eth_resolution) { +			/* get the prefix of the ethernet address in the L2 +			 * option */ +			struct rfapi_l2address_option *pL2o; +			struct rfapi_vn_option *vo; + +			/* +			 * Look for VN option of type +			 * RFAPI_VN_OPTION_TYPE_L2ADDR +			 */ +			for (pL2o = NULL, vo = nhp->vn_options; vo; +			     vo = vo->next) { +				if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) { +					pL2o = &vo->v.l2addr; +					break; +				} +			} + +			if (!pL2o) { +				/* +				 * not supposed to happen +				 */ +				vnc_zlog_debug_verbose("%s: missing L2 info", +						       __func__); +				continue; +			} + +			afi = AFI_L2VPN; +			rfapiL2o2Qprefix(pL2o, &pfx); +		} else { +			rfapiRprefix2Qprefix(&nhp->prefix, &pfx); +			afi = family2afi(pfx.family); +		} + +		/* +		 * TBD for ethernet, rib must know the right way to distinguish +		 * duplicate routes +		 * +		 * Current approach: prefix is key to radix tree; then +		 * each prefix has a set of routes with unique VN addrs +		 */ + +		/* +		 * Look up prefix in RIB +		 */ +		rn = route_node_get(rfd->rib[afi], &pfx); /* locks rn */ + +		if (rn->info) { +			rib_node_started_nonempty = 1; +		} else { +			rn->info = skiplist_new(0, rfapi_rib_key_cmp, NULL); +			route_lock_node(rn); +		} + +		/* +		 * Look up route at prefix +		 */ +		need_insert = 0; +		memset((void *)&rk, 0, sizeof(rk)); +		assert(!rfapiRaddr2Qprefix(&nhp->vn_address, &rk.vn)); + +		if (use_eth_resolution) { +			/* copy what came from aux_prefix to rk.aux_prefix */ +			rfapiRprefix2Qprefix(&nhp->prefix, &rk.aux_prefix); +			if (RFAPI_0_PREFIX(&rk.aux_prefix) +			    && RFAPI_HOST_PREFIX(&rk.aux_prefix)) { +				/* mark as "none" if nhp->prefix is 0/32 or +				 * 0/128 */ +				rk.aux_prefix.family = 0; +			} +		}  #if DEBUG_NHL -      { -        char str_vn[BUFSIZ]; -        char str_aux_prefix[BUFSIZ]; - -        str_vn[0] = 0; -        str_aux_prefix[0] = 0; - -        prefix2str (&rk.vn, str_vn, BUFSIZ); -        prefix2str (&rk.aux_prefix, str_aux_prefix, BUFSIZ); - -        if (!rk.aux_prefix.family) -          { - -          } -        vnc_zlog_debug_verbose ("%s:   rk.vn=%s rk.aux_prefix=%s", -                    __func__, str_vn, -                    (rk.aux_prefix.family ? str_aux_prefix : "-")); -      } -      vnc_zlog_debug_verbose ("%s: RIB skiplist for this prefix follows", __func__); -      rfapiRibShowRibSl (NULL, &rn->p, (struct skiplist *) rn->info); +		{ +			char str_vn[BUFSIZ]; +			char str_aux_prefix[BUFSIZ]; + +			str_vn[0] = 0; +			str_aux_prefix[0] = 0; + +			prefix2str(&rk.vn, str_vn, BUFSIZ); +			prefix2str(&rk.aux_prefix, str_aux_prefix, BUFSIZ); + +			if (!rk.aux_prefix.family) { +			} +			vnc_zlog_debug_verbose( +				"%s:   rk.vn=%s rk.aux_prefix=%s", __func__, +				str_vn, +				(rk.aux_prefix.family ? str_aux_prefix : "-")); +		} +		vnc_zlog_debug_verbose( +			"%s: RIB skiplist for this prefix follows", __func__); +		rfapiRibShowRibSl(NULL, &rn->p, (struct skiplist *)rn->info);  #endif -      if (!skiplist_search ((struct skiplist *) rn->info, &rk, (void **) &ri)) -        { -          /* -           * Already have this route; make values match -           */ -          rfapiFreeRfapiUnOptionChain (ri->un_options); -          ri->un_options = NULL; -          rfapiFreeRfapiVnOptionChain (ri->vn_options); -          ri->vn_options = NULL; +		if (!skiplist_search((struct skiplist *)rn->info, &rk, +				     (void **)&ri)) { +			/* +			 * Already have this route; make values match +			 */ +			rfapiFreeRfapiUnOptionChain(ri->un_options); +			ri->un_options = NULL; +			rfapiFreeRfapiVnOptionChain(ri->vn_options); +			ri->vn_options = NULL;  #if DEBUG_NHL -          vnc_zlog_debug_verbose ("%s: found in RIB", __func__); +			vnc_zlog_debug_verbose("%s: found in RIB", __func__);  #endif -          /* -           * Filter duplicate routes from initial response. -           * Check timestamps to avoid wraparound problems -           */ -          if ((ri->rsp_counter != rfd->rsp_counter) || -              (ri->last_sent_time != new_last_sent_time)) -            { +			/* +			 * Filter duplicate routes from initial response. +			 * Check timestamps to avoid wraparound problems +			 */ +			if ((ri->rsp_counter != rfd->rsp_counter) +			    || (ri->last_sent_time != new_last_sent_time)) {  #if DEBUG_NHL -              vnc_zlog_debug_verbose ("%s: allowed due to counter/timestamp diff", -                          __func__); +				vnc_zlog_debug_verbose( +					"%s: allowed due to counter/timestamp diff", +					__func__);  #endif -              allowed = 1; -            } +				allowed = 1; +			} -        } -      else -        { +		} else {  #if DEBUG_NHL -          vnc_zlog_debug_verbose ("%s: allowed due to not yet in RIB", __func__); +			vnc_zlog_debug_verbose( +				"%s: allowed due to not yet in RIB", __func__);  #endif -          /* not found: add new route to RIB */ -          ri = rfapi_info_new (); -          need_insert = 1; -          allowed = 1; -        } - -      ri->rk = rk; -      assert (!rfapiRaddr2Qprefix (&nhp->un_address, &ri->un)); -      ri->cost = nhp->prefix.cost; -      ri->lifetime = nhp->lifetime; -      ri->vn_options = rfapiVnOptionsDup (nhp->vn_options); -      ri->rsp_counter = rfd->rsp_counter; -      ri->last_sent_time = rfapi_time (NULL); - -      if (need_insert) -        { -          int rc; -          rc = skiplist_insert ((struct skiplist *) rn->info, &ri->rk, ri); -          assert (!rc); -        } - -      if (!rib_node_started_nonempty) -        { -          RFAPI_RIB_PREFIX_COUNT_INCR (rfd, bgp->rfapi); -        } - -      RFAPI_RIB_CHECK_COUNTS (0, 0); -      rfapiRibStartTimer (rfd, ri, rn, 0); -      RFAPI_RIB_CHECK_COUNTS (0, 0); - -      route_unlock_node (rn); - -      /* -       * update this NVE's timestamp for this prefix -       */ -      trn = route_node_get (rfd->rsp_times[afi], &pfx); /* locks trn */ -      trn->info = (void *) (uintptr_t) bgp_clock (); -      if (trn->lock > 1) -        route_unlock_node (trn); - -      { -        char str_pfx[BUFSIZ]; -        char str_pfx_vn[BUFSIZ]; - -        prefix2str (&pfx, str_pfx, BUFSIZ); -        prefix2str (&rk.vn, str_pfx_vn, BUFSIZ); -        vnc_zlog_debug_verbose -          ("%s:   added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d", -           __func__, str_pfx, str_pfx_vn, nhp->prefix.cost, nhp->lifetime, -           allowed); -      } - -      if (allowed) -        { -          if (tail) -            (tail)->next = nhp; -          tail = nhp; -          if (!head) -            { -              head = nhp; -            } -        } -      else -        { -          rfapi_un_options_free (nhp->un_options); -          nhp->un_options = NULL; -          rfapi_vn_options_free (nhp->vn_options); -          nhp->vn_options = NULL; - -          XFREE (MTYPE_RFAPI_NEXTHOP, nhp); -          nhp = NULL; -        } -    } - -  if (tail) -    tail->next = NULL; -  return head; +			/* not found: add new route to RIB */ +			ri = rfapi_info_new(); +			need_insert = 1; +			allowed = 1; +		} + +		ri->rk = rk; +		assert(!rfapiRaddr2Qprefix(&nhp->un_address, &ri->un)); +		ri->cost = nhp->prefix.cost; +		ri->lifetime = nhp->lifetime; +		ri->vn_options = rfapiVnOptionsDup(nhp->vn_options); +		ri->rsp_counter = rfd->rsp_counter; +		ri->last_sent_time = rfapi_time(NULL); + +		if (need_insert) { +			int rc; +			rc = skiplist_insert((struct skiplist *)rn->info, +					     &ri->rk, ri); +			assert(!rc); +		} + +		if (!rib_node_started_nonempty) { +			RFAPI_RIB_PREFIX_COUNT_INCR(rfd, bgp->rfapi); +		} + +		RFAPI_RIB_CHECK_COUNTS(0, 0); +		rfapiRibStartTimer(rfd, ri, rn, 0); +		RFAPI_RIB_CHECK_COUNTS(0, 0); + +		route_unlock_node(rn); + +		/* +		 * update this NVE's timestamp for this prefix +		 */ +		trn = route_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */ +		trn->info = (void *)(uintptr_t)bgp_clock(); +		if (trn->lock > 1) +			route_unlock_node(trn); + +		{ +			char str_pfx[BUFSIZ]; +			char str_pfx_vn[BUFSIZ]; + +			prefix2str(&pfx, str_pfx, BUFSIZ); +			prefix2str(&rk.vn, str_pfx_vn, BUFSIZ); +			vnc_zlog_debug_verbose( +				"%s:   added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d", +				__func__, str_pfx, str_pfx_vn, nhp->prefix.cost, +				nhp->lifetime, allowed); +		} + +		if (allowed) { +			if (tail) +				(tail)->next = nhp; +			tail = nhp; +			if (!head) { +				head = nhp; +			} +		} else { +			rfapi_un_options_free(nhp->un_options); +			nhp->un_options = NULL; +			rfapi_vn_options_free(nhp->vn_options); +			nhp->vn_options = NULL; + +			XFREE(MTYPE_RFAPI_NEXTHOP, nhp); +			nhp = NULL; +		} +	} + +	if (tail) +		tail->next = NULL; +	return head;  } -void -rfapiRibPendingDeleteRoute ( -  struct bgp			*bgp, -  struct rfapi_import_table	*it, -  afi_t				afi, -  struct route_node		*it_node) +void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, +				afi_t afi, struct route_node *it_node)  { -  struct rfapi_descriptor *rfd; -  struct listnode *node; -  char buf[BUFSIZ]; - -  prefix2str (&it_node->p, buf, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: entry, it=%p, afi=%d, it_node=%p, pfx=%s", -              __func__, it, afi, it_node, buf); - -  if (AFI_L2VPN == afi) -    { -      /* -       * ethernet import tables are per-LNI and each ethernet monitor  -       * identifies the rfd that owns it. -       */ -      struct rfapi_monitor_eth *m; -      struct route_node *rn; -      struct skiplist *sl; -      void *cursor; -      int rc; - -      /* -       * route-specific monitors -       */ -      if ((sl = RFAPI_MONITOR_ETH (it_node))) -        { - -          vnc_zlog_debug_verbose ("%s: route-specific skiplist: %p", __func__, sl); - -          for (cursor = NULL, rc = -               skiplist_next (sl, NULL, (void **) &m, (void **) &cursor); !rc; -               rc = skiplist_next (sl, NULL, (void **) &m, (void **) &cursor)) -            { +	struct rfapi_descriptor *rfd; +	struct listnode *node; +	char buf[BUFSIZ]; + +	prefix2str(&it_node->p, buf, BUFSIZ); +	vnc_zlog_debug_verbose("%s: entry, it=%p, afi=%d, it_node=%p, pfx=%s", +			       __func__, it, afi, it_node, buf); + +	if (AFI_L2VPN == afi) { +		/* +		 * ethernet import tables are per-LNI and each ethernet monitor +		 * identifies the rfd that owns it. +		 */ +		struct rfapi_monitor_eth *m; +		struct route_node *rn; +		struct skiplist *sl; +		void *cursor; +		int rc; + +		/* +		 * route-specific monitors +		 */ +		if ((sl = RFAPI_MONITOR_ETH(it_node))) { + +			vnc_zlog_debug_verbose( +				"%s: route-specific skiplist: %p", __func__, +				sl); + +			for (cursor = NULL, +			    rc = skiplist_next(sl, NULL, (void **)&m, +					       (void **)&cursor); +			     !rc; rc = skiplist_next(sl, NULL, (void **)&m, +						     (void **)&cursor)) {  #if DEBUG_PENDING_DELETE_ROUTE -              vnc_zlog_debug_verbose ("%s: eth monitor rfd=%p", __func__, m->rfd); +				vnc_zlog_debug_verbose("%s: eth monitor rfd=%p", +						       __func__, m->rfd);  #endif -              /* -               * If we have already sent a route with this prefix to this -               * NVE, it's OK to send an update with the delete -               */ -              if ((rn = route_node_lookup (m->rfd->rib[afi], &it_node->p))) -                { -                  rfapiRibUpdatePendingNode (bgp, m->rfd, it, it_node, -                                             m->rfd->response_lifetime); -                  route_unlock_node (rn); -                } -            } -        } - -      /* -       * all-routes/FTD monitors -       */ -      for (m = it->eth0_queries; m; m = m->next) -        { +				/* +				 * If we have already sent a route with this +				 * prefix to this +				 * NVE, it's OK to send an update with the +				 * delete +				 */ +				if ((rn = route_node_lookup(m->rfd->rib[afi], +							    &it_node->p))) { +					rfapiRibUpdatePendingNode( +						bgp, m->rfd, it, it_node, +						m->rfd->response_lifetime); +					route_unlock_node(rn); +				} +			} +		} + +		/* +		 * all-routes/FTD monitors +		 */ +		for (m = it->eth0_queries; m; m = m->next) {  #if DEBUG_PENDING_DELETE_ROUTE -          vnc_zlog_debug_verbose ("%s: eth0 monitor rfd=%p", __func__, m->rfd); +			vnc_zlog_debug_verbose("%s: eth0 monitor rfd=%p", +					       __func__, m->rfd);  #endif -          /* -           * If we have already sent a route with this prefix to this -           * NVE, it's OK to send an update with the delete -           */ -          if ((rn = route_node_lookup (m->rfd->rib[afi], &it_node->p))) -            { -              rfapiRibUpdatePendingNode (bgp, m->rfd, it, it_node, -                                         m->rfd->response_lifetime); -            } -        } - -    } -  else -    { -      /* -       * Find RFDs that reference this import table -       */ -      for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -        { - -          struct route_node *rn; - -          vnc_zlog_debug_verbose ("%s: comparing rfd(%p)->import_table=%p to it=%p", -                      __func__, rfd, rfd->import_table, it); - -          if (rfd->import_table != it) -            continue; - -          vnc_zlog_debug_verbose ("%s: matched rfd %p", __func__, rfd); - -          /* -           * If we have sent a response to this NVE with this prefix -           * previously, we should send an updated response. -           */ -          if ((rn = route_node_lookup (rfd->rib[afi], &it_node->p))) -            { -              rfapiRibUpdatePendingNode (bgp, rfd, it, it_node, -                                         rfd->response_lifetime); -              route_unlock_node (rn); -            } -        } -    } +			/* +			 * If we have already sent a route with this prefix to +			 * this +			 * NVE, it's OK to send an update with the delete +			 */ +			if ((rn = route_node_lookup(m->rfd->rib[afi], +						    &it_node->p))) { +				rfapiRibUpdatePendingNode( +					bgp, m->rfd, it, it_node, +					m->rfd->response_lifetime); +			} +		} + +	} else { +		/* +		 * Find RFDs that reference this import table +		 */ +		for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, +					  rfd)) { + +			struct route_node *rn; + +			vnc_zlog_debug_verbose( +				"%s: comparing rfd(%p)->import_table=%p to it=%p", +				__func__, rfd, rfd->import_table, it); + +			if (rfd->import_table != it) +				continue; + +			vnc_zlog_debug_verbose("%s: matched rfd %p", __func__, +					       rfd); + +			/* +			 * If we have sent a response to this NVE with this +			 * prefix +			 * previously, we should send an updated response. +			 */ +			if ((rn = route_node_lookup(rfd->rib[afi], +						    &it_node->p))) { +				rfapiRibUpdatePendingNode( +					bgp, rfd, it, it_node, +					rfd->response_lifetime); +				route_unlock_node(rn); +			} +		} +	}  } -void -rfapiRibShowResponsesSummary (void *stream) +void rfapiRibShowResponsesSummary(void *stream)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; -  struct bgp *bgp = bgp_get_default (); - -  int nves = 0; -  int nves_with_nonempty_ribs = 0; -  struct rfapi_descriptor *rfd; -  struct listnode *node; - - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; - -  fp (out, "%-24s ", "Responses: (Prefixes)"); -  fp (out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total); -  fp (out, "%-8s %-8u", "Maximum:", bgp->rfapi->rib_prefix_count_total_max); -  fp (out, "%s", VTY_NEWLINE); - -  fp (out, "%-24s ", "           (Updated)"); -  fp (out, "%-8s %-8u ", "Update:", -      bgp->rfapi->stat.count_updated_response_updates); -  fp (out, "%-8s %-8u", "Remove:", -      bgp->rfapi->stat.count_updated_response_deletes); -  fp (out, "%-8s %-8u", "Total:", -      bgp->rfapi->stat.count_updated_response_updates + -      bgp->rfapi->stat.count_updated_response_deletes); -  fp (out, "%s", VTY_NEWLINE); - -  fp (out, "%-24s ", "           (NVEs)"); -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -    { -      ++nves; -      if (rfd->rib_prefix_count) -        ++nves_with_nonempty_ribs; -    } -  fp (out, "%-8s %-8u ", "Active:", nves_with_nonempty_ribs); -  fp (out, "%-8s %-8u", "Total:", nves); -  fp (out, "%s", VTY_NEWLINE); - +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; +	struct bgp *bgp = bgp_get_default(); + +	int nves = 0; +	int nves_with_nonempty_ribs = 0; +	struct rfapi_descriptor *rfd; +	struct listnode *node; + + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; + +	fp(out, "%-24s ", "Responses: (Prefixes)"); +	fp(out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total); +	fp(out, "%-8s %-8u", +	   "Maximum:", bgp->rfapi->rib_prefix_count_total_max); +	fp(out, "%s", VTY_NEWLINE); + +	fp(out, "%-24s ", "           (Updated)"); +	fp(out, "%-8s %-8u ", +	   "Update:", bgp->rfapi->stat.count_updated_response_updates); +	fp(out, "%-8s %-8u", +	   "Remove:", bgp->rfapi->stat.count_updated_response_deletes); +	fp(out, "%-8s %-8u", "Total:", +	   bgp->rfapi->stat.count_updated_response_updates +		   + bgp->rfapi->stat.count_updated_response_deletes); +	fp(out, "%s", VTY_NEWLINE); + +	fp(out, "%-24s ", "           (NVEs)"); +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { +		++nves; +		if (rfd->rib_prefix_count) +			++nves_with_nonempty_ribs; +	} +	fp(out, "%-8s %-8u ", "Active:", nves_with_nonempty_ribs); +	fp(out, "%-8s %-8u", "Total:", nves); +	fp(out, "%s", VTY_NEWLINE);  } -void -rfapiRibShowResponsesSummaryClear (void) +void rfapiRibShowResponsesSummaryClear(void)  { -  struct bgp *bgp = bgp_get_default (); +	struct bgp *bgp = bgp_get_default(); -  bgp->rfapi->rib_prefix_count_total_max = bgp->rfapi->rib_prefix_count_total; +	bgp->rfapi->rib_prefix_count_total_max = +		bgp->rfapi->rib_prefix_count_total;  } -static int -print_rib_sl ( -  int (*fp) (void *, const char *, ...), -  struct vty		*vty, -  void			*out, -  struct skiplist	*sl, -  int			deleted, -  char			*str_pfx, -  int			*printedprefix) +static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty, +			void *out, struct skiplist *sl, int deleted, +			char *str_pfx, int *printedprefix)  { -  struct rfapi_info *ri; -  int rc; -  void *cursor; -  int routes_displayed = 0; - -  cursor = NULL; -  for (rc = skiplist_next (sl, NULL, (void **) &ri, &cursor); -       !rc; rc = skiplist_next (sl, NULL, (void **) &ri, &cursor)) -    { - -      char str_vn[BUFSIZ]; -      char str_un[BUFSIZ]; -      char str_lifetime[BUFSIZ]; -      char str_age[BUFSIZ]; -      char *p; -      char str_rd[BUFSIZ]; - -      ++routes_displayed; - -      prefix2str (&ri->rk.vn, str_vn, BUFSIZ); -      p = index (str_vn, '/'); -      if (p) -        *p = 0; - -      prefix2str (&ri->un, str_un, BUFSIZ); -      p = index (str_un, '/'); -      if (p) -        *p = 0; - -      rfapiFormatSeconds (ri->lifetime, str_lifetime, BUFSIZ); +	struct rfapi_info *ri; +	int rc; +	void *cursor; +	int routes_displayed = 0; + +	cursor = NULL; +	for (rc = skiplist_next(sl, NULL, (void **)&ri, &cursor); !rc; +	     rc = skiplist_next(sl, NULL, (void **)&ri, &cursor)) { + +		char str_vn[BUFSIZ]; +		char str_un[BUFSIZ]; +		char str_lifetime[BUFSIZ]; +		char str_age[BUFSIZ]; +		char *p; +		char str_rd[BUFSIZ]; + +		++routes_displayed; + +		prefix2str(&ri->rk.vn, str_vn, BUFSIZ); +		p = index(str_vn, '/'); +		if (p) +			*p = 0; + +		prefix2str(&ri->un, str_un, BUFSIZ); +		p = index(str_un, '/'); +		if (p) +			*p = 0; + +		rfapiFormatSeconds(ri->lifetime, str_lifetime, BUFSIZ);  #if RFAPI_REGISTRATIONS_REPORT_AGE -      rfapiFormatAge (ri->last_sent_time, str_age, BUFSIZ); +		rfapiFormatAge(ri->last_sent_time, str_age, BUFSIZ);  #else -      { -        time_t now = rfapi_time (NULL); -        time_t expire = ri->last_sent_time + (time_t) ri->lifetime; -        /* allow for delayed/async removal */ -        rfapiFormatSeconds ((expire > now ? expire - now : 1), -                            str_age, BUFSIZ); -      } +		{ +			time_t now = rfapi_time(NULL); +			time_t expire = +				ri->last_sent_time + (time_t)ri->lifetime; +			/* allow for delayed/async removal */ +			rfapiFormatSeconds((expire > now ? expire - now : 1), +					   str_age, BUFSIZ); +		}  #endif -    str_rd[0] = 0;	/* start empty */ +		str_rd[0] = 0; /* start empty */  #if DEBUG_RIB_SL_RD -    str_rd[0] = ' '; -    prefix_rd2str(&ri->rk.rd, str_rd+1, BUFSIZ-1); +		str_rd[0] = ' '; +		prefix_rd2str(&ri->rk.rd, str_rd + 1, BUFSIZ - 1);  #endif -      fp (out, " %c %-20s %-15s %-15s %-4u %-8s %-8s%s%s", -          deleted ? 'r' : ' ', -          *printedprefix ? "" : str_pfx, -          str_vn, str_un, ri->cost, str_lifetime, str_age, str_rd, VTY_NEWLINE); +		fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s%s%s", +		   deleted ? 'r' : ' ', *printedprefix ? "" : str_pfx, str_vn, +		   str_un, ri->cost, str_lifetime, str_age, str_rd, +		   VTY_NEWLINE); -      if (!*printedprefix) -        *printedprefix = 1; -    } -  return routes_displayed; +		if (!*printedprefix) +			*printedprefix = 1; +	} +	return routes_displayed;  }  #if DEBUG_NHL  /*   * This one is for debugging (set stream to NULL to send output to log)   */ -static void -rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl) +static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, +			      struct skiplist *sl)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  int nhs_displayed = 0; -  char str_pfx[BUFSIZ]; -  int printedprefix = 0; +	int nhs_displayed = 0; +	char str_pfx[BUFSIZ]; +	int printedprefix = 0; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  prefix2str (pfx, str_pfx, BUFSIZ); +	prefix2str(pfx, str_pfx, BUFSIZ); -  nhs_displayed += print_rib_sl (fp, vty, out, sl, -                                 0, str_pfx, &printedprefix); +	nhs_displayed += +		print_rib_sl(fp, vty, out, sl, 0, str_pfx, &printedprefix);  }  #endif -void -rfapiRibShowResponses ( -  void		*stream, -  struct prefix	*pfx_match, -  int		show_removed) +void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, +			   int show_removed)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  struct rfapi_descriptor *rfd; -  struct listnode *node; - -  struct bgp *bgp = bgp_get_default (); -  int printedheader = 0; -  int routes_total = 0; -  int nhs_total = 0; -  int prefixes_total = 0; -  int prefixes_displayed = 0; -  int nves_total = 0; -  int nves_with_routes = 0; -  int nves_displayed = 0; -  int routes_displayed = 0; -  int nhs_displayed = 0; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  /* -   * loop over NVEs -   */ -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -    { - -      int printednve = 0; -      afi_t afi; - -      ++nves_total; -      if (rfd->rib_prefix_count) -        ++nves_with_routes; - -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          struct route_node *rn; - -          if (!rfd->rib[afi]) -            continue; - -          for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) -            { - -              struct skiplist *sl; -              char str_pfx[BUFSIZ]; -              int printedprefix = 0; - -              if (!show_removed) -                sl = rn->info; -              else -                sl = rn->aggregate; - -              if (!sl) -                continue; - -              routes_total++; -              nhs_total += skiplist_count (sl); -              ++prefixes_total; - -              if (pfx_match && !prefix_match (pfx_match, &rn->p) && -                  !prefix_match (&rn->p, pfx_match)) -                continue; - -              ++prefixes_displayed; - -              if (!printedheader) -                { -                  ++printedheader; - -                  fp (out, "%s[%s]%s", -                      VTY_NEWLINE, -                      show_removed ? "Removed" : "Active", VTY_NEWLINE); -                  fp (out, "%-15s %-15s%s", "Querying VN", "Querying UN", -                      VTY_NEWLINE); -                  fp (out, "   %-20s %-15s %-15s %4s %-8s %-8s%s", -                      "Prefix", "Registered VN", "Registered UN", "Cost", -                      "Lifetime", +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	struct rfapi_descriptor *rfd; +	struct listnode *node; + +	struct bgp *bgp = bgp_get_default(); +	int printedheader = 0; +	int routes_total = 0; +	int nhs_total = 0; +	int prefixes_total = 0; +	int prefixes_displayed = 0; +	int nves_total = 0; +	int nves_with_routes = 0; +	int nves_displayed = 0; +	int routes_displayed = 0; +	int nhs_displayed = 0; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	/* +	 * loop over NVEs +	 */ +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { + +		int printednve = 0; +		afi_t afi; + +		++nves_total; +		if (rfd->rib_prefix_count) +			++nves_with_routes; + +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			struct route_node *rn; + +			if (!rfd->rib[afi]) +				continue; + +			for (rn = route_top(rfd->rib[afi]); rn; +			     rn = route_next(rn)) { + +				struct skiplist *sl; +				char str_pfx[BUFSIZ]; +				int printedprefix = 0; + +				if (!show_removed) +					sl = rn->info; +				else +					sl = rn->aggregate; + +				if (!sl) +					continue; + +				routes_total++; +				nhs_total += skiplist_count(sl); +				++prefixes_total; + +				if (pfx_match +				    && !prefix_match(pfx_match, &rn->p) +				    && !prefix_match(&rn->p, pfx_match)) +					continue; + +				++prefixes_displayed; + +				if (!printedheader) { +					++printedheader; + +					fp(out, "%s[%s]%s", VTY_NEWLINE, +					   show_removed ? "Removed" : "Active", +					   VTY_NEWLINE); +					fp(out, "%-15s %-15s%s", "Querying VN", +					   "Querying UN", VTY_NEWLINE); +					fp(out, +					   "   %-20s %-15s %-15s %4s %-8s %-8s%s", +					   "Prefix", "Registered VN", +					   "Registered UN", "Cost", "Lifetime",  #if RFAPI_REGISTRATIONS_REPORT_AGE -                      "Age", +					   "Age",  #else -                      "Remaining", +					   "Remaining",  #endif -                      VTY_NEWLINE); -                } -              if (!printednve) -                { -                  char str_vn[BUFSIZ]; -                  char str_un[BUFSIZ]; - -                  ++printednve; -                  ++nves_displayed; - -                  fp (out, "%-15s %-15s%s", -                      rfapiRfapiIpAddr2Str (&rfd->vn_addr, str_vn, BUFSIZ), -                      rfapiRfapiIpAddr2Str (&rfd->un_addr, str_un, BUFSIZ), -                      VTY_NEWLINE); - -                } -              prefix2str (&rn->p, str_pfx, BUFSIZ); -              //fp(out, "  %s%s", buf, VTY_NEWLINE);  /* prefix */ - -              routes_displayed++; -              nhs_displayed += print_rib_sl (fp, vty, out, sl, -                                             show_removed, str_pfx, -                                             &printedprefix); -            } -        } -    } - -  if (routes_total) -    { -      fp (out, "%s", VTY_NEWLINE); -      fp (out, "Displayed %u NVEs, and %u out of %u %s prefixes", -          nves_displayed, routes_displayed, -          routes_total, show_removed ? "removed" : "active"); -      if (nhs_displayed != routes_displayed || nhs_total != routes_total) -        fp (out, " with %u out of %u next hops", nhs_displayed, nhs_total); -      fp (out, "%s", VTY_NEWLINE); -    } +					   VTY_NEWLINE); +				} +				if (!printednve) { +					char str_vn[BUFSIZ]; +					char str_un[BUFSIZ]; + +					++printednve; +					++nves_displayed; + +					fp(out, "%-15s %-15s%s", +					   rfapiRfapiIpAddr2Str(&rfd->vn_addr, +								str_vn, BUFSIZ), +					   rfapiRfapiIpAddr2Str(&rfd->un_addr, +								str_un, BUFSIZ), +					   VTY_NEWLINE); +				} +				prefix2str(&rn->p, str_pfx, BUFSIZ); +				// fp(out, "  %s%s", buf, VTY_NEWLINE);  /* +				// prefix */ + +				routes_displayed++; +				nhs_displayed += print_rib_sl( +					fp, vty, out, sl, show_removed, str_pfx, +					&printedprefix); +			} +		} +	} + +	if (routes_total) { +		fp(out, "%s", VTY_NEWLINE); +		fp(out, "Displayed %u NVEs, and %u out of %u %s prefixes", +		   nves_displayed, routes_displayed, routes_total, +		   show_removed ? "removed" : "active"); +		if (nhs_displayed != routes_displayed +		    || nhs_total != routes_total) +			fp(out, " with %u out of %u next hops", nhs_displayed, +			   nhs_total); +		fp(out, "%s", VTY_NEWLINE); +	}  }  | 
