diff options
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/bsd/krt-sock.c | 13 | ||||
-rw-r--r-- | sysdep/linux/netlink.c | 58 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 207 | ||||
-rw-r--r-- | sysdep/unix/krt.h | 3 |
4 files changed, 144 insertions, 137 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index bc6b1839..19ef2394 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -398,7 +398,6 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan) /* p is NULL iff KRT_SHARED_SOCKET and !scan */ int ipv6; - rte *e; net *net; sockaddr dst, gate, mask; ip_addr idst, igate, imask; @@ -519,7 +518,6 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan) net = net_get(p->p.main_channel->table, &ndst); rta a = { - .src = p->p.main_source, .source = RTS_INHERIT, }; @@ -578,17 +576,16 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan) } } - done: - e = rte_get_temp(&a); - e->net = net; + done:; + rte e0 = { .attrs = &a, .net = net, }; - ea_set_attr(e->attrs->eattrs, + ea_set_attr(e0.attrs->eattrs, EA_LITERAL_EMBEDDED(EA_KRT_SOURCE, T_INT, 0, src2)); if (scan) - krt_got_route(p, e, src); + krt_got_route(p, &e0, src); else - krt_got_route_async(p, e, new, src); + krt_got_route_async(p, &e0, new, src); } static void diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index c506c71c..2dbe59e9 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -110,7 +110,7 @@ struct nl_parse_state int scan; int merge; - net *net; + net_addr *net; rta *attrs; struct krt_proto *proto; s8 new; @@ -1421,10 +1421,9 @@ nh_bufsize(struct nexthop *nh) } static int -nl_send_route(struct krt_proto *p, rte *e, int op, int dest, struct nexthop *nh) +nl_send_route(struct krt_proto *p, const rte *e, int op, int dest, struct nexthop *nh) { eattr *ea; - net *net = e->net; rta *a = e->attrs; ea_list *eattrs = a->eattrs; int bufsize = 128 + KRT_METRICS_MAX*8 + nh_bufsize(&(a->nh)); @@ -1439,7 +1438,7 @@ nl_send_route(struct krt_proto *p, rte *e, int op, int dest, struct nexthop *nh) int rsize = sizeof(*r) + bufsize; r = alloca(rsize); - DBG("nl_send_route(%N,op=%x)\n", net->n.addr, op); + DBG("nl_send_route(%N,op=%x)\n", e->net, op); bzero(&r->h, sizeof(r->h)); bzero(&r->r, sizeof(r->r)); @@ -1448,7 +1447,7 @@ nl_send_route(struct krt_proto *p, rte *e, int op, int dest, struct nexthop *nh) r->h.nlmsg_flags = op | NLM_F_REQUEST | NLM_F_ACK; r->r.rtm_family = p->af; - r->r.rtm_dst_len = net_pxlen(net->n.addr); + r->r.rtm_dst_len = net_pxlen(e->net); r->r.rtm_protocol = RTPROT_BIRD; r->r.rtm_scope = RT_SCOPE_NOWHERE; #ifdef HAVE_MPLS_KERNEL @@ -1460,7 +1459,7 @@ nl_send_route(struct krt_proto *p, rte *e, int op, int dest, struct nexthop *nh) * 2) Never use RTA_PRIORITY */ - u32 label = net_mpls(net->n.addr); + u32 label = net_mpls(e->net); nl_add_attr_mpls(&r->h, rsize, RTA_DST, 1, &label); r->r.rtm_scope = RT_SCOPE_UNIVERSE; r->r.rtm_type = RTN_UNICAST; @@ -1468,12 +1467,12 @@ nl_send_route(struct krt_proto *p, rte *e, int op, int dest, struct nexthop *nh) else #endif { - nl_add_attr_ipa(&r->h, rsize, RTA_DST, net_prefix(net->n.addr)); + nl_add_attr_ipa(&r->h, rsize, RTA_DST, net_prefix(e->net)); /* Add source address for IPv6 SADR routes */ - if (net->n.addr->type == NET_IP6_SADR) + if (e->net->type == NET_IP6_SADR) { - net_addr_ip6_sadr *a = (void *) &net->n.addr; + net_addr_ip6_sadr *a = (void *) &e->net; nl_add_attr_ip6(&r->h, rsize, RTA_SRC, a->src_prefix); r->r.rtm_src_len = a->src_pxlen; } @@ -1594,7 +1593,7 @@ nl_add_rte(struct krt_proto *p, rte *e) } static inline int -nl_delete_rte(struct krt_proto *p, rte *e) +nl_delete_rte(struct krt_proto *p, const rte *e) { int err = 0; @@ -1615,7 +1614,7 @@ nl_replace_rte(struct krt_proto *p, rte *e) void -krt_replace_rte(struct krt_proto *p, net *n UNUSED, rte *new, rte *old) +krt_replace_rte(struct krt_proto *p, const net_addr *n UNUSED, rte *new, const rte *old) { int err = 0; @@ -1654,7 +1653,7 @@ krt_replace_rte(struct krt_proto *p, net *n UNUSED, rte *new, rte *old) } static int -nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint priority, uint krt_type, uint rtm_family) +nl_mergable_route(struct nl_parse_state *s, const net_addr *net, struct krt_proto *p, uint priority, uint krt_type, uint rtm_family) { /* Route merging is used for IPv6 scans */ if (!s->scan || (rtm_family != AF_INET6)) @@ -1674,23 +1673,25 @@ nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint static void nl_announce_route(struct nl_parse_state *s) { - rte *e = rte_get_temp(s->attrs, s->proto->p.main_source); - e->net = s->net; + rte e0 = { + .attrs = s->attrs, + .net = s->net, + }; EA_LOCAL_LIST(2) ea = { - .l = { .count = 2, .next = e->attrs->eattrs }, + .l = { .count = 2, .next = e0.attrs->eattrs }, .a = { EA_LITERAL_EMBEDDED(&ea_krt_source, 0, s->krt_proto), EA_LITERAL_EMBEDDED(&ea_krt_metric, 0, s->krt_metric), }, }; - e->attrs->eattrs = &ea.l; + e0.attrs->eattrs = &ea.l; if (s->scan) - krt_got_route(s->proto, e, s->krt_src); + krt_got_route(s->proto, &e0, s->krt_src); else - krt_got_route_async(s->proto, e, s->new, s->krt_src); + krt_got_route_async(s->proto, &e0, s->new, s->krt_src); s->net = NULL; s->attrs = NULL; @@ -1840,16 +1841,14 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) krt_src = KRT_SRC_ALIEN; } - net_addr *n = &dst; + net_addr *net = &dst; if (p->p.net_type == NET_IP6_SADR) { - n = alloca(sizeof(net_addr_ip6_sadr)); - net_fill_ip6_sadr(n, net6_prefix(&dst), net6_pxlen(&dst), + net = alloca(sizeof(net_addr_ip6_sadr)); + net_fill_ip6_sadr(net, net6_prefix(&dst), net6_pxlen(&dst), net6_prefix(&src), net6_pxlen(&src)); } - net *net = net_get(p->p.main_channel->table, n); - if (s->net && !nl_mergable_route(s, net, p, priority, i->rtm_type, i->rtm_family)) nl_announce_route(s); @@ -1868,7 +1867,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) if (a[RTA_MULTIPATH]) { - struct nexthop *nh = nl_parse_multipath(s, p, n, a[RTA_MULTIPATH], i->rtm_family, krt_src); + struct nexthop *nh = nl_parse_multipath(s, p, net, a[RTA_MULTIPATH], i->rtm_family, krt_src); if (!nh) SKIP("strange RTA_MULTIPATH\n"); @@ -1882,7 +1881,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) ra->nh.iface = if_find_by_index(oif); if (!ra->nh.iface) { - log(L_ERR "KRT: Received route %N with unknown ifindex %u", net->n.addr, oif); + log(L_ERR "KRT: Received route %N with unknown ifindex %u", net, oif); return; } @@ -1909,8 +1908,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) (ra->nh.flags & RNF_ONLINK) ? NEF_ONLINK : 0); if (!nbr || (nbr->scope == SCOPE_HOST)) { - log(L_ERR "KRT: Received route %N with strange next-hop %I", net->n.addr, - ra->nh.gw); + log(L_ERR "KRT: Received route %N with strange next-hop %I", net, ra->nh.gw); return; } } @@ -1976,7 +1974,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) u32 metrics[KRT_METRICS_MAX]; if (nl_parse_metrics(a[RTA_METRICS], metrics, ARRAY_SIZE(metrics)) < 0) { - log(L_ERR "KRT: Received route %N with strange RTA_METRICS attribute", net->n.addr); + log(L_ERR "KRT: Received route %N with strange RTA_METRICS attribute", net); return; } @@ -1997,7 +1995,9 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) if (!s->net) { /* Store the new route */ - s->net = net; + s->net = lp_alloc(s->pool, net->length); + net_copy(s->net, net); + s->attrs = ra; s->proto = p; s->new = new; diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index b8e7670e..b94b05ae 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -257,14 +257,14 @@ static inline void krt_trace_in(struct krt_proto *p, rte *e, char *msg) { if (p->p.debug & D_PACKETS) - log(L_TRACE "%s: %N: %s", p->p.name, e->net->n.addr, msg); + log(L_TRACE "%s: %N: %s", p->p.name, e->net, msg); } static inline void krt_trace_in_rl(struct tbf *f, struct krt_proto *p, rte *e, char *msg) { if (p->p.debug & D_PACKETS) - log_rl(f, L_TRACE "%s: %N: %s", p->p.name, e->net->n.addr, msg); + log_rl(f, L_TRACE "%s: %N: %s", p->p.name, e->net, msg); } /* @@ -305,38 +305,39 @@ krt_uptodate(rte *a, rte *b) static void krt_learn_announce_update(struct krt_proto *p, rte *e) { - net *n = e->net; - rta *aa = rta_clone(e->attrs); - rte *ee = rte_get_temp(aa, p->p.main_source); - rte_update(&p->p, n->n.addr, ee); + rte e0 = { + .attrs = rta_clone(e->attrs), + .src = p->p.main_source, + }; + + rte_update(p->p.main_channel, e->net, &e0, p->p.main_source); } static void -krt_learn_announce_delete(struct krt_proto *p, net *n) +krt_learn_announce_delete(struct krt_proto *p, net_addr *n) { - rte_update(&p->p, n->n.addr, NULL); + rte_update(p->p.main_channel, n, NULL, p->p.main_source); } /* Called when alien route is discovered during scan */ static void krt_learn_scan(struct krt_proto *p, rte *e) { - net *n0 = e->net; - net *n = net_get(p->krt_table, n0->n.addr); - rte *m, **mm; + net *n = net_get(p->krt_table, e->net); + struct rte_storage *m, **mm; - e->attrs = rta_lookup(e->attrs); + struct rte_storage *ee = rte_store(e, n, p->krt_table); - for(mm=&n->routes; m = *mm; mm=&m->next) - if (krt_same_key(m, e)) + for(mm = &n->routes; m = *mm; mm = &m->next) + if (krt_same_key(&m->rte, e)) break; if (m) { - if (krt_uptodate(m, e)) + if (krt_uptodate(&m->rte, e)) { krt_trace_in_rl(&rl_alien, p, e, "[alien] seen"); - rte_free(e); - m->pflags |= KRT_REF_SEEN; + rte_free(ee); + m->rte.pflags |= KRT_REF_SEEN; } else { @@ -348,11 +349,12 @@ krt_learn_scan(struct krt_proto *p, rte *e) } else krt_trace_in(p, e, "[alien] created"); + if (!m) { - e->next = n->routes; - n->routes = e; - e->pflags |= KRT_REF_SEEN; + ee->next = n->routes; + n->routes = ee; + ee->rte.pflags |= KRT_REF_SEEN; } } @@ -368,7 +370,7 @@ krt_learn_prune(struct krt_proto *p) again: FIB_ITERATE_START(fib, &fit, net, n) { - rte *e, **ee, *best, **pbest, *old_best; + struct rte_storage *e, **ee, *best, **pbest, *old_best; /* * Note that old_best may be NULL even if there was an old best route in @@ -382,48 +384,48 @@ again: ee = &n->routes; while (e = *ee) { - if (e->pflags & KRT_REF_BEST) + if (e->rte.pflags & KRT_REF_BEST) old_best = e; - if (!(e->pflags & KRT_REF_SEEN)) + if (!(e->rte.pflags & KRT_REF_SEEN)) { *ee = e->next; rte_free(e); continue; } - if (!best || krt_metric(best) > krt_metric(e)) + if (!best || krt_metric(&best->rte) > krt_metric(&e->rte)) { best = e; pbest = ee; } - e->pflags &= ~(KRT_REF_SEEN | KRT_REF_BEST); + e->rte.pflags &= ~(KRT_REF_SEEN | KRT_REF_BEST); ee = &e->next; } if (!n->routes) { DBG("%I/%d: deleting\n", n->n.prefix, n->n.pxlen); if (old_best) - krt_learn_announce_delete(p, n); + krt_learn_announce_delete(p, n->n.addr); FIB_ITERATE_PUT(&fit); fib_delete(fib, n); goto again; } - best->pflags |= KRT_REF_BEST; + best->rte.pflags |= KRT_REF_BEST; *pbest = best->next; best->next = n->routes; n->routes = best; if ((best != old_best) || p->reload) { - DBG("%I/%d: announcing (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(best)); - krt_learn_announce_update(p, best); + DBG("%I/%d: announcing (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(&best->rte)); + krt_learn_announce_update(p, &best->rte); } else - DBG("%I/%d: uptodate (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(best)); + DBG("%I/%d: uptodate (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(&best->rte)); } FIB_ITERATE_END; @@ -433,27 +435,26 @@ again: static void krt_learn_async(struct krt_proto *p, rte *e, int new) { - net *n0 = e->net; - net *n = net_get(p->krt_table, n0->n.addr); - rte *g, **gg, *best, **bestp, *old_best; + net *n = net_get(p->krt_table, e->net); + struct rte_storage *g, **gg, *best, **bestp, *old_best; ASSERT(!e->attrs->cached); ea_set_attr_u32(&e->attrs->eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); - e->attrs = rta_lookup(e->attrs); + struct rte_storage *ee = rte_store(e, n, p->krt_table); old_best = n->routes; for(gg=&n->routes; g = *gg; gg = &g->next) - if (krt_same_key(g, e)) + if (krt_same_key(&g->rte, e)) break; if (new) { if (g) { - if (krt_uptodate(g, e)) + if (krt_uptodate(&g->rte, e)) { krt_trace_in(p, e, "[alien async] same"); - rte_free(e); + rte_free(ee); return; } krt_trace_in(p, e, "[alien async] updated"); @@ -463,38 +464,38 @@ krt_learn_async(struct krt_proto *p, rte *e, int new) else krt_trace_in(p, e, "[alien async] created"); - e->next = n->routes; - n->routes = e; + ee->next = n->routes; + n->routes = ee; } else if (!g) { krt_trace_in(p, e, "[alien async] delete failed"); - rte_free(e); + rte_free(ee); return; } else { krt_trace_in(p, e, "[alien async] removed"); *gg = g->next; - rte_free(e); + rte_free(ee); rte_free(g); } best = n->routes; bestp = &n->routes; for(gg=&n->routes; g=*gg; gg=&g->next) { - if (krt_metric(best) > krt_metric(g)) + if (krt_metric(&best->rte) > krt_metric(&g->rte)) { best = g; bestp = gg; } - g->pflags &= ~KRT_REF_BEST; + g->rte.pflags &= ~KRT_REF_BEST; } if (best) { - best->pflags |= KRT_REF_BEST; + best->rte.pflags |= KRT_REF_BEST; *bestp = best->next; best->next = n->routes; n->routes = best; @@ -504,9 +505,9 @@ krt_learn_async(struct krt_proto *p, rte *e, int new) { DBG("krt_learn_async: distributing change\n"); if (best) - krt_learn_announce_update(p, best); + krt_learn_announce_update(p, &best->rte); else - krt_learn_announce_delete(p, n); + krt_learn_announce_delete(p, n->n.addr); } } @@ -544,40 +545,53 @@ krt_dump(struct proto *P) static inline int krt_is_installed(struct krt_proto *p, net *n) { - return n->routes && bmap_test(&p->p.main_channel->export_map, n->routes->id); + return n->routes && bmap_test(&p->p.main_channel->export_map, n->routes->rte.id); } -static void -krt_flush_routes(struct krt_proto *p) +static uint +rte_feed_count(net *n) { - struct rtable *t = p->p.main_channel->table; + uint count = 0; + for (struct rte_storage *e = n->routes; e; e = e->next) + if (rte_is_valid(RTE_OR_NULL(e))) + count++; + return count; +} - KRT_TRACE(p, D_EVENTS, "Flushing kernel routes"); - FIB_WALK(&t->fib, net, n) +static void +rte_feed_obtain(net *n, rte **feed, uint count) +{ + uint i = 0; + for (struct rte_storage *e = n->routes; e; e = e->next) + if (rte_is_valid(RTE_OR_NULL(e))) { - if (krt_is_installed(p, n)) - { - /* FIXME: this does not work if gw is changed in export filter */ - krt_replace_rte(p, n, NULL, n->routes); - } + ASSERT_DIE(i < count); + feed[i++] = &e->rte; } - FIB_WALK_END; + ASSERT_DIE(i == count); } static struct rte * -krt_export_net(struct krt_proto *p, net *net, rte **rt_free) +krt_export_net(struct krt_proto *p, net *net) { struct channel *c = p->p.main_channel; const struct filter *filter = c->out_filter; - rte *rt; if (c->ra_mode == RA_MERGED) - return rt_export_merged(c, net, rt_free, krt_filter_lp, 1); + { + uint count = rte_feed_count(net); + if (!count) + return NULL; - rt = net->routes; - *rt_free = NULL; + rte **feed = alloca(count * sizeof(rte *)); + rte_feed_obtain(net, feed, count); + return rt_export_merged(c, feed, count, krt_filter_lp, 1); + } - if (!rte_is_valid(rt)) + static _Thread_local rte rt; + rt = net->routes->rte; + + if (!rte_is_valid(&rt)) return NULL; if (filter == FILTER_REJECT) @@ -593,13 +607,9 @@ krt_export_net(struct krt_proto *p, net *net, rte **rt_free) accept: - if (rt != net->routes) - *rt_free = rt; - return rt; + return &rt; reject: - if (rt != net->routes) - rte_free(rt); return NULL; } @@ -625,8 +635,7 @@ krt_same_dest(rte *k, rte *e) void krt_got_route(struct krt_proto *p, rte *e, s8 src) { - rte *new = NULL, *rt_free = NULL; - net *n = e->net; + rte *new = NULL; e->pflags = 0; #ifdef KRT_ALLOW_LEARN @@ -642,24 +651,25 @@ krt_got_route(struct krt_proto *p, rte *e, s8 src) if (KRT_CF->learn) krt_learn_scan(p, e); else - { - krt_trace_in_rl(&rl_alien, p, e, "[alien] ignored"); - rte_free(e); - } + krt_trace_in_rl(&rl_alien, p, e, "[alien] ignored"); return; } #endif /* The rest is for KRT_SRC_BIRD (or KRT_SRC_UNKNOWN) */ + /* Deleting all routes if flush is requested */ + if (p->flush_routes) + goto delete; /* We wait for the initial feed to have correct installed state */ if (!p->ready) goto ignore; - if (!krt_is_installed(p, n)) + net *net = net_find(p->p.main_channel->table, e->net); + if (!net || !krt_is_installed(p, net)) goto delete; - new = krt_export_net(p, n, &rt_free); + new = krt_export_net(p, net); /* Rejected by filters */ if (!new) @@ -692,20 +702,15 @@ ignore: update: krt_trace_in(p, new, "updating"); - krt_replace_rte(p, n, new, e); + krt_replace_rte(p, e->net, new, e); goto done; delete: krt_trace_in(p, e, "deleting"); - krt_replace_rte(p, n, NULL, e); + krt_replace_rte(p, e->net, NULL, e); goto done; done: - rte_free(e); - - if (rt_free) - rte_free(rt_free); - lp_flush(krt_filter_lp); } @@ -723,20 +728,16 @@ krt_prune(struct krt_proto *p) KRT_TRACE(p, D_EVENTS, "Pruning table %s", t->name); FIB_WALK(&t->fib, net, n) { - if (p->ready && krt_is_installed(p, n) && !bmap_test(&p->seen_map, n->routes->id)) + if (p->ready && krt_is_installed(p, n) && !bmap_test(&p->seen_map, n->routes->rte.id)) { - rte *rt_free = NULL; - rte *new = krt_export_net(p, n, &rt_free); + rte *new = krt_export_net(p, n); if (new) { krt_trace_in(p, new, "installing"); - krt_replace_rte(p, n, new, NULL); + krt_replace_rte(p, n->n.addr, new, NULL); } - if (rt_free) - rte_free(rt_free); - lp_flush(krt_filter_lp); } } @@ -751,10 +752,20 @@ krt_prune(struct krt_proto *p) p->initialized = 1; } +static void +krt_flush_routes(struct krt_proto *p) +{ + KRT_TRACE(p, D_EVENTS, "Flushing kernel routes"); + p->flush_routes = 1; + krt_init_scan(p); + krt_do_scan(p); + /* No prune! */ + p->flush_routes = 0; +} + void krt_got_route_async(struct krt_proto *p, rte *e, int new, s8 src) { - net *net = e->net; e->pflags = 0; switch (src) @@ -767,7 +778,7 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new, s8 src) if (new) { krt_trace_in(p, e, "[redirect] deleting"); - krt_replace_rte(p, net, NULL, e); + krt_replace_rte(p, e->net, NULL, e); } /* If !new, it is probably echo of our deletion */ break; @@ -781,7 +792,6 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new, s8 src) } #endif } - rte_free(e); } /* @@ -888,10 +898,9 @@ krt_scan_timer_kick(struct krt_proto *p) */ static int -krt_preexport(struct proto *P, rte *e) +krt_preexport(struct channel *c, rte *e) { - // struct krt_proto *p = (struct krt_proto *) P; - if (e->src->proto == P) + if (e->src->proto == c->proto) return -1; if (!krt_capable(e)) @@ -901,8 +910,8 @@ krt_preexport(struct proto *P, rte *e) } static void -krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net, - rte *new, rte *old) +krt_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *net, + rte *new, const rte *old) { struct krt_proto *p = (struct krt_proto *) P; diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index 04b04162..69fc9aa1 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -70,6 +70,7 @@ struct krt_proto { byte ready; /* Initial feed has been finished */ byte initialized; /* First scan has been finished */ byte reload; /* Next scan is doing reload */ + byte flush_routes; /* Scanning to flush */ }; extern pool *krt_pool; @@ -147,7 +148,7 @@ void krt_sys_copy_config(struct krt_config *, struct krt_config *); int krt_capable(rte *e); void krt_do_scan(struct krt_proto *); -void krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old); +void krt_replace_rte(struct krt_proto *p, const net_addr *n, rte *new, const rte *old); int krt_sys_get_attr(const eattr *a, byte *buf, int buflen); |