zebra: atomic FIB updates

This commit updates the kernel API so that route changes are
atomically updated using change/replaces messages instead
of first sending a withdraw followed with update.

Same for zclient updates, changes are sent as single ADD
instead of DELETE + ADD.

Signed-off-by: Timo Teräs <timo.teras@iki.fi>
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 790b142..ba03498 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -861,7 +861,7 @@
     return;
 #endif
 
-  if ((rtm->rtm_type == RTM_ADD) && ! (flags & RTF_UP))
+  if ((rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && ! (flags & RTF_UP))
     return;
 
   /* This is connected route. */
@@ -1072,14 +1072,14 @@
 
   ifp = if_lookup_by_index (index);
 
-  if (gate && message == RTM_ADD)
+  if (gate && (message == RTM_ADD || message == RTM_CHANGE))
     msg.rtm.rtm_flags |= RTF_GATEWAY;
 
   /* When RTF_CLONING is unavailable on BSD, should we set some
    * other flag instead?
    */
 #ifdef RTF_CLONING
-  if (! gate && message == RTM_ADD && ifp &&
+  if (! gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp &&
       (ifp->flags & IFF_POINTOPOINT) == 0)
     msg.rtm.rtm_flags |= RTF_CLONING;
 #endif /* RTF_CLONING */
@@ -1104,7 +1104,7 @@
 
   if (mask)
     msg.rtm.rtm_addrs |= RTA_NETMASK;
-  else if (message == RTM_ADD) 
+  else if (message == RTM_ADD || message == RTM_CHANGE)
     msg.rtm.rtm_flags |= RTF_HOST;
 
   /* Tagging route with flags */