mirror_frr/pceplib/test/pcep_msg_tlvs_test.c
David Lamparter 0490ce41c1 pceplib: add missing endian.h and config.h
endian.h supplies be*toh() and htobe*() functions.  This fixes the build
on musl libc.  On other systems it seems endian.h comes in transitively
from some other header.

(Also, all .c files should have config.h or zebra.h as the first
include, even if it works without that it's b0rked and only works due to
luck.)

Tested-by: Lucian Cristian <lucian.cristian@gmail.com>
Signed-off-by: David Lamparter <equinox@diac24.net>
2021-04-09 20:41:57 +02:00

701 lines
23 KiB
C

/*
* 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 <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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
}