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>
diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h
index ab06d81..75c5dfa 100644
--- a/ripngd/ripngd.h
+++ b/ripngd/ripngd.h
@@ -389,12 +389,8 @@
 extern void ripng_distribute_update_interface (struct interface *);
 extern void ripng_if_rmap_update_interface (struct interface *);
 
-extern void ripng_zebra_ipv6_add (struct prefix_ipv6 *p,
-                                  struct in6_addr *nexthop,
-                                  unsigned int ifindex, u_char metric);
-extern void ripng_zebra_ipv6_delete (struct prefix_ipv6 *p,
-                                     struct in6_addr *nexthop,
-                                     unsigned int ifindex);
+extern void ripng_zebra_ipv6_add (struct route_node *);
+extern void ripng_zebra_ipv6_delete (struct route_node *);
 
 extern void ripng_redistribute_clean (void);
 extern int ripng_redistribute_check (int);
@@ -418,4 +414,8 @@
 
 extern int ripng_network_write (struct vty *, int);
 
+extern struct ripng_info *ripng_ecmp_add (struct ripng_info *);
+extern struct ripng_info *ripng_ecmp_replace (struct ripng_info *);
+extern struct ripng_info *ripng_ecmp_delete (struct ripng_info *);
+
 #endif /* _ZEBRA_RIPNG_RIPNGD_H */