Commit 84cac51a authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Nest: Keep multipath next hops sorted

parent a1839f3c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -506,6 +506,8 @@ int mpnh__same(struct mpnh *x, struct mpnh *y); /* Compare multipath nexthops */
static inline int mpnh_same(struct mpnh *x, struct mpnh *y)
{ return (x == y) || mpnh__same(x, y); }
struct mpnh *mpnh_merge(struct mpnh *x, struct mpnh *y, int rx, int ry, int max, linpool *lp);
void mpnh_insert(struct mpnh **n, struct mpnh *y);
int mpnh_is_sorted(struct mpnh *x);

void rta_init(void);
rta *rta_lookup(rta *);			/* Get rta equivalent to this one, uc++ */
+28 −0
Original line number Diff line number Diff line
@@ -302,6 +302,34 @@ mpnh_merge(struct mpnh *x, struct mpnh *y, int rx, int ry, int max, linpool *lp)
  return root;
}

void
mpnh_insert(struct mpnh **n, struct mpnh *x)
{
  for (; *n; n = &((*n)->next))
  {
    int cmp = mpnh_compare_node(*n, x);

    if (cmp < 0)
      continue;
    else if (cmp > 0)
      break;
    else
      return;
  }

  x->next = *n;
  *n = x;
}

int
mpnh_is_sorted(struct mpnh *x)
{
  for (; x && x->next; x = x->next)
    if (mpnh_compare_node(x, x->next) >= 0)
      return 0;

  return 1;
}

static struct mpnh *
mpnh_copy(struct mpnh *o)
+7 −0
Original line number Diff line number Diff line
@@ -804,6 +804,13 @@ rte_validate(rte *e)
      return 0;
    }

  if ((e->attrs->dest == RTD_MULTIPATH) && !mpnh_is_sorted(e->attrs->nexthops))
    {
      log(L_WARN "Ignoring unsorted multipath route %I/%d received via %s",
	  n->n.prefix, n->n.pxlen, e->sender->proto->name);
      return 0;
    }

  return 1;
}

+1 −4
Original line number Diff line number Diff line
@@ -173,7 +173,6 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
    {
      /* ECMP route */
      struct mpnh *nhs = NULL;
      struct mpnh **nhp = &nhs;
      int num = 0;

      for (rt = en->routes; rt && (num < p->ecmp); rt = rt->next)
@@ -185,9 +184,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
	nh->gw = rt->next_hop;
	nh->iface = rt->from->nbr->iface;
	nh->weight = rt->from->ifa->cf->ecmp_weight;
	nh->next = NULL;
	*nhp = nh;
	nhp = &(nh->next);
	mpnh_insert(&nhs, nh);
	num++;

	if (rt->tag != rt_tag)
+1 −4
Original line number Diff line number Diff line
@@ -81,7 +81,6 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
    {
      struct static_route *r2;
      struct mpnh *nhs = NULL;
      struct mpnh **nhp = &nhs;

      for (r2 = r->mp_next; r2; r2 = r2->mp_next)
	if (r2->installed)
@@ -90,9 +89,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
	    nh->gw = r2->via;
	    nh->iface = r2->neigh->iface;
	    nh->weight = r2->masklen; /* really */
	    nh->next = NULL;
	    *nhp = nh;
	    nhp = &(nh->next);
	    mpnh_insert(&nhs, nh);
	  }

      /* There is at least one nexthop */