summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/attrs.c3
-rw-r--r--proto/bgp/packets.c12
-rw-r--r--proto/ospf/rt.c10
-rw-r--r--proto/pipe/pipe.c2
-rw-r--r--proto/rip/rip.c21
-rw-r--r--proto/rpki/rpki.c2
-rw-r--r--proto/static/config.Y87
-rw-r--r--proto/static/static.c53
8 files changed, 88 insertions, 102 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 11666f30..1b124a17 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1461,8 +1461,7 @@ bgp_get_neighbor(rte *r)
static inline int
rte_resolvable(rte *rt)
{
- int rd = rt->attrs->dest;
- return (rd == RTD_UNICAST);
+ return rt->attrs->dest == RTD_UNICAST;
}
int
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index 9c59e6d8..9380f999 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -700,9 +700,7 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll)
WITHDRAW(BAD_NEXT_HOP);
a->dest = RTD_UNICAST;
- a->nh.gw = nbr->addr;
- a->nh.iface = nbr->iface;
- a->nh.next = NULL;
+ a->nh = (struct nexthop){ .gw = nbr->addr, .iface = nbr->iface };
a->hostentry = NULL;
a->igp_metric = 0;
}
@@ -749,8 +747,8 @@ bgp_use_gateway(struct bgp_export_state *s)
if (s->channel->cf->next_hop_self)
return 0;
- /* We need valid global gateway */
- if ((ra->dest != RTD_UNICAST) || (ra->nh.next) || ipa_zero(ra->nh.gw) || ipa_is_link_local(ra->nh.gw))
+ /* We need one valid global gateway */
+ if ((ra->dest != RTD_UNICAST) || ra->nh.next || ipa_zero(ra->nh.gw) || ipa_is_link_local(ra->nh.gw))
return 0;
/* Use it when exported to internal peers */
@@ -1434,12 +1432,10 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis
if (ea)
{
- a = alloca(sizeof(struct rta));
- memset(a, 0, sizeof(struct rta));
+ a = allocz(sizeof(struct rta));
a->source = RTS_BGP;
a->scope = SCOPE_UNIVERSE;
- a->dest = RTD_UNREACHABLE;
a->from = s->proto->cf->remote_ip;
a->eattrs = ea;
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index 74f47810..1b0ac5e9 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -36,11 +36,9 @@ unresolved_vlink(ort *ort)
static inline struct nexthop *
new_nexthop(struct ospf_proto *p, ip_addr gw, struct iface *iface, byte weight)
{
- struct nexthop *nh = lp_alloc(p->nhpool, sizeof(struct nexthop));
- nh->labels = 0;
+ struct nexthop *nh = lp_allocz(p->nhpool, sizeof(struct nexthop));
nh->gw = gw;
nh->iface = iface;
- nh->next = NULL;
nh->weight = weight;
return nh;
}
@@ -1907,7 +1905,6 @@ ort_changed(ort *nf, rta *nr)
(nf->n.metric1 != nf->old_metric1) || (nf->n.metric2 != nf->old_metric2) ||
(nf->n.tag != nf->old_tag) || (nf->n.rid != nf->old_rid) ||
(nr->source != or->source) || (nr->dest != or->dest) ||
- (nr->nh.iface != or->nh.iface) || !ipa_equal(nr->nh.gw, or->nh.gw) ||
!nexthop_same(&(nr->nh), &(or->nh));
}
@@ -1952,11 +1949,10 @@ again1:
.src = p->p.main_source,
.source = nf->n.type,
.scope = SCOPE_UNIVERSE,
+ .dest = RTD_UNICAST,
+ .nh = *(nf->n.nhs),
};
- nexthop_link(&a0, nf->n.nhs);
- a0.dest = RTD_UNICAST;
-
if (reload || ort_changed(nf, &a0))
{
rta *a = rta_lookup(&a0);
diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c
index a4d371fe..310f3c01 100644
--- a/proto/pipe/pipe.c
+++ b/proto/pipe/pipe.c
@@ -43,8 +43,6 @@
#include "pipe.h"
-#include <alloca.h>
-
static void
pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old, ea_list *attrs)
{
diff --git a/proto/rip/rip.c b/proto/rip/rip.c
index 9bed9249..157093aa 100644
--- a/proto/rip/rip.c
+++ b/proto/rip/rip.c
@@ -147,20 +147,16 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
.src = p->p.main_source,
.source = RTS_RIP,
.scope = SCOPE_UNIVERSE,
+ .dest = RTD_UNICAST,
};
u8 rt_metric = rt->metric;
u16 rt_tag = rt->tag;
- struct rip_rte *rt2 = rt->next;
- /* Find second valid rte */
- while (rt2 && !rip_valid_rte(rt2))
- rt2 = rt2->next;
-
- a0.dest = RTD_UNICAST;
- if (p->ecmp && rt2)
+ if (p->ecmp)
{
/* ECMP route */
+ struct nexthop *nhs = NULL;
int num = 0;
for (rt = en->routes; rt && (num < p->ecmp); rt = rt->next)
@@ -168,28 +164,27 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
if (!rip_valid_rte(rt))
continue;
- struct nexthop *nh = (a0.nh.next ? &(a0.nh) : alloca(sizeof(struct nexthop)));
+ struct nexthop *nh = allocz(sizeof(struct nexthop));
nh->gw = rt->next_hop;
nh->iface = rt->from->nbr->iface;
nh->weight = rt->from->ifa->cf->ecmp_weight;
- if (a0.nh.next)
- nexthop_insert(&(a0.nh), nh);
-
+ nexthop_insert(&nhs, nh);
num++;
if (rt->tag != rt_tag)
rt_tag = 0;
}
+
+ a0.nh = *nhs;
}
else
{
/* Unipath route */
- a0.nh.next = NULL;
+ a0.from = rt->from->nbr->addr;
a0.nh.gw = rt->next_hop;
a0.nh.iface = rt->from->nbr->iface;
- a0.from = rt->from->nbr->addr;
}
rta *a = rta_lookup(&a0);
diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c
index 81268e83..497edd3c 100644
--- a/proto/rpki/rpki.c
+++ b/proto/rpki/rpki.c
@@ -124,7 +124,7 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_
.src = p->p.main_source,
.source = RTS_RPKI,
.scope = SCOPE_UNIVERSE,
- .dest = RTD_BLACKHOLE,
+ .dest = RTD_NONE,
};
rta *a = rta_lookup(&a0);
diff --git a/proto/static/config.Y b/proto/static/config.Y
index 2fb54448..16c276ce 100644
--- a/proto/static/config.Y
+++ b/proto/static/config.Y
@@ -13,9 +13,33 @@ CF_HDR
CF_DEFINES
#define STATIC_CFG ((struct static_config *) this_proto)
-static struct static_route *this_srt, *last_srt;
+static struct static_route *this_srt, *this_snh;
static struct f_inst **this_srt_last_cmd;
+static struct static_route *
+static_nexthop_new(void)
+{
+ struct static_route *nh;
+
+ if (!this_snh)
+ {
+ /* First next hop */
+ nh = this_srt;
+ rem_node(&this_srt->n);
+ }
+ else
+ {
+ /* Additional next hop */
+ nh = cfg_allocz(sizeof(struct static_route));
+ nh->net = this_srt->net;
+ this_snh->mp_next = nh;
+ }
+
+ nh->dest = RTD_UNICAST;
+ nh->mp_head = this_srt;
+ return nh;
+};
+
static void
static_route_finish(void)
{ }
@@ -45,48 +69,35 @@ static_proto:
| static_proto stat_route stat_route_opt_list ';' { static_route_finish(); }
;
-stat_nexthop_via: VIA
-{
- if (last_srt)
- {
- last_srt = (last_srt->mp_next = cfg_allocz(sizeof(struct static_route)));
- last_srt->net = this_srt->net;
- }
- else
- {
- last_srt = this_srt;
- rem_node(&this_srt->n);
- }
-
- last_srt->mp_head = this_srt;
- last_srt->dest = RTD_UNICAST;
-};
-
-stat_nexthop_ident:
- stat_nexthop_via ipa ipa_scope {
- last_srt->via = $2;
- last_srt->iface = $3;
- add_tail(&STATIC_CFG->neigh_routes, &last_srt->n);
+stat_nexthop:
+ VIA ipa ipa_scope {
+ this_snh = static_nexthop_new();
+ this_snh->via = $2;
+ this_snh->iface = $3;
+ add_tail(&STATIC_CFG->neigh_routes, &this_snh->n);
}
- | stat_nexthop_via TEXT {
- last_srt->via = IPA_NONE;
- last_srt->if_name = $2;
- add_tail(&STATIC_CFG->iface_routes, &last_srt->n);
+ | VIA TEXT {
+ this_snh = static_nexthop_new();
+ this_snh->via = IPA_NONE;
+ this_snh->if_name = $2;
+ add_tail(&STATIC_CFG->iface_routes, &this_snh->n);
}
- | stat_nexthop_ident MPLS label_stack {
- last_srt->label_count = $3[0];
- last_srt->label_stack = &($3[1]);
+ | stat_nexthop MPLS label_stack {
+ this_snh->label_count = $3[0];
+ this_snh->label_stack = &($3[1]);
}
- | stat_nexthop_ident WEIGHT expr {
- last_srt->weight = $3 - 1;
+ | stat_nexthop WEIGHT expr {
+ this_snh->weight = $3 - 1;
if (($3<1) || ($3>256)) cf_error("Weight must be in range 1-256");
}
- | stat_nexthop_ident BFD bool { last_srt->use_bfd = $3; cf_check_bfd($3); }
+ | stat_nexthop BFD bool {
+ this_snh->use_bfd = $3; cf_check_bfd($3);
+ }
;
-stat_nexthop:
- stat_nexthop_ident
- | stat_nexthop stat_nexthop_ident
+stat_nexthops:
+ stat_nexthop
+ | stat_nexthops stat_nexthop
;
stat_route0: ROUTE net_any {
@@ -95,12 +106,12 @@ stat_route0: ROUTE net_any {
this_srt->net = $2;
this_srt_last_cmd = &(this_srt->cmds);
this_srt->mp_next = NULL;
- last_srt = NULL;
+ this_snh = NULL;
}
;
stat_route:
- stat_route0 stat_nexthop
+ stat_route0 stat_nexthops
| stat_route0 RECURSIVE ipa {
this_srt->dest = RTDX_RECURSIVE;
this_srt->via = $3;
diff --git a/proto/static/static.c b/proto/static/static.c
index 3e03708c..e5251bf6 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -60,54 +60,44 @@ p_igp_table(struct proto *p)
static void
static_install(struct proto *p, struct static_route *r)
{
- rta *ap = alloca(RTA_MAX_SIZE);
+ rta *ap = allocz(RTA_MAX_SIZE);
rte *e;
if (!(r->state & STS_WANT) && (r->state & (STS_INSTALLED | STS_FORCE)) && r->dest != RTD_UNICAST)
goto drop;
DBG("Installing static route %N, rtd=%d\n", r->net, r->dest);
- bzero(ap, RTA_MAX_SIZE);
ap->src = p->main_source;
- ap->source = ((r->dest == RTD_UNICAST) && ipa_zero(r->via)) ? RTS_STATIC_DEVICE : RTS_STATIC;
+ ap->source = RTS_STATIC;
ap->scope = SCOPE_UNIVERSE;
ap->dest = r->dest;
if (r->dest == RTD_UNICAST)
{
+ struct nexthop *nhs = NULL;
struct static_route *r2;
- int num = 0, update = 0;
+ int update = 0;
+ r = r->mp_head;
for (r2 = r; r2; r2 = r2->mp_next)
{
-
if ((r2->state & STS_FORCE) ||
(!!(r2->state & STS_INSTALLED) != !!(r2->state & STS_WANT)))
update++;
if (r2->state & STS_WANT)
- {
- struct nexthop *nh = (ap->nh.next) ? alloca(NEXTHOP_MAX_SIZE) : &(ap->nh);
- if (ipa_zero(r2->via)) // Device nexthop
- {
- nh->gw = IPA_NONE;
- nh->iface = r2->iface;
- }
- else // Router nexthop
- {
- nh->gw = r2->via;
- nh->iface = r2->neigh->iface;
- }
- nh->weight = r2->weight;
- nh->labels = r2->label_count;
- for (int i=0; i<nh->labels; i++)
- nh->label[i] = r2->label_stack[i];
-
- if (ap->nh.next)
- nexthop_insert(&(ap->nh), nh);
- r2->state |= STS_INSTALLED;
- num++;
- }
+ {
+ struct nexthop *nh = allocz(NEXTHOP_MAX_SIZE);
+
+ nh->gw = r2->via;
+ nh->iface = r2->neigh ? r2->neigh->iface : r2->iface;
+ nh->weight = r2->weight;
+ nh->labels = r2->label_count;
+ memcpy(nh->label, r2->label_stack, r2->label_count * sizeof(u32));
+
+ r2->state |= STS_INSTALLED;
+ nexthop_insert(&nhs, nh);
+ }
else
r2->state = 0;
}
@@ -115,18 +105,19 @@ static_install(struct proto *p, struct static_route *r)
if (!update) // Nothing changed
return;
- r = r->mp_head;
-
- if (!num) // No nexthop to install
+ if (!nhs) // No nexthop to install
{
drop:
rte_update(p, r->net, NULL);
return;
}
+
+ ap->dest = RTD_UNICAST;
+ nexthop_link(ap, nhs);
}
else
r->state |= STS_INSTALLED;
-
+
if (r->dest == RTDX_RECURSIVE)
{
ap->nh.labels_append = ap->nh.labels = r->label_count;