Revision d47c3d64 nest/rt-table.c

View differences:

nest/rt-table.c
1768 1768
rta_apply_hostentry(rta *a, struct hostentry *he)
1769 1769
{
1770 1770
  a->hostentry = he;
1771

  
1772
  a->nh.gw = ipa_nonzero(he->nh->gw) ? he->nh->gw : he->link;
1773
  a->nh.iface = he->nh->iface;
1774
  a->nh.weight = he->nh->weight;
1775
  a->nh.next = he->nh->next;
1776 1771
  
1777 1772
  a->dest = he->dest;
1778 1773
  a->igp_metric = he->igp_metric;
1774

  
1775
  if (a->nh.labels_append == 0)
1776
  {
1777
    a->nh = *(he->nh);
1778
    a->nh.labels_append = 0;
1779
    return;
1780
  }
1781

  
1782
  int labels_append = a->nh.labels_append;
1783
  u32 label_stack[MPLS_MAX_LABEL_STACK];
1784
  memcpy(label_stack, a->nh.label, labels_append * sizeof(u32));
1785

  
1786
  struct nexthop *nhp = NULL;
1787
  for (struct nexthop *nh = he->nh; nh; nh = nh->next)
1788
  {
1789
    nhp = nhp ? (nhp->next = lp_alloc(rte_update_pool, NEXTHOP_MAX_SIZE)) : &(a->nh);
1790
    nhp->gw = ipa_nonzero(nh->gw) ? nh->gw : he->link;
1791
    nhp->iface = nh->iface; /* FIXME: This is at least strange, if not utter nonsense. */
1792
    nhp->weight = nh->weight;
1793
    nhp->labels = nh->labels + labels_append;
1794
    nhp->labels_append = labels_append;
1795
    if (nhp->labels <= MPLS_MAX_LABEL_STACK)
1796
    {
1797
      memcpy(nhp->label, nh->label, nh->labels * sizeof(u32));
1798
      memcpy(&(nhp->label[nh->labels]), label_stack, labels_append * sizeof(u32));
1799
    }
1800
    else
1801
    {
1802
      log(L_WARN "Sum of label stack sizes %d + %d = %d exceedes allowed maximum (%d)",
1803
	  nh->labels, labels_append, nhp->labels, MPLS_MAX_LABEL_STACK);
1804
      a->dest = RTD_UNREACHABLE;
1805
      break;
1806
    }
1807
  }
1779 1808
}
1780 1809

  
1781 1810
static inline rte *
1782 1811
rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
1783 1812
{
1784
  rta a;
1785
  memcpy(&a, old->attrs, rta_size(old->attrs));
1786
  rta_apply_hostentry(&a, old->attrs->hostentry);
1787
  a.aflags = 0;
1813
  rta *ap = alloca(RTA_MAX_SIZE);
1814
  memcpy(ap, old->attrs, rta_size(old->attrs));
1815
  rta_apply_hostentry(ap, old->attrs->hostentry);
1816
  ap->aflags = 0;
1788 1817

  
1789 1818
  rte *e = sl_alloc(rte_slab);
1790 1819
  memcpy(e, old, sizeof(rte));
1791
  e->attrs = rta_lookup(&a);
1820
  e->attrs = rta_lookup(ap);
1792 1821

  
1793 1822
  return e;
1794 1823
}

Also available in: Unified diff