MPLS: Label stack concatenation for recursive routes
This commit is contained in:
parent
d14f8c3c45
commit
d47c3d64b2
4 changed files with 52 additions and 13 deletions
|
@ -338,7 +338,8 @@ struct nexthop {
|
||||||
struct iface *iface; /* Outgoing interface */
|
struct iface *iface; /* Outgoing interface */
|
||||||
struct nexthop *next;
|
struct nexthop *next;
|
||||||
byte weight;
|
byte weight;
|
||||||
byte labels; /* Number of labels appended */
|
byte labels_append; /* Number of labels before hostentry was applied */
|
||||||
|
byte labels; /* Number of labels prepended */
|
||||||
u32 label[0];
|
u32 label[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1768,27 +1768,56 @@ static inline void
|
||||||
rta_apply_hostentry(rta *a, struct hostentry *he)
|
rta_apply_hostentry(rta *a, struct hostentry *he)
|
||||||
{
|
{
|
||||||
a->hostentry = he;
|
a->hostentry = he;
|
||||||
|
|
||||||
a->nh.gw = ipa_nonzero(he->nh->gw) ? he->nh->gw : he->link;
|
|
||||||
a->nh.iface = he->nh->iface;
|
|
||||||
a->nh.weight = he->nh->weight;
|
|
||||||
a->nh.next = he->nh->next;
|
|
||||||
|
|
||||||
a->dest = he->dest;
|
a->dest = he->dest;
|
||||||
a->igp_metric = he->igp_metric;
|
a->igp_metric = he->igp_metric;
|
||||||
|
|
||||||
|
if (a->nh.labels_append == 0)
|
||||||
|
{
|
||||||
|
a->nh = *(he->nh);
|
||||||
|
a->nh.labels_append = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int labels_append = a->nh.labels_append;
|
||||||
|
u32 label_stack[MPLS_MAX_LABEL_STACK];
|
||||||
|
memcpy(label_stack, a->nh.label, labels_append * sizeof(u32));
|
||||||
|
|
||||||
|
struct nexthop *nhp = NULL;
|
||||||
|
for (struct nexthop *nh = he->nh; nh; nh = nh->next)
|
||||||
|
{
|
||||||
|
nhp = nhp ? (nhp->next = lp_alloc(rte_update_pool, NEXTHOP_MAX_SIZE)) : &(a->nh);
|
||||||
|
nhp->gw = ipa_nonzero(nh->gw) ? nh->gw : he->link;
|
||||||
|
nhp->iface = nh->iface; /* FIXME: This is at least strange, if not utter nonsense. */
|
||||||
|
nhp->weight = nh->weight;
|
||||||
|
nhp->labels = nh->labels + labels_append;
|
||||||
|
nhp->labels_append = labels_append;
|
||||||
|
if (nhp->labels <= MPLS_MAX_LABEL_STACK)
|
||||||
|
{
|
||||||
|
memcpy(nhp->label, nh->label, nh->labels * sizeof(u32));
|
||||||
|
memcpy(&(nhp->label[nh->labels]), label_stack, labels_append * sizeof(u32));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log(L_WARN "Sum of label stack sizes %d + %d = %d exceedes allowed maximum (%d)",
|
||||||
|
nh->labels, labels_append, nhp->labels, MPLS_MAX_LABEL_STACK);
|
||||||
|
a->dest = RTD_UNREACHABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline rte *
|
static inline rte *
|
||||||
rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
|
rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
|
||||||
{
|
{
|
||||||
rta a;
|
rta *ap = alloca(RTA_MAX_SIZE);
|
||||||
memcpy(&a, old->attrs, rta_size(old->attrs));
|
memcpy(ap, old->attrs, rta_size(old->attrs));
|
||||||
rta_apply_hostentry(&a, old->attrs->hostentry);
|
rta_apply_hostentry(ap, old->attrs->hostentry);
|
||||||
a.aflags = 0;
|
ap->aflags = 0;
|
||||||
|
|
||||||
rte *e = sl_alloc(rte_slab);
|
rte *e = sl_alloc(rte_slab);
|
||||||
memcpy(e, old, sizeof(rte));
|
memcpy(e, old, sizeof(rte));
|
||||||
e->attrs = rta_lookup(&a);
|
e->attrs = rta_lookup(ap);
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,12 @@ stat_route:
|
||||||
this_srt->dest = RTDX_RECURSIVE;
|
this_srt->dest = RTDX_RECURSIVE;
|
||||||
this_srt->via = $3;
|
this_srt->via = $3;
|
||||||
}
|
}
|
||||||
|
| stat_route0 RECURSIVE ipa MPLS label_stack {
|
||||||
|
this_srt->dest = RTDX_RECURSIVE;
|
||||||
|
this_srt->via = $3;
|
||||||
|
this_srt->label_count = $5[0];
|
||||||
|
this_srt->label_stack = &($5[1]);
|
||||||
|
}
|
||||||
| stat_route0 DROP { this_srt->dest = RTD_BLACKHOLE; }
|
| stat_route0 DROP { this_srt->dest = RTD_BLACKHOLE; }
|
||||||
| stat_route0 REJECT { this_srt->dest = RTD_UNREACHABLE; }
|
| stat_route0 REJECT { this_srt->dest = RTD_UNREACHABLE; }
|
||||||
| stat_route0 BLACKHOLE { this_srt->dest = RTD_BLACKHOLE; }
|
| stat_route0 BLACKHOLE { this_srt->dest = RTD_BLACKHOLE; }
|
||||||
|
|
|
@ -128,7 +128,11 @@ drop:
|
||||||
r->state |= STS_INSTALLED;
|
r->state |= STS_INSTALLED;
|
||||||
|
|
||||||
if (r->dest == RTDX_RECURSIVE)
|
if (r->dest == RTDX_RECURSIVE)
|
||||||
rta_set_recursive_next_hop(p->main_channel->table, ap, p_igp_table(p), r->via, IPA_NONE);
|
{
|
||||||
|
ap->nh.labels_append = ap->nh.labels = r->label_count;
|
||||||
|
memcpy(ap->nh.label, r->label_stack, r->label_count * sizeof(u32));
|
||||||
|
rta_set_recursive_next_hop(p->main_channel->table, ap, p_igp_table(p), r->via, IPA_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
/* We skip rta_lookup() here */
|
/* We skip rta_lookup() here */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue