]> granicus.if.org Git - libnl/commitdiff
Fix for cgroup filter addition problem.
authord0u9 <d0u9.su@outlook.com>
Tue, 23 Jan 2018 06:13:43 +0000 (14:13 +0800)
committerd0u9 <d0u9.su@outlook.com>
Tue, 23 Jan 2018 16:02:55 +0000 (00:02 +0800)
Currently, due to the incomplete netlink datagram sent by libnl, cgroup
filter addition is not fully functional. The datagram generated by `tc`
command includes an empty attribute section, which is stripped off
in the libnl counterpart.

In this commit, a new `interface nla_nest_end_keep_empty()` is added.
This function closes attribute without stripping off empty attribute.

include/netlink/attr.h
lib/attr.c
lib/route/tc.c
libnl-3.sym

index da9eee4e7d1edc4d2499923be1c377aad13622bc..e47aa5d5206a2c4564829bf245ac84387c3a6873 100644 (file)
@@ -143,6 +143,7 @@ extern int          nla_put_nested(struct nl_msg *, int,
                                       const struct nl_msg *);
 extern struct nlattr * nla_nest_start(struct nl_msg *, int);
 extern int             nla_nest_end(struct nl_msg *, struct nlattr *);
+extern int             nla_nest_end_keep_empty(struct nl_msg *, struct nlattr *);
 extern void            nla_nest_cancel(struct nl_msg *, const struct nlattr *);
 extern int             nla_parse_nested(struct nlattr **, int, struct nlattr *,
                                         const struct nla_policy *);
index b81e550b4cd84dca3487e10f47c0fec7b87e6d53..d90fa47988f073fba5c5aa83ed622ef72fd4b469 100644 (file)
@@ -961,6 +961,55 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
        return 0;
 }
 
+/**
+ * Finalize nesting of attributes without stripping off empty attributes.
+ * @arg msg            Netlink message.
+ * @arg start          Container attribute as returned from nla_nest_start().
+ *
+ * Corrects the container attribute header to include the appeneded attributes.
+ * Keep empty attribute if NO actual attribute payload exists.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int nla_nest_end_keep_empty(struct nl_msg *msg, struct nlattr *start)
+{
+       size_t pad, len;
+
+       len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) start;
+
+       if (len > USHRT_MAX) {
+               /*
+                * Max nlattr size is exceeded, trim the attribute header again
+                */
+               nla_nest_cancel(msg, start);
+
+               /* Return error only if nlattr size was exceeded */
+               return -NLE_ATTRSIZE;
+       }
+
+       start->nla_len = len;
+
+       pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len;
+       if (pad > 0) {
+               /*
+                * Data inside attribute does not end at a alignment boundry.
+                * Pad accordingly and accoun for the additional space in
+                * the message. nlmsg_reserve() may never fail in this situation,
+                * the allocate message buffer must be a multiple of NLMSG_ALIGNTO.
+                */
+               if (!nlmsg_reserve(msg, pad, 0))
+                       BUG();
+
+               NL_DBG(2, "msg %p: attr <%p> %d: added %zu bytes of padding\n",
+                       msg, start, start->nla_type, pad);
+       }
+
+       NL_DBG(2, "msg %p: attr <%p> %d: closing nesting, len=%u\n",
+               msg, start, start->nla_type, start->nla_len);
+
+       return 0;
+}
+
 /**
  * Cancel the addition of a nested attribute
  * @arg msg            Netlink message
index 5dc43e175f06617bd581050c467fb3d1fbe27a51..62efd3548e6ea4acfb82671becc404ed6935c727 100644 (file)
@@ -226,7 +226,10 @@ int rtnl_tc_msg_build(struct rtnl_tc *tc, int type, int flags,
                        if ((err = ops->to_msg_fill(tc, data, msg)) < 0)
                                goto nla_put_failure;
 
-                       nla_nest_end(msg, opts);
+                       if (strcmp("cgroup", tc->tc_kind))
+                               nla_nest_end(msg, opts);
+                       else
+                               nla_nest_end_keep_empty(msg, opts);
                } else if ((err = ops->to_msg_fill_raw(tc, data, msg)) < 0)
                        goto nla_put_failure;
        }
index 4546a40c1f857373a681e101a6bc0d663b00cd01..42b38b7be68175953dbab1e1c31e05a4a84cc3a0 100644 (file)
@@ -260,6 +260,7 @@ global:
        nla_memcpy;
        nla_nest_cancel;
        nla_nest_end;
+       nla_nest_end_keep_empty;
        nla_nest_start;
        nla_next;
        nla_ok;