]> git.puffer.fish Git - matthieu/frr.git/commitdiff
BGP: Restart the BGP FSM if update source fails.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 12 Jun 2015 14:59:11 +0000 (07:59 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 12 Jun 2015 14:59:11 +0000 (07:59 -0700)
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 <ddutt@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com>
bgpd/bgp_network.c

index c65119489c50ed9e0612b90ca5b625664f8970cd..c8d20e83f8045b6849e3fa7457b826d66eb3191f 100644 (file)
@@ -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)