summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-05-05 19:28:56 +0200
committerMaria Matejka <mq@ucw.cz>2022-05-05 19:28:56 +0200
commitf2e725a76882ba6b75c3ce4fb3c760bd83462410 (patch)
tree48883d91d8cdfaba9420efe33e1b81778e70b0a8 /nest
parent1c30b689ddd032ef8000fb7836348a48ba3184ff (diff)
All outstanding MPLS label stacks are stored as adata
Diffstat (limited to 'nest')
-rw-r--r--nest/rt-attr.c11
-rw-r--r--nest/rt-table.c27
-rw-r--r--nest/rt.h6
3 files changed, 23 insertions, 21 deletions
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 39fd7db4..dc4fe785 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -108,6 +108,12 @@ struct ea_class ea_gen_source = {
.format = ea_gen_source_format,
};
+struct ea_class ea_mpls_labels = {
+ .name = "mpls_labels",
+ .type = T_CLIST,
+ .readonly = 1,
+};
+
const char * rta_dest_names[RTD_MAX] = {
[RTD_NONE] = "",
[RTD_UNICAST] = "unicast",
@@ -220,7 +226,7 @@ nexthop__same(struct nexthop *x, struct nexthop *y)
{
if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) ||
(x->flags != y->flags) || (x->weight != y->weight) ||
- (x->labels_orig != y->labels_orig) || (x->labels != y->labels))
+ (x->labels != y->labels))
return 0;
for (int i = 0; i < x->labels; i++)
@@ -402,7 +408,6 @@ nexthop_copy(struct nexthop *o)
n->next = NULL;
n->flags = o->flags;
n->weight = o->weight;
- n->labels_orig = o->labels_orig;
n->labels = o->labels;
for (int i=0; i<o->labels; i++)
n->label[i] = o->label[i];
@@ -1484,6 +1489,8 @@ rta_init(void)
ea_register_init(&ea_gen_igp_metric);
ea_register_init(&ea_gen_from);
ea_register_init(&ea_gen_source);
+
+ ea_register_init(&ea_mpls_labels);
}
/*
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 4f119ac0..37f17bbc 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -2385,7 +2385,7 @@ rt_preconfig(struct config *c)
*/
void
-rta_apply_hostentry(rta *a, struct hostentry *he, mpls_label_stack *mls)
+rta_apply_hostentry(rta *a, struct hostentry *he)
{
a->hostentry = he;
a->dest = he->dest;
@@ -2397,15 +2397,12 @@ rta_apply_hostentry(rta *a, struct hostentry *he, mpls_label_stack *mls)
/* No nexthop */
no_nexthop:
a->nh = (struct nexthop) {};
- if (mls)
- { /* Store the label stack for later changes */
- a->nh.labels_orig = a->nh.labels = mls->len;
- memcpy(a->nh.label, mls->stack, mls->len * sizeof(u32));
- }
return;
}
- if (((!mls) || (!mls->len)) && he->nexthop_linkable)
+ eattr *mls_ea = ea_find(a->eattrs, &ea_mpls_labels);
+
+ if (!mls_ea && he->nexthop_linkable)
{ /* Just link the nexthop chain, no label append happens. */
memcpy(&(a->nh), &(he->src->nh), nexthop_size(&(he->src->nh)));
return;
@@ -2414,6 +2411,9 @@ no_nexthop:
struct nexthop *nhp = NULL, *nhr = NULL;
int skip_nexthop = 0;
+ const struct adata *mls = mls_ea ? mls_ea->u.ptr : NULL;
+ uint mls_cnt = mls ? mls->length / sizeof(u32) : 0;
+
for (struct nexthop *nh = &(he->src->nh); nh; nh = nh->next)
{
if (skip_nexthop)
@@ -2430,17 +2430,16 @@ no_nexthop:
if (mls)
{
- nhp->labels = nh->labels + mls->len;
- nhp->labels_orig = mls->len;
+ nhp->labels = nh->labels + mls_cnt;
if (nhp->labels <= MPLS_MAX_LABEL_STACK)
{
memcpy(nhp->label, nh->label, nh->labels * sizeof(u32)); /* First the hostentry labels */
- memcpy(&(nhp->label[nh->labels]), mls->stack, mls->len * sizeof(u32)); /* Then the bottom labels */
+ memcpy(&(nhp->label[nh->labels]), mls->data, mls->length); /* Then the bottom labels */
}
else
{
log(L_WARN "Sum of label stack sizes %d + %d = %d exceedes allowed maximum (%d)",
- nh->labels, mls->len, nhp->labels, MPLS_MAX_LABEL_STACK);
+ nh->labels, mls_cnt, nhp->labels, MPLS_MAX_LABEL_STACK);
skip_nexthop++;
continue;
}
@@ -2448,7 +2447,6 @@ no_nexthop:
else if (nh->labels)
{
nhp->labels = nh->labels;
- nhp->labels_orig = 0;
memcpy(nhp->label, nh->label, nh->labels * sizeof(u32));
}
@@ -2501,10 +2499,7 @@ rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
rta *a = alloca(RTA_MAX_SIZE);
memcpy(a, old->attrs, rta_size(old->attrs));
- mpls_label_stack mls = { .len = a->nh.labels_orig };
- memcpy(mls.stack, &a->nh.label[a->nh.labels - mls.len], mls.len * sizeof(u32));
-
- rta_apply_hostentry(a, old->attrs->hostentry, &mls);
+ rta_apply_hostentry(a, old->attrs->hostentry);
a->cached = 0;
rte *e = sl_alloc(rte_slab);
diff --git a/nest/rt.h b/nest/rt.h
index 6bd9cd38..50be7e0b 100644
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -281,12 +281,12 @@ struct rt_show_data_rtable * rt_show_add_table(struct rt_show_data *d, rtable *t
#define RSEM_EXPORTED 4 /* Routes marked in export map */
struct hostentry * rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep);
-void rta_apply_hostentry(rta *a, struct hostentry *he, mpls_label_stack *mls);
+void rta_apply_hostentry(rta *a, struct hostentry *he);
static inline void
-rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr gw, ip_addr ll, mpls_label_stack *mls)
+rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr gw, ip_addr ll)
{
- rta_apply_hostentry(a, rt_get_hostentry(tab, gw, ll, dep), mls);
+ rta_apply_hostentry(a, rt_get_hostentry(tab, gw, ll, dep));
}
/*