]>
Commit | Line | Data |
---|---|---|
74971473 JG |
1 | /* |
2 | * This file is part of the PCEPlib, a PCEP protocol library. | |
3 | * | |
4 | * Copyright (C) 2020 Volta Networks https://voltanet.io/ | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public License | |
17 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
18 | * | |
19 | * Author : Brady Johnson <brady@voltanet.io> | |
20 | * | |
21 | */ | |
22 | ||
23 | ||
1f8031f7 DL |
24 | #ifdef HAVE_CONFIG_H |
25 | #include "config.h" | |
26 | #endif | |
27 | ||
74971473 JG |
28 | #include <stdlib.h> |
29 | ||
30 | #include <CUnit/CUnit.h> | |
31 | ||
32 | #include "pcep_msg_encoding.h" | |
33 | #include "pcep_msg_objects.h" | |
34 | #include "pcep_msg_tools.h" | |
35 | #include "pcep_utils_memory.h" | |
36 | #include "pcep_msg_objects_test.h" | |
37 | ||
38 | /* | |
39 | * Notice: | |
40 | * All of these object Unit Tests encode the created objects by explicitly | |
41 | * calling pcep_encode_object() thus testing the object creation and the object | |
42 | * encoding. All APIs expect IPs to be in network byte order. | |
43 | */ | |
44 | ||
45 | static struct pcep_versioning *versioning = NULL; | |
46 | static uint8_t object_buf[2000]; | |
47 | ||
48 | void reset_objects_buffer(void); | |
49 | ||
50 | int pcep_objects_test_suite_setup(void) | |
51 | { | |
52 | pceplib_memory_reset(); | |
53 | return 0; | |
54 | } | |
55 | ||
56 | int pcep_objects_test_suite_teardown(void) | |
57 | { | |
58 | printf("\n"); | |
59 | pceplib_memory_dump(); | |
60 | return 0; | |
61 | } | |
62 | ||
63 | void reset_objects_buffer() | |
64 | { | |
65 | memset(object_buf, 0, 2000); | |
66 | } | |
67 | ||
68 | void pcep_objects_test_setup() | |
69 | { | |
70 | versioning = create_default_pcep_versioning(); | |
71 | reset_objects_buffer(); | |
72 | } | |
73 | ||
74 | void pcep_objects_test_teardown() | |
75 | { | |
76 | destroy_pcep_versioning(versioning); | |
77 | } | |
78 | ||
79 | /* Internal util verification function */ | |
80 | static void verify_pcep_obj_header2(uint8_t obj_class, uint8_t obj_type, | |
81 | uint16_t obj_length, const uint8_t *obj_buf) | |
82 | { | |
83 | /* Object Header | |
84 | * | |
85 | * 0 1 2 3 | |
86 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
87 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
88 | * | Object-Class | OT |Res|P|I| Object Length (bytes) | | |
89 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
90 | */ | |
91 | ||
92 | /* Not using CU_ASSERT_EQUAL here, so that in case of failure, | |
93 | * we can provide more info in the error message. */ | |
94 | if (obj_buf[0] != obj_class) { | |
95 | fprintf(stderr, | |
96 | "Test failure obj_class expected [%d] found [%d]\n", | |
97 | obj_class, obj_buf[0]); | |
98 | CU_FAIL("Object Header Class"); | |
99 | } | |
100 | ||
101 | uint8_t found8 = (obj_buf[1] >> 4) & 0x0f; | |
102 | if (obj_type != found8) { | |
103 | fprintf(stderr, | |
104 | "Test failure obj_class [%d] obj_type expected [%d] found [%d]\n", | |
105 | obj_class, obj_type, found8); | |
106 | CU_FAIL("Object Header Type"); | |
107 | } | |
108 | ||
109 | uint8_t exp8 = 0; | |
110 | found8 = obj_buf[1] & 0x0f; | |
111 | if (exp8 != found8) { | |
112 | fprintf(stderr, | |
113 | "Test failure obj_class [%d] flags expected [%d] found [%d]\n", | |
114 | obj_class, exp8, found8); | |
115 | CU_FAIL("Object Header Flags"); | |
116 | } | |
117 | ||
118 | uint16_t found16 = ntohs(*((uint16_t *)(obj_buf + 2))); | |
119 | if (obj_length != found16) { | |
120 | fprintf(stderr, | |
121 | "Test failure obj_class [%d] obj_length expected [%d] found [%d]\n", | |
122 | obj_class, obj_length, found16); | |
123 | CU_FAIL("Object Header Length"); | |
124 | } | |
125 | } | |
126 | ||
127 | /* Internal util verification function */ | |
128 | static void verify_pcep_obj_header(uint8_t obj_class, uint8_t obj_type, | |
129 | struct pcep_object_header *obj_hdr) | |
130 | { | |
131 | verify_pcep_obj_header2(obj_class, obj_type, | |
132 | pcep_object_get_length_by_hdr(obj_hdr), | |
133 | obj_hdr->encoded_object); | |
134 | } | |
135 | ||
136 | void test_pcep_obj_create_open() | |
137 | { | |
138 | uint8_t deadtimer = 60; | |
139 | uint8_t keepalive = 30; | |
140 | uint8_t sid = 1; | |
141 | ||
142 | struct pcep_object_open *open = | |
143 | pcep_obj_create_open(keepalive, deadtimer, sid, NULL); | |
144 | ||
145 | CU_ASSERT_PTR_NOT_NULL(open); | |
146 | pcep_encode_object(&open->header, versioning, object_buf); | |
147 | verify_pcep_obj_header(PCEP_OBJ_CLASS_OPEN, PCEP_OBJ_TYPE_OPEN, | |
148 | &open->header); | |
149 | ||
150 | CU_ASSERT_EQUAL(open->header.encoded_object[4], | |
151 | (PCEP_OBJECT_OPEN_VERSION << 5) & 0xe0); | |
152 | CU_ASSERT_EQUAL(open->header.encoded_object[4] & 0x1f, 0); | |
153 | CU_ASSERT_EQUAL(open->header.encoded_object[5], keepalive); | |
154 | CU_ASSERT_EQUAL(open->header.encoded_object[6], deadtimer); | |
155 | CU_ASSERT_EQUAL(open->header.encoded_object[7], sid); | |
156 | ||
157 | pcep_obj_free_object((struct pcep_object_header *)open); | |
158 | } | |
159 | ||
160 | void test_pcep_obj_create_open_with_tlvs() | |
161 | { | |
162 | uint8_t deadtimer = 60; | |
163 | uint8_t keepalive = 30; | |
164 | uint8_t sid = 1; | |
165 | double_linked_list *tlv_list = dll_initialize(); | |
166 | ||
167 | struct pcep_object_tlv_stateful_pce_capability *tlv = | |
168 | pcep_tlv_create_stateful_pce_capability(true, true, true, true, | |
169 | true, true); | |
170 | dll_append(tlv_list, tlv); | |
171 | struct pcep_object_open *open = | |
172 | pcep_obj_create_open(keepalive, deadtimer, sid, tlv_list); | |
173 | ||
174 | CU_ASSERT_PTR_NOT_NULL(open); | |
175 | pcep_encode_object(&open->header, versioning, object_buf); | |
176 | verify_pcep_obj_header2(PCEP_OBJ_CLASS_OPEN, PCEP_OBJ_TYPE_OPEN, | |
177 | pcep_object_get_length_by_hdr(&open->header) | |
178 | + sizeof(uint32_t) * 2, | |
179 | open->header.encoded_object); | |
180 | CU_ASSERT_PTR_NOT_NULL(open->header.tlv_list); | |
181 | CU_ASSERT_EQUAL(open->header.tlv_list->num_entries, 1); | |
182 | ||
183 | CU_ASSERT_EQUAL(open->header.encoded_object[4], | |
184 | (PCEP_OBJECT_OPEN_VERSION << 5) & 0xe0); | |
185 | CU_ASSERT_EQUAL(open->header.encoded_object[4] & 0x1f, 0); | |
186 | CU_ASSERT_EQUAL(open->header.encoded_object[5], keepalive); | |
187 | CU_ASSERT_EQUAL(open->header.encoded_object[6], deadtimer); | |
188 | CU_ASSERT_EQUAL(open->header.encoded_object[7], sid); | |
189 | ||
190 | pcep_obj_free_object((struct pcep_object_header *)open); | |
191 | } | |
192 | ||
193 | void test_pcep_obj_create_rp() | |
194 | { | |
195 | uint32_t reqid = 15; | |
196 | uint8_t invalid_priority = 100; | |
197 | uint8_t priority = 7; | |
198 | ||
199 | struct pcep_object_rp *rp = pcep_obj_create_rp( | |
200 | invalid_priority, true, false, false, true, reqid, NULL); | |
201 | CU_ASSERT_PTR_NULL(rp); | |
202 | ||
203 | rp = pcep_obj_create_rp(priority, true, false, false, true, reqid, | |
204 | NULL); | |
205 | CU_ASSERT_PTR_NOT_NULL(rp); | |
206 | pcep_encode_object(&rp->header, versioning, object_buf); | |
207 | verify_pcep_obj_header(PCEP_OBJ_CLASS_RP, PCEP_OBJ_TYPE_RP, | |
208 | &rp->header); | |
209 | ||
210 | CU_ASSERT_EQUAL(rp->header.encoded_object[4], 0); | |
211 | CU_ASSERT_EQUAL(rp->header.encoded_object[5], 0); | |
212 | CU_ASSERT_EQUAL(rp->header.encoded_object[6], 0); | |
213 | CU_ASSERT_EQUAL((rp->header.encoded_object[7] & 0x07), priority); | |
214 | CU_ASSERT_TRUE(rp->header.encoded_object[7] & OBJECT_RP_FLAG_R); | |
215 | CU_ASSERT_TRUE(rp->header.encoded_object[7] & OBJECT_RP_FLAG_OF); | |
216 | CU_ASSERT_TRUE(rp->header.encoded_object[7] & ~OBJECT_RP_FLAG_B); | |
217 | CU_ASSERT_TRUE(rp->header.encoded_object[7] & ~OBJECT_RP_FLAG_O); | |
218 | CU_ASSERT_EQUAL(*((uint32_t *)(rp->header.encoded_object + 8)), | |
219 | htonl(reqid)); | |
220 | ||
221 | pcep_obj_free_object((struct pcep_object_header *)rp); | |
222 | } | |
223 | ||
224 | void test_pcep_obj_create_nopath() | |
225 | { | |
226 | uint8_t ni = 8; | |
227 | uint32_t errorcode = 42; | |
228 | ||
229 | struct pcep_object_nopath *nopath = | |
230 | pcep_obj_create_nopath(ni, true, errorcode); | |
231 | ||
232 | CU_ASSERT_PTR_NOT_NULL(nopath); | |
233 | pcep_encode_object(&nopath->header, versioning, object_buf); | |
234 | verify_pcep_obj_header(PCEP_OBJ_CLASS_NOPATH, PCEP_OBJ_TYPE_NOPATH, | |
235 | &nopath->header); | |
236 | ||
237 | CU_ASSERT_EQUAL(nopath->header.encoded_object[4], ni); | |
238 | CU_ASSERT_TRUE(nopath->header.encoded_object[5] & OBJECT_NOPATH_FLAG_C); | |
239 | CU_ASSERT_EQUAL(nopath->header.encoded_object[6], 0); | |
240 | CU_ASSERT_EQUAL(nopath->header.encoded_object[7], 0); | |
241 | ||
242 | /* Verify the TLV */ | |
243 | CU_ASSERT_PTR_NOT_NULL(nopath->header.tlv_list); | |
244 | struct pcep_object_tlv_nopath_vector *tlv = | |
245 | (struct pcep_object_tlv_nopath_vector *) | |
246 | nopath->header.tlv_list->head->data; | |
247 | CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, 4); | |
248 | CU_ASSERT_EQUAL(tlv->header.type, 1); | |
249 | CU_ASSERT_EQUAL(tlv->error_code, errorcode); | |
250 | ||
251 | CU_ASSERT_EQUAL(*((uint16_t *)(nopath->header.encoded_object + 8)), | |
252 | htons(PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR)); | |
253 | CU_ASSERT_EQUAL(*((uint16_t *)(nopath->header.encoded_object + 10)), | |
254 | htons(4)); | |
255 | CU_ASSERT_EQUAL(*((uint32_t *)(nopath->header.encoded_object + 12)), | |
256 | htonl(errorcode)); | |
257 | ||
258 | pcep_obj_free_object((struct pcep_object_header *)nopath); | |
259 | } | |
260 | void test_pcep_obj_create_association_ipv4() | |
261 | { | |
262 | ||
263 | uint16_t all_assoc_groups = 0xffff; | |
264 | struct in_addr src; | |
265 | inet_pton(AF_INET, "192.168.1.2", &src); | |
266 | ||
267 | struct pcep_object_association_ipv4 *assoc = | |
268 | pcep_obj_create_association_ipv4( | |
269 | false, PCEP_ASSOCIATION_TYPE_SR_POLICY_ASSOCIATION_TYPE, | |
270 | all_assoc_groups, src); | |
271 | CU_ASSERT_PTR_NOT_NULL(assoc); | |
272 | CU_ASSERT_EQUAL(assoc->association_type, | |
273 | PCEP_ASSOCIATION_TYPE_SR_POLICY_ASSOCIATION_TYPE); | |
274 | CU_ASSERT_EQUAL(assoc->association_id, all_assoc_groups); | |
275 | CU_ASSERT_EQUAL(assoc->header.object_class, PCEP_OBJ_CLASS_ASSOCIATION); | |
276 | CU_ASSERT_EQUAL(assoc->header.object_type, | |
277 | PCEP_OBJ_TYPE_ASSOCIATION_IPV4); | |
278 | CU_ASSERT_EQUAL(assoc->src.s_addr, src.s_addr); | |
279 | ||
280 | pcep_obj_free_object((struct pcep_object_header *)assoc); | |
281 | } | |
282 | ||
283 | void test_pcep_obj_create_association_ipv6() | |
284 | { | |
285 | uint32_t all_assoc_groups = 0xffff; | |
286 | struct in6_addr src; | |
287 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &src); | |
288 | ||
289 | struct pcep_object_association_ipv6 *assoc = | |
290 | pcep_obj_create_association_ipv6( | |
291 | false, PCEP_ASSOCIATION_TYPE_SR_POLICY_ASSOCIATION_TYPE, | |
292 | all_assoc_groups, src); | |
293 | CU_ASSERT_PTR_NOT_NULL(assoc); | |
294 | CU_ASSERT_EQUAL(assoc->association_type, | |
295 | PCEP_ASSOCIATION_TYPE_SR_POLICY_ASSOCIATION_TYPE); | |
296 | CU_ASSERT_EQUAL(assoc->association_id, all_assoc_groups); | |
297 | CU_ASSERT_EQUAL(assoc->header.object_class, PCEP_OBJ_CLASS_ASSOCIATION); | |
298 | CU_ASSERT_EQUAL(assoc->header.object_type, | |
299 | PCEP_OBJ_TYPE_ASSOCIATION_IPV6); | |
300 | CU_ASSERT_EQUAL(assoc->src.__in6_u.__u6_addr32[0], | |
301 | (src.__in6_u.__u6_addr32[0])); | |
302 | CU_ASSERT_EQUAL(assoc->src.__in6_u.__u6_addr32[1], | |
303 | (src.__in6_u.__u6_addr32[1])); | |
304 | CU_ASSERT_EQUAL(assoc->src.__in6_u.__u6_addr32[2], | |
305 | (src.__in6_u.__u6_addr32[2])); | |
306 | CU_ASSERT_EQUAL(assoc->src.__in6_u.__u6_addr32[3], | |
307 | (src.__in6_u.__u6_addr32[3])); | |
308 | ||
309 | pcep_obj_free_object((struct pcep_object_header *)assoc); | |
310 | } | |
311 | ||
312 | void test_pcep_obj_create_endpoint_ipv4() | |
313 | { | |
314 | struct in_addr src_ipv4, dst_ipv4; | |
315 | inet_pton(AF_INET, "192.168.1.2", &src_ipv4); | |
316 | inet_pton(AF_INET, "172.168.1.2", &dst_ipv4); | |
317 | ||
318 | struct pcep_object_endpoints_ipv4 *ipv4 = | |
319 | pcep_obj_create_endpoint_ipv4(NULL, NULL); | |
320 | CU_ASSERT_PTR_NULL(ipv4); | |
321 | ||
322 | ipv4 = pcep_obj_create_endpoint_ipv4(&src_ipv4, NULL); | |
323 | CU_ASSERT_PTR_NULL(ipv4); | |
324 | ||
325 | ipv4 = pcep_obj_create_endpoint_ipv4(NULL, &dst_ipv4); | |
326 | CU_ASSERT_PTR_NULL(ipv4); | |
327 | ||
328 | ipv4 = pcep_obj_create_endpoint_ipv4(&src_ipv4, &dst_ipv4); | |
329 | CU_ASSERT_PTR_NOT_NULL(ipv4); | |
330 | pcep_encode_object(&ipv4->header, versioning, object_buf); | |
331 | verify_pcep_obj_header(PCEP_OBJ_CLASS_ENDPOINTS, | |
332 | PCEP_OBJ_TYPE_ENDPOINT_IPV4, &ipv4->header); | |
333 | CU_ASSERT_EQUAL(*((uint32_t *)(ipv4->header.encoded_object + 4)), | |
334 | src_ipv4.s_addr); | |
335 | CU_ASSERT_EQUAL(*((uint32_t *)(ipv4->header.encoded_object + 8)), | |
336 | dst_ipv4.s_addr); | |
337 | ||
338 | pcep_obj_free_object((struct pcep_object_header *)ipv4); | |
339 | } | |
340 | ||
341 | void test_pcep_obj_create_endpoint_ipv6() | |
342 | { | |
343 | struct in6_addr src_ipv6, dst_ipv6; | |
344 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &src_ipv6); | |
345 | inet_pton(AF_INET6, "2001:db8::8a2e:370:8446", &dst_ipv6); | |
346 | ||
347 | struct pcep_object_endpoints_ipv6 *ipv6 = | |
348 | pcep_obj_create_endpoint_ipv6(NULL, NULL); | |
349 | CU_ASSERT_PTR_NULL(ipv6); | |
350 | ||
351 | ipv6 = pcep_obj_create_endpoint_ipv6(&src_ipv6, NULL); | |
352 | CU_ASSERT_PTR_NULL(ipv6); | |
353 | ||
354 | ipv6 = pcep_obj_create_endpoint_ipv6(NULL, &dst_ipv6); | |
355 | CU_ASSERT_PTR_NULL(ipv6); | |
356 | ||
357 | ipv6 = pcep_obj_create_endpoint_ipv6(&src_ipv6, &dst_ipv6); | |
358 | CU_ASSERT_PTR_NOT_NULL(ipv6); | |
359 | pcep_encode_object(&ipv6->header, versioning, object_buf); | |
360 | verify_pcep_obj_header(PCEP_OBJ_CLASS_ENDPOINTS, | |
361 | PCEP_OBJ_TYPE_ENDPOINT_IPV6, &ipv6->header); | |
362 | uint32_t *uint32_ptr = (uint32_t *)(ipv6->header.encoded_object + 4); | |
363 | CU_ASSERT_EQUAL(uint32_ptr[0], src_ipv6.__in6_u.__u6_addr32[0]); | |
364 | CU_ASSERT_EQUAL(uint32_ptr[1], src_ipv6.__in6_u.__u6_addr32[1]); | |
365 | CU_ASSERT_EQUAL(uint32_ptr[2], src_ipv6.__in6_u.__u6_addr32[2]); | |
366 | CU_ASSERT_EQUAL(uint32_ptr[3], src_ipv6.__in6_u.__u6_addr32[3]); | |
367 | CU_ASSERT_EQUAL(uint32_ptr[4], dst_ipv6.__in6_u.__u6_addr32[0]); | |
368 | CU_ASSERT_EQUAL(uint32_ptr[5], dst_ipv6.__in6_u.__u6_addr32[1]); | |
369 | CU_ASSERT_EQUAL(uint32_ptr[6], dst_ipv6.__in6_u.__u6_addr32[2]); | |
370 | CU_ASSERT_EQUAL(uint32_ptr[7], dst_ipv6.__in6_u.__u6_addr32[3]); | |
371 | ||
372 | pcep_obj_free_object((struct pcep_object_header *)ipv6); | |
373 | } | |
374 | ||
375 | void test_pcep_obj_create_bandwidth() | |
376 | { | |
377 | /* 1.8 => binary 1.11001101 | |
378 | * exponent = 127 => 0111 1111 | |
379 | * fraction = 1100 1101 0000 0000 0000 000 */ | |
380 | float bandwidth = 1.8; | |
381 | ||
382 | struct pcep_object_bandwidth *bw = pcep_obj_create_bandwidth(bandwidth); | |
383 | ||
384 | CU_ASSERT_PTR_NOT_NULL(bw); | |
385 | pcep_encode_object(&bw->header, versioning, object_buf); | |
386 | verify_pcep_obj_header(PCEP_OBJ_CLASS_BANDWIDTH, | |
387 | PCEP_OBJ_TYPE_BANDWIDTH_REQ, &bw->header); | |
388 | CU_ASSERT_EQUAL(bw->header.encoded_object[4], 0x3f); | |
389 | CU_ASSERT_EQUAL(bw->header.encoded_object[5], 0xe6); | |
390 | CU_ASSERT_EQUAL(bw->header.encoded_object[6], 0x66); | |
391 | CU_ASSERT_EQUAL(bw->header.encoded_object[7], 0x66); | |
392 | ||
393 | pcep_obj_free_object((struct pcep_object_header *)bw); | |
394 | } | |
395 | ||
396 | void test_pcep_obj_create_metric() | |
397 | { | |
398 | uint8_t type = PCEP_METRIC_BORDER_NODE_COUNT; | |
399 | /* https://en.wikipedia.org/wiki/IEEE_754-1985 | |
400 | * 0.15625 = 1/8 + 1/32 = binary 0.00101 = 1.01 x 10^-3 | |
401 | * Exponent bias = 127, so exponent = (127-3) = 124 = 0111 1100 | |
402 | * Sign Exponent Fraction | |
403 | * (8 bits) (23 bits) | |
404 | * 0.15625 => 0 0111 1100 010 0000 ... 0000 */ | |
405 | float value = 0.15625; | |
406 | ||
407 | struct pcep_object_metric *metric = | |
408 | pcep_obj_create_metric(type, true, true, value); | |
409 | ||
410 | CU_ASSERT_PTR_NOT_NULL(metric); | |
411 | pcep_encode_object(&metric->header, versioning, object_buf); | |
412 | verify_pcep_obj_header(PCEP_OBJ_CLASS_METRIC, PCEP_OBJ_TYPE_METRIC, | |
413 | &metric->header); | |
414 | CU_ASSERT_EQUAL(metric->header.encoded_object[4], 0); | |
415 | CU_ASSERT_EQUAL(metric->header.encoded_object[5], 0); | |
416 | CU_ASSERT_TRUE(metric->header.encoded_object[6] & OBJECT_METRIC_FLAC_B); | |
417 | CU_ASSERT_TRUE(metric->header.encoded_object[6] & OBJECT_METRIC_FLAC_C); | |
418 | CU_ASSERT_EQUAL(metric->header.encoded_object[7], type); | |
419 | /* See comments above for explanation of these values */ | |
420 | CU_ASSERT_EQUAL(metric->header.encoded_object[8], 0x3e); | |
421 | CU_ASSERT_EQUAL(metric->header.encoded_object[9], 0x20); | |
422 | CU_ASSERT_EQUAL(metric->header.encoded_object[10], 0x00); | |
423 | CU_ASSERT_EQUAL(metric->header.encoded_object[11], 0x00); | |
424 | ||
425 | pcep_obj_free_object((struct pcep_object_header *)metric); | |
426 | } | |
427 | ||
428 | void test_pcep_obj_create_lspa() | |
429 | { | |
430 | uint32_t exclude_any = 10; | |
431 | uint32_t include_any = 20; | |
432 | uint32_t include_all = 30; | |
433 | uint8_t prio = 0; | |
434 | uint8_t hold_prio = 10; | |
435 | ||
436 | struct pcep_object_lspa *lspa = pcep_obj_create_lspa( | |
437 | exclude_any, include_any, include_all, prio, hold_prio, true); | |
438 | ||
439 | CU_ASSERT_PTR_NOT_NULL(lspa); | |
440 | pcep_encode_object(&lspa->header, versioning, object_buf); | |
441 | verify_pcep_obj_header(PCEP_OBJ_CLASS_LSPA, PCEP_OBJ_TYPE_LSPA, | |
442 | &lspa->header); | |
443 | uint32_t *uint32_ptr = (uint32_t *)(lspa->header.encoded_object + 4); | |
444 | CU_ASSERT_EQUAL(uint32_ptr[0], htonl(exclude_any)); | |
445 | CU_ASSERT_EQUAL(uint32_ptr[1], htonl(include_any)); | |
446 | CU_ASSERT_EQUAL(uint32_ptr[2], htonl(include_all)); | |
447 | CU_ASSERT_EQUAL(lspa->header.encoded_object[16], prio); | |
448 | CU_ASSERT_EQUAL(lspa->header.encoded_object[17], hold_prio); | |
449 | CU_ASSERT_TRUE(lspa->header.encoded_object[18] & OBJECT_LSPA_FLAG_L); | |
450 | CU_ASSERT_EQUAL(lspa->header.encoded_object[19], 0); | |
451 | ||
452 | pcep_obj_free_object((struct pcep_object_header *)lspa); | |
453 | } | |
454 | ||
455 | void test_pcep_obj_create_svec() | |
456 | { | |
457 | struct pcep_object_svec *svec = | |
458 | pcep_obj_create_svec(true, true, true, NULL); | |
459 | CU_ASSERT_PTR_NULL(svec); | |
460 | ||
461 | double_linked_list *id_list = dll_initialize(); | |
462 | uint32_t *uint32_ptr = | |
463 | pceplib_malloc(PCEPLIB_MESSAGES, sizeof(uint32_t)); | |
464 | *uint32_ptr = 10; | |
465 | dll_append(id_list, uint32_ptr); | |
466 | ||
467 | svec = pcep_obj_create_svec(true, true, true, id_list); | |
468 | CU_ASSERT_PTR_NOT_NULL(svec); | |
469 | pcep_encode_object(&svec->header, versioning, object_buf); | |
470 | verify_pcep_obj_header2(PCEP_OBJ_CLASS_SVEC, PCEP_OBJ_TYPE_SVEC, | |
471 | (OBJECT_HEADER_LENGTH + sizeof(uint32_t) * 2), | |
472 | svec->header.encoded_object); | |
473 | CU_ASSERT_EQUAL(svec->header.encoded_object[4], 0); | |
474 | CU_ASSERT_EQUAL(svec->header.encoded_object[5], 0); | |
475 | CU_ASSERT_EQUAL(svec->header.encoded_object[6], 0); | |
476 | CU_ASSERT_TRUE(svec->header.encoded_object[7] & OBJECT_SVEC_FLAG_S); | |
477 | CU_ASSERT_TRUE(svec->header.encoded_object[7] & OBJECT_SVEC_FLAG_N); | |
478 | CU_ASSERT_TRUE(svec->header.encoded_object[7] & OBJECT_SVEC_FLAG_L); | |
479 | CU_ASSERT_EQUAL(*((uint32_t *)(svec->header.encoded_object + 8)), | |
480 | htonl(*uint32_ptr)); | |
481 | ||
482 | pcep_obj_free_object((struct pcep_object_header *)svec); | |
483 | } | |
484 | ||
485 | void test_pcep_obj_create_error() | |
486 | { | |
487 | uint8_t error_type = PCEP_ERRT_SESSION_FAILURE; | |
488 | uint8_t error_value = PCEP_ERRV_RECVD_INVALID_OPEN_MSG; | |
489 | ||
490 | struct pcep_object_error *error = | |
491 | pcep_obj_create_error(error_type, error_value); | |
492 | ||
493 | CU_ASSERT_PTR_NOT_NULL(error); | |
494 | pcep_encode_object(&error->header, versioning, object_buf); | |
495 | verify_pcep_obj_header(PCEP_OBJ_CLASS_ERROR, PCEP_OBJ_TYPE_ERROR, | |
496 | &error->header); | |
497 | CU_ASSERT_EQUAL(error->header.encoded_object[4], 0); | |
498 | CU_ASSERT_EQUAL(error->header.encoded_object[5], 0); | |
499 | CU_ASSERT_EQUAL(error->header.encoded_object[6], error_type); | |
500 | CU_ASSERT_EQUAL(error->header.encoded_object[7], error_value); | |
501 | ||
502 | pcep_obj_free_object((struct pcep_object_header *)error); | |
503 | } | |
504 | ||
505 | void test_pcep_obj_create_close() | |
506 | { | |
507 | uint8_t reason = PCEP_CLOSE_REASON_DEADTIMER; | |
508 | ||
509 | struct pcep_object_close *close = pcep_obj_create_close(reason); | |
510 | ||
511 | CU_ASSERT_PTR_NOT_NULL(close); | |
512 | pcep_encode_object(&close->header, versioning, object_buf); | |
513 | verify_pcep_obj_header(PCEP_OBJ_CLASS_CLOSE, PCEP_OBJ_TYPE_CLOSE, | |
514 | &close->header); | |
515 | CU_ASSERT_EQUAL(close->header.encoded_object[4], 0); | |
516 | CU_ASSERT_EQUAL(close->header.encoded_object[5], 0); | |
517 | CU_ASSERT_EQUAL(close->header.encoded_object[6], 0); | |
518 | CU_ASSERT_EQUAL(close->header.encoded_object[7], reason); | |
519 | ||
520 | pcep_obj_free_object((struct pcep_object_header *)close); | |
521 | } | |
522 | ||
523 | void test_pcep_obj_create_srp() | |
524 | { | |
525 | bool lsp_remove = true; | |
526 | uint32_t srp_id_number = 0x89674523; | |
527 | struct pcep_object_srp *srp = | |
528 | pcep_obj_create_srp(lsp_remove, srp_id_number, NULL); | |
529 | ||
530 | CU_ASSERT_PTR_NOT_NULL(srp); | |
531 | pcep_encode_object(&srp->header, versioning, object_buf); | |
532 | verify_pcep_obj_header(PCEP_OBJ_CLASS_SRP, PCEP_OBJ_TYPE_SRP, | |
533 | &srp->header); | |
534 | CU_ASSERT_EQUAL(srp->header.encoded_object[4], 0); | |
535 | CU_ASSERT_EQUAL(srp->header.encoded_object[5], 0); | |
536 | CU_ASSERT_EQUAL(srp->header.encoded_object[6], 0); | |
537 | CU_ASSERT_TRUE(srp->header.encoded_object[7] & OBJECT_SRP_FLAG_R); | |
538 | CU_ASSERT_EQUAL(*((uint32_t *)(srp->header.encoded_object + 8)), | |
539 | htonl(srp_id_number)); | |
540 | ||
541 | pcep_obj_free_object((struct pcep_object_header *)srp); | |
542 | } | |
543 | ||
544 | void test_pcep_obj_create_lsp() | |
545 | { | |
546 | uint32_t plsp_id = 0x000fffff; | |
547 | enum pcep_lsp_operational_status status = PCEP_LSP_OPERATIONAL_ACTIVE; | |
548 | bool c_flag = true; | |
549 | bool a_flag = true; | |
550 | bool r_flag = true; | |
551 | bool s_flag = true; | |
552 | bool d_flag = true; | |
553 | ||
554 | /* Should return for invalid plsp_id */ | |
555 | struct pcep_object_lsp *lsp = | |
556 | pcep_obj_create_lsp(0x001fffff, status, c_flag, a_flag, r_flag, | |
557 | s_flag, d_flag, NULL); | |
558 | CU_ASSERT_PTR_NULL(lsp); | |
559 | ||
560 | /* Should return for invalid status */ | |
561 | lsp = pcep_obj_create_lsp(plsp_id, 8, c_flag, a_flag, r_flag, s_flag, | |
562 | d_flag, NULL); | |
563 | CU_ASSERT_PTR_NULL(lsp); | |
564 | ||
565 | lsp = pcep_obj_create_lsp(plsp_id, status, c_flag, a_flag, r_flag, | |
566 | s_flag, d_flag, NULL); | |
567 | ||
568 | CU_ASSERT_PTR_NOT_NULL(lsp); | |
569 | pcep_encode_object(&lsp->header, versioning, object_buf); | |
570 | verify_pcep_obj_header(PCEP_OBJ_CLASS_LSP, PCEP_OBJ_TYPE_LSP, | |
571 | &lsp->header); | |
572 | CU_ASSERT_EQUAL((ntohl(*((uint32_t *)(lsp->header.encoded_object + 4))) | |
573 | >> 12) & 0x000fffff, | |
574 | plsp_id); | |
575 | CU_ASSERT_EQUAL((lsp->header.encoded_object[7] >> 4) & 0x07, status); | |
576 | CU_ASSERT_TRUE(lsp->header.encoded_object[7] & OBJECT_LSP_FLAG_A); | |
577 | CU_ASSERT_TRUE(lsp->header.encoded_object[7] & OBJECT_LSP_FLAG_C); | |
578 | CU_ASSERT_TRUE(lsp->header.encoded_object[7] & OBJECT_LSP_FLAG_D); | |
579 | CU_ASSERT_TRUE(lsp->header.encoded_object[7] & OBJECT_LSP_FLAG_R); | |
580 | CU_ASSERT_TRUE(lsp->header.encoded_object[7] & OBJECT_LSP_FLAG_S); | |
581 | ||
582 | pcep_obj_free_object((struct pcep_object_header *)lsp); | |
583 | } | |
584 | ||
585 | void test_pcep_obj_create_vendor_info() | |
586 | { | |
587 | uint32_t enterprise_number = 0x01020304; | |
588 | uint32_t enterprise_specific_info = 0x05060708; | |
589 | ||
590 | struct pcep_object_vendor_info *obj = pcep_obj_create_vendor_info( | |
591 | enterprise_number, enterprise_specific_info); | |
592 | ||
593 | CU_ASSERT_PTR_NOT_NULL(obj); | |
594 | pcep_encode_object(&obj->header, versioning, object_buf); | |
595 | verify_pcep_obj_header(PCEP_OBJ_CLASS_VENDOR_INFO, | |
596 | PCEP_OBJ_TYPE_VENDOR_INFO, &obj->header); | |
597 | uint32_t *uint32_ptr = (uint32_t *)(obj->header.encoded_object + 4); | |
598 | CU_ASSERT_EQUAL(uint32_ptr[0], htonl(enterprise_number)); | |
599 | CU_ASSERT_EQUAL(uint32_ptr[1], htonl(enterprise_specific_info)); | |
600 | ||
601 | pcep_obj_free_object((struct pcep_object_header *)obj); | |
602 | } | |
603 | ||
604 | /* Internal test function. The only difference between pcep_obj_create_ero(), | |
605 | * pcep_obj_create_iro(), and pcep_obj_create_rro() is the object_class | |
606 | * and the object_type. | |
607 | */ | |
608 | typedef struct pcep_object_ro *(*ro_func)(double_linked_list *); | |
609 | static void test_pcep_obj_create_object_common(ro_func func_to_test, | |
610 | uint8_t object_class, | |
611 | uint8_t object_type) | |
612 | { | |
613 | double_linked_list *ero_list = dll_initialize(); | |
614 | ||
615 | struct pcep_object_ro *ero = func_to_test(NULL); | |
616 | CU_ASSERT_PTR_NOT_NULL(ero); | |
617 | pcep_encode_object(&ero->header, versioning, object_buf); | |
618 | verify_pcep_obj_header2(object_class, object_type, OBJECT_HEADER_LENGTH, | |
619 | ero->header.encoded_object); | |
620 | pcep_obj_free_object((struct pcep_object_header *)ero); | |
621 | ||
622 | reset_objects_buffer(); | |
623 | ero = func_to_test(ero_list); | |
624 | CU_ASSERT_PTR_NOT_NULL(ero); | |
625 | pcep_encode_object(&ero->header, versioning, object_buf); | |
626 | verify_pcep_obj_header2(object_class, object_type, OBJECT_HEADER_LENGTH, | |
627 | ero->header.encoded_object); | |
628 | pcep_obj_free_object((struct pcep_object_header *)ero); | |
629 | ||
630 | reset_objects_buffer(); | |
631 | struct pcep_ro_subobj_32label *ro_subobj = | |
632 | pcep_obj_create_ro_subobj_32label(false, 0, 101); | |
633 | ero_list = dll_initialize(); | |
634 | dll_append(ero_list, ro_subobj); | |
635 | ero = func_to_test(ero_list); | |
636 | CU_ASSERT_PTR_NOT_NULL(ero); | |
637 | pcep_encode_object(&ero->header, versioning, object_buf); | |
638 | /* 4 bytes for obj header + | |
639 | * 2 bytes for ro_subobj header + | |
640 | * 2 bytes for lable c-type and flags + | |
641 | * 4 bytes for label */ | |
642 | verify_pcep_obj_header2(object_class, object_type, | |
643 | OBJECT_HEADER_LENGTH + sizeof(uint32_t) * 2, | |
644 | ero->header.encoded_object); | |
645 | pcep_obj_free_object((struct pcep_object_header *)ero); | |
646 | } | |
647 | ||
648 | void test_pcep_obj_create_ero() | |
649 | { | |
650 | test_pcep_obj_create_object_common( | |
651 | pcep_obj_create_ero, PCEP_OBJ_CLASS_ERO, PCEP_OBJ_TYPE_ERO); | |
652 | } | |
653 | ||
654 | void test_pcep_obj_create_rro() | |
655 | { | |
656 | test_pcep_obj_create_object_common( | |
657 | pcep_obj_create_rro, PCEP_OBJ_CLASS_RRO, PCEP_OBJ_TYPE_RRO); | |
658 | } | |
659 | ||
660 | void test_pcep_obj_create_iro() | |
661 | { | |
662 | test_pcep_obj_create_object_common( | |
663 | pcep_obj_create_iro, PCEP_OBJ_CLASS_IRO, PCEP_OBJ_TYPE_IRO); | |
664 | } | |
665 | ||
666 | /* Internal util function to wrap an RO Subobj in a RO and encode it */ | |
667 | static struct pcep_object_ro *encode_ro_subobj(struct pcep_object_ro_subobj *sr) | |
668 | { | |
669 | double_linked_list *sr_subobj_list = dll_initialize(); | |
670 | dll_append(sr_subobj_list, sr); | |
671 | struct pcep_object_ro *ro = pcep_obj_create_ero(sr_subobj_list); | |
672 | pcep_encode_object(&ro->header, versioning, object_buf); | |
673 | ||
674 | return ro; | |
675 | } | |
676 | ||
677 | static void verify_pcep_obj_ro_header(struct pcep_object_ro *ro, | |
678 | struct pcep_object_ro_subobj *ro_subobj, | |
679 | uint8_t ro_subobj_type, bool loose_hop, | |
680 | uint16_t length) | |
681 | { | |
682 | (void)ro_subobj; | |
683 | ||
684 | verify_pcep_obj_header2(PCEP_OBJ_CLASS_ERO, PCEP_OBJ_TYPE_ERO, length, | |
685 | ro->header.encoded_object); | |
686 | ||
687 | /* TODO consider printing the stack trace: | |
688 | * https://stackoverflow.com/questions/105659/how-can-one-grab-a-stack-trace-in-c | |
689 | */ | |
690 | ||
691 | /* Not using CU_ASSERT_EQUAL here, so that in case of failure, | |
692 | * we can provide more info in the error message. */ | |
693 | uint8_t found_type = (ro->header.encoded_object[4] | |
694 | & 0x7f); /* remove the Loose hop bit */ | |
695 | if (found_type != ro_subobj_type) { | |
696 | fprintf(stderr, | |
697 | "Test failure ro_sub_obj_type expected [%d] found [%d]\n", | |
698 | ro_subobj_type, found_type); | |
699 | CU_FAIL("Sub Object Header Type"); | |
700 | } | |
701 | ||
702 | bool loose_hop_found = (ro->header.encoded_object[4] & 0x80); | |
703 | if (loose_hop != loose_hop_found) { | |
704 | fprintf(stderr, | |
705 | "Test failure ro_sub_obj Loose Hop bit expected [%d] found [%d]\n", | |
706 | loose_hop, loose_hop_found); | |
707 | CU_FAIL("Sub Object Header Loose Hop bit"); | |
708 | } | |
709 | ||
710 | if (length - 4 != ro->header.encoded_object[5]) { | |
711 | fprintf(stderr, | |
712 | "Test failure ro_sub_obj length expected [%d] found [%d]\n", | |
713 | length - 4, ro->header.encoded_object[5]); | |
714 | CU_FAIL("Sub Object Length"); | |
715 | } | |
716 | } | |
717 | ||
718 | static void | |
719 | verify_pcep_obj_ro_sr_header(struct pcep_object_ro *ro, | |
720 | struct pcep_object_ro_subobj *ro_subobj, | |
721 | uint8_t nai_type, bool loose_hop, uint16_t length) | |
722 | { | |
723 | verify_pcep_obj_ro_header(ro, ro_subobj, RO_SUBOBJ_TYPE_SR, loose_hop, | |
724 | length); | |
725 | uint8_t found_nai_type = ((ro->header.encoded_object[6] >> 4) & 0x0f); | |
726 | if (nai_type != found_nai_type) { | |
727 | fprintf(stderr, | |
728 | "Test failure ro_sr_sub_obj nai_type expected [%d] found [%d]\n", | |
729 | nai_type, found_nai_type); | |
730 | CU_FAIL("Sub Object SR NAI Type"); | |
731 | } | |
732 | } | |
733 | ||
734 | void test_pcep_obj_create_ro_subobj_ipv4() | |
735 | { | |
736 | struct in_addr ro_ipv4; | |
737 | inet_pton(AF_INET, "192.168.1.2", &ro_ipv4); | |
738 | uint8_t prefix_len = 8; | |
739 | ||
740 | struct pcep_ro_subobj_ipv4 *ipv4 = | |
741 | pcep_obj_create_ro_subobj_ipv4(true, NULL, prefix_len, false); | |
742 | CU_ASSERT_PTR_NULL(ipv4); | |
743 | ||
744 | ipv4 = pcep_obj_create_ro_subobj_ipv4(false, &ro_ipv4, prefix_len, | |
745 | true); | |
746 | CU_ASSERT_PTR_NOT_NULL(ipv4); | |
747 | struct pcep_object_ro *ro = encode_ro_subobj(&ipv4->ro_subobj); | |
748 | verify_pcep_obj_ro_header(ro, &ipv4->ro_subobj, RO_SUBOBJ_TYPE_IPV4, | |
749 | false, sizeof(uint32_t) * 3); | |
750 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 6)), | |
751 | ro_ipv4.s_addr); | |
752 | CU_ASSERT_EQUAL(ro->header.encoded_object[10], prefix_len); | |
753 | CU_ASSERT_TRUE(ro->header.encoded_object[11] | |
754 | & OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT); | |
755 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
756 | ||
757 | reset_objects_buffer(); | |
758 | ipv4 = pcep_obj_create_ro_subobj_ipv4(true, &ro_ipv4, prefix_len, | |
759 | false); | |
760 | CU_ASSERT_PTR_NOT_NULL(ipv4); | |
761 | ro = encode_ro_subobj(&ipv4->ro_subobj); | |
762 | verify_pcep_obj_ro_header(ro, &ipv4->ro_subobj, RO_SUBOBJ_TYPE_IPV4, | |
763 | true, sizeof(uint32_t) * 3); | |
764 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 6)), | |
765 | ro_ipv4.s_addr); | |
766 | CU_ASSERT_EQUAL(ro->header.encoded_object[10], prefix_len); | |
767 | CU_ASSERT_EQUAL(ro->header.encoded_object[11], 0); | |
768 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
769 | } | |
770 | ||
771 | void test_pcep_obj_create_ro_subobj_ipv6() | |
772 | { | |
773 | struct in6_addr ro_ipv6; | |
774 | uint8_t prefix_len = 16; | |
775 | ||
776 | struct pcep_ro_subobj_ipv6 *ipv6 = | |
777 | pcep_obj_create_ro_subobj_ipv6(true, NULL, prefix_len, true); | |
778 | CU_ASSERT_PTR_NULL(ipv6); | |
779 | ||
780 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &ro_ipv6); | |
781 | ipv6 = pcep_obj_create_ro_subobj_ipv6(false, &ro_ipv6, prefix_len, | |
782 | true); | |
783 | CU_ASSERT_PTR_NOT_NULL(ipv6); | |
784 | struct pcep_object_ro *ro = encode_ro_subobj(&ipv6->ro_subobj); | |
785 | verify_pcep_obj_ro_header(ro, &ipv6->ro_subobj, RO_SUBOBJ_TYPE_IPV6, | |
786 | false, sizeof(uint32_t) * 6); | |
787 | uint32_t *uint32_ptr = (uint32_t *)(ro->header.encoded_object + 6); | |
788 | CU_ASSERT_EQUAL(uint32_ptr[0], ro_ipv6.__in6_u.__u6_addr32[0]); | |
789 | CU_ASSERT_EQUAL(uint32_ptr[1], ro_ipv6.__in6_u.__u6_addr32[1]); | |
790 | CU_ASSERT_EQUAL(uint32_ptr[2], ro_ipv6.__in6_u.__u6_addr32[2]); | |
791 | CU_ASSERT_EQUAL(uint32_ptr[3], ro_ipv6.__in6_u.__u6_addr32[3]); | |
792 | CU_ASSERT_EQUAL(ro->header.encoded_object[22], prefix_len); | |
793 | CU_ASSERT_TRUE(ro->header.encoded_object[23] | |
794 | & OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT); | |
795 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
796 | ||
797 | reset_objects_buffer(); | |
798 | ipv6 = pcep_obj_create_ro_subobj_ipv6(true, &ro_ipv6, prefix_len, | |
799 | false); | |
800 | CU_ASSERT_PTR_NOT_NULL(ipv6); | |
801 | ro = encode_ro_subobj(&ipv6->ro_subobj); | |
802 | verify_pcep_obj_ro_header(ro, &ipv6->ro_subobj, RO_SUBOBJ_TYPE_IPV6, | |
803 | true, sizeof(uint32_t) * 6); | |
804 | uint32_ptr = (uint32_t *)(ro->header.encoded_object + 6); | |
805 | CU_ASSERT_EQUAL(uint32_ptr[0], ro_ipv6.__in6_u.__u6_addr32[0]); | |
806 | CU_ASSERT_EQUAL(uint32_ptr[1], ro_ipv6.__in6_u.__u6_addr32[1]); | |
807 | CU_ASSERT_EQUAL(uint32_ptr[2], ro_ipv6.__in6_u.__u6_addr32[2]); | |
808 | CU_ASSERT_EQUAL(uint32_ptr[3], ro_ipv6.__in6_u.__u6_addr32[3]); | |
809 | CU_ASSERT_EQUAL(ro->header.encoded_object[22], prefix_len); | |
810 | CU_ASSERT_EQUAL(ro->header.encoded_object[23], 0); | |
811 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
812 | } | |
813 | ||
814 | void test_pcep_obj_create_ro_subobj_unnum() | |
815 | { | |
816 | struct in_addr router_id; | |
817 | uint32_t if_id = 123; | |
818 | ||
819 | struct pcep_ro_subobj_unnum *unnum = | |
820 | pcep_obj_create_ro_subobj_unnum(NULL, if_id); | |
821 | CU_ASSERT_PTR_NULL(unnum); | |
822 | ||
823 | inet_pton(AF_INET, "192.168.1.2", &router_id); | |
824 | unnum = pcep_obj_create_ro_subobj_unnum(&router_id, if_id); | |
825 | CU_ASSERT_PTR_NOT_NULL(unnum); | |
826 | struct pcep_object_ro *ro = encode_ro_subobj(&unnum->ro_subobj); | |
827 | verify_pcep_obj_ro_header(ro, &unnum->ro_subobj, RO_SUBOBJ_TYPE_UNNUM, | |
828 | false, sizeof(uint32_t) * 4); | |
829 | CU_ASSERT_EQUAL(ro->header.encoded_object[6], 0); | |
830 | CU_ASSERT_EQUAL(ro->header.encoded_object[7], 0); | |
831 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 8)), | |
832 | router_id.s_addr); | |
833 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 12)), | |
834 | htonl(if_id)); | |
835 | ||
836 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
837 | } | |
838 | ||
839 | void test_pcep_obj_create_ro_subobj_32label() | |
840 | { | |
841 | uint8_t class_type = 1; | |
842 | uint32_t label = 0xeeffaabb; | |
843 | ||
844 | struct pcep_ro_subobj_32label *label32 = | |
845 | pcep_obj_create_ro_subobj_32label(true, class_type, label); | |
846 | CU_ASSERT_PTR_NOT_NULL(label32); | |
847 | struct pcep_object_ro *ro = encode_ro_subobj(&label32->ro_subobj); | |
848 | verify_pcep_obj_ro_header(ro, &label32->ro_subobj, RO_SUBOBJ_TYPE_LABEL, | |
849 | false, sizeof(uint32_t) * 3); | |
850 | CU_ASSERT_TRUE(ro->header.encoded_object[6] | |
851 | & OBJECT_SUBOBJ_LABEL_FLAG_GLOGAL); | |
852 | CU_ASSERT_EQUAL(ro->header.encoded_object[7], class_type); | |
853 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 8)), | |
854 | htonl(label)); | |
855 | ||
856 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
857 | } | |
858 | ||
859 | void test_pcep_obj_create_ro_subobj_asn() | |
860 | { | |
861 | uint16_t asn = 0x0102; | |
862 | ||
863 | struct pcep_ro_subobj_asn *asn_obj = pcep_obj_create_ro_subobj_asn(asn); | |
864 | CU_ASSERT_PTR_NOT_NULL(asn_obj); | |
865 | struct pcep_object_ro *ro = encode_ro_subobj(&asn_obj->ro_subobj); | |
866 | verify_pcep_obj_ro_header(ro, &asn_obj->ro_subobj, RO_SUBOBJ_TYPE_ASN, | |
867 | false, sizeof(uint32_t) * 2); | |
868 | CU_ASSERT_EQUAL(*((uint16_t *)(ro->header.encoded_object + 6)), | |
869 | htons(asn)); | |
870 | ||
871 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
872 | } | |
873 | ||
874 | void test_pcep_obj_create_ro_subobj_sr_nonai() | |
875 | { | |
876 | uint32_t sid = 0x01020304; | |
877 | ||
878 | struct pcep_ro_subobj_sr *sr = | |
879 | pcep_obj_create_ro_subobj_sr_nonai(false, sid, false, false); | |
880 | CU_ASSERT_PTR_NOT_NULL(sr); | |
881 | struct pcep_object_ro *ro = encode_ro_subobj(&sr->ro_subobj); | |
882 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
883 | PCEP_SR_SUBOBJ_NAI_ABSENT, false, | |
884 | sizeof(uint32_t) * 3); | |
885 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_S); | |
886 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_F); | |
887 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_C); | |
888 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_M); | |
889 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
890 | ||
891 | reset_objects_buffer(); | |
892 | sr = pcep_obj_create_ro_subobj_sr_nonai(true, sid, true, true); | |
893 | CU_ASSERT_PTR_NOT_NULL(sr); | |
894 | ro = encode_ro_subobj(&sr->ro_subobj); | |
895 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
896 | PCEP_SR_SUBOBJ_NAI_ABSENT, true, | |
897 | sizeof(uint32_t) * 3); | |
898 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_S); | |
899 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_F); | |
900 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_C); | |
901 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_M); | |
902 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
903 | } | |
904 | ||
905 | void test_pcep_obj_create_ro_subobj_sr_ipv4_node() | |
906 | { | |
907 | uint32_t sid = 0x01020304; | |
908 | struct in_addr ipv4_node_id; | |
909 | inet_pton(AF_INET, "192.168.1.2", &ipv4_node_id); | |
910 | ||
911 | /* (loose_hop, sid_absent, c_flag, m_flag, sid, ipv4_node_id) */ | |
912 | struct pcep_ro_subobj_sr *sr = pcep_obj_create_ro_subobj_sr_ipv4_node( | |
913 | true, false, true, true, sid, NULL); | |
914 | CU_ASSERT_PTR_NULL(sr); | |
915 | ||
916 | /* Test the sid is absent */ | |
917 | sr = pcep_obj_create_ro_subobj_sr_ipv4_node(true, true, false, false, | |
918 | sid, &ipv4_node_id); | |
919 | CU_ASSERT_PTR_NOT_NULL(sr); | |
920 | struct pcep_object_ro *ro = encode_ro_subobj(&sr->ro_subobj); | |
921 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
922 | PCEP_SR_SUBOBJ_NAI_IPV4_NODE, true, | |
923 | sizeof(uint32_t) * 3); | |
924 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_S); | |
925 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
926 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_C); | |
927 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_M); | |
928 | CU_ASSERT_EQUAL(sr->sid, 0); | |
929 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 8)), | |
930 | ipv4_node_id.s_addr); | |
931 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
932 | ||
933 | /* Test the sid is present */ | |
934 | reset_objects_buffer(); | |
935 | inet_pton(AF_INET, "192.168.1.2", &ipv4_node_id); | |
936 | sr = pcep_obj_create_ro_subobj_sr_ipv4_node(false, false, true, true, | |
937 | sid, &ipv4_node_id); | |
938 | CU_ASSERT_PTR_NOT_NULL(sr); | |
939 | ro = encode_ro_subobj(&sr->ro_subobj); | |
940 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
941 | PCEP_SR_SUBOBJ_NAI_IPV4_NODE, false, | |
942 | sizeof(uint32_t) * 4); | |
943 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_C); | |
944 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_M); | |
945 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_S); | |
946 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
947 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 8)), | |
948 | htonl(sid)); | |
949 | CU_ASSERT_EQUAL(*((uint32_t *)(ro->header.encoded_object + 12)), | |
950 | ipv4_node_id.s_addr); | |
951 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
952 | } | |
953 | ||
954 | void test_pcep_obj_create_ro_subobj_sr_ipv6_node() | |
955 | { | |
956 | uint32_t sid = 0x01020304; | |
957 | struct in6_addr ipv6_node_id; | |
958 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &ipv6_node_id); | |
959 | ||
960 | /* (loose_hop, sid_absent, c_flag, m_flag, sid, ipv6_node_id) */ | |
961 | struct pcep_ro_subobj_sr *sr = pcep_obj_create_ro_subobj_sr_ipv6_node( | |
962 | false, true, true, true, sid, NULL); | |
963 | CU_ASSERT_PTR_NULL(sr); | |
964 | ||
965 | /* Test the sid is absent */ | |
966 | sr = pcep_obj_create_ro_subobj_sr_ipv6_node(true, true, true, true, sid, | |
967 | &ipv6_node_id); | |
968 | CU_ASSERT_PTR_NOT_NULL(sr); | |
969 | struct pcep_object_ro *ro = encode_ro_subobj(&sr->ro_subobj); | |
970 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
971 | PCEP_SR_SUBOBJ_NAI_IPV6_NODE, true, | |
972 | sizeof(uint32_t) * 6); | |
973 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_S); | |
974 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
975 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_C); | |
976 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_M); | |
977 | uint32_t *uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
978 | CU_ASSERT_EQUAL(uint32_ptr[0], ipv6_node_id.__in6_u.__u6_addr32[0]); | |
979 | CU_ASSERT_EQUAL(uint32_ptr[1], ipv6_node_id.__in6_u.__u6_addr32[1]); | |
980 | CU_ASSERT_EQUAL(uint32_ptr[2], ipv6_node_id.__in6_u.__u6_addr32[2]); | |
981 | CU_ASSERT_EQUAL(uint32_ptr[3], ipv6_node_id.__in6_u.__u6_addr32[3]); | |
982 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
983 | ||
984 | /* Test the sid is present */ | |
985 | reset_objects_buffer(); | |
986 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &ipv6_node_id); | |
987 | sr = pcep_obj_create_ro_subobj_sr_ipv6_node(false, false, true, true, | |
988 | sid, &ipv6_node_id); | |
989 | CU_ASSERT_PTR_NOT_NULL(sr); | |
990 | ro = encode_ro_subobj(&sr->ro_subobj); | |
991 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
992 | PCEP_SR_SUBOBJ_NAI_IPV6_NODE, false, | |
993 | sizeof(uint32_t) * 7); | |
994 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_M); | |
995 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_C); | |
996 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_S); | |
997 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
998 | uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
999 | CU_ASSERT_EQUAL(uint32_ptr[0], htonl(sid)); | |
1000 | CU_ASSERT_EQUAL(uint32_ptr[1], ipv6_node_id.__in6_u.__u6_addr32[0]); | |
1001 | CU_ASSERT_EQUAL(uint32_ptr[2], ipv6_node_id.__in6_u.__u6_addr32[1]); | |
1002 | CU_ASSERT_EQUAL(uint32_ptr[3], ipv6_node_id.__in6_u.__u6_addr32[2]); | |
1003 | CU_ASSERT_EQUAL(uint32_ptr[4], ipv6_node_id.__in6_u.__u6_addr32[3]); | |
1004 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1005 | } | |
1006 | ||
1007 | void test_pcep_obj_create_ro_subobj_sr_ipv4_adj() | |
1008 | { | |
1009 | struct in_addr local_ipv4; | |
1010 | struct in_addr remote_ipv4; | |
1011 | inet_pton(AF_INET, "192.168.1.2", &local_ipv4); | |
1012 | inet_pton(AF_INET, "172.168.1.2", &remote_ipv4); | |
1013 | ||
1014 | uint32_t sid = ENCODE_SR_ERO_SID(3, 7, 0, 188); | |
1015 | CU_ASSERT_EQUAL(sid, 16060); | |
1016 | ||
1017 | /* (loose_hop, sid_absent, c_flag, m_flag, sid, local_ipv4, remote_ipv4) | |
1018 | */ | |
1019 | struct pcep_ro_subobj_sr *sr = pcep_obj_create_ro_subobj_sr_ipv4_adj( | |
1020 | false, true, true, true, sid, NULL, NULL); | |
1021 | CU_ASSERT_PTR_NULL(sr); | |
1022 | ||
1023 | sr = pcep_obj_create_ro_subobj_sr_ipv4_adj(false, true, true, true, sid, | |
1024 | &local_ipv4, NULL); | |
1025 | CU_ASSERT_PTR_NULL(sr); | |
1026 | ||
1027 | sr = pcep_obj_create_ro_subobj_sr_ipv4_adj(false, true, true, true, sid, | |
1028 | NULL, &remote_ipv4); | |
1029 | CU_ASSERT_PTR_NULL(sr); | |
1030 | ||
1031 | /* Test the sid is absent */ | |
1032 | sr = pcep_obj_create_ro_subobj_sr_ipv4_adj(true, true, true, true, sid, | |
1033 | &local_ipv4, &remote_ipv4); | |
1034 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1035 | struct pcep_object_ro *ro = encode_ro_subobj(&sr->ro_subobj); | |
1036 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
1037 | PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY, true, | |
1038 | sizeof(uint32_t) * 4); | |
1039 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_S); | |
1040 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
1041 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_C); | |
1042 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_M); | |
1043 | CU_ASSERT_EQUAL(sr->sid, 0); | |
1044 | uint32_t *uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1045 | CU_ASSERT_EQUAL(uint32_ptr[0], local_ipv4.s_addr); | |
1046 | CU_ASSERT_EQUAL(uint32_ptr[1], remote_ipv4.s_addr); | |
1047 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1048 | ||
1049 | /* Test the sid is present */ | |
1050 | inet_pton(AF_INET, "192.168.1.2", &local_ipv4); | |
1051 | inet_pton(AF_INET, "172.168.1.2", &remote_ipv4); | |
1052 | reset_objects_buffer(); | |
1053 | sr = pcep_obj_create_ro_subobj_sr_ipv4_adj( | |
1054 | false, false, true, true, sid, &local_ipv4, &remote_ipv4); | |
1055 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1056 | ro = encode_ro_subobj(&sr->ro_subobj); | |
1057 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
1058 | PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY, false, | |
1059 | sizeof(uint32_t) * 5); | |
1060 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_C); | |
1061 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_M); | |
1062 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_S); | |
1063 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
1064 | uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1065 | CU_ASSERT_EQUAL(uint32_ptr[0], htonl(sid)); | |
1066 | CU_ASSERT_EQUAL(uint32_ptr[1], local_ipv4.s_addr); | |
1067 | CU_ASSERT_EQUAL(uint32_ptr[2], remote_ipv4.s_addr); | |
1068 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1069 | } | |
1070 | ||
1071 | void test_pcep_obj_create_ro_subobj_sr_ipv6_adj() | |
1072 | { | |
1073 | uint32_t sid = 0x01020304; | |
1074 | struct in6_addr local_ipv6; | |
1075 | struct in6_addr remote_ipv6; | |
1076 | inet_pton(AF_INET6, "2001:db8::8a2e:370:8221", &local_ipv6); | |
1077 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &remote_ipv6); | |
1078 | ||
1079 | /* (loose_hop, sid_absent, c_flag, m_flag, sid, local_ipv6, remote_ipv6) | |
1080 | */ | |
1081 | struct pcep_ro_subobj_sr *sr = pcep_obj_create_ro_subobj_sr_ipv6_adj( | |
1082 | false, true, true, true, sid, NULL, NULL); | |
1083 | CU_ASSERT_PTR_NULL(sr); | |
1084 | ||
1085 | sr = pcep_obj_create_ro_subobj_sr_ipv6_adj(false, true, true, true, sid, | |
1086 | &local_ipv6, NULL); | |
1087 | CU_ASSERT_PTR_NULL(sr); | |
1088 | ||
1089 | sr = pcep_obj_create_ro_subobj_sr_ipv6_adj(false, true, true, true, sid, | |
1090 | NULL, &remote_ipv6); | |
1091 | CU_ASSERT_PTR_NULL(sr); | |
1092 | ||
1093 | /* Test the sid is absent */ | |
1094 | sr = pcep_obj_create_ro_subobj_sr_ipv6_adj(true, true, true, true, sid, | |
1095 | &local_ipv6, &remote_ipv6); | |
1096 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1097 | struct pcep_object_ro *ro = encode_ro_subobj(&sr->ro_subobj); | |
1098 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
1099 | PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY, true, | |
1100 | sizeof(uint32_t) * 10); | |
1101 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_S); | |
1102 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
1103 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_C); | |
1104 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_M); | |
1105 | CU_ASSERT_EQUAL(sr->sid, 0); | |
1106 | uint32_t *uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1107 | CU_ASSERT_EQUAL(uint32_ptr[0], local_ipv6.__in6_u.__u6_addr32[0]); | |
1108 | CU_ASSERT_EQUAL(uint32_ptr[1], local_ipv6.__in6_u.__u6_addr32[1]); | |
1109 | CU_ASSERT_EQUAL(uint32_ptr[2], local_ipv6.__in6_u.__u6_addr32[2]); | |
1110 | CU_ASSERT_EQUAL(uint32_ptr[3], local_ipv6.__in6_u.__u6_addr32[3]); | |
1111 | ||
1112 | CU_ASSERT_EQUAL(uint32_ptr[4], remote_ipv6.__in6_u.__u6_addr32[0]); | |
1113 | CU_ASSERT_EQUAL(uint32_ptr[5], remote_ipv6.__in6_u.__u6_addr32[1]); | |
1114 | CU_ASSERT_EQUAL(uint32_ptr[6], remote_ipv6.__in6_u.__u6_addr32[2]); | |
1115 | CU_ASSERT_EQUAL(uint32_ptr[7], remote_ipv6.__in6_u.__u6_addr32[3]); | |
1116 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1117 | ||
1118 | /* Test the sid is present */ | |
1119 | reset_objects_buffer(); | |
1120 | inet_pton(AF_INET6, "2001:db8::8a2e:370:8221", &local_ipv6); | |
1121 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &remote_ipv6); | |
1122 | sr = pcep_obj_create_ro_subobj_sr_ipv6_adj( | |
1123 | false, false, true, false, sid, &local_ipv6, &remote_ipv6); | |
1124 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1125 | ro = encode_ro_subobj(&sr->ro_subobj); | |
1126 | verify_pcep_obj_ro_sr_header(ro, &sr->ro_subobj, | |
1127 | PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY, false, | |
1128 | sizeof(uint32_t) * 11); | |
1129 | /* All flags are false */ | |
1130 | CU_ASSERT_EQUAL(ro->header.encoded_object[7], 0); | |
1131 | uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1132 | CU_ASSERT_EQUAL(uint32_ptr[0], htonl(sid)); | |
1133 | CU_ASSERT_EQUAL(uint32_ptr[1], local_ipv6.__in6_u.__u6_addr32[0]); | |
1134 | CU_ASSERT_EQUAL(uint32_ptr[2], local_ipv6.__in6_u.__u6_addr32[1]); | |
1135 | CU_ASSERT_EQUAL(uint32_ptr[3], local_ipv6.__in6_u.__u6_addr32[2]); | |
1136 | CU_ASSERT_EQUAL(uint32_ptr[4], local_ipv6.__in6_u.__u6_addr32[3]); | |
1137 | ||
1138 | CU_ASSERT_EQUAL(uint32_ptr[5], remote_ipv6.__in6_u.__u6_addr32[0]); | |
1139 | CU_ASSERT_EQUAL(uint32_ptr[6], remote_ipv6.__in6_u.__u6_addr32[1]); | |
1140 | CU_ASSERT_EQUAL(uint32_ptr[7], remote_ipv6.__in6_u.__u6_addr32[2]); | |
1141 | CU_ASSERT_EQUAL(uint32_ptr[8], remote_ipv6.__in6_u.__u6_addr32[3]); | |
1142 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1143 | } | |
1144 | ||
1145 | void test_pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj() | |
1146 | { | |
1147 | uint32_t sid = 0x01020304; | |
1148 | uint32_t local_node_id = 0x11223344; | |
1149 | uint32_t local_if_id = 0x55667788; | |
1150 | uint32_t remote_node_id = 0x99aabbcc; | |
1151 | uint32_t remote_if_id = 0xddeeff11; | |
1152 | ||
1153 | /* (loose_hop, sid_absent, c_flag, m_flag, | |
1154 | sid, local_node_id, local_if_id, remote_node_id, remote_if_id) */ | |
1155 | ||
1156 | /* Test the sid is absent */ | |
1157 | struct pcep_ro_subobj_sr *sr = | |
1158 | pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj( | |
1159 | true, true, true, true, sid, local_node_id, local_if_id, | |
1160 | remote_node_id, remote_if_id); | |
1161 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1162 | struct pcep_object_ro *ro = encode_ro_subobj(&sr->ro_subobj); | |
1163 | verify_pcep_obj_ro_sr_header( | |
1164 | ro, &sr->ro_subobj, | |
1165 | PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY, true, | |
1166 | sizeof(uint32_t) * 6); | |
1167 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_S); | |
1168 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
1169 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_C); | |
1170 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_M); | |
1171 | CU_ASSERT_EQUAL(sr->sid, 0); | |
1172 | uint32_t *uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1173 | CU_ASSERT_EQUAL(uint32_ptr[0], local_node_id); | |
1174 | CU_ASSERT_EQUAL(uint32_ptr[1], local_if_id); | |
1175 | CU_ASSERT_EQUAL(uint32_ptr[2], remote_node_id); | |
1176 | CU_ASSERT_EQUAL(uint32_ptr[3], remote_if_id); | |
1177 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1178 | ||
1179 | /* Test the sid is present */ | |
1180 | reset_objects_buffer(); | |
1181 | sr = pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj( | |
1182 | false, false, true, true, sid, local_node_id, local_if_id, | |
1183 | remote_node_id, remote_if_id); | |
1184 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1185 | ro = encode_ro_subobj(&sr->ro_subobj); | |
1186 | verify_pcep_obj_ro_sr_header( | |
1187 | ro, &sr->ro_subobj, | |
1188 | PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY, false, | |
1189 | sizeof(uint32_t) * 7); | |
1190 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_C); | |
1191 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_M); | |
1192 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_S); | |
1193 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
1194 | uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1195 | CU_ASSERT_EQUAL(uint32_ptr[0], htonl(sid)); | |
1196 | CU_ASSERT_EQUAL(uint32_ptr[1], local_node_id); | |
1197 | CU_ASSERT_EQUAL(uint32_ptr[2], local_if_id); | |
1198 | CU_ASSERT_EQUAL(uint32_ptr[3], remote_node_id); | |
1199 | CU_ASSERT_EQUAL(uint32_ptr[4], remote_if_id); | |
1200 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1201 | ||
1202 | /* TODO Test draft07 types */ | |
1203 | } | |
1204 | ||
1205 | void test_pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj() | |
1206 | { | |
1207 | uint32_t sid = 0x01020304; | |
1208 | uint32_t local_if_id = 0x11002200; | |
1209 | uint32_t remote_if_id = 0x00110022; | |
1210 | struct in6_addr local_ipv6; | |
1211 | struct in6_addr remote_ipv6; | |
1212 | inet_pton(AF_INET6, "2001:db8::8a2e:370:8221", &local_ipv6); | |
1213 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &remote_ipv6); | |
1214 | ||
1215 | /* (loose_hop, sid_absent, c_flag, m_flag, sid, local_ipv6, local_if_id, | |
1216 | * remote_ipv6, remote_if_id */ | |
1217 | struct pcep_ro_subobj_sr *sr = | |
1218 | pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj( | |
1219 | false, true, true, true, sid, NULL, local_if_id, NULL, | |
1220 | remote_if_id); | |
1221 | CU_ASSERT_PTR_NULL(sr); | |
1222 | ||
1223 | sr = pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj( | |
1224 | false, true, true, true, sid, &local_ipv6, local_if_id, NULL, | |
1225 | remote_if_id); | |
1226 | CU_ASSERT_PTR_NULL(sr); | |
1227 | ||
1228 | sr = pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj( | |
1229 | false, true, true, true, sid, NULL, local_if_id, &remote_ipv6, | |
1230 | remote_if_id); | |
1231 | CU_ASSERT_PTR_NULL(sr); | |
1232 | ||
1233 | /* Test the sid is absent */ | |
1234 | sr = pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj( | |
1235 | true, true, true, true, sid, &local_ipv6, local_if_id, | |
1236 | &remote_ipv6, remote_if_id); | |
1237 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1238 | struct pcep_object_ro *ro = encode_ro_subobj(&sr->ro_subobj); | |
1239 | verify_pcep_obj_ro_sr_header( | |
1240 | ro, &sr->ro_subobj, | |
1241 | PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY, true, | |
1242 | sizeof(uint32_t) * 12); | |
1243 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_S); | |
1244 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
1245 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_C); | |
1246 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_M); | |
1247 | CU_ASSERT_EQUAL(sr->sid, 0); | |
1248 | uint32_t *uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1249 | CU_ASSERT_EQUAL(uint32_ptr[0], local_ipv6.__in6_u.__u6_addr32[0]); | |
1250 | CU_ASSERT_EQUAL(uint32_ptr[1], local_ipv6.__in6_u.__u6_addr32[1]); | |
1251 | CU_ASSERT_EQUAL(uint32_ptr[2], local_ipv6.__in6_u.__u6_addr32[2]); | |
1252 | CU_ASSERT_EQUAL(uint32_ptr[3], local_ipv6.__in6_u.__u6_addr32[3]); | |
1253 | CU_ASSERT_EQUAL(uint32_ptr[4], local_if_id); | |
1254 | ||
1255 | CU_ASSERT_EQUAL(uint32_ptr[5], remote_ipv6.__in6_u.__u6_addr32[0]); | |
1256 | CU_ASSERT_EQUAL(uint32_ptr[6], remote_ipv6.__in6_u.__u6_addr32[1]); | |
1257 | CU_ASSERT_EQUAL(uint32_ptr[7], remote_ipv6.__in6_u.__u6_addr32[2]); | |
1258 | CU_ASSERT_EQUAL(uint32_ptr[8], remote_ipv6.__in6_u.__u6_addr32[3]); | |
1259 | CU_ASSERT_EQUAL(uint32_ptr[9], remote_if_id); | |
1260 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1261 | ||
1262 | /* Test the sid is present */ | |
1263 | inet_pton(AF_INET6, "2001:db8::8a2e:370:8221", &local_ipv6); | |
1264 | inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &remote_ipv6); | |
1265 | reset_objects_buffer(); | |
1266 | sr = pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj( | |
1267 | false, false, true, true, sid, &local_ipv6, local_if_id, | |
1268 | &remote_ipv6, remote_if_id); | |
1269 | CU_ASSERT_PTR_NOT_NULL(sr); | |
1270 | ro = encode_ro_subobj(&sr->ro_subobj); | |
1271 | verify_pcep_obj_ro_sr_header( | |
1272 | ro, &sr->ro_subobj, | |
1273 | PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY, false, | |
1274 | sizeof(uint32_t) * 13); | |
1275 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_C); | |
1276 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & OBJECT_SUBOBJ_SR_FLAG_M); | |
1277 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_S); | |
1278 | CU_ASSERT_TRUE(ro->header.encoded_object[7] & ~OBJECT_SUBOBJ_SR_FLAG_F); | |
1279 | uint32_ptr = (uint32_t *)(ro->header.encoded_object + 8); | |
1280 | CU_ASSERT_EQUAL(uint32_ptr[0], htonl(sid)); | |
1281 | CU_ASSERT_EQUAL(uint32_ptr[1], local_ipv6.__in6_u.__u6_addr32[0]); | |
1282 | CU_ASSERT_EQUAL(uint32_ptr[2], local_ipv6.__in6_u.__u6_addr32[1]); | |
1283 | CU_ASSERT_EQUAL(uint32_ptr[3], local_ipv6.__in6_u.__u6_addr32[2]); | |
1284 | CU_ASSERT_EQUAL(uint32_ptr[4], local_ipv6.__in6_u.__u6_addr32[3]); | |
1285 | CU_ASSERT_EQUAL(uint32_ptr[5], local_if_id); | |
1286 | ||
1287 | CU_ASSERT_EQUAL(uint32_ptr[6], remote_ipv6.__in6_u.__u6_addr32[0]); | |
1288 | CU_ASSERT_EQUAL(uint32_ptr[7], remote_ipv6.__in6_u.__u6_addr32[1]); | |
1289 | CU_ASSERT_EQUAL(uint32_ptr[8], remote_ipv6.__in6_u.__u6_addr32[2]); | |
1290 | CU_ASSERT_EQUAL(uint32_ptr[9], remote_ipv6.__in6_u.__u6_addr32[3]); | |
1291 | CU_ASSERT_EQUAL(uint32_ptr[10], remote_if_id); | |
1292 | pcep_obj_free_object((struct pcep_object_header *)ro); | |
1293 | } |