From: Alex Stancu Date: Thu, 30 Sep 2021 08:18:20 +0000 (+0300) Subject: Add network emulation feature. X-Git-Tag: 1.5.0~19 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fo1-interface.git;a=commitdiff_plain;h=22cd30649dfac2fcfdf233765aa7feeea7141d96 Add network emulation feature. Issue-ID: SIM-78 Change-Id: I20a9ad92ed09316ab65b9ef74cdbd93b1082a1f6 Signed-off-by: Alex Stancu --- diff --git a/ntsimulator/deploy/base/build_ntsim-ng.sh b/ntsimulator/deploy/base/build_ntsim-ng.sh index fe7a367..aa24594 100755 --- a/ntsimulator/deploy/base/build_ntsim-ng.sh +++ b/ntsimulator/deploy/base/build_ntsim-ng.sh @@ -49,6 +49,7 @@ files=( "utils/http_client.c" "utils/nts_utils.c" "utils/nc_client.c" + "utils/network_emulation.c" "features/ves_pnf_registration/ves_pnf_registration.c" "features/ves_heartbeat/ves_heartbeat.c" "features/ves_file_ready/ves_file_ready.c" diff --git a/ntsimulator/deploy/base/ubuntu.Dockerfile b/ntsimulator/deploy/base/ubuntu.Dockerfile index 354ef0c..cacd9d1 100644 --- a/ntsimulator/deploy/base/ubuntu.Dockerfile +++ b/ntsimulator/deploy/base/ubuntu.Dockerfile @@ -161,9 +161,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ openssh-client \ vsftpd \ openssh-server \ + iproute2 \ && rm -rf /var/lib/apt/lists/* - ARG BUILD_WITH_DEBUG ENV BUILD_WITH_DEBUG=${BUILD_WITH_DEBUG} RUN if [ -n "${BUILD_WITH_DEBUG}" ]; then DEBIAN_FRONTEND="noninteractive" apt-get install -y gdb valgrind nano mc && unset BUILD_WITH_DEBUG; fi diff --git a/ntsimulator/deploy/base/yang/nts-network-function.yang b/ntsimulator/deploy/base/yang/nts-network-function.yang index 626038d..69c39fc 100644 --- a/ntsimulator/deploy/base/yang/nts-network-function.yang +++ b/ntsimulator/deploy/base/yang/nts-network-function.yang @@ -21,6 +21,12 @@ module nts-network-function { description "This module contains YANG definitions for the Network Topology Simulator - Network Functions"; + revision 2021-05-17 { + description + "Added support for network emulation."; + reference + "O-RAN-SC SIM project"; + } revision 2021-03-26 { description "Added info container, and expanted feature control mechanism and status."; @@ -183,6 +189,139 @@ module nts-network-function { uses ntsc:netconf-config-g; uses ntsc:ves-config-g; } + container network-emulation { + description + "Container which encompasses the details of the network emulation."; + leaf limit { + type uint16 { + range "16 .. max"; + } + units "packets"; + default "1000"; + description + "Maximum number of packets the qdisc may hold queued at a time."; + } + container delay { + description + "Adds the chosen delay to the packets outgoing to chosen network interface."; + leaf time { + type uint16; + units "miliseconds (ms)"; + description + "Delay time between packets."; + } + leaf jitter { + type uint16; + units "miliseconds (ms)"; + description + "Delay jitter."; + } + leaf correlation { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Delay correlation."; + } + leaf distribution { + type enumeration { + enum uniform { + description + "Uniform delay distribution."; + } + enum normal { + description + "Normal delay distribution."; + } + enum pareto { + description + "Pareto delay distribution."; + } + enum paretonormal { + description + "Paretonormal delay distribution."; + } + } + description + "Delay distribution."; + } + } + leaf loss { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Adds an independent loss probability to the packets outgoing from the chosen network interface."; + } + container corruption { + description + "Allows the emulation of random noise introducing an error in a random position for a chosen percent of packets."; + leaf percentage { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Corruption percentage."; + } + leaf correlation { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Corruption correlation."; + } + } + container duplication { + description + "Using this option the chosen percent of packets is duplicated before queuing them."; + leaf percentage { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Duplication percentage."; + } + leaf correlation { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Duplication correlation."; + } + } + container reordering { + description + "Used together with delay; a percentage of packets are sent immediately (with defined correlation) while the others are delayed (by specified delay)."; + leaf percentage { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Reordering percentage."; + } + leaf correlation { + type uint8 { + range "0 .. 100"; + } + units "percentage"; + description + "Reordering correlation."; + } + } + leaf rate { + type uint16; + units "kbits"; + description + "Delay packets based on packet size."; + } + } container sdn-controller { description "Groups details about the SDN Controller."; diff --git a/ntsimulator/deploy/blank/container-tag.yaml b/ntsimulator/deploy/blank/container-tag.yaml index 7377987..edd6735 100644 --- a/ntsimulator/deploy/blank/container-tag.yaml +++ b/ntsimulator/deploy/blank/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 1.3.3 \ No newline at end of file +tag: 1.3.4 \ No newline at end of file diff --git a/ntsimulator/deploy/nts-manager/container-tag.yaml b/ntsimulator/deploy/nts-manager/container-tag.yaml index 7377987..edd6735 100644 --- a/ntsimulator/deploy/nts-manager/container-tag.yaml +++ b/ntsimulator/deploy/nts-manager/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 1.3.3 \ No newline at end of file +tag: 1.3.4 \ No newline at end of file diff --git a/ntsimulator/deploy/o-ran-du/container-tag.yaml b/ntsimulator/deploy/o-ran-du/container-tag.yaml index 7377987..edd6735 100644 --- a/ntsimulator/deploy/o-ran-du/container-tag.yaml +++ b/ntsimulator/deploy/o-ran-du/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 1.3.3 \ No newline at end of file +tag: 1.3.4 \ No newline at end of file diff --git a/ntsimulator/deploy/o-ran-ru-fh/container-tag.yaml b/ntsimulator/deploy/o-ran-ru-fh/container-tag.yaml index 7377987..edd6735 100644 --- a/ntsimulator/deploy/o-ran-ru-fh/container-tag.yaml +++ b/ntsimulator/deploy/o-ran-ru-fh/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 1.3.3 \ No newline at end of file +tag: 1.3.4 \ No newline at end of file diff --git a/ntsimulator/deploy/o-ran/container-tag.yaml b/ntsimulator/deploy/o-ran/container-tag.yaml index 7377987..edd6735 100644 --- a/ntsimulator/deploy/o-ran/container-tag.yaml +++ b/ntsimulator/deploy/o-ran/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 1.3.3 \ No newline at end of file +tag: 1.3.4 \ No newline at end of file diff --git a/ntsimulator/deploy/x-ran/container-tag.yaml b/ntsimulator/deploy/x-ran/container-tag.yaml index 7377987..edd6735 100644 --- a/ntsimulator/deploy/x-ran/container-tag.yaml +++ b/ntsimulator/deploy/x-ran/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 1.3.3 \ No newline at end of file +tag: 1.3.4 \ No newline at end of file diff --git a/ntsimulator/ntsim-ng/core/app/app_common.c b/ntsimulator/ntsim-ng/core/app/app_common.c index 74be703..e74b655 100644 --- a/ntsimulator/ntsim-ng/core/app/app_common.c +++ b/ntsimulator/ntsim-ng/core/app/app_common.c @@ -20,6 +20,7 @@ #include "supervisor.h" #include "utils/log_utils.h" #include "utils/sys_utils.h" +#include "utils/network_emulation.h" #include #include @@ -28,6 +29,8 @@ #include "core/framework.h" static int app_common_populate_info(void); +static int app_common_populate_network_emulation_info(void); +static int app_common_populate_network_emulation_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data); int app_common_init(void) { assert_session(); @@ -38,20 +41,35 @@ int app_common_init(void) { return NTS_ERR_FAILED; } + network_emulation_init(); + + rc = app_common_populate_network_emulation_info(); + if(rc != NTS_ERR_OK) { + log_error("app_common_populate_network_emulation() failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_module_change_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH, app_common_populate_network_emulation_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_UPDATE, &session_subscription); + if(rc != SR_ERR_OK) { + log_error("could not subscribe to faults"); + return NTS_ERR_FAILED; + } + return NTS_ERR_OK; } static int app_common_populate_info(void) { int rc; + if (framework_environment.nts.build_time && strlen(framework_environment.nts.build_time) > 0) { - rc = sr_set_item_str(session_operational, NTS_NF_INFO_BUILD_TIME_XPATH, framework_environment.nts.build_time, 0, 0); + rc = sr_set_item_str(session_operational, NTS_NF_INFO_SCHEMA_XPATH"/build-time", framework_environment.nts.build_time, 0, 0); if(rc != SR_ERR_OK) { log_error("sr_set_item_str failed\n"); return NTS_ERR_FAILED; } } - rc = sr_set_item_str(session_operational, NTS_NF_INFO_VERSION_XPATH, framework_environment.nts.version, 0, 0); + rc = sr_set_item_str(session_operational, NTS_NF_INFO_SCHEMA_XPATH"/version", framework_environment.nts.version, 0, 0); if(rc != SR_ERR_OK) { log_error("sr_set_item_str failed\n"); return NTS_ERR_FAILED; @@ -65,3 +83,213 @@ static int app_common_populate_info(void) { return NTS_ERR_OK; } + +static int app_common_populate_network_emulation_info(void) { + int rc; + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/limit", NETWORK_EMULATION_DEFAULT_LIMIT, 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/time", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/jitter", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/correlation", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/distribution", "normal", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/loss", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/corruption/percentage", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/corruption/correlation", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/duplication/percentage", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/duplication/correlation", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/reordering/percentage", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/reordering/correlation", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_set_item_str(session_running, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/rate", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item_str failed\n"); + return NTS_ERR_FAILED; + } + + rc = sr_apply_changes(session_running, 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_apply_changes failed: %s\n", sr_strerror(rc)); + return NTS_ERR_FAILED; + } + + return NTS_ERR_OK; +} + +static int app_common_populate_network_emulation_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) { + + if(event == SR_EV_UPDATE) { + sr_change_iter_t *it = 0; + int rc = SR_ERR_OK; + sr_change_oper_t oper; + sr_val_t *old_value = 0; + sr_val_t *new_value = 0; + + rc = sr_get_changes_iter(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"//.", &it); + if(rc != SR_ERR_OK) { + log_error("sr_get_changes_iter failed\n"); + return SR_ERR_VALIDATION_FAILED; + } + + uint16_t delay_time = 0; + uint16_t delay_jitter = 0; + + while((rc = sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) { + if(new_value->xpath && (strstr(new_value->xpath, "/delay/time"))) { + delay_time = new_value->data.uint16_val; + } + + if(new_value->xpath && (strstr(new_value->xpath, "/delay/jitter"))) { + delay_jitter = new_value->data.uint16_val; + } + sr_free_val(old_value); + sr_free_val(new_value); + } + + sr_free_change_iter(it); + + if((delay_time == 0) || (delay_jitter == 0)) { + rc = sr_set_item_str(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/distribution", "normal", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item failed\n"); + return SR_ERR_VALIDATION_FAILED; + } + } + + if(delay_time == 0) { + rc = sr_set_item_str(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/jitter", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item failed\n"); + return SR_ERR_VALIDATION_FAILED; + } + + rc = sr_set_item_str(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"/delay/correlation", "0", 0, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item failed\n"); + return SR_ERR_VALIDATION_FAILED; + } + } + } + else if(event == SR_EV_DONE) { + sr_val_t *values = NULL; + size_t count = 0; + + int rc = sr_get_items(session, NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH"//.", 0, 0, &values, &count); + if (rc != SR_ERR_OK) { + log_error("sr_get_items failed\n"); + return rc; + } + + network_emultation_settings_t s; + + for(size_t i = 0; i < count; i++) { + if(strstr(values[i].xpath, "/limit")) { + s.limit = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/delay/time")) { + s.delay.time = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/delay/jitter")) { + s.delay.jitter = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/delay/correlation")) { + s.delay.correlation = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/delay/distribution")) { + s.delay.distribution = strdup(values[i].data.string_val); + } + else if(strstr(values[i].xpath, "/loss")) { + s.loss = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/corruption/percentage")) { + s.corruption.percentage = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/corruption/correlation")) { + s.corruption.correlation = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/duplication/percentage")) { + s.duplication.percentage = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/duplication/correlation")) { + s.duplication.correlation = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/reordering/percentage")) { + s.reordering.percentage = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/reordering/correlation")) { + s.reordering.correlation = values[i].data.uint16_val; + } + else if(strstr(values[i].xpath, "/rate")) { + s.rate = values[i].data.uint16_val; + } + } + + sr_free_values(values, count); + if(network_emulation_update(&s) != NTS_ERR_OK) { + log_error("network_emulation_update() failed\n"); + free(s.delay.distribution); + return SR_ERR_OPERATION_FAILED; + } + free(s.delay.distribution); + } + + return SR_ERR_OK; +} diff --git a/ntsimulator/ntsim-ng/core/app/network_function.c b/ntsimulator/ntsim-ng/core/app/network_function.c index af80c94..2a5ff0f 100644 --- a/ntsimulator/ntsim-ng/core/app/network_function.c +++ b/ntsimulator/ntsim-ng/core/app/network_function.c @@ -56,8 +56,7 @@ static int network_function_feature_control_cb(sr_session_ctx_t *session, const static int network_function_faults_clear_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt, sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data); static int network_function_faults_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data); static int network_function_faults_count_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data); - -static int network_function_started_features_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data); +static int network_function_info_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data); static int network_function_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data); @@ -131,13 +130,13 @@ int network_function_run(void) { rc = sr_module_change_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_FAULT_GENERATION_SCHEMA_XPATH, network_function_faults_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &session_subscription); if(rc != SR_ERR_OK) { log_error("could not subscribe to faults"); - return 0; + return NTS_ERR_FAILED; } rc = sr_oper_get_items_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_FAULT_COUNT_LIST_SCHEMA_XPATH, network_function_faults_count_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE, &session_subscription); if(rc != SR_ERR_OK) { log_error("could not subscribe to oper faults: %s\n", sr_strerror(rc)); - return 0; + return NTS_ERR_FAILED; } rc = sr_rpc_subscribe(session_running, NTS_NF_RPC_FAULTS_CLEAR_SCHEMA_XPATH, network_function_faults_clear_cb, 0, 0, SR_SUBSCR_CTX_REUSE, &session_subscription); @@ -146,23 +145,22 @@ int network_function_run(void) { return NTS_ERR_FAILED; } - rc = sr_oper_get_items_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_INFO_STARTED_FEATURES_SCHEMA_XPATH, network_function_started_features_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE, &session_subscription); + rc = sr_oper_get_items_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_INFO_SCHEMA_XPATH, network_function_info_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_OPER_MERGE, &session_subscription); if(rc != SR_ERR_OK) { log_error("could not subscribe to oper started-features: %s\n", sr_strerror(rc)); - return 0; + return NTS_ERR_FAILED; } - //subscribe to any changes on the main - rc = sr_module_change_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_NETWORK_FUNCTION_SCHEMA_XPATH, network_function_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_UPDATE, &session_subscription); + rc = sr_module_change_subscribe(session_running, NTS_NETWORK_FUNCTION_MODULE, NTS_NF_NETWORK_FUNCTION_SCHEMA_XPATH, network_function_change_cb, NULL, 1, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_UPDATE, &session_subscription); if(rc != SR_ERR_OK) { - log_error("could not subscribe to simulation changes\n"); + log_error("could not subscribe to simulation changes: %s\n", sr_strerror(rc)); return NTS_ERR_FAILED; } rc = faults_init(); if(rc != NTS_ERR_OK) { - log_error("faults_init error\n", sr_strerror(rc)); + log_error("faults_init error\n"); return NTS_ERR_FAILED; } @@ -636,44 +634,50 @@ static int network_function_faults_count_get_items_cb(sr_session_ctx_t *session, return SR_ERR_OK; } -static int network_function_started_features_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) { - char value[1024]; - value[0] = 0; +static int network_function_info_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) { + char started_features[1024]; + started_features[0] = 0; if(ves_file_ready_feature_get_status()) { - strcat(value, "ves-file-ready "); + strcat(started_features, "ves-file-ready "); } if(ves_pnf_registration_feature_get_status()) { - strcat(value, "ves-pnf-registration "); + strcat(started_features, "ves-pnf-registration "); } if(ves_heartbeat_feature_get_status()) { - strcat(value, "ves-heartbeat "); + strcat(started_features, "ves-heartbeat "); } if(manual_notification_feature_get_status()) { - strcat(value, "manual-notification-generation "); + strcat(started_features, "manual-notification-generation "); } if(netconf_call_home_feature_get_status()) { - strcat(value, "netconf-call-home "); + strcat(started_features, "netconf-call-home "); } if(web_cut_through_feature_get_status()) { - strcat(value, "web-cut-through "); + strcat(started_features, "web-cut-through "); } - if(strlen(value)) { - value[strlen(value) - 1] = 0; + if(strlen(started_features)) { + started_features[strlen(started_features) - 1] = 0; } - *parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), NTS_NF_INFO_STARTED_FEATURES_SCHEMA_XPATH, value, 0, 0); + *parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), NTS_NF_INFO_SCHEMA_XPATH, 0, 0, 0); if(*parent == 0) { log_error("lyd_new_path failed\n"); return SR_ERR_OPERATION_FAILED; } + struct lyd_node *n = lyd_new_leaf(*parent, (*parent)->schema->module, "started-features", started_features); + if(n == 0) { + log_error("lyd_new_leaf failed\n"); + return SR_ERR_OPERATION_FAILED; + } + return SR_ERR_OK; } diff --git a/ntsimulator/ntsim-ng/core/datastore/generate.c b/ntsimulator/ntsim-ng/core/datastore/generate.c index 1fa255c..285dbcf 100644 --- a/ntsimulator/ntsim-ng/core/datastore/generate.c +++ b/ntsimulator/ntsim-ng/core/datastore/generate.c @@ -182,41 +182,42 @@ int datastore_generate_data(const char *running_filename, const char *operationa } } - char **xpaths = 0; - int instance_count = datastore_schema_get_xpaths(&xpaths); - if(instance_count < 0) { - log_error("datastore_schema_get_xpaths failed\n"); - return NTS_ERR_FAILED; - } + if(framework_config.datastore_populate.random_generation_enabled) { + char **xpaths = 0; + int instance_count = datastore_schema_get_xpaths(&xpaths); + if(instance_count < 0) { + log_error("datastore_schema_get_xpaths failed\n"); + return NTS_ERR_FAILED; + } - //exclude pre-populated modules - struct lyd_node *elem; - LY_TREE_FOR(job.operational, elem) { - for(int i = 0; i < instance_count; i++) { - if(strstr(xpaths[i], elem->schema->module->name) == (xpaths[i] + 1)) { //xpaths[i] is "/module:container" - free(xpaths[i]); + //exclude pre-populated modules + struct lyd_node *elem; + LY_TREE_FOR(job.operational, elem) { + for(int i = 0; i < instance_count; i++) { + if(strstr(xpaths[i], elem->schema->module->name) == (xpaths[i] + 1)) { //xpaths[i] is "/module:container" + free(xpaths[i]); - instance_count--; - for(int j = i; j < instance_count; j++) { - xpaths[j] = xpaths[j + 1]; - } + instance_count--; + for(int j = i; j < instance_count; j++) { + xpaths[j] = xpaths[j + 1]; + } - break; + break; + } } } - } - generate_instance_t *instance = (generate_instance_t *)malloc(sizeof(generate_instance_t) * instance_count); - if(!instance) { - log_error("bad malloc\n"); - for(int i = 0; i < instance_count; i++) { - free(xpaths[i]); + generate_instance_t *instance = (generate_instance_t *)malloc(sizeof(generate_instance_t) * instance_count); + if(!instance) { + log_error("bad malloc\n"); + for(int i = 0; i < instance_count; i++) { + free(xpaths[i]); + } + free(xpaths); + return NTS_ERR_FAILED; } - free(xpaths); - return NTS_ERR_FAILED; - } - if(framework_config.datastore_populate.random_generation_enabled) { + //RANDOM generate everything for(int i = 0; i < instance_count; i++) { log_add_verbose(1, "generating "LOG_COLOR_BOLD_YELLOW"%s"LOG_COLOR_RESET" data...\n", xpaths[i]); @@ -309,6 +310,20 @@ int datastore_generate_data(const char *running_filename, const char *operationa log_error("generate_validate failed\n"); return rc; } + + for(int i = 0; i < instance_count; i++) { + log_add(1, "%d ", i); + + free(instance[i].modules); + free(instance[i].xpath); + + free(xpaths[i]); + } + free(xpaths); + free(job.late_resolve_instance); + free(job.late_resolve_schema); + free(job.late_resolve_parent_o); + free(job.late_resolve_parent_r); } //export generated data @@ -321,19 +336,7 @@ int datastore_generate_data(const char *running_filename, const char *operationa //cleanup log_add_verbose(1, LOG_COLOR_BOLD_YELLOW"datastore_generate_data() cleaning up... "LOG_COLOR_RESET); - for(int i = 0; i < instance_count; i++) { - log_add(1, "%d ", i); - - free(instance[i].modules); - free(instance[i].xpath); - - free(xpaths[i]); - } - free(xpaths); - free(job.late_resolve_instance); - free(job.late_resolve_schema); - free(job.late_resolve_parent_o); - free(job.late_resolve_parent_r); + lyd_free_withsiblings(job.operational); lyd_free_withsiblings(job.running); @@ -347,8 +350,12 @@ int datastore_generate_data(const char *running_filename, const char *operationa int datastore_generate_external(void) { char cmd[512]; sprintf(cmd, "%s --generate", framework_arguments.argv[0]); - system(cmd); - return NTS_ERR_OK; + if(system(cmd) == 0) { + return NTS_ERR_OK; + } + else { + return NTS_ERR_FAILED; + } } diff --git a/ntsimulator/ntsim-ng/core/docker.c b/ntsimulator/ntsim-ng/core/docker.c index 3d5faa2..aea7ae8 100644 --- a/ntsimulator/ntsim-ng/core/docker.c +++ b/ntsimulator/ntsim-ng/core/docker.c @@ -555,9 +555,33 @@ static int docker_container_create(const char *image, docker_container_t *contai return NTS_ERR_FAILED; } + cJSON *capAdd = cJSON_CreateArray(); + if(capAdd == 0) { + log_error("could not create JSON array: CapAdd\n"); + cJSON_Delete(postDataJson); + return NTS_ERR_FAILED; + } + if(cJSON_AddItemToObject(hostConfig, "CapAdd", capAdd) == 0) { + log_error("cJSON_AddItemToObject failed\n"); + cJSON_Delete(postDataJson); + return NTS_ERR_FAILED; + } + cJSON *net_admin = cJSON_CreateString("NET_ADMIN"); + if(net_admin == 0) { + log_error("could not create JSON string\n"); + cJSON_Delete(postDataJson); + return NTS_ERR_FAILED; + } + if(cJSON_AddItemToArray(capAdd, net_admin) == 0) { + log_error("cJSON_AddItemToArray failed\n"); + cJSON_Delete(postDataJson); + return NTS_ERR_FAILED; + } + + cJSON *portBindings = cJSON_CreateObject(); if(portBindings == 0) { - printf("could not create JSON object: PortBindings"); + log_error("could not create JSON object: PortBindings\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } diff --git a/ntsimulator/ntsim-ng/core/xpath.h b/ntsimulator/ntsim-ng/core/xpath.h index b0514ff..3c57770 100644 --- a/ntsimulator/ntsim-ng/core/xpath.h +++ b/ntsimulator/ntsim-ng/core/xpath.h @@ -26,9 +26,7 @@ #define NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH "/nts-manager:simulation/ves-endpoint" #define NTS_NETWORK_FUNCTION_MODULE "nts-network-function" -#define NTS_NF_INFO_BUILD_TIME_XPATH "/nts-network-function:info/build-time" -#define NTS_NF_INFO_STARTED_FEATURES_SCHEMA_XPATH "/nts-network-function:info/started-features" -#define NTS_NF_INFO_VERSION_XPATH "/nts-network-function:info/version" +#define NTS_NF_INFO_SCHEMA_XPATH "/nts-network-function:info" #define NTS_NF_NETWORK_FUNCTION_SCHEMA_XPATH "/nts-network-function:simulation/network-function" #define NTS_NF_NETWORK_FUNCTION_FTYPE_SCHEMA_XPATH "/nts-network-function:simulation/network-function/function-type" #define NTS_NF_NETWORK_FUNCTION_MPAM_SCHEMA_XPATH "/nts-network-function:simulation/network-function/mount-point-addressing-method" @@ -41,6 +39,7 @@ #define NTS_NF_VES_FAULTS_ENABLED_SCHEMA_XPATH "/nts-network-function:simulation/network-function/ves/faults-enabled" #define NTS_NF_VES_HEARTBEAT_SCHEMA_XPATH "/nts-network-function:simulation/network-function/ves/heartbeat-period" #define NTS_NF_VES_PNF_REGISTRATION_SCHEMA_XPATH "/nts-network-function:simulation/network-function/ves/pnf-registration" +#define NTS_NF_NETWORK_EMULATION_SCHEMA_XPATH "/nts-network-function:simulation/network-emulation" #define NTS_NF_VES_ENDPOINT_CONFIG_XPATH "/nts-network-function:simulation/ves-endpoint" #define NTS_NF_SDN_CONTROLLER_CONFIG_XPATH "/nts-network-function:simulation/sdn-controller" @@ -49,6 +48,7 @@ #define NTS_NF_RPC_FAULTS_CLEAR_SCHEMA_XPATH "/nts-network-function:clear-fault-counters" #define NTS_NF_RPC_MANUAL_NOTIF_SCHEMA_XPATH "/nts-network-function:invoke-notification" #define NTS_NF_RPC_FILE_READY_SCHEMA_XPATH "/nts-network-function:invoke-ves-pm-file-ready" +#define NTS_NF_RPC_SET_NETWORK_LATENCY_SCHEMA_XPATH "/nts-network-function:set-network-latency" #define IETF_KEYSTORE_MODULE "ietf-keystore" #define IETF_KEYSTORE_SCHEMA_XPATH "/ietf-keystore:keystore" diff --git a/ntsimulator/ntsim-ng/features/ves_file_ready/ves_file_ready.c b/ntsimulator/ntsim-ng/features/ves_file_ready/ves_file_ready.c index f344f9a..12a7e4d 100644 --- a/ntsimulator/ntsim-ng/features/ves_file_ready/ves_file_ready.c +++ b/ntsimulator/ntsim-ng/features/ves_file_ready/ves_file_ready.c @@ -130,7 +130,7 @@ static int ves_file_ready_invoke_pm_cb(sr_session_ctx_t *session, const char *pa failed++; } } - + rc = sr_session_stop(current_session); if(rc != SR_ERR_OK) { log_error("could not stop sysrepo session\n"); diff --git a/ntsimulator/ntsim-ng/utils/http_client.c b/ntsimulator/ntsim-ng/utils/http_client.c index 4578dd4..dd15a6d 100644 --- a/ntsimulator/ntsim-ng/utils/http_client.c +++ b/ntsimulator/ntsim-ng/utils/http_client.c @@ -160,7 +160,7 @@ int http_socket_request(const char *url, const char *sock_fname, const char *met } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30); //seconds timeout for a connection + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); //seconds timeout for a connection curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); //seconds timeout for an operation curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L); curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); diff --git a/ntsimulator/ntsim-ng/utils/network_emulation.c b/ntsimulator/ntsim-ng/utils/network_emulation.c new file mode 100644 index 0000000..94af8c8 --- /dev/null +++ b/ntsimulator/ntsim-ng/utils/network_emulation.c @@ -0,0 +1,44 @@ +/************************************************************************* +* +* Copyright 2020 highstreet technologies GmbH and others +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +***************************************************************************/ + +#define _GNU_SOURCE + +#include "network_emulation.h" +#include "log_utils.h" +#include +#include +#include + +int network_emulation_init(void) { + system("tc qdisc add dev eth0 root netem limit "NETWORK_EMULATION_DEFAULT_LIMIT" delay 0ms > /dev/null"); + return NTS_ERR_OK; +} + +int network_emulation_update(const network_emultation_settings_t *s) { + assert(s); + + char command[512]; + if(s->delay.time && s->delay.jitter) { + sprintf(command, "tc qdisc change dev eth0 root netem limit %d delay %dms %dms %d%% distribution %s loss random %d%% corrupt %d%% %d%% duplicate %d%% %d%% reorder %d%% %d%% rate %dkbit > /dev/null", s->limit, s->delay.time, s->delay.jitter, s->delay.correlation, s->delay.distribution, s->loss, s->corruption.percentage, s->corruption.correlation, s->duplication.percentage, s->duplication.correlation, s->reordering.percentage, s->reordering.correlation, s->rate); + } + else { + sprintf(command, "tc qdisc change dev eth0 root netem limit %d delay %dms %dms %d%% loss random %d%% corrupt %d%% %d%% duplicate %d%% %d%% reorder %d%% %d%% rate %dkbit > /dev/null", s->limit, s->delay.time, s->delay.jitter, s->delay.correlation, s->loss, s->corruption.percentage, s->corruption.correlation, s->duplication.percentage, s->duplication.correlation, s->reordering.percentage, s->reordering.correlation, s->rate); + } + log_add_verbose(2, "chaning netem: %s\n", command); + int rc = system(command); + return rc; +} diff --git a/ntsimulator/ntsim-ng/utils/network_emulation.h b/ntsimulator/ntsim-ng/utils/network_emulation.h new file mode 100644 index 0000000..474dbec --- /dev/null +++ b/ntsimulator/ntsim-ng/utils/network_emulation.h @@ -0,0 +1,55 @@ +/************************************************************************* +* +* Copyright 2020 highstreet technologies GmbH and others +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +***************************************************************************/ + +#pragma once + +#include + +typedef struct { + uint16_t limit; + + struct { + uint16_t time; + uint16_t jitter; + uint16_t correlation; + char *distribution; + } delay; + + uint16_t loss; + + struct { + uint16_t percentage; + uint16_t correlation; + } corruption; + + struct { + uint16_t percentage; + uint16_t correlation; + } duplication; + + struct { + uint16_t percentage; + uint16_t correlation; + } reordering; + + uint16_t rate; +} network_emultation_settings_t; + +#define NETWORK_EMULATION_DEFAULT_LIMIT "1000" + +int network_emulation_init(void); +int network_emulation_update(const network_emultation_settings_t *s);