diff options
Diffstat (limited to 'proto/rip/rip.c')
-rw-r--r-- | proto/rip/rip.c | 107 |
1 files changed, 57 insertions, 50 deletions
diff --git a/proto/rip/rip.c b/proto/rip/rip.c index c85fd69b..22023279 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -92,15 +92,6 @@ static void rip_trigger_update(struct rip_proto *p); * RIP routes */ -static void -rip_init_entry(struct fib_node *fn) -{ - // struct rip_entry *en = (void) *fn; - - const uint offset = OFFSETOF(struct rip_entry, routes); - memset((byte *)fn + offset, 0, sizeof(struct rip_entry) - offset); -} - static struct rip_rte * rip_add_rte(struct rip_proto *p, struct rip_rte **rp, struct rip_rte *src) { @@ -152,7 +143,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) if (rt) { /* Update */ - net *n = net_get(p->p.table, en->n.prefix, en->n.pxlen); + net *n = net_get(p->p.main_channel->table, en->n.addr); rta a0 = { .src = p->p.main_source, @@ -221,7 +212,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) else { /* Withdraw */ - net *n = net_find(p->p.table, en->n.prefix, en->n.pxlen); + net *n = net_find(p->p.main_channel->table, en->n.addr); rte_update(&p->p, n, NULL); } } @@ -229,8 +220,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) /** * rip_update_rte - enter a route update to RIP routing table * @p: RIP instance - * @prefix: network prefix - * @pxlen: network prefix length + * @addr: network address * @new: a &rip_rte representing the new route * * The function is called by the RIP packet processing code whenever it receives @@ -240,9 +230,9 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) * rip_withdraw_rte() should be called instead of rip_update_rte(). */ void -rip_update_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_rte *new) +rip_update_rte(struct rip_proto *p, net_addr *n, struct rip_rte *new) { - struct rip_entry *en = fib_get(&p->rtable, prefix, pxlen); + struct rip_entry *en = fib_get(&p->rtable, n); struct rip_rte *rt, **rp; int changed = 0; @@ -282,8 +272,7 @@ rip_update_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_rte * /** * rip_withdraw_rte - enter a route withdraw to RIP routing table * @p: RIP instance - * @prefix: network prefix - * @pxlen: network prefix length + * @addr: network address * @from: a &rip_neighbor propagating the withdraw * * The function is called by the RIP packet processing code whenever it receives @@ -291,9 +280,9 @@ rip_update_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_rte * * removed. Eventually, the change is also propagated by rip_announce_rte(). */ void -rip_withdraw_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_neighbor *from) +rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from) { - struct rip_entry *en = fib_find(&p->rtable, prefix, pxlen); + struct rip_entry *en = fib_find(&p->rtable, n); struct rip_rte *rt, **rp; if (!en) @@ -320,7 +309,7 @@ rip_withdraw_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_nei * it into our data structures. */ static void -rip_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net, struct rte *new, +rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, struct rte *new, struct rte *old UNUSED, struct ea_list *attrs) { struct rip_proto *p = (struct rip_proto *) P; @@ -335,15 +324,15 @@ rip_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net, if (rt_metric > p->infinity) { - log(L_WARN "%s: Invalid rip_metric value %u for route %I/%d", - p->p.name, rt_metric, net->n.prefix, net->n.pxlen); + log(L_WARN "%s: Invalid rip_metric value %u for route %N", + p->p.name, rt_metric, net->n.addr); rt_metric = p->infinity; } if (rt_tag > 0xffff) { - log(L_WARN "%s: Invalid rip_tag value %u for route %I/%d", - p->p.name, rt_tag, net->n.prefix, net->n.pxlen); + log(L_WARN "%s: Invalid rip_tag value %u for route %N", + p->p.name, rt_tag, net->n.addr); rt_metric = p->infinity; rt_tag = 0; } @@ -355,7 +344,7 @@ rip_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net, * collection. */ - en = fib_get(&p->rtable, &net->n.prefix, net->n.pxlen); + en = fib_get(&p->rtable, net->n.addr); old_metric = en->valid ? en->metric : -1; @@ -369,7 +358,7 @@ rip_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net, else { /* Withdraw */ - en = fib_find(&p->rtable, &net->n.prefix, net->n.pxlen); + en = fib_find(&p->rtable, net->n.addr); if (!en || en->valid != RIP_ENTRY_VALID) return; @@ -834,9 +823,8 @@ rip_timer(timer *t) FIB_ITERATE_INIT(&fit, &p->rtable); loop: - FIB_ITERATE_START(&p->rtable, &fit, node) + FIB_ITERATE_START(&p->rtable, &fit, struct rip_entry, en) { - struct rip_entry *en = (struct rip_entry *) node; struct rip_rte *rt, **rp; int changed = 0; @@ -863,7 +851,7 @@ rip_timer(timer *t) * rip_rt_notify() -> p->rtable change, invalidating hidden variables. */ - FIB_ITERATE_PUT_NEXT(&fit, &p->rtable, node); + FIB_ITERATE_PUT_NEXT(&fit, &p->rtable); rip_announce_rte(p, en); goto loop; } @@ -875,7 +863,7 @@ rip_timer(timer *t) if (expires <= now) { - // TRACE(D_EVENTS, "entry is too old: %I/%d", en->n.prefix, en->n.pxlen); + // TRACE(D_EVENTS, "entry is too old: %N", en->n.addr); en->valid = 0; } else @@ -885,12 +873,12 @@ rip_timer(timer *t) /* Remove empty nodes */ if (!en->valid && !en->routes) { - FIB_ITERATE_PUT(&fit, node); - fib_delete(&p->rtable, node); + FIB_ITERATE_PUT(&fit); + fib_delete(&p->rtable, en); goto loop; } } - FIB_ITERATE_END(node); + FIB_ITERATE_END; p->rt_reload = 0; @@ -1039,19 +1027,17 @@ rip_import_control(struct proto *P, struct rte **rt, struct ea_list **attrs, str return 0; } -static int -rip_reload_routes(struct proto *P) +static void +rip_reload_routes(struct channel *C) { - struct rip_proto *p = (struct rip_proto *) P; + struct rip_proto *p = (struct rip_proto *) C->proto; if (p->rt_reload) - return 1; + return; TRACE(D_EVENTS, "Scheduling route reload"); p->rt_reload = 1; rip_kick_timer(p); - - return 1; } static struct ea_list * @@ -1082,12 +1068,23 @@ rip_rte_same(struct rte *new, struct rte *old) } +static void +rip_postconfig(struct proto_config *CF) +{ + // struct rip_config *cf = (void *) CF; + + /* Define default channel */ + if (EMPTY_LIST(CF->channels)) + channel_config_new(NULL, CF->net_type, CF); +} + static struct proto * -rip_init(struct proto_config *cfg) +rip_init(struct proto_config *CF) { - struct proto *P = proto_new(cfg, sizeof(struct rip_proto)); + struct proto *P = proto_new(CF); + + P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF)); - P->accept_ra_types = RA_OPTIMAL; P->if_notify = rip_if_notify; P->rt_notify = rip_rt_notify; P->neigh_notify = rip_neigh_notify; @@ -1108,10 +1105,12 @@ rip_start(struct proto *P) struct rip_config *cf = (void *) (P->cf); init_list(&p->iface_list); - fib_init(&p->rtable, P->pool, sizeof(struct rip_entry), 0, rip_init_entry); + fib_init(&p->rtable, P->pool, cf->rip2 ? NET_IP4 : NET_IP6, + sizeof(struct rip_entry), OFFSETOF(struct rip_entry, n), 0, NULL); p->rte_slab = sl_new(P->pool, sizeof(struct rip_rte)); p->timer = tm_new_set(P->pool, rip_timer, p, 0, 0); + p->rip2 = cf->rip2; p->ecmp = cf->ecmp; p->infinity = cf->infinity; p->triggered = 0; @@ -1125,18 +1124,24 @@ rip_start(struct proto *P) } static int -rip_reconfigure(struct proto *P, struct proto_config *c) +rip_reconfigure(struct proto *P, struct proto_config *CF) { struct rip_proto *p = (void *) P; - struct rip_config *new = (void *) c; + struct rip_config *new = (void *) CF; // struct rip_config *old = (void *) (P->cf); + if (new->rip2 != p->rip2) + return 0; + if (new->infinity != p->infinity) return 0; + if (!proto_configure_channel(P, &P->main_channel, proto_cf_main_channel(CF))) + return 0; + TRACE(D_EVENTS, "Reconfiguring"); - p->p.cf = c; + p->p.cf = CF; p->ecmp = new->ecmp; rip_reconfigure_ifaces(p, new); @@ -1254,11 +1259,10 @@ rip_dump(struct proto *P) int i; i = 0; - FIB_WALK(&p->rtable, e) + FIB_WALK(&p->rtable, struct rip_entry, en) { - struct rip_entry *en = (struct rip_entry *) e; - debug("RIP: entry #%d: %I/%d via %I dev %s valid %d metric %d age %d s\n", - i++, en->n.prefix, en->n.pxlen, en->next_hop, en->iface->name, + debug("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %d s\n", + i++, en->n.addr, en->next_hop, en->iface->name, en->valid, en->metric, now - en->changed); } FIB_WALK_END; @@ -1278,7 +1282,10 @@ struct protocol proto_rip = { .template = "rip%d", .attr_class = EAP_RIP, .preference = DEF_PREF_RIP, + .channel_mask = NB_IP, + .proto_size = sizeof(struct rip_proto), .config_size = sizeof(struct rip_config), + .postconfig = rip_postconfig, .init = rip_init, .dump = rip_dump, .start = rip_start, |