Commit 01c9f3d7 authored by Maria Matejka's avatar Maria Matejka
Browse files

Merge commit '575da88f' into haugesund

Conflicts:
	nest/rt-table.c
parents 36f5fea3 575da88f
Loading
Loading
Loading
Loading
+43 −38
Original line number Diff line number Diff line
@@ -637,7 +637,7 @@ rte_mergable(rte *pri, rte *sec)
}

static void
rte_trace(struct channel *c, rte *e, int dir, char *msg)
rte_trace(struct channel *c, rte *e, int dir, const char *msg)
{
  log(L_TRACE "%s.%s %c %s %N %uL %uG %s",
      c->proto->name, c->name ?: "?", dir, msg, e->net, e->src->private_id, e->src->global_id,
@@ -645,14 +645,14 @@ rte_trace(struct channel *c, rte *e, int dir, char *msg)
}

static inline void
rte_trace_in(uint flag, struct channel *c, rte *e, char *msg)
rte_trace_in(uint flag, struct channel *c, rte *e, const char *msg)
{
  if ((c->debug & flag) || (c->proto->debug & flag))
    rte_trace(c, e, '>', msg);
}

static inline void
rte_trace_out(uint flag, struct channel *c, rte *e, char *msg)
rte_trace_out(uint flag, struct channel *c, rte *e, const char *msg)
{
  if ((c->debug & flag) || (c->proto->debug & flag))
    rte_trace(c, e, '<', msg);
@@ -2516,50 +2516,53 @@ rt_flowspec_update_rte(rtable *tab, net *n, rte *r)
static inline int
rt_next_hop_update_net(rtable *tab, net *n)
{
  struct rte_storage **k, *e, *new, *old_best, **new_best;
  struct rte_storage *new;
  int count = 0;
  int free_old_best = 0;
  int is_flow = net_is_flow(n->n.addr);

  old_best = n->routes;
  struct rte_storage *old_best = n->routes;
  if (!old_best)
    return 0;

  for (k = &n->routes; e = *k; k = &e->next)
  {
    if (!net_is_flow(n->n.addr))
      new = rt_next_hop_update_rte(tab, n, &e->rte);
    else
      new = rt_flowspec_update_rte(tab, n, &e->rte);
  for (struct rte_storage *e, **k = &n->routes; e = *k; k = &e->next)
    if (is_flow || rta_next_hop_outdated(e->rte.attrs))
      count++;

    if (new)
      {
	new->next = e->next;
	*k = new;
  if (!count)
    return 0;

	rte_trace_in(D_ROUTES, new->rte.sender, &new->rte, "updated");
	rte_announce_i(tab, RA_ANY, n, new, e, NULL, NULL);
  struct rte_multiupdate {
    struct rte_storage *old, *new;
  } *updates = alloca(sizeof(struct rte_multiupdate) * count);

  int pos = 0;
  for (struct rte_storage *e, **k = &n->routes; e = *k; k = &e->next)
    if (is_flow || rta_next_hop_outdated(e->rte.attrs))
      {
	struct rte_storage *new = is_flow
	  ? rt_flowspec_update_rte(tab, n, &e->rte)
	  : rt_next_hop_update_rte(tab, n, &e->rte);

	/* Call a pre-comparison hook */
	/* Not really an efficient way to compute this */
	if (e->rte.src->proto->rte_recalculate)
	  e->rte.src->proto->rte_recalculate(tab, n, &new->rte, &e->rte, NULL);
	  e->rte.src->proto->rte_recalculate(tab, n, &new->rte, &e->rte, &old_best->rte);

	if (e != old_best)
	  rte_free(e, tab);
	else /* Freeing of the old best rte is postponed */
	  free_old_best = 1;
	updates[pos++] = (struct rte_multiupdate) {
	  .old = e,
	  .new = new,
	};

	e = new;
	count++;
      }
	/* Replace the route in the list */
	new->next = e->next;
	*k = e = new;
      }

  if (!count)
    return 0;
  ASSERT_DIE(pos == count);

  /* Find the new best route */
  new_best = NULL;
  for (k = &n->routes; e = *k; k = &e->next)
  struct rte_storage **new_best = NULL;
  for (struct rte_storage *e, **k = &n->routes; e = *k; k = &e->next)
    {
      if (!new_best || rte_better(&e->rte, &(*new_best)->rte))
	new_best = k;
@@ -2574,15 +2577,17 @@ rt_next_hop_update_net(rtable *tab, net *n)
      n->routes = new;
    }

  /* Announce the new best route */
  if (new != old_best)
    rte_trace_in(D_ROUTES, new->rte.sender, &new->rte, "updated [best]");

  /* Propagate changes */
  rte_announce_i(tab, RA_UNDEF, n, NULL, NULL, n->routes, old_best);
  /* Announce the changes */
  for (int i=0; i<count; i++)
  {
    _Bool nb = (new == updates[i].new), ob = (old_best == updates[i].old);
    const char *best_indicator[2][2] = { { "updated", "updated [-best]" }, { "updated [+best]", "updated [best]" } };
    rte_trace_in(D_ROUTES, new->rte.sender, &updates[i].new->rte, best_indicator[nb][ob]);
    rte_announce_i(tab, RA_UNDEF, n, updates[i].new, updates[i].old, new, old_best);
  }

  if (free_old_best)
    rte_free(old_best, tab);
  for (int i=0; i<count; i++)
    rte_free(updates[i].old, tab);

  return count;
}
+2 −2
Original line number Diff line number Diff line
@@ -113,13 +113,13 @@ mrt_buffer_flush(buffer *b)
}

#define MRT_DEFINE_TYPE(S, T)						\
  static inline void mrt_put_##S##_(buffer *b, T x)			\
  UNUSED static inline void mrt_put_##S##_(buffer *b, T x)		\
  {									\
    put_##S(b->pos, x);							\
    b->pos += sizeof(T);						\
  }									\
									\
  static inline void mrt_put_##S(buffer *b, T x)			\
  UNUSED static inline void mrt_put_##S(buffer *b, T x)			\
  {									\
    mrt_buffer_need(b, sizeof(T));					\
    put_##S(b->pos, x);							\