diff options
Diffstat (limited to '')
-rw-r--r-- | pceplib/test/pcep_msg_tlvs_test.c | 725 |
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); +} |