aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/ietf/ietf_nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/ietf/ietf_nat.c')
-rw-r--r--src/plugins/ietf/ietf_nat.c525
1 files changed, 0 insertions, 525 deletions
diff --git a/src/plugins/ietf/ietf_nat.c b/src/plugins/ietf/ietf_nat.c
deleted file mode 100644
index 86b700f..0000000
--- a/src/plugins/ietf/ietf_nat.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (c) 2019 PANTHEON.tech.
- *
- * 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.
- */
-
-#include <scvpp/comm.h>
-#include <scvpp/interface.h>
-#include <scvpp/nat.h>
-
-#include <sc_plugins.h>
-
-#include <assert.h>
-#include <string.h>
-#include <sysrepo.h>
-#include <sysrepo/xpath.h>
-#include <sysrepo/values.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/**
- * @brief Wrapper struct for VAPI address range payload.
- */
-struct address_range_t {
- nat44_add_del_address_range_t payload; //< VAPI payload for address range.
- bool last_ip_address_set; //< Variable last_ip_address in payload is set.
-};
-
-// Check input structure, set VAPI payload and call VAPI function to set
-// nat44 address range.
-static sr_error_t set_address_range(struct address_range_t *address_r)
-{
- sr_error_t rc = SR_ERR_OK;
-// char tmp_ip1[VPP_IP4_ADDRESS_STRING_LEN];
-// char tmp_ip2[VPP_IP4_ADDRESS_STRING_LEN];
-
- ARG_CHECK(SR_ERR_INVAL_ARG, address_r);
-
- //if end of IP range not provided, then range size = 1 with only first ip
- if (!address_r->last_ip_address_set) {
- memcpy(&address_r->payload.last_ip_address[0],
- &address_r->payload.first_ip_address[0],
- VPP_IP4_ADDRESS_LEN);
- }
-
- if (hardntohlu32(address_r->payload.last_ip_address) <
- hardntohlu32(address_r->payload.first_ip_address)) {
- SRP_LOG_ERR_MSG("End address less than start address");
- return SR_ERR_INVAL_ARG;
- }
-
-// strncpy(tmp_ip1, sc_ntoa(address_r->payload.first_ip_address),
-// VPP_IP4_ADDRESS_STRING_LEN);
-// strncpy(tmp_ip2, sc_ntoa(address_r->payload.last_ip_address),
-// VPP_IP4_ADDRESS_STRING_LEN);
-// SRP_LOG_DBG("Fist ip address: %s, last ip address: %s, twice_nat: %u,"
-// "is_add: %u", tmp_ip1, tmp_ip2, address_r->payload.twice_nat,
-// address_r->payload.is_add);
-
- int rv = nat44_add_del_addr_range(&address_r->payload);
- if (0 != rv) {
- SRP_LOG_ERR_MSG("Failed set address range.");
- rc = SR_ERR_OPERATION_FAILED;
- }
-
- return rc;
-}
-
-// parse leaf from this xpath:
-// /ietf-nat:nat/instances/instance[id='%s']/policy[id='%s']/external-ip-address-pool[pool-id='%s']/
-static int parse_instance_policy_external_ip_address_pool(
- const sr_val_t *val, struct address_range_t *address_range)
-{
- int rc;
- char tmp_str[VPP_IP4_PREFIX_STRING_LEN] = {0};
- uint8_t prefix = 0;
-
- ARG_CHECK2(SR_ERR_INVAL_ARG, val, address_range);
-
- if (sr_xpath_node_name_eq(val->xpath, "pool-id")) {
- SRP_LOG_WRN("%s not supported.", val->xpath);
- } else if(sr_xpath_node_name_eq(val->xpath, "external-ip-pool")) {
- rc = prefix2ip4(tmp_str, val->data.string_val, &prefix);
- if (0 != rc) {
- SRP_LOG_ERR_MSG("Error translate");
- return SR_ERR_INVAL_ARG;
- }
-
- rc = sc_aton(tmp_str, address_range->payload.first_ip_address,
- VPP_IP4_ADDRESS_LEN);
- if (0 != rc) {
- SRP_LOG_ERR_MSG("Failed convert string IP address to int.");
- return SR_ERR_INVAL_ARG;
- }
-
- if (prefix < VPP_IP4_HOST_PREFIX_LEN) {
- // External IP pool is represented as IPv4 prefix in YANG module.
- // VPP support range from first IPv4 address to last IPv4 address, not prefix.
- // In this concept the broadcast IPv4 address of this IPv4 prefix,
- // represent last IPv4 address for VPP
- get_last_ip_address(
- (sc_ipv4_addr*) &address_range->payload.last_ip_address[0],
- (sc_ipv4_addr*) &address_range->payload.first_ip_address[0],
- prefix);
- address_range->last_ip_address_set = true;
- }
- }
-
- return SR_ERR_OK;
-}
-
-// XPATH: /ietf-nat:nat/instances/instance[id='%s']/policy[id='%s']/external-ip-address-pool[pool-id='%s']/
-static int instances_instance_policy_external_ip_address_pool_cb(
- sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event,
- void *private_ctx)
-{
- UNUSED(private_ctx);
- sr_error_t rc = SR_ERR_OK;
- sr_change_iter_t *it = NULL;
- sr_change_oper_t oper;
- sr_val_t *old_val = NULL;
- sr_val_t *new_val = NULL;
- bool create = false;
- bool delete = false;
- struct address_range_t new_address_r = {0};
- struct address_range_t old_address_r = {0};
-
- ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath);
-
- SRP_LOG_INF("In %s", __FUNCTION__);
-
- new_address_r.payload.vrf_id = ~0;
- old_address_r.payload.vrf_id = ~0;
-
- SRP_LOG_DBG("'%s' modified, event=%d", xpath, event);
-
- if (event != SR_EV_APPLY) {
- return SR_ERR_OK;
- }
-
- if (sr_get_changes_iter(ds, (char *)xpath, &it) != SR_ERR_OK) {
- // in example he calls even on fale
- sr_free_change_iter(it);
- return SR_ERR_OK;
- }
-
- foreach_change (ds, it, oper, old_val, new_val) {
-
- SRP_LOG_DBG("A change detected in '%s', op=%d",
- new_val ? new_val->xpath : old_val->xpath, oper);
-
- switch (oper) {
- case SR_OP_CREATED:
- create = true;
- rc = parse_instance_policy_external_ip_address_pool(new_val,
- &new_address_r);
- break;
-
- case SR_OP_MODIFIED:
- delete = true;
- rc = parse_instance_policy_external_ip_address_pool(old_val,
- &old_address_r);
- if (SR_ERR_OK != rc) {
- break;
- }
-
- create = true;
- rc = parse_instance_policy_external_ip_address_pool(new_val,
- &new_address_r);
- break;
-
- case SR_OP_MOVED:
- break;
-
- case SR_OP_DELETED:
- delete = true;
- rc = parse_instance_policy_external_ip_address_pool(old_val,
- &old_address_r);
- break;
- }
-
- sr_free_val(old_val);
- sr_free_val(new_val);
-
- if (SR_ERR_OK != rc) {
- rc = SR_ERR_OPERATION_FAILED;
- goto error;
- }
- }
-
- if (delete) {
- old_address_r.payload.is_add = 0;
- rc = set_address_range(&old_address_r);
- if (SR_ERR_OK != rc) {
- goto error;
- }
- }
-
- if (create) {
- new_address_r.payload.is_add = 1;
- rc = set_address_range(&new_address_r);
- if (SR_ERR_OK != rc) {
- goto error;
- }
- }
-
-error:
- sr_free_change_iter(it);
- return rc;
-}
-
-enum mapping_type {
- STATIC,
- DYNAMIC_IMPLICIT,
- DYNAMIC_EXPLICIT,
- UNKNOWN,
-};
-
-/**
- * @brief Wrapper struct for VAPI static mapping payload.
- */
-struct static_mapping_t {
- enum mapping_type mtype; //< Mapping type
- bool local_ip_address_set; //< Variable are set in payload.
- bool external_ip_address_set; //< Variable are set in payload.
- bool protocol_set; //< Variable are set in payload.
- bool local_port_set; //< Variable are set in payload.
- bool external_port_set; //< Variable are set in payload.
- bool external_sw_if_index_set; //< Variable are set in payload.
- bool vrf_id_set; //< Variable are set in payload.
- bool twice_nat_set; //< Variable are set in payload.
- nat44_add_del_static_mapping_t payload; //< VAPI payload for static mapping
-};
-
-// Check input structure, set VAPI payload and call VAPI function to set
-// nat44 static mapping.
-static sr_error_t set_static_mapping(struct static_mapping_t *mapping)
-{
- int rc = 0;
-// char tmp_ip1[VPP_IP4_ADDRESS_STRING_LEN];
-// char tmp_ip2[VPP_IP4_ADDRESS_STRING_LEN];
-
- ARG_CHECK(SR_ERR_INVAL_ARG, mapping);
-
- if ((mapping->local_port_set != mapping->external_port_set) ||
- !mapping->local_ip_address_set || !mapping->external_ip_address_set) {
- SRP_LOG_ERR_MSG("NAT44 parameter missing.");
-
- return SR_ERR_VALIDATION_FAILED;
- }
-
- if (!mapping->local_port_set && !mapping->external_port_set) {
- //FIXME!!!!! Compile error
-// mapping->payload.flags = NAT_IS_ADDR_ONLY;
- } else {
- //FIXME!!!!! Compile error
-// mapping->payload.flags = NAT_IS_TWICE_NAT;
- if (!mapping->protocol_set) {
-
- SRP_LOG_ERR_MSG("NAT44 protocol missing.");
- return SR_ERR_VALIDATION_FAILED;
- }
- }
-
- mapping->payload.external_sw_if_index = ~0;
-
-// strncpy(tmp_ip1, sc_ntoa(mapping->payload.local_ip_address),
-// VPP_IP4_ADDRESS_STRING_LEN);
-// strncpy(tmp_ip2, sc_ntoa(mapping->payload.external_ip_address),
-// VPP_IP4_ADDRESS_STRING_LEN);
-// SRP_LOG_DBG("Local ip address: %s, external ip address: %s, addr_only: %u,"
-// " protocol: %u, local port: %u, external port: %u, twice_nat: %u,"
-// "is_add: %u", tmp_ip1, tmp_ip2, mapping->payload.addr_only,
-// mapping->payload.protocol, mapping->payload.local_port,
-// mapping->payload.external_port, mapping->payload.twice_nat,
-// mapping->payload.is_add);
-
- rc = nat44_add_del_static_mapping(&mapping->payload);
- if (0 != rc) {
- SRP_LOG_ERR_MSG("Failed set static mapping");
- return SR_ERR_OPERATION_FAILED;
- }
-
- return SR_ERR_OK;
-}
-
-// parse leaf from this xpath:
-// /ietf-nat:nat/instances/instance[id='%s']/mapping-table/mapping-entry[index='%s']/
-static int parse_instance_mapping_table_mapping_entry(
- const sr_val_t *val,
- struct static_mapping_t *mapping)
-{
- int rc;
- char tmp_str[VPP_IP4_PREFIX_STRING_LEN] = {0};
-
- ARG_CHECK2(SR_ERR_INVAL_ARG, val, mapping);
-
- sr_xpath_ctx_t state = {0};
-
- if(sr_xpath_node_name_eq(val->xpath, "type")) {
- if (!strncmp("static", val->data.string_val, strlen("static"))) {
- mapping->mtype = STATIC;
- } else if (!strncmp("dynamic-implicit", val->data.string_val,
- strlen("dynamic-implicit"))) {
- mapping->mtype = DYNAMIC_IMPLICIT;
- } else if (!strncmp("dynamic-explicit", val->data.string_val,
- strlen("dynamic-explicit"))) {
- mapping->mtype = DYNAMIC_EXPLICIT;
- }
- } else if(sr_xpath_node_name_eq(val->xpath, "transport-protocol")) {
- if (SR_UINT8_T != val->type) {
- SRP_LOG_ERR("Wrong transport-protocol, type, current type: %d.",
- val->type);
- return SR_ERR_INVAL_ARG;
- }
-
- mapping->payload.protocol = val->data.uint8_val;
- mapping->protocol_set = true;
- } else if(sr_xpath_node_name_eq(val->xpath, "internal-src-address")) {
- if (SR_STRING_T != val->type) {
- SRP_LOG_ERR("Wrong internal-src-address, type, current type: %d.",
- val->type);
- return SR_ERR_INVAL_ARG;
- }
-
- rc = prefix2ip4(tmp_str, val->data.string_val, NULL);
- if (0 != rc) {
- SRP_LOG_ERR_MSG("Error translate");
- return SR_ERR_INVAL_ARG;
- }
-
- rc = sc_aton(tmp_str, mapping->payload.local_ip_address,
- VPP_IP4_ADDRESS_LEN);
- if (0 != rc) {
- SRP_LOG_ERR_MSG("Failed convert string IP address to int.");
- return SR_ERR_INVAL_ARG;
- }
-
- mapping->local_ip_address_set = true;
- } else if(sr_xpath_node_name_eq(val->xpath, "external-src-address")) {
- if (SR_STRING_T != val->type) {
- SRP_LOG_ERR("Wrong external-src-address, type, current type: %d.",
- val->type);
- return SR_ERR_INVAL_ARG;
- }
-
- rc = prefix2ip4(tmp_str, val->data.string_val, NULL);
- if (0 != rc) {
- SRP_LOG_ERR_MSG("Error translate");
- return SR_ERR_INVAL_ARG;
- }
-
- rc = sc_aton(tmp_str, mapping->payload.external_ip_address,
- VPP_IP4_ADDRESS_LEN);
- if (0 != rc) {
- SRP_LOG_ERR_MSG("Failed convert string IP address to int.");
- return SR_ERR_INVAL_ARG;
- }
-
- mapping->external_ip_address_set = true;
- } else if (sr_xpath_node(val->xpath, "internal-src-port", &state)) {
- sr_xpath_recover(&state);
- if(sr_xpath_node_name_eq(val->xpath, "start-port-number")) {
- mapping->local_port_set = true;
- mapping->payload.local_port = val->data.uint16_val;
- }
- } else if (sr_xpath_node(val->xpath, "external-src-port", &state)) {
- sr_xpath_recover(&state);
- if(sr_xpath_node_name_eq(val->xpath, "start-port-number")) {
- mapping->external_port_set = true;
- mapping->payload.external_port = val->data.uint16_val;
- }
- }
-
- return SR_ERR_OK;
-}
-
-// XPATH: /ietf-nat:nat/instances/instance[id='%s']/mapping-table/mapping-entry[index='%s']/
-static int instances_instance_mapping_table_mapping_entry_cb(
- sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event,
- void *private_ctx)
-{
- UNUSED(private_ctx);
- sr_error_t rc = SR_ERR_OK;
- sr_change_iter_t *it = NULL;
- sr_change_oper_t oper;
- sr_val_t *old_val = NULL;
- sr_val_t *new_val = NULL;
- bool create = false;
- bool delete = false;
- struct static_mapping_t new_mapping = {0};
- struct static_mapping_t old_mapping = {0};
-
- ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath);
-
- SRP_LOG_INF("In %s", __FUNCTION__);
-
- new_mapping.mtype = UNKNOWN;
- old_mapping.mtype = UNKNOWN;
-
- SRP_LOG_DBG("'%s' modified, event=%d", xpath, event);
-
- if (event != SR_EV_APPLY) {
- return SR_ERR_OK;
- }
-
- if (sr_get_changes_iter(ds, (char *)xpath, &it) != SR_ERR_OK) {
- // in example he calls even on fale
- sr_free_change_iter(it);
- return SR_ERR_OK;
- }
-
- foreach_change (ds, it, oper, old_val, new_val) {
-
- SRP_LOG_DBG("A change detected in '%s', op=%d",
- new_val ? new_val->xpath : old_val->xpath, oper);
-
- switch (oper) {
- case SR_OP_CREATED:
- create = true;
- rc = parse_instance_mapping_table_mapping_entry(new_val,
- &new_mapping);
- break;
-
- case SR_OP_MODIFIED:
- delete = true;
- rc = parse_instance_mapping_table_mapping_entry(old_val,
- &old_mapping);
- if (SR_ERR_OK != rc) {
- break;
- }
-
- create = true;
- rc = parse_instance_mapping_table_mapping_entry(new_val,
- &new_mapping);
- break;
-
- case SR_OP_MOVED:
- break;
-
- case SR_OP_DELETED:
- delete = true;
- rc = parse_instance_mapping_table_mapping_entry(old_val,
- &old_mapping);
- break;
- }
-
- sr_free_val(old_val);
- sr_free_val(new_val);
-
- if (SR_ERR_OK != rc) {
- rc = SR_ERR_OPERATION_FAILED;
- goto error;
- }
- }
-
- if (delete) {
- old_mapping.payload.is_add = 0;
- if (STATIC == old_mapping.mtype) {
- rc = set_static_mapping(&old_mapping);
- if (SR_ERR_OK != rc) {
- goto error;
- }
- }
- }
-
- if (create) {
- new_mapping.payload.is_add = 1;
- if (STATIC == new_mapping.mtype) {
- rc = set_static_mapping(&new_mapping);
- if (SR_ERR_OK != rc) {
- goto error;
- }
- }
- }
-
-error:
- sr_free_change_iter(it);
- return rc;
-}
-
-int
-ietf_nat_init(sc_plugin_main_t *pm)
-{
- int rc = SR_ERR_OK;
- SRP_LOG_DBG_MSG("Initializing ietf-nat plugin.");
-
- rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance/policy/external-ip-address-pool",
- instances_instance_policy_external_ip_address_pool_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription);
- if (rc != SR_ERR_OK) {
- goto error;
- }
-
- rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance/mapping-table/mapping-entry",
- instances_instance_mapping_table_mapping_entry_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription);
- if (rc != SR_ERR_OK) {
- goto error;
- }
-
- SRP_LOG_DBG_MSG("ietf-nat plugin initialized successfully.");
- return SR_ERR_OK;
-
-error:
- SRP_LOG_ERR("Error by initialization of ietf-nat plugin. Error : %d", rc);
- return rc;
-}
-
-void
-ietf_nat_exit(__attribute__((unused)) sc_plugin_main_t *pm)
-{
-}
-
-SC_INIT_FUNCTION(ietf_nat_init);
-SC_EXIT_FUNCTION(ietf_nat_exit);