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 "test_nlattr.h"
13 #include <linux/pkt_sched.h>
14 #include <linux/rtnetlink.h>
15
16 const unsigned int hdrlen = sizeof(struct tcmsg);
17
18 static void
19 init_tcmsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
20 {
21 SET_STRUCT(struct nlmsghdr, nlh,
22 .nlmsg_len = msg_len,
23 .nlmsg_type = RTM_GETQDISC,
24 .nlmsg_flags = NLM_F_DUMP
25 );
26
27 struct tcmsg *const msg = NLMSG_DATA(nlh);
28 SET_STRUCT(struct tcmsg, msg,
29 .tcm_family = AF_UNIX,
30 .tcm_ifindex = ifindex_lo()
31 );
32
33 struct nlattr *const nla = NLMSG_ATTR(nlh, sizeof(*msg));
34 SET_STRUCT(struct nlattr, nla,
35 .nla_len = msg_len - NLMSG_SPACE(hdrlen),
36 .nla_type = TCA_STAB
37 );
38 }
39
40 static void
41 print_tcmsg(const unsigned int msg_len)
42 {
43 printf("{nlmsg_len=%u, nlmsg_type=RTM_GETQDISC, nlmsg_flags=NLM_F_DUMP"
44 ", nlmsg_seq=0, nlmsg_pid=0}, {tcm_family=AF_UNIX"
45 ", tcm_ifindex=" IFINDEX_LO_STR
46 ", tcm_handle=0, tcm_parent=0, tcm_info=0}"
47 ", [{nla_len=%u, nla_type=TCA_STAB}",
48 msg_len, msg_len - NLMSG_SPACE(hdrlen));
49 }
50
51 static void
52 print_uint16(const uint16_t *p, size_t idx)
53 {
54 printf("%u", *p);
55 }
56
57 int
58 main(void)
59 {
60 skip_if_unavailable("/proc/self/fd/");
61
62 const int fd = create_nl_socket(NETLINK_ROUTE);
63 void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
64 NLA_HDRLEN + sizeof(struct tc_sizespec));
65
66 static char pattern[4096];
67 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
68
69 static const struct tc_sizespec s = {
70 .cell_log = 0xab,
71 .size_log = 0xcd,
72 .cell_align = 0xefab,
73 .overhead = 0xcdadeefa,
74 .linklayer = 0xefbaafeb,
75 .mpu = 0xfebfaefb,
76 .mtu = 0xacdbefab,
77 .tsize = 0xbdeaabed
78 };
79 TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
80 init_tcmsg, print_tcmsg,
81 TCA_STAB_BASE, pattern, s,
82 printf("{");
83 PRINT_FIELD_U(s, cell_log);
84 printf(", ");
85 PRINT_FIELD_U(s, size_log);
86 printf(", ");
87 PRINT_FIELD_D(s, cell_align);
88 printf(", ");
89 PRINT_FIELD_D(s, overhead);
90 printf(", ");
91 PRINT_FIELD_U(s, linklayer);
92 printf(", ");
93 PRINT_FIELD_U(s, mpu);
94 printf(", ");
95 PRINT_FIELD_U(s, mtu);
96 printf(", ");
97 PRINT_FIELD_U(s, tsize);
98 printf("}"));
99
100 uint16_t data[2] = { 0xacbd, 0xefba };
101 TEST_NESTED_NLATTR_ARRAY(fd, nlh0, hdrlen,
102 init_tcmsg, print_tcmsg,
103 TCA_STAB_DATA, pattern, data, print_uint16);
104
105 puts("+++ exited with 0 +++");
106 return 0;
107 }