Merged own patch for the bug #391 (debugging and comments mostly).
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index b06c586..e8668a1 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -32,6 +32,7 @@
 #include "zebra/debug.h"
 #include "zebra/rib.h"
 #include "zebra/rt.h"
+#include "zebra/kernel_socket.h"
 
 extern struct zebra_privs_t zserv_privs;
 
@@ -75,7 +76,10 @@
   unsigned int ifindex = 0;
   int gate = 0;
   int error;
+  char prefix_buf[INET_ADDRSTRLEN];
 
+  if (IS_ZEBRA_DEBUG_RIB)
+    inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);
   memset (&sin_dest, 0, sizeof (struct sockaddr_in));
   sin_dest.sin_family = AF_INET;
 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
@@ -95,6 +99,7 @@
   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
     {
       gate = 0;
+      char gate_buf[INET_ADDRSTRLEN] = "NULL";
 
       /*
        * XXX We need to refrain from kernel operations in some cases,
@@ -161,29 +166,61 @@
 			     rib->flags,
 			     rib->metric);
 
-#if 0
-	  if (error)
-	    {
-	      zlog_info ("kernel_rtm_ipv4(): nexthop %d add error=%d.",
-			 nexthop_num, error);
-	    }
-#endif
-	  if (error == 0)
-	    {
-	      nexthop_num++;
-	      if (cmd == RTM_ADD)
-		SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
-	    }
-	}
-    }
-
-  /* If there is no useful nexthop then return. */
-  if (nexthop_num == 0)
-    {
-      if (IS_ZEBRA_DEBUG_KERNEL)
-	zlog_debug ("kernel_rtm_ipv4(): No useful nexthop.");
-      return 0;
-    }
+           if (IS_ZEBRA_DEBUG_RIB)
+           {
+             if (!gate)
+             {
+               zlog_debug ("%s: %s/%d: attention! gate not found for rib %p",
+                 __func__, prefix_buf, p->prefixlen, rib);
+               rib_dump (__func__, (struct prefix_ipv4 *)p, rib);
+             }
+             else
+               inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);
+           }
+ 
+           switch (error)
+           {
+             /* We only flag nexthops as being in FIB if rtm_write() did its work. */
+             case ZEBRA_ERR_NOERROR:
+               nexthop_num++;
+               if (IS_ZEBRA_DEBUG_RIB)
+                 zlog_debug ("%s: %s/%d: successfully did NH %s",
+                   __func__, prefix_buf, p->prefixlen, gate_buf);
+               if (cmd == RTM_ADD)
+                 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+               break;
+ 
+             /* The only valid case for this error is kernel's failure to install
+              * a multipath route, which is common for FreeBSD. This should be
+              * ignored silently, but logged as an error otherwise.
+              */
+             case ZEBRA_ERR_RTEXIST:
+               if (cmd != RTM_ADD)
+                 zlog_err ("%s: rtm_write() returned %d for command %d",
+                   __func__, error, cmd);
+               continue;
+               break;
+ 
+             /* Given that our NEXTHOP_FLAG_FIB matches real kernel FIB, it isn't
+              * normal to get any other messages in ANY case.
+              */
+             case ZEBRA_ERR_RTNOEXIST:
+             case ZEBRA_ERR_RTUNREACH:
+             default:
+               zlog_err ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s",
+                 __func__, prefix_buf, p->prefixlen, error, LOOKUP (rtm_type_str, cmd));
+               break;
+           }
+         } /* if (cmd and flags make sense) */
+       else
+         if (IS_ZEBRA_DEBUG_RIB)
+           zlog_debug ("%s: odd command %s for flags %d",
+             __func__, LOOKUP (rtm_type_str, cmd), nexthop->flags);
+     } /* for (nexthop = ... */
+ 
+   /* If there was no useful nexthop, then complain. */
+   if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
+     zlog_debug ("%s: No useful nexthops were found in RIB entry %p", __func__, rib);
 
   return 0; /*XXX*/
 }