I have not yet checked how other implementations handle the
situation where an update with a as-path loop hides the fact
that the neighbor just lost a path.
But I made a quick patch if anyone feel like testing.
The black-hole condition does not appear anymore when
I test.
Be gentle, I only browsed through the code while on
the underground to and from work.
/Tony
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.228
diff -r1.228 rde.c
922,927d921
< /* aspath needs to be loop free nota bene this is not a hard error */
< if (peer->conf.ebgp && !aspath_loopfree(asp->aspath, conf->as)) {
< error = 0;
< goto done;
< }
<
957,959c951,961
< if (peer->conf.softreconfig_in)
< path_update(peer, asp, &prefix, prefixlen, F_ORIGINAL);
<
---
> if (peer->conf.softreconfig_in) {
> /* handle an update with loop as a withdraw */
> if (peer->conf.ebgp && !aspath_loopfree(asp->aspath,
> conf->as))
> prefix_remove(peer, &prefix, prefixlen,
> F_ORIGINAL);
> else
> path_update(peer, asp, &prefix, prefixlen,
> F_ORIGINAL);
>
> }
980,983c982,993
< rde_update_log("update", peer, &fasp->nexthop->exit_nexthop,
< &prefix, prefixlen);
< path_update(peer, fasp, &prefix, prefixlen, F_LOCAL);
<
---
> rde_update_log("update", peer,
> &fasp->nexthop->exit_nexthop,&prefix,
> prefixlen);
> /* handle an update with loop as a withdraw */
> if (peer->conf.ebgp && !aspath_loopfree(asp->aspath,
> conf->as))
> prefix_remove(peer, &prefix, prefixlen,
> F_LOCAL);
> else
> path_update(peer, fasp, &prefix, prefixlen,
> F_LOCAL);
>
1050,1053c1060,1069
< if (peer->conf.softreconfig_in)
< path_update(peer, asp, &prefix,
< prefixlen, F_ORIGINAL);
<
---
> if (peer->conf.softreconfig_in) {
> /* handle an update with loop as a withdraw */
> if (peer->conf.ebgp &&
>
> !aspath_loopfree(asp->aspath,conf->as))
> prefix_remove(peer, &prefix,
> prefixlen,F_ORIGINAL);
> else
> path_update(peer, asp, &prefix,
> prefixlen, F_ORIGINAL);
> }
1078,1080c1094,1102
< &prefix, prefixlen);
< path_update(peer, fasp, &prefix, prefixlen,
< F_LOCAL);
---
> &prefix, prefixlen);
> /* handle an update with loop as a withdraw */
> if (peer->conf.ebgp &&
> !aspath_loopfree(asp->aspath,conf->as))
> prefix_remove(peer, &prefix,
> prefixlen,F_LOCAL);
> else
> path_update(peer, fasp, &prefix,
> prefixlen,F_LOCAL);