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