Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Oct 2003 15:35:30 +0400 (MSD)
From:      Vladimir Ivanov <wawa@yandex-team.ru>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/58514: Zebra based software BGP routers may freeze after a small network disturbance
Message-ID:  <200310251135.h9PBZU4P062413@wawa.yandex.ru>
Resent-Message-ID: <200310251140.h9PBe6HC061127@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         58514
>Category:       ports
>Synopsis:       Zebra based software BGP routers may freeze after a small network disturbance
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Oct 25 04:40:01 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Vladimir Ivanov
>Release:        
>Organization:
Yandex LLC
>Environment:
System: FreeBSD wawa.yandex.ru 4.9-RC FreeBSD 4.9-RC #1: Wed Oct 22 09:28:23 MSD 2003 wawa@wawa.yandex.ru:/usr/obj/usr/src/sys/WAWA i386


	
>Description:
	Sometimes Zebra (BGPD) software router freeze.

	After short investigations we've discovered blocked write operation in the BGP code (see the patch below). 
	It's a little bit funny because a couple lines before we can see authors comments which promissed non-blocking write operation.

	Alternate releases of Zebra (aka gnuzebra or quagga) contain the same bug I seem.

>How-To-Repeat:
	The problem occured when two Zebra routers being used to share network traffic. Both routers sould be bgp neighbours.
	Then we have to force both Zebras to fill network sendbuffers of session to each other. It's not very hard task I guess.
	In freeze situation each Zebra waits when other one will read packet and that's why it doesn read packet as we can see.
>Fix:

--- bgpd/bgp_packet.c   Tue Aug 20 19:31:54 2002
+++ bgpd/bgp_packet.c   Thu Oct 16 19:33:14 2003
@@ -566,17 +566,22 @@
   while (1)
     {
       int writenum;
+      int val;

       s = bgp_write_packet (peer);
       if (! s)
        return 0;

+      val = fcntl (peer->fd, F_GETFL, 0);
+      fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
+
       /* Number of bytes to be sent.  */
       writenum = stream_get_endp (s) - stream_get_getp (s);

       /* Call write() system call.  */
       num = write (peer->fd, STREAM_PNT (s), writenum);
       write_errno = errno;
+      fcntl (peer->fd, F_SETFL, val);
       if (num <= 0)
        {
          /* Partial write. */


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310251135.h9PBZU4P062413>