#ifdef CONFIG_RIP
/* lastmod is used internally by RIP as the last time
when the route was received. */
- if ((src->proto == &proto_rip) ||
- (src->proto == &proto_ripng))
- if (src->proto->proto == &proto_rip)
++ if ((src->proto->proto == &proto_rip) ||
++ (src->proto->proto == &proto_ripng))
old->lastmod = now;
#endif
return;
rt_next_hop_update(tab);
if (tab->gc_scheduled)
- rt_prune_nets(tab);
+ {
+ rt_prune_nets(tab);
+ rt_prune_sources(); // FIXME this should be moved to independent event
+ }
}
+/**
+ * rt_addrsize - returns (host format) size of address of given type
+ * @addr_type: address type
+ *
+ * Returns sizeof() appropriate structure or sizeof(ip_addr) if
+ * address type is unknown
+ *
+ */
+int
+rt_addrsize(int addr_type)
+{
+ switch (addr_type)
+ {
+#ifdef MPLS_VPN
+ case RT_VPN4:
+ return sizeof(vpn4_addr);
+ case RT_VPN6:
+ return sizeof(vpn6_addr);
+#endif
+ case RT_IPV4:
+ // XXXX
+ return sizeof(ip6_addr);
+ case RT_IPV6:
+ return sizeof(ip6_addr);
+ }
+
+ return sizeof(ip_addr);
+}
+
+
+/**
+ * rt_setup - initialize routing table
+ *
+ * This function is called to set up rtable (hooks, lists, fib, ..)
+ */
void
rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
{
void
rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll)
{
- rta_apply_hostentry(a, rt_find_hostentry(tab, *gw, *ll, dep));
+ if (tab->addr_type != RT_IP)
+ return;
+
+ rta_apply_hostentry(a, rt_get_hostentry(tab, *gw, *ll, dep));
}
+
/*
* CLI commands
*/
ea_merge(t, tmpa);
ea_sort(tmpa);
}
- if (a->proto->proto->get_route_info)
- a->proto->proto->get_route_info(e, info, tmpa);
+ if (get_route_info)
+ get_route_info(e, info, tmpa);
else
bsprintf(info, " (%d)", e->pref);
- cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", prefix, via, a->proto->name,
- cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", ia, via, a->src->proto->name,
++ cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", prefix, via, a->src->proto->name,
tm, from, primary ? (sync_error ? " !" : " *") : "", info);
for (nh = a->nexthops; nh; nh = nh->next)
cli_printf(c, -1007, "\tvia %I on %s weight %d", nh->gw, nh->iface->name, nh->weight + 1);
while (!EMPTY_LIST(buck->prefixes) && remains >= (1+sizeof(ip_addr)))
{
struct bgp_prefix *px = SKIP_BACK(struct bgp_prefix, bucket_node, HEAD(buck->prefixes));
- DBG("\tDequeued route %I/%d\n", px->n.prefix, px->n.pxlen);
+ DBG("\tDequeued route %F\n", &px->n);
+
+ if (p->add_path_tx)
+ {
+ put_u32(w, px->path_id);
+ w += 4;
+ }
+
*w++ = px->n.pxlen;
bytes = (px->n.pxlen + 7) / 8;
- a = px->n.prefix;
+ a = *FPREFIX_IP(&px->n);
ipa_hton(a);
memcpy(w, &a, bytes);
w += bytes;
while (!EMPTY_LIST(buck->prefixes))
{
struct bgp_prefix *px = SKIP_BACK(struct bgp_prefix, bucket_node, HEAD(buck->prefixes));
- log(L_ERR "%s: - route %I/%d skipped", p->p.name, px->n.prefix, px->n.pxlen);
+ log(L_ERR "%s: - route %F skipped", p->p.name, &px->n);
rem_node(&px->bucket_node);
- fib_delete(&p->prefix_fib, px);
+ bgp_free_prefix(p, px);
+ // fib_delete(&p->prefix_fib, px);
}
}
static struct proto *
ospf_init(struct proto_config *c)
{
+ struct ospf_config *oc = (struct ospf_config *) c;
struct proto *p = proto_new(c, sizeof(struct proto_ospf));
- p->make_tmp_attrs = ospf_make_tmp_attrs;
- p->store_tmp_attrs = ospf_store_tmp_attrs;
- p->import_control = ospf_import_control;
- p->reload_routes = ospf_reload_routes;
p->accept_ra_types = RA_OPTIMAL;
p->rt_notify = ospf_rt_notify;
p->if_notify = ospf_if_notify;
- p->ifa_notify = ospf_ifa_notify;
+ p->ifa_notify = oc->ospf2 ? ospf_ifa_notify2 : ospf_ifa_notify3;
+ p->import_control = ospf_import_control;
+ p->reload_routes = ospf_reload_routes;
+ p->make_tmp_attrs = ospf_make_tmp_attrs;
+ p->store_tmp_attrs = ospf_store_tmp_attrs;
p->rte_better = ospf_rte_better;
p->rte_same = ospf_rte_same;
nf->old_rta = NULL;
net *ne = net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
- rte_update(p->table, ne, p, p, NULL);
+ rte_update(p, ne, NULL);
}
- /* Remove unused rt entry. Entries with fn.x0 == 1 are persistent. */
- if (!nf->n.type && !nf->fn.x0 && !nf->fn.x1)
+ /* Remove unused rt entry. Entries with any flags are persistent. */
+ if (!nf->n.type && !nf->fn.flags)
{
FIB_ITERATE_PUT(&fit, nftmp);
fib_delete(fib, nftmp);
return;
}
- A.iface = neighbor->iface;
- if (!(rif = neighbor->data)) {
- rif = neighbor->data = find_interface(p, A.iface);
+
+ TRACE(D_PACKETS, "Received %I/%d metric %d from %I",
+ prefix, pxlen, metric, from);
+
+ rta A = {
- .proto = p,
++ .src= p->main_source,
+ .source = RTS_RIP,
+ .scope = SCOPE_UNIVERSE,
+ .cast = RTC_UNICAST,
+ .dest = RTD_ROUTER,
+ .gw = gw,
+ .from = from,
+ .iface = neigh->iface
+ };
+
+ if (rip_is_old(p)) pxlen += 96; // XXXX: Hack
+ net *n = net_get(p->table, prefix, pxlen);
+ rta *a = rta_lookup(&A);
+ rte *r = rte_get_temp(a);
+
+ if (!(rif = neigh->data)) {
+ rif = neigh->data = find_interface(p, A.iface);
}
if (!rif)
bug("Route packet using unknown interface? No.");
return;
DBG("Installing static route %I/%d, rtd=%d\n", r->net, r->masklen, r->dest);
- bzero(&a, sizeof(a));
- a.src = p->main_source;
- a.source = (r->dest == RTD_DEVICE) ? RTS_STATIC_DEVICE : RTS_STATIC;
- a.scope = SCOPE_UNIVERSE;
- a.cast = RTC_UNICAST;
- a.dest = r->dest;
- a.gw = r->via;
- a.iface = ifa;
+
+ rta a = {
- .proto = p,
++ .src = p->main_source;
+ .source = (r->dest == RTD_DEVICE) ? RTS_STATIC_DEVICE : RTS_STATIC,
+ .scope = SCOPE_UNIVERSE,
+ .cast = RTC_UNICAST,
+ .dest = r->dest,
+ .gw = r->via,
+ .iface = ifa
+ };
if (r->dest == RTD_MULTIPATH)
{
if (r->dest == RTDX_RECURSIVE)
rta_set_recursive_next_hop(p->table, &a, p_igp_table(p), &r->via, &r->via);
- aa = rta_lookup(&a);
- n = net_get(p->table, r->net, r->masklen);
- e = rte_get_temp(aa);
+ // int pxlen = r->masklen + (ipa_is_ip4(r->net) ? 96 : 0); // XXXX: Hack
+ net *n = net_get(p->table, r->net, r->masklen);
+ rta *aa = rta_lookup(&a);
+ rte *e = rte_get_temp(aa);
e->net = n;
e->pflags = 0;
- rte_update(p->table, n, p, p, e);
+ rte_update(p, n, e);
r->installed = 1;
}
return;
DBG("Removing static route %I/%d\n", r->net, r->masklen);
- n = net_find(p->table, r->net, r->masklen);
+
+ // int pxlen = r->masklen + (ipa_is_ip4(r->net) ? 96 : 0); // XXXX: Hack
+ net *n = net_find(p->table, r->net, r->masklen);
- if (n)
- rte_update(p->table, n, p, p, NULL);
+ rte_update(p, n, NULL);
r->installed = 0;
}
src = KRT_SRC_ALIEN;
}
- net *net = net_get(p->p.table, dst, i->rtm_dst_len);
+ int pxlen = i->rtm_dst_len + (ipv4 ? 96 : 0); // XXXX: Hack
+ net *net = net_get(p->p.table, dst, pxlen);
rta ra = {
- .proto = &p->p,
+ .src= p->p.main_source,
.source = RTS_INHERIT,
.scope = SCOPE_UNIVERSE,
.cast = RTC_UNICAST
static void
krt_learn_announce_delete(struct krt_proto *p, net *n)
{
- n = net_find(p->p.table, n->n.prefix, n->n.pxlen);
+ n = fib_find(&p->p.table->fib, FPREFIX(&n->n), n->n.pxlen);
- if (n)
- rte_update(p->p.table, n, &p->p, &p->p, NULL);
+ rte_update(&p->p, n, NULL);
}
/* Called when alien route is discovered during scan */