diff options
author | Feng Lu <lu.feng@6wind.com> | 2015-05-22 11:39:53 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-06-08 21:16:23 +0200 |
commit | c880b6367ec69eeae5ad7ed7527d0cf567918a10 (patch) | |
tree | e0223eb96e2a5864c23f309b6813046dcb573ddc /ripngd/ripng_interface.c | |
parent | isisd: always print adj->sysid (clang 3.6 warning) (diff) | |
download | frr-c880b6367ec69eeae5ad7ed7527d0cf567918a10.tar.xz frr-c880b6367ec69eeae5ad7ed7527d0cf567918a10.zip |
ripngd: add ECMP support
* Each node in the routing table is changed into a list, holding
the multiple equal-cost paths.
* If one of the multiple entries gets less-preferred (greater
metric or greater distance), it will be directly deleted instead
of starting a garbage-collection timer for it.
The garbage-collection timer is started only when the last entry
in the list gets INFINITY.
* Some new functions are used to maintain the ECMP list. And hence
ripng_route_process(), ripng_redistribute_add() and ripng_timeout()
are significantly simplified.
* ripng_zebra_ipv6_add() and ripng_zebra_ipv6_delete() now can share
the common code. The common part is moved to ripng_zebra_ipv6_send().
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Vincent Jardin <vincent.jardin@6wind.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ripngd/ripng_interface.c')
-rw-r--r-- | ripngd/ripng_interface.c | 37 |
1 files changed, 7 insertions, 30 deletions
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index 15ce0a238..0061c0e80 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -164,38 +164,15 @@ ripng_if_down (struct interface *ifp) struct route_node *rp; struct ripng_info *rinfo; struct ripng_interface *ri; + struct list *list = NULL; + struct listnode *listnode = NULL, *nextnode = NULL; if (ripng) - { - for (rp = route_top (ripng->table); rp; rp = route_next (rp)) - if ((rinfo = rp->info) != NULL) - { - /* Routes got through this interface. */ - if (rinfo->ifindex == ifp->ifindex - && rinfo->type == ZEBRA_ROUTE_RIPNG - && rinfo->sub_type == RIPNG_ROUTE_RTE) - { - ripng_zebra_ipv6_delete ((struct prefix_ipv6 *) &rp->p, - &rinfo->nexthop, - rinfo->ifindex); - - ripng_redistribute_delete (rinfo->type, rinfo->sub_type, - (struct prefix_ipv6 *)&rp->p, - rinfo->ifindex); - } - else - { - /* All redistributed routes got through this interface, - * but the static and system ones are kept. */ - if ((rinfo->ifindex == ifp->ifindex) && - (rinfo->type != ZEBRA_ROUTE_STATIC) && - (rinfo->type != ZEBRA_ROUTE_SYSTEM)) - ripng_redistribute_delete (rinfo->type, rinfo->sub_type, - (struct prefix_ipv6 *) &rp->p, - rinfo->ifindex); - } - } - } + for (rp = route_top (ripng->table); rp; rp = route_next (rp)) + if ((list = rp->info) != NULL) + for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo)) + if (rinfo->ifindex == ifp->ifindex) + ripng_ecmp_delete (rinfo); ri = ifp->info; |