| /* |
| * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials provided |
| * with the distribution. |
| * * Neither the name of The Linux Foundation nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <stdint.h> |
| #include <cstring> // for memcpy |
| #include "hton.h" // for htonl |
| #include "InterfaceAbstraction.h" |
| #include "Constants.h" |
| #include "Logger.h" |
| #include "TestsUtils.h" |
| #include "Filtering.h" |
| #include "RoutingDriverWrapper.h" |
| #include "IPAFilteringTable.h" |
| extern "C" { |
| #include "ipa_nat_drv.h" |
| } |
| |
| //IP offsets |
| #define IPV4_PROTOCOL_OFFSET (9) |
| #define IPV4_IP_CHECKSUM_OFFSET (10) |
| #define IPV4_SRC_ADDR_OFFSET (12) |
| #define IPV4_DST_ADDR_OFFSET (16) |
| |
| //TCP offsets |
| #define IPV4_SRC_PORT_OFFSET (20) |
| #define IPV4_DST_PORT_OFFSET (20+2) |
| #define IPV4_TCP_FLAGS_OFFSET (33) |
| #define IPV4_TCP_CHECKSUM_OFFSET (36) |
| |
| #define IPA_16BIT_ROUND_UP(val) \ |
| do { \ |
| if (val >> 16) { \ |
| val = (val & 0x0000FFFF);\ |
| val += 1;\ |
| } \ |
| } while(0) |
| |
| extern Logger g_Logger; |
| |
| class IpaNatBlockTestFixture : public TestBase |
| { |
| public: |
| |
| IpaNatBlockTestFixture() : |
| m_sendSize(BUFF_MAX_SIZE), |
| m_sendSize2(BUFF_MAX_SIZE), |
| m_sendSize3(BUFF_MAX_SIZE), |
| m_IpaIPType(IPA_IP_v4), |
| m_extHdrType(NONE) |
| { |
| memset(m_sendBuffer, 0, sizeof(m_sendBuffer)); // First input file / IP packet |
| memset(m_sendBuffer2, 0, sizeof(m_sendBuffer2)); // Second input file / IP packet |
| memset(m_sendBuffer3, 0, sizeof(m_sendBuffer3)); // Third input file (default) / IP packet |
| m_testSuiteName.push_back("Nat"); |
| } |
| |
| static int SetupKernelModule(bool en_status = 0, bool nat_suppress = 0) |
| { |
| int retval; |
| struct ipa_channel_config from_ipa_channels[3]; |
| struct test_ipa_ep_cfg from_ipa_cfg[3]; |
| struct ipa_channel_config to_ipa_channels[2]; |
| struct test_ipa_ep_cfg to_ipa_cfg[2]; |
| |
| struct ipa_test_config_header header = { 0 }; |
| struct ipa_channel_config *to_ipa_array[2]; |
| struct ipa_channel_config *from_ipa_array[3]; |
| |
| /* From ipa configurations - 3 pipes */ |
| memset(&from_ipa_cfg[0], 0, sizeof(from_ipa_cfg[0])); |
| prepare_channel_struct(&from_ipa_channels[0], |
| header.from_ipa_channels_num++, |
| IPA_CLIENT_TEST2_CONS, |
| (void *)&from_ipa_cfg[0], |
| sizeof(from_ipa_cfg[0]), |
| en_status); |
| from_ipa_array[0] = &from_ipa_channels[0]; |
| |
| memset(&from_ipa_cfg[1], 0, sizeof(from_ipa_cfg[1])); |
| prepare_channel_struct(&from_ipa_channels[1], |
| header.from_ipa_channels_num++, |
| IPA_CLIENT_TEST3_CONS, |
| (void *)&from_ipa_cfg[1], |
| sizeof(from_ipa_cfg[1]), |
| en_status); |
| from_ipa_array[1] = &from_ipa_channels[1]; |
| |
| memset(&from_ipa_cfg[2], 0, sizeof(from_ipa_cfg[2])); |
| prepare_channel_struct(&from_ipa_channels[2], |
| header.from_ipa_channels_num++, |
| IPA_CLIENT_TEST4_CONS, |
| (void *)&from_ipa_cfg[2], |
| sizeof(from_ipa_cfg[2]), |
| en_status); |
| from_ipa_array[2] = &from_ipa_channels[2]; |
| |
| /* To ipa configurations - 2 pipes */ |
| memset(&to_ipa_cfg[0], 0, sizeof(to_ipa_cfg[0])); |
| to_ipa_cfg[0].nat.nat_exc_suppress = nat_suppress; |
| prepare_channel_struct(&to_ipa_channels[0], |
| header.to_ipa_channels_num++, |
| IPA_CLIENT_TEST_PROD, |
| (void *)&to_ipa_cfg[0], |
| sizeof(to_ipa_cfg[0])); |
| to_ipa_array[0] = &to_ipa_channels[0]; |
| |
| /* header removal for Ethernet header + 8021Q header */ |
| memset(&to_ipa_cfg[1], 0, sizeof(to_ipa_cfg[1])); |
| to_ipa_cfg[1].nat.nat_exc_suppress = nat_suppress; |
| to_ipa_cfg[1].hdr.hdr_len = ETH8021Q_HEADER_LEN; |
| to_ipa_cfg[1].hdr.hdr_ofst_metadata_valid = 1; |
| to_ipa_cfg[1].hdr.hdr_ofst_metadata = |
| ETH8021Q_METADATA_OFFSET; |
| prepare_channel_struct(&to_ipa_channels[1], |
| header.to_ipa_channels_num++, |
| IPA_CLIENT_TEST2_PROD, |
| (void *)&to_ipa_cfg[1], |
| sizeof(to_ipa_cfg[1])); |
| to_ipa_array[1] = &to_ipa_channels[1]; |
| |
| prepare_header_struct(&header, from_ipa_array, to_ipa_array); |
| |
| retval = GenericConfigureScenario(&header); |
| |
| return retval; |
| } |
| |
| |
| bool Setup() |
| { |
| bool bRetVal = true; |
| |
| if (SetupKernelModule() != true) |
| return bRetVal; |
| |
| m_producer.Open(INTERFACE0_TO_IPA_DATA_PATH, INTERFACE0_FROM_IPA_DATA_PATH); |
| m_producer2.Open(INTERFACE4_TO_IPA_DATA_PATH, INTERFACE4_FROM_IPA_DATA_PATH); |
| |
| m_consumer.Open(INTERFACE1_TO_IPA_DATA_PATH, INTERFACE1_FROM_IPA_DATA_PATH); |
| m_consumer2.Open(INTERFACE2_TO_IPA_DATA_PATH, INTERFACE2_FROM_IPA_DATA_PATH); |
| m_defaultConsumer.Open(INTERFACE3_TO_IPA_DATA_PATH, INTERFACE3_FROM_IPA_DATA_PATH); |
| |
| if (!m_routing.DeviceNodeIsOpened()) |
| { |
| LOG_MSG_ERROR("Routing block is not ready for immediate commands!\n"); |
| return false; |
| } |
| |
| if (!m_filtering.DeviceNodeIsOpened()) |
| { |
| LOG_MSG_ERROR("Filtering block is not ready for immediate commands!\n"); |
| return false; |
| } |
| m_routing.Reset(IPA_IP_v4); // This will issue a Reset command to the Filtering as well |
| m_routing.Reset(IPA_IP_v6); // This will issue a Reset command to the Filtering as well |
| return true; |
| } // Setup() |
| |
| bool Setup(bool en_status = false, bool nat_suppress = false) |
| { |
| bool bRetVal = true; |
| |
| if (SetupKernelModule(en_status, nat_suppress) != true) |
| return bRetVal; |
| |
| m_producer.Open(INTERFACE0_TO_IPA_DATA_PATH, INTERFACE0_FROM_IPA_DATA_PATH); |
| |
| m_consumer.Open(INTERFACE1_TO_IPA_DATA_PATH, INTERFACE1_FROM_IPA_DATA_PATH); |
| m_consumer2.Open(INTERFACE2_TO_IPA_DATA_PATH, INTERFACE2_FROM_IPA_DATA_PATH); |
| m_defaultConsumer.Open(INTERFACE3_TO_IPA_DATA_PATH, INTERFACE3_FROM_IPA_DATA_PATH); |
| |
| if (!m_routing.DeviceNodeIsOpened()) |
| { |
| LOG_MSG_ERROR("Routing block is not ready for immediate commands!\n"); |
| return false; |
| } |
| |
| if (!m_filtering.DeviceNodeIsOpened()) |
| { |
| LOG_MSG_ERROR("Filtering block is not ready for immediate commands!\n"); |
| return false; |
| } |
| m_routing.Reset(IPA_IP_v4); // This will issue a Reset command to the Filtering as well |
| m_routing.Reset(IPA_IP_v6); // This will issue a Reset command to the Filtering as well |
| return true; |
| } // Setup() |
| |
| |
| bool Teardown() |
| { |
| ipa_nat_dump_ipv4_table(m_tbl_hdl); |
| ipa_nat_del_ipv4_tbl(m_tbl_hdl); |
| |
| m_producer.Close(); |
| m_producer2.Close(); |
| m_consumer.Close(); |
| m_consumer2.Close(); |
| m_defaultConsumer.Close(); |
| return true; |
| } // Teardown() |
| |
| virtual bool LoadFiles(enum ipa_ip_type ip) |
| { |
| string fileName; |
| |
| if (IPA_IP_v4 == ip) { |
| fileName = "Input/IPv4_1"; |
| } |
| else { |
| fileName = "Input/IPv6"; |
| } |
| |
| if (!LoadDefaultPacket(ip, m_extHdrType, m_sendBuffer, m_sendSize)) { |
| LOG_MSG_ERROR("Failed default Packet\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("Loaded %zu Bytes to Buffer 1\n", m_sendSize); |
| |
| if (!LoadDefaultPacket(ip, m_extHdrType, m_sendBuffer2, m_sendSize2)) { |
| LOG_MSG_ERROR("Failed default Packet\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("Loaded %zu Bytes to Buffer 2\n", m_sendSize2); |
| |
| if (!LoadDefaultPacket(ip, m_extHdrType, m_sendBuffer3, m_sendSize3)) { |
| LOG_MSG_ERROR("Failed default Packet\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("Loaded %zu Bytes to Buffer 3\n", m_sendSize3); |
| |
| return true; |
| } |
| |
| inline bool VerifyStatusReceived(size_t SendSize, size_t RecvSize) |
| { |
| size_t stts_size = sizeof(struct ipa3_hw_pkt_status); |
| |
| if (TestManager::GetInstance()->GetIPAHwType() >= IPA_HW_v5_0) { |
| stts_size = sizeof(struct ipa3_hw_pkt_status_hw_v5_0); |
| } |
| |
| if ((RecvSize <= SendSize) || |
| ((RecvSize - SendSize) != stts_size)) { |
| LOG_MSG_ERROR("received buffer size does not match! sent:receive [%zu]:[%zu]\n", SendSize, RecvSize); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| inline bool IsCacheHit(size_t SendSize, size_t RecvSize, void *Buff) |
| { |
| struct ipa3_hw_pkt_status *pStatus = (struct ipa3_hw_pkt_status *)Buff; |
| |
| if (VerifyStatusReceived(SendSize, RecvSize) == false) { |
| return false; |
| } |
| |
| if ((bool)pStatus->route_hash) { |
| LOG_MSG_DEBUG("cache hit!! \n"); |
| return true; |
| } |
| |
| LOG_MSG_ERROR("cache miss!! \n"); |
| return false; |
| |
| } |
| |
| inline bool IsCacheHit_v5_0(size_t SendSize, size_t RecvSize, void *Buff) |
| { |
| struct ipa3_hw_pkt_status_hw_v5_0 *pStatus = (struct ipa3_hw_pkt_status_hw_v5_0 *)Buff; |
| |
| if (VerifyStatusReceived(SendSize, RecvSize) == false) { |
| return false; |
| } |
| |
| if ((bool)pStatus->route_hash) { |
| LOG_MSG_DEBUG("cache hit!! \n"); |
| return true; |
| } |
| |
| LOG_MSG_ERROR("cache miss!! \n"); |
| return false; |
| |
| } |
| |
| inline bool IsCacheMiss(size_t SendSize, size_t RecvSize, void *Buff) |
| { |
| struct ipa3_hw_pkt_status *pStatus = (struct ipa3_hw_pkt_status *)Buff; |
| |
| if (VerifyStatusReceived(SendSize, RecvSize) == false) { |
| return false; |
| } |
| |
| if (!((bool)pStatus->route_hash)) { |
| LOG_MSG_DEBUG("cache miss!! \n"); |
| return true; |
| } |
| |
| LOG_MSG_ERROR("cache hit!! \n"); |
| return false; |
| } |
| |
| inline bool IsCacheMiss_v5_0(size_t SendSize, size_t RecvSize, void *Buff) |
| { |
| struct ipa3_hw_pkt_status_hw_v5_0 *pStatus = (struct ipa3_hw_pkt_status_hw_v5_0 *)Buff; |
| |
| if (VerifyStatusReceived(SendSize, RecvSize) == false) { |
| return false; |
| } |
| |
| if (!((bool)pStatus->route_hash)) { |
| LOG_MSG_DEBUG("cache miss!! \n"); |
| return true; |
| } |
| |
| LOG_MSG_ERROR("cache hit!! \n"); |
| return false; |
| } |
| |
| bool CompareResultVsGoldenNat(Byte *goldenBuffer, unsigned int goldenSize, |
| Byte *receivedBuffer, unsigned int receivedSize, int private_ip, int public_ip, |
| int private_port, int public_port, bool src_nat, int IPv4_offset = 0, bool with_status = false) |
| { |
| bool result; |
| uint32_t address; |
| uint16_t port; |
| uint32_t val; |
| uint16_t ip_checksum_diff, tcp_checksum_diff; |
| uint32_t ip_checksum, tcp_checksum; |
| int recv_offset = 0; |
| size_t stts_size = sizeof(struct ipa3_hw_pkt_status); |
| |
| if (TestManager::GetInstance()->GetIPAHwType() >= IPA_HW_v5_0) { |
| stts_size = sizeof(struct ipa3_hw_pkt_status_hw_v5_0); |
| } |
| |
| if (with_status) |
| recv_offset += stts_size; |
| |
| ip_checksum_diff = calc_ip_cksum_diff(public_ip, private_ip); |
| tcp_checksum_diff = calc_tcp_udp_cksum_diff(public_ip, public_port, private_ip, private_port); |
| |
| //calculate new ip checksum, old checksum + 1's compliment of checksum diff |
| ip_checksum = *((uint16_t *)&goldenBuffer[IPV4_IP_CHECKSUM_OFFSET + IPv4_offset]); |
| ip_checksum = ntohs(ip_checksum); |
| |
| if(src_nat) |
| ip_checksum += (uint16_t)(~ip_checksum_diff); |
| else |
| ip_checksum += (uint16_t)ip_checksum_diff; |
| |
| IPA_16BIT_ROUND_UP(ip_checksum); |
| |
| //return to network format |
| ip_checksum = htons(ip_checksum); |
| |
| //calculate new tcp checksum, old checksum + 1's compliment of checksum diff |
| tcp_checksum = *((uint16_t *)&goldenBuffer[IPV4_TCP_CHECKSUM_OFFSET + IPv4_offset]); |
| tcp_checksum = ntohs(tcp_checksum); |
| |
| if(src_nat) |
| tcp_checksum += (uint16_t)(~tcp_checksum_diff); |
| else |
| tcp_checksum += (uint16_t)tcp_checksum_diff; |
| |
| IPA_16BIT_ROUND_UP(tcp_checksum); |
| |
| //return to network format |
| tcp_checksum = htons(tcp_checksum); |
| |
| if ((receivedSize - recv_offset) != goldenSize) { |
| g_Logger.AddMessage(LOG_VERBOSE, "%s Buffers sizes are different.\n", __FUNCTION__); |
| return false; |
| } |
| |
| Byte *tmp_buff = new Byte[goldenSize]; |
| |
| memcpy(tmp_buff, goldenBuffer, goldenSize); |
| |
| if (src_nat) { |
| address = htonl(public_ip); |
| port = htons(public_port); |
| |
| memcpy(&tmp_buff[IPV4_SRC_ADDR_OFFSET + IPv4_offset], &address, sizeof(address)); |
| memcpy(&tmp_buff[IPV4_SRC_PORT_OFFSET + IPv4_offset], &port, sizeof(port)); |
| |
| val = (*(uint32_t*)(&receivedBuffer[IPV4_SRC_ADDR_OFFSET + IPv4_offset + recv_offset])); |
| if (address != val) |
| LOG_MSG_ERROR("received src ip 0x%X != 0x%X\n", val, address); |
| |
| val = (*(uint16_t*)(&receivedBuffer[IPV4_SRC_PORT_OFFSET + IPv4_offset + recv_offset])); |
| if (port != val) |
| LOG_MSG_ERROR("received src port %d != %d\n", val, port); |
| } |
| else { |
| address = htonl(private_ip); |
| port = htons(private_port); |
| |
| memcpy(&tmp_buff[IPV4_DST_ADDR_OFFSET + IPv4_offset], &address, sizeof(address)); |
| memcpy(&tmp_buff[IPV4_DST_PORT_OFFSET + IPv4_offset], &port, sizeof(port)); |
| |
| val = (*(uint32_t*)(&receivedBuffer[IPV4_DST_ADDR_OFFSET + IPv4_offset + +recv_offset])); |
| if (address != val) |
| LOG_MSG_ERROR("received dst ip 0x%X != 0x%X\n", val, address); |
| val = (*(uint16_t*)(&receivedBuffer[IPV4_DST_PORT_OFFSET + IPv4_offset + recv_offset])); |
| if (port != val) |
| LOG_MSG_ERROR("received dst port %d != %d\n", val, port); |
| } |
| |
| memcpy(&tmp_buff[IPV4_IP_CHECKSUM_OFFSET + IPv4_offset], &ip_checksum, sizeof(uint16_t)); |
| val = (*(uint16_t*)(&receivedBuffer[IPV4_IP_CHECKSUM_OFFSET + IPv4_offset + recv_offset])); |
| if (ip_checksum != val) |
| LOG_MSG_ERROR("received checksum %d != %d\n", val, ip_checksum); |
| |
| memcpy(&tmp_buff[IPV4_TCP_CHECKSUM_OFFSET + IPv4_offset], &tcp_checksum, sizeof(uint16_t)); |
| val = (*(uint16_t*)(&receivedBuffer[IPV4_TCP_CHECKSUM_OFFSET + IPv4_offset + recv_offset])); |
| if (tcp_checksum != val) |
| LOG_MSG_ERROR("received checksum %d != %d\n", val, tcp_checksum); |
| |
| size_t j; |
| char tmpBuffer[512] = { 0 }; |
| |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&tmpBuffer[3 * j], sizeof(tmpBuffer) - (3 * j + 1), " %02X", tmp_buff[j]); |
| LOG_MSG_STACK("expected packet should be (%zu)\n%s\n", receivedSize, tmpBuffer); |
| |
| result = !memcmp((void*)tmp_buff, (void*)(receivedBuffer + recv_offset), goldenSize); |
| if (!result) |
| LOG_MSG_ERROR("buffers comparison failed!!\n"); |
| |
| delete[] tmp_buff; |
| |
| return result; |
| } |
| |
| bool CreateMetdataRoutingRule(const char * bypass0) |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| struct ipa_ioc_add_rt_rule *rt_rule0 = NULL; |
| struct ipa_rt_rule_add *rt_rule_entry; |
| |
| rt_rule0 = (struct ipa_ioc_add_rt_rule *) |
| calloc(1, |
| sizeof(struct ipa_ioc_add_rt_rule) + |
| 1 * sizeof(struct ipa_rt_rule_add) |
| ); |
| if (!rt_rule0) { |
| LOG_MSG_ERROR("calloc failed to allocate rt_rule0\n"); |
| return false; |
| } |
| |
| rt_rule0->num_rules = 1; |
| rt_rule0->ip = IPA_IP_v4; |
| rt_rule0->commit = true; |
| strlcpy(rt_rule0->rt_tbl_name, bypass0, sizeof(rt_rule0->rt_tbl_name)); |
| |
| rt_rule_entry = &rt_rule0->rules[0]; |
| rt_rule_entry->at_rear = 0; |
| rt_rule_entry->rule.dst = IPA_CLIENT_TEST2_CONS; |
| rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_META_DATA; |
| rt_rule_entry->rule.attrib.meta_data = m_metadata; |
| rt_rule_entry->rule.attrib.meta_data_mask = 0xFFFFFFFF;// Filter exact metadata value |
| if (false == m_routing.AddRoutingRule(rt_rule0)) |
| { |
| LOG_MSG_ERROR("Routing rule addition(rt_rule0) failed!\n"); |
| Free(rt_rule0); |
| return false; |
| } |
| |
| Free(rt_rule0); |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| } |
| |
| bool CreateHashableRoutingRules(const char * bypass0) |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| struct ipa_ioc_add_rt_rule *rt_rule0 = 0, *rt_rule1 = 0; |
| struct ipa_rt_rule_add *rt_rule_entry; |
| |
| rt_rule0 = (struct ipa_ioc_add_rt_rule *) |
| calloc(1, |
| sizeof(struct ipa_ioc_add_rt_rule) + |
| 2 * sizeof(struct ipa_rt_rule_add) |
| ); |
| if (!rt_rule0) { |
| LOG_MSG_ERROR("calloc failed to allocate rt_rule0\n"); |
| return false; |
| } |
| |
| rt_rule0->num_rules = 2; |
| rt_rule0->ip = IPA_IP_v4; |
| rt_rule0->commit = true; |
| strlcpy(rt_rule0->rt_tbl_name, bypass0, sizeof(rt_rule0->rt_tbl_name)); |
| |
| rt_rule_entry = &rt_rule0->rules[0]; |
| rt_rule_entry->at_rear = 0; |
| rt_rule_entry->rule.dst = IPA_CLIENT_TEST2_CONS; |
| rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr = m_private_ip; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;// Exact match |
| rt_rule_entry->rule.hashable = 1; |
| |
| rt_rule_entry = &rt_rule0->rules[1]; |
| rt_rule_entry->at_rear = 1; |
| rt_rule_entry->rule.dst = IPA_CLIENT_TEST3_CONS; |
| rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr = m_private_ip2; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;// Exact match |
| rt_rule_entry->rule.hashable = 1; |
| if (false == m_routing.AddRoutingRule(rt_rule0)) |
| { |
| LOG_MSG_ERROR("Routing rule addition(rt_rule0) failed!\n"); |
| Free(rt_rule1); |
| Free(rt_rule0); |
| return false; |
| } |
| |
| Free(rt_rule0); |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| } |
| |
| // This function creates three IPv4 bypass routing entries and commits them. |
| bool CreateThreeIPv4BypassRoutingTables(const char * bypass0, const char * bypass1, const char * bypass2) |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| struct ipa_ioc_add_rt_rule *rt_rule0 = 0, *rt_rule1 = 0, *rt_rule2 = 0; |
| struct ipa_rt_rule_add *rt_rule_entry; |
| |
| rt_rule0 = (struct ipa_ioc_add_rt_rule *) |
| calloc(1, |
| sizeof(struct ipa_ioc_add_rt_rule) + |
| 1 * sizeof(struct ipa_rt_rule_add) |
| ); |
| if (!rt_rule0) { |
| LOG_MSG_ERROR("calloc failed to allocate rt_rule0\n"); |
| return false; |
| } |
| rt_rule1 = (struct ipa_ioc_add_rt_rule *) |
| calloc(1, |
| sizeof(struct ipa_ioc_add_rt_rule) + |
| 1 * sizeof(struct ipa_rt_rule_add) |
| ); |
| if (!rt_rule1) { |
| LOG_MSG_ERROR("calloc failed to allocate rt_rule1\n"); |
| Free(rt_rule0); |
| return false; |
| } |
| rt_rule2 = (struct ipa_ioc_add_rt_rule *) |
| calloc(1, |
| sizeof(struct ipa_ioc_add_rt_rule) + |
| 1 * sizeof(struct ipa_rt_rule_add) |
| ); |
| if (!rt_rule2) { |
| LOG_MSG_ERROR("calloc failed to allocate rt_rule2\n"); |
| Free(rt_rule0); |
| Free(rt_rule1); |
| return false; |
| } |
| |
| rt_rule0->num_rules = 1; |
| rt_rule0->ip = IPA_IP_v4; |
| rt_rule0->commit = true; |
| strlcpy(rt_rule0->rt_tbl_name, bypass0, sizeof(rt_rule0->rt_tbl_name)); |
| |
| rt_rule_entry = &rt_rule0->rules[0]; |
| rt_rule_entry->at_rear = 0; |
| rt_rule_entry->rule.dst = IPA_CLIENT_TEST2_CONS; |
| rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr = 0xaabbccdd; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0x00000000;// All Packets will get a "Hit" |
| if (false == m_routing.AddRoutingRule(rt_rule0)) |
| { |
| LOG_MSG_ERROR("Routing rule addition(rt_rule0) failed!\n"); |
| Free(rt_rule2); |
| Free(rt_rule1); |
| Free(rt_rule0); |
| return false; |
| } |
| |
| |
| rt_rule1->num_rules = 1; |
| rt_rule1->ip = IPA_IP_v4; |
| rt_rule1->commit = true; |
| strlcpy(rt_rule1->rt_tbl_name, bypass1, sizeof(rt_rule1->rt_tbl_name)); |
| rt_rule_entry = &rt_rule1->rules[0]; |
| rt_rule_entry->at_rear = 0; |
| rt_rule_entry->rule.dst = IPA_CLIENT_TEST3_CONS; |
| rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr = 0xaabbccdd; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0x00000000;// All Packets will get a "Hit" |
| if (false == m_routing.AddRoutingRule(rt_rule1)) |
| { |
| LOG_MSG_ERROR("Routing rule addition(rt_rule1) failed!\n"); |
| Free(rt_rule2); |
| Free(rt_rule1); |
| Free(rt_rule0); |
| return false; |
| } |
| |
| |
| rt_rule2->num_rules = 1; |
| rt_rule2->ip = IPA_IP_v4; |
| rt_rule2->commit = true; |
| strlcpy(rt_rule2->rt_tbl_name, bypass2, sizeof(rt_rule2->rt_tbl_name)); |
| rt_rule_entry = &rt_rule2->rules[0]; |
| rt_rule_entry->at_rear = 0; |
| rt_rule_entry->rule.dst = IPA_CLIENT_TEST4_CONS; |
| rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr = 0xaabbccdd; |
| rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0x00000000;// All Packets will get a "Hit" |
| if (false == m_routing.AddRoutingRule(rt_rule2)) |
| { |
| LOG_MSG_ERROR("Routing rule addition(rt_rule2) failed!\n"); |
| Free(rt_rule2); |
| Free(rt_rule1); |
| Free(rt_rule0); |
| return false; |
| } |
| |
| |
| Free(rt_rule2); |
| Free(rt_rule1); |
| Free(rt_rule0); |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| } |
| |
| void Load8021QPacket() |
| { |
| m_sendSize = sizeof(m_sendBuffer); |
| LoadDefault802_1Q(IPA_IP_v4, m_sendBuffer, m_sendSize); |
| } |
| |
| virtual bool ModifyPackets() = 0; |
| virtual bool AddRules() = 0; |
| virtual bool SendPackets() = 0; |
| virtual bool ReceivePacketsAndCompare() = 0; |
| |
| bool Run() |
| { |
| bool res = false; |
| bool isSuccess = false; |
| |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| // Add the relevant filtering rules |
| res = AddRules(); |
| if (false == res) { |
| LOG_MSG_ERROR("Failed adding filtering rules.\n"); |
| return false; |
| } |
| |
| // Load input data (IP packet) from file |
| res = LoadFiles(m_IpaIPType); |
| if (false == res) { |
| LOG_MSG_ERROR("Failed loading files.\n"); |
| return false; |
| } |
| |
| res = ModifyPackets(); |
| if (false == res) { |
| LOG_MSG_ERROR("Failed to modify packets.\n"); |
| return false; |
| } |
| |
| res = SendPackets(); |
| if (res == false) { |
| LOG_MSG_ERROR("failed to send packets\n"); |
| return false; |
| } |
| // Receive packets from the channels and compare results |
| isSuccess = ReceivePacketsAndCompare(); |
| |
| LOG_MSG_DEBUG("Returning %d\n", isSuccess); |
| |
| return isSuccess; |
| } // Run() |
| |
| /** |
| * calc_ip_cksum_diff() - Calculate the source nat |
| * IP checksum diff |
| * @pub_ip_addr: [in] public ip address |
| * @priv_ip_addr: [in] Private ip address |
| * |
| * source nat ip checksum different is calculated as |
| * public_ip_addr - private_ip_addr |
| * Here we are using 1's complement to represent -negative number. |
| * So take 1's complement of private ip addr and add it |
| * to public ip addr. |
| * |
| * Returns: >0 ip checksum diff |
| */ |
| uint16_t calc_ip_cksum_diff(uint32_t pub_ip_addr, |
| uint32_t priv_ip_addr) |
| { |
| uint16_t ret; |
| uint32_t cksum = 0; |
| |
| /* Add LSB(2 bytes) of public ip address to cksum */ |
| cksum += (pub_ip_addr & 0xFFFF); |
| |
| /* Add MSB(2 bytes) of public ip address to cksum |
| and check for carry forward(CF), if any add it |
| */ |
| cksum += (pub_ip_addr >> 16); |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* Calculate the 1's complement of private ip address */ |
| priv_ip_addr = (~priv_ip_addr); |
| |
| /* Add LSB(2 bytes) of private ip address to cksum |
| and check for carry forward(CF), if any add it |
| */ |
| cksum += (priv_ip_addr & 0xFFFF); |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* Add MSB(2 bytes) of private ip address to cksum |
| and check for carry forward(CF), if any add it |
| */ |
| cksum += (priv_ip_addr >> 16); |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* Return the LSB(2 bytes) of checksum */ |
| ret = (uint16_t)cksum; |
| return ret; |
| } |
| |
| /** |
| * calc_tcp_udp_cksum() - Calculate the source nat |
| * TCP/UDP checksum diff |
| * @pub_ip_addr: [in] public ip address |
| * @pub_port: [in] public tcp/udp port |
| * @priv_ip_addr: [in] Private ip address |
| * @priv_port: [in] Private tcp/udp prot |
| * |
| * source nat tcp/udp checksum is calculated as |
| * (pub_ip_addr + pub_port) - (priv_ip_addr + priv_port) |
| * Here we are using 1's complement to represent -ve number. |
| * So take 1's complement of prviate ip addr &private port |
| * and add it public ip addr & public port. |
| * |
| * Returns: >0 tcp/udp checksum diff |
| */ |
| uint16_t calc_tcp_udp_cksum_diff(uint32_t pub_ip_addr, |
| uint16_t pub_port, |
| uint32_t priv_ip_addr, |
| uint16_t priv_port) |
| { |
| uint16_t ret = 0; |
| uint32_t cksum = 0; |
| |
| /* Add LSB(2 bytes) of public ip address to cksum */ |
| cksum += (pub_ip_addr & 0xFFFF); |
| |
| /* Add MSB(2 bytes) of public ip address to cksum |
| and check for carry forward(CF), if any add it |
| */ |
| cksum += (pub_ip_addr >> 16); |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* Add public port to cksum and |
| check for carry forward(CF), if any add it */ |
| cksum += pub_port; |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* Calculate the 1's complement of private ip address */ |
| priv_ip_addr = (~priv_ip_addr); |
| |
| /* Add LSB(2 bytes) of private ip address to cksum |
| and check for carry forward(CF), if any add it |
| */ |
| cksum += (priv_ip_addr & 0xFFFF); |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* Add MSB(2 bytes) of private ip address to cksum |
| and check for carry forward(CF), if any add |
| */ |
| cksum += (priv_ip_addr >> 16); |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* Calculate the 1's complement of private port */ |
| priv_port = (~priv_port); |
| |
| /* Add public port to cksum and |
| check for carry forward(CF), if any add it */ |
| cksum += priv_port; |
| IPA_16BIT_ROUND_UP(cksum); |
| |
| /* return the LSB(2 bytes) of checksum */ |
| ret = (uint16_t)cksum; |
| return ret; |
| } |
| |
| ~IpaNatBlockTestFixture() |
| { |
| m_sendSize = 0; |
| m_sendSize2 = 0; |
| m_sendSize3 = 0; |
| } |
| |
| static Filtering m_filtering; |
| static RoutingDriverWrapper m_routing; |
| InterfaceAbstraction m_producer; |
| InterfaceAbstraction m_producer2; |
| InterfaceAbstraction m_consumer; |
| InterfaceAbstraction m_consumer2; |
| InterfaceAbstraction m_defaultConsumer; |
| |
| static const size_t BUFF_MAX_SIZE = 1024; |
| |
| Byte m_sendBuffer[BUFF_MAX_SIZE]; // First input file / IP packet |
| Byte m_sendBuffer2[BUFF_MAX_SIZE]; // Second input file / IP packet |
| Byte m_sendBuffer3[BUFF_MAX_SIZE]; // Third input file (default) / IP packet |
| size_t m_sendSize; |
| size_t m_sendSize2; |
| size_t m_sendSize3; |
| enum ipa_ip_type m_IpaIPType; |
| enum ipv6_ext_hdr_type m_extHdrType; |
| uint32_t m_tbl_hdl; |
| uint32_t m_nat_rule_hdl1; |
| uint32_t m_public_ip; |
| uint32_t m_public_ip2; |
| uint32_t m_private_ip; |
| uint32_t m_private_ip2; |
| uint32_t m_target_ip; |
| uint16_t m_public_port; |
| uint16_t m_public_port2; |
| uint16_t m_private_port; |
| uint16_t m_private_port2; |
| uint16_t m_target_port; |
| uint32_t m_metadata; |
| private: |
| }; |
| |
| RoutingDriverWrapper IpaNatBlockTestFixture::m_routing; |
| Filtering IpaNatBlockTestFixture::m_filtering; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test001: Single PDN src NAT test */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest001 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest001() |
| { |
| m_name = "IpaNatBlockTest001"; |
| m_description = |
| "NAT block test 001 - single PDN src NAT test\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to src NAT \ |
| All DST_IP == (193.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit one NAT rule:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 1); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00FFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_target_ip; // Filter DST_IP == 193.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| |
| ret = ipa_nat_add_ipv4_tbl(m_public_ip, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_DEBUG("failed creating NAT table\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| m_public_ip); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("failed adding NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = htonl(m_target_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET],&flags , sizeof(flags)); |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test002: Single PDN dst NAT test */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest002 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest002() |
| { |
| m_name = "IpaNatBlockTest002"; |
| m_description = |
| "NAT block test 002 - single PDN dst NAT test\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block (public IP filtering) \ |
| 3. generate and commit one NAT rule:\ |
| public ip 192.23.22.1 --> private ip 194.23.22.1 "; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 3); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00FFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip; // Filter DST_IP == 192.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| uint32_t pub_ip_add = m_public_ip; |
| |
| ret = ipa_nat_add_ipv4_tbl(pub_ip_add, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| pub_ip_add); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = htonl(m_public_ip);//192.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_public_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_target_ip);/* 193.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| false)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test003: Multi PDN src NAT test */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest003 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest003() |
| { |
| m_name = "IpaNatBlockTest003"; |
| m_description = |
| "NAT block test 003 - Multi PDN src NAT test\ |
| 1. Generate and commit three routing tables (two are used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit two filtering rule: (DST & Mask Match). \ |
| - action go to src NAT \ |
| All SRC_IP == (194.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| All SRC_IP == (197.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit two NAT rules:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1 \ |
| private ip 197.23.22.1 --> public ip 195.23.22.1"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_private_ip2 = 0xC5171601; /* 197.23.22.1 */ |
| m_private_port2 = 5679; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_public_ip2 = 0xC3171601; /* "195.23.22.1" */ |
| m_public_port2 = 9051; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| m_minIPAHwType = IPA_HW_v4_0; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0, routing_table1; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| routing_table1.ip = IPA_IP_v4; |
| strlcpy(routing_table1.name, bypass1, sizeof(routing_table1.name)); |
| if (!m_routing.GetRoutingTable(&routing_table1)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table1=0x%p) Failed.\n", &routing_table1); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass1, routing_table1.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 2); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.src_addr = m_private_ip; // Filter SRC_IP == 194.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| |
| // Configuring Filtering Rule No.1 |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table1.hdl; //put here the handle corresponding to Routing Rule 2 |
| flt_rule_entry.rule.attrib.u.v4.src_addr = m_private_ip2; // Filter SRC_IP == 197.23.22.1 |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| LOG_MSG_DEBUG("flt rule hdl1=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(1)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(1)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| uint32_t pub_ip_add = m_public_ip; |
| ipa_nat_pdn_entry pdn_info; |
| |
| // first create the NAT table |
| ret = ipa_nat_add_ipv4_tbl(pub_ip_add, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| pub_ip_add); |
| |
| // modify the PDN entries that will be pointed by the NAT rules |
| pdn_info.public_ip = m_public_ip; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 0, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 0 \n"); |
| return false; |
| } |
| |
| pdn_info.public_ip = m_public_ip2; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 1, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 1 \n"); |
| return false; |
| } |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| ipv4_rule.private_ip = m_private_ip2; |
| ipv4_rule.private_port = m_private_port2; |
| ipv4_rule.public_port = m_public_port2; |
| ipv4_rule.pdn_index = 1; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 1\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule 2 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| //first packet private ip 194.23.22.1 --> public ip 192.23.22.1 |
| address = htonl(m_target_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| // second packet private ip 197.23.22.1 --> public ip 195.23.22.1 |
| address = htonl(m_target_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer2[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer2[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip2);/* 197.23.22.1 */ |
| memcpy(&m_sendBuffer2[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port2); |
| memcpy(&m_sendBuffer2[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer2[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| LOG_MSG_DEBUG("sending first packet\n"); |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| // Send second packet |
| LOG_MSG_DEBUG("sending second packet\n"); |
| isSuccess = m_producer.SendData(m_sendBuffer2, m_sendSize2); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully two packets\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| size_t receivedSize2 = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| Byte *rxBuff2 = new Byte[0x400]; |
| |
| if (rxBuff1 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| if (rxBuff2) |
| delete[] rxBuff2; |
| return false; |
| } |
| |
| if (rxBuff2 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| delete[] rxBuff1; |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| receivedSize2 = m_consumer2.ReceiveData(rxBuff2, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize2, m_consumer2.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| char recievedBuffer2[256] = { 0 }; |
| char SentBuffer2[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| isSuccess &= CompareResultVsGoldenNat( |
| m_sendBuffer2, m_sendSize2, |
| rxBuff2, receivedSize2, |
| m_private_ip2, m_public_ip2, |
| m_private_port2, m_public_port2, |
| true); |
| |
| for (j = 0; j < m_sendSize2; j++) |
| snprintf(&SentBuffer2[3 * j], sizeof(SentBuffer2) - (3 * j + 1), " %02X", m_sendBuffer2[j]); |
| for (j = 0; j < receivedSize2; j++) |
| snprintf(&recievedBuffer2[3 * j], sizeof(recievedBuffer2) - (3 * j + 1), " %02X", rxBuff2[j]); |
| LOG_MSG_STACK("sent Value2 (%zu)\n%s\n, Received Value2(%zu)\n%s\n", m_sendSize2, SentBuffer2, receivedSize2, recievedBuffer2); |
| |
| delete[] rxBuff2; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test004: Multi PDN dst NAT test */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest004 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest004() |
| { |
| m_name = "IpaNatBlockTest004"; |
| m_description = |
| "NAT block test 004 - Multi PDN dst NAT test\ |
| 1. Generate and commit three routing tables (two are used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit two filtering rule: (DST & Mask Match). \ |
| - action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| All DST_IP == (195.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit two NAT rules:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1 \ |
| private ip 197.23.22.1 --> public ip 195.23.22.1"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_private_ip2 = 0xC5171601; /* 197.23.22.1 */ |
| m_private_port2 = 5679; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_public_ip2 = 0xC3171601; /* "195.23.22.1" */ |
| m_public_port2 = 9051; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| m_minIPAHwType = IPA_HW_v4_0; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0, routing_table1; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| routing_table1.ip = IPA_IP_v4; |
| strlcpy(routing_table1.name, bypass1, sizeof(routing_table1.name)); |
| if (!m_routing.GetRoutingTable(&routing_table1)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table1=0x%p) Failed.\n", &routing_table1); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass1, routing_table1.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 2); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip; // Filter DST_IP == 192.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| |
| // Configuring Filtering Rule No.1 |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table1.hdl; //put here the handle corresponding to Routing Rule 2 |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip2; // Filter DST_IP == 195.23.22.1 |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| LOG_MSG_DEBUG("flt rule hdl1=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(1)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(1)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| uint32_t pub_ip_add = m_public_ip; |
| ipa_nat_pdn_entry pdn_info; |
| |
| // first create the NAT table |
| ret = ipa_nat_add_ipv4_tbl(pub_ip_add, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| pub_ip_add); |
| |
| // modify the PDN entries that will be pointed by the NAT rules |
| pdn_info.public_ip = m_public_ip; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 0,&pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 0 \n"); |
| return false; |
| } |
| |
| pdn_info.public_ip = m_public_ip2; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 1, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 1 \n"); |
| return false; |
| } |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| ipv4_rule.private_ip = m_private_ip2; |
| ipv4_rule.private_port = m_private_port2; |
| ipv4_rule.public_port = m_public_port2; |
| ipv4_rule.pdn_index = 1; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule 2 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| //first packet private ip public ip 192.23.22.1 --> 194.23.22.1 |
| address = htonl(m_public_ip);//192.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_public_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_target_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| // second packet public ip 195.23.22.1--> private ip 197.23.22.1 |
| address = htonl(m_public_ip2);//193.23.22.1 |
| memcpy(&m_sendBuffer2[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_public_port2); |
| memcpy(&m_sendBuffer2[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_target_ip);/* 197.23.22.1 */ |
| memcpy(&m_sendBuffer2[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer2[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer2[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| // Send second packet |
| isSuccess = m_producer.SendData(m_sendBuffer2, m_sendSize2); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully two packets\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| size_t receivedSize2 = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| Byte *rxBuff2 = new Byte[0x400]; |
| |
| if (rxBuff1 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| if (rxBuff2) |
| delete[] rxBuff2; |
| return false; |
| } |
| |
| if (rxBuff2 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| delete[] rxBuff1; |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| receivedSize2 = m_consumer2.ReceiveData(rxBuff2, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize2, m_consumer2.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| false)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| char recievedBuffer2[256] = { 0 }; |
| char SentBuffer2[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| isSuccess &= CompareResultVsGoldenNat( |
| m_sendBuffer2, m_sendSize2, |
| rxBuff2, receivedSize2, |
| m_private_ip2, m_public_ip2, |
| m_private_port2, m_public_port2, |
| false); |
| |
| for (j = 0; j < m_sendSize2; j++) |
| snprintf(&SentBuffer2[3 * j], sizeof(SentBuffer2) - (3 * j + 1), " %02X", m_sendBuffer2[j]); |
| for (j = 0; j < receivedSize2; j++) |
| snprintf(&recievedBuffer2[3 * j], sizeof(recievedBuffer2) - (3 * j + 1), " %02X", rxBuff2[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize2, SentBuffer2, receivedSize2, recievedBuffer2); |
| |
| delete[] rxBuff2; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test005: Single PDN src metadata replacement NAT test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest005 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest005() |
| { |
| m_name = "IpaNatBlockTest005"; |
| m_description = |
| "NAT block test 005 - single PDN src metadata replacement NAT test\ |
| source metadata will be replaced and the routing rule equation will be done upon replaced value\ |
| 1. Generate and commit two routing tables (only one is used). \ |
| the routing table will catch packets with metadata value 0x34567890 (different from original value)\ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to src NAT \ |
| All DST_IP == (193.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| action parameters metadata replacement = true\ |
| 3. generate and commit one NAT rule:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1\ |
| source metadata value shall be replaced to 0x34567890 (caught by the routing rule)"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| m_metadata = 0x34567890; |
| m_minIPAHwType = IPA_HW_v4_0; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateMetdataRoutingRule(bypass0)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateMetdataRoutingRule completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST2_PROD, false, 1); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_target_ip; // Filter DST_IP == 193.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 1; |
| flt_rule_entry.rule.retain_hdr = 1; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| ipa_nat_pdn_entry pdn_info; |
| |
| ret = ipa_nat_add_ipv4_tbl(m_public_ip, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| m_public_ip); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| // modify the PDN entries that will be pointed by the NAT rules |
| pdn_info.public_ip = m_public_ip; |
| pdn_info.src_metadata = m_metadata; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 0, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed modifying PDN index 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("PDN 0 was modified to hold ip 0x%X, src_metadata 0x%X\n", m_public_ip, m_metadata); |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| Load8021QPacket(); |
| |
| address = htonl(m_target_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET + ETH8021Q_HEADER_LEN], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET + ETH8021Q_HEADER_LEN], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET + ETH8021Q_HEADER_LEN], &address, sizeof(address)); |
| port = htons(m_private_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET + ETH8021Q_HEADER_LEN], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET + ETH8021Q_HEADER_LEN], &flags, sizeof(flags)); |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer2.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| true, ETH8021Q_HEADER_LEN)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test006: Single PDN dst metadata replacement NAT test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest006 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest006() |
| { |
| m_name = "IpaNatBlockTest006"; |
| m_description = |
| "NAT block test 006 - single PDN dst metadata replacement NAT test\ |
| destination metadata will be replaced and the routing rule equation will be done upon replaced value\ |
| 1. Generate and commit two routing tables (only one is used). \ |
| the routing table will catch packets with metadata value 0x34567890 (different from original value)\ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| action parameters metadata replacement = true\ |
| 3. generate and commit one NAT rule:\ |
| public ip 192.23.22.1 --> private ip 194.23.22.1 \ |
| destination metadata value shall be replaced to 0x34567890 (caught by the routing rule)"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| m_metadata = 0x34567890; |
| m_minIPAHwType = IPA_HW_v4_0; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateMetdataRoutingRule(bypass0)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateMetdataRoutingRule completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST2_PROD, false, 1); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip; // Filter DST_IP == 193.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 1; |
| flt_rule_entry.rule.retain_hdr = 1; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| ipa_nat_pdn_entry pdn_info; |
| |
| ret = ipa_nat_add_ipv4_tbl(m_public_ip, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| m_public_ip); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| // modify the PDN entries that will be pointed by the NAT rules |
| pdn_info.public_ip = m_public_ip; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = m_metadata; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 0, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed modifying PDN index 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("PDN 0 was modified to hold ip 0x%X, dst_metadata 0x%X\n", m_public_ip, m_metadata); |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_ERROR("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| Load8021QPacket(); |
| |
| address = htonl(m_public_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET + ETH8021Q_HEADER_LEN], &address, sizeof(address)); |
| port = htons(m_public_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET + ETH8021Q_HEADER_LEN], &port, sizeof(port)); |
| |
| address = htonl(m_target_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET + ETH8021Q_HEADER_LEN], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET + ETH8021Q_HEADER_LEN], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET + ETH8021Q_HEADER_LEN], &flags, sizeof(flags)); |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer2.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| false, ETH8021Q_HEADER_LEN)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test007: Hashable routing rule with dst NAT test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest007 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest007() |
| { |
| m_name = "IpaNatBlockTest007"; |
| m_description = |
| "NAT block test 007 - single PDN dst NAT with hashable routing rule test\ |
| test if routing block hash mechanism tests NATed values or pre NAT values\ |
| 1. Generate and commit routing table with two hashable rules. \ |
| first routing rule will send packets with ip == 192.168.9.119 to first pipe \ |
| second routing rule will send packets with ip == 192.168.9.120 to second pipe\ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.168.9.1 & 255.255.255.0)traffic goes to NAT block \ |
| 3. generate and commit two NAT rules with target ip 211.1.1.4:\ |
| 1. public ip 5.5.6.120 --> private ip 192.168.9.119 \ |
| public port 4501 --> private port 4500 \ |
| 2. public ip 5.5.6.120 --> private ip 192.168.9.119 \ |
| public port 4502 --> private port 4500"; |
| m_private_ip = 0xC0A80977; /* 192.168.9.119 */ |
| m_private_port = 4500; |
| m_private_ip2 = 0xC0A80978; /* 192.168.9.120 */ |
| m_private_port2 = 4500; |
| m_public_ip = 0x05050678; /* 5.5.6.120 */ |
| m_public_port = 4501; |
| m_public_port2 = 4502; |
| m_target_ip = 0xD3010104; /* 211.1.1.4 */ |
| m_target_port = 1234; |
| m_minIPAHwType = IPA_HW_v4_0; |
| Register(*this); |
| } |
| |
| bool Setup() |
| { |
| return IpaNatBlockTestFixture::Setup(true); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateHashableRoutingRules(bypass0)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateHashableRoutingRules completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 1); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing table 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; // Mask - catch all |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip; // Filter DST_IP == 5.5.6.120 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| |
| ret = ipa_nat_add_ipv4_tbl(m_public_ip, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| m_public_ip); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule 1 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip2; |
| ipv4_rule.private_port = m_private_port2; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port2; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule 2 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = ntohl(m_public_ip);//5.5.6.120 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = ntohs(m_public_port); // 4501 |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = ntohl(m_target_ip);/* 211.1.1.4 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = ntohs(m_target_port); // 4500 |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| // second packet |
| address = ntohl(m_public_ip);//5.5.6.120 |
| memcpy(&m_sendBuffer2[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = ntohs(m_public_port2); // 4502 |
| memcpy(&m_sendBuffer2[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = ntohl(m_target_ip);/* 211.1.1.4 */ |
| memcpy(&m_sendBuffer2[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = ntohs(m_target_port); // 4500 |
| memcpy(&m_sendBuffer2[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer2[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully the first packet\n"); |
| |
| isSuccess = m_producer.SendData(m_sendBuffer2, m_sendSize2); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully two packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| size_t receivedSize2 = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| Byte *rxBuff2 = new Byte[0x400]; |
| |
| if (rxBuff1 == NULL || rxBuff2 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| receivedSize2 = m_consumer2.ReceiveData(rxBuff2, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize2, m_consumer2.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| false, 0, true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| isSuccess &= (TestManager::GetInstance()->GetIPAHwType() >= IPA_HW_v5_0) ? |
| IsCacheMiss_v5_0(m_sendSize, receivedSize, rxBuff1) : IsCacheMiss(m_sendSize, receivedSize, rxBuff1); |
| |
| char recievedBuffer[0x400] = { 0 }; |
| char SentBuffer[0x400] = { 0 }; |
| char recievedBuffer2[0x400] = { 0 }; |
| char SentBuffer2[0x400] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| isSuccess &= CompareResultVsGoldenNat( |
| m_sendBuffer2, m_sendSize2, |
| rxBuff2, receivedSize2, |
| m_private_ip2, m_public_ip, |
| m_private_port2, m_public_port2, |
| false, 0, true); |
| |
| isSuccess &= (TestManager::GetInstance()->GetIPAHwType() >= IPA_HW_v5_0) ? |
| IsCacheMiss_v5_0(m_sendSize2, receivedSize2, rxBuff2) : IsCacheMiss(m_sendSize2, receivedSize2, rxBuff2); |
| |
| for (j = 0; j < m_sendSize2; j++) |
| snprintf(&SentBuffer2[3 * j], sizeof(SentBuffer2) - (3 * j + 1), " %02X", m_sendBuffer2[j]); |
| for (j = 0; j < receivedSize2; j++) |
| snprintf(&recievedBuffer2[3 * j], sizeof(recievedBuffer2) - (3 * j + 1), " %02X", rxBuff2[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize2, SentBuffer2, receivedSize2, recievedBuffer2); |
| |
| delete[] rxBuff2; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test008: Multi PDN src NAT test match PDN by input from filtering block */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest008 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest008() |
| { |
| m_name = "IpaNatBlockTest008"; |
| m_description = |
| "NAT block test 008 - Multi PDN src NAT test match PDN by input from filtering block\ |
| 1. Generate and commit three routing tables (two are used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| - action go to src NAT + PDN index 2\ |
| All SRC_IP == (194.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit two NAT rules:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1 PDN index 1\ |
| private ip 194.23.22.1 --> public ip 195.23.22.1 PDN index 2"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_public_ip2 = 0xC3171601; /* "195.23.22.1" */ |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| m_minIPAHwType = IPA_HW_v4_0; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0, routing_table1; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| routing_table1.ip = IPA_IP_v4; |
| strlcpy(routing_table1.name, bypass1, sizeof(routing_table1.name)); |
| if (!m_routing.GetRoutingTable(&routing_table1)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table1=0x%p) Failed.\n", &routing_table1); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass1, routing_table1.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 2); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.src_addr = m_private_ip; // Filter SRC_IP == 194.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 2; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_ERROR("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| uint32_t pub_ip_add = m_public_ip; |
| ipa_nat_pdn_entry pdn_info; |
| |
| // first create the NAT table |
| ret = ipa_nat_add_ipv4_tbl(pub_ip_add, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| pub_ip_add); |
| |
| // modify the PDN entries that will be pointed by the NAT rules |
| pdn_info.public_ip = m_public_ip; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 1, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 0 \n"); |
| return false; |
| } |
| |
| pdn_info.public_ip = m_public_ip2; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 2, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 1 \n"); |
| return false; |
| } |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 1; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| // the second rule shall be identical to the first on all parameters except PDN index so the filtering |
| // block action parameter will provide the PDN index. |
| ipv4_rule.pdn_index = 2; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 1\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule 2 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| //first packet private ip 194.23.22.1 --> public ip 195.23.22.1 |
| address = htonl(m_target_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (rxBuff1 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results - verify that the ip of PDN 2 was selected (m_public_ip2) |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip2, |
| m_private_port, m_public_port, |
| true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test009: Single PDN src NAT delete rule test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest009 : public IpaNatBlockTest001 |
| { |
| public: |
| IpaNatBlockTest009() |
| { |
| m_name = "IpaNatBlockTest009"; |
| m_description = |
| "NAT block test 009 - single PDN src NAT rule deletion test\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to src NAT \ |
| All DST_IP == (193.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit one NAT rule:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1\ |
| 4. delete the NAT rule and expect NAT miss"; |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| int ret = IpaNatBlockTest001::AddRules(); |
| if (!ret) { |
| LOG_MSG_ERROR("Leaving, failed Adding test 001 rules 0\n"); |
| return false; |
| } |
| |
| ret = ipa_nat_del_ipv4_rule(m_tbl_hdl, m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed deleting NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule deleted\n"); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| if (receivedSize) { |
| LOG_MSG_ERROR("Data received - test failed!\n"); |
| isSuccess = false; |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| } else { |
| LOG_MSG_ERROR("Comparison of Buffer0 succeeded - NAT rule was hit despite deletion!\n"); |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| } |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test010: Single PDN dst NAT rule deletion test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest010 : public IpaNatBlockTest002 |
| { |
| public: |
| IpaNatBlockTest010() |
| { |
| m_name = "IpaNatBlockTest010"; |
| m_description = |
| "NAT block test 010 - single PDN dst NAT rule deletion test\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block (public IP filtering) \ |
| 3. generate and commit one NAT rule:\ |
| public ip 192.23.22.1 --> private ip 194.23.22.1 \ |
| delete rule and verrify NAT miss"; |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| int ret = IpaNatBlockTest002::AddRules(); |
| if (!ret) { |
| LOG_MSG_ERROR("Leaving, failed Adding test 002 rules 0\n"); |
| return false; |
| } |
| |
| ret = ipa_nat_del_ipv4_rule(m_tbl_hdl, m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed deleting NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule deleted\n"); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| if (receivedSize) { |
| LOG_MSG_ERROR("Data received - test failed!\n"); |
| isSuccess = false; |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| false)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| } |
| else { |
| LOG_MSG_ERROR("Comparison of Buffer0 succeeded - NAT rule was hit despite deletion!\n"); |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| } |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test011: Multi PDN src NAT - MAX number of PDNs test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest011 : public IpaNatBlockTestFixture |
| { |
| uint32_t m_public_ip3; |
| uint32_t m_public_ip4; |
| uint32_t m_private_ip3; |
| uint32_t m_private_ip4; |
| uint16_t m_public_port3; |
| uint16_t m_public_port4; |
| uint16_t m_private_port3; |
| uint16_t m_private_port4; |
| Byte m_sendBuffer4[BUFF_MAX_SIZE]; |
| size_t m_sendSize4; |
| |
| public: |
| IpaNatBlockTest011() |
| { |
| m_name = "IpaNatBlockTest011"; |
| m_description = |
| "NAT block test 011 - Multi PDN src NAT test\ |
| 1. Generate and commit three routing tables (one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| - action go to src NAT \ |
| All SRC_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| All SRC_IP == (194.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| All SRC_IP == (196.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| All SRC_IP == (198.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit four NAT rules:\ |
| private ip 192.23.22.1 --> public ip 193.23.22.1 \ |
| private ip 194.23.22.1 --> public ip 195.23.22.1 \ |
| private ip 196.23.22.1 --> public ip 197.23.22.1 \ |
| private ip 198.23.22.1 --> public ip 199.23.22.1"; |
| m_private_ip = 0xC0171601; /* 192.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC1171601; /* "193.23.22.1" */ |
| m_public_port = 9050; |
| |
| m_private_ip2 = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port2 = 5679; |
| m_public_ip2 = 0xC3171601; /* "195.23.22.1" */ |
| m_public_port2 = 9051; |
| |
| m_private_ip3 = 0xC4171601; /* 196.23.22.1 */ |
| m_private_port3 = 5680; |
| m_public_ip3 = 0xC5171601; /* "197.23.22.1" */ |
| m_public_port3 = 9052; |
| |
| m_private_ip4 = 0xC6171601; /* 198.23.22.1 */ |
| m_private_port4 = 5681; |
| m_public_ip4 = 0xC7171601; /* "199.23.22.1" */ |
| m_public_port4 = 9053; |
| |
| m_target_ip = 0xBF171601; /* 191.23.22.1 */ |
| m_target_port = 1234; |
| |
| m_sendSize4 = BUFF_MAX_SIZE; |
| m_minIPAHwType = IPA_HW_v4_0; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0, routing_table1; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| routing_table1.ip = IPA_IP_v4; |
| strlcpy(routing_table1.name, bypass1, sizeof(routing_table1.name)); |
| if (!m_routing.GetRoutingTable(&routing_table1)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table1=0x%p) Failed.\n", &routing_table1); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass1, routing_table1.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 1); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.src_addr_mask = 0x00FFFFFF; // Mask - catch all private IPs |
| flt_rule_entry.rule.attrib.u.v4.src_addr = m_private_ip; // Filter SRC_IP == 192.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| ipa_nat_pdn_entry pdn_info; |
| |
| // first create the NAT table |
| ret = ipa_nat_add_ipv4_tbl(m_public_ip, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| m_public_ip); |
| |
| // modify the PDN entries that will be pointed by the NAT rules |
| pdn_info.public_ip = m_public_ip; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 0, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 0 \n"); |
| return false; |
| } |
| |
| pdn_info.public_ip = m_public_ip2; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 1, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 1 \n"); |
| return false; |
| } |
| |
| pdn_info.public_ip = m_public_ip3; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 2, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 2 \n"); |
| return false; |
| } |
| |
| pdn_info.public_ip = m_public_ip4; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 3, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 3 \n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("Added 4 PDNs successfully: 0x%X, 0x%X, 0x%X, 0x%X\n", |
| m_public_ip, m_public_ip2, m_public_ip3, m_public_ip4); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d, $d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port, ipv4_rule.pdn_index); |
| |
| ipv4_rule.private_ip = m_private_ip2; |
| ipv4_rule.private_port = m_private_port2; |
| ipv4_rule.public_port = m_public_port2; |
| ipv4_rule.pdn_index = 1; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 1\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule 2 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d, $d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port, ipv4_rule.pdn_index); |
| |
| ipv4_rule.private_ip = m_private_ip3; |
| ipv4_rule.private_port = m_private_port3; |
| ipv4_rule.public_port = m_public_port3; |
| ipv4_rule.pdn_index = 2; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 2\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule 3 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d, $d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port, ipv4_rule.pdn_index); |
| |
| ipv4_rule.private_ip = m_private_ip4; |
| ipv4_rule.private_port = m_private_port4; |
| ipv4_rule.public_port = m_public_port4; |
| ipv4_rule.pdn_index = 3; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 3\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule 4 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d, $d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port, ipv4_rule.pdn_index); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| if (!LoadDefaultPacket(IPA_IP_v4, m_extHdrType, m_sendBuffer4, m_sendSize4)) { |
| LOG_MSG_ERROR("Failed default Packet buffer 4\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("Loaded %zu Bytes to Buffer 4\n", m_sendSize4); |
| |
| //first packet private ip 192.23.22.1 --> public ip 193.23.22.1 |
| address = htonl(m_target_ip);//191.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip);/* 192.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| // second packet private ip 194.23.22.1 --> public ip 195.23.22.1 |
| address = htonl(m_target_ip);//191.23.22.1 |
| memcpy(&m_sendBuffer2[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer2[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip2);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer2[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port2); |
| memcpy(&m_sendBuffer2[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer2[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| // third packet private ip 196.23.22.1 --> public ip 197.23.22.1 |
| address = htonl(m_target_ip);//191.23.22.1 |
| memcpy(&m_sendBuffer3[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer3[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip3);/* 196.23.22.1 */ |
| memcpy(&m_sendBuffer3[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port3); |
| memcpy(&m_sendBuffer3[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer3[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| // third packet private ip 198.23.22.1 --> public ip 199.23.22.1 |
| address = htonl(m_target_ip);//191.23.22.1 |
| memcpy(&m_sendBuffer4[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer4[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip4);/* 198.23.22.1 */ |
| memcpy(&m_sendBuffer4[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port4); |
| memcpy(&m_sendBuffer4[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer4[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| LOG_MSG_DEBUG("sending first packet\n"); |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| // Send second packet |
| LOG_MSG_DEBUG("sending second packet\n"); |
| isSuccess = m_producer.SendData(m_sendBuffer2, m_sendSize2); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| // Send third packet |
| LOG_MSG_DEBUG("sending third packet\n"); |
| isSuccess = m_producer.SendData(m_sendBuffer3, m_sendSize3); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| // Send fourth packet |
| LOG_MSG_DEBUG("sending fourth packet\n"); |
| isSuccess = m_producer.SendData(m_sendBuffer4, m_sendSize4); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully four packets\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| size_t receivedSize2 = 0; |
| size_t receivedSize3 = 0; |
| size_t receivedSize4 = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| Byte *rxBuff2 = new Byte[0x400]; |
| Byte *rxBuff3 = new Byte[0x400]; |
| Byte *rxBuff4 = new Byte[0x400]; |
| |
| if (rxBuff1 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error 1.\n"); |
| if (rxBuff2) |
| delete[] rxBuff2; |
| if (rxBuff3) |
| delete[] rxBuff3; |
| if (rxBuff4) |
| delete[] rxBuff4; |
| return false; |
| } |
| |
| if (rxBuff2 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error 2.\n"); |
| delete[] rxBuff1; |
| if (rxBuff3) |
| delete[] rxBuff3; |
| if (rxBuff4) |
| delete[] rxBuff4; |
| return false; |
| } |
| |
| if (rxBuff3 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error 3.\n"); |
| delete[] rxBuff1; |
| delete[] rxBuff2; |
| if (rxBuff4) |
| delete[] rxBuff4; |
| return false; |
| } |
| |
| if (rxBuff4 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error 4.\n"); |
| delete[] rxBuff1; |
| delete[] rxBuff2; |
| delete[] rxBuff3; |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| receivedSize2 = m_consumer.ReceiveData(rxBuff2, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize2, m_consumer.m_fromChannelName.c_str()); |
| |
| receivedSize3 = m_consumer.ReceiveData(rxBuff3, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize3, m_consumer.m_fromChannelName.c_str()); |
| |
| receivedSize4 = m_consumer.ReceiveData(rxBuff4, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize4, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| char recievedBuffer2[256] = { 0 }; |
| char SentBuffer2[256] = { 0 }; |
| char recievedBuffer3[256] = { 0 }; |
| char SentBuffer3[256] = { 0 }; |
| char recievedBuffer4[256] = { 0 }; |
| char SentBuffer4[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| isSuccess &= CompareResultVsGoldenNat( |
| m_sendBuffer2, m_sendSize2, |
| rxBuff2, receivedSize2, |
| m_private_ip2, m_public_ip2, |
| m_private_port2, m_public_port2, |
| true); |
| |
| for (j = 0; j < m_sendSize2; j++) |
| snprintf(&SentBuffer2[3 * j], sizeof(SentBuffer2) - (3 * j + 1), " %02X", m_sendBuffer2[j]); |
| for (j = 0; j < receivedSize2; j++) |
| snprintf(&recievedBuffer2[3 * j], sizeof(recievedBuffer2) - (3 * j + 1), " %02X", rxBuff2[j]); |
| LOG_MSG_STACK("sent Value2 (%zu)\n%s\n, Received Value2(%zu)\n%s\n", m_sendSize2, SentBuffer2, receivedSize2, recievedBuffer2); |
| |
| delete[] rxBuff2; |
| |
| isSuccess &= CompareResultVsGoldenNat( |
| m_sendBuffer3, m_sendSize3, |
| rxBuff3, receivedSize3, |
| m_private_ip3, m_public_ip3, |
| m_private_port3, m_public_port3, |
| true); |
| |
| for (j = 0; j < m_sendSize3; j++) |
| snprintf(&SentBuffer3[3 * j], sizeof(SentBuffer3) - (3 * j + 1), " %02X", m_sendBuffer3[j]); |
| for (j = 0; j < receivedSize3; j++) |
| snprintf(&recievedBuffer3[3 * j], sizeof(recievedBuffer3) - (3 * j + 1), " %02X", rxBuff3[j]); |
| LOG_MSG_STACK("sent Value3 (%zu)\n%s\n, Received Value3(%zu)\n%s\n", m_sendSize3, SentBuffer3, receivedSize3, recievedBuffer3); |
| |
| delete[] rxBuff3; |
| |
| isSuccess &= CompareResultVsGoldenNat( |
| m_sendBuffer4, m_sendSize4, |
| rxBuff4, receivedSize4, |
| m_private_ip4, m_public_ip4, |
| m_private_port4, m_public_port4, |
| true); |
| |
| for (j = 0; j < m_sendSize4; j++) |
| snprintf(&SentBuffer4[3 * j], sizeof(SentBuffer4) - (3 * j + 1), " %02X", m_sendBuffer4[j]); |
| for (j = 0; j < receivedSize4; j++) |
| snprintf(&recievedBuffer4[3 * j], sizeof(recievedBuffer4) - (3 * j + 1), " %02X", rxBuff4[j]); |
| LOG_MSG_STACK("sent Value4 (%zu)\n%s\n, Received Value4(%zu)\n%s\n", m_sendSize4, SentBuffer4, receivedSize4, recievedBuffer4); |
| |
| delete[] rxBuff4; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test012: Single PDN dst NAT test expansion table usage */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest012 : public IpaNatBlockTestFixture |
| { |
| uint32_t m_target_ip2; |
| uint16_t m_target_port2; |
| public: |
| IpaNatBlockTest012() |
| { |
| m_name = "IpaNatBlockTest012"; |
| m_description = |
| "NAT block test 012 - single PDN dst NAT test - expansion table usage\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block (public IP filtering) \ |
| 3. generate and commit two NAT rules so second one is located in expansion table:\ |
| since we use a single public ip this test should work also on pre IPAv4 targets\ |
| public ip 192.23.22.1 --> private ip 194.23.22.1 "; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_private_ip2 = 0xC5171601; /* 197.23.22.1 */ |
| m_private_port2 = 5679; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| m_target_ip2 = 0x1601C117; /* swap m_target_ip to get same hash*/ |
| m_target_port2 = m_target_port; |
| Register(*this); |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 3); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00FFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip; // Filter DST_IP == 192.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| uint32_t pub_ip_add = m_public_ip; |
| |
| ret = ipa_nat_add_ipv4_tbl(pub_ip_add, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| pub_ip_add); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d, $d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port, ipv4_rule.pdn_index); |
| |
| ipv4_rule.target_ip = m_target_ip2; |
| ipv4_rule.target_port = m_target_port2; |
| |
| // private IPs are not part of the dst NAT entry hash calculation |
| ipv4_rule.private_ip = m_private_ip2; |
| ipv4_rule.private_port = m_private_port2; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule 2 added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d, $d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port, ipv4_rule.pdn_index); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = htonl(m_public_ip); |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_public_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_target_ip2); |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port2); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip2, m_public_ip, |
| m_private_port2, m_public_port, |
| false)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test013: Single PDN dst NAT expansion rule deletion test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest013 : public IpaNatBlockTest012 |
| { |
| public: |
| IpaNatBlockTest013() |
| { |
| m_name = "IpaNatBlockTest013"; |
| m_description = |
| "NAT block test 013 - single PDN dst NAT test - expansion table rule deletion\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block (public IP filtering) \ |
| 3. generate and commit two NAT rules so second one is located in expansion table:\ |
| since we use a single public ip this test should work also on pre IPAv4 targets\ |
| public ip 192.23.22.1 --> private ip 194.23.22.1\ |
| 4. delete NAT rule and expect NAT miss"; |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| int ret = IpaNatBlockTest012::AddRules(); |
| if (!ret) { |
| LOG_MSG_ERROR("Leaving, failed Adding test 012 rules 0\n"); |
| return false; |
| } |
| |
| ret = ipa_nat_del_ipv4_rule(m_tbl_hdl, m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed deleting NAT rule 1\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule deleted\n"); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| if (receivedSize) { |
| LOG_MSG_ERROR("Data received - test failed!\n"); |
| isSuccess = false; |
| |
| // Compare results for debug in the case of failure only |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip2, m_public_ip, |
| m_private_port2, m_public_port, |
| false)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| } |
| else { |
| LOG_MSG_ERROR("Comparison of Buffer0 succeeded - NAT rule was hit despite deletion!\n"); |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| } |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test014: Single PDN src NAT zero PDN test */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest014 : public IpaNatBlockTest001 |
| { |
| public: |
| IpaNatBlockTest014() |
| { |
| m_name = "IpaNatBlockTest014"; |
| m_description = |
| "NAT block test 014 - single PDN src NAT PDN zeroing test\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to src NAT \ |
| All DST_IP == (193.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit one NAT rule:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1\ |
| 4. modify PDN entry 0 and expect NAT miss"; |
| m_minIPAHwType = IPA_HW_v4_0; |
| } |
| |
| |
| virtual bool AddRules() |
| { |
| ipa_nat_pdn_entry pdn_info; |
| |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| int ret = IpaNatBlockTest001::AddRules(); |
| if (!ret) { |
| LOG_MSG_ERROR("Leaving, failed Adding test 001 rules 0\n"); |
| return false; |
| } |
| |
| // modify PDN entry 0 so the NAT rule will get a NAT miss |
| pdn_info.public_ip = 0; |
| pdn_info.src_metadata = 0; |
| pdn_info.dst_metadata = 0; |
| ret = ipa_nat_modify_pdn(m_tbl_hdl, 0, &pdn_info); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed Modifying PDN entry 0 \n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("PDN modified\n"); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| if (receivedSize) { |
| LOG_MSG_ERROR("Data received - test failed!\n"); |
| isSuccess = false; |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| } |
| else { |
| LOG_MSG_ERROR("Comparison of Buffer0 succeeded - NAT rule was hit despite deletion!\n"); |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| } |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test015: Single PDN src NAT send two packets that will hit the same rule */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest015 : public IpaNatBlockTest001 |
| { |
| public: |
| IpaNatBlockTest015() |
| { |
| m_name = "IpaNatBlockTest015"; |
| m_description = |
| "NAT block test 015 - single PDN src NAT hit the same rule twice\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to src NAT \ |
| All DST_IP == (193.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit one NAT rule:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1\ |
| 4. send two pakcets and verify NATing"; |
| } |
| |
| virtual bool SendPackets() |
| { |
| bool ret = IpaNatBlockTest001::SendPackets(); |
| if (!ret) |
| { |
| LOG_MSG_ERROR("failed sending first pakcket.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("first packet sent succesfully.\n"); |
| |
| ret = IpaNatBlockTest001::SendPackets(); |
| if (!ret) |
| { |
| LOG_MSG_ERROR("failed sending second pakcket.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("second packet sent succesfully.\n"); |
| |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| bool isSuccess = true; |
| |
| isSuccess &= IpaNatBlockTest001::ReceivePacketsAndCompare(); |
| if (!isSuccess) |
| { |
| LOG_MSG_ERROR("failed to receive\\compare first packet.\n"); |
| } |
| |
| isSuccess &= IpaNatBlockTest001::ReceivePacketsAndCompare(); |
| if (!isSuccess) |
| { |
| LOG_MSG_ERROR("failed to receive\\compare second packet.\n"); |
| } |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test016: Single PDN dst NAT send two packets that will hit the same rule */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest016 : public IpaNatBlockTest002 |
| { |
| public: |
| IpaNatBlockTest016() |
| { |
| m_name = "IpaNatBlockTest016"; |
| m_description = |
| "NAT block test 016 - single PDN dst NAT hit the same rule twice\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit one NAT rule:\ |
| public ip 192.23.22.1 --> private ip 194.23.22.1\ |
| 4. send two pakcets and verify NATing"; |
| } |
| |
| virtual bool SendPackets() |
| { |
| bool ret = IpaNatBlockTest002::SendPackets(); |
| if (!ret) |
| { |
| LOG_MSG_ERROR("failed sending first pakcket.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("first packet sent succesfully.\n"); |
| |
| ret = IpaNatBlockTest002::SendPackets(); |
| if (!ret) |
| { |
| LOG_MSG_ERROR("failed sending second pakcket.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("second packet sent succesfully.\n"); |
| |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| bool isSuccess = true; |
| |
| isSuccess &= IpaNatBlockTest002::ReceivePacketsAndCompare(); |
| if (!isSuccess) |
| { |
| LOG_MSG_ERROR("failed to receive\\compare first packet.\n"); |
| } |
| |
| isSuccess &= IpaNatBlockTest002::ReceivePacketsAndCompare(); |
| if (!isSuccess) |
| { |
| LOG_MSG_ERROR("failed to receive\\compare second packet.\n"); |
| } |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------------*/ |
| /* Test017: Multi PDN src NAT test with identical private IPs and different ports */ |
| /*---------------------------------------------------------------------------------*/ |
| class IpaNatBlockTest017 : public IpaNatBlockTest003 |
| { |
| public: |
| IpaNatBlockTest017() |
| { |
| m_name = "IpaNatBlockTest017"; |
| m_description = |
| "NAT block test 017 - Multi PDN src NAT test with identical private IPs\ |
| 1. Generate and commit three routing tables (two are used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit two filtering rule: (DST & Mask Match). \ |
| - action go to src NAT \ |
| All SRC_IP == (194.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| All SRC_IP == (197.23.22.1 & 0.255.255.255)traffic goes to NAT block - not relevant for this test \ |
| 3. generate and commit two NAT rules:\ |
| private ip 194.23.22.1 && port 5678--> public ip 192.23.22.1 \ |
| private ip 194.23.22.1 && port 5679--> public ip 195.23.22.1"; |
| m_private_ip2 = m_private_ip; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| // we cannot just use test 003 ReceivePacketsAndCompare since the filtering rules send the |
| // packets to two different pipes, but since the private IPs are now equal the second filtering rule |
| // won't be hit so we need to recive the second packet on the first pipe |
| |
| size_t receivedSize = 0; |
| size_t receivedSize2 = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| Byte *rxBuff2 = new Byte[0x400]; |
| |
| if (rxBuff1 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| if (rxBuff2) |
| delete[] rxBuff2; |
| return false; |
| } |
| |
| if (rxBuff2 == NULL) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| delete[] rxBuff1; |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| receivedSize2 = m_consumer.ReceiveData(rxBuff2, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize2, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGoldenNat( |
| m_sendBuffer, m_sendSize, |
| rxBuff1, receivedSize, |
| m_private_ip, m_public_ip, |
| m_private_port, m_public_port, |
| true)) |
| { |
| LOG_MSG_ERROR("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| char recievedBuffer2[256] = { 0 }; |
| char SentBuffer2[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| isSuccess &= CompareResultVsGoldenNat( |
| m_sendBuffer2, m_sendSize2, |
| rxBuff2, receivedSize2, |
| m_private_ip2, m_public_ip2, |
| m_private_port2, m_public_port2, |
| true); |
| |
| for (j = 0; j < m_sendSize2; j++) |
| snprintf(&SentBuffer2[3 * j], sizeof(SentBuffer2) - (3 * j + 1), " %02X", m_sendBuffer2[j]); |
| for (j = 0; j < receivedSize2; j++) |
| snprintf(&recievedBuffer2[3 * j], sizeof(recievedBuffer2) - (3 * j + 1), " %02X", rxBuff2[j]); |
| LOG_MSG_STACK("sent Value2 (%zu)\n%s\n, Received Value2(%zu)\n%s\n", m_sendSize2, SentBuffer2, receivedSize2, recievedBuffer2); |
| |
| delete[] rxBuff2; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------------*/ |
| /* Test018: Multi PDN dst NAT test with identical private IPs and different ports */ |
| /*---------------------------------------------------------------------------------*/ |
| class IpaNatBlockTest018 : public IpaNatBlockTest004 |
| { |
| public: |
| IpaNatBlockTest018() |
| { |
| m_name = "IpaNatBlockTest018"; |
| m_description = |
| "NAT block test 018 - Multi PDN dst NAT test with identical private IPs\ |
| 1. Generate and commit three routing tables (two are used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit two filtering rule: (DST & Mask Match). \ |
| - action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| All DST_IP == (195.23.22.1 & 0.255.255.255)traffic goes to NAT block - not releveant for this test\ |
| 3. generate and commit two NAT rules:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1 && port 9050\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1 && port 9051"; |
| m_private_ip2 = m_private_ip; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test019: NAT Suppression test */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest019 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest019() |
| { |
| m_name = "IpaNatBlockTest019"; |
| m_description = |
| "NAT block test 019 - single PDN src NAT test\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to src NAT \ |
| All DST_IP == (193.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit one NAT rule:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| Register(*this); |
| } |
| |
| virtual bool Setup() |
| { |
| return IpaNatBlockTestFixture::Setup(false, true); |
| } |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| /* Setup NAT Exception routing table. */ |
| if (!m_routing.SetNatConntrackExcRoutingTable(routing_table0.hdl, true)) |
| { |
| LOG_MSG_ERROR("m_routing.SetNatConntrackExcRoutingTable(routing_table0 hdl=%d) Failed.\n", |
| routing_table0.hdl); |
| return false; |
| } |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 1); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFF00; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_target_ip; // Filter DST_IP == 193.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| |
| ret = ipa_nat_add_ipv4_tbl(m_public_ip, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_DEBUG("failed creating NAT table\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| m_public_ip); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("failed adding NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = htonl(m_target_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port+1); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET],&flags , sizeof(flags)); |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGolden(m_sendBuffer, m_sendSize, rxBuff1, receivedSize)) |
| { |
| printf("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test020: NAT Suppression test with Status */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest020 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest020() |
| { |
| m_name = "IpaNatBlockTest020"; |
| m_description = |
| "NAT block test 020 - single PDN src NAT test with status enabled\ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to src NAT \ |
| All DST_IP == (193.23.22.1 & 0.255.255.255)traffic goes to NAT block \ |
| 3. generate and commit one NAT rule:\ |
| private ip 194.23.22.1 --> public ip 192.23.22.1"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| Register(*this); |
| } |
| |
| virtual bool Setup() |
| { |
| return IpaNatBlockTestFixture::Setup(true, true); |
| } |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| /* Setup NAT Exception routing table. */ |
| if (!m_routing.SetNatConntrackExcRoutingTable(routing_table0.hdl, true)) |
| { |
| LOG_MSG_ERROR("m_routing.SetNatConntrackExcRoutingTable(routing_table0 hdl=%d) Failed.\n", |
| routing_table0.hdl); |
| return false; |
| } |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 1); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFF00; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_target_ip; // Filter DST_IP == 193.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| |
| ret = ipa_nat_add_ipv4_tbl(m_public_ip, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_DEBUG("failed creating NAT table\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| m_public_ip); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("failed adding NAT rule 0\n"); |
| return false; |
| } |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = htonl(m_target_ip);//193.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_private_ip);/* 194.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_private_port+1); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET],&flags , sizeof(flags)); |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| struct ipa3_hw_pkt_status_hw_v5_5 *status = NULL; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGolden_w_Status(m_sendBuffer, m_sendSize, rxBuff1, receivedSize)) |
| { |
| printf("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| status = (struct ipa3_hw_pkt_status_hw_v5_5 *)rxBuff1; |
| if (!status->nat_exc_suppress) |
| { |
| printf("NAT Suppression not hit!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test021: Single PDN dst NAT test with NAT suppresssion */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest021 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest021() |
| { |
| m_name = "IpaNatBlockTest021"; |
| m_description = |
| "NAT block test 002 - single PDN dst NAT test with NAT suppression \ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block (public IP filtering) \ |
| 3. generate and commit one NAT rule: \ |
| public ip 192.23.22.1 --> private ip 194.23.22.1. \ |
| 4. Send packet not matching with NAT entry.\n"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| Register(*this); |
| } |
| |
| virtual bool Setup() |
| { |
| return IpaNatBlockTestFixture::Setup(false, true); |
| } |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| /* Setup NAT Exception routing table. */ |
| if (!m_routing.SetNatConntrackExcRoutingTable(routing_table0.hdl, true)) |
| { |
| LOG_MSG_ERROR("m_routing.SetNatConntrackExcRoutingTable(routing_table0 hdl=%d) Failed.\n", |
| routing_table0.hdl); |
| return false; |
| } |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 3); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00FFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip; // Filter DST_IP == 192.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| uint32_t pub_ip_add = m_public_ip; |
| |
| ret = ipa_nat_add_ipv4_tbl(pub_ip_add, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| pub_ip_add); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = htonl(m_public_ip);//192.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_public_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_target_ip);/* 193.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port+1); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGolden(m_sendBuffer, m_sendSize, rxBuff1, receivedSize)) |
| { |
| printf("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| /*---------------------------------------------------------------------------*/ |
| /* Test022: Single PDN dst NAT test with NAT suppresssion and status enabled */ |
| /* NOTE: other classes are derived from this class - change carefully */ |
| /*---------------------------------------------------------------------------*/ |
| class IpaNatBlockTest022 : public IpaNatBlockTestFixture |
| { |
| public: |
| IpaNatBlockTest022() |
| { |
| m_name = "IpaNatBlockTest022"; |
| m_description = |
| "NAT block test 022 - single PDN dst NAT test with NAT suppression and status enabled \ |
| 1. Generate and commit three routing tables (only one is used). \ |
| Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \ |
| 2. Generate and commit one filtering rule: (DST & Mask Match). \ |
| action go to dst NAT \ |
| All DST_IP == (192.23.22.1 & 0.255.255.255)traffic goes to NAT block (public IP filtering) \ |
| 3. generate and commit one NAT rule:\ |
| public ip 192.23.22.1 --> private ip 194.23.22.1. \ |
| 4. Send packet not matching with NAT entry.\n"; |
| m_private_ip = 0xC2171601; /* 194.23.22.1 */ |
| m_private_port = 5678; |
| m_public_ip = 0xC0171601; /* "192.23.22.1" */ |
| m_public_port = 9050; |
| m_target_ip = 0xC1171601; /* 193.23.22.1 */ |
| m_target_port = 1234; |
| Register(*this); |
| } |
| |
| virtual bool Setup() |
| { |
| return IpaNatBlockTestFixture::Setup(true, true); |
| } |
| |
| virtual bool AddRules() |
| { |
| LOG_MSG_DEBUG("Entering\n"); |
| |
| const char bypass0[20] = "Bypass0"; |
| const char bypass1[20] = "Bypass1"; |
| const char bypass2[20] = "Bypass2"; |
| struct ipa_ioc_get_rt_tbl routing_table0; |
| |
| if (!CreateThreeIPv4BypassRoutingTables(bypass0, bypass1, bypass2)) |
| { |
| LOG_MSG_ERROR("CreateThreeBypassRoutingTables Failed\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("CreateThreeBypassRoutingTables completed successfully\n"); |
| routing_table0.ip = IPA_IP_v4; |
| strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name)); |
| if (!m_routing.GetRoutingTable(&routing_table0)) |
| { |
| LOG_MSG_ERROR("m_routing.GetRoutingTable(&routing_table0=0x%p) Failed.\n", &routing_table0); |
| return false; |
| } |
| LOG_MSG_DEBUG("%s route table handle = %u\n", bypass0, routing_table0.hdl); |
| |
| /* Setup NAT Exception routing table. */ |
| if (!m_routing.SetNatConntrackExcRoutingTable(routing_table0.hdl, true)) |
| { |
| LOG_MSG_ERROR("m_routing.SetNatConntrackExcRoutingTable(routing_table0 hdl=%d) Failed.\n", |
| routing_table0.hdl); |
| return false; |
| } |
| |
| IPAFilteringTable FilterTable0; |
| struct ipa_flt_rule_add flt_rule_entry; |
| FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST_PROD, false, 3); |
| LOG_MSG_DEBUG("FilterTable*.Init Completed Successfully..\n"); |
| |
| // Configuring Filtering Rule No.0 |
| FilterTable0.GeneratePresetRule(1, flt_rule_entry); |
| flt_rule_entry.at_rear = true; |
| flt_rule_entry.flt_rule_hdl = -1; // return Value |
| flt_rule_entry.status = -1; // return value |
| flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; |
| flt_rule_entry.rule.rt_tbl_hdl = routing_table0.hdl; //put here the handle corresponding to Routing Rule 1 |
| flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; |
| flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00FFFFFF; // Mask |
| flt_rule_entry.rule.attrib.u.v4.dst_addr = m_public_ip; // Filter DST_IP == 192.23.22.1 |
| flt_rule_entry.rule.pdn_idx = 0; |
| flt_rule_entry.rule.set_metadata = 0; |
| if ( |
| ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) || |
| !m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()) |
| ) |
| { |
| LOG_MSG_ERROR("Error Adding Rule to Filter Table, aborting...\n"); |
| return false; |
| } |
| else |
| { |
| LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl, FilterTable0.ReadRuleFromTable(0)->status); |
| } |
| |
| //NAT table and rules creation |
| int total_entries = 20; |
| int ret; |
| ipa_nat_ipv4_rule ipv4_rule; |
| uint32_t pub_ip_add = m_public_ip; |
| |
| ret = ipa_nat_add_ipv4_tbl(pub_ip_add, m_mem_type, total_entries, &m_tbl_hdl); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed creating NAT table\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("nat table added, hdl %d, public ip 0x%X\n", m_tbl_hdl, |
| pub_ip_add); |
| |
| ipv4_rule.target_ip = m_target_ip; |
| ipv4_rule.target_port = m_target_port; |
| ipv4_rule.private_ip = m_private_ip; |
| ipv4_rule.private_port = m_private_port; |
| ipv4_rule.protocol = IPPROTO_TCP; |
| ipv4_rule.public_port = m_public_port; |
| ipv4_rule.pdn_index = 0; |
| |
| ret = ipa_nat_add_ipv4_rule(m_tbl_hdl, &ipv4_rule, &m_nat_rule_hdl1); |
| if (ret) { |
| LOG_MSG_ERROR("Leaving, failed adding NAT rule 0\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("NAT rule added, hdl %d, data: 0x%X, %d, 0x%X, %d, %d, %d\n", |
| m_nat_rule_hdl1, ipv4_rule.target_ip, ipv4_rule.target_port, |
| ipv4_rule.private_ip, ipv4_rule.private_port, |
| ipv4_rule.protocol, ipv4_rule.public_port); |
| |
| LOG_MSG_DEBUG("Leaving\n"); |
| return true; |
| }// AddRules() |
| |
| virtual bool ModifyPackets() |
| { |
| uint32_t address; |
| uint16_t port; |
| char flags = 0x18; |
| |
| address = htonl(m_public_ip);//192.23.22.1 |
| memcpy(&m_sendBuffer[IPV4_DST_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_public_port); |
| memcpy(&m_sendBuffer[IPV4_DST_PORT_OFFSET], &port, sizeof(port)); |
| |
| address = htonl(m_target_ip);/* 193.23.22.1 */ |
| memcpy(&m_sendBuffer[IPV4_SRC_ADDR_OFFSET], &address, sizeof(address)); |
| port = htons(m_target_port+1); |
| memcpy(&m_sendBuffer[IPV4_SRC_PORT_OFFSET], &port, sizeof(port)); |
| |
| //make sure the FIN flag is not set, otherwise we will get a NAT miss |
| memcpy(&m_sendBuffer[IPV4_TCP_FLAGS_OFFSET], &flags, sizeof(flags)); |
| |
| return true; |
| }// ModifyPacktes () |
| |
| virtual bool SendPackets() |
| { |
| bool isSuccess = false; |
| |
| // Send first packet |
| isSuccess = m_producer.SendData(m_sendBuffer, m_sendSize); |
| if (false == isSuccess) |
| { |
| LOG_MSG_ERROR("SendData failure.\n"); |
| return false; |
| } |
| |
| LOG_MSG_DEBUG("sent successfully one packet\n"); |
| return true; |
| } |
| |
| virtual bool ReceivePacketsAndCompare() |
| { |
| size_t receivedSize = 0; |
| bool isSuccess = true; |
| struct ipa3_hw_pkt_status_hw_v5_5 *status = NULL; |
| |
| // Receive results |
| Byte *rxBuff1 = new Byte[0x400]; |
| |
| if (NULL == rxBuff1) |
| { |
| LOG_MSG_ERROR("Memory allocation error.\n"); |
| return false; |
| } |
| |
| receivedSize = m_consumer.ReceiveData(rxBuff1, 0x400); |
| LOG_MSG_DEBUG("Received %zu bytes on %s.\n", receivedSize, m_consumer.m_fromChannelName.c_str()); |
| |
| // Compare results |
| if (!CompareResultVsGolden_w_Status(m_sendBuffer, m_sendSize, rxBuff1, receivedSize)) |
| { |
| printf("Comparison of Buffer0 Failed!\n"); |
| isSuccess = false; |
| } |
| |
| status = (struct ipa3_hw_pkt_status_hw_v5_5 *)rxBuff1; |
| if (!status->nat_exc_suppress) |
| { |
| printf("NAT Suppression not hit!\n"); |
| isSuccess = false; |
| } |
| |
| char recievedBuffer[256] = { 0 }; |
| char SentBuffer[256] = { 0 }; |
| size_t j; |
| |
| for (j = 0; j < m_sendSize; j++) |
| snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3 * j + 1), " %02X", m_sendBuffer[j]); |
| for (j = 0; j < receivedSize; j++) |
| snprintf(&recievedBuffer[3 * j], sizeof(recievedBuffer) - (3 * j + 1), " %02X", rxBuff1[j]); |
| LOG_MSG_STACK("sent Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n", m_sendSize, SentBuffer, receivedSize, recievedBuffer); |
| |
| delete[] rxBuff1; |
| |
| return isSuccess; |
| } |
| }; |
| |
| |
| static class IpaNatBlockTest001 IpaNatBlockTest001;//single PDN src NAT test |
| static class IpaNatBlockTest002 IpaNatBlockTest002;//single PDN dst NAT test |
| static class IpaNatBlockTest003 IpaNatBlockTest003;//multi PDN (tuple) src NAT test |
| static class IpaNatBlockTest004 IpaNatBlockTest004;//multi PDN (tuple) dst NAT test |
| static class IpaNatBlockTest005 IpaNatBlockTest005;//single PDN src NAT test - src metadata replacement |
| static class IpaNatBlockTest006 IpaNatBlockTest006;//single PDN dst NAT test - dst metadata replacement |
| static class IpaNatBlockTest007 IpaNatBlockTest007;//hashable routing rule with dst NAT test |
| static class IpaNatBlockTest008 IpaNatBlockTest008;//Multi PDN src NAT test match PDN by input from filtering block |
| static class IpaNatBlockTest009 IpaNatBlockTest009;//single PDN src NAT rule deletion test |
| static class IpaNatBlockTest010 IpaNatBlockTest010;//single PDN dst NAT rule deletion test |
| static class IpaNatBlockTest011 IpaNatBlockTest011;//Multi PDN src NAT - MAX number of PDNs test |
| static class IpaNatBlockTest012 IpaNatBlockTest012;//Single PDN dst NAT test expansion table usage |
| static class IpaNatBlockTest013 IpaNatBlockTest013;//Single PDN dst NAT test expansion table delete test |
| static class IpaNatBlockTest014 IpaNatBlockTest014;//single PDN src NAT zero PDN test |
| static class IpaNatBlockTest015 IpaNatBlockTest015;//single PDN src NAT test - send two packets that will hit the same rule |
| static class IpaNatBlockTest016 IpaNatBlockTest016;//single PDN dst NAT test - send two packets that will hit the same rule |
| static class IpaNatBlockTest017 IpaNatBlockTest017;//multi PDN (tuple) src NAT test - identical private IPs different ports |
| static class IpaNatBlockTest018 IpaNatBlockTest018;//multi PDN (tuple) dst NAT test - identical private IPs different ports |
| static class IpaNatBlockTest019 IpaNatBlockTest019;//Single PDN SRC NAT suppression test |
| static class IpaNatBlockTest020 IpaNatBlockTest020;//Single PDN SRC NAT suppression test with status |
| static class IpaNatBlockTest021 IpaNatBlockTest021;//Single PDN DST NAT suppression test |
| static class IpaNatBlockTest022 IpaNatBlockTest022;//Single PDN DST NAT suppression test with status |