On Mon, Mar 06, 2017 at 07:41:44PM +0200, Lennert Buytenhek wrote: > Hi! > > bgp_init() in proto/bgp/bgp.c does: > > P->accept_ra_types = c->secondary ? RA_ACCEPTED : RA_OPTIMAL; > > and then bgp_rx_open() in proto/bgp/packets.c does: > > if (p->add_path_tx) > p->p.accept_ra_types = RA_ANY; > > As bgp_init() seems to only be called at configuration time, this > means that if you have add path tx, and you have a peer that advertises > rx add path and then reconnects without advertising rx add path, you > will still have RA_ANY set on the sending side and not have the correct > behavior of only sending the optimal route. (This is easy to verify.) > > Not entirely sure how you'd want to fix this, but perhaps replicating > the RA_ACCEPTED / RA_OPTIONAL assignment in bgp_rx_open() (or just > moving it there) would do the trick?
In other words, something like this? (I didn't trace all the code paths, but I'm guessing it should be safe to remove the ->accept_ra_types assignment from bgp_init() based on the fact that we are overriding it in bgp_rx_open() and expecting that to do the trick for the add_path_tx case -- if that's not sufficient then it's not safe to do that reassignment from there to begin with.) diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index d100b7d..a566d11 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1039,6 +1039,8 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len) if (p->add_path_tx) p->p.accept_ra_types = RA_ANY; + else + p->p.accept_ra_types = p->cf->secondary ? RA_ACCEPTED : RA_OPTIMAL; DBG("BGP: Hold timer set to %d, keepalive to %d, AS to %d, ID to %x, AS4 session to %d\n", conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, p->as4_session);