/* * 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 . * * Author : Brady Johnson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __FreeBSD__ #include #else #include #endif /* __FreeBSD__ */ #include #include #include #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); }