Commit 600998fc authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Modify FIB_WALK() and FIB_ITERATE() to work with new FIB code

Returned user data pointers have offset relative to fib_node.
parent 67aa8833
Loading
Loading
Loading
Loading
+26 −17
Original line number Diff line number Diff line
@@ -65,6 +65,12 @@ struct fib {
  fib_init_fn init;			/* Constructor */
};

static inline void * fib_node_to_user(struct fib *f, struct fib_node *e)
{ return e ? (void *) ((char *) e - f->node_offset) : NULL; }

static inline struct fib_node * fib_user_to_node(struct fib *f, void *e)
{ return e ? (void *) ((char *) e + f->node_offset) : NULL; }

void fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offset, uint hash_order, fib_init_fn init);
void *fib_find(struct fib *, const net_addr *);	/* Find or return NULL if doesn't exist */
void *fib_get(struct fib *, const net_addr *); 	/* Find or create new if nonexistent */
@@ -78,35 +84,38 @@ struct fib_node *fit_get(struct fib *, struct fib_iterator *);
void fit_put(struct fib_iterator *, struct fib_node *);
void fit_put_next(struct fib *f, struct fib_iterator *i, struct fib_node *n, uint hpos);

/* XXXX: return user entries */
#define FIB_WALK(fib, z) do {					\
	struct fib_node *z, **ff = (fib)->hash_table;		\
	uint count = (fib)->hash_size;				\
	while (count--)						\
	  for(z = *ff++; z; z=z->next)

#define FIB_WALK(fib, type, z) do {				\
	struct fib_node *fn_, **ff_ = (fib)->hash_table;	\
	uint count_ = (fib)->hash_size;				\
	type *z;						\
	while (count_--)					\
	  for (fn_ = *ff_++; z = fib_node_to_user(fib, fn_); fn_=fn_->next)

#define FIB_WALK_END } while (0)

#define FIB_ITERATE_INIT(it, fib) fit_init(it, fib)

#define FIB_ITERATE_START(fib, it, z) do {			\
	struct fib_node *z = fit_get(fib, it);			\
	uint count = (fib)->hash_size;				\
	uint hpos = (it)->hash;					\
#define FIB_ITERATE_START(fib, it, type, z) do {		\
	struct fib_node *fn_ = fit_get(fib, it);		\
	uint count_ = (fib)->hash_size;				\
	uint hpos_ = (it)->hash;				\
	type *z;						\
	for(;;) {						\
	  if (!z)						\
	  if (!fn_)						\
            {							\
	       if (++hpos >= count)				\
	       if (++hpos_ >= count_)				\
		 break;						\
	       z = (fib)->hash_table[hpos];			\
	       fn_ = (fib)->hash_table[hpos_];			\
	       continue;					\
	    }
	    }							\
	  z = fib_node_to_user(fib, fn_);

#define FIB_ITERATE_END(z) z = z->next; } } while(0)
#define FIB_ITERATE_END fn_ = fn_->next; } } while(0)

#define FIB_ITERATE_PUT(it, z) fit_put(it, z)
#define FIB_ITERATE_PUT(it) fit_put(it, fn_)

#define FIB_ITERATE_PUT_NEXT(it, fib, z) fit_put_next(fib, it, z, hpos)
#define FIB_ITERATE_PUT_NEXT(it, fib) fit_put_next(fib, it, fn_, hpos_)

#define FIB_ITERATE_UNLINK(it, fib) fit_get(fib, it)

+1 −7
Original line number Diff line number Diff line
@@ -49,12 +49,6 @@
#define HASH_LO_MIN 10


static inline void * fib_node_to_user(struct fib *f, struct fib_node *e)
{ return (void *) ((char *) e - f->node_offset); }

static inline struct fib_node * fib_user_to_node(struct fib *f, void *e)
{ return (void *) ((char *) e + f->node_offset); }

static void
fib_ht_alloc(struct fib *f)
{
@@ -168,7 +162,7 @@ fib_rehash(struct fib *f, int step)
    struct fib_node *e = f->hash_table[FIB_HASH(f, a, t)];		\
    while (e && !net_equal_##t(CAST(t) e->addr, CAST(t) a))		\
      e = e->next;							\
    e ? fib_node_to_user(f, e) : NULL;					\
    fib_node_to_user(f, e);						\
  })

#define FIB_INSERT(f,a,e,t)						\
+27 −38
Original line number Diff line number Diff line
@@ -1315,12 +1315,9 @@ rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter)
void
rt_refresh_begin(rtable *t, struct announce_hook *ah)
{
  net *n;
  rte *e;

  FIB_WALK(&t->fib, fn)
  FIB_WALK(&t->fib, net, n)
    {
      n = (net *) fn;
      rte *e;
      for (e = n->routes; e; e = e->next)
	if (e->sender == ah)
	  e->flags |= REF_STALE;
@@ -1340,12 +1337,10 @@ void
rt_refresh_end(rtable *t, struct announce_hook *ah)
{
  int prune = 0;
  net *n;
  rte *e;

  FIB_WALK(&t->fib, fn)
  FIB_WALK(&t->fib, net, n)
    {
      n = (net *) fn;
      rte *e;
      for (e = n->routes; e; e = e->next)
	if ((e->sender == ah) && (e->flags & REF_STALE))
	  {
@@ -1387,21 +1382,19 @@ rte_dump(rte *e)
void
rt_dump(rtable *t)
{
  rte *e;
  net *n;
  struct announce_hook *a;

  debug("Dump of routing table <%s>\n", t->name);
#ifdef DEBUGGING
  fib_check(&t->fib);
#endif
  FIB_WALK(&t->fib, fn)
  FIB_WALK(&t->fib, net, n)
    {
      n = (net *) fn;
      rte *e;
      for(e=n->routes; e; e=e->next)
	rte_dump(e);
    }
  FIB_WALK_END;

  struct announce_hook *a;
  WALK_LIST(a, t->hooks)
    debug("\tAnnounces routes to protocol %s\n", a->proto->name);
  debug("\n");
@@ -1471,19 +1464,18 @@ rt_prune_nets(rtable *tab)

  FIB_ITERATE_INIT(&fit, &tab->fib);
again:
  FIB_ITERATE_START(&tab->fib, &fit, f)
  FIB_ITERATE_START(&tab->fib, &fit, net, n)
    {
      net *n = (net *) f;
      ncnt++;
      if (!n->routes)		/* Orphaned FIB entry */
	{
	  FIB_ITERATE_PUT(&fit, f);
	  fib_delete(&tab->fib, f);
	  FIB_ITERATE_PUT(&fit);
	  fib_delete(&tab->fib, n);
	  ndel++;
	  goto again;
	}
    }
  FIB_ITERATE_END(f);
  FIB_ITERATE_END;
  DBG("Pruned %d of %d networks\n", ndel, ncnt);

  tab->gc_counter = 0;
@@ -1572,9 +1564,8 @@ rt_prune_step(rtable *tab, int *limit)
    }

again:
  FIB_ITERATE_START(&tab->fib, fit, fn)
  FIB_ITERATE_START(&tab->fib, fit, net, n)
    {
      net *n = (net *) fn;
      rte *e;

    rescan:
@@ -1583,7 +1574,7 @@ again:
	  {
	    if (*limit <= 0)
	      {
		FIB_ITERATE_PUT(fit, fn);
		FIB_ITERATE_PUT(fit);
		return 0;
	      }

@@ -1594,12 +1585,12 @@ again:
	  }
      if (!n->routes)		/* Orphaned FIB entry */
	{
	  FIB_ITERATE_PUT(fit, fn);
	  fib_delete(&tab->fib, fn);
	  FIB_ITERATE_PUT(fit);
	  fib_delete(&tab->fib, n);
	  goto again;
	}
    }
  FIB_ITERATE_END(fn);
  FIB_ITERATE_END;

#ifdef DEBUGGING
  fib_check(&tab->fib);
@@ -1791,17 +1782,17 @@ rt_next_hop_update(rtable *tab)
      tab->nhu_state = 2;
    }

  FIB_ITERATE_START(&tab->fib, fit, fn)
  FIB_ITERATE_START(&tab->fib, fit, net, n)
    {
      if (max_feed <= 0)
	{
	  FIB_ITERATE_PUT(fit, fn);
	  FIB_ITERATE_PUT(fit);
	  ev_schedule(tab->rt_event);
	  return;
	}
      max_feed -= rt_next_hop_update_net(tab, (net *) fn);
      max_feed -= rt_next_hop_update_net(tab, n);
    }
  FIB_ITERATE_END(fn);
  FIB_ITERATE_END;

  /* state change 2->0, 3->1 */
  tab->nhu_state &= 1;
@@ -1971,13 +1962,12 @@ rt_feed_baby(struct proto *p)

again:
  h = p->feed_ahook;
  FIB_ITERATE_START(&h->table->fib, fit, fn)
  FIB_ITERATE_START(&h->table->fib, fit, net, n)
    {
      net *n = (net *) fn;
      rte *e = n->routes;
      if (max_feed <= 0)
	{
	  FIB_ITERATE_PUT(fit, fn);
	  FIB_ITERATE_PUT(fit);
	  return 0;
	}

@@ -2008,7 +1998,7 @@ again:
	    max_feed--;
	  }
    }
  FIB_ITERATE_END(fn);
  FIB_ITERATE_END;
  p->feed_ahook = h->next;
  if (!p->feed_ahook)
    {
@@ -2534,9 +2524,8 @@ rt_show_cont(struct cli *c)
  struct fib *fib = &d->table->fib;
  struct fib_iterator *it = &d->fit;

  FIB_ITERATE_START(fib, it, f)
  FIB_ITERATE_START(fib, it, net, n)
    {
      net *n = (net *) f;
      if (d->running_on_config && d->running_on_config != config)
	{
	  cli_printf(c, 8004, "Stopped due to reconfiguration");
@@ -2549,12 +2538,12 @@ rt_show_cont(struct cli *c)
	}
      if (!max--)
	{
	  FIB_ITERATE_PUT(it, f);
	  FIB_ITERATE_PUT(it);
	  return;
	}
      rt_show_net(c, n, d);
    }
  FIB_ITERATE_END(f);
  FIB_ITERATE_END;
  if (d->stats)
    cli_printf(c, 14, "%d of %d routes for %d networks", d->show_counter, d->rt_counter, d->net_counter);
  else
+4 −7
Original line number Diff line number Diff line
@@ -502,9 +502,9 @@ ospf_shutdown(struct proto *P)
    ospf_iface_shutdown(ifa);

  /* Cleanup locked rta entries */
  FIB_WALK(&p->rtf, nftmp)
  FIB_WALK(&p->rtf, ort, nf)
  {
    rta_free(((ort *) nftmp)->old_rta);
    rta_free(nf->old_rta);
  }
  FIB_WALK_END;

@@ -745,7 +745,6 @@ ospf_sh(struct proto *P)
  struct ospf_iface *ifa;
  struct ospf_neighbor *n;
  int ifano, nno, adjno, firstfib;
  struct area_net *anet;

  if (p->p.proto_state != PS_UP)
  {
@@ -794,9 +793,8 @@ ospf_sh(struct proto *P)
    cli_msg(-1014, "\t\tNumber of adjacent neighbors:\t%u", adjno);

    firstfib = 1;
    FIB_WALK(&oa->net_fib, nftmp)
    FIB_WALK(&oa->net_fib, struct area_net, anet)
    {
      anet = (struct area_net *) nftmp;
      if(firstfib)
      {
	cli_msg(-1014, "\t\tArea networks:");
@@ -808,9 +806,8 @@ ospf_sh(struct proto *P)
    FIB_WALK_END;

    firstfib = 1;
    FIB_WALK(&oa->enet_fib, nftmp)
    FIB_WALK(&oa->enet_fib, struct area_net, anet)
    {
      anet = (struct area_net *) nftmp;
      if(firstfib)
      {
	cli_msg(-1014, "\t\tArea external networks:");
+24 −48
Original line number Diff line number Diff line
@@ -1158,25 +1158,20 @@ static void
ospf_rt_abr1(struct ospf_proto *p)
{
  struct area_net *anet;
  ort *nf, *default_nf;
  ort *default_nf;
  net_addr default_net;

  /* RFC 2328 G.3 - incomplete resolution of virtual next hops - routers */
  FIB_WALK(&p->backbone->rtr, nftmp)
  FIB_WALK(&p->backbone->rtr, ort, nf)
  {
    nf = (ort *) nftmp;

    if (nf->n.type && unresolved_vlink(nf))
      reset_ri(nf);
  }
  FIB_WALK_END;


  FIB_WALK(&p->rtf, nftmp)
  FIB_WALK(&p->rtf, ort, nf)
  {
    nf = (ort *) nftmp;


    /* RFC 2328 G.3 - incomplete resolution of virtual next hops - networks */
    if (nf->n.type && unresolved_vlink(nf))
      reset_ri(nf);
@@ -1241,9 +1236,8 @@ ospf_rt_abr1(struct ospf_proto *p)
    /* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
    if (oa_is_ext(oa))
    {
      FIB_WALK(&oa->rtr, nftmp)
      FIB_WALK(&oa->rtr, ort, nf)
      {
	nf = (ort *) nftmp;
	if (nf->n.options & ORTA_ASBR)
	  ri_install_asbr(p, rid_from_net(nf->fn.addr), &nf->n);
      }
@@ -1253,9 +1247,9 @@ ospf_rt_abr1(struct ospf_proto *p)


  /* Originate or flush ASBR summary LSAs */
  FIB_WALK(&p->backbone->rtr, nftmp)
  FIB_WALK(&p->backbone->rtr, ort, nf)
  {
    check_sum_rt_lsa(p, (ort *) nftmp);
    check_sum_rt_lsa(p, nf);
  }
  FIB_WALK_END;

@@ -1282,8 +1276,6 @@ ospf_rt_abr2(struct ospf_proto *p)
{
  struct ospf_area *oa;
  struct top_hash_entry *en;
  ort *nf, *nf2;


  /* RFC 3103 3.1 - type-7 translator election */
  struct ospf_area *bb = p->backbone;
@@ -1295,13 +1287,12 @@ ospf_rt_abr2(struct ospf_proto *p)
      if (oa->ac->translator)
	goto decided;

      FIB_WALK(&oa->rtr, nftmp)
      FIB_WALK(&oa->rtr, ort, nf)
      {
	nf = (ort *) nftmp;
	if (!nf->n.type || !(nf->n.options & ORTA_ABR))
	  continue;

	nf2 = fib_find(&bb->rtr, nf->fn.addr);
	ort *nf2 = fib_find(&bb->rtr, nf->fn.addr);
	if (!nf2 || !nf2->n.type || !(nf2->n.options & ORTA_ABR))
	  continue;

@@ -1341,13 +1332,11 @@ ospf_rt_abr2(struct ospf_proto *p)


  /* Compute condensed external networks */
  FIB_WALK(&p->rtf, nftmp)
  FIB_WALK(&p->rtf, ort, nf)
  {
    nf = (ort *) nftmp;
    if (rt_is_nssa(nf) && (nf->n.options & ORTA_PROP))
    {
      struct area_net *anet = (struct area_net *)
	fib_route(&nf->n.oa->enet_fib, nf->fn.addr);
      struct area_net *anet = fib_route(&nf->n.oa->enet_fib, nf->fn.addr);

      if (anet)
      {
@@ -1356,7 +1345,7 @@ ospf_rt_abr2(struct ospf_proto *p)
	  anet->active = 1;

	  /* Get a RT entry and mark it to know that it is an area network */
	  nf2 = fib_get(&p->rtf, anet->fn.addr);
	  ort *nf2 = fib_get(&p->rtf, anet->fn.addr);
	  nf2->area_net = 1;
	}

@@ -1371,10 +1360,8 @@ ospf_rt_abr2(struct ospf_proto *p)
  FIB_WALK_END;


  FIB_WALK(&p->rtf, nftmp)
  FIB_WALK(&p->rtf, ort, nf)
  {
    nf = (ort *) nftmp;

    check_sum_net_lsa(p, nf);
    check_nssa_lsa(p, nf);
  }
@@ -1586,13 +1573,10 @@ ospf_rt_reset(struct ospf_proto *p)
{
  struct ospf_area *oa;
  struct top_hash_entry *en;
  struct area_net *anet;
  ort *ri;

  /* Reset old routing table */
  FIB_WALK(&p->rtf, nftmp)
  FIB_WALK(&p->rtf, ort, ri)
  {
    ri = (ort *) nftmp;
    ri->area_net = 0;
    reset_ri(ri);
  }
@@ -1613,9 +1597,8 @@ ospf_rt_reset(struct ospf_proto *p)
  WALK_LIST(oa, p->area_list)
  {
    /* Reset ASBR routing tables */
    FIB_WALK(&oa->rtr, nftmp)
    FIB_WALK(&oa->rtr, ort, ri)
    {
      ri = (ort *) nftmp;
      reset_ri(ri);
    }
    FIB_WALK_END;
@@ -1623,17 +1606,15 @@ ospf_rt_reset(struct ospf_proto *p)
    /* Reset condensed area networks */
    if (p->areano > 1)
    {
      FIB_WALK(&oa->net_fib, nftmp)
      FIB_WALK(&oa->net_fib, struct area_net, anet)
      {
	anet = (struct area_net *) nftmp;
	anet->active = 0;
	anet->metric = 0;
      }
      FIB_WALK_END;

      FIB_WALK(&oa->enet_fib, nftmp)
      FIB_WALK(&oa->enet_fib, struct area_net, anet)
      {
	anet = (struct area_net *) nftmp;
	anet->active = 0;
	anet->metric = 0;
      }
@@ -1935,7 +1916,6 @@ rt_sync(struct ospf_proto *p)
  struct top_hash_entry *en;
  struct fib_iterator fit;
  struct fib *fib = &p->rtf;
  ort *nf;
  struct ospf_area *oa;

  /* This is used for forced reload of routes */
@@ -1946,10 +1926,8 @@ rt_sync(struct ospf_proto *p)
  DBG("Now syncing my rt table with nest's\n");
  FIB_ITERATE_INIT(&fit, fib);
again1:
  FIB_ITERATE_START(fib, &fit, nftmp)
  FIB_ITERATE_START(fib, &fit, ort, nf)
  {
    nf = (ort *) nftmp;

    /* Sanity check of next-hop addresses, failure should not happen */
    if (nf->n.type)
    {
@@ -2027,12 +2005,12 @@ again1:
    /* Remove unused rt entry, some special entries are persistent */
    if (!nf->n.type && !nf->external_rte && !nf->area_net)
    {
      FIB_ITERATE_PUT(&fit, nftmp);
      fib_delete(fib, nftmp);
      FIB_ITERATE_PUT(&fit);
      fib_delete(fib, nf);
      goto again1;
    }
  }
  FIB_ITERATE_END(nftmp);
  FIB_ITERATE_END;


  WALK_LIST(oa, p->area_list)
@@ -2040,18 +2018,16 @@ again1:
    /* Cleanup ASBR hash tables */
    FIB_ITERATE_INIT(&fit, &oa->rtr);
again2:
    FIB_ITERATE_START(&oa->rtr, &fit, nftmp)
    FIB_ITERATE_START(&oa->rtr, &fit, ort, nf)
    {
      nf = (ort *) nftmp;

      if (!nf->n.type)
      {
	FIB_ITERATE_PUT(&fit, nftmp);
	fib_delete(&oa->rtr, nftmp);
	FIB_ITERATE_PUT(&fit);
	fib_delete(&oa->rtr, nf);
	goto again2;
      }
    }
    FIB_ITERATE_END(nftmp);
    FIB_ITERATE_END;
  }

  /* Cleanup stale LSAs */
Loading