]> git.puffer.fish Git - mirror/frr.git/commitdiff
Do not allow a program outside Quagga to delete a Quagga route from the kernel.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:40:43 +0000 (17:40 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:40:43 +0000 (17:40 -0700)
To delete a Quagga route, do it inside Quagga.

zebra/rt_netlink.c
zebra/zebra_rib.c

index 4ab6b4bc1537fa2ce4d27bea7f168f01354db3c0..290c8bc282bbf9cbf86901e12126cf03e6feae8b 100644 (file)
@@ -839,6 +839,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 };
 
@@ -895,6 +896,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)
     {
@@ -1004,7 +1007,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
             }
         }
       else
-        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, SAFI_UNICAST);
+        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index,
+                         table, SAFI_UNICAST);
     }
 
 #ifdef HAVE_IPV6
@@ -1032,7 +1036,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
       if (h->nlmsg_type == RTM_NEWROUTE)
         rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST);
       else
-        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, SAFI_UNICAST);
+        rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index,
+                         table, SAFI_UNICAST);
     }
 #endif /* HAVE_IPV6 */
 
index 5cd81e3de45dc3f3f3ddb823e2a5ce3368bc93e5..dac1166cbc7e344ac65acc601efef1921ce1420a 100644 (file)
@@ -2236,14 +2236,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)
@@ -2900,14 +2905,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)