summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorJan Moskyto Matejka <mq@ucw.cz>2016-06-13 15:49:53 +0200
committerJan Moskyto Matejka <mq@ucw.cz>2016-12-22 21:38:33 +0100
commitf2010f9c65ca69584c34c762fb3e5e957958478e (patch)
tree821f3c498cef0e17feb50e5074ac29854f991175 /nest
parent33ad6e0188b56f682a012ca1b782812c96285d51 (diff)
Static: Protocol rework wrt. struct nexthop changes; MPLS label support
Diffstat (limited to 'nest')
-rw-r--r--nest/route.h2
-rw-r--r--nest/rt-attr.c9
-rw-r--r--nest/rt-table.c28
3 files changed, 28 insertions, 11 deletions
diff --git a/nest/route.h b/nest/route.h
index d9a1737b..c293fbb1 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -513,6 +513,7 @@ ea_list *ea_append(ea_list *to, ea_list *what);
void ea_format_bitfield(struct eattr *a, byte *buf, int bufsize, const char **names, int min, int max);
#define NEXTHOP_MAX_LABEL_STACK 8
+#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*NEXTHOP_MAX_LABEL_STACK)
static inline size_t nexthop_size(const struct nexthop *nh)
{ return sizeof(struct nexthop) + sizeof(u32)*nh->labels; }
@@ -527,6 +528,7 @@ int nexthop_is_sorted(struct nexthop *x);
void rta_init(void);
static inline size_t rta_size(const rta *a) { return sizeof(rta) + sizeof(u32)*a->nh.labels; }
+#define RTA_MAX_SIZE (sizeof(rta) + sizeof(u32)*NEXTHOP_MAX_LABEL_STACK)
rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */
static inline int rta_is_cached(rta *r) { return r->aflags & RTAF_CACHED; }
static inline rta *rta_clone(rta *r) { r->uc++; return r; }
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index d3671a53..22a5cb14 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -330,6 +330,9 @@ nexthop_copy(struct nexthop *o)
n->iface = o->iface;
n->next = NULL;
n->weight = o->weight;
+ n->labels = o->labels;
+ for (int i=0; i<o->labels; i++)
+ n->label[i] = o->label[i];
*last = n;
last = &(n->next);
@@ -1176,6 +1179,12 @@ rta_do_cow(rta *o, linpool *lp)
{
rta *r = lp_alloc(lp, rta_size(o));
memcpy(r, o, rta_size(o));
+ for (struct nexthop **nhn = &(r->nh.next), *nho = o->nh.next; nho; nho = nho->next)
+ {
+ *nhn = lp_alloc(lp, nexthop_size(nho));
+ memcpy(*nhn, nho, nexthop_size(nho));
+ nhn = &((*nhn)->next);
+ }
r->aflags = 0;
r->uc = 0;
return r;
diff --git a/nest/rt-table.c b/nest/rt-table.c
index a7ceddb8..92542ea8 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -2443,14 +2443,7 @@ rt_format_via(rte *e)
switch (a->dest)
{
- case RTD_UNICAST: if (a->nh.next)
- bsprintf(via, "multipath");
- else
- {
- if (ipa_nonzero(a->nh.gw)) bsprintf(via, "via %I ", a->nh.gw);
- bsprintf(via, "dev %s", a->nh.iface->name);
- }
- break;
+ case RTD_UNICAST: bsprintf(via, "unicast"); break;
case RTD_BLACKHOLE: bsprintf(via, "blackhole"); break;
case RTD_UNREACHABLE: bsprintf(via, "unreachable"); break;
case RTD_PROHIBIT: bsprintf(via, "prohibited"); break;
@@ -2492,11 +2485,24 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
bsprintf(info, " (%d)", e->pref);
cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", ia, rt_format_via(e), a->src->proto->name,
tm, from, primary ? (sync_error ? " !" : " *") : "", info);
- if (a->nh.next)
- for (nh = &(a->nh); nh; nh = nh->next)
- cli_printf(c, -1007, "\tvia %I on %s weight %d", nh->gw, nh->iface->name, nh->weight + 1);
+ for (nh = &(a->nh); nh; nh = nh->next)
+ {
+ char ls[NEXTHOP_MAX_LABEL_STACK*8 + 5]; char *lsp = ls;
+ if (nh->labels)
+ {
+ lsp += bsprintf(lsp, " mpls %d", nh->label[0]);
+ for (int i=1;i<nh->labels; i++)
+ lsp += bsprintf(lsp, "/%d", nh->label[i]);
+ *lsp++ = '\0';
+ }
+ if (a->nh.next)
+ cli_printf(c, -1007, "\tvia %I%s on %s weight %d", nh->gw, (nh->labels ? ls : ""), nh->iface->name, nh->weight + 1);
+ else
+ cli_printf(c, -1007, "\tvia %I%s on %s", nh->gw, (nh->labels ? ls : ""), nh->iface->name);
+ }
if (d->verbose)
rta_show(c, a, tmpa);
+
}
static void