summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2017-07-04 23:36:21 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2017-07-04 23:36:21 +0200
commita1f5e514ef091b82754f38f0e583af40778c7d97 (patch)
treeb449e8da19c061bb4a64857cf29cae9a521cf86f /proto
parent5220cb63e34961b097d3bc274e394c0fa946d7d3 (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 'proto')
-rw-r--r--proto/static/config.Y5
-rw-r--r--proto/static/static.c17
-rw-r--r--proto/static/static.h1
3 files changed, 16 insertions, 7 deletions
diff --git a/proto/static/config.Y b/proto/static/config.Y
index 66ae3c98..66e5ea4c 100644
--- a/proto/static/config.Y
+++ b/proto/static/config.Y
@@ -44,7 +44,7 @@ static_route_finish(void)
CF_DECLS
CF_KEYWORDS(STATIC, ROUTE, VIA, DROP, REJECT, PROHIBIT, PREFERENCE, CHECK, LINK)
-CF_KEYWORDS(WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE, BFD, MPLS)
+CF_KEYWORDS(ONLINK, WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE, BFD, MPLS)
CF_GRAMMAR
@@ -87,6 +87,9 @@ stat_nexthop:
| stat_nexthop MPLS label_stack {
this_snh->mls = $3;
}
+ | stat_nexthop ONLINK bool {
+ this_snh->onlink = $3;
+ }
| stat_nexthop WEIGHT expr {
this_snh->weight = $3 - 1;
if (($3<1) || ($3>256)) cf_error("Weight must be in range 1-256");
diff --git a/proto/static/static.c b/proto/static/static.c
index bb1501a5..ede4c734 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -71,6 +71,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
struct nexthop *nh = allocz(NEXTHOP_MAX_SIZE);
nh->gw = r2->via;
nh->iface = r2->neigh->iface;
+ nh->flags = r2->onlink ? RNF_ONLINK : 0;
nh->weight = r2->weight;
if (r2->mls)
{
@@ -205,7 +206,8 @@ static_add_rte(struct static_proto *p, struct static_route *r)
for (r2 = r; r2; r2 = r2->mp_next)
{
n = ipa_nonzero(r2->via) ?
- neigh_find2(&p->p, &r2->via, r2->iface, NEF_STICKY) :
+ neigh_find2(&p->p, &r2->via, r2->iface,
+ NEF_STICKY | (r2->onlink ? NEF_ONLINK : 0)) :
neigh_find_iface(&p->p, r2->iface);
if (!n)
@@ -267,8 +269,9 @@ static_same_dest(struct static_route *x, struct static_route *y)
{
if (!ipa_equal(x->via, y->via) ||
(x->iface != y->iface) ||
- (x->use_bfd != y->use_bfd) ||
+ (x->onlink != y->onlink) ||
(x->weight != y->weight) ||
+ (x->use_bfd != y->use_bfd) ||
(!x->mls != !y->mls) ||
((x->mls) && (y->mls) && (x->mls->len != y->mls->len)))
return 0;
@@ -614,11 +617,13 @@ static_show_rt(struct static_route *r)
for (r2 = r; r2; r2 = r2->mp_next)
{
if (r2->iface && ipa_zero(r2->via))
- cli_msg(-1009, "\tdev %s%s%s", r2->iface->name,
- r2->bfd_req ? " (bfd)" : "", r2->active ? "" : " (dormant)");
+ cli_msg(-1009, "\tdev %s%s", r2->iface->name,
+ r2->active ? "" : " (dormant)");
else
- cli_msg(-1009, "\tvia %I%J%s%s", r2->via, r2->iface,
- r2->bfd_req ? " (bfd)" : "", r2->active ? "" : " (dormant)");
+ cli_msg(-1009, "\tvia %I%J%s%s%s", r2->via, r2->iface,
+ r2->onlink ? " onlink" : "",
+ r2->bfd_req ? " (bfd)" : "",
+ r2->active ? "" : " (dormant)");
}
break;
}
diff --git a/proto/static/static.h b/proto/static/static.h
index c84dfa98..b202c0b1 100644
--- a/proto/static/static.h
+++ b/proto/static/static.h
@@ -43,6 +43,7 @@ struct static_route {
byte dest; /* Destination type (RTD_*) */
byte state; /* State of route announcement (SRS_*) */
byte active; /* Next hop is active (nbr/iface/BFD available) */
+ byte onlink; /* Gateway is onlink regardless of IP ranges */
byte weight; /* Multipath next hop weight */
byte use_bfd; /* Configured to use BFD */
struct bfd_request *bfd_req; /* BFD request, if BFD is used */