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 2253cc1..f5a9450 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -850,6 +850,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 };
 
@@ -908,6 +909,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)
     {
@@ -1031,8 +1034,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
@@ -1056,7 +1059,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, mtu, 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 674a1f7..812ef96 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2189,14 +2189,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)
@@ -2847,14 +2852,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.9.1


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

Reply via email to