From: James Li <[email protected]>

Do not allow a program outside Quagga to delete a Quagga route from the kernel.
To delete a Quagga route, do it inside Quagga.

Signed-off-by: James Li <[email protected]>
---
 zebra/rt_netlink.c |    9 ++++++---
 zebra/zebra_rib.c  |   42 ++++++++++++++++++++++++++----------------
 2 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 0f069e3..adb5684 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -837,6 +837,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct 
nlmsghdr *h,
   int len;
   struct rtmsg *rtm;
   struct rtattr *tb[RTA_MAX + 1];
+  u_char zebra_flags = 0;
 
   char anyaddr[16] = { 0 };
 
@@ -894,6 +895,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct 
nlmsghdr *h,
 
   if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
     return 0;
+  if (rtm->rtm_protocol == RTPROT_ZEBRA)
+    SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE);
 
   if (rtm->rtm_src_len != 0)
     {
@@ -1001,8 +1004,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct 
nlmsghdr *h,
             }
         }
       else
-        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id,
-                         SAFI_UNICAST);
+        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate,
+                        index, vrf_id, SAFI_UNICAST);
     }
 
 #ifdef HAVE_IPV6
@@ -1026,7 +1029,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct 
nlmsghdr *h,
         rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, table,
                       metric, 0, SAFI_UNICAST);
       else
-        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id,
+        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index, 
vrf_id,
                          SAFI_UNICAST);
     }
 #endif /* HAVE_IPV6 */
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 2ac102f..7d2b230 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2232,14 +2232,19 @@ rib_delete_ipv4 (int type, int flags, struct 
prefix_ipv4 *p,
      kernel. */
   if (! same)
     {
-      if (fib && type == ZEBRA_ROUTE_KERNEL)
-       {
-         /* Unset flags. */
-         for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
-           UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
-
-         UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
-       }
+      if (fib && type == ZEBRA_ROUTE_KERNEL &&
+          CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
+        {
+          if (IS_ZEBRA_DEBUG_KERNEL)
+            {
+              zlog_debug ("Zebra route %s/%d was deleted by others from 
kernel",
+                         inet_ntop (AF_INET, &p->prefix, buf1, 
INET_ADDRSTRLEN),
+                         p->prefixlen);
+            }
+          /* This means someone else, other than Zebra, has deleted
+           * a Zebra router from the kernel. We will add it back */
+           rib_install_kernel(rn, fib);
+        }
       else
        {
          if (IS_ZEBRA_DEBUG_KERNEL)
@@ -2866,14 +2871,19 @@ rib_delete_ipv6 (int type, int flags, struct 
prefix_ipv6 *p,
      kernel. */
   if (! same)
     {
-      if (fib && type == ZEBRA_ROUTE_KERNEL)
-       {
-         /* Unset flags. */
-         for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
-           UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
-
-         UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
-       }
+      if (fib && type == ZEBRA_ROUTE_KERNEL &&
+          CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE))
+        {
+          if (IS_ZEBRA_DEBUG_KERNEL)
+            {
+              zlog_debug ("Zebra route %s/%d was deleted by others from 
kernel",
+                         inet_ntop (AF_INET, &p->prefix, buf1, 
INET_ADDRSTRLEN),
+                         p->prefixlen);
+            }
+          /* This means someone else, other than Zebra, has deleted a Zebra
+           * route from the kernel. We will add it back */
+          rib_install_kernel(rn, fib);
+        }
       else
        {
          if (IS_ZEBRA_DEBUG_KERNEL)
-- 
1.7.10.4


_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to