Add network emulation feature.
Issue-ID: SIM-78
Change-Id: I20a9ad92ed09316ab65b9ef74cdbd93b1082a1f6
Signed-off-by: Alex Stancu <alexandru.stancu@highstreet-technologies.com>
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 @@
"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 @@
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 @@
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 @@
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 <stdio.h>
#include <assert.h>
@@ -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 @@
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 @@
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_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 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
//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_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 @@
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 @@
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 @@
}
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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+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 <stdint.h>
+
+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);