diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2017-07-04 23:36:21 +0200 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2017-07-04 23:36:21 +0200 |
commit | a1f5e514ef091b82754f38f0e583af40778c7d97 (patch) | |
tree | b449e8da19c061bb4a64857cf29cae9a521cf86f /nest | |
parent | 5220cb63e34961b097d3bc274e394c0fa946d7d3 (diff) |
Implement onlink flag for nexthops
Add proper support for per-nexthop onlink flag in routes to handle next
hop addresses that are not covered by interface IP ranges. Supported by
kernel and static protocols.
Thanks to Vincent Bernat for the idea.
Diffstat (limited to 'nest')
-rw-r--r-- | nest/route.h | 4 | ||||
-rw-r--r-- | nest/rt-attr.c | 6 | ||||
-rw-r--r-- | nest/rt-show.c | 7 | ||||
-rw-r--r-- | nest/rt-table.c | 5 |
4 files changed, 18 insertions, 4 deletions
diff --git a/nest/route.h b/nest/route.h index 6c9b00c2..c1a60ccc 100644 --- a/nest/route.h +++ b/nest/route.h @@ -366,12 +366,16 @@ struct nexthop { ip_addr gw; /* Next hop */ struct iface *iface; /* Outgoing interface */ struct nexthop *next; + byte flags; byte weight; byte labels_orig; /* Number of labels before hostentry was applied */ byte labels; /* Number of all labels */ u32 label[0]; }; +#define RNF_ONLINK 0x1 /* Gateway is onlink regardless of IP ranges */ + + struct rte_src { struct rte_src *next; /* Hash chain */ struct proto *proto; /* Protocol the source is based on */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 1b7f5836..761ba9fe 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -171,7 +171,9 @@ nexthop__same(struct nexthop *x, struct nexthop *y) { for (; x && y; x = x->next, y = y->next) { - if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) || (x->weight != y->weight) || (x->labels != y->labels)) + if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) || + (x->flags != y->flags) || (x->weight != y->weight) || + (x->labels != y->labels)) return 0; for (int i = 0; i < x->labels; i++) @@ -193,6 +195,8 @@ nexthop_compare_node(struct nexthop *x, struct nexthop *y) if (!y) return -1; + /* Should we also compare flags ? */ + r = ((int) y->weight) - ((int) x->weight); if (r) return r; diff --git a/nest/rt-show.c b/nest/rt-show.c index 3f5ef04d..afde2810 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -70,6 +70,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm for (nh = &(a->nh); nh; nh = nh->next) { char mpls[MPLS_MAX_LABEL_STACK*12 + 5], *lsp = mpls; + char *onlink = (nh->flags & RNF_ONLINK) ? " onlink" : ""; if (nh->labels) { @@ -80,9 +81,11 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm *lsp = '\0'; if (a->nh.next) - cli_printf(c, -1007, "\tvia %I%s on %s weight %d", nh->gw, mpls, nh->iface->name, nh->weight + 1); + cli_printf(c, -1007, "\tvia %I%s on %s%s weight %d", + nh->gw, mpls, nh->iface->name, onlink, nh->weight + 1); else - cli_printf(c, -1007, "\tvia %I%s on %s", nh->gw, mpls, nh->iface->name); + cli_printf(c, -1007, "\tvia %I%s on %s%s", + nh->gw, mpls, nh->iface->name, onlink); } if (d->verbose) diff --git a/nest/rt-table.c b/nest/rt-table.c index 85a951b8..2bb78cf2 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1819,7 +1819,10 @@ no_nexthop: } } if (ipa_nonzero(nh->gw)) - nhp->gw = nh->gw; /* Router nexthop */ + { + nhp->gw = nh->gw; /* Router nexthop */ + nhp->flags |= (nh->flags & RNF_ONLINK); + } else if (ipa_nonzero(he->link)) nhp->gw = he->link; /* Device nexthop with link-local address known */ else |