Revision d47c3d64

View differences:

nest/route.h
338 338
  struct iface *iface;			/* Outgoing interface */
339 339
  struct nexthop *next;
340 340
  byte weight;
341
  byte labels;				/* Number of labels appended */
341
  byte labels_append;			/* Number of labels before hostentry was applied */
342
  byte labels;				/* Number of labels prepended */
342 343
  u32 label[0];
343 344
};
344 345

  
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
}
proto/static/config.Y
105 105
      this_srt->dest = RTDX_RECURSIVE;
106 106
      this_srt->via = $3;
107 107
   }
108

  
108
 | stat_route0 RECURSIVE ipa MPLS label_stack {
109
      this_srt->dest = RTDX_RECURSIVE;
110
      this_srt->via = $3;
111
      this_srt->label_count = $5[0];
112
      this_srt->label_stack = &($5[1]);
113
   }
109 114
 | stat_route0 DROP		{ this_srt->dest = RTD_BLACKHOLE; }
110 115
 | stat_route0 REJECT		{ this_srt->dest = RTD_UNREACHABLE; }
111 116
 | stat_route0 BLACKHOLE	{ this_srt->dest = RTD_BLACKHOLE; }
proto/static/static.c
128 128
    r->state |= STS_INSTALLED;
129 129
  
130 130
  if (r->dest == RTDX_RECURSIVE)
131
    rta_set_recursive_next_hop(p->main_channel->table, ap, p_igp_table(p), r->via, IPA_NONE);
131
    {
132
      ap->nh.labels_append = ap->nh.labels = r->label_count;
133
      memcpy(ap->nh.label, r->label_stack, r->label_count * sizeof(u32));
134
      rta_set_recursive_next_hop(p->main_channel->table, ap, p_igp_table(p), r->via, IPA_NONE);
135
    }
132 136

  
133 137
  /* We skip rta_lookup() here */
134 138

  

Also available in: Unified diff