From: Donald Sharp Date: Fri, 12 Jun 2015 14:59:11 +0000 (-0700) Subject: BGP: Restart the BGP FSM if update source fails. X-Git-Tag: frr-2.0-rc1~1324 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=490674967fc964c992d06dd8e104a359483768fd;p=matthieu%2Ffrr.git BGP: Restart the BGP FSM if update source fails. For IPv6, update source sometimes fails at the first attempt. If we continue ignoring the error, some sessions will not come up. If instead we check for the error and return connect_error, the FSM will reset its state and try again till the update source bind succeeds and the session will come up. This patch adds checking for the result of bind and update_source to return connect_error or success. The rest of the code handles the situation correctly after that. Signed-off-by: Dinesh G Dutt Reviewed-by: Donald Sharp Reviewed-by: Vivek Venkataraman --- diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index c65119489c..c8d20e83f8 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -416,28 +416,31 @@ bgp_update_address (struct interface *ifp, const union sockunion *dst, } /* Update source selection. */ -static void +static int bgp_update_source (struct peer *peer) { struct interface *ifp; union sockunion addr; + int ret = 0; /* Source is specified with interface name. */ if (peer->update_if) { ifp = if_lookup_by_name (peer->update_if); if (! ifp) - return; + return -1; if (bgp_update_address (ifp, &peer->su, &addr)) - return; + return -1; - sockunion_bind (peer->fd, &addr, 0, &addr); + ret = sockunion_bind (peer->fd, &addr, 0, &addr); } /* Source is specified with IP address. */ if (peer->update_source) - sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source); + ret = sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source); + + return ret; } #define DATAPLANE_MARK 254 /* main table ID */ @@ -492,7 +495,10 @@ bgp_connect (struct peer *peer) bgp_bind (peer); /* Update source bind. */ - bgp_update_source (peer); + if (bgp_update_source (peer) < 0) + { + return connect_error; + } #ifdef HAVE_IPV6 if (peer->conf_if || peer->ifname)