]> git.proxmox.com Git - mirror_frr.git/blame - pceplib/test/pcep_msg_objects_test.c
Merge pull request #8441 from mjstapp/fix_topo_pylint1
[mirror_frr.git] / pceplib / test / pcep_msg_objects_test.c
CommitLineData
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
45static struct pcep_versioning *versioning = NULL;
46static uint8_t object_buf[2000];
47
48void reset_objects_buffer(void);
49
50int pcep_objects_test_suite_setup(void)
51{
52 pceplib_memory_reset();
53 return 0;
54}
55
56int pcep_objects_test_suite_teardown(void)
57{
58 printf("\n");
59 pceplib_memory_dump();
60 return 0;
61}
62
63void reset_objects_buffer()
64{
65 memset(object_buf, 0, 2000);
66}
67
68void pcep_objects_test_setup()
69{
70 versioning = create_default_pcep_versioning();
71 reset_objects_buffer();
72}
73
74void pcep_objects_test_teardown()
75{
76 destroy_pcep_versioning(versioning);
77}
78
79/* Internal util verification function */
80static 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 */
128static 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
136void 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
160void 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
193void 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
224void 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}
260void 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
283void 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
312void 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
341void 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
375void 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
396void 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
428void 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
455void 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
485void 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
505void 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
523void 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
544void 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
585void 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 */
608typedef struct pcep_object_ro *(*ro_func)(double_linked_list *);
609static 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
648void 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
654void 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
660void 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 */
667static 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
677static 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
718static void
719verify_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
734void 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
771void 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
814void 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
839void 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
859void 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
874void 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
905void 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
954void 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
1007void 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
1071void 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
1145void 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
1205void 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}