summaryrefslogtreecommitdiffstats
path: root/pceplib/test/pcep_msg_tlvs_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'pceplib/test/pcep_msg_tlvs_test.c')
-rw-r--r--pceplib/test/pcep_msg_tlvs_test.c725
1 files changed, 725 insertions, 0 deletions
diff --git a/pceplib/test/pcep_msg_tlvs_test.c b/pceplib/test/pcep_msg_tlvs_test.c
new file mode 100644
index 0000000..888925f
--- /dev/null
+++ b/pceplib/test/pcep_msg_tlvs_test.c
@@ -0,0 +1,725 @@
+/*
+ * This file is part of the PCEPlib, a PCEP protocol library.
+ *
+ * Copyright (C) 2020 Volta Networks https://voltanet.io/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * Author : Brady Johnson <brady@voltanet.io>
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/endian.h>
+#else
+#include <endian.h>
+#endif /* __FreeBSD__ */
+#include <assert.h>
+#include <stdlib.h>
+
+#include <CUnit/CUnit.h>
+
+#include "pcep_msg_encoding.h"
+#include "pcep_msg_objects.h"
+#include "pcep_msg_tlvs.h"
+#include "pcep_msg_tools.h"
+#include "pcep_utils_memory.h"
+#include "pcep_msg_tlvs_test.h"
+
+/*
+ * Notice:
+ * All of these TLV Unit Tests encode the created TLVs by explicitly calling
+ * pcep_encode_tlv() thus testing the TLV creation and the TLV encoding.
+ * All APIs expect IPs to be in network byte order.
+ */
+
+static struct pcep_versioning *versioning = NULL;
+static uint8_t tlv_buf[2000];
+
+void reset_tlv_buffer(void);
+
+int pcep_tlvs_test_suite_setup(void)
+{
+ pceplib_memory_reset();
+ return 0;
+}
+
+int pcep_tlvs_test_suite_teardown(void)
+{
+ printf("\n");
+ pceplib_memory_dump();
+ return 0;
+}
+
+void reset_tlv_buffer()
+{
+ memset(tlv_buf, 0, 2000);
+}
+
+void pcep_tlvs_test_setup()
+{
+ versioning = create_default_pcep_versioning();
+ reset_tlv_buffer();
+}
+
+void pcep_tlvs_test_teardown()
+{
+ destroy_pcep_versioning(versioning);
+}
+
+void test_pcep_tlv_create_stateful_pce_capability()
+{
+ struct pcep_object_tlv_stateful_pce_capability *tlv =
+ pcep_tlv_create_stateful_pce_capability(true, true, true, true,
+ true, true);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t));
+ CU_ASSERT_TRUE(tlv->flag_u_lsp_update_capability);
+ CU_ASSERT_TRUE(tlv->flag_s_include_db_version);
+ CU_ASSERT_TRUE(tlv->flag_i_lsp_instantiation_capability);
+ CU_ASSERT_TRUE(tlv->flag_t_triggered_resync);
+ CU_ASSERT_TRUE(tlv->flag_d_delta_lsp_sync);
+ CU_ASSERT_TRUE(tlv->flag_f_triggered_initial_sync);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[7], 0x3f);
+ /* TODO add a new function: verify_tlv_header(tlv->header.encoded_tlv)
+ * to all tests */
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_speaker_entity_id()
+{
+ struct pcep_object_tlv_speaker_entity_identifier *tlv =
+ pcep_tlv_create_speaker_entity_id(NULL);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ double_linked_list *list = dll_initialize();
+ tlv = pcep_tlv_create_speaker_entity_id(list);
+ CU_ASSERT_PTR_NULL(tlv);
+ if (tlv != NULL) {
+ pceplib_free(PCEPLIB_INFRA, tlv);
+ tlv = NULL;
+ }
+
+ uint32_t *speaker_entity =
+ pceplib_malloc(PCEPLIB_MESSAGES, sizeof(uint32_t));
+ *speaker_entity = 42;
+ dll_append(list, speaker_entity);
+ tlv = pcep_tlv_create_speaker_entity_id(list);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t));
+ CU_ASSERT_PTR_NOT_NULL(tlv->speaker_entity_id_list);
+ assert(tlv->speaker_entity_id_list != NULL);
+ CU_ASSERT_EQUAL(tlv->speaker_entity_id_list->num_entries, 1);
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1], htonl(*speaker_entity));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_lsp_db_version()
+{
+ uint64_t lsp_db_version = 0xf005ba11ba5eba11;
+ struct pcep_object_tlv_lsp_db_version *tlv =
+ pcep_tlv_create_lsp_db_version(lsp_db_version);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint64_t));
+ CU_ASSERT_EQUAL(tlv->lsp_db_version, lsp_db_version);
+ CU_ASSERT_EQUAL(*((uint64_t *)(tlv->header.encoded_tlv + 4)),
+ be64toh(lsp_db_version));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_path_setup_type()
+{
+ uint8_t pst = 0x89;
+
+ struct pcep_object_tlv_path_setup_type *tlv =
+ pcep_tlv_create_path_setup_type(pst);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t));
+ CU_ASSERT_EQUAL(tlv->path_setup_type, pst);
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1], htonl(0x000000FF & pst));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_path_setup_type_capability()
+{
+ /* The sub_tlv list is optional */
+
+ /* Should return NULL if pst_list is NULL */
+ struct pcep_object_tlv_path_setup_type_capability *tlv =
+ pcep_tlv_create_path_setup_type_capability(NULL, NULL);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ /* Should return NULL if pst_list is empty */
+ double_linked_list *pst_list = dll_initialize();
+ tlv = pcep_tlv_create_path_setup_type_capability(pst_list, NULL);
+ CU_ASSERT_PTR_NULL(tlv);
+ if (tlv != NULL) {
+ pcep_obj_free_tlv(&tlv->header);
+ tlv = NULL;
+ }
+
+ /* Should still return NULL if pst_list is NULL */
+ double_linked_list *sub_tlv_list = dll_initialize();
+ tlv = pcep_tlv_create_path_setup_type_capability(NULL, sub_tlv_list);
+ CU_ASSERT_PTR_NULL(tlv);
+ if (tlv != NULL) {
+ pcep_obj_free_tlv(&tlv->header);
+ tlv = NULL;
+ }
+
+ /* Should still return NULL if pst_list is empty */
+ tlv = pcep_tlv_create_path_setup_type_capability(pst_list,
+ sub_tlv_list);
+ CU_ASSERT_PTR_NULL(tlv);
+ if (tlv != NULL) {
+ pcep_obj_free_tlv(&tlv->header);
+ tlv = NULL;
+ }
+
+ /* Test only populating the pst list */
+ uint8_t *pst1 = pceplib_malloc(PCEPLIB_MESSAGES, 1);
+ uint8_t *pst2 = pceplib_malloc(PCEPLIB_MESSAGES, 1);
+ uint8_t *pst3 = pceplib_malloc(PCEPLIB_MESSAGES, 1);
+ *pst1 = 1;
+ *pst2 = 2;
+ *pst3 = 3;
+ dll_append(pst_list, pst1);
+ dll_append(pst_list, pst2);
+ dll_append(pst_list, pst3);
+ tlv = pcep_tlv_create_path_setup_type_capability(pst_list,
+ sub_tlv_list);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ if (tlv == NULL) {
+ CU_ASSERT_TRUE(tlv != NULL);
+ return;
+ }
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t) * 2);
+ CU_ASSERT_PTR_NOT_NULL(tlv->pst_list);
+ assert(tlv != NULL);
+ CU_ASSERT_EQUAL(tlv->pst_list->num_entries, 3);
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1], htonl(0x00000003));
+ CU_ASSERT_EQUAL(uint32_ptr[2], htonl(0x01020300));
+ pcep_obj_free_tlv(&tlv->header);
+
+ /* Now test populating both the pst_list and the sub_tlv_list */
+ reset_tlv_buffer();
+ struct pcep_object_tlv_header *sub_tlv =
+ (struct pcep_object_tlv_header *)
+ pcep_tlv_create_sr_pce_capability(true, true, 0);
+ pst_list = dll_initialize();
+ sub_tlv_list = dll_initialize();
+ pst1 = pceplib_malloc(PCEPLIB_MESSAGES, 1);
+ *pst1 = 1;
+ dll_append(pst_list, pst1);
+ dll_append(sub_tlv_list, sub_tlv);
+ tlv = pcep_tlv_create_path_setup_type_capability(pst_list,
+ sub_tlv_list);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length,
+ sizeof(uint32_t) * 2 + TLV_HEADER_LENGTH
+ + sub_tlv->encoded_tlv_length);
+ CU_ASSERT_PTR_NOT_NULL(tlv->pst_list);
+ CU_ASSERT_PTR_NOT_NULL(tlv->sub_tlv_list);
+ uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ uint16_t *uint16_ptr = (uint16_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint16_ptr[0],
+ htons(PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY));
+ CU_ASSERT_EQUAL(uint16_ptr[1], htons(tlv->header.encoded_tlv_length));
+ CU_ASSERT_EQUAL(uint32_ptr[1], htonl(0x00000001));
+ CU_ASSERT_EQUAL(uint32_ptr[2], htonl(0x01000000));
+ /* Verify the Sub-TLV */
+ uint16_ptr = (uint16_t *)(tlv->header.encoded_tlv + 12);
+ CU_ASSERT_EQUAL(uint16_ptr[0],
+ htons(PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY));
+ CU_ASSERT_EQUAL(uint16_ptr[1], htons(4));
+ CU_ASSERT_EQUAL(uint16_ptr[2], 0);
+ CU_ASSERT_EQUAL(uint16_ptr[3], htons(0x0300));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_sr_pce_capability()
+{
+ struct pcep_object_tlv_sr_pce_capability *tlv =
+ pcep_tlv_create_sr_pce_capability(true, true, 8);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t));
+ uint16_t *uint16_ptr = (uint16_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint16_ptr[0],
+ htons(PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY));
+ CU_ASSERT_EQUAL(uint16_ptr[1], htons(tlv->header.encoded_tlv_length));
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1], htonl(0x00000308));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_symbolic_path_name()
+{
+ /* char *symbolic_path_name, uint16_t symbolic_path_name_length); */
+ char path_name[16] = "Some Path Name";
+ uint16_t path_name_length = 14;
+ struct pcep_object_tlv_symbolic_path_name *tlv =
+ pcep_tlv_create_symbolic_path_name(path_name, path_name_length);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, path_name_length);
+ /* Test the padding is correct */
+ CU_ASSERT_EQUAL(0, strncmp((char *)&(tlv->header.encoded_tlv[4]),
+ &path_name[0], 4));
+ CU_ASSERT_EQUAL(0, strncmp((char *)&(tlv->header.encoded_tlv[8]),
+ &path_name[4], 4));
+ CU_ASSERT_EQUAL(0, strncmp((char *)&(tlv->header.encoded_tlv[12]),
+ &path_name[8], 4));
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[16], 'm');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[17], 'e');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[18], 0);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[19], 0);
+ pcep_obj_free_tlv(&tlv->header);
+
+ reset_tlv_buffer();
+ tlv = pcep_tlv_create_symbolic_path_name(path_name, 3);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ printf("El tlv es %p", tlv);
+ assert(tlv != NULL); // crash si FALSE
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, 3);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[4], 'S');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[5], 'o');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[6], 'm');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[7], 0);
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_ipv4_lsp_identifiers()
+{
+ struct in_addr sender_ip, endpoint_ip;
+ uint16_t lsp_id = 7;
+ uint16_t tunnel_id = 16;
+ struct in_addr extended_tunnel_id;
+ extended_tunnel_id.s_addr = 256;
+ inet_pton(AF_INET, "192.168.1.1", &sender_ip);
+ inet_pton(AF_INET, "192.168.1.2", &endpoint_ip);
+
+ struct pcep_object_tlv_ipv4_lsp_identifier *tlv =
+ pcep_tlv_create_ipv4_lsp_identifiers(NULL, &endpoint_ip, lsp_id,
+ tunnel_id,
+ &extended_tunnel_id);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ tlv = pcep_tlv_create_ipv4_lsp_identifiers(
+ &sender_ip, NULL, lsp_id, tunnel_id, &extended_tunnel_id);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ tlv = pcep_tlv_create_ipv4_lsp_identifiers(
+ NULL, NULL, lsp_id, tunnel_id, &extended_tunnel_id);
+ CU_ASSERT_PTR_NULL(tlv);
+ assert(tlv == NULL);
+
+ tlv = pcep_tlv_create_ipv4_lsp_identifiers(&sender_ip, &endpoint_ip,
+ lsp_id, tunnel_id,
+ &extended_tunnel_id);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t) * 4);
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1], sender_ip.s_addr);
+ CU_ASSERT_EQUAL(uint32_ptr[2],
+ (uint32_t)(htons(tunnel_id) << 16) | htons(lsp_id));
+ CU_ASSERT_EQUAL(uint32_ptr[3], extended_tunnel_id.s_addr);
+ CU_ASSERT_EQUAL(uint32_ptr[4], endpoint_ip.s_addr);
+ pcep_obj_free_tlv(&tlv->header);
+
+ reset_tlv_buffer();
+ tlv = pcep_tlv_create_ipv4_lsp_identifiers(&sender_ip, &endpoint_ip,
+ lsp_id, tunnel_id, NULL);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t) * 4);
+ uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1], sender_ip.s_addr);
+ CU_ASSERT_EQUAL(uint32_ptr[2],
+ (uint32_t)(htons(tunnel_id) << 16) | htons(lsp_id));
+ CU_ASSERT_EQUAL(uint32_ptr[3], INADDR_ANY);
+ CU_ASSERT_EQUAL(uint32_ptr[4], endpoint_ip.s_addr);
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_ipv6_lsp_identifiers()
+{
+ struct in6_addr sender_ip, endpoint_ip;
+ uint16_t lsp_id = 3;
+ uint16_t tunnel_id = 16;
+ uint32_t extended_tunnel_id[4];
+
+ inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &sender_ip);
+ inet_pton(AF_INET6, "2001:db8::8a2e:370:8446", &endpoint_ip);
+ extended_tunnel_id[0] = 1;
+ extended_tunnel_id[1] = 2;
+ extended_tunnel_id[2] = 3;
+ extended_tunnel_id[3] = 4;
+
+ struct pcep_object_tlv_ipv6_lsp_identifier *tlv =
+ pcep_tlv_create_ipv6_lsp_identifiers(
+ NULL, &endpoint_ip, lsp_id, tunnel_id,
+ (struct in6_addr *)&extended_tunnel_id);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ tlv = pcep_tlv_create_ipv6_lsp_identifiers(
+ &sender_ip, NULL, lsp_id, tunnel_id,
+ (struct in6_addr *)&extended_tunnel_id);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ tlv = pcep_tlv_create_ipv6_lsp_identifiers(
+ NULL, NULL, lsp_id, tunnel_id,
+ (struct in6_addr *)&extended_tunnel_id);
+ CU_ASSERT_PTR_NULL(tlv);
+ assert(tlv == NULL);
+
+ tlv = pcep_tlv_create_ipv6_lsp_identifiers(
+ &sender_ip, &endpoint_ip, lsp_id, tunnel_id,
+ (struct in6_addr *)&extended_tunnel_id);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, 52);
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[5],
+ (uint32_t)(htons(tunnel_id) << 16) | htons(lsp_id));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+void test_pcep_tlv_create_srpag_pol_id_ipv4()
+{
+ uint32_t color = 1;
+ struct in_addr src;
+ inet_pton(AF_INET, "192.168.1.2", &src);
+
+ struct pcep_object_tlv_srpag_pol_id *tlv =
+ pcep_tlv_create_srpag_pol_id_ipv4(color, (void *)&src);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, (PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID));
+ CU_ASSERT_EQUAL(
+ tlv->header.encoded_tlv_length,
+ (8 /*draft-barth-pce-segment-routing-policy-cp-04#5.1*/));
+ CU_ASSERT_EQUAL(tlv->color, (color));
+ uint32_t aux_color = htonl(color); // Is color right encoded
+ CU_ASSERT_EQUAL(0, memcmp(&tlv_buf[0] + TLV_HEADER_LENGTH, &aux_color,
+ sizeof(color)));
+ CU_ASSERT_EQUAL(tlv->end_point.ipv4.s_addr, (src.s_addr));
+ // Are simetrical?
+ struct pcep_object_tlv_header *dec_hdr = pcep_decode_tlv(tlv_buf);
+ struct pcep_object_tlv_srpag_pol_id *dec_tlv =
+ (struct pcep_object_tlv_srpag_pol_id *)dec_hdr;
+ CU_ASSERT_EQUAL(tlv->color, dec_tlv->color);
+
+ pceplib_free(PCEPLIB_MESSAGES, dec_hdr);
+ pcep_obj_free_tlv(&tlv->header);
+}
+void test_pcep_tlv_create_srpag_pol_id_ipv6()
+{
+
+ uint32_t color = 1;
+ struct in6_addr src;
+ inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &src);
+
+ struct pcep_object_tlv_srpag_pol_id *tlv =
+ pcep_tlv_create_srpag_pol_id_ipv6(color, &src);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, (PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID));
+ CU_ASSERT_EQUAL(
+ tlv->header.encoded_tlv_length,
+ (20 /*draft-barth-pce-segment-routing-policy-cp-04#5.1*/));
+ CU_ASSERT_EQUAL(tlv->color, (color));
+ CU_ASSERT_EQUAL(0, memcmp(&tlv->end_point.ipv6, &src, sizeof(src)));
+
+ uint32_t aux_color = htonl(color);
+ CU_ASSERT_EQUAL(0, memcmp(&aux_color, tlv_buf + TLV_HEADER_LENGTH,
+ sizeof(tlv->color)));
+ // Are simetrical?
+ struct pcep_object_tlv_header *dec_hdr = pcep_decode_tlv(tlv_buf);
+ struct pcep_object_tlv_srpag_pol_id *dec_tlv =
+ (struct pcep_object_tlv_srpag_pol_id *)dec_hdr;
+ CU_ASSERT_EQUAL(tlv->color, dec_tlv->color);
+
+ pceplib_free(PCEPLIB_MESSAGES, dec_hdr);
+ pcep_obj_free_tlv(&tlv->header);
+}
+void test_pcep_tlv_create_srpag_pol_name()
+{
+ const char *pol_name = "Some Pol Name";
+
+ struct pcep_object_tlv_srpag_pol_name *tlv =
+ pcep_tlv_create_srpag_pol_name(pol_name, strlen(pol_name));
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ (PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME));
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length,
+ (normalize_pcep_tlv_length(strlen(pol_name))));
+ CU_ASSERT_EQUAL(0, strcmp(pol_name, (char *)tlv->name));
+
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_srpag_cp_id()
+{
+ // draft-ietf-spring-segment-routing-policy-06.pdf#2.3
+ // 10 PCEP, 20 BGP SR Policy, 30 Via Configuration
+ uint8_t proto_origin = 10;
+ uint32_t ASN = 0;
+ struct in6_addr with_mapped_ipv4;
+ inet_pton(AF_INET6, "::ffff:192.0.2.128", &with_mapped_ipv4);
+ uint32_t discriminator = 0;
+
+ struct pcep_object_tlv_srpag_cp_id *tlv = pcep_tlv_create_srpag_cp_id(
+ proto_origin, ASN, &with_mapped_ipv4, discriminator);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ (PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID));
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length,
+ (sizeof(proto_origin) + sizeof(ASN)
+ + sizeof(with_mapped_ipv4) + sizeof(discriminator)));
+ CU_ASSERT_EQUAL(tlv->proto, (proto_origin));
+ CU_ASSERT_EQUAL(tlv->orig_asn, (ASN));
+ CU_ASSERT_EQUAL(0, memcmp(&tlv->orig_addres, &with_mapped_ipv4,
+ sizeof(with_mapped_ipv4)));
+ CU_ASSERT_EQUAL(tlv->discriminator, (discriminator));
+ // Are simetrical?
+ struct pcep_object_tlv_header *dec_hdr = pcep_decode_tlv(tlv_buf);
+ struct pcep_object_tlv_srpag_cp_id *dec_tlv =
+ (struct pcep_object_tlv_srpag_cp_id *)dec_hdr;
+ CU_ASSERT_EQUAL(tlv->proto, dec_tlv->proto);
+
+ pceplib_free(PCEPLIB_MESSAGES, dec_hdr);
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_srpag_cp_pref()
+{
+ uint32_t preference_default = 100;
+
+ struct pcep_object_tlv_srpag_cp_pref *tlv =
+ pcep_tlv_create_srpag_cp_pref(preference_default);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type,
+ (PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE));
+ printf(" encoded length vs sizeof pref (%d) vs (%ld)\n",
+ tlv->header.encoded_tlv_length, sizeof(preference_default));
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length,
+ sizeof(preference_default));
+ CU_ASSERT_EQUAL(tlv->preference, (preference_default));
+ uint32_t aux_pref = htonl(preference_default); // Is pref right encoded
+ CU_ASSERT_EQUAL(0, memcmp(tlv_buf + TLV_HEADER_LENGTH, &aux_pref,
+ sizeof(preference_default)));
+ // Are simetrical?
+ struct pcep_object_tlv_header *dec_hdr = pcep_decode_tlv(tlv_buf);
+ struct pcep_object_tlv_srpag_cp_pref *dec_tlv =
+ (struct pcep_object_tlv_srpag_cp_pref *)dec_hdr;
+ CU_ASSERT_EQUAL(tlv->preference, dec_tlv->preference);
+
+ pceplib_free(PCEPLIB_MESSAGES, dec_hdr);
+ pcep_obj_free_tlv(&tlv->header);
+}
+void test_pcep_tlv_create_lsp_error_code()
+{
+ struct pcep_object_tlv_lsp_error_code *tlv =
+ pcep_tlv_create_lsp_error_code(
+ PCEP_TLV_LSP_ERROR_CODE_RSVP_SIGNALING_ERROR);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, sizeof(uint32_t));
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1],
+ htonl(PCEP_TLV_LSP_ERROR_CODE_RSVP_SIGNALING_ERROR));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_rsvp_ipv4_error_spec()
+{
+ struct in_addr error_node_ip;
+ inet_pton(AF_INET, "192.168.1.1", &error_node_ip);
+ uint8_t error_code = 8;
+ uint16_t error_value = 0xaabb;
+
+ struct pcep_object_tlv_rsvp_error_spec *tlv =
+ pcep_tlv_create_rsvp_ipv4_error_spec(NULL, error_code,
+ error_value);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ tlv = pcep_tlv_create_rsvp_ipv4_error_spec(&error_node_ip, error_code,
+ error_value);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, 12);
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_rsvp_ipv6_error_spec()
+{
+ struct in6_addr error_node_ip;
+ inet_pton(AF_INET6, "2001:db8::8a2e:370:7334", &error_node_ip);
+ uint8_t error_code = 8;
+ uint16_t error_value = 0xaabb;
+
+ struct pcep_object_tlv_rsvp_error_spec *tlv =
+ pcep_tlv_create_rsvp_ipv6_error_spec(NULL, error_code,
+ error_value);
+ CU_ASSERT_PTR_NULL(tlv);
+
+ tlv = pcep_tlv_create_rsvp_ipv6_error_spec(&error_node_ip, error_code,
+ error_value);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, 24);
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_nopath_vector()
+{
+ uint32_t enterprise_number = 0x01020304;
+ uint32_t enterprise_specific_info = 0x05060708;
+
+ struct pcep_object_tlv_vendor_info *tlv = pcep_tlv_create_vendor_info(
+ enterprise_number, enterprise_specific_info);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, PCEP_OBJ_TLV_TYPE_VENDOR_INFO);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, 8);
+ uint32_t *uint32_ptr = (uint32_t *)tlv->header.encoded_tlv;
+ CU_ASSERT_EQUAL(uint32_ptr[1], htonl(enterprise_number));
+ CU_ASSERT_EQUAL(uint32_ptr[2], htonl(enterprise_specific_info));
+
+ pcep_obj_free_tlv(&tlv->header);
+}
+
+void test_pcep_tlv_create_arbitrary()
+{
+ char data[16] = "Some Data";
+ uint16_t data_length = 9;
+ uint16_t tlv_id_unknown = 1; // 65505; // Whatever id to be created
+ struct pcep_object_tlv_arbitrary *tlv = pcep_tlv_create_tlv_arbitrary(
+ data, data_length, tlv_id_unknown);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, tlv_id_unknown);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, data_length);
+ /* Test the padding is correct */
+ CU_ASSERT_EQUAL(
+ 0, strncmp((char *)&(tlv->header.encoded_tlv[4]), &data[0], 4));
+ CU_ASSERT_EQUAL(
+ 0, strncmp((char *)&(tlv->header.encoded_tlv[8]), &data[4], 4));
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[11], 't');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[12], 'a');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[13], 0);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[14], 0);
+ pcep_obj_free_tlv(&tlv->header);
+
+ reset_tlv_buffer();
+ tlv = pcep_tlv_create_tlv_arbitrary(data, 3, tlv_id_unknown);
+ CU_ASSERT_PTR_NOT_NULL(tlv);
+ assert(tlv != NULL);
+ pcep_encode_tlv(&tlv->header, versioning, tlv_buf);
+ CU_ASSERT_EQUAL(tlv->header.type, tlv_id_unknown);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv_length, 3);
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[4], 'S');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[5], 'o');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[6], 'm');
+ CU_ASSERT_EQUAL(tlv->header.encoded_tlv[7], 0);
+
+ pcep_obj_free_tlv(&tlv->header);
+}