1 /*
2 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3 * Copyright (c) 2017-2021 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "tests.h"
10
11 #include <stdio.h>
12 #include <stddef.h>
13 #include "test_nlattr.h"
14 #include <linux/pkt_sched.h>
15 #include <linux/rtnetlink.h>
16
17 static void
18 init_tcmsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
19 {
20 SET_STRUCT(struct nlmsghdr, nlh,
21 .nlmsg_len = msg_len,
22 .nlmsg_type = RTM_GETQDISC,
23 .nlmsg_flags = NLM_F_DUMP
24 );
25
26 struct tcmsg *const msg = NLMSG_DATA(nlh);
27 SET_STRUCT(struct tcmsg, msg,
28 .tcm_family = AF_UNIX,
29 .tcm_ifindex = ifindex_lo()
30 );
31
32 }
33
34 static void
35 print_tcmsg(const unsigned int msg_len)
36 {
37 printf("{nlmsg_len=%u, nlmsg_type=RTM_GETQDISC, nlmsg_flags=NLM_F_DUMP"
38 ", nlmsg_seq=0, nlmsg_pid=0}, {tcm_family=AF_UNIX"
39 ", tcm_ifindex=" IFINDEX_LO_STR
40 ", tcm_handle=0, tcm_parent=0, tcm_info=0}",
41 msg_len);
42 }
43
44 int
45 main(void)
46 {
47 skip_if_unavailable("/proc/self/fd/");
48
49 const int fd = create_nl_socket(NETLINK_ROUTE);
50 const unsigned int hdrlen = sizeof(struct tcmsg);
51 void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
52 NLA_HDRLEN + sizeof(struct tc_stats));
53
54 static char pattern[4096];
55 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
56
57 const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
58 char nla_type_str[256];
59 sprintf(nla_type_str, "%#x /* TCA_??? */", nla_type);
60 TEST_NLATTR_(fd, nlh0, hdrlen,
61 init_tcmsg, print_tcmsg,
62 nla_type, nla_type_str,
63 4, pattern, 4,
64 print_quoted_hex(pattern, 4));
65
66 static const struct tc_stats st = {
67 .bytes = 0xabcdcdbefeadefac,
68 .packets = 0xbcdeaefd,
69 .drops = 0xcdedafed,
70 .overlimits = 0xdcdbefad,
71 .bps = 0xefaebfad,
72 .pps = 0xfefbaedb,
73 .qlen = 0xabcdefab,
74 .backlog = 0xbdeabeab
75 };
76 char buf[offsetofend(struct tc_stats, backlog)];
77 memcpy(buf, &st, sizeof(buf));
78 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
79 init_tcmsg, print_tcmsg,
80 TCA_STATS, pattern, buf,
81 printf("{");
82 PRINT_FIELD_U(st, bytes);
83 printf(", ");
84 PRINT_FIELD_U(st, packets);
85 printf(", ");
86 PRINT_FIELD_U(st, drops);
87 printf(", ");
88 PRINT_FIELD_U(st, overlimits);
89 printf(", ");
90 PRINT_FIELD_U(st, bps);
91 printf(", ");
92 PRINT_FIELD_U(st, pps);
93 printf(", ");
94 PRINT_FIELD_U(st, qlen);
95 printf(", ");
96 PRINT_FIELD_U(st, backlog);
97 printf("}"));
98
99 static const struct tc_estimator est = {
100 .interval = 0xcd,
101 .ewma_log = 0xab
102 };
103 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
104 init_tcmsg, print_tcmsg,
105 TCA_RATE, pattern, est,
106 printf("{");
107 PRINT_FIELD_D(est, interval);
108 printf(", ");
109 PRINT_FIELD_U(est, ewma_log);
110 printf("}"));
111
112 puts("+++ exited with 0 +++");
113 return 0;
114 }