This is an automated email from the ASF dual-hosted git repository.

jieyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new d458311  Fixed rtnl_act leak in routing::filter::internal::attach().
d458311 is described below

commit d4583113dd921515323c71e296046fc61e6ffe14
Author: Ilya Pronin <[email protected]>
AuthorDate: Wed Sep 19 12:05:00 2018 -0700

    Fixed rtnl_act leak in routing::filter::internal::attach().
    
    We should free the action once we've attached it to a filter, because
    rtnl_basic_add_action() and rtnl_u32_add_action() increase the
    refcounter of rtnl_act object upon adding it to the filter's list.
    
    Reference grabbing was added to libnl along with a corresponding
    capability NL_CAPABILITY_ROUTE_LINK_CLS_ADD_ACT_OWN_REFERENCE. Its
    support is already checked by Mesos in routing::check(). It seems that
    we simply forgot to adapt our code.
    
    Review: https://reviews.apache.org/r/68769/
---
 src/linux/routing/filter/internal.hpp | 53 +++++++++++++++--------------------
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git a/src/linux/routing/filter/internal.hpp 
b/src/linux/routing/filter/internal.hpp
index 4be4797..e62d50b 100644
--- a/src/linux/routing/filter/internal.hpp
+++ b/src/linux/routing/filter/internal.hpp
@@ -66,6 +66,13 @@ inline void cleanup(struct rtnl_cls* cls)
   rtnl_cls_put(cls);
 }
 
+
+template <>
+inline void cleanup(struct rtnl_act* act)
+{
+  rtnl_act_put(act);
+}
+
 namespace filter {
 namespace internal {
 
@@ -103,39 +110,33 @@ inline Try<Nothing> attach(
     return Error("Link '" + redirect.link + "' is not found");
   }
 
-  // TODO(jieyu): Note that currently, we don't use Netlink for 'act'
-  // because libnl has a refcount issue for rtnl_act. Clean this up
-  // once the bug is fixed in libnl.
-  struct rtnl_act* act = rtnl_act_alloc();
-  if (act == nullptr) {
+  Netlink<struct rtnl_act> act(rtnl_act_alloc());
+  if (act.get() == nullptr) {
     return Error("Failed to allocate a libnl action (rtnl_act)");
   }
 
   // Set the kind of the action to 'mirred'. The kind 'mirred' stands
   // for mirror or redirect actions.
-  int error = rtnl_tc_set_kind(TC_CAST(act), "mirred");
+  int error = rtnl_tc_set_kind(TC_CAST(act.get()), "mirred");
   if (error != 0) {
-    rtnl_act_put(act);
     return Error(
         "Failed to set the kind of the action: " +
         std::string(nl_geterror(error)));
   }
 
-  rtnl_mirred_set_ifindex(act, rtnl_link_get_ifindex(link->get()));
-  rtnl_mirred_set_action(act, TCA_EGRESS_REDIR);
-  rtnl_mirred_set_policy(act, TC_ACT_STOLEN);
+  rtnl_mirred_set_ifindex(act.get(), rtnl_link_get_ifindex(link->get()));
+  rtnl_mirred_set_action(act.get(), TCA_EGRESS_REDIR);
+  rtnl_mirred_set_policy(act.get(), TC_ACT_STOLEN);
 
   const std::string kind = rtnl_tc_get_kind(TC_CAST(cls.get()));
   if (kind == "basic") {
-    error = rtnl_basic_add_action(cls.get(), act);
+    error = rtnl_basic_add_action(cls.get(), act.get());
     if (error != 0) {
-      rtnl_act_put(act);
       return Error(std::string(nl_geterror(error)));
     }
   } else if (kind == "u32") {
-    error = rtnl_u32_add_action(cls.get(), act);
+    error = rtnl_u32_add_action(cls.get(), act.get());
     if (error != 0) {
-      rtnl_act_put(act);
       return Error(std::string(nl_geterror(error)));
     }
 
@@ -148,7 +149,6 @@ inline Try<Nothing> attach(
           std::string(nl_geterror(error)));
     }
   } else {
-    rtnl_act_put(act);
     return Error("Unsupported classifier kind: " + kind);
   }
 
@@ -171,40 +171,33 @@ inline Try<Nothing> attach(
       return Error("Link '" + _link + "' is not found");
     }
 
-    // TODO(jieyu): Note that currently, we don't use Netlink for
-    // 'act' because libnl has a refcount issue for rtnl_act. Clean
-    // this up once libnl fixes the bug.
-    struct rtnl_act* act = rtnl_act_alloc();
-    if (act == nullptr) {
+    Netlink<struct rtnl_act> act(rtnl_act_alloc());
+    if (act.get() == nullptr) {
       return Error("Failed to allocate a libnl action (rtnl_act)");
     }
 
-    int error = rtnl_tc_set_kind(TC_CAST(act), "mirred");
+    int error = rtnl_tc_set_kind(TC_CAST(act.get()), "mirred");
     if (error != 0) {
-      rtnl_act_put(act);
       return Error(
           "Failed to set the kind of the action: " +
           std::string(nl_geterror(error)));
     }
 
-    rtnl_mirred_set_ifindex(act, rtnl_link_get_ifindex(link->get()));
-    rtnl_mirred_set_action(act, TCA_EGRESS_MIRROR);
-    rtnl_mirred_set_policy(act, TC_ACT_PIPE);
+    rtnl_mirred_set_ifindex(act.get(), rtnl_link_get_ifindex(link->get()));
+    rtnl_mirred_set_action(act.get(), TCA_EGRESS_MIRROR);
+    rtnl_mirred_set_policy(act.get(), TC_ACT_PIPE);
 
     if (kind == "basic") {
-      error = rtnl_basic_add_action(cls.get(), act);
+      error = rtnl_basic_add_action(cls.get(), act.get());
       if (error != 0) {
-        rtnl_act_put(act);
         return Error(std::string(nl_geterror(error)));
       }
     } else if (kind == "u32") {
-      error = rtnl_u32_add_action(cls.get(), act);
+      error = rtnl_u32_add_action(cls.get(), act.get());
       if (error != 0) {
-        rtnl_act_put(act);
         return Error(std::string(nl_geterror(error)));
       }
     } else {
-      rtnl_act_put(act);
       return Error("Unsupported classifier kind: " + kind);
     }
   }

Reply via email to