summaryrefslogtreecommitdiffstats
path: root/ripngd/ripng_interface.c
diff options
context:
space:
mode:
authorFeng Lu <lu.feng@6wind.com>2015-05-22 11:39:53 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-06-08 21:16:23 +0200
commitc880b6367ec69eeae5ad7ed7527d0cf567918a10 (patch)
treee0223eb96e2a5864c23f309b6813046dcb573ddc /ripngd/ripng_interface.c
parentisisd: always print adj->sysid (clang 3.6 warning) (diff)
downloadfrr-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.c37
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;