]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: kernel interface simplification
authorTimo Teräs <timo.teras@iki.fi>
Fri, 15 Jan 2016 15:36:29 +0000 (17:36 +0200)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 18 Oct 2016 12:36:21 +0000 (08:36 -0400)
[DL: picked out from: "atomic FIB updates"]

This simplifies the OS-specific route update API into a single entry
point, kernel_route_rib(), which dispatches the various operations
internally.

Signed-off-by: Timo Teräs <timo.teras@iki.fi>
zebra/kernel_null.c
zebra/kernel_socket.c
zebra/rt.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/zebra_rib.c

index 17b3c7bc8d421a1e25767f8648b897f48bc5ca7d..d02939882c1ebc957b1aab57da650ed744c0f89b 100644 (file)
 #include "zebra/rt_netlink.h"
 #include "zebra/rib.h"
 
-int kernel_add_ipv4 (struct prefix *a, struct rib *b) { return 0; }
-int kernel_update_ipv4 (struct prefix *a, struct rib *b) { return 0; }
-int kernel_delete_ipv4 (struct prefix *a, struct rib *b) { return 0; }
-
-int kernel_add_ipv6 (struct prefix *a, struct rib *b) { return 0; }
-int kernel_update_ipv6 (struct prefix *a, struct rib *b) { return 0; }
-int kernel_delete_ipv6 (struct prefix *a, struct rib *b) { return 0; }
+int kernel_route_rib (struct prefix *a, struct rib *old, struct rib *new) { return 0; }
 
 int kernel_address_add_ipv4 (struct interface *a, struct connected *b)
 {
index f3f0a2777e1660c813625f6ac368a68075591adf..6cb9f785982c60452e3be318b2a610d19dac75bf 100644 (file)
@@ -899,7 +899,7 @@ rtm_read (struct rt_msghdr *rtm)
     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. */
@@ -1115,14 +1115,14 @@ rtm_write (int message,
 
   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 */
@@ -1147,7 +1147,7 @@ rtm_write (int message,
 
   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;
 
 #ifdef __OpenBSD__
index 1899ef17dabfea71a7ca7e6c7a6cd3537d1c8eda..e56e3b8fe3a68af4c11c2ece97c482e79cbda680 100644 (file)
 #include "zebra/zebra_ns.h"
 #include "zebra/zebra_mpls.h"
 
-extern int kernel_add_ipv4 (struct prefix *, struct rib *);
-extern int kernel_update_ipv4 (struct prefix *, struct rib *);
-extern int kernel_delete_ipv4 (struct prefix *, struct rib *);
+extern int kernel_route_rib (struct prefix *, struct rib *, struct rib *);
 
 extern int kernel_address_add_ipv4 (struct interface *, struct connected *);
 extern int kernel_address_delete_ipv4 (struct interface *, struct connected *);
 extern int kernel_neigh_update (int, int, uint32_t, char *, int);
 
-extern int kernel_add_ipv6 (struct prefix *, struct rib *);
-extern int kernel_update_ipv6 (struct prefix *, struct rib *);
-extern int kernel_delete_ipv6 (struct prefix *, struct rib *);
-
 extern int kernel_add_lsp (zebra_lsp_t *);
 extern int kernel_upd_lsp (zebra_lsp_t *);
 extern int kernel_del_lsp (zebra_lsp_t *);
index 4d60ceda70445cf0d94a9bc240e479183984ec5e..f16fd55c981f13bb3d05749bb2ef39a9e59f1883 100644 (file)
@@ -1117,7 +1117,7 @@ netlink_neigh_update (int cmd, int ifindex, uint32_t addr, char *lla, int llalen
 /* Update flag indicates whether this is a "replace" or not. */
 static int
 netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
-                         int family, int update)
+                         int update)
 {
   int bytelen;
   struct sockaddr_nl snl;
@@ -1125,6 +1125,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
   int recursing;
   int nexthop_num;
   int discard;
+  int family = PREFIX_FAMILY(p);
   const char *routedesc;
   int setsrc = 0;
   union g_addr src;
@@ -1408,52 +1409,16 @@ skip:
 }
 
 int
-kernel_add_ipv4 (struct prefix *p, struct rib *rib)
+kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
 {
-  return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET, 0);
-}
-
-int
-kernel_update_ipv4 (struct prefix *p, struct rib *rib)
-{
-  return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET, 1);
-}
-
-int
-kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
-{
-  return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET, 0);
-}
-
-#ifdef HAVE_IPV6
-int
-kernel_add_ipv6 (struct prefix *p, struct rib *rib)
-{
-    {
-      return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6, 0);
-    }
-}
+  if (!old && new)
+    return netlink_route_multipath (RTM_NEWROUTE, p, new, 0);
+  if (old && !new)
+    return netlink_route_multipath (RTM_DELROUTE, p, old, 0);
 
-int
-kernel_update_ipv6 (struct prefix *p, struct rib *rib)
-{
-#if defined (HAVE_V6_RR_SEMANTICS)
-  return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6, 1);
-#else
-  kernel_delete_ipv6 (p, rib);
-  return kernel_add_ipv6 (p, rib);
-#endif
+  return netlink_route_multipath (RTM_NEWROUTE, p, new, 1);
 }
 
-int
-kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
-{
-    {
-      return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET6, 0);
-    }
-}
-#endif /* HAVE_IPV6 */
-
 int
 kernel_neigh_update (int add, int ifindex, uint32_t addr, char *lla, int llalen)
 {
index f23f9d5da34535ed120b92624dc48cd1d5eda861..b00d7757374a4ca074cf6c2af64ed96b8c2ac89c 100644 (file)
@@ -237,43 +237,6 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
   return 0; /*XXX*/
 }
 
-int
-kernel_add_ipv4 (struct prefix *p, struct rib *rib)
-{
-  int route;
-
-  if (zserv_privs.change(ZPRIVS_RAISE))
-    zlog (NULL, LOG_ERR, "Can't raise privileges");
-  route = kernel_rtm_ipv4 (RTM_ADD, p, rib, AF_INET);
-  if (zserv_privs.change(ZPRIVS_LOWER))
-    zlog (NULL, LOG_ERR, "Can't lower privileges");
-
-  return route;
-}
-
-int
-kernel_update_ipv4 (struct prefix *p, struct rib *rib)
-{
-  kernel_delete_ipv4 (p, rib);
-  return kernel_add_ipv4 (p, rib);
-}
-
-int
-kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
-{
-  int route;
-
-  if (zserv_privs.change(ZPRIVS_RAISE))
-    zlog (NULL, LOG_ERR, "Can't raise privileges");
-  route = kernel_rtm_ipv4 (RTM_DELETE, p, rib, AF_INET);
-  if (zserv_privs.change(ZPRIVS_LOWER))
-    zlog (NULL, LOG_ERR, "Can't lower privileges");
-
-  return route;
-}
-
-#ifdef HAVE_IPV6
-
 #ifdef SIN6_LEN
 /* Calculate sin6_len value for netmask socket value. */
 static int
@@ -301,8 +264,7 @@ sin6_masklen (struct in6_addr mask)
 
 /* Interface between zebra message and rtm message. */
 static int
-kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
-                          int family)
+kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib, int family)
 {
   struct sockaddr_in6 *mask;
   struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
@@ -395,7 +357,7 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
 #if 0
       if (error)
        {
-         zlog_info ("kernel_rtm_ipv6_multipath(): nexthop %d add error=%d.",
+         zlog_info ("kernel_rtm_ipv6(): nexthop %d add error=%d.",
            nexthop_num, error);
        }
 #else
@@ -409,7 +371,7 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
   if (nexthop_num == 0)
     {
       if (IS_ZEBRA_DEBUG_KERNEL)
-       zlog_debug ("kernel_rtm_ipv6_multipath(): No useful nexthop.");
+       zlog_debug ("kernel_rtm_ipv6(): No useful nexthop.");
       return 0;
     }
 
@@ -417,40 +379,38 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
 }
 
 int
-kernel_add_ipv6 (struct prefix *p, struct rib *rib)
+kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
 {
-  int route;
-
-  if (zserv_privs.change(ZPRIVS_RAISE))
-    zlog (NULL, LOG_ERR, "Can't raise privileges");
-  route =  kernel_rtm_ipv6_multipath (RTM_ADD, p, rib, AF_INET6);
-  if (zserv_privs.change(ZPRIVS_LOWER))
-    zlog (NULL, LOG_ERR, "Can't lower privileges");
-
-  return route;
-}
+  struct rib *rib;
+  int route = 0, cmd;
 
-int
-kernel_update_ipv6 (struct prefix *p, struct rib *rib)
-{
-  kernel_delete_ipv6 (p, rib);
-  return kernel_add_ipv6 (p, rib);
-}
+  if (!old && new)
+    cmd = RTM_ADD;
+  else if (old && !new)
+    cmd = RTM_DELETE;
+  else
+    cmd = RTM_CHANGE;
 
-int
-kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
-{
-  int route;
+  rib = new ? new : old;
 
   if (zserv_privs.change(ZPRIVS_RAISE))
     zlog (NULL, LOG_ERR, "Can't raise privileges");
-  route =  kernel_rtm_ipv6_multipath (RTM_DELETE, p, rib, AF_INET6);
+
+  switch (PREFIX_FAMILY(p))
+    {
+    case AF_INET:
+      route = kernel_rtm_ipv4 (cmd, p, rib, AF_INET);
+      break;
+    case AF_INET6:
+      route = kernel_rtm_ipv6 (cmd, p, rib, AF_INET6);
+      break;
+    }
+
   if (zserv_privs.change(ZPRIVS_LOWER))
     zlog (NULL, LOG_ERR, "Can't lower privileges");
 
   return route;
 }
-#endif /* HAVE_IPV6 */
 
 int
 kernel_neigh_update (int add, int ifindex, uint32_t addr, char *lla, int llalen)
index b7d12a5cb43c32dd5058ea658a42294b5403f029..394469950dde335618a90bffbd74ee5bcade2eba 100644 (file)
@@ -1232,21 +1232,7 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, int update)
    * the kernel.
    */
   zfpm_trigger_update (rn, "installing in kernel");
-  switch (PREFIX_FAMILY (&rn->p))
-    {
-    case AF_INET:
-      if (update)
-        ret = kernel_update_ipv4 (&rn->p, rib);
-      else
-        ret = kernel_add_ipv4 (&rn->p, rib);
-      break;
-    case AF_INET6:
-      if (update)
-        ret = kernel_update_ipv6 (&rn->p, rib);
-      else
-        ret = kernel_add_ipv6 (&rn->p, rib);
-      break;
-    }
+  ret = kernel_route_rib (&rn->p, update ? rib : NULL, rib);
 
   /* If install succeeds, update FIB flag for nexthops. */
   if (!ret)
@@ -1287,16 +1273,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
    * the kernel.
    */
   zfpm_trigger_update (rn, "uninstalling from kernel");
-
-  switch (PREFIX_FAMILY (&rn->p))
-    {
-    case AF_INET:
-      ret = kernel_delete_ipv4 (&rn->p, rib);
-      break;
-    case AF_INET6:
-      ret = kernel_delete_ipv6 (&rn->p, rib);
-      break;
-    }
+  ret = kernel_route_rib (&rn->p, rib, NULL);
 
   for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
     UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);