strace tc -s class sh dev eth1 parent 2: strace is fooled with rtnl_dump_request() way: sendmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={nlmsg_len=36, nlmsg_type=RTM_GETTCLASS, nlmsg_flags=NLM_F_REQUEST|NLM_F_DUMP, nlmsg_seq=1778082626, nlmsg_pid=0}, iov_len=16}, {iov_base={nlmsg_len=0, nlmsg_type=NLMSG_NOOP, nlmsg_flags=0, nlmsg_seq=0, nlmsg_pid=131072}, iov_len=20}], msg_iovlen=2, msg_controllen=0, msg_flags=0}, 0) = 36 With rtnl_dump_request_n() we get instead: sendmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=36, nlmsg_type=RTM_GETTCLASS, nlmsg_flags=NLM_F_REQUEST|NLM_F_DUMP, nlmsg_seq=1778082790, nlmsg_pid=0}, {tcm_family=AF_UNSPEC, tcm_ifindex=if_nametoindex("eth1"), tcm_handle=0, tcm_parent=131072, tcm_info=0}], iov_len=36}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 36 This will also permit future attribute additions, like skip stats. Signed-off-by: Eric Dumazet Cc: Jamal Hadi Salim --- tc/tc_class.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tc/tc_class.c b/tc/tc_class.c index 310514ce560ab6c1b42665cb6c75314e45b84cd6..82f0f85ee39a335bc7e1c3bea2e3ea9571ea155f 100644 --- a/tc/tc_class.c +++ b/tc/tc_class.c @@ -386,7 +386,14 @@ int print_class(struct nlmsghdr *n, void *arg) static int tc_class_list(int argc, char **argv) { - struct tcmsg t = { .tcm_family = AF_UNSPEC }; + struct { + struct nlmsghdr n; + struct tcmsg t; + } req = { + .n.nlmsg_type = RTM_GETTCLASS, + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)), + .t.tcm_family = AF_UNSPEC, + }; char d[IFNAMSIZ] = {}; char buf[1024] = {0}; @@ -412,20 +419,20 @@ static int tc_class_list(int argc, char **argv) if (get_tc_classid(&filter_classid, *argv)) invarg("invalid class ID", *argv); } else if (strcmp(*argv, "root") == 0) { - if (t.tcm_parent) { + if (req.t.tcm_parent) { fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); return -1; } - t.tcm_parent = TC_H_ROOT; + req.t.tcm_parent = TC_H_ROOT; } else if (strcmp(*argv, "parent") == 0) { __u32 handle; - if (t.tcm_parent) + if (req.t.tcm_parent) duparg("parent", *argv); NEXT_ARG(); if (get_tc_classid(&handle, *argv)) invarg("invalid parent ID", *argv); - t.tcm_parent = handle; + req.t.tcm_parent = handle; } else if (matches(*argv, "help") == 0) { usage(); } else { @@ -437,13 +444,13 @@ static int tc_class_list(int argc, char **argv) } if (d[0]) { - t.tcm_ifindex = ll_name_to_index(d); - if (!t.tcm_ifindex) + req.t.tcm_ifindex = ll_name_to_index(d); + if (!req.t.tcm_ifindex) return -nodev(d); - filter_ifindex = t.tcm_ifindex; + filter_ifindex = req.t.tcm_ifindex; } - if (rtnl_dump_request(&rth, RTM_GETTCLASS, &t, sizeof(t)) < 0) { + if (rtnl_dump_request_n(&rth, &req.n) < 0) { perror("Cannot send dump request"); return 1; } -- 2.54.0.545.g6539524ca2-goog