Commits

Feng Lu authored and David Lamparter committed e97c31aafc0
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>
No tags

ripngd/ripng_interface.c

Modified
156 156
157 157 return count;
158 158 }
159 159
160 160 static int
161 161 ripng_if_down (struct interface *ifp)
162 162 {
163 163 struct route_node *rp;
164 164 struct ripng_info *rinfo;
165 165 struct ripng_interface *ri;
166 + struct list *list = NULL;
167 + struct listnode *listnode = NULL, *nextnode = NULL;
166 168
167 169 if (ripng)
168 - {
169 - for (rp = route_top (ripng->table); rp; rp = route_next (rp))
170 - if ((rinfo = rp->info) != NULL)
171 - {
172 - /* Routes got through this interface. */
173 - if (rinfo->ifindex == ifp->ifindex
174 - && rinfo->type == ZEBRA_ROUTE_RIPNG
175 - && rinfo->sub_type == RIPNG_ROUTE_RTE)
176 - {
177 - ripng_zebra_ipv6_delete ((struct prefix_ipv6 *) &rp->p,
178 - &rinfo->nexthop,
179 - rinfo->ifindex);
180 -
181 - ripng_redistribute_delete (rinfo->type, rinfo->sub_type,
182 - (struct prefix_ipv6 *)&rp->p,
183 - rinfo->ifindex);
184 - }
185 - else
186 - {
187 - /* All redistributed routes got through this interface,
188 - * but the static and system ones are kept. */
189 - if ((rinfo->ifindex == ifp->ifindex) &&
190 - (rinfo->type != ZEBRA_ROUTE_STATIC) &&
191 - (rinfo->type != ZEBRA_ROUTE_SYSTEM))
192 - ripng_redistribute_delete (rinfo->type, rinfo->sub_type,
193 - (struct prefix_ipv6 *) &rp->p,
194 - rinfo->ifindex);
195 - }
196 - }
197 - }
170 + for (rp = route_top (ripng->table); rp; rp = route_next (rp))
171 + if ((list = rp->info) != NULL)
172 + for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo))
173 + if (rinfo->ifindex == ifp->ifindex)
174 + ripng_ecmp_delete (rinfo);
198 175
199 176 ri = ifp->info;
200 177
201 178 if (ri->running)
202 179 {
203 180 if (IS_RIPNG_DEBUG_EVENT)
204 181 zlog_debug ("turn off %s", ifp->name);
205 182
206 183 /* Leave from multicast group. */
207 184 ripng_multicast_leave (ifp);

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut