1 /*
2 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3 * Copyright (c) 2017-2023 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 <inttypes.h>
13 #include "test_nlattr.h"
14 #include <linux/if.h>
15 #include <linux/if_arp.h>
16 #include <linux/if_link.h>
17 #include <linux/rtnetlink.h>
18
19 #define IFLA_ATTR IFLA_PROTINFO
20 #define IFLA_AF AF_BRIDGE
21 #define IFLA_AF_STR "AF_BRIDGE"
22 #include "nlattr_ifla.h"
23
24 int
25 main(void)
26 {
27 skip_if_unavailable("/proc/self/fd/");
28
29 const int fd = create_nl_socket(NETLINK_ROUTE);
30 void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
31 NLA_HDRLEN * 2 + 42);
32
33 static char pattern[4096];
34 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
35
36
37 /* Unknown, unhandled, unsupported */
38 static const struct strval16 un_attrs[] = {
39 { ENUM_KNOWN(0, IFLA_BRPORT_UNSPEC) },
40 { ENUM_KNOWN(0x18, IFLA_BRPORT_FLUSH) },
41 { ENUM_KNOWN(0x1a, IFLA_BRPORT_PAD) },
42 { ARG_XLAT_UNKNOWN(0x2c, "IFLA_BRPORT_???") },
43 { ARG_XLAT_UNKNOWN(0xbad, "IFLA_BRPORT_???") },
44 };
45 for (size_t i = 0; i < ARRAY_SIZE(un_attrs); i++) {
46 TEST_NLATTR_(fd, nlh0 - NLA_HDRLEN, hdrlen + NLA_HDRLEN,
47 init_ifinfomsg, print_ifinfomsg,
48 un_attrs[i].val, un_attrs[i].str,
49 42, pattern, 42,
50 print_quoted_hex(pattern, 32);
51 printf("...]"));
52 }
53
54 /* u8 attrs */
55 static const struct strval16 u8_attrs[] = {
56 { ENUM_KNOWN(0x1, IFLA_BRPORT_STATE) },
57 { ENUM_KNOWN(0x4, IFLA_BRPORT_MODE) },
58 { ENUM_KNOWN(0x5, IFLA_BRPORT_GUARD) },
59 { ENUM_KNOWN(0x6, IFLA_BRPORT_PROTECT) },
60 { ENUM_KNOWN(0x7, IFLA_BRPORT_FAST_LEAVE) },
61 { ENUM_KNOWN(0x8, IFLA_BRPORT_LEARNING) },
62 { ENUM_KNOWN(0x9, IFLA_BRPORT_UNICAST_FLOOD) },
63 { ENUM_KNOWN(0xa, IFLA_BRPORT_PROXYARP) },
64 { ENUM_KNOWN(0xb, IFLA_BRPORT_LEARNING_SYNC) },
65 { ENUM_KNOWN(0xc, IFLA_BRPORT_PROXYARP_WIFI) },
66 { ENUM_KNOWN(0x13, IFLA_BRPORT_TOPOLOGY_CHANGE_ACK) },
67 { ENUM_KNOWN(0x14, IFLA_BRPORT_CONFIG_PENDING) },
68 { ENUM_KNOWN(0x19, IFLA_BRPORT_MULTICAST_ROUTER) },
69 { ENUM_KNOWN(0x1b, IFLA_BRPORT_MCAST_FLOOD) },
70 { ENUM_KNOWN(0x1c, IFLA_BRPORT_MCAST_TO_UCAST) },
71 { ENUM_KNOWN(0x1d, IFLA_BRPORT_VLAN_TUNNEL) },
72 { ENUM_KNOWN(0x1e, IFLA_BRPORT_BCAST_FLOOD) },
73 { ENUM_KNOWN(0x20, IFLA_BRPORT_NEIGH_SUPPRESS) },
74 { ENUM_KNOWN(0x21, IFLA_BRPORT_ISOLATED) },
75 { ENUM_KNOWN(0x23, IFLA_BRPORT_MRP_RING_OPEN) },
76 { ENUM_KNOWN(0x24, IFLA_BRPORT_MRP_IN_OPEN) },
77 { ENUM_KNOWN(0x27, IFLA_BRPORT_LOCKED) },
78 { ENUM_KNOWN(0x28, IFLA_BRPORT_MAB) },
79 { ENUM_KNOWN(0x2b, IFLA_BRPORT_NEIGH_VLAN_SUPPRESS) },
80 };
81 void *nlh_u8 = midtail_alloc(NLMSG_SPACE(hdrlen),
82 NLA_HDRLEN * 2 + sizeof(uint8_t));
83 for (size_t i = 0; i < ARRAY_SIZE(u8_attrs); i++) {
84 check_u8_nlattr(fd, nlh_u8, hdrlen,
85 init_ifinfomsg, print_ifinfomsg,
86 u8_attrs[i].val, u8_attrs[i].str, pattern, 1);
87 }
88
89
90 /* u16 attrs */
91 static const struct strval16 u16_attrs[] = {
92 { ENUM_KNOWN(0x2, IFLA_BRPORT_PRIORITY) },
93 { ENUM_KNOWN(0xf, IFLA_BRPORT_DESIGNATED_PORT) },
94 { ENUM_KNOWN(0x10, IFLA_BRPORT_DESIGNATED_COST) },
95 { ENUM_KNOWN(0x11, IFLA_BRPORT_ID) },
96 { ENUM_KNOWN(0x12, IFLA_BRPORT_NO) },
97 };
98 void *nlh_u16 = midtail_alloc(NLMSG_SPACE(hdrlen),
99 NLA_HDRLEN * 2 + sizeof(uint16_t));
100 for (size_t i = 0; i < ARRAY_SIZE(u16_attrs); i++) {
101 check_u16_nlattr(fd, nlh_u16, hdrlen,
102 init_ifinfomsg, print_ifinfomsg,
103 u16_attrs[i].val, u16_attrs[i].str,
104 pattern, 1);
105 }
106
107
108 /* x16 attrs */
109 static const struct strval16 x16_attrs[] = {
110 { ENUM_KNOWN(0x1f, IFLA_BRPORT_GROUP_FWD_MASK) },
111 };
112 void *nlh_x16 = midtail_alloc(NLMSG_SPACE(hdrlen),
113 NLA_HDRLEN * 2 + sizeof(uint16_t));
114 for (size_t i = 0; i < ARRAY_SIZE(x16_attrs); i++) {
115 check_x16_nlattr(fd, nlh_x16, hdrlen,
116 init_ifinfomsg, print_ifinfomsg,
117 x16_attrs[i].val, x16_attrs[i].str,
118 pattern, 1);
119 }
120
121
122 /* u32 attrs */
123 static const struct strval16 u32_attrs[] = {
124 { ENUM_KNOWN(0x3, IFLA_BRPORT_COST) },
125 { ENUM_KNOWN(0x25, IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT) },
126 { ENUM_KNOWN(0x26, IFLA_BRPORT_MCAST_EHT_HOSTS_CNT) },
127 { ENUM_KNOWN(0x29, IFLA_BRPORT_MCAST_N_GROUPS) },
128 { ENUM_KNOWN(0x2a, IFLA_BRPORT_MCAST_MAX_GROUPS) },
129 };
130 void *nlh_u32 = midtail_alloc(NLMSG_SPACE(hdrlen),
131 NLA_HDRLEN * 2 + sizeof(uint32_t));
132 for (size_t i = 0; i < ARRAY_SIZE(u32_attrs); i++) {
133 check_u32_nlattr(fd, nlh_u32, hdrlen,
134 init_ifinfomsg, print_ifinfomsg,
135 u32_attrs[i].val, u32_attrs[i].str,
136 pattern, 1);
137 }
138
139
140 /* clock_t attrs */
141 static const struct strval16 c_t_attrs[] = {
142 { ENUM_KNOWN(0x15, IFLA_BRPORT_MESSAGE_AGE_TIMER) },
143 { ENUM_KNOWN(0x16, IFLA_BRPORT_FORWARD_DELAY_TIMER) },
144 { ENUM_KNOWN(0x17, IFLA_BRPORT_HOLD_TIMER) },
145 };
146 void *nlh_c_t = midtail_alloc(NLMSG_SPACE(hdrlen),
147 NLA_HDRLEN * 2 + sizeof(uint64_t));
148 for (size_t i = 0; i < ARRAY_SIZE(c_t_attrs); i++) {
149 check_clock_t_nlattr(fd, nlh_c_t, hdrlen,
150 init_ifinfomsg, print_ifinfomsg,
151 c_t_attrs[i].val, c_t_attrs[i].str, 1);
152 }
153
154
155 /* struct ifla_bridge_id attrs */
156 static const struct ifla_bridge_id id = {
157 .prio = { 0xab, 0xcd },
158 .addr = { 0xab, 0xcd, 0xef, 0xac, 0xbc, 0xcd }
159 };
160 static const struct strval16 id_attrs[] = {
161 { ENUM_KNOWN(0xd, IFLA_BRPORT_ROOT_ID) },
162 { ENUM_KNOWN(0xe, IFLA_BRPORT_BRIDGE_ID) },
163 };
164 void *nlh_id = midtail_alloc(NLMSG_SPACE(hdrlen),
165 NLA_HDRLEN * 2 + sizeof(id));
166 for (size_t i = 0; i < ARRAY_SIZE(id_attrs); i++) {
167 TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh_id, hdrlen,
168 init_ifinfomsg, print_ifinfomsg,
169 id_attrs[i].val, id_attrs[i].str,
170 pattern, id, print_quoted_hex, 1,
171 printf("{prio=[%1$u, %2$u], addr="
172 XLAT_KNOWN_FMT("\""
173 "\\x%3$02x\\x%4$02x"
174 "\\x%5$02x\\x%6$02x"
175 "\\x%7$02x\\x%8$02x\"",
176 "%3$02x:%4$02x:%5$02x"
177 ":%6$02x:%7$02x:%8$02x")
178 "}",
179 id.prio[0], id.prio[1],
180 id.addr[0], id.addr[1],
181 id.addr[2], id.addr[3],
182 id.addr[4], id.addr[5]));
183 }
184
185
186 /* ifindex attrs */
187 uint32_t ifidx = 0xbadc0ded;
188 static const struct strval16 if_attrs[] = {
189 { ENUM_KNOWN(0x22, IFLA_BRPORT_BACKUP_PORT) },
190 };
191 for (size_t i = 0; i < ARRAY_SIZE(if_attrs); i++) {
192 ifidx = 0xbadc0ded;
193 TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh_u32, hdrlen,
194 init_ifinfomsg, print_ifinfomsg,
195 if_attrs[i].val, if_attrs[i].str,
196 pattern, ifidx,
197 print_quoted_hex, 1,
198 printf("3134983661"));
199 ifidx = ifindex_lo();
200 TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh_u32, hdrlen,
201 init_ifinfomsg, print_ifinfomsg,
202 if_attrs[i].val, if_attrs[i].str,
203 pattern, ifidx,
204 print_quoted_hex, 1,
205 printf(XLAT_FMT_U,
206 XLAT_SEL(ifidx,
207 IFINDEX_LO_STR)));
208 }
209
210
211 puts("+++ exited with 0 +++");
212 return 0;
213 }