Commit c38a645d authored by Pavel Tvrdík's avatar Pavel Tvrdík
Browse files

Merge branch 'master' into birdtest

parents 00572d96 d0e23d42
Loading
Loading
Loading
Loading
+27 −35
Original line number Diff line number Diff line
@@ -347,11 +347,13 @@ do_rt_notify(struct announce_hook *ah, net *net, rte *new, rte *old, ea_list *tm
}

static void
rt_notify_basic(struct announce_hook *ah, net *net, rte *new, rte *old, ea_list *tmpa, int refeed)
rt_notify_basic(struct announce_hook *ah, net *net, rte *new0, rte *old0, ea_list *tmpa, int refeed)
{
  // struct proto *p = ah->proto;
  struct proto *p = ah->proto;
  struct proto_stats *stats = ah->stats;

  rte *new = new0;
  rte *old = old0;
  rte *new_free = NULL;
  rte *old_free = NULL;

@@ -386,9 +388,26 @@ rt_notify_basic(struct announce_hook *ah, net *net, rte *new, rte *old, ea_list
  if (old && !refeed)
    old = export_filter(ah, old, &old_free, NULL, 1);

  /* FIXME - This is broken because of incorrect 'old' value (see above) */
  if (!new && !old)
  {
    /*
     * As mentioned above, 'old' value may be incorrect in some race conditions.
     * We generally ignore it with the exception of withdraw to pipe protocol.
     * In that case we rather propagate unfiltered withdraws regardless of
     * export filters to ensure that when a protocol is flushed, its routes are
     * removed from all tables. Possible spurious unfiltered withdraws are not
     * problem here as they are ignored if there is no corresponding route at
     * the other end of the pipe. We directly call rt_notify() hook instead of
     * do_rt_notify() to avoid logging and stat counters.
     */

#ifdef CONFIG_PIPE
    if ((p->proto == &proto_pipe) && !new0 && (p != old0->sender->proto))
      p->rt_notify(p, ah->table, net, NULL, old0, NULL);
#endif

    return;
  }

  do_rt_notify(ah, net, new, old, tmpa, refeed);

@@ -1365,9 +1384,8 @@ rt_init(void)


static int
rt_prune_step(rtable *tab, int step, int *limit)
rt_prune_step(rtable *tab, int *limit)
{
  static struct tbf rl_flush = TBF_DEFAULT_LOG_LIMITS;
  struct fib_iterator *fit = &tab->prune_fit;

  DBG("Pruning route table %s\n", tab->name);
@@ -1392,9 +1410,7 @@ again:

    rescan:
      for (e=n->routes; e; e=e->next)
	if (e->sender->proto->flushing ||
	    (e->flags & REF_DISCARD) ||
	    (step && e->attrs->src->proto->flushing))
	if (e->sender->proto->flushing || (e->flags & REF_DISCARD))
	  {
	    if (*limit <= 0)
	      {
@@ -1402,10 +1418,6 @@ again:
		return 0;
	      }

	    if (step)
	      log_rl(&rl_flush, L_WARN "Route %I/%d from %s still in %s after flush",
		  n->n.prefix, n->n.pxlen, e->attrs->src->proto->name, tab->name);

	    rte_discard(tab, e);
	    (*limit)--;

@@ -1445,7 +1457,7 @@ static inline int
rt_prune_table(rtable *tab)
{
  int limit = 512;
  return rt_prune_step(tab, 0, &limit);
  return rt_prune_step(tab, &limit);
}

/**
@@ -1454,37 +1466,17 @@ rt_prune_table(rtable *tab)
 * The prune loop scans routing tables and removes routes belonging to flushing
 * protocols, discarded routes and also stale network entries. Returns 1 when
 * all such routes are pruned. It is a part of the protocol flushing loop.
 *
 * The prune loop runs in two steps. In the first step it prunes just the routes
 * with flushing senders (in explicitly marked tables) so the route removal is
 * propagated as usual. In the second step, all remaining relevant routes are
 * removed. Ideally, there shouldn't be any, but it happens when pipe filters
 * are changed.
 */
int
rt_prune_loop(void)
{
  static int step = 0;
  int limit = 512;
  rtable *t;

 again:
  WALK_LIST(t, routing_tables)
    if (! rt_prune_step(t, step, &limit))
    if (! rt_prune_step(t, &limit))
      return 0;

  if (step == 0)
    {
      /* Prepare for the second step */
      WALK_LIST(t, routing_tables)
	t->prune_state = RPS_SCHEDULED;

      step = 1;
      goto again;
    }

  /* Done */
  step = 0;
  return 1;
}

+1 −1
Original line number Diff line number Diff line
@@ -316,7 +316,7 @@ nl_add_multipath(struct nlmsghdr *h, unsigned bufsize, struct mpnh *nh)
    rtnh->rtnh_hops = nh->weight;
    rtnh->rtnh_ifindex = nh->iface->index;

    nl_add_attr_u32(h, bufsize, RTA_GATEWAY, nh->gw);
    nl_add_attr_ipa(h, bufsize, RTA_GATEWAY, nh->gw);

    nl_close_nexthop(h, rtnh);
  }