diff --git a/filter/f-inst.c b/filter/f-inst.c index 52b6d81d..984e7fc5 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -501,7 +501,7 @@ case SA_FROM: RESULT(sa.f_type, ip, rta->from); break; case SA_GW: RESULT(sa.f_type, ip, rta->nh.gw); break; case SA_NET: RESULT(sa.f_type, net, (*fs->rte)->net->n.addr); break; - case SA_PROTO: RESULT(sa.f_type, s, rta->src->proto->name); break; + case SA_PROTO: RESULT(sa.f_type, s, (*fs->rte)->src->proto->name); break; case SA_SOURCE: RESULT(sa.f_type, i, rta->source); break; case SA_SCOPE: RESULT(sa.f_type, i, rta->scope); break; case SA_DEST: RESULT(sa.f_type, i, rta->dest); break; @@ -534,7 +534,7 @@ case SA_GW: { ip_addr ip = v1.val.ip; - neighbor *n = neigh_find(rta->src->proto, ip, NULL, 0); + neighbor *n = neigh_find((*fs->rte)->src->proto, ip, NULL, 0); if (!n || (n->scope == SCOPE_HOST)) runtime( "Invalid gw address" ); diff --git a/nest/route.h b/nest/route.h index bb6677e1..1a4ec2aa 100644 --- a/nest/route.h +++ b/nest/route.h @@ -215,6 +215,7 @@ struct hostentry { typedef struct rte { struct rte *next; net *net; /* Network this RTE belongs to */ + struct rte_src *src; /* Route source that created the route */ struct channel *sender; /* Channel used to send the route to the routing table */ struct rta *attrs; /* Attributes of this route */ u32 id; /* Table specific route id */ @@ -429,7 +430,6 @@ typedef struct rta { u32 uc; /* Use count */ u32 hash_key; /* Hash over important fields */ struct ea_list *eattrs; /* Extended Attribute chain */ - struct rte_src *src; /* Route source that created the route */ struct hostentry *hostentry; /* Hostentry for recursive next-hops */ ip_addr from; /* Advertising router */ u32 igp_metric; /* IGP metric to next hop (for iBGP routes) */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index e1a07c91..78fb58d6 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -1099,7 +1099,6 @@ rta_hash(rta *a) mem_hash_init(&h); #define MIX(f) mem_hash_mix(&h, &(a->f), sizeof(a->f)); #define BMIX(f) mem_hash_mix_num(&h, a->f); - MIX(src); MIX(hostentry); MIX(from); MIX(igp_metric); @@ -1115,8 +1114,7 @@ rta_hash(rta *a) static inline int rta_same(rta *x, rta *y) { - return (x->src == y->src && - x->source == y->source && + return (x->source == y->source && x->scope == y->scope && x->dest == y->dest && x->igp_metric == y->igp_metric && @@ -1206,7 +1204,6 @@ rta_lookup(rta *o) r = rta_copy(o); r->hash_key = h; r->cached = 1; - rt_lock_source(r->src); rt_lock_hostentry(r->hostentry); rta_insert(r); @@ -1225,7 +1222,6 @@ rta__free(rta *a) if (a->next) a->next->pprev = a->pprev; rt_unlock_hostentry(a->hostentry); - rt_unlock_source(a->src); if (a->nh.next) nexthop_free(a->nh.next); ea_free(a->eattrs); @@ -1264,8 +1260,8 @@ rta_dump(rta *a) "RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" }; static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" }; - debug("p=%s pref=%d uc=%d %s %s%s h=%04x", - a->src->proto->name, a->pref, a->uc, rts[a->source], ip_scope_text(a->scope), + debug("pref=%d uc=%d %s %s%s h=%04x", + a->pref, a->uc, rts[a->source], ip_scope_text(a->scope), rtd[a->dest], a->hash_key); if (!a->cached) debug(" !CACHED"); diff --git a/nest/rt-dev.c b/nest/rt-dev.c index 7a340160..dae1223b 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -77,7 +77,6 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) rta a0 = { /* Use iface ID as local source ID */ - .src = rt_get_source(P, ad->iface->index), .pref = c->preference, .source = RTS_DEVICE, .scope = SCOPE_UNIVERSE, @@ -85,6 +84,7 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) .nh.iface = ad->iface, }; rte e0 = { + .src = rt_get_source(P, ad->iface->index), .attrs = &a0, }; rte_update(c, net, &e0); diff --git a/nest/rt-show.c b/nest/rt-show.c index 0d912570..6a45b518 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -56,7 +56,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary if (d->verbose && !rta_is_cached(a) && a->eattrs) ea_normalize(a->eattrs); - get_route_info = a->src->proto->proto->get_route_info; + get_route_info = e->src->proto->proto->get_route_info; if (get_route_info) get_route_info(e, info); else @@ -66,7 +66,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary rt_show_table(c, d); cli_printf(c, -1007, "%-20s %s [%s %s%s]%s%s", ia, rta_dest_name(a->dest), - a->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info); + e->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info); if (a->dest == RTD_UNICAST) for (nh = &(a->nh); nh; nh = nh->next) @@ -180,7 +180,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) } } - if (d->show_protocol && (d->show_protocol != e->attrs->src->proto)) + if (d->show_protocol && (d->show_protocol != e->src->proto)) goto skip; if (f_run(d->filter, &e, c->show_pool, 0) > F_ACCEPT) diff --git a/nest/rt-table.c b/nest/rt-table.c index 38d93791..711e368a 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -270,7 +270,7 @@ rte_find(net *net, struct rte_src *src) { rte *e = net->routes; - while (e && e->attrs->src != src) + while (e && e->src != src) e = e->next; return e; } @@ -283,6 +283,7 @@ rte_do_cow(rte *r) memcpy(e, r, sizeof(rte)); e->attrs = rta_clone(r->attrs); e->flags = 0; + rt_lock_source(e->src); return e; } @@ -291,6 +292,8 @@ rte_store(rte *r) { rte *e = sl_alloc(rte_slab); memcpy(e, r, sizeof(rte)); + + rt_lock_source(e->src); if (e->attrs->cached) e->attrs = rta_clone(r->attrs); else @@ -339,6 +342,7 @@ rte_cow_rta(rte *r, linpool *lp) void rte_free(rte *e) { + rt_unlock_source(e->src); if (rta_is_cached(e->attrs)) rta_free(e->attrs); sl_free(rte_slab, e); @@ -347,6 +351,7 @@ rte_free(rte *e) static inline void rte_free_quick(rte *e) { + rt_unlock_source(e->src); rta_free(e->attrs); sl_free(rte_slab, e); } @@ -374,16 +379,16 @@ rte_better(rte *new, rte *old) return 1; if (new->attrs->pref < old->attrs->pref) return 0; - if (new->attrs->src->proto->proto != old->attrs->src->proto->proto) + if (new->src->proto->proto != old->src->proto->proto) { /* * If the user has configured protocol preferences, so that two different protocols * have the same preference, try to break the tie by comparing addresses. Not too * useful, but keeps the ordering of routes unambiguous. */ - return new->attrs->src->proto->proto > old->attrs->src->proto->proto; + return new->src->proto->proto > old->src->proto->proto; } - if (better = new->attrs->src->proto->rte_better) + if (better = new->src->proto->rte_better) return better(new, old); return 0; } @@ -399,10 +404,10 @@ rte_mergable(rte *pri, rte *sec) if (pri->attrs->pref != sec->attrs->pref) return 0; - if (pri->attrs->src->proto->proto != sec->attrs->src->proto->proto) + if (pri->src->proto->proto != sec->src->proto->proto) return 0; - if (mergable = pri->attrs->src->proto->rte_mergable) + if (mergable = pri->src->proto->rte_mergable) return mergable(pri, sec); return 0; @@ -513,13 +518,13 @@ rt_notify_basic(struct channel *c, struct rte_export_internal *e) if (e->new) { ep->new = export_filter(c, e->new, &e->rt_free, 0); - ep->new_src = e->new->attrs->src; + ep->new_src = e->new->src; } if (e->old && bmap_test(&c->export_map, e->old->id)) { ep->old = e->old; - ep->old_src = e->old->attrs->src; + ep->old_src = e->old->src; } return (ep->new || ep->old) ? ep : NULL; @@ -597,9 +602,9 @@ rt_notify_accepted(struct channel *c, struct rte_export_internal *e) struct rte_export *ep = lp_alloc(rte_update_pool, sizeof(struct rte_export)); *ep = (struct rte_export) { .new = new_best, - .new_src = new_best ? new_best->attrs->src : NULL, + .new_src = new_best ? new_best->src : NULL, .old = old_best, - .old_src = old_best ? old_best->attrs->src : NULL, + .old_src = old_best ? old_best->src : NULL, }; return ep; @@ -692,7 +697,7 @@ rt_notify_merged(struct channel *c, struct rte_export_internal *e) if (e->new_best) { ep->new = rt_export_merged(c, e->net, &(e->rt_free), rte_update_pool, 0); - ep->new_src = e->net->routes->attrs->src; + ep->new_src = e->net->routes->src; } /* Check old merged route */ @@ -702,7 +707,7 @@ rt_notify_merged(struct channel *c, struct rte_export_internal *e) if (!ep->new && !ep->old) return NULL; - ep->old_src = ep->old ? ep->old->attrs->src : NULL; + ep->old_src = ep->old ? ep->old->src : NULL; return ep; } @@ -980,7 +985,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src) k = &net->routes; /* Find and remove original route from the same protocol */ while (old = *k) { - if (old->attrs->src == src) + if (old->src == src) { /* If there is the same route in the routing table but from * a different sender, then there are two paths from the @@ -1349,8 +1354,9 @@ static int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct void rte_withdraw(struct channel *c, const net_addr *n, struct rte_src *src) { + ASSERT(src); if (!c->in_table || rte_update_in(c, n, NULL, src)) - rte_update2(c, n, NULL, src ?: c->proto->main_source); + rte_update2(c, n, NULL, src); } void @@ -1358,7 +1364,7 @@ rte_update(struct channel *c, const net_addr *n, struct rte *new) { ASSERT(new); ASSERT(new->attrs); - ASSERT(new->attrs->src); + ASSERT(new->src); if (!new->attrs->pref) { @@ -1369,8 +1375,10 @@ rte_update(struct channel *c, const net_addr *n, struct rte *new) rte *e = sl_alloc(rte_slab); *e = *new; - if (!c->in_table || rte_update_in(c, n, e, e->attrs->src)) - rte_update2(c, n, e, e->attrs->src); + rt_lock_source(e->src); + + if (!c->in_table || rte_update_in(c, n, e, e->src)) + rte_update2(c, n, e, e->src); } /* Independent call to rte_announce(), used from next hop @@ -1388,7 +1396,7 @@ static inline void rte_discard(rte *old) /* Non-filtered route deletion, used during garbage collection */ { rte_update_lock(); - rte_recalculate(old->sender, old->net, NULL, old->attrs->src); + rte_recalculate(old->sender, old->net, NULL, old->src); rte_update_unlock(); } @@ -1408,7 +1416,7 @@ rte_modify(rte *old) new->flags = (old->flags & ~REF_MODIFY) | REF_COW; } - rte_recalculate(old->sender, old->net, new, old->attrs->src); + rte_recalculate(old->sender, old->net, new, old->src); } rte_update_unlock(); @@ -1884,6 +1892,7 @@ rt_next_hop_update_rte(rtable *tab UNUSED, rte *old) rte *e = sl_alloc(rte_slab); memcpy(e, old, sizeof(rte)); e->attrs = rta_lookup(a); + rt_lock_source(e->src); return e; } @@ -1910,8 +1919,8 @@ rt_next_hop_update_net(rtable *tab, net *n) /* Call a pre-comparison hook */ /* Not really an efficient way to compute this */ - if (e->attrs->src->proto->rte_recalculate) - e->attrs->src->proto->rte_recalculate(tab, n, new, e, NULL); + if (e->src->proto->rte_recalculate) + e->src->proto->rte_recalculate(tab, n, new, e, NULL); if (e != old_best) rte_free_quick(e); @@ -2249,7 +2258,7 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr /* Find the old rte */ for (pos = &net->routes; old = *pos; pos = &old->next) - if (old->attrs->src == src) + if (old->src == src) { if (new && rte_same(old, new)) { @@ -2344,7 +2353,7 @@ rt_reload_channel(struct channel *c) return 0; } - rte_update2(c, e->net->n.addr, rte_do_cow(e), e->attrs->src); + rte_update2(c, e->net->n.addr, rte_do_cow(e), e->src); } c->reload_next_rte = NULL; @@ -2427,7 +2436,7 @@ rte_update_out(struct channel *c, const net_addr *n, struct rte_src *src, rte *n /* Find the old rte */ for (pos = &net->routes; old = *pos; pos = &old->next) - if ((c->ra_mode != RA_ANY) || (old->attrs->src == src)) + if ((c->ra_mode != RA_ANY) || (old->src == src)) { if (new && rte_same(old, new)) { diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 6765b895..1a072c9c 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -631,7 +631,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) if (r) { rta a0 = { - .src = p->p.main_source, .source = RTS_BABEL, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, @@ -665,6 +664,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) }; rte e0 = { + .src = p->p.main_source, .attrs = &a0, }; @@ -675,7 +675,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) { /* Unreachable */ rta a0 = { - .src = p->p.main_source, .source = RTS_BABEL, .scope = SCOPE_UNIVERSE, .dest = RTD_UNREACHABLE, @@ -683,6 +682,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) }; rte e0 = { + .src = p->p.main_source, .attrs = &a0, }; @@ -2107,10 +2107,8 @@ babel_kick_timer(struct babel_proto *p) static int babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED) { - struct rta *a = (*new)->attrs; - /* Reject our own unreachable routes */ - if ((a->dest == RTD_UNREACHABLE) && (a->src->proto == P)) + if (((*new)->attrs->dest == RTD_UNREACHABLE) && ((*new)->src->proto == P)) return -1; return 0; diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index e8bbafc6..e11f01e5 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1633,7 +1633,7 @@ int bgp_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED) { rte *e = *new; - struct proto *SRC = e->attrs->src->proto; + struct proto *SRC = e->src->proto; struct bgp_proto *p = (struct bgp_proto *) P; struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (struct bgp_proto *) SRC : NULL; @@ -1688,7 +1688,7 @@ bgp_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED) static ea_list * bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs0, struct linpool *pool) { - struct proto *SRC = e->attrs->src->proto; + struct proto *SRC = e->src->proto; struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (void *) SRC : NULL; struct bgp_export_state s = { .proto = p, .channel = c, .pool = pool, .src = src, .route = e, .mpls = c->desc->mpls }; ea_list *attrs = attrs0; @@ -1843,7 +1843,7 @@ bgp_get_neighbor(rte *r) return as; /* If AS_PATH is not defined, we treat rte as locally originated */ - struct bgp_proto *p = (void *) r->attrs->src->proto; + struct bgp_proto *p = (void *) r->src->proto; return p->cf->confederation ?: p->local_as; } @@ -1873,8 +1873,8 @@ rte_stale(rte *r) int bgp_rte_better(rte *new, rte *old) { - struct bgp_proto *new_bgp = (struct bgp_proto *) new->attrs->src->proto; - struct bgp_proto *old_bgp = (struct bgp_proto *) old->attrs->src->proto; + struct bgp_proto *new_bgp = (struct bgp_proto *) new->src->proto; + struct bgp_proto *old_bgp = (struct bgp_proto *) old->src->proto; eattr *x, *y; u32 n, o; @@ -2018,8 +2018,8 @@ bgp_rte_better(rte *new, rte *old) int bgp_rte_mergable(rte *pri, rte *sec) { - struct bgp_proto *pri_bgp = (struct bgp_proto *) pri->attrs->src->proto; - struct bgp_proto *sec_bgp = (struct bgp_proto *) sec->attrs->src->proto; + struct bgp_proto *pri_bgp = (struct bgp_proto *) pri->src->proto; + struct bgp_proto *sec_bgp = (struct bgp_proto *) sec->src->proto; eattr *x, *y; u32 p, s; @@ -2100,7 +2100,7 @@ same_group(rte *r, u32 lpref, u32 lasn) static inline int use_deterministic_med(rte *r) { - struct proto *P = r->attrs->src->proto; + struct proto *P = r->src->proto; return (P->proto == &proto_bgp) && ((struct bgp_proto *) P)->cf->deterministic_med; } diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 23e42ec3..000b5921 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1296,9 +1296,6 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0) { s->last_src = rt_get_source(&s->proto->p, path_id); s->last_id = path_id; - - rta_free(s->cached_rta); - s->cached_rta = NULL; } if (!a0) @@ -1311,8 +1308,6 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0) /* Prepare cached route attributes */ if (s->cached_rta == NULL) { - a0->src = s->last_src; - /* Workaround for rta_lookup() breaking eattrs */ ea_list *ea = a0->eattrs; s->cached_rta = rta_lookup(a0); @@ -1321,6 +1316,7 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0) rte e0 = { .attrs = rta_clone(s->cached_rta), + .src = s->last_src, }; rte_update(&(s->channel->c), n, &e0); diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c index 4048040c..a7d6508a 100644 --- a/proto/mrt/mrt.c +++ b/proto/mrt/mrt.c @@ -425,9 +425,9 @@ mrt_rib_table_entry(struct mrt_table_dump_state *s, rte *r) #ifdef CONFIG_BGP /* Find peer index */ - if (r->attrs->src->proto->proto == &proto_bgp) + if (r->src->proto->proto == &proto_bgp) { - struct bgp_proto *p = (void *) r->attrs->src->proto; + struct bgp_proto *p = (void *) r->src->proto; struct mrt_peer_entry *n = HASH_FIND(s->peer_hash, PEER, p->remote_id, p->remote_as, p->remote_ip); @@ -441,7 +441,7 @@ mrt_rib_table_entry(struct mrt_table_dump_state *s, rte *r) /* Path Identifier */ if (s->add_path) - mrt_put_u32(b, r->attrs->src->private_id); + mrt_put_u32(b, r->src->private_id); /* Route Attributes */ mrt_put_u16(b, 0); @@ -490,7 +490,7 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path) continue; /* Skip routes that should be reported in the other phase */ - if (!s->always_add_path && (!rt->attrs->src->private_id != !s->add_path)) + if (!s->always_add_path && (!rt->src->private_id != !s->add_path)) { s->want_add_path = 1; continue; diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 3c0a9232..0f4e4c0d 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -478,7 +478,7 @@ ospf_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED) rte *e = *new; /* Reject our own routes */ - if (e->attrs->src->proto == P) + if (e->src->proto == P) return -1; /* Do not export routes to stub areas */ diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index 66fb3741..18a596da 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -2043,7 +2043,6 @@ again1: if (nf->n.type) /* Add the route */ { rta a0 = { - .src = p->p.main_source, .source = nf->n.type, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, @@ -2092,7 +2091,10 @@ again1: .u.data = nf->n.rid, }; - rte e0 = { .attrs = rta_lookup(&a0), }; + rte e0 = { + .attrs = rta_lookup(&a0), + .src = p->p.main_source, + }; rta_free(nf->old_rta); nf->old_rta = rta_clone(e0.attrs); diff --git a/proto/perf/perf.c b/proto/perf/perf.c index a6681592..0989b9fe 100644 --- a/proto/perf/perf.c +++ b/proto/perf/perf.c @@ -143,7 +143,6 @@ perf_loop(void *data) if (!p->attrs_per_rte || !(i % p->attrs_per_rte)) { struct rta a0 = { - .src = p->p.main_source, .source = RTS_PERF, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, @@ -163,7 +162,10 @@ perf_loop(void *data) for (uint i=0; idata[i].a, }; + rte e0 = { + .attrs = p->data[i].a, + .src = p->p.main_source, + }; rte_update(P->main_channel, &(p->data[i].net), &e0); } diff --git a/proto/rip/rip.c b/proto/rip/rip.c index d19588bd..1e9bbc22 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -144,7 +144,6 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) { /* Update */ rta a0 = { - .src = p->p.main_source, .pref = p->p.main_channel->preference, .source = RTS_RIP, .scope = SCOPE_UNIVERSE, @@ -209,6 +208,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) rte e0 = { .attrs = &a0, + .src = p->p.main_source, }; rte_update(p->p.main_channel, en->n.addr, &e0); diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 442ce859..cb1d0e3c 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -121,14 +121,16 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_ struct rpki_proto *p = cache->p; rta a0 = { - .src = p->p.main_source, .pref = channel->preference, .source = RTS_RPKI, .scope = SCOPE_UNIVERSE, .dest = RTD_NONE, }; - rte e0 = { .attrs = &a0 }; + rte e0 = { + .attrs = &a0, + .src = p->p.main_source, + }; rte_update(channel, &pfxr->n, &e0); } diff --git a/proto/static/static.c b/proto/static/static.c index 932bef7c..4439e4e5 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -53,7 +53,6 @@ static void static_announce_rte(struct static_proto *p, struct static_route *r) { rta *a = allocz(RTA_MAX_SIZE); - a->src = p->p.main_source; a->source = RTS_STATIC; a->scope = SCOPE_UNIVERSE; a->dest = r->dest; @@ -100,7 +99,10 @@ static_announce_rte(struct static_proto *p, struct static_route *r) return; /* We skip rta_lookup() here */ - rte e0 = { .attrs = a }, *e = &e0; + rte e0 = { + .attrs = a, + .src = p->p.main_source, + }, *e = &e0; if (r->cmds) f_eval_rte(r->cmds, &e, static_lp); @@ -250,7 +252,7 @@ static void static_remove_rte(struct static_proto *p, struct static_route *r) { if (r->state) - rte_withdraw(p->p.main_channel, r->net, NULL); + rte_withdraw(p->p.main_channel, r->net, p->p.main_source); static_reset_rte(p, r); } diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index e6176b3a..6a0b8eae 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -301,6 +301,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e) { rte e0 = { .attrs = rta_clone(e->attrs), + .src = p->p.main_source, }; rte_update(p->p.main_channel, e->net->n.addr, &e0); @@ -877,7 +878,7 @@ krt_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED) // struct krt_proto *p = (struct krt_proto *) P; rte *e = *new; - if (e->attrs->src->proto == P) + if (e->src->proto == P) return -1; if (!krt_capable(e))