405 lines
14 KiB
C++
405 lines
14 KiB
C++
/*
|
|
* Copyright (c) 2014-2015, 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 "HeaderRemovalTestFixture.h"
|
|
|
|
#include "Constants.h"
|
|
#include "Logger.h"
|
|
#include "IPAFilteringTable.h"
|
|
|
|
#define IPA_TEST_DMUX_HEADER_LENGTH 8
|
|
#define IPA_TEST_META_DATA_IS_VALID 1
|
|
#define IPA_TEST_DMUX_HEADER_META_DATA_OFFSET 4
|
|
|
|
extern Logger g_Logger;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//define the static Pipes which will be used by all derived tests.
|
|
Pipe HeaderRemovalTestFixture::m_A2NDUNToIpaPipe(IPA_CLIENT_TEST2_PROD, IPA_TEST_CONFIFURATION_3);
|
|
Pipe HeaderRemovalTestFixture::m_IpaToUsbPipe(IPA_CLIENT_TEST_CONS, IPA_TEST_CONFIFURATION_3);
|
|
Pipe HeaderRemovalTestFixture::m_IpaToA2NDUNPipe(IPA_CLIENT_TEST2_CONS, IPA_TEST_CONFIFURATION_3);
|
|
Pipe HeaderRemovalTestFixture::m_IpaToQ6LANPipe(IPA_CLIENT_TEST4_CONS, IPA_TEST_CONFIFURATION_3);
|
|
RoutingDriverWrapper HeaderRemovalTestFixture::m_routing;
|
|
Filtering HeaderRemovalTestFixture::m_filtering;
|
|
const char HeaderRemovalTestFixture_bypass0[20] = "Bypass0";
|
|
const char HeaderRemovalTestFixture_bypassIPv60[20] = "BypassIPv60";
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HeaderRemovalTestFixture::HeaderRemovalTestFixture()
|
|
{
|
|
m_testSuiteName.push_back("Removal");
|
|
Register(*this);
|
|
}
|
|
|
|
static int SetupKernelModule(void)
|
|
{
|
|
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[1];
|
|
struct test_ipa_ep_cfg to_ipa_cfg[1];
|
|
|
|
struct ipa_test_config_header header = {0};
|
|
struct ipa_channel_config *to_ipa_array[1];
|
|
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_TEST_CONS,
|
|
(void *)&from_ipa_cfg[0],
|
|
sizeof(from_ipa_cfg[0]));
|
|
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_TEST2_CONS,
|
|
(void *)&from_ipa_cfg[1],
|
|
sizeof(from_ipa_cfg[1]));
|
|
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]));
|
|
from_ipa_array[2] = &from_ipa_channels[2];
|
|
|
|
/* To ipa configurations - 1 pipes */
|
|
memset(&to_ipa_cfg[0], 0, sizeof(to_ipa_cfg[0]));
|
|
to_ipa_cfg[0].hdr.hdr_len = IPA_TEST_DMUX_HEADER_LENGTH;
|
|
to_ipa_cfg[0].hdr.hdr_ofst_metadata_valid = IPA_TEST_META_DATA_IS_VALID;
|
|
to_ipa_cfg[0].hdr.hdr_ofst_metadata =
|
|
IPA_TEST_DMUX_HEADER_META_DATA_OFFSET;
|
|
prepare_channel_struct(&to_ipa_channels[0],
|
|
header.to_ipa_channels_num++,
|
|
IPA_CLIENT_TEST2_PROD,
|
|
(void *)&to_ipa_cfg[0],
|
|
sizeof(to_ipa_cfg[0]));
|
|
to_ipa_array[0] = &to_ipa_channels[0];
|
|
|
|
header.head_marker = IPA_TEST_CONFIG_MARKER;
|
|
header.tail_marker = IPA_TEST_CONFIG_MARKER;
|
|
|
|
prepare_header_struct(&header, from_ipa_array, to_ipa_array);
|
|
|
|
retval = GenericConfigureScenario(&header);
|
|
|
|
return retval;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool HeaderRemovalTestFixture::Setup()
|
|
{
|
|
bool bRetVal = true;
|
|
|
|
//Set the configuration to support USB->IPA and IPA->USB pipes.
|
|
//ConfigureScenario(PHASE_THREE_TEST_CONFIGURATION);
|
|
|
|
bRetVal = SetupKernelModule();
|
|
if (bRetVal != true) {
|
|
return bRetVal;
|
|
}
|
|
|
|
//Initialize the pipe for all the tests - this will open the inode which represents the pipe.
|
|
bRetVal &= m_A2NDUNToIpaPipe.Init();
|
|
bRetVal &= m_IpaToUsbPipe.Init();
|
|
bRetVal &= m_IpaToA2NDUNPipe.Init();
|
|
bRetVal &= m_IpaToQ6LANPipe.Init();
|
|
|
|
// remove default "LAN" routing table (as we want to pass to USB pipe)
|
|
m_routing.Reset(IPA_IP_v4);
|
|
m_routing.Reset(IPA_IP_v6);
|
|
|
|
return bRetVal;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool HeaderRemovalTestFixture::Teardown()
|
|
{
|
|
//The Destroy method will close the inode.
|
|
m_A2NDUNToIpaPipe.Destroy();
|
|
m_IpaToUsbPipe.Destroy();
|
|
m_IpaToA2NDUNPipe.Destroy();
|
|
m_IpaToQ6LANPipe.Destroy();
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Byte* HeaderRemovalTestFixture::CreateA2NDUNPacket(
|
|
unsigned int magicNumber,
|
|
unsigned int nID,
|
|
string sPayloadFileName,
|
|
unsigned int *nTotalLength)
|
|
{
|
|
size_t nIpv4ByteSize = 1024;
|
|
bool bRetVal = false;
|
|
Byte *pA2NDUNPacket = 0;
|
|
unsigned int nA2NDUNPacketByteSize = 0;
|
|
Byte *pIpv4Packet = (Byte*) malloc(1024);
|
|
|
|
if(0 == pIpv4Packet)
|
|
{
|
|
LOG_MSG_ERROR("Cannot allocate the memory for IPv4 packet");
|
|
return 0;
|
|
}
|
|
|
|
bRetVal = LoadDefaultPacket(IPA_IP_v4, pIpv4Packet, nIpv4ByteSize);
|
|
if(false == bRetVal)
|
|
{
|
|
LOG_MSG_ERROR("Cannot load the packet");
|
|
pA2NDUNPacket = 0;
|
|
goto bail;
|
|
}
|
|
//Magic Number(4 Bytes) Logical Channel ID(2 Bytes) Length(2 Bytes)
|
|
nA2NDUNPacketByteSize = m_A2NDUNToIpaPipe.GetHeaderLengthAdd() + nIpv4ByteSize;
|
|
|
|
pA2NDUNPacket = new Byte[ nA2NDUNPacketByteSize ];
|
|
|
|
//htobe32 for the magic number:
|
|
pA2NDUNPacket[0] = (magicNumber & 0xFF000000) >> 24;//MSB
|
|
pA2NDUNPacket[1] = (magicNumber & 0x00FF0000) >> 16;
|
|
pA2NDUNPacket[2] = (magicNumber & 0x0000FF00) >> 8;
|
|
pA2NDUNPacket[3] = (magicNumber & 0x000000FF) >> 0;//LSB
|
|
|
|
//htobe16 for the Logical Channel ID:
|
|
pA2NDUNPacket[4] = (nID & 0xFF00) >> 8;//MSB
|
|
pA2NDUNPacket[5] = (nID & 0x00FF) >> 0;//LSB
|
|
|
|
//htobe16 for the Length of the packet:
|
|
pA2NDUNPacket[6] = (nA2NDUNPacketByteSize & 0xFF00) >> 8;//MSB
|
|
pA2NDUNPacket[7] = (nA2NDUNPacketByteSize & 0x00FF) >> 0;//LSB
|
|
|
|
//add the payload to the A2NDUN packet
|
|
memcpy(&pA2NDUNPacket[8], pIpv4Packet, nIpv4ByteSize);
|
|
|
|
*nTotalLength = nA2NDUNPacketByteSize;
|
|
|
|
/* fall through */
|
|
|
|
bail:
|
|
|
|
Free(pIpv4Packet);
|
|
|
|
return pA2NDUNPacket;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool HeaderRemovalTestFixture::SetIPATablesToPassAllToSpecificClient(
|
|
enum ipa_client_type nClientTypeSrc,
|
|
enum ipa_client_type nClientTypeDst)
|
|
{
|
|
bool bRetVal = true;
|
|
|
|
bRetVal = SetRoutingTableToPassAllToSpecificClient(nClientTypeDst);
|
|
if(false == bRetVal)
|
|
goto bail;
|
|
bRetVal = SetFilterTableToPassAllToSpecificClient(nClientTypeSrc);
|
|
if(false == bRetVal)
|
|
goto bail;
|
|
bRetVal = SetHeaderInsertionTableAddEmptyHeaderForTheClient(nClientTypeSrc);
|
|
if(false == bRetVal)
|
|
goto bail;
|
|
/* fall through */
|
|
|
|
bail:
|
|
return bRetVal;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool HeaderRemovalTestFixture::SetFilterTableToPassAllToSpecificClient(
|
|
enum ipa_client_type nClientType)
|
|
{
|
|
IPAFilteringTable FilterTable;
|
|
struct ipa_flt_rule_add flt_rule_entry;
|
|
struct ipa_ioc_get_rt_tbl sRoutingTable;
|
|
|
|
sRoutingTable.ip = IPA_IP_v4;
|
|
strlcpy(sRoutingTable.name, "Bypass0", sizeof(sRoutingTable.name));
|
|
|
|
if (false == m_routing.GetRoutingTable(&sRoutingTable)) {
|
|
LOG_MSG_ERROR("Configure the routing block first");
|
|
return false;
|
|
}
|
|
|
|
FilterTable.Init(IPA_IP_v4, nClientType, false, 1);
|
|
FilterTable.GeneratePresetRule(0, flt_rule_entry);
|
|
flt_rule_entry.at_rear = true;
|
|
flt_rule_entry.flt_rule_hdl = -1;
|
|
flt_rule_entry.status = -1;
|
|
flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
|
|
flt_rule_entry.rule.rt_tbl_hdl = sRoutingTable.hdl;
|
|
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
|
|
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000;
|
|
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000;
|
|
if ((-1 == FilterTable.AddRuleToTable(flt_rule_entry)) ||
|
|
!m_filtering.AddFilteringRule(FilterTable.GetFilteringTable())) {
|
|
LOG_MSG_INFO ("%s::Error Adding RuleTable(0) to Filtering, aborting...");
|
|
return false;
|
|
} else {
|
|
LOG_MSG_INFO( "flt rule hdl0=0x%x, status=0x%x",
|
|
FilterTable.ReadRuleFromTable(0)->flt_rule_hdl,
|
|
FilterTable.ReadRuleFromTable(0)->status);
|
|
}
|
|
LOG_MSG_INFO("Leaving ");
|
|
|
|
return true;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool HeaderRemovalTestFixture::SetRoutingTableToPassAllToSpecificClient(
|
|
enum ipa_client_type nClientType)
|
|
{
|
|
if (!CreateBypassRoutingTablesIPv4(
|
|
HeaderRemovalTestFixture_bypass0,
|
|
nClientType)) {
|
|
LOG_MSG_INFO("CreateThreeBypassRoutingTables Failed");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool HeaderRemovalTestFixture::SetHeaderInsertionTableAddEmptyHeaderForTheClient(
|
|
enum ipa_client_type nClientType)
|
|
{
|
|
//TODO Header Removal: add header insertion data
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
// This function creates IPv4 bypass routing entry and commits it.
|
|
bool HeaderRemovalTestFixture::CreateBypassRoutingTablesIPv4(
|
|
const char * bypass0,
|
|
enum ipa_client_type nClientType)
|
|
{
|
|
struct ipa_ioc_add_rt_rule *rt_rule0 = 0;
|
|
struct ipa_rt_rule_add *rt_rule_entry;
|
|
|
|
LOG_MSG_INFO("Entering");
|
|
|
|
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_INFO("calloc failed to allocate rt_rule0");
|
|
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 = nClientType;
|
|
// rt_rule_entry->rule.hdr_hdl = hdr_entry->hdr_hdl; // gidons, there is no support for header insertion / removal yet.
|
|
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_INFO("Routing rule addition(rt_rule0) failed!");
|
|
Free (rt_rule0);
|
|
return false;
|
|
}
|
|
|
|
Free (rt_rule0);
|
|
LOG_MSG_INFO("Leaving ");
|
|
return true;
|
|
}
|
|
|
|
bool HeaderRemovalTestFixture::ConfigureFilteringBlockWithMetaDataEq(
|
|
enum ipa_client_type nClientType,
|
|
unsigned int nMetaData,
|
|
unsigned int nMetaDataMask)
|
|
{
|
|
const char bypass0[20] = "Bypass0";
|
|
struct ipa_ioc_get_rt_tbl routing_table0;
|
|
IPAFilteringTable FilterTable0;
|
|
struct ipa_flt_rule_add flt_rule_entry;
|
|
|
|
LOG_MSG_INFO("Entering ");
|
|
|
|
if (!CreateBypassRoutingTablesIPv4(
|
|
HeaderRemovalTestFixture_bypass0,
|
|
nClientType)) {
|
|
LOG_MSG_INFO("CreateBypassRoutingTablesIPv4 Failed");
|
|
return false;
|
|
}
|
|
|
|
LOG_MSG_INFO("CreateBypassRoutingTablesIPv4 completed successfully");
|
|
routing_table0.ip = IPA_IP_v4;
|
|
strlcpy(routing_table0.name, bypass0, sizeof(routing_table0.name));
|
|
if (!m_routing.GetRoutingTable(&routing_table0)) {
|
|
LOG_MSG_INFO(
|
|
"m_routing.GetRoutingTable(&routing_table0=0x%p) Failed."
|
|
,&routing_table0);
|
|
return false;
|
|
}
|
|
|
|
FilterTable0.Init(IPA_IP_v4, IPA_CLIENT_TEST2_PROD, false, 1);
|
|
|
|
LOG_MSG_INFO("FilterTable*.Init Completed Successfully..");
|
|
|
|
// 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_ROUTING;
|
|
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_META_DATA;
|
|
flt_rule_entry.rule.attrib.meta_data = nMetaData;
|
|
flt_rule_entry.rule.attrib.meta_data_mask = nMetaDataMask;
|
|
if ( (-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) ||
|
|
!m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()))
|
|
{
|
|
LOG_MSG_INFO ("%s::Error Adding RuleTable(0) to Filtering, aborting...");
|
|
return false;
|
|
} else {
|
|
LOG_MSG_INFO("flt rule hdl0=0x%x, status=0x%x", FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl,FilterTable0.ReadRuleFromTable(0)->status);
|
|
}
|
|
|
|
LOG_MSG_INFO("Leaving ");
|
|
|
|
return true;
|
|
}
|