diff options
author | d0u9 <d0u9.su@outlook.com> | 2018-01-23 06:13:43 (GMT) |
---|---|---|
committer | d0u9 <d0u9.su@outlook.com> | 2018-01-23 16:02:55 (GMT) |
commit | 52057832033ac8f6c6969e4ae3a7e65db1c9f540 (patch) | |
tree | 5af32d0dd5a3ca7c8735bf38ebdff4067fef779b | |
parent | 4eba9c8f43f9389063fb510f38d3e16ee8f6a715 (diff) | |
download | libnl-52057832033ac8f6c6969e4ae3a7e65db1c9f540.zip libnl-52057832033ac8f6c6969e4ae3a7e65db1c9f540.tar.gz libnl-52057832033ac8f6c6969e4ae3a7e65db1c9f540.tar.bz2 |
Fix for cgroup filter addition problem.
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.
-rw-r--r-- | include/netlink/attr.h | 1 | ||||
-rw-r--r-- | lib/attr.c | 49 | ||||
-rw-r--r-- | lib/route/tc.c | 5 | ||||
-rw-r--r-- | libnl-3.sym | 1 |
4 files changed, 55 insertions, 1 deletions
diff --git a/include/netlink/attr.h b/include/netlink/attr.h index da9eee4..e47aa5d 100644 --- a/include/netlink/attr.h +++ b/include/netlink/attr.h @@ -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 *); @@ -962,6 +962,55 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start) } /** + * 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 * @arg attr Nested netlink attribute diff --git a/lib/route/tc.c b/lib/route/tc.c index 5dc43e1..62efd35 100644 --- a/lib/route/tc.c +++ b/lib/route/tc.c @@ -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; } diff --git a/libnl-3.sym b/libnl-3.sym index 4546a40..42b38b7 100644 --- a/libnl-3.sym +++ b/libnl-3.sym @@ -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; |