1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3 * Author: Susant Sahani <[email protected]>
4 * Copyright (c) 2018 Red Hat, Inc.
5 */
6
7 #include "nl-default.h"
8
9 #include <linux/netlink.h>
10
11 #include <netlink/route/link.h>
12 #include <netlink/route/link/sit.h>
13 #include <netlink/route/link/bonding.h>
14 #include <netlink/route/link/bridge.h>
15 #include <netlink/route/link/ip6tnl.h>
16 #include <netlink/route/link/ipgre.h>
17 #include <netlink/route/link/ipip.h>
18 #include <netlink/route/link/ipvlan.h>
19 #include <netlink/route/link/ipvti.h>
20 #include <netlink/route/link/macsec.h>
21 #include <netlink/route/link/macvlan.h>
22 #include <netlink/route/link/macvtap.h>
23 #include <netlink/route/link/veth.h>
24 #include <netlink/route/link/vlan.h>
25 #include <netlink/route/link/vrf.h>
26 #include <netlink/route/link/vxlan.h>
27
28 #include "cksuite-all.h"
29
30 /*****************************************************************************/
31
_nltst_delete_link2(const char * ifname)32 static void _nltst_delete_link2(const char *ifname)
33 {
34 _nltst_delete_link(NULL, ifname);
35 }
36 #define _nltst_auto_delete_link _nl_auto(_nltst_auto_delete_link_fcn)
37 _NL_AUTO_DEFINE_FCN_TYPED0(const char *, _nltst_auto_delete_link_fcn,
38 _nltst_delete_link2);
39
40 /*****************************************************************************/
41
START_TEST(cache_and_clone)42 START_TEST(cache_and_clone)
43 {
44 _nl_auto_nl_socket struct nl_sock *sk = NULL;
45 _nl_auto_nl_cache struct nl_cache *link_cache = NULL;
46 _nl_auto_free struct nl_object **links_all = NULL;
47 static const struct {
48 const char *ifname;
49 const char *kind;
50 bool add;
51 } links[] = {
52 {
53 .ifname = "xbr0",
54 .kind = "bridge",
55 .add = true,
56 },
57 {
58 .ifname = "xdummy0",
59 .kind = "dummy",
60 .add = true,
61 },
62 {
63 .ifname = "xbond0",
64 .kind = "bond",
65 .add = true,
66 },
67 {
68 .ifname = "lo",
69 .kind = NULL,
70 .add = false,
71 },
72 };
73 size_t i;
74 int r;
75
76 for (i = 0; i < _NL_N_ELEMENTS(links); i++) {
77 if (links[i].add)
78 _nltst_add_link(NULL, links[i].ifname, links[i].kind,
79 NULL);
80 }
81
82 sk = _nltst_socket(NETLINK_ROUTE);
83
84 r = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache);
85 ck_assert_int_eq(r, 0);
86
87 r = nl_cache_refill(sk, link_cache);
88 ck_assert_int_eq(r, 0);
89
90 for (i = 0; i < _NL_N_ELEMENTS(links); i++) {
91 _nl_auto_rtnl_link struct rtnl_link *link_clone = NULL;
92 struct rtnl_link *link;
93
94 link = _nltst_cache_get_link(link_cache, links[i].ifname);
95 ck_assert_ptr_nonnull(link);
96
97 ck_assert_str_eq(rtnl_link_get_name(link), links[i].ifname);
98
99 if (_nl_streq(links[i].ifname, "lo"))
100 ck_assert_int_eq(rtnl_link_get_ifindex(link), 1);
101 else
102 ck_assert_int_gt(rtnl_link_get_ifindex(link), 1);
103
104 link_clone = (struct rtnl_link *)nl_object_clone(
105 (struct nl_object *)link);
106 ck_assert(link_clone);
107
108 _nltst_object_identical(link, link_clone);
109 }
110
111 links_all = _nltst_cache_get_all(link_cache, NULL);
112 for (i = 0; links_all[i]; i++) {
113 struct rtnl_link *link = (struct rtnl_link *)links_all[i];
114 _nl_auto_rtnl_link struct rtnl_link *link_clone = NULL;
115
116 link_clone = (struct rtnl_link *)nl_object_clone(
117 (struct nl_object *)link);
118 ck_assert(link_clone);
119
120 _nltst_object_identical(link, link_clone);
121 }
122 }
123 END_TEST
124
125 /*****************************************************************************/
126
START_TEST(test_create_iface)127 START_TEST(test_create_iface)
128 {
129 const int TEST_IDX = _i;
130 _nl_auto_nl_socket struct nl_sock *sk = _nltst_socket(NETLINK_ROUTE);
131 _nl_auto_rtnl_link struct rtnl_link *link = NULL;
132 _nl_auto_rtnl_link struct rtnl_link *link2 = NULL;
133 _nl_auto_rtnl_link struct rtnl_link *peer = NULL;
134 _nltst_auto_delete_link const char *IFNAME_DUMMY = NULL;
135 _nltst_auto_delete_link const char *IFNAME = "ifname";
136 int ifindex_dummy;
137 uint32_t u32;
138 int r;
139
140 switch (TEST_IDX) {
141 case 0:
142 link = _nltst_assert(rtnl_link_bridge_alloc());
143 rtnl_link_set_name(link, IFNAME);
144 break;
145 case 1:
146 link = _nltst_assert(rtnl_link_vxlan_alloc());
147 rtnl_link_set_name(link, IFNAME);
148 _nltst_assert_retcode(rtnl_link_vxlan_set_id(link, 128));
149 break;
150 case 2:
151 link = _nltst_assert(rtnl_link_alloc());
152 rtnl_link_set_type(link, "ifb");
153 rtnl_link_set_name(link, IFNAME);
154 break;
155 case 3:
156 link = _nltst_assert(rtnl_link_ipgre_alloc());
157 rtnl_link_set_name(link, IFNAME);
158 _nltst_assert_retcode(rtnl_link_ipgre_set_local(
159 link, _nltst_inet4("192.168.254.12")));
160 _nltst_assert_retcode(rtnl_link_ipgre_set_remote(
161 link, _nltst_inet4("192.168.254.13")));
162 _nltst_assert_retcode(rtnl_link_ipgre_set_ttl(link, 64));
163 break;
164 case 4:
165 link = _nltst_assert(rtnl_link_ip6_tnl_alloc());
166 rtnl_link_set_name(link, IFNAME);
167 _nltst_assert_retcode(rtnl_link_ip6_tnl_set_local(
168 link, _nltst_inet6p("2607:f0d0:1002:51::4")));
169 _nltst_assert_retcode(rtnl_link_ip6_tnl_set_remote(
170 link, _nltst_inet6p("2607:f0d0:1002:52::5")));
171 break;
172 case 5:
173 link = _nltst_assert(rtnl_link_ipgretap_alloc());
174 rtnl_link_set_name(link, IFNAME);
175 _nltst_assert_retcode(rtnl_link_ipgre_set_local(
176 link, _nltst_inet4("10.211.55.10")));
177 _nltst_assert_retcode(rtnl_link_ipgre_set_remote(
178 link, _nltst_inet4("10.133.6.33")));
179 _nltst_assert_retcode(rtnl_link_ipgre_set_ttl(link, 64));
180 break;
181 case 6:
182 link = _nltst_assert(rtnl_link_ipvti_alloc());
183 rtnl_link_set_name(link, IFNAME);
184 _nltst_assert_retcode(rtnl_link_ipvti_set_local(
185 link, _nltst_inet4("192.168.254.12")));
186 _nltst_assert_retcode(rtnl_link_ipvti_set_remote(
187 link, _nltst_inet4("192.168.254.13")));
188 break;
189 case 7:
190 link = _nltst_assert(rtnl_link_sit_alloc());
191 rtnl_link_set_name(link, IFNAME);
192 _nltst_assert_retcode(rtnl_link_sit_set_local(
193 link, _nltst_inet4("192.168.254.12")));
194 _nltst_assert_retcode(rtnl_link_sit_set_remote(
195 link, _nltst_inet4("192.168.254.13")));
196 _nltst_assert_retcode(rtnl_link_sit_set_ttl(link, 64));
197 break;
198 case 8:
199 link = _nltst_assert(rtnl_link_ipip_alloc());
200 rtnl_link_set_name(link, IFNAME);
201 _nltst_assert_retcode(rtnl_link_ipip_set_local(
202 link, _nltst_inet4("192.168.254.12")));
203 _nltst_assert_retcode(rtnl_link_ipip_set_remote(
204 link, _nltst_inet4("192.168.254.13")));
205 _nltst_assert_retcode(rtnl_link_ipip_set_ttl(link, 64));
206 break;
207 case 9:
208 link = _nltst_assert(rtnl_link_bond_alloc());
209 rtnl_link_set_name(link, IFNAME);
210 break;
211 case 10:
212 IFNAME_DUMMY = "ci-dummy";
213 _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
214
215 link = _nltst_assert(rtnl_link_macvtap_alloc());
216 rtnl_link_set_link(link, ifindex_dummy);
217 rtnl_link_set_name(link, IFNAME);
218 _nltst_assert_retcode(rtnl_link_macvtap_set_mode(
219 link, rtnl_link_macvtap_str2mode("bridge")));
220 break;
221 case 11:
222 IFNAME_DUMMY = "ci-dummy";
223 _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
224
225 link = _nltst_assert(rtnl_link_macvlan_alloc());
226 rtnl_link_set_link(link, ifindex_dummy);
227 rtnl_link_set_name(link, IFNAME);
228 break;
229 case 12:
230 IFNAME_DUMMY = "ci-dummy";
231 _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
232
233 link = _nltst_assert(rtnl_link_vlan_alloc());
234 rtnl_link_set_link(link, ifindex_dummy);
235 rtnl_link_set_name(link, IFNAME);
236 _nltst_assert_retcode(rtnl_link_vlan_set_id(link, 10));
237 break;
238 case 13:
239 IFNAME_DUMMY = "ci-dummy";
240 _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
241
242 link = _nltst_assert(rtnl_link_macsec_alloc());
243 rtnl_link_set_link(link, ifindex_dummy);
244 rtnl_link_set_name(link, IFNAME);
245 _nltst_assert_retcode(rtnl_link_macsec_set_port(link, 10));
246 _nltst_assert_retcode(rtnl_link_macsec_set_encrypt(link, 1));
247 _nltst_assert_retcode(
248 rtnl_link_macsec_set_replay_protect(link, 1));
249 _nltst_assert_retcode(rtnl_link_macsec_set_window(link, 200));
250 break;
251 case 14:
252 IFNAME_DUMMY = "ci-dummy";
253 _nltst_add_link(sk, IFNAME_DUMMY, "dummy", &ifindex_dummy);
254
255 link = _nltst_assert(rtnl_link_ipvlan_alloc());
256 rtnl_link_set_link(link, ifindex_dummy);
257 _nltst_assert_retcode(rtnl_link_ipvlan_set_mode(
258 link, rtnl_link_ipvlan_str2mode("l2")));
259 rtnl_link_set_name(link, IFNAME);
260 break;
261 case 15:
262 link = _nltst_assert(rtnl_link_vrf_alloc());
263 rtnl_link_set_name(link, IFNAME);
264 _nltst_assert_retcode(rtnl_link_vrf_set_tableid(link, 10));
265 break;
266 case 16: {
267 link = _nltst_assert(rtnl_link_veth_alloc());
268 rtnl_link_set_name(link, IFNAME);
269 peer = _nltst_assert(rtnl_link_veth_get_peer(link));
270 rtnl_link_set_name(peer, "ci-veth-peer");
271 } break;
272 default:
273 ck_assert_msg(0, "unexpected TEST_IDX=%d", _i);
274 break;
275 }
276
277 r = rtnl_link_add(sk, link, NLM_F_CREATE);
278 if (r == -NLE_OPNOTSUPP) {
279 /* Hm, no kernel module? Skip the test. */
280 _nltst_assert_link_not_exists(IFNAME);
281 IFNAME = NULL;
282 return;
283 }
284 _nltst_assert_retcode(r);
285
286 _nltst_assert_link_exists(IFNAME);
287
288 switch (TEST_IDX) {
289 case 15:
290 _nltst_get_link(sk, IFNAME, NULL, &link2);
291 _nltst_assert_retcode(rtnl_link_vrf_get_tableid(link2, &u32));
292 ck_assert_int_eq(u32, 10);
293 break;
294 case 16:
295 _nltst_assert_link_exists("ci-veth-peer");
296 if (_nltst_rand_bool())
297 IFNAME = "ci-veth-peer";
298 break;
299 }
300 }
301 END_TEST
302
303 /*****************************************************************************/
304
_route_init(int addr_family,struct nl_sock ** sk,struct nl_cache ** cache)305 static void _route_init(int addr_family, struct nl_sock **sk,
306 struct nl_cache **cache)
307 {
308 ck_assert(sk && !*sk);
309 ck_assert(cache && !*cache);
310
311 *sk = _nltst_socket(NETLINK_ROUTE);
312 *cache = _nltst_rtnl_route_alloc_cache(*sk, addr_family);
313 }
314
START_TEST(route_1)315 START_TEST(route_1)
316 {
317 _nl_auto_nl_socket struct nl_sock *sk = NULL;
318 _nl_auto_nl_cache struct nl_cache *cache = NULL;
319
320 if (_nltst_skip_no_iproute2("route_1"))
321 return;
322
323 _nltst_add_link(NULL, "v1", "dummy", NULL);
324 _nltst_system("ip -d link set v1 up");
325
326 _route_init(AF_INET6, &sk, &cache);
327
328 _nltst_assert_route_cache(cache, "fe80::/64", "6 fe80::*/128",
329 "ff00::/8");
330 }
331 END_TEST
332
333 /*****************************************************************************/
334
make_nl_netns_suite(void)335 Suite *make_nl_netns_suite(void)
336 {
337 Suite *suite = suite_create("netns");
338 TCase *tc = tcase_create("Core");
339
340 tcase_add_checked_fixture(tc, nltst_netns_fixture_setup,
341 nltst_netns_fixture_teardown);
342 tcase_add_test(tc, cache_and_clone);
343 tcase_add_loop_test(tc, test_create_iface, 0, 17);
344 tcase_add_test(tc, route_1);
345 suite_add_tcase(suite, tc);
346
347 return suite;
348 }
349