ipa: Move kernel-tests from ip_accelerator to techpack.

Move ip_accelerator which is a part of kernel-tests-internal
from kernel to techpack. Updated up to SHA1:
b8790774643dbfea5b312ed422ef86b54e4c8d7f

The kernel-test-module was moved into the driver,
and will be compiled as part of debug build.

Change-Id: I427b9ea061401c74845d2bd0d505da747d5fe89f
Acked-by: Eliad Ben Yishay <ebenyish@qti.qualcomm.com>
Signed-off-by: Amir Levy <alevy@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
This commit is contained in:
Ilia Lin
2021-05-04 15:55:34 +03:00
committed by Gerrit - the friendly Code Review server
parent 5faad0ab9e
commit f1c1fb3a16
80 changed files with 47608 additions and 2 deletions

View File

@@ -1,2 +1,3 @@
export CONFIG_IPA_DEBUG=y export CONFIG_IPA_DEBUG=y
export CONFIG_IPA_UT=y export CONFIG_IPA_UT=y
export CONFIG_IPA_KERNEL_TESTS_MODULE=y

View File

@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2020, The Linux Foundation. All rights reserved. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/ */
#define CONFIG_IPA_DEBUG 1 #define CONFIG_IPA_DEBUG 1
#define CONFIG_IPA_UT 1 #define CONFIG_IPA_UT 1
#define CONFIG_IPA_KERNEL_TESTS_MODULE 1

View File

@@ -52,6 +52,9 @@ LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa
LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa/ipa_v3 LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa/ipa_v3
LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa/ipa_v3/ipahal LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa/ipa_v3/ipahal
LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa/ipa_clients LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa/ipa_clients
ifneq (,$(filter $(CONFIG_IPA_KERNEL_TESTS_MODULE),y m))
LINUXINCLUDE += -I$(DATAIPADRVTOP)/ipa/ipa_test_module
endif
endif endif
ifneq (,$(filter $(CONFIG_IPA3_REGDUMP),y m)) ifneq (,$(filter $(CONFIG_IPA3_REGDUMP),y m))

View File

@@ -49,10 +49,15 @@ ipam-$(CONFIG_IPA_UT) += test/ipa_ut_framework.o test/ipa_test_example.o \
test/ipa_test_hw_stats.o test/ipa_pm_ut.o \ test/ipa_test_hw_stats.o test/ipa_pm_ut.o \
test/ipa_test_wdi3.o test/ipa_test_wdi3.o
ipatestm-$(CONFIG_IPA_KERNEL_TESTS_MODULE) += \
ipa_test_module/ipa_test_module_impl.o \
ipa_test_module/ipa_rm_ut.o
ipanetm-y += ipa_v3/ipa_net.o ipanetm-y += ipa_v3/ipa_net.o
obj-$(CONFIG_IPA3) += ipam.o obj-$(CONFIG_IPA3) += ipam.o
obj-$(CONFIG_IPA3) += ipanetm.o obj-$(CONFIG_IPA3) += ipanetm.o
obj-$(CONFIG_IPA_KERNEL_TESTS_MODULE) += ipatestm.o
obj-y += ipa_v3/ ipa_clients/ obj-y += ipa_v3/ ipa_clients/

View File

@@ -0,0 +1,404 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*/
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/ipa.h>
#include <linux/msm_ipa.h>
#include <linux/kernel.h>
#include "ipa_rm_ut.h"
#define IPA_UT_DBG(x...) pr_err(x)
/**
* enum ut_wq_cmd - workqueue commands
*/
enum ut_wq_cmd {
UT_WQ_REQ,
UT_WQ_REL
};
/**
* struct ipa_rm_ut_wq_work_type - IPA RM worqueue specific
* work type
* @work: work struct
* @wq_cmd: command that should be processed in workqueue context
* @resource_name: name of the resource on which this work
* should be done
* @dep_graph: data structure to search for resource if exists
* @event: event to notify
*/
struct ipa_rm_ut_wq_work_type {
struct work_struct work;
enum ut_wq_cmd wq_cmd;
enum ipa_rm_resource_name resource_name;
enum ipa_rm_event event;
};
static struct {
int (*add_dependency)(enum ipa_rm_resource_name
dependant_name,
enum ipa_rm_resource_name
dependency_name);
int (*resource_request)(enum ipa_rm_resource_name resource_name);
int (*resource_release)(enum ipa_rm_resource_name resource_name);
int (*consumer_cb)(enum ipa_rm_event,
enum ipa_rm_resource_name resource_name);
struct workqueue_struct *wq;
} ipa_rm_ut_cb;
struct device_manager_type {
void *user_data;
ipa_rm_notify_cb notify_cb;
int (*release_function)(void);
int (*request_function)(void);
};
static void ipa_ut_wq_handler(struct work_struct *work);
int ipa_ut_wq_send_cmd(enum ut_wq_cmd wq_cmd,
enum ipa_rm_resource_name resource_name,
enum ipa_rm_event event);
static int usb_mgr_release_function(void);
static int usb_mgr_request_function(void);
static void usb_mgr_notify_function(void *user_data,
enum ipa_rm_event event,
unsigned long data);
static struct device_manager_type usb_device_manager = {
NULL,
usb_mgr_notify_function,
usb_mgr_release_function,
usb_mgr_request_function
};
/* USB device manager */
static int usb_mgr_release_function(void)
{
IPA_UT_DBG("USB Released\n");
IPA_UT_DBG("ASYNC CALL USB calling to IPA RM provided CB\n");
ipa_ut_wq_send_cmd(UT_WQ_REL,
IPA_RM_RESOURCE_USB_CONS,
IPA_RM_RESOURCE_RELEASED);
return -EINPROGRESS;
}
static int usb_mgr_request_function(void)
{
IPA_UT_DBG("USB Requested\n");
IPA_UT_DBG("ASYNC CALL USB calling to IPA RM provided CB\n");
ipa_ut_wq_send_cmd(UT_WQ_REQ,
IPA_RM_RESOURCE_USB_CONS,
IPA_RM_RESOURCE_GRANTED);
return -EINPROGRESS;
}
static void usb_mgr_notify_function(void *notify_cb_data,
enum ipa_rm_event event,
unsigned long data)
{
IPA_UT_DBG("USB got event [%d]\n", event);
}
/* HSIC device manager */
static int hsic_mgr_release_function(void)
{
int result = 0;
IPA_UT_DBG("HSIC Released\n");
IPA_UT_DBG("HSIC calling to IPA RM provided CB\n");
result = ipa_rm_ut_cb.consumer_cb(IPA_RM_RESOURCE_RELEASED,
IPA_RM_RESOURCE_HSIC_CONS);
return -EINPROGRESS;
}
static int hsic_mgr_request_function(void)
{
int result = 0;
IPA_UT_DBG("HSIC Requested\n");
IPA_UT_DBG("HSIC calling to IPA RM provided CB\n");
result = ipa_rm_ut_cb.consumer_cb(IPA_RM_RESOURCE_GRANTED,
IPA_RM_RESOURCE_HSIC_CONS);
return -EINPROGRESS;
}
static void hsic_notify_function(void *notify_cb_data,
enum ipa_rm_event event,
unsigned long data)
{
IPA_UT_DBG("HSIC got event [%d]\n", event);
}
static struct device_manager_type hsic_device_manager = {
NULL,
hsic_notify_function,
hsic_mgr_release_function,
hsic_mgr_request_function
};
static void rmnet_bridge_mgr_notify_function
(void *notify_cb_data,
enum ipa_rm_event event,
unsigned long data)
{
IPA_UT_DBG("RmNet got event [%d]\n", event);
}
static struct device_manager_type rmnet_bridge_device_manager = {
NULL,
rmnet_bridge_mgr_notify_function,
NULL,
NULL
};
static void ipa_ut_wq_handler(struct work_struct *work)
{
enum ut_wq_cmd ut_cmd;
struct ipa_rm_ut_wq_work_type *ipa_rm_work =
(struct ipa_rm_ut_wq_work_type *)work;
if (!ipa_rm_work)
return;
ut_cmd = (enum ut_wq_cmd)ipa_rm_work->wq_cmd;
IPA_UT_DBG("***UT CMD Q command [%d]\n", ut_cmd);
switch (ut_cmd) {
case UT_WQ_REQ:
switch (ipa_rm_work->resource_name) {
case IPA_RM_RESOURCE_USB_CONS:
IPA_UT_DBG
("***calling to USB consumer notify request CB\n");
ipa_rm_ut_cb.consumer_cb(IPA_RM_RESOURCE_GRANTED,
IPA_RM_RESOURCE_USB_CONS);
break;
case IPA_RM_RESOURCE_HSIC_CONS:
break;
default:
return;
}
break;
case UT_WQ_REL:
switch (ipa_rm_work->resource_name) {
case IPA_RM_RESOURCE_USB_CONS:
IPA_UT_DBG
("***calling to USB consumer notify release CB\n");
ipa_rm_ut_cb.consumer_cb(IPA_RM_RESOURCE_RELEASED,
IPA_RM_RESOURCE_USB_CONS);
break;
case IPA_RM_RESOURCE_HSIC_CONS:
break;
default:
return;
}
break;
default:
break;
}
kfree((void *) work);
}
int ipa_ut_wq_send_cmd(enum ut_wq_cmd wq_cmd,
enum ipa_rm_resource_name resource_name,
enum ipa_rm_event event)
{
int result = 0;
struct ipa_rm_ut_wq_work_type *work =
(struct ipa_rm_ut_wq_work_type *)
kzalloc(sizeof(*work), GFP_KERNEL);
if (work) {
INIT_WORK((struct work_struct *)work, ipa_ut_wq_handler);
work->wq_cmd = (enum ut_wq_cmd) wq_cmd;
work->resource_name = resource_name;
work->event = event;
result = queue_work(ipa_rm_ut_cb.wq,
(struct work_struct *)work);
} else {
result = -ENOMEM;
}
return result;
}
/**
* build_rmnet_bridge_use_case_graph() - simulate resource creation
*
* @create_resource: create resource function provided by ipa_rm
* unit under test
* @consumer_cb: consumer CB function provided by ipa_rm
* unit under test
*
* Returns: 0 on success, negative on failure
*/
int build_rmnet_bridge_use_case_graph(
int (*create_resource)
(struct ipa_rm_create_params *create_params),
int (*consumer_cb)(enum ipa_rm_event event,
enum ipa_rm_resource_name resource_name))
{
int result = 0;
struct ipa_rm_create_params create_params = {0};
IPA_UT_DBG("build_rmnet_bridge_use_case_graph ENTER\n");
ipa_rm_ut_cb.consumer_cb = consumer_cb;
/* create USB PROD */
create_params.name = IPA_RM_RESOURCE_USB_PROD;
create_params.reg_params.notify_cb =
usb_device_manager.notify_cb;
create_params.reg_params.user_data =
usb_device_manager.user_data;
result = create_resource(&create_params);
if (result)
goto bail;
/* create USB CONS */
create_params.name = IPA_RM_RESOURCE_USB_CONS;
create_params.release_resource =
usb_device_manager.release_function;
create_params.request_resource =
usb_device_manager.request_function;
result = create_resource(&create_params);
if (result)
goto bail;
/* create HSIC PROD */
create_params.name = IPA_RM_RESOURCE_HSIC_PROD;
create_params.reg_params.notify_cb =
hsic_device_manager.notify_cb;
create_params.reg_params.user_data =
hsic_device_manager.user_data;
result = create_resource(&create_params);
if (result)
goto bail;
/* create HSIC CONS */
create_params.name = IPA_RM_RESOURCE_HSIC_CONS;
create_params.release_resource =
hsic_device_manager.release_function;
create_params.request_resource =
hsic_device_manager.request_function;
result = create_resource(&create_params);
if (result)
goto bail;
/* BRIDGE PROD */
create_params.name = IPA_RM_RESOURCE_WWAN_0_PROD;
create_params.reg_params.notify_cb =
rmnet_bridge_device_manager.notify_cb;
create_params.reg_params.user_data =
rmnet_bridge_device_manager.user_data;
result = create_resource(&create_params);
if (result)
goto bail;
ipa_rm_ut_cb.wq = create_singlethread_workqueue("ut_wq");
if (!ipa_rm_ut_cb.wq) {
result = -ENOMEM;
goto bail;
}
IPA_UT_DBG("build_rmnet_bridge_use_case_graph EXIT SUCCESS\n");
bail:
return result;
}
/**
* build_rmnet_bridge_use_case_dependencies() - simulate build
* dependency graph process
* @add_dependency: add dependency function provided by ipa_rm
* unit under test
*
* Returns: 0 on success, negative on failure
*/
int build_rmnet_bridge_use_case_dependencies(
int (*add_dependency)
(enum ipa_rm_resource_name dependant_name,
enum ipa_rm_resource_name dependency_name))
{
int result = 0;
IPA_UT_DBG("build_rmnet_bridge_use_case_dependencies ENTER\n");
ipa_rm_ut_cb.add_dependency = add_dependency;
result = add_dependency(IPA_RM_RESOURCE_USB_PROD,
IPA_RM_RESOURCE_HSIC_CONS);
if (result)
goto bail;
result = add_dependency(IPA_RM_RESOURCE_HSIC_PROD,
IPA_RM_RESOURCE_USB_CONS);
if (result)
goto bail;
result = add_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
IPA_RM_RESOURCE_HSIC_CONS);
if (result)
goto bail;
result = add_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
IPA_RM_RESOURCE_USB_CONS);
if (result)
goto bail;
bail:
IPA_UT_DBG(
"build_rmnet_bridge_use_case_dependencies EXIT result [%d]\n",
result);
return result;
}
/**
* request_release_resource_sequence() - simulate request / release
* resource sequence
* @resource_request: request resource function provided by ipa_rm
* unit under test
* @resource_release: release resource function provided by ipa_rm
* unit under test
*
* Returns: 0 on success, negative on failure
*/
int request_release_resource_sequence(
int (*resource_request)
(enum ipa_rm_resource_name resource_name),
int (*resource_release)
(enum ipa_rm_resource_name resource_name))
{
int result = 0;
ipa_rm_ut_cb.resource_request = resource_request;
ipa_rm_ut_cb.resource_release = resource_release;
IPA_UT_DBG("request_release_resource_sequence ENTER\n");
result = resource_request(IPA_RM_RESOURCE_USB_PROD);
IPA_UT_DBG("result [%d]\n", result);
result = resource_request(IPA_RM_RESOURCE_HSIC_PROD);
IPA_UT_DBG("result [%d]\n", result);
result = resource_release(IPA_RM_RESOURCE_USB_PROD);
IPA_UT_DBG("result [%d]\n", result);
result = resource_release(IPA_RM_RESOURCE_HSIC_PROD);
IPA_UT_DBG("result [%d]\n", result);
IPA_UT_DBG("request_release_resource_sequence EXIT SUCCESS\n");
return result;
}
/**
* clean_ut() - free unit test module resources
*
*/
void clean_ut(void)
{
IPA_UT_DBG("clean_ut ENTER\n");
if (ipa_rm_ut_cb.wq)
destroy_workqueue(ipa_rm_ut_cb.wq);
IPA_UT_DBG("clean_ut EXIT SUCCESS\n");
}

View File

@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*/
#ifndef _IPA_RM_UT_H_
#define _IPA_RM_UT_H_
/**
* ipa_rm_ut - unit test module
* Defines sanity test scenarios executed from debugfs
* writer function defined in ipa_rm module
*/
#include <linux/msm_ipa.h>
#include <linux/ipa.h>
int build_rmnet_bridge_use_case_graph(
int (*create_resource)(struct ipa_rm_create_params *create_params),
int (*consumer_cb)(enum ipa_rm_event event,
enum ipa_rm_resource_name resource_name));
int build_rmnet_bridge_use_case_dependencies(
int (*add_dependency)(enum ipa_rm_resource_name dependant_name,
enum ipa_rm_resource_name dependency_name));
int request_release_resource_sequence(
int (*resource_request)(enum ipa_rm_resource_name resource_name),
int (*resource_release)(enum ipa_rm_resource_name resource_name));
void clean_ut(void);
#endif /* _IPA_RM_UT_H_ */

View File

@@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2018,2020, The Linux Foundation. All rights reserved.
*/
#ifndef _IPA_TEST_MODULE_H_
#define _IPA_TEST_MODULE_H_
#include <stddef.h>
#include <linux/msm_ipa.h>
#include <linux/ioctl.h>
#ifdef _KERNEL_
#include <linux/ipa.h>
#endif
#define IPA_TEST_IOC_MAGIC 0xA5
enum {
IPA_TEST_IOCTL_GET_HW_TYPE = 1,
IPA_TEST_IOCTL_CONFIGURE,
IPA_TEST_IOCTL_CLEAN,
IPA_TEST_IOCTL_EP_CTRL,
IPA_TEST_IOCTL_REG_SUSPEND_HNDL,
IPA_TEST_IOCTL_HOLB_CONFIG,
IPA_TEST_IOCTL_NUM,
};
#define IPA_TEST_IOC_GET_HW_TYPE _IO(IPA_TEST_IOC_MAGIC, \
IPA_TEST_IOCTL_GET_HW_TYPE)
#define IPA_TEST_IOC_CONFIGURE _IOWR(IPA_TEST_IOC_MAGIC, \
IPA_TEST_IOCTL_CONFIGURE, \
struct ipa_test_config_header *)
#define IPA_TEST_IOC_CLEAN _IO(IPA_TEST_IOC_MAGIC, \
IPA_TEST_IOCTL_CLEAN)
#define IPA_TEST_IOC_EP_CTRL _IOWR(IPA_TEST_IOC_MAGIC, \
IPA_TEST_IOCTL_EP_CTRL, \
struct ipa_test_ep_ctrl *)
#define IPA_TEST_IOC_REG_SUSPEND_HNDL _IOWR(IPA_TEST_IOC_MAGIC, \
IPA_TEST_IOCTL_REG_SUSPEND_HNDL, \
struct ipa_test_reg_suspend_handler *)
#define IPA_TEST_IOC_HOLB_CONFIG _IOWR(IPA_TEST_IOC_MAGIC, \
IPA_TEST_IOCTL_HOLB_CONFIG, \
struct handle_holb_config_ioctl *)
#define IPA_TEST_CONFIG_MARKER 0x57
#define IPA_TEST_CHANNEL_CONFIG_MARKER 0x83
/*
* This is the configuration number that is saved for Generic configuration
* we need it in order to allow coexistence of Generic
* configured tests with old fashion tests
*/
#define GENERIC_TEST_CONFIGURATION_IDX 37788239
struct ipa_test_config_header
{
unsigned char head_marker; /* IPA_TEST_CONFIG_MARKER */
int to_ipa_channels_num;
struct ipa_channel_config **to_ipa_channel_config;
int from_ipa_channels_num;
struct ipa_channel_config **from_ipa_channel_config;
unsigned char tail_marker; /* IPA_TEST_CONFIG_MARKER */
};
struct ipa_test_en_status
{
int num_clients;
enum ipa_client_type *clients;
};
struct ipa_test_ep_ctrl
{
bool ipa_ep_suspend;
bool ipa_ep_delay;
int from_dev_num;
};
struct ipa_test_reg_suspend_handler
{
int DevNum;
bool reg;
bool deferred_flag;
};
struct ipa_channel_config
{
unsigned char head_marker; /* IPA_TEST_CHANNEL_CONFIG_MARKER */
enum ipa_client_type client;
int index; /* shall be used for to_ipa_x or from_ipa_x */
size_t config_size;
void *cfg;
bool en_status;
unsigned char tail_marker; /* IPA_TEST_CHANNEL_CONFIG_MARKER */
};
struct ipa_test_holb_config
{
enum ipa_client_type client;
unsigned tmr_val;
unsigned short en;
};
#endif /* _IPA_TEST_MODULE_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -2932,6 +2932,14 @@ bool ipa3_get_lan_rx_napi(void);
bool ipa3_get_qmap_pipe_enable(void); bool ipa3_get_qmap_pipe_enable(void);
struct device *ipa3_get_pdev(void);
int ipa3_sys_update_gsi_hdls(u32 clnt_hdl, unsigned long gsi_ch_hdl,
unsigned long gsi_ev_hdl);
int ipa3_sys_setup(struct ipa_sys_connect_params *sys_in,
unsigned long *ipa_transport_hdl,
u32 *ipa_pipe_num, u32 *clnt_hdl, bool en_status);
int ipa3_sys_teardown(u32 clnt_hdl);
/* internal functions */ /* internal functions */
u8 ipa3_get_hw_type_index(void); u8 ipa3_get_hw_type_index(void);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
*/ */
#include <linux/bitops.h> #include <linux/bitops.h>
@@ -2108,6 +2108,7 @@ ret:
return result; return result;
} }
EXPORT_SYMBOL(ipa3_get_rt_tbl);
/** /**
* ipa3_put_rt_tbl() - Release the specified routing table handle * ipa3_put_rt_tbl() - Release the specified routing table handle

395
kernel-tests/Constants.h Normal file
View File

@@ -0,0 +1,395 @@
/*
* Copyright (c) 2017,2019 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.
*/
#ifndef CONSTANTS_H_
#define CONSTANTS_H_
#include <stdlib.h>
#include <stdio.h>
#define PRE_PHASE_ZERO_TEST_CONFIGURATION 0
/*----------------------------------------------------------------------
*Configuration 1 (see configure_system_1 )
*-----USB_PROD--->[IPA DMA]----USB_CONS--->
*----------------------------------------------------------------------
*/
#define PHASE_ZERO_TEST_CONFIGURATION 1
/*----------------------------------------------------------------------
*Configuration 2 (see configure_system_2 )
* [IPA]----USB2_CONS-->
*-----USB_PROD--->[IPA]----USB3_CONS--->
* [IPA]----USB4_CONS--->
*----------------------------------------------------------------------
*/
#define PHASE_TWO_TEST_CONFIGURATION 2
/*----------------------------------------------------------------------
*Configuration 3 (see configure_system_3 )
* [IPA]----USB_CONS------>
*-----USB2_PROD--->[IPA]----USB2_CONS--->
* [IPA]----USB4_CONS---->
*----------------------------------------------------------------------
*/
#define PHASE_THREE_TEST_CONFIGURATION 3
/*Configuration 5 (see configure_system_5 )
* [IPA]----USB2_CONS + Header Insertion (6Bytes) -->
*-----USB_PROD--->[IPA]----USB3_CONS +
*Header Insertion (22Bytes) + Length offset (11Bytes) -->
* [IPA]----USB4_CONS +
*Header Insertion (22Bytes) + Length offset (11Bytes) + Const(1Byte)-->
*/
/* This Cfg is only for USB Integration Phase I*/
#define PHASE_FIVE_TEST_CONFIGURATION 5
#define PHASE_SIX_TEST_CONFIGURATION 6
/*Configuration 7 (see configure_system_7 )
* [IPA]----USB2_CONS-->
*-----USB_PROD--->[IPA]----USB3_CONS--->
* [IPA]----USB4_CONS--->
* [IPA]----A5 - Exception Pipe--->
*/
#define PHASE_SEVEN_TEST_CONFIGURATION 7
/*----------------------------------------------------------------------
*Configuration 8 (see configure_system_8 )
*-----USB3_CONS--->[IPA DMA]----USB_CONS (TLP aggregation byte limit)--->
*-----USB_PROD (TLP deaggregation)--->[IPA DMA]----USB3_CONS--->
*-----USB2_PROD (TLP deaggregation)--->
*-----[IPA DMA]----USB_CONS (TLP aggregation byte limit)--->
*-----USB4_PROD--->[IPA DMA]----USB2_CONS (TLP aggregation time limit)--->
*----------------------------------------------------------------------
*/
#define PHASE_EIGHT_TEST_CONFIGURATION 8
/*----------------------------------------------------------------------
*Configuration 9 (see configure_system_9 )
*-----USB3_PROD--->[IPA DMA]----USB_CONS (MBIM aggregation byte limit)--->
*-----USB_PROD (MBIM deaggregation)--->[IPA DMA]----USB3_CONS--->
*-----USB2_PROD (MBIM deaggregation)--->
*-----[IPA DMA]----USB_CONS (MBIM aggregation byte limit)--->
*-----USB4_PROD--->[IPA DMA]----USB2_CONS (MBIM aggregation time limit)--->
*----------------------------------------------------------------------
*/
#define PHASE_NINE_TEST_CONFIGURATION 9
/*----------------------------------------------------------------------
*Configuration 10 (see configure_system_10 )
*-----USB_PROD--->[IPA DMA]----USB_CONS (MBIM aggregation no limits)--->
*----------------------------------------------------------------------
*/
#define PHASE_TEN_TEST_CONFIGURATION 10
/*----------------------------------------------------------------------
*Configuration 11 (see configure_system_11 )
*-----USB_PROD----->[IPA]----
* USB2_CONS(MBIM aggregation byte limit)--->
*-USB2_PROD (MBIM deaggregation)->[IPA]----USB3_CONS--->
*------------------>[IPA]----
*USB_CONS (MBIM aggregation time limit)----------->
*------------------>[IPA]----
*A5_LAN_WAN_CONS (MBIM aggregation no limits)---->
*----------------------------------------------------------------------
*/
#define PHASE_ELEVEN_TEST_CONFIGURATION 11
/*----------------------------------------------------------------------
*Configuration 12 (see configure_system_12 )
*-----USB_PROD----->[IPA]----USB2_CONS (MBIM aggregation byte limit)--->
*-USB2_PROD (MBIM deaggregation)->[IPA]----USB3_CONS--->
*------------------>[IPA]----
* USB_CONS (MBIM aggregation time limit)----------->
*------------------>[IPA]----
* A5_LAN_WAN_CONS (MBIM aggregation no limits)---->
*----------------------------------------------------------------------
*/
#define PHASE_TWELVE_TEST_CONFIGURATION 12
/*----------------------------------------------------------------------
*Configuration 9 (see configure_system_17 )
*-----USB3_PROD--->[IPA DMA]----USB_CONS (RNDIS aggregation byte limit)--->
*-----USB_PROD (RNDIS deaggregation)--->[IPA DMA]----USB3_CONS--->
*-----USB2_PROD (RNDIS deaggregation)--->
*-----[IPA DMA]----USB_CONS (RNDIS aggregation byte limit)--->
*-----USB4--->[IPA DMA]----USB2_CONS (RNDIS aggregation time limit)--->
*----------------------------------------------------------------------
*/
#define PHASE_SEVENTEEN_TEST_CONFIGURATION 17
/*
* Data path test
*/
#define PHASE_EIGHTEEN_TEST_CONFIGURATION 18
/*----------------------------------------------------------------------
*Configuration 19 (see configure_system_19 )
*-----USB_PROD--->[IPA DMA]----USB_CONS--->
*-----suspend [IPA DMA]----USB_CONS (for testing suspend interrupt)--->
*----------------------------------------------------------------------
*/
#define PHASE_NINETEEN_TEST_CONFIGURATION 19
#define PHASE_TWENTY_TEST_CONFIGURATION 20
/*----------------------------------------------------------------------
*Configuration 20 (see configure_system_20 )
*-----PROD (WLAN header removal)--------------------->[IPA]----CONS---->
*-----PROD (RNDIS de-aggregation + Header removal)--->[IPA]
*----------------------------------------------------------------------
*/
enum IPATestConfiguration {
IPA_TEST_CONFIFURATION_0 = PRE_PHASE_ZERO_TEST_CONFIGURATION,
IPA_TEST_CONFIFURATION_1 = PHASE_ZERO_TEST_CONFIGURATION,
IPA_TEST_CONFIFURATION_2 = PHASE_TWO_TEST_CONFIGURATION,
IPA_TEST_CONFIFURATION_3 = PHASE_THREE_TEST_CONFIGURATION,
IPA_TEST_CONFIFURATION_5 = PHASE_FIVE_TEST_CONFIGURATION,
IPA_TEST_CONFIFURATION_6 = PHASE_SIX_TEST_CONFIGURATION,
IPA_TEST_CONFIFURATION_7 = PHASE_SEVEN_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_8 = PHASE_EIGHT_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_9 = PHASE_NINE_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_10 = PHASE_TEN_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_11 = PHASE_ELEVEN_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_12 = PHASE_TWELVE_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_17 = PHASE_SEVENTEEN_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_18 = PHASE_EIGHTEEN_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_19 = PHASE_NINETEEN_TEST_CONFIGURATION,
IPA_TEST_CONFIGURATION_20 = PHASE_NINETEEN_TEST_CONFIGURATION,
};
#define CONFIGURATION_NODE_PATH "/dev/ipa_test"
/*producer*/
#define INTERFACE0_TO_IPA_DATA_PATH "/dev/to_ipa_0"
#define INTERFACE0_FROM_IPA_DATA_PATH NULL
/*producer*/
#define INTERFACE4_TO_IPA_DATA_PATH "/dev/to_ipa_1"
#define INTERFACE4_FROM_IPA_DATA_PATH NULL
/*producer*/
#define INTERFACE5_TO_IPA_DATA_PATH "/dev/to_ipa_2"
#define INTERFACE5_FROM_IPA_DATA_PATH NULL
/*consumer*/
#define INTERFACE1_TO_IPA_DATA_PATH NULL
#define INTERFACE1_FROM_IPA_DATA_PATH "/dev/from_ipa_0"
/*consumer 2*/
#define INTERFACE2_TO_IPA_DATA_PATH NULL
#define INTERFACE2_FROM_IPA_DATA_PATH "/dev/from_ipa_1"
/*Default consumer*/
#define INTERFACE3_TO_IPA_DATA_PATH NULL
#define INTERFACE3_FROM_IPA_DATA_PATH "/dev/from_ipa_2"
/*Exceptions producer*/
#define INTERFACE_TO_IPA_EXCEPTION_PATH NULL
#define INTERFACE_FROM_IPA_EXCEPTION_PATH "/dev/ipa_exception_pipe"
/*The next configuration should be used by the ITAKEM as well.*/
/*----------------------------------------------------------------------
*Configuration 1 (see configure_system_1 )
*-----USB_PROD--->[IPA DMA]----USB_CONS--->
*----------------------------------------------------------------------
*/
#define CONFIG_1_FROM_USB1_TO_IPA_DMA "/dev/to_ipa_0"
#define CONFIG_1_FROM_IPA_TO_USB1_DMA "/dev/from_ipa_0"
/*----------------------------------------------------------------------
*Configuration 2 (see configure_system_2 )
* [IPA]----USB2_CONS-->
*-----USB_PROD--->[IPA]----USB3_CONS--->
* [IPA]----Q6_LAN_CONS--->
*---------------------------------------------------------------------
*/
#define CONFIG_2_FROM_USB_TO_IPA "/dev/to_ipa_0"
#define CONFIG_2_FROM_IPA_TO_A2_NDUN "/dev/from_ipa_0"
#define CONFIG_2_FROM_IPA_TO_A2_DUN "/dev/from_ipa_1"
#define CONFIG_2_FROM_IPA_TO_Q6_LAN "/dev/from_ipa_2"
/*USB1 is an EthernetII Client*/
#define FROM_USB1_TO_IPA "/dev/to_ipa_0"
#define FROM_IPA_TO_USB1 "/dev/from_ipa_0"
#define USB1_CLIENT_HEADER_LENGTH 14
/*----------------------------------------------------------------------
*Configuration 3 (see configure_system_3 )
* [IPA]----USB_CONS------>
*-----USB2_PROD--->[IPA]----USB2_CONS--->
* [IPA]----Q6_LAN_CONS---->
*----------------------------------------------------------------------
*/
#define CONFIG_3_FROM_A2_NDUN_TO_IPA "/dev/to_ipa_0"
#define CONFIG_3_FROM_IPA_TO_USB1 "/dev/from_ipa_0"
#define CONFIG_3_FROM_IPA_TO_A2_NDUN "/dev/from_ipa_1"
#define CONFIG_3_FROM_IPA_TO_Q6_LAN "/dev/from_ipa_2"
/*----------------------------------------------------------------------
*Configuration 8 (see configure_system_8 )
*-----USB3_PROD--->[IPA DMA]----
*-----USB_CONS (TLP aggregation byte limit)--->
*-----USB_PROD (TLP deaggregation)--->[IPA DMA]----USB3_CONS--->
*-----USB2_PROD (TLP deaggregation)--->
* [IPA DMA]----USB_CONS (TLP aggregation byte limit)--->
*-----USB4--->[IPA DMA]----USB2_CONS (TLP aggregation time limit)--->
*----------------------------------------------------------------------
*/
#define CONFIG_8_NO_AGG_TO_IPA_AGG "/dev/to_ipa_0"
#define CONFIG_8_DEAGG_TO_IPA_NO_AGG "/dev/to_ipa_1"
#define CONFIG_8_DEAGG_TO_IPA_AGG "/dev/to_ipa_2"
#define CONFIG_8_NO_AGG_TO_IPA_AGG_TIME "/dev/to_ipa_3"
#define CONFIG_8_FROM_IPA_AGG "/dev/from_ipa_0"
#define CONFIG_8_FROM_IPA_NO_AGG "/dev/from_ipa_1"
#define CONFIG_8_DEAGG_FROM_IPA_AGG "/dev/from_ipa_2"
/*----------------------------------------------------------------------
*Configuration 9 (see configure_system_9 )
*-----USB3_PROD--->[IPA DMA]----
* USB_CONS (MBIM aggregation byte limit)--->
*-----USB_PROD (MBIM deaggregation)--->[IPA DMA]----USB3_CONS--->
*-----USB2_PROD (MBIM deaggregation)--->
* [IPA DMA]----USB_CONS (MBIM aggregation byte limit)--->
*-----USB4--->[IPA DMA]----
* USB2_CONS (MBIM aggregation time limit)--->
*----------------------------------------------------------------------
*/
#define CONFIG_9_NO_AGG_TO_IPA_AGG "/dev/to_ipa_0"
#define CONFIG_9_DEAGG_TO_IPA_NO_AGG "/dev/to_ipa_1"
#define CONFIG_9_DEAGG_TO_IPA_AGG "/dev/to_ipa_2"
#define CONFIG_9_NO_AGG_TO_IPA_AGG_TIME "/dev/to_ipa_3"
#define CONFIG_9_FROM_IPA_AGG "/dev/from_ipa_0"
#define CONFIG_9_FROM_IPA_NO_AGG "/dev/from_ipa_1"
#define CONFIG_9_DEAGG_FROM_IPA_AGG "/dev/from_ipa_2"
/*----------------------------------------------------------------------
*Configuration 10 (see configure_system_10 )
*-----USB_PROD--->[IPA DMA]----
* USB_CONS (MBIM aggregation no limits)--->
*----------------------------------------------------------------------
*/
#define CONFIG_10_TO_IPA_AGG_ZERO_LIMITS "/dev/to_ipa_0"
#define CONFIG_10_FROM_IPA_AGG_ZERO_LIMITS "/dev/from_ipa_0"
/*----------------------------------------------------------------------
*Configuration 11 (see configure_system_11 )
*-----USB_PROD----->[IPA]----
* USB2_CONS (MBIM aggregation byte limit)--->
* USB2_PROD (MBIM deaggregation)->[IPA]----USB3_CONS--->
*------------------>[IPA]----
* USB_CONS (MBIM aggregation time limit)----------->
*------------------>[IPA
* A5_LAN_WAN_CONS (MBIM aggregation no limits)---->
*----------------------------------------------------------------------
*/
#define CONFIG_11_TO_IPA "/dev/to_ipa_0"
#define CONFIG_11_TO_IPA_DEAGG "/dev/to_ipa_1"
#define CONFIG_11_FROM_IPA_AGG "/dev/from_ipa_0"
#define CONFIG_11_FROM_IPA "/dev/from_ipa_1"
#define CONFIG_11_FROM_IPA_AGG_TIME "/dev/from_ipa_2"
#define CONFIG_11_FROM_IPA_ZERO_LIMITS "/dev/from_ipa_3"
/*----------------------------------------------------------------------
*Configuration 12 (see configure_system_12 )
*-----USB_PROD----->[IPA]----
* USB2_CONS (MBIM aggregation byte limit)--->
*-USB2_PROD (MBIM deaggregation)->[IPA]----USB3_CONS--->
*------------------>[IPA]----
* USB_CONS (MBIM aggregation time limit)----------->
*------------------>[IPA]----
* A5_LAN_WAN_CONS (MBIM aggregation no limits)---->
*----------------------------------------------------------------------
*/
#define CONFIG_12_TO_IPA "/dev/to_ipa_0"
#define CONFIG_12_TO_IPA_DEAGG "/dev/to_ipa_1"
#define CONFIG_12_FROM_IPA_AGG "/dev/from_ipa_0"
#define CONFIG_12_FROM_IPA "/dev/from_ipa_1"
#define CONFIG_12_FROM_IPA_AGG_TIME "/dev/from_ipa_2"
#define CONFIG_12_FROM_IPA_ZERO_LIMITS "/dev/from_ipa_3"
/*Configuration 7 (see configure_system_7 )
* [IPA]----USB2_CONS-->
*-----USB_PROD--->[IPA]----USB3_CONS--->
* [IPA]----Q6_LAN_CONS--->
* [IPA]----A5 - Exception Pipe--->
*/
#define CONFIG_7_FROM_USB1_TO_IPA "/dev/to_ipa_0"
#define CONFIG_7_FROM_IPA_TO_A5_EXCEPTION "/dev/ipa_exception_pipe"
/*----------------------------------------------------------------------
*Configuration 17 (see configure_system_17 )
*-----USB_PROD----->[IPA]----
* USB2_CONS (RNDIS aggregation byte limit)--->
* USB2_PROD (RNDIS deaggregation)->[IPA]----USB3_CONS--->
*------------------>[IPA]----
* USB_CONS (RNDIS aggregation time limit)----------->
*------------------>[IPA]----
* A5_LAN_WAN_CONS (RNDIS aggregation no limits)---->
*----------------------------------------------------------------------
*/
#define CONFIG_17_TO_IPA "/dev/to_ipa_0"
#define CONFIG_17_TO_IPA_NO_HDR "/dev/to_ipa_1"
#define CONFIG_17_TO_IPA_DEAGG "/dev/to_ipa_2"
#define CONFIG_17_FROM_IPA_AGG "/dev/from_ipa_0"
#define CONFIG_17_FROM_IPA "/dev/from_ipa_1"
#define CONFIG_17_FROM_IPA_AGG_TIME "/dev/from_ipa_2"
#define CONFIG_17_FROM_IPA_ZERO_LIMITS "/dev/from_ipa_3"
/*----------------------------------------------------------------------
*Configuration 18 (see configure_system_18 )---------------------------
*-----USB_PROD----->[IPA]--------------->USB_CONS--------->A5----------
*-----USB_PROD2 is a dummy endpoint handle for packet handling between-
*-----user space and kernel space in the IPA driver--------------------
*----------------------------------------------------------------------
*/
#define CONFIG_18_TO_IPA "/dev/to_ipa_0"
#define CONFIG_18_DUMMY_ENDPOINT "/dev/to_ipa_1"
#define CONFIG_18_FROM_IPA "/dev/from_ipa_0"
/*----------------------------------------------------------------------
*Configuration 19 (see configure_system_19 )
*-----USB_PROD--->[IPA DMA]----USB_CONS--->
*----------------------------------------------------------------------
*/
#define CONFIG_19_FROM_USB_TO_IPA_DMA "/dev/to_ipa_0"
#define CONFIG_19_FROM_IPA_TO_USB_DMA "/dev/from_ipa_0"
enum ipv6_ext_hdr_type {
HOP_BY_HOP_OPT = 0,
DEST_OPT = 60,
ROUTING = 43,
FRAGMENT = 44,
AH = 51,
ESP = 50,
DEST_OPT_UL = 60,
Mobility = 135,
NONE = 59
};
/*File that are being used by the test application:*/
#define IPV4_FILE_PATH "Input/IPV4_3"
/*---------------------------------------------------------------------
*XUnit tests results format file name
*----------------------------------------------------------------------
*/
#define XUNIT_REPORT_PATH_AND_NAME "junit_result.xml"
#endif /* CONSTANTS_H_ */

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2017 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 "DataPathTestFixture.h"
Pipe DataPathTestFixture::m_FromIPAPipe(IPA_CLIENT_TEST_CONS,
IPA_TEST_CONFIGURATION_18);
Pipe DataPathTestFixture::m_ToIpaPipe(IPA_CLIENT_TEST_PROD,
IPA_TEST_CONFIGURATION_18);
Pipe DataPathTestFixture::m_IpaDriverPipe(IPA_CLIENT_TEST2_PROD,
IPA_TEST_CONFIGURATION_18);
RoutingDriverWrapper DataPathTestFixture::m_Routing;
Filtering DataPathTestFixture::m_Filtering;
HeaderInsertion DataPathTestFixture::m_HeaderInsertion;
DataPathTestFixture::DataPathTestFixture()
{
m_testSuiteName.push_back("DataPath");
Register(*this);
}
bool DataPathTestFixture::Setup()
{
bool bRetVal = true;
/*Set the configuration to support USB->IPA and IPA->USB pipes.*/
ConfigureScenario(IPA_TEST_CONFIGURATION_18);
bRetVal &= m_ToIpaPipe.Init();
bRetVal &= m_FromIPAPipe.Init();
bRetVal &= m_IpaDriverPipe.Init();
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;
}
if (!m_HeaderInsertion.DeviceNodeIsOpened())
{
LOG_MSG_ERROR("Header Insertion block is not ready for immediate commands!\n");
return false;
}\
/*resetting this component will reset both Routing and Filtering tables*/
m_HeaderInsertion.Reset();
return bRetVal;
}
bool DataPathTestFixture::Teardown()
{
/*The Destroy method will close the inode.*/
m_FromIPAPipe.Destroy();
m_ToIpaPipe.Destroy();
m_IpaDriverPipe.Destroy();
return true;
}
bool DataPathTestFixture::Run()
{
LOG_MSG_DEBUG("Entering Function");
if (!TestLogic()) {
LOG_MSG_ERROR(
"Test failed, Input and expected output mismatch.");
return false;
}
LOG_MSG_DEBUG("Leaving Function (Returning True)");
return true;
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef DATAPATHTESTFIXTURE_H_
#define DATAPATHTESTFIXTURE_H_
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <linux/if_ether.h>
#include "Constants.h"
#include "Logger.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "TestBase.h"
#include "Pipe.h"
#include "RoutingDriverWrapper.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
class DataPathTestFixture:public TestBase
{
public:
/*
* This Constructor will register each instance
* that it creates.
*/
DataPathTestFixture();
/*
* This method will create and initialize two Pipe object for the USB
* (Ethernet) Pipes, one as input and the other as output.
*/
virtual bool Setup();
/*This method will destroy the pipes.*/
virtual bool Teardown();
virtual bool Run();
virtual bool TestLogic() = 0;
/*The client type are set from the peripheral perspective*/
static Pipe m_FromIPAPipe;
static Pipe m_ToIpaPipe;
static Pipe m_IpaDriverPipe;
static RoutingDriverWrapper m_Routing;
static Filtering m_Filtering;
static HeaderInsertion m_HeaderInsertion;
};
#endif /* DATAPATHTESTFIXTURE_H_ */

View File

@@ -0,0 +1,391 @@
/*
* 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 "hton.h" /* for htonl*/
#include "DataPathTestFixture.h"
#include "Constants.h"
#include "TestsUtils.h"
#include "linux/msm_ipa.h"
#define PACKET_SIZE ((10)*(4))
class IpaTxDpTest:public DataPathTestFixture {
public:
IpaTxDpTest() {
m_name = "IpaTxDpTest";
m_description = "Sending one SKB via ipa_tx_dp() and checking"
"if it was received";
m_runInRegression = true;
}
bool TestLogic() {
LOG_MSG_DEBUG("Entering %s\n", __func__);
int ret;
unsigned char *input, *output;
char pkt[PACKET_SIZE] = {
0x59, 0x61, 0x6e, 0x69,
0x76, 0x5f, 0x48 ,0x61,
0x73 ,0x62 ,0x61 ,0x6e,
0x69 ,0x5f ,0x54 ,0x68,
0x65 ,0x5f ,0x47 ,0x72,
0x65 ,0x61 ,0x74 ,0x16,
0x32 ,0x49 ,0x0c ,0x3f,
0x37 ,0x23 ,0x6d ,0x15,
0x50 ,0x10 ,0x3f ,0xbd,
0xcc ,0xd8 ,0x00, 0x00
};
input = (unsigned char *)malloc(PACKET_SIZE);
if(!input) {
LOG_MSG_ERROR("Error in allocation\n");
goto fail;
}
output = (unsigned char *)malloc(PACKET_SIZE);
if(!output) {
LOG_MSG_ERROR("Error in allocation\n");
free(input);
goto fail;
}
memcpy(input, pkt, PACKET_SIZE);
LOG_MSG_DEBUG("Sending packet through ipa_tx_dp() in func %s\n", __func__);
ret = m_IpaDriverPipe.Send(input, PACKET_SIZE);
if (ret != PACKET_SIZE) {
LOG_MSG_ERROR(
"Amount of bits sent are: %d instead of %d\nExiting..\n"
, ret
, PACKET_SIZE);
free(input);
free(output);
goto fail;
}
ret = m_FromIPAPipe.Receive(output, PACKET_SIZE);
if (ret != PACKET_SIZE) {
LOG_MSG_ERROR(
"Amount of bits sent are: %d instead of %d\nExiting..\n",
ret,
PACKET_SIZE);
free(input);
free(output);
goto fail;
}
LOG_MSG_INFO("Input buff:\n");
print_buff(input, PACKET_SIZE);
LOG_MSG_INFO("Output buff:\n");
print_buff(output, PACKET_SIZE);
if (memcmp(input,output, PACKET_SIZE)) {
free(input);
free(output);
return false;
}
free(input);
free(output);
return true;
fail:
return false;
}
};
class IpaTxDpMultipleTest:public DataPathTestFixture {
public:
IpaTxDpMultipleTest() {
m_name = "IpaTxDpMultipleTest";
m_description = "Sending multiple SKB via ipa_tx_dp() and checking"
"if it was received";
m_runInRegression = false;
}
bool TestLogic() {
int packet_to_send = 10;
int loop_size = 100;
int i;
int j;
LOG_MSG_DEBUG("Entering %s\n", __func__);
int ret;
unsigned char *input, *output;
char pkt[PACKET_SIZE] = {
0x59, 0x61, 0x6e, 0x69,
0x76, 0x5f, 0x48 ,0x61,
0x73 ,0x62 ,0x61 ,0x6e,
0x69 ,0x5f ,0x54 ,0x68,
0x65 ,0x5f ,0x47 ,0x72,
0x65 ,0x61 ,0x74 ,0x16,
0x32 ,0x49 ,0x0c ,0x3f,
0x37 ,0x23 ,0x6d ,0x15,
0x50 ,0x10 ,0x3f ,0xbd,
0xcc ,0xd8 ,0x00, 0x00
};
input = (unsigned char *)malloc(PACKET_SIZE);
if(!input) {
LOG_MSG_ERROR("Error in allocation\n");
goto fail;
}
output = (unsigned char *)malloc(PACKET_SIZE);
if(!output) {
LOG_MSG_ERROR("Error in allocation\n");
free(input);
goto fail;
}
memcpy(input, pkt, PACKET_SIZE);
for (i = 0; i < loop_size; i++) {
for (j = 0; j < packet_to_send; j++) {
input[0] = i;
input[1] = j;
LOG_MSG_DEBUG("Sending packet through ipa_tx_dp() in func %s\n", __func__);
ret = m_IpaDriverPipe.Send(input, PACKET_SIZE);
if (ret != PACKET_SIZE) {
LOG_MSG_ERROR(
"Amount of bits sent are: %d instead of %d\nExiting..\n"
, ret
, PACKET_SIZE);
free(input);
free(output);
goto fail;
}
}
for (j = 0; j < packet_to_send; j++) {
ret = m_FromIPAPipe.Receive(output, PACKET_SIZE);
if (ret != PACKET_SIZE) {
LOG_MSG_ERROR(
"Amount of bits sent are: %d instead of %d\nExiting..\n",
ret,
PACKET_SIZE);
free(input);
free(output);
goto fail;
}
input[0] = i;
input[1] = j;
LOG_MSG_INFO("Input buff:\n");
print_buff(input, PACKET_SIZE);
LOG_MSG_INFO("Output buff:\n");
print_buff(output, PACKET_SIZE);
if (memcmp(input,output, PACKET_SIZE)) {
free(input);
free(output);
LOG_MSG_ERROR("Failed in buffers comparison");
return false;
}
}
}
free(input);
free(output);
return true;
fail:
return false;
}
};
class IPAToAppsTest:public DataPathTestFixture {
public:
IPAToAppsTest() {
m_name = "IPAToApps";
m_description = "Sending one SKB via USB_PROD pipe and checking"
"if it was received";
m_runInRegression = true;
}
bool TestLogic() {
int ret;
unsigned char *input, *output;
unsigned char pkt[PACKET_SIZE] = {
0x59, 0x61, 0x6e, 0x69,
0x76, 0x5f, 0x48 ,0x61,
0x73 ,0x62 ,0x61 ,0x6e,
0x69 ,0x5f ,0x54 ,0x68,
0x65 ,0x5f ,0x47 ,0x72,
0x65 ,0x61 ,0x74 ,0x16,
0x32 ,0x49 ,0x0c ,0x3f,
0x37 ,0x23 ,0x6d ,0x15,
0x50 ,0x10 ,0x3f ,0xbd,
0xcc ,0xd8 ,0x00, 0x00
};
input = (unsigned char *)malloc(PACKET_SIZE);
if(!input) {
LOG_MSG_ERROR("Error in allocation\n");
goto fail;
}
output = (unsigned char *)malloc(PACKET_SIZE);
if(!output) {
LOG_MSG_ERROR("Error in allocation\n");
free(input);
goto fail;
}
memcpy(input, pkt, PACKET_SIZE);
LOG_MSG_DEBUG("Sending packet through USB_PROD pipe in func %s\n", __func__);
ret = m_ToIpaPipe.Send(input, PACKET_SIZE);
if (ret != PACKET_SIZE) {
LOG_MSG_ERROR(
"Amount of bits sent are: %d instead of %d\nExiting..\n",
ret,
PACKET_SIZE);
goto fail;
}
LOG_MSG_DEBUG("Reading packet through Dummy Endpoint pipe in func %s\n", __func__);
ret = m_IpaDriverPipe.Receive(output, PACKET_SIZE);
if (ret != 0) {
LOG_MSG_ERROR("Failed in reading buffer. %d error", ret);
free(input);
free(output);
goto fail;
}
LOG_MSG_DEBUG("SKB original packet:\n");
print_buff(input, PACKET_SIZE);
LOG_MSG_DEBUG("SKB received packet:\n");
print_buff(output, PACKET_SIZE);
if (memcmp(input,output, PACKET_SIZE)) {
free(input);
free(output);
return false;
}
free(input);
free(output);
return true;
fail:
return false;
}
};
class IPAToAppsMultipleTest:public DataPathTestFixture {
public:
IPAToAppsMultipleTest() {
m_name = "IPAToAppsMultipleTest";
m_description = "Sending multiple SKB via USB_PROD pipe and checking"
"if they was received";
m_runInRegression = false;
}
bool TestLogic() {
int packet_to_send = 10;
int loop_size = 100;
int i;
int j;
int ret;
unsigned char *input, *output;
unsigned char pkt[PACKET_SIZE] = {
0x59, 0x61, 0x6e, 0x69,
0x76, 0x5f, 0x48 ,0x61,
0x73 ,0x62 ,0x61 ,0x6e,
0x69 ,0x5f ,0x54 ,0x68,
0x65 ,0x5f ,0x47 ,0x72,
0x65 ,0x61 ,0x74 ,0x16,
0x32 ,0x49 ,0x0c ,0x3f,
0x37 ,0x23 ,0x6d ,0x15,
0x50 ,0x10 ,0x3f ,0xbd,
0xcc ,0xd8 ,0x00, 0x00
};
input = (unsigned char *)malloc(PACKET_SIZE);
if(!input) {
LOG_MSG_ERROR("Error in allocation\n");
goto fail;
}
output = (unsigned char *)malloc(PACKET_SIZE);
if(!output) {
LOG_MSG_ERROR("Error in allocation\n");
free(input);
goto fail;
}
memcpy(input, pkt, PACKET_SIZE);
for (i = 0; i < loop_size; i++) {
for (j = 0; j < packet_to_send; j++) {
input[0] = i;
input[1] = j;
LOG_MSG_DEBUG("Sending packet through USB_PROD pipe in func %s\n", __func__);
ret = m_ToIpaPipe.Send(input, PACKET_SIZE);
if (ret != PACKET_SIZE) {
LOG_MSG_ERROR(
"Amount of bits sent are: %d instead of %d\nExiting..\n",
ret,
PACKET_SIZE);
free(input);
free(output);
goto fail;
}
}
for (j = 0; j < packet_to_send; j++) {
input[0] = i;
input[1] = j;
LOG_MSG_DEBUG("Reading packet through Dummy Endpoint pipe in func %s\n", __func__);
ret = m_IpaDriverPipe.Receive(output, PACKET_SIZE);
if (ret != 0) {
LOG_MSG_ERROR("Failed in reading buffer. %d error", ret);
free(input);
free(output);
goto fail;
}
LOG_MSG_DEBUG("SKB original packet:\n");
print_buff(input, PACKET_SIZE);
LOG_MSG_DEBUG("SKB received packet:\n");
print_buff(output, PACKET_SIZE);
if (memcmp(input,output, PACKET_SIZE)) {
free(input);
free(output);
LOG_MSG_ERROR("Failed in buffers comparison");
return false;
}
}
}
free(input);
free(output);
return true;
fail:
return false;
}
};
static IpaTxDpTest ipaTxDpTest;
static IpaTxDpMultipleTest ipaTxDpMultipleTest;
static IPAToAppsTest ipaToApps;
static IPAToAppsMultipleTest iPAToAppsMultipleTestApps;

View File

@@ -0,0 +1,472 @@
/*
* Copyright (c) 2017 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 "TestsUtils.h"
#include "RoutingDriverWrapper.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
#include <string.h>
using namespace IPA;
class IPAExceptionTestFixture: public TestBase {
public:
IPAExceptionTestFixture() :
m_uBufferSize(0) {
memset(m_aBuffer, 0, sizeof(m_aBuffer));
m_testSuiteName.push_back("Exception");
}
virtual bool AddRules() = 0;
virtual bool ModifyPackets() = 0;
virtual bool TestLogic() = 0;
bool Setup() {
ConfigureScenario(PHASE_SEVEN_TEST_CONFIGURATION);
m_producer.Open(INTERFACE0_TO_IPA_DATA_PATH,
INTERFACE0_FROM_IPA_DATA_PATH);
m_Consumer1.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_Consumer3.Open(INTERFACE3_TO_IPA_DATA_PATH,
INTERFACE3_FROM_IPA_DATA_PATH);
m_Exceptions.Open(INTERFACE_TO_IPA_EXCEPTION_PATH,
INTERFACE_FROM_IPA_EXCEPTION_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;
}
if (!m_HeaderInsertion.DeviceNodeIsOpened())
{
LOG_MSG_ERROR("Header Insertion block is not ready for immediate commands!\n");
return false;
}
m_HeaderInsertion.Reset();
return true;
} // Setup()
bool Run() {
m_uBufferSize = BUFF_MAX_SIZE;
LOG_MSG_STACK("Entering Function");
// Configure the system by adding Routing / Filtering / HDR
if (!AddRules()) {
LOG_MSG_ERROR("Failed adding Routing / Filtering / HDR.");
return false;
}
// Load input data (IP packet) from file
if (!LoadDefaultPacket(m_eIP, m_aBuffer, m_uBufferSize)) {
LOG_MSG_ERROR("Failed default Packet");
return false;
}
if (!ModifyPackets()) {
LOG_MSG_ERROR("Failed to modify packets.");
return false;
}
if (!TestLogic()) {
LOG_MSG_ERROR("Test failed, Input and expected output mismatch.");
return false;
}
LOG_MSG_STACK("Leaving Function (Returning True)");
return true;
} // Run()
bool Teardown() {
m_producer.Close();
m_Consumer1.Close();
m_Consumer2.Close();
m_Consumer3.Close();
m_Exceptions.Close();
return true;
} // Teardown()
~IPAExceptionTestFixture() {
}
static RoutingDriverWrapper m_Routing;
static Filtering m_Filtering;
static HeaderInsertion m_HeaderInsertion;
InterfaceAbstraction m_producer;
InterfaceAbstraction m_Consumer1;
InterfaceAbstraction m_Consumer2;
InterfaceAbstraction m_Consumer3;
InterfaceAbstraction m_Exceptions;
protected:
static const size_t BUFF_MAX_SIZE = 1024;
static const uint8_t MAX_HEADER_SIZE = 64; // 64Bytes - Max Header Length
enum ipa_ip_type m_eIP;
uint8_t m_aBuffer[BUFF_MAX_SIZE]; // Input file \ IP packet
size_t m_uBufferSize;
};
RoutingDriverWrapper IPAExceptionTestFixture::m_Routing;
Filtering IPAExceptionTestFixture::m_Filtering;
HeaderInsertion IPAExceptionTestFixture::m_HeaderInsertion;
//----------------------------------------------------------------------------------------------------------------------------------------/
// Test001: Test that when a packet with (IPVer != 4) && (IPVer Ver != 6) , an exception packet is created and received & exception_pipe /
//----------------------------------------------------------------------------------------------------------------------------------------/
class IPAExceptionPacketTest001: public IPAExceptionTestFixture {
public:
IPAExceptionPacketTest001() {
m_name = "IPAExceptionPacketTest001";
m_description = "\
IPA Exception Test 001 - Test that when a packet with (IPVer != 4) && (IPVer Ver != 6) , an exception packet is created and received & exception_pipe \
Test Generates send NUM_OF_EXCEPTION_PKTS packets with IP Version changing from 0 to 9.\
First IP Version == 4, hence it is not considered as exception (same goes for IP Ver == 6) \
";
m_eIP = IPA_IP_v4;
Register(*this);
}
virtual bool AddRules() {
// Clear All Rules
bool bRetVal = true;
LOG_MSG_STACK("Entering Function");
const char bypass0[20] = "Bypass0";
struct ipa_ioc_get_rt_tbl sRoutingTable;
IPAFilteringTable cFilterTable;
struct ipa_flt_rule_add sFilterRuleEntry;
uint32_t nRTTableHdl=0;
memset(&sRoutingTable, 0, sizeof(sRoutingTable));
LOG_MSG_STACK("Entering Function");
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, bypass0, IPA_CLIENT_TEST2_CONS,
0,&nRTTableHdl)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
LOG_MSG_INFO("CreateBypassRoutingTable completed successfully");
sRoutingTable.ip = m_eIP;
strlcpy(sRoutingTable.name, bypass0, sizeof(sRoutingTable.name));
if (!m_Routing.GetRoutingTable(&sRoutingTable)) {
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&sRoutingTable=0x%p) Failed.", &sRoutingTable);
bRetVal = false;
goto bail;
}
// Creating Filtering Rules
cFilterTable.Init(m_eIP,IPA_CLIENT_TEST_PROD,true,1);
LOG_MSG_INFO("Creation of filtering table completed successfully");
// Configuring Filtering Rule No.1
cFilterTable.GeneratePresetRule(0,sFilterRuleEntry);
sFilterRuleEntry.at_rear = true;
sFilterRuleEntry.flt_rule_hdl = -1; // return Value
sFilterRuleEntry.status = -1; // return value
sFilterRuleEntry.rule.action = IPA_PASS_TO_ROUTING;
sFilterRuleEntry.rule.rt_tbl_hdl = nRTTableHdl;
if (
((uint8_t)-1 == cFilterTable.AddRuleToTable(sFilterRuleEntry)) ||
!m_Filtering.AddFilteringRule(cFilterTable.GetFilteringTable())
)
{
LOG_MSG_ERROR ("Adding Rule (0) to Filtering block Failed.");
bRetVal = false;
goto bail;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable.ReadRuleFromTable(0)->flt_rule_hdl,cFilterTable.ReadRuleFromTable(0)->status);
}
bail:
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddRules()
virtual bool ModifyPackets() {
m_eIP = IPA_IP_v6;
AddRules(); // Need to add Routing / Filtering rules for IPv6 as well.
return true;
} // ModifyPacktes ()
virtual bool TestLogic() {
int i = 0, nIPVer = 0;;
memset(m_aExpectedBuffer, 0, sizeof(m_aExpectedBuffer));
m_aExpectedBuffer[2] = 0x0b;
m_aExpectedBuffer[3] = 0x80;
memcpy(m_aExpectedBuffer+8, m_aBuffer, m_uBufferSize);
m_aExpectedBufSize = m_uBufferSize+8;
for (i=0;i<NUM_OF_EXCEPTION_PKTS;i++)
{
LOG_MSG_INFO("Packet %d\n",i);
nIPVer = i+4 % 10;
m_aBuffer[0] = (m_aBuffer[0] & 0x0F)+0x10*nIPVer;// Change to Invalid IP version
m_aExpectedBuffer[8] = (m_aExpectedBuffer[8] & 0x0F)+0x10*nIPVer;
if (4 == nIPVer || 6 == nIPVer)
{
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Consumer1, m_aExpectedBuffer+8, m_aExpectedBufSize-8))
{
LOG_MSG_ERROR("SendReceiveAndCompare failed. IPVer = %d",nIPVer);
return false;
}
} else
{
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Exceptions, m_aExpectedBuffer, m_aExpectedBufSize))
{
LOG_MSG_ERROR("SendReceiveAndCompare failed. IPVer = %d",nIPVer);
return false;
}
}
}
return true;
}
private:
static const int NUM_OF_EXCEPTION_PKTS = 9;
uint8_t m_aExpectedBuffer[BUFF_MAX_SIZE];
size_t m_aExpectedBufSize;
};
//------------------------------------------------------------------------------------------------------------------------------------------/
// Test003: Test that when Filtering Routes the Packet to the Exception Pipe, an exception packet is created and received & exception_pipe /
//------------------------------------------------------------------------------------------------------------------------------------------/
class IPAExceptionPacketTest003: public IPAExceptionTestFixture {
public:
IPAExceptionPacketTest003() {
m_name = "IPAExceptionPacketTest003";
m_description = "\
IPA Exception Test 003 - Test that when Filtering Routes the Packet to the Exception Pipe, an exception packet is created and received & exception_pipe \
Test Generates a Filtering Table that routes all packets to the Exception Pipe. \
and verify that the packet is recieved @ the Exception Pipe. \
";
m_eIP = IPA_IP_v4;
Register(*this);
}
virtual bool AddRules() {
// Clear All Rules
bool bRetVal = true;
LOG_MSG_STACK("Entering Function");
const char bypass0[20] = "Bypass0";
struct ipa_ioc_get_rt_tbl sRoutingTable;
IPAFilteringTable cFilterTable;
struct ipa_flt_rule_add sFilterRuleEntry;
uint32_t nRTTableHdl=0;
memset(&sRoutingTable, 0, sizeof(sRoutingTable));
LOG_MSG_STACK("Entering Function");
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, bypass0, IPA_CLIENT_TEST2_CONS,
0,&nRTTableHdl)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
LOG_MSG_INFO("CreateBypassRoutingTable completed successfully");
sRoutingTable.ip = m_eIP;
strlcpy(sRoutingTable.name, bypass0, sizeof(sRoutingTable.name));
if (!m_Routing.GetRoutingTable(&sRoutingTable)) {
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&sRoutingTable=0x%p) Failed.", &sRoutingTable);
bRetVal = false;
goto bail;
}
// Creating Filtering Rules
cFilterTable.Init(m_eIP,IPA_CLIENT_TEST_PROD,true,1);
LOG_MSG_INFO("Creation of filtering table completed successfully");
// Configuring Filtering Rule No.1
cFilterTable.GeneratePresetRule(0,sFilterRuleEntry);
sFilterRuleEntry.at_rear = true;
sFilterRuleEntry.flt_rule_hdl = -1; // return Value
sFilterRuleEntry.status = -1; // return value
sFilterRuleEntry.rule.action = IPA_PASS_TO_EXCEPTION;
sFilterRuleEntry.rule.rt_tbl_hdl = nRTTableHdl;
if (
((uint8_t)-1 == cFilterTable.AddRuleToTable(sFilterRuleEntry)) ||
!m_Filtering.AddFilteringRule(cFilterTable.GetFilteringTable())
)
{
LOG_MSG_ERROR ("Adding Rule (0) to Filtering block Failed.");
bRetVal = false;
goto bail;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable.ReadRuleFromTable(0)->flt_rule_hdl,cFilterTable.ReadRuleFromTable(0)->status);
}
bail:
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddRules()
virtual bool ModifyPackets() {
return true;
} // ModifyPacktes ()
virtual bool TestLogic() {
memset(m_aExpectedBuffer, 0, sizeof(m_aExpectedBuffer));
m_aExpectedBuffer[2] = 0x0b;
m_aExpectedBuffer[3] = 0x20;
memcpy(m_aExpectedBuffer+8, m_aBuffer, m_uBufferSize);
m_aExpectedBufSize = m_uBufferSize+8;
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Exceptions, m_aExpectedBuffer, m_aExpectedBufSize))
{
LOG_MSG_ERROR("SendReceiveAndCompare failed.");
return false;
}
return true;
}
private:
uint8_t m_aExpectedBuffer[BUFF_MAX_SIZE];
size_t m_aExpectedBufSize;
};
//-----------------------------------------------------------------------------------------------------------------------------------------/
// Test006: Test that when a packet with Internet Header Length < 5 Arrives, an exception packet is created and received & exception_pipe /
//-----------------------------------------------------------------------------------------------------------------------------------------/
class IPAExceptionPacketTest006: public IPAExceptionTestFixture {
public:
IPAExceptionPacketTest006() {
m_name = "IPAExceptionPacketTest006"
m_description = "\
IPA Exception Test 006 - Test that when a packet with Internet Header Length < 5 Arrives, an exception packet is created and received & exception_pipe \
Test Generates a Packet with Internet Header Length (IHL == 4). \
and verifies that the packet is recieved @ the Exception Pipe. \
";
m_eIP = IPA_IP_v4;
Register(*this);
}
virtual bool AddRules() {
// Clear All Rules
bool bRetVal = true;
LOG_MSG_STACK("Entering Function");
const char bypass0[20] = "Bypass0";
struct ipa_ioc_get_rt_tbl sRoutingTable;
IPAFilteringTable cFilterTable;
struct ipa_flt_rule_add sFilterRuleEntry;
uint32_t nRTTableHdl=0;
memset(&sRoutingTable, 0, sizeof(sRoutingTable));
LOG_MSG_STACK("Entering Function");
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, bypass0, IPA_CLIENT_TEST2_CONS,
0,&nRTTableHdl)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
LOG_MSG_INFO("CreateBypassRoutingTable completed successfully");
sRoutingTable.ip = m_eIP;
strlcpy(sRoutingTable.name, bypass0, sizeof(sRoutingTable.name));
if (!m_Routing.GetRoutingTable(&sRoutingTable)) {
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&sRoutingTable=0x%p) Failed.", &sRoutingTable);
bRetVal = false;
goto bail;
}
// Creating Filtering Rules
cFilterTable.Init(m_eIP,IPA_CLIENT_TEST_PROD,true,1);
LOG_MSG_INFO("Creation of filtering table completed successfully");
// Configuring Filtering Rule No.1
cFilterTable.GeneratePresetRule(0,sFilterRuleEntry);
sFilterRuleEntry.at_rear = true;
sFilterRuleEntry.flt_rule_hdl = -1; // return Value
sFilterRuleEntry.status = -1; // return value
sFilterRuleEntry.rule.action = IPA_PASS_TO_ROUTING;
sFilterRuleEntry.rule.rt_tbl_hdl = nRTTableHdl;
if (
((uint8_t)-1 == cFilterTable.AddRuleToTable(sFilterRuleEntry)) ||
!m_Filtering.AddFilteringRule(cFilterTable.GetFilteringTable())
)
{
LOG_MSG_ERROR ("Adding Rule (0) to Filtering block Failed.");
bRetVal = false;
goto bail;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable.ReadRuleFromTable(0)->flt_rule_hdl,cFilterTable.ReadRuleFromTable(0)->status);
}
bail:
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddRules()
virtual bool ModifyPackets() {
m_aBuffer[0] =(m_aBuffer[0] & 0xF0)+0x04;// Change the IHL to 4
return true;
} // ModifyPacktes ()
virtual bool TestLogic() {
memset(m_aExpectedBuffer, 0, sizeof(m_aExpectedBuffer));
m_aExpectedBuffer[2] = 0x0b;
m_aExpectedBuffer[3] = 0x04;
memcpy(m_aExpectedBuffer+8, m_aBuffer, m_uBufferSize);
m_aExpectedBufSize = m_uBufferSize+8;
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Exceptions, m_aExpectedBuffer, m_aExpectedBufSize))
{
LOG_MSG_ERROR("SendReceiveAndCompare failed.");
return false;
}
return true;
}
private:
uint8_t m_aExpectedBuffer[BUFF_MAX_SIZE];
size_t m_aExpectedBufSize;
};
static IPAExceptionPacketTest001 ipaExceptionPacketTest001;
static IPAExceptionPacketTest002 ipaExceptionPacketTest002;
static IPAExceptionPacketTest003 ipaExceptionPacketTest003;
static IPAExceptionPacketTest006 ipaExceptionPacketTest006;

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2017 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 "RoutingDriverWrapper.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
#include "TestsUtils.h"
#include <string.h>
#include "ExceptionsTestFixture.h"
///////////////////////////////////////////////////////////////////////////////
Pipe ExceptionsTestFixture::m_USB1ToIpaPipe(IPA_CLIENT_TEST_PROD, IPA_TEST_CONFIFURATION_7);
Pipe ExceptionsTestFixture::m_IpaToA5ExceptionPipe(IPA_TEST_CONFIFURATION_7);//Exception pipe
///////////////////////////////////////////////////////////////////////////////
ExceptionsTestFixture::ExceptionsTestFixture(){
Register(*this);
m_testSuiteName.push_back("Exceptions");
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////// EOF ///////
///////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2017 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 "Routing.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
#include "TestsUtils.h"
#include "Pipe.h"
#include <string.h>
#ifndef _EXCEPTION_TESTS_FIXTURE_
#define _EXCEPTION_TESTS_FIXTURE_
class ExceptionsTestFixture:public TestBase {
public:
/*This Constructor will register the
*exception tests and set the suit name
*/
ExceptionsTestFixture();
protected:
static Pipe m_USB1ToIpaPipe;
/*from the test application into the IPA(DMUX header)*/
static Pipe m_IpaToA5ExceptionPipe;
/*from the IPA back to the test application(Exception pipe)*/
};
#endif

View File

@@ -0,0 +1,264 @@
/*
* Copyright (c) 2017 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 "RoutingDriverWrapper.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
#include "TestsUtils.h"
#include "ExceptionsTestFixture.h"
#include "IPv4Packet.h"
#include <string.h>
#define MAX_SENT_BUFFER_SIZE 1500
#define MAX_RECEIVE_BUFFER_SIZE 1500
#define VALIDATE_WITH_MSG_AND_RETVAL(bRetVal,msg) \
if (false == bRetVal){ \
LOG_MSG_ERROR(msg); \
return false; \
}
using namespace IPA;
///////////////////////////////////////////////////////////////////////////////
class ExceptionsTestNonIpPacket: public ExceptionsTestFixture {
public:
//The packet size to be sent
size_t m_nPacketSize;
//A buffer to hold the non-IP(V4/V6) packet
Byte *m_pSendBuffer;
///////////////////////////////////////////////////////////////////////////
//Set the tests name and description
ExceptionsTestNonIpPacket() :
m_nPacketSize(0), m_pSendBuffer(NULL) {
m_name = "ExceptionsTestNonIpPacket";
m_description =
"Create a non-IP packet(version!=4 && version !=6) and \
expect exception from Filter block";
}
///////////////////////////////////////////////////////////////////////////
virtual bool Run() {
bool bRetVal = true;
Byte *pReceiveBuffer = new Byte[MAX_RECEIVE_BUFFER_SIZE];
//Send the non-IPV4/IPV6 packet to the IPA
LOG_MSG_DEBUG("Send the non-IPV4/IPV6 packet to the IPA");
size_t nBytesSent = m_USB1ToIpaPipe.Send(m_pSendBuffer, m_nPacketSize);
if (nBytesSent != m_nPacketSize) {
LOG_MSG_ERROR("Not all data was sent into the IPA");
return false;
}
//Read from the exception pipe(from IPA to A5) - try to read as much as we can
size_t nBytesRead = m_IpaToA5ExceptionPipe.Receive(pReceiveBuffer,
MAX_RECEIVE_BUFFER_SIZE);
if (nBytesRead != nBytesSent) {
LOG_MSG_ERROR("Not all data was read:");
print_buff(pReceiveBuffer, nBytesRead);
return false;
}
//check the exception packet against the one that we sent
bRetVal = !memcmp(m_pSendBuffer, pReceiveBuffer, nBytesSent);
if (false == bRetVal) {
LOG_MSG_ERROR("Received packet is not equal, Received:");
print_buff(pReceiveBuffer, nBytesRead);
LOG_MSG_ERROR("Received packet is not equal, Sent:");
print_buff(m_pSendBuffer, m_nPacketSize);
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////
//build the non-IP packet
virtual bool Setup() {
bool bRetVal = true;
m_pSendBuffer = new Byte[MAX_SENT_BUFFER_SIZE];
//Load some default IPV4 packet and save its size
m_nPacketSize = MAX_SENT_BUFFER_SIZE; //This parameter is In/Out
bRetVal = LoadDefaultPacket(IPA_IP_v4, m_pSendBuffer, m_nPacketSize);
VALIDATE_WITH_MSG_AND_RETVAL(bRetVal, "Load failed");
//Set the version field to non-IPV4/IPV6(version = 5)
m_pSendBuffer[0] &= 0x0F;
m_pSendBuffer[0] |= 0x50;
//initialize Pipes
bRetVal = m_USB1ToIpaPipe.Init();
VALIDATE_WITH_MSG_AND_RETVAL(bRetVal, "Pipe Initialization failed");
bRetVal = m_IpaToA5ExceptionPipe.Init();
VALIDATE_WITH_MSG_AND_RETVAL(bRetVal, "Pipe Initialization failed");
return true;
}
///////////////////////////////////////////////////////////////////////////
virtual bool Teardown() {
bool bRetVal = true;
delete[] m_pSendBuffer;
m_USB1ToIpaPipe.Destroy();
m_IpaToA5ExceptionPipe.Destroy();
return bRetVal;
}
///////////////////////////////////////////////////////////////////////////
};
//ExceptionTestNoneIpPacket
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class ExceptionsTestFragmentedException: public ExceptionsTestFixture {
public:
//The packet size to be sent
size_t m_nPacketSize;
//A buffer to hold the non-IP(V4/V6) packet
Byte *m_pSendBuffer;
Byte *m_pReceiveBuffer;
///////////////////////////////////////////////////////////////////////////
//Set the tests name and description
ExceptionsTestFragmentedException():m_nPacketSize(0), m_pSendBuffer(NULL),
m_pReceiveBuffer(NULL){
m_name = "ExceptionsTestFragmentedException";
m_description =
"Send IP packet with MF set, create global Filter rule \
that will hit it as Exception";
}
///////////////////////////////////////////////////////////////////////////
virtual bool Run() {
bool bRetVal = true;
//configuring the Filter block to catch the fragmented packet:
ConfigureFilterGlobalRuleForMF();
//Send the non-IPV4/IPV6 packet to the IPA
LOG_MSG_DEBUG("Send the IP packet with the MF bit set(size = %d)", m_nPacketSize);
size_t nBytesSent = m_USB1ToIpaPipe.Send(m_pSendBuffer, m_nPacketSize);
if (nBytesSent != m_nPacketSize) {
LOG_MSG_ERROR("Not all data was sent into the IPA(only %d)", nBytesSent);
return false;
}
//Read from the exception pipe(from IPA to A5) - try to read as much as we can
size_t nBytesRead = m_IpaToA5ExceptionPipe.Receive(m_pReceiveBuffer,
MAX_RECEIVE_BUFFER_SIZE);
if (nBytesRead != nBytesSent) {
LOG_MSG_ERROR("Not all data was read:");
print_buff(m_pReceiveBuffer, nBytesRead);
return false;
}
//check the exception packet against the one that we sent
bRetVal = !memcmp(m_pSendBuffer, m_pReceiveBuffer, nBytesSent);
if (false == bRetVal) {
LOG_MSG_ERROR("Received packet is not equal, Received:");
print_buff(m_pReceiveBuffer, nBytesRead);
LOG_MSG_ERROR("Received packet is not equal, Sent:");
print_buff(m_pSendBuffer, m_nPacketSize);
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////
//build the non-IP packet
virtual bool Setup() {
bool bRetVal = true;
m_pReceiveBuffer = new Byte[MAX_RECEIVE_BUFFER_SIZE];
m_pSendBuffer = new Byte[MAX_RECEIVE_BUFFER_SIZE];
//Load some default TCP packet
TCPPacket tcpPacket;
//Set the MF bit
tcpPacket.SetMF(true);
//copy the packet to the send buffer
m_nPacketSize = tcpPacket.GetSize();
tcpPacket.ToNetworkByteStream(m_pSendBuffer);
//initialize Pipes
bRetVal = m_USB1ToIpaPipe.Init();
VALIDATE_WITH_MSG_AND_RETVAL(bRetVal, "Pipe Initialization failed");
bRetVal = m_IpaToA5ExceptionPipe.Init();
VALIDATE_WITH_MSG_AND_RETVAL(bRetVal, "Pipe Initialization failed");
return true;
}
///////////////////////////////////////////////////////////////////////////
virtual bool Teardown() {
bool bRetVal = true;
delete[] m_pSendBuffer;
m_USB1ToIpaPipe.Destroy();
m_IpaToA5ExceptionPipe.Destroy();
return bRetVal;
}
///////////////////////////////////////////////////////////////////////////
void ConfigureFilterGlobalRuleForMF(){
//struct ipa_ioc_add_flt_rule *pRuleTable;
//Allocate memory for a table with one rule.
//Instruct the Driver to write this table(with its one rule) to the HW
//Continue from here - build the rule to catch the fragmented packet
}
///////////////////////////////////////////////////////////////////////////
};
//ExceptionsTestFragmentedException
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class ExceptionsTestNonTCPUDP: public ExceptionsTestFixture {
};
///////////////////////////////////////////////////////////////////////////////
//Classes instances:
static ExceptionsTestNonIpPacket exceptionsTestNonIpPacket;
static ExceptionsTestFragmentedException exceptionsTestFragmentedException;
///////////////////////////////////////////////////////////////////////////////
////////////// EOF ////////
///////////////////////////////////////////////////////////////////////////////

127
kernel-tests/Filtering.cpp Normal file
View File

@@ -0,0 +1,127 @@
/*
* 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 <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include "Filtering.h"
const char* Filtering::DEVICE_NAME = "/dev/ipa";
Filtering::Filtering()
{
fd = open(DEVICE_NAME, O_RDWR);
if (0 == fd) {
printf("Failed opening %s.\n", DEVICE_NAME);
}
}
Filtering::~Filtering()
{
close(fd);
}
bool Filtering::DeviceNodeIsOpened()
{
return fd;
}
bool Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const * ruleTable)
{
int retval = 0;
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE, ruleTable);
if (retval) {
printf("%s(), failed adding Filtering rule table %p\n", __FUNCTION__, ruleTable);
return false;
}
printf("%s(), Added Filtering rule to table %p\n", __FUNCTION__, ruleTable);
return true;
}
bool Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule_v2 const * ruleTable)
{
int retval = 0;
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_V2, ruleTable);
if (retval) {
printf("%s(), failed adding Filtering rule table %p\n", __FUNCTION__, ruleTable);
return false;
}
printf("%s(), Added Filtering rule to table %p\n", __FUNCTION__, ruleTable);
return true;
}
bool Filtering::DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable)
{
int retval = 0;
retval = ioctl(fd, IPA_IOC_DEL_FLT_RULE, ruleTable);
if (retval) {
printf("%s(), failed deleting Filtering rule in table %p\n", __FUNCTION__, ruleTable);
return false;
}
printf("%s(), Deleted Filtering rule in table %p\n", __FUNCTION__, ruleTable);
return true;
}
bool Filtering::Commit(enum ipa_ip_type ip)
{
int retval = 0;
retval = ioctl(fd, IPA_IOC_COMMIT_FLT, ip);
if (retval) {
printf("%s(), failed committing Filtering rules.\n", __FUNCTION__);
return false;
}
printf("%s(), Committed Filtering rules to IPA HW.\n", __FUNCTION__);
return true;
}
bool Filtering::Reset(enum ipa_ip_type ip)
{
int retval = 0;
retval = ioctl(fd, IPA_IOC_RESET_FLT, ip);
retval |= ioctl(fd, IPA_IOC_COMMIT_FLT, ip);
if (retval) {
printf("%s(), failed resetting Filtering block.\n", __FUNCTION__);
return false;
}
printf("%s(), Reset command issued to IPA Filtering block.\n", __FUNCTION__);
return true;
}

54
kernel-tests/Filtering.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* 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.
*/
#ifndef FILTERING_H_
#define FILTERING_H_
#include <stdint.h>
#include "linux/msm_ipa.h"
class Filtering
{
public:
Filtering();
~Filtering();
bool AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTable);
bool AddFilteringRule(ipa_ioc_add_flt_rule_v2 const *ruleTable);
bool DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable);
bool Commit(enum ipa_ip_type ip);
bool Reset(enum ipa_ip_type ip);
bool DeviceNodeIsOpened();
private:
static const char *DEVICE_NAME;
int fd; /*File descriptor of the IPA device node /dev/ipa*/
};
#endif

View File

@@ -0,0 +1,513 @@
/*
* Copyright (c) 2017 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 "FilteringEthernetBridgingTestFixture.h"
IpaFilteringEthernetBridgingTestFixture::IpaFilteringEthernetBridgingTestFixture():
m_sendSize1 (m_BUFF_MAX_SIZE),
m_sendSize2 (m_BUFF_MAX_SIZE),
m_sendSize3 (m_BUFF_MAX_SIZE),
m_IpaIPType(IPA_IP_v4)
{
memset(m_sendBuffer1, 0, sizeof(m_sendBuffer1));
memset(m_sendBuffer2, 0, sizeof(m_sendBuffer2));
memset(m_sendBuffer3, 0, sizeof(m_sendBuffer3));
m_testSuiteName.push_back("FilteringEth");
}
bool IpaFilteringEthernetBridgingTestFixture::Setup()
{
ConfigureScenario(PHASE_TWO_TEST_CONFIGURATION);
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);
m_routing.Reset(IPA_IP_v6);
return true;
} // Setup()
bool IpaFilteringEthernetBridgingTestFixture::Teardown()
{
m_producer.Close();
m_producer2.Close();
m_consumer.Close();
m_consumer2.Close();
m_defaultConsumer.Close();
return true;
} // Teardown()
bool IpaFilteringEthernetBridgingTestFixture::LoadFiles(enum ipa_ip_type ip)
{
if (!LoadDefaultEth2Packet(ip, m_sendBuffer1, m_sendSize1)) {
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
LOG_MSG_DEBUG ("Loaded %zu Bytes to Buffer 1\n",m_sendSize1);
if (!LoadDefaultEth2Packet(ip, 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 (!LoadDefaultEth2Packet(ip, 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;
}
bool IpaFilteringEthernetBridgingTestFixture::ReceivePacketsAndCompare()
{
size_t receivedSize = 0;
size_t receivedSize2 = 0;
size_t receivedSize3 = 0;
bool isSuccess = true;
// Receive results
Byte *rxBuff1 = new Byte[m_BUFF_MAX_SIZE];
Byte *rxBuff2 = new Byte[m_BUFF_MAX_SIZE];
Byte *rxBuff3 = new Byte[m_BUFF_MAX_SIZE];
if (NULL == rxBuff1 || NULL == rxBuff2 || NULL == rxBuff3)
{
printf("Memory allocation error.\n");
return false;
}
receivedSize = m_consumer.ReceiveData(rxBuff1,
m_BUFF_MAX_SIZE);
LOG_MSG_DEBUG("Received %zu bytes on %s.\n",
receivedSize,
m_consumer.m_fromChannelName.c_str());
receivedSize2 = m_consumer2.ReceiveData(rxBuff2,
m_BUFF_MAX_SIZE);
LOG_MSG_DEBUG("Received %zu bytes on %s.\n",
receivedSize2,
m_consumer2.m_fromChannelName.c_str());
receivedSize3 = m_defaultConsumer.ReceiveData(rxBuff3,
m_BUFF_MAX_SIZE);
LOG_MSG_DEBUG("Received %zu bytes on %s.\n",
receivedSize3,
m_defaultConsumer.m_fromChannelName.c_str());
// Compare results
if (!CompareResultVsGolden(m_sendBuffer1,
m_sendSize1,
rxBuff1,
receivedSize))
{
LOG_MSG_ERROR("Comparison of Buffer0 Failed!");
isSuccess = false;
}
char recievedBuffer[256] = {0};
char SentBuffer[256] = {0};
size_t j;
for(j = 0; j < m_sendSize1; j++)
snprintf(&SentBuffer[3*j], sizeof(SentBuffer) - (3*j + 1), " %02X", m_sendBuffer1[j]);
for(j = 0; j < receivedSize; j++)
snprintf(&recievedBuffer[3*j], sizeof(recievedBuffer) - (3*j + 1), " %02X", rxBuff1[j]);
printf("Expected Value1 (%zu)\n%s\n, Received Value1(%zu)\n%s\n",
m_sendSize1,SentBuffer,receivedSize,recievedBuffer);
recievedBuffer[0] = 0;
for(j = 0; j < m_sendSize2; j++)
snprintf(&SentBuffer[3 * j], sizeof(SentBuffer) - (3*j + 1), " %02X", m_sendBuffer2[j]);
for(j = 0; j < receivedSize2; j++)
snprintf(&recievedBuffer[3*j], sizeof(recievedBuffer) - (3*j + 1), " %02X", rxBuff2[j]);
printf("Expected Value2 (%zu)\n%s\n, Received Value2(%zu)\n%s\n",
m_sendSize2,SentBuffer,receivedSize2,recievedBuffer);
recievedBuffer[0] = 0;
for(j = 0; j < m_sendSize3; j++)
snprintf(&SentBuffer[3*j], sizeof(SentBuffer) - (3*j + 1), " %02X", m_sendBuffer3[j]);
for(j = 0; j < receivedSize3; j++)
snprintf(&recievedBuffer[3*j], sizeof(recievedBuffer) - (3*j + 1), " %02X", rxBuff3[j]);
printf("Expected Value3 (%zu)\n%s\n, Received Value3(%zu)\n%s\n",
m_sendSize3,SentBuffer,receivedSize3,recievedBuffer);
recievedBuffer[0] = 0;
isSuccess &= CompareResultVsGolden(m_sendBuffer2,
m_sendSize2, rxBuff2, receivedSize2);
isSuccess &= CompareResultVsGolden(m_sendBuffer3,
m_sendSize3, rxBuff3, receivedSize3);
delete[] rxBuff1;
delete[] rxBuff2;
delete[] rxBuff3;
return isSuccess;
}
// This function creates three IPv4 bypass routing entries and commits them.
bool IpaFilteringEthernetBridgingTestFixture::CreateThreeIPv4BypassRoutingTables(const char *bypass0, const char *bypass1,
const char *bypass2)
{
LOG_MSG_DEBUG("Entering");
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");
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");
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");
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)\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");
return true;
}
// This function creates three IPv6 bypass routing entries and commits them.
bool IpaFilteringEthernetBridgingTestFixture::CreateThreeIPv6BypassRoutingTables (const char *bypass0, const char *bypass1,
const char *bypass2)
{
LOG_MSG_DEBUG("Entering");
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_v6;
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.v6.dst_addr[0] = 0xaabbccdd;
rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0xeeff0011;
rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0x22334455;
rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0x66778899;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;// All Packets will get a "Hit"
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
if (false == m_routing.AddRoutingRule(rt_rule0))
{
LOG_MSG_ERROR("Routing rule addition(rt_rule0)");
Free (rt_rule2);
Free (rt_rule1);
Free (rt_rule0);
return false;
}
rt_rule1->num_rules = 1;
rt_rule1->ip = IPA_IP_v6;
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.v6.dst_addr[0] = 0xaabbccdd;
rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0xeeff0011;
rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0x22334455;
rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0x66778899;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;// All Packets will get a "Hit"
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
if (false == m_routing.AddRoutingRule(rt_rule1))
{
LOG_MSG_ERROR("Routing rule addition(rt_rule1)");
Free (rt_rule2);
Free (rt_rule1);
Free (rt_rule0);
return false;
}
rt_rule2->num_rules = 1;
rt_rule2->ip = IPA_IP_v6;
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.v6.dst_addr[0] = 0xaabbccdd;
rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0xeeff0011;
rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0x22334455;
rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0x66778899;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;// All Packets will get a "Hit"
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
if (false == m_routing.AddRoutingRule(rt_rule2))
{
LOG_MSG_ERROR("Routing rule addition(rt_rule2)");
Free (rt_rule2);
Free (rt_rule1);
Free (rt_rule0);
return false;
}
Free (rt_rule2);
Free (rt_rule1);
Free (rt_rule0);
LOG_MSG_DEBUG("Leaving function\n");
return true;
}
bool IpaFilteringEthernetBridgingTestFixture::Run()
{
bool res = false;
bool isSuccess = false;
LOG_MSG_DEBUG("Entering");
// Add the relevant filtering rules
res = AddRules();
if (false == res) {
LOG_MSG_ERROR("Failed adding filtering rules");
return false;
}
// Load input data (IP packet) from file
res = LoadFiles(m_IpaIPType);
if (false == res) {
LOG_MSG_ERROR("Failed loading files");
return false;
}
res = ModifyPackets();
if (false == res) {
LOG_MSG_ERROR("Failed to modify packets");
return false;
}
// Send first packet
isSuccess = m_pCurrentProducer->SendData(m_sendBuffer1,
m_sendSize1);
if (false == isSuccess)
{
LOG_MSG_ERROR("SendData failure");
return false;
}
// Send second packet
isSuccess = m_pCurrentProducer->SendData(m_sendBuffer2,
m_sendSize2);
if (false == isSuccess)
{
LOG_MSG_ERROR("SendData failure");
return false;
}
// Send third packet
isSuccess = m_pCurrentProducer->SendData(m_sendBuffer3,
m_sendSize3);
if (false == isSuccess)
{
LOG_MSG_ERROR("SendData failure");
return false;
}
// Receive packets from the channels and compare results
isSuccess = ReceivePacketsAndCompare();
LOG_MSG_DEBUG("Leaving function returning %d", isSuccess);
return isSuccess;
} // Run()
IpaFilteringEthernetBridgingTestFixture::~IpaFilteringEthernetBridgingTestFixture()
{
m_sendSize1 = 0;
m_sendSize2 = 0;
m_sendSize3 = 0;
}
static const size_t m_BUFF_MAX_SIZE = 1024;
static Filtering m_filtering;
static RoutingDriverWrapper m_routing;
InterfaceAbstraction m_producer;
InterfaceAbstraction m_producer2; // Pipe with ETH2 header removal
InterfaceAbstraction *m_pCurrentProducer;
InterfaceAbstraction m_consumer;
InterfaceAbstraction m_consumer2;
InterfaceAbstraction m_defaultConsumer;
Byte m_sendBuffer1[m_BUFF_MAX_SIZE];
Byte m_sendBuffer2[m_BUFF_MAX_SIZE];
Byte m_sendBuffer3[m_BUFF_MAX_SIZE];
size_t m_sendSize1;
size_t m_sendSize2;
size_t m_sendSize3;
enum ipa_ip_type m_IpaIPType;
RoutingDriverWrapper IpaFilteringEthernetBridgingTestFixture::m_routing;
Filtering IpaFilteringEthernetBridgingTestFixture::m_filtering;
const uint8_t IpaFilteringEthernetBridgingTestFixture::m_ETH2_DST_ADDR[ETH_ALEN] =
{
0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11
};
const uint8_t IpaFilteringEthernetBridgingTestFixture::m_ETH2_SRC_ADDR[ETH_ALEN] =
{
0x22, 0xee, 0xdd, 0xcc, 0xbb, 0xaa
};
const uint8_t IpaFilteringEthernetBridgingTestFixture::m_MAC_ADDR_MASK_ALL[ETH_ALEN] =
{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2017 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"
#define IPV4_DST_ADDR_OFFSET (16)
#define IPV4_SRC_PORT_OFFSET (20)
#define IPV4_DST_PORT_OFFSET (20+2)
#define DST_ADDR_LSB_OFFSET_IPV4 (19)
#define DST_ADDR_LSB_OFFSET_IPV6 (39)
class IpaFilteringEthernetBridgingTestFixture : public TestBase
{
public:
virtual bool ModifyPackets() = 0;
virtual bool AddRules() = 0;
IpaFilteringEthernetBridgingTestFixture();
bool Setup();
bool Teardown();
virtual bool LoadFiles(enum ipa_ip_type ip);
bool ReceivePacketsAndCompare();
// This function creates three IPv4 bypass routing entries and commits them.
bool CreateThreeIPv4BypassRoutingTables (const char *bypass0, const char *bypass1,
const char *bypass2);
// This function creates three IPv6 bypass routing entries and commits them.
bool CreateThreeIPv6BypassRoutingTables (const char *bypass0, const char *bypass1,
const char *bypass2);
bool Run();
~IpaFilteringEthernetBridgingTestFixture();
static const size_t m_BUFF_MAX_SIZE = 1024;
static const uint8_t m_ETH2_DST_ADDR[ETH_ALEN];
static const uint8_t m_ETH2_SRC_ADDR[ETH_ALEN];
static const uint8_t m_MAC_ADDR_MASK_ALL[ETH_ALEN];
static Filtering m_filtering;
static RoutingDriverWrapper m_routing;
InterfaceAbstraction m_producer;
InterfaceAbstraction m_producer2; // Pipe with ETH2 header removal
InterfaceAbstraction *m_pCurrentProducer;
InterfaceAbstraction m_consumer;
InterfaceAbstraction m_consumer2;
InterfaceAbstraction m_defaultConsumer;
Byte m_sendBuffer1[m_BUFF_MAX_SIZE];
Byte m_sendBuffer2[m_BUFF_MAX_SIZE];
Byte m_sendBuffer3[m_BUFF_MAX_SIZE];
size_t m_sendSize1;
size_t m_sendSize2;
size_t m_sendSize3;
enum ipa_ip_type m_IpaIPType;
private:
};

View File

@@ -0,0 +1,700 @@
/*
* Copyright (c) 2017 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 "FilteringEthernetBridgingTestFixture.h"
/*---------------------------------------------------------------------------*/
/* Test 00: Destination IP address and subnet mask match against LAN subnet */
/*---------------------------------------------------------------------------*/
class IpaFilterEthIPv4Test00 : public IpaFilteringEthernetBridgingTestFixture
{
public:
IpaFilterEthIPv4Test00()
{
m_name = "IpaFilterEthIPv4Test00";
m_description =
"Filtering block test 01 - Ethernet Bridge, ETH2 filters, \
IPv4 address (EP Filtering Table, \
Insert all rules in a single commit) \
1. Generate and commit three routing tables. \
Each table contains a single \"bypass\" rule \
(all data goes to output pipe 0, 1 and 2 (accordingly)) \
2. Generate and commit 3 ETH2 filtering rules: \
All MAC DST == (aabbccddee11) traffic goes to routing table 0 \
All MAC SRC == (22eeddccbbaa) traffic goes to routing table 1 \
All (1) traffic goes to routing table 2";
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
Register(*this);
m_pCurrentProducer = &m_producer2;
}
virtual bool AddRules()
{
LOG_MSG_DEBUG("Entering");
const char bypass0[] = "bypass0";
const char bypass1[] = "bypass1";
const char bypass2[] = "bypass2";
struct ipa_ioc_get_rt_tbl routing_table0,routing_table1,routing_table2;
if (!CreateThreeIPv4BypassRoutingTables (bypass0,bypass1,bypass2))
{
printf("CreateThreeIPv4BypassRoutingTables");
return false;
}
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)",
&routing_table0);
return false;
}
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)",
&routing_table1);
return false;
}
routing_table2.ip = IPA_IP_v4;
strlcpy(routing_table2.name, bypass2, sizeof(routing_table2.name));
if (!m_routing.GetRoutingTable(&routing_table2))
{
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&routing_table2=0x%p)",
&routing_table2);
return false;
}
// Create 3 filter rules
IPAFilteringTable FilterTable0;
struct ipa_flt_rule_add flt_rule_entry;
FilterTable0.Init(IPA_IP_v4,IPA_CLIENT_TEST2_PROD,false,3);
// Configuring Filtering Rule 0 - ETH2 DST
FilterTable0.GeneratePresetRule(1,flt_rule_entry);
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.retain_hdr = 1; // retain header removed in producer pipe
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; // Handle corresponding to routing table 0
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_DST_ADDR_ETHER_II; // Filter using ETH2 DST address
memcpy(flt_rule_entry.rule.attrib.dst_mac_addr_mask,
m_MAC_ADDR_MASK_ALL,
sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask)); // ETH2 DST address mask
memcpy(flt_rule_entry.rule.attrib.dst_mac_addr,
m_ETH2_DST_ADDR,
sizeof(flt_rule_entry.rule.attrib.dst_mac_addr)); // ETH2 DST address
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(0) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(0)->status);
}
// Configuring Filtering Rule 1 - ETH2 SRC
flt_rule_entry.rule.rt_tbl_hdl=routing_table1.hdl; // Handle corresponding to routing table 1
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_SRC_ADDR_ETHER_II; // Filter using ETH2 SRC address
memcpy(flt_rule_entry.rule.attrib.src_mac_addr_mask,
m_MAC_ADDR_MASK_ALL,
sizeof(flt_rule_entry.rule.attrib.src_mac_addr_mask)); // ETH2 SRC address mask
memcpy(flt_rule_entry.rule.attrib.src_mac_addr,
m_ETH2_SRC_ADDR,
sizeof(flt_rule_entry.rule.attrib.src_mac_addr)); // ETH2 SRC address
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(1) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(1)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(1)->status);
}
// Configuring Filtering Rule 2 - Accept all
flt_rule_entry.rule.rt_tbl_hdl = routing_table2.hdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; // Accept all
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; // Has no effect
if (((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) ||
!m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()))
{
LOG_MSG_ERROR ("Adding RuleTable(2) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(2)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(2)->status);
}
LOG_MSG_DEBUG("Leaving function\n");
return true;
}// AddRules()
virtual bool ModifyPackets()
{
memcpy(&m_sendBuffer1[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer2[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
m_sendBuffer2[ETH2_DST_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer2[ETH2_SRC_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
// swap destination and source addresses so that both
// rule0 and rule1 are miss and rule2 (accept all) is hit
memcpy(&m_sendBuffer3[ETH2_DST_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer3[ETH2_SRC_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
return true;
}// ModifyPacktes ()
};
/*---------------------------------------------------------------------------*/
/* Test 01: Destination IP address and subnet mask match against LAN subnet */
/*---------------------------------------------------------------------------*/
class IpaFilterEthIPv4Test01 : public IpaFilteringEthernetBridgingTestFixture
{
public:
IpaFilterEthIPv4Test01()
{
m_name = "IpaFilterEthIPv4Test01";
m_description =
"Filtering block test 01 - Ethernet Bridge, ETH2 filters, \
IPv4 address (EP Filtering Table, \
Insert all rules in a single commit) \
1. Generate and commit three routing tables. \
Each table contains a single \"bypass\" rule \
(all data goes to output pipe 0, 1 and 2 (accordingly)) \
2. Generate and commit 3 ETH2 filtering rules: \
All MAC DST == (aabbccddee11) traffic goes to routing table 0 \
All MAC ETH TYPE == (0800) traffic goes to routing table 1 \
All (1) traffic goes to routing table 2";
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
Register(*this);
m_pCurrentProducer = &m_producer2;
}
virtual bool AddRules()
{
LOG_MSG_DEBUG("Entering");
const char bypass0[] = "bypass0";
const char bypass1[] = "bypass1";
const char bypass2[] = "bypass2";
struct ipa_ioc_get_rt_tbl routing_table0,routing_table1,routing_table2;
if (!CreateThreeIPv4BypassRoutingTables (bypass0,bypass1,bypass2))
{
printf("CreateThreeIPv4BypassRoutingTables");
return false;
}
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)",
&routing_table0);
return false;
}
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)",
&routing_table1);
return false;
}
routing_table2.ip = IPA_IP_v4;
strlcpy(routing_table2.name, bypass2, sizeof(routing_table2.name));
if (!m_routing.GetRoutingTable(&routing_table2))
{
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&routing_table2=0x%p)",
&routing_table2);
return false;
}
// Create 3 filter rules
IPAFilteringTable FilterTable0;
struct ipa_flt_rule_add flt_rule_entry;
FilterTable0.Init(IPA_IP_v4,IPA_CLIENT_TEST2_PROD,false,3);
// Configuring Filtering Rule 0 - ETH2 DST
FilterTable0.GeneratePresetRule(1,flt_rule_entry);
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.retain_hdr = 1; // retain header removed in producer pipe
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;
// DST
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_DST_ADDR_ETHER_II;
memcpy(flt_rule_entry.rule.attrib.dst_mac_addr_mask,
m_MAC_ADDR_MASK_ALL,
sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask));
memcpy(flt_rule_entry.rule.attrib.dst_mac_addr,
m_ETH2_DST_ADDR,
sizeof(flt_rule_entry.rule.attrib.dst_mac_addr));
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(0) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(0)->status);
}
// Configuring Filtering Rule 1 - ETH2 type
flt_rule_entry.rule.rt_tbl_hdl=routing_table1.hdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_ETHER_TYPE;
flt_rule_entry.rule.attrib.ether_type = ETH_P_IP;
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(1) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(1)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(1)->status);
}
// Configuring Filtering Rule 2 - Accept all
flt_rule_entry.rule.rt_tbl_hdl = routing_table2.hdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; // Accept all
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; // Has no effect
if (((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) ||
!m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()))
{
LOG_MSG_ERROR ("Adding RuleTable(2) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(2)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(2)->status);
}
LOG_MSG_DEBUG("Leaving function\n");
return true;
}// AddRules()
virtual bool ModifyPackets()
{
uint16_t ether_type = ETH_P_IP;
uint16_t wrong_ether_type = 0x1234;
// DST && SRC correct
memcpy(&m_sendBuffer1[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer1[ETH2_SRC_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
// DST is wrong, ETH2 type is correct
memcpy(&m_sendBuffer2[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
m_sendBuffer2[ETH2_DST_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer2[ETH2_ETH_TYPE_OFFSET],
&ether_type, sizeof(ether_type));
// DST is wrong, ETH2 type is wrong
memcpy(&m_sendBuffer3[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
m_sendBuffer3[ETH2_DST_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer3[ETH2_ETH_TYPE_OFFSET],
&wrong_ether_type, sizeof(wrong_ether_type));
return true;
}// ModifyPacktes ()
};
/*---------------------------------------------------------------------------*/
/* Test 02: Destination IP address and subnet mask match against LAN subnet */
/*---------------------------------------------------------------------------*/
class IpaFilterEthIPv4Test02 : public IpaFilteringEthernetBridgingTestFixture
{
public:
IpaFilterEthIPv4Test02()
{
m_name = "IpaFilterEthIPv4Test02";
m_description =
"Filtering block test 02 - Ethernet Bridge, ETH2 filters, \
IPv4 address (EP Filtering Table, \
Insert all rules in a single commit) \
1. Generate and commit three routing tables. \
Each table contains a single \"bypass\" rule \
(all data goes to output pipe 0, 1 and 2 (accordingly)) \
2. Generate and commit 3 ETH2 filtering rules: \
All MAC SRC == (22eeddccbbaa) traffic goes to routing table 0 \
All MAC ETH TYPE == (0801) traffic goes to routing table 1 \
All (1) traffic goes to routing table 2";
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
Register(*this);
m_pCurrentProducer = &m_producer2;
}
virtual bool AddRules()
{
LOG_MSG_DEBUG("Entering");
const char bypass0[] = "bypass0";
const char bypass1[] = "bypass1";
const char bypass2[] = "bypass2";
struct ipa_ioc_get_rt_tbl routing_table0,routing_table1,routing_table2;
if (!CreateThreeIPv4BypassRoutingTables (bypass0,bypass1,bypass2))
{
printf("CreateThreeIPv4BypassRoutingTables");
return false;
}
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)",
&routing_table0);
return false;
}
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)",
&routing_table1);
return false;
}
routing_table2.ip = IPA_IP_v4;
strlcpy(routing_table2.name, bypass2, sizeof(routing_table2.name));
if (!m_routing.GetRoutingTable(&routing_table2))
{
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&routing_table2=0x%p)",
&routing_table2);
return false;
}
// Create 3 filter rules
IPAFilteringTable FilterTable0;
struct ipa_flt_rule_add flt_rule_entry;
FilterTable0.Init(IPA_IP_v4,IPA_CLIENT_TEST2_PROD,false,3);
// Configuring Filtering Rule 0 - ETH2 SRC
FilterTable0.GeneratePresetRule(1,flt_rule_entry);
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.retain_hdr = 1; // retain header removed in producer pipe
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;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_SRC_ADDR_ETHER_II;
memcpy(flt_rule_entry.rule.attrib.src_mac_addr_mask,
m_MAC_ADDR_MASK_ALL,
sizeof(flt_rule_entry.rule.attrib.src_mac_addr_mask));
memcpy(flt_rule_entry.rule.attrib.src_mac_addr,
m_ETH2_SRC_ADDR,
sizeof(flt_rule_entry.rule.attrib.src_mac_addr));
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(0) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(0)->status);
}
// Configuring Filtering Rule 1 - ETH2 type
flt_rule_entry.rule.rt_tbl_hdl=routing_table1.hdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_ETHER_TYPE;
flt_rule_entry.rule.attrib.ether_type = ETH_P_IP + 1;
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(1) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(1)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(1)->status);
}
// Configuring Filtering Rule 2 - Accept all
flt_rule_entry.rule.rt_tbl_hdl = routing_table2.hdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; // Accept all
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; // Has no effect
if (((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) ||
!m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()))
{
LOG_MSG_ERROR ("Adding RuleTable(2) to Filtering");
return false;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x",
FilterTable0.ReadRuleFromTable(2)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(2)->status);
}
LOG_MSG_DEBUG("Leaving function\n");
return true;
}// AddRules()
virtual bool ModifyPackets()
{
uint16_t ether_type = ETH_P_IP;
uint16_t wrong_ether_type = 0x1234;
memcpy(&m_sendBuffer1[ETH2_SRC_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer1[ETH2_ETH_TYPE_OFFSET],
&ether_type, sizeof(ether_type));
memcpy(&m_sendBuffer2[ETH2_SRC_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
m_sendBuffer2[ETH2_SRC_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer2[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
ether_type++;
memcpy(&m_sendBuffer2[ETH2_ETH_TYPE_OFFSET],
&ether_type, sizeof(ether_type));
memcpy(&m_sendBuffer3[ETH2_DST_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer3[ETH2_SRC_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer3[ETH2_ETH_TYPE_OFFSET],
&wrong_ether_type, sizeof(wrong_ether_type));
return true;
}// ModifyPacktes ()
};
/*---------------------------------------------------------------------------*/
/* Test 03: Destination IP address and subnet mask match against LAN subnet */
/*---------------------------------------------------------------------------*/
class IpaFilterEthIPv4Test03 : public IpaFilteringEthernetBridgingTestFixture
{
public:
IpaFilterEthIPv4Test03()
{
m_name = "IpaFilterEthIPv4Test03";
m_description =
"Filtering block test 03 - Ethernet Bridge, ETH2 filters, \
IPv4 address (EP Filtering Table, \
Insert all rules in a single commit) \
1. Generate and commit three routing tables. \
Each table contains a single \"bypass\" rule \
(all data goes to output pipe 0, 1 and 2 (accordingly)) \
2. Generate and commit 3 ETH2 filtering rules: \
All MAC SRC == (22eeddccbbaa) traffic goes to routing table 0 \
All MAC ETH TYPE == (0800) traffic goes to routing table 1 \
All (1) traffic goes to routing table 2";
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
Register(*this);
m_pCurrentProducer = &m_producer2;
}
virtual bool AddRules()
{
LOG_MSG_DEBUG("Entering");
const char bypass0[] = "bypass0";
const char bypass1[] = "bypass1";
const char bypass2[] = "bypass2";
struct ipa_ioc_get_rt_tbl routing_table0,routing_table1,routing_table2;
if (!CreateThreeIPv4BypassRoutingTables (bypass0,bypass1,bypass2))
{
printf("CreateThreeIPv4BypassRoutingTables");
return false;
}
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)",
&routing_table0);
return false;
}
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)",
&routing_table1);
return false;
}
routing_table2.ip = IPA_IP_v4;
strlcpy(routing_table2.name, bypass2, sizeof(routing_table2.name));
if (!m_routing.GetRoutingTable(&routing_table2))
{
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&routing_table2=0x%p)",
&routing_table2);
return false;
}
// Create 3 filter rules
IPAFilteringTable FilterTable0;
struct ipa_flt_rule_add flt_rule_entry;
FilterTable0.Init(IPA_IP_v4,IPA_CLIENT_TEST2_PROD,false,3);
// Configuring Filtering Rule 0 - ETH2 DST
FilterTable0.GeneratePresetRule(1,flt_rule_entry);
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.retain_hdr = 1; // retain header removed in producer pipe
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;
// SRC
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_SRC_ADDR_ETHER_II;
memcpy(flt_rule_entry.rule.attrib.src_mac_addr_mask,
m_MAC_ADDR_MASK_ALL,
sizeof(flt_rule_entry.rule.attrib.src_mac_addr_mask));
memcpy(flt_rule_entry.rule.attrib.src_mac_addr,
m_ETH2_SRC_ADDR,
sizeof(flt_rule_entry.rule.attrib.src_mac_addr));
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(0) to Filtering");
return false;
}
// Configuring Filtering Rule 1 - ETH2 type
flt_rule_entry.rule.rt_tbl_hdl=routing_table1.hdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_MAC_ETHER_TYPE;
flt_rule_entry.rule.attrib.ether_type = ETH_P_IP;
if ((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry))
{
LOG_MSG_ERROR ("Adding RuleTable(1) to Filtering");
return false;
}
// Configuring Filtering Rule 2 - Accept all
flt_rule_entry.rule.rt_tbl_hdl = routing_table2.hdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; // Accept all
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; // Has no effect
if (((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) ||
!m_filtering.AddFilteringRule(FilterTable0.GetFilteringTable()))
{
LOG_MSG_ERROR ("Adding RuleTable(2) to Filtering");
return false;
}
LOG_MSG_DEBUG("flt rule status: s0=0x%x, s1=0x%x s2=0x%x",
FilterTable0.ReadRuleFromTable(0)->status,
FilterTable0.ReadRuleFromTable(1)->status,
FilterTable0.ReadRuleFromTable(2)->status);
LOG_MSG_DEBUG("Leaving function\n");
return true;
}// AddRules()
virtual bool ModifyPackets()
{
uint16_t ether_type = ETH_P_IP;
uint16_t wrong_ether_type = 0x1234;
// SRC correct, DST wrong, ETH type wrong
memcpy(&m_sendBuffer1[ETH2_SRC_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer1[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
m_sendBuffer1[ETH2_DST_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer1[ETH2_ETH_TYPE_OFFSET],
&wrong_ether_type, sizeof(wrong_ether_type));
// SRC wrong, DST wrong, ETH type correct
memcpy(&m_sendBuffer2[ETH2_SRC_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
m_sendBuffer2[ETH2_SRC_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer2[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
m_sendBuffer2[ETH2_DST_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer2[ETH2_ETH_TYPE_OFFSET],
&ether_type, sizeof(ether_type));
// SRC wrong, DST correct, ETH type wrong
memcpy(&m_sendBuffer3[ETH2_SRC_ADDR_OFFSET],
m_ETH2_SRC_ADDR, ETH_ALEN);
m_sendBuffer3[ETH2_SRC_ADDR_OFFSET] = 0x00;
memcpy(&m_sendBuffer3[ETH2_DST_ADDR_OFFSET],
m_ETH2_DST_ADDR, ETH_ALEN);
memcpy(&m_sendBuffer3[ETH2_ETH_TYPE_OFFSET],
&wrong_ether_type, sizeof(wrong_ether_type));
return true;
}// ModifyPacktes ()
};
static IpaFilterEthIPv4Test00 ipaFilterEthIPv4Test00;
static IpaFilterEthIPv4Test01 ipaFilterEthIPv4Test01;
static IpaFilterEthIPv4Test02 ipaFilterEthIPv4Test02;
static IpaFilterEthIPv4Test03 ipaFilterEthIPv4Test03;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,178 @@
/*
* Copyright (c) 2017 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 <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include "HeaderInsertion.h"
/*All interaction through the driver are
* made through this inode.
*/
static const char* DEVICE_NAME = "/dev/ipa";
#define LOG_IOCTL_RETURN_VALUE(nRetVal) \
printf("%s()- %s\n", __func__, \
(-1 == nRetVal) ? "Fail" : "Success");
HeaderInsertion::HeaderInsertion()
{
m_fd = open(DEVICE_NAME, O_RDWR);
if (-1 == m_fd)
{
printf(
"Failed to open %s in HeaderInsertion test application constructor.\n",
DEVICE_NAME);
}
}
HeaderInsertion::~HeaderInsertion()
{
if (-1 != m_fd)
{
close(m_fd);
}
}
bool HeaderInsertion::DeviceNodeIsOpened()
{
return (-1 != m_fd);
}
bool HeaderInsertion::AddHeader(struct ipa_ioc_add_hdr *pHeaderTableToAdd)
{
int nRetVal = 0;
/*call the Driver ioctl in order to add header*/
nRetVal = ioctl(m_fd, IPA_IOC_ADD_HDR, pHeaderTableToAdd);
LOG_IOCTL_RETURN_VALUE(nRetVal);
return (-1 != nRetVal);
}
bool HeaderInsertion::DeleteHeader(struct ipa_ioc_del_hdr *pHeaderTableToDelete)
{
int nRetVal = 0;
/*call the Driver ioctl in order to remove header*/
nRetVal = ioctl(m_fd, IPA_IOC_DEL_HDR , pHeaderTableToDelete);
LOG_IOCTL_RETURN_VALUE(nRetVal);
return (-1 != nRetVal);
}
bool HeaderInsertion::AddProcCtx(struct ipa_ioc_add_hdr_proc_ctx *procCtxTable)
{
int retval = 0;
retval = ioctl(m_fd, IPA_IOC_ADD_HDR_PROC_CTX, procCtxTable);
if (retval) {
printf("%s(), failed adding ProcCtx rule table %p\n", __FUNCTION__, procCtxTable);
return false;
}
printf("%s(), Added ProcCtx rule to table %p\n", __FUNCTION__, procCtxTable);
return true;
}
bool HeaderInsertion::DeleteProcCtx(struct ipa_ioc_del_hdr_proc_ctx *procCtxTable)
{
int retval = 0;
retval = ioctl(m_fd, IPA_IOC_DEL_HDR_PROC_CTX, procCtxTable);
if (retval) {
printf("%s(), failed deleting ProcCtx rule in table %p\n", __FUNCTION__, procCtxTable);
return false;
}
printf("%s(), Deleted ProcCtx rule in table %p\n", __FUNCTION__, procCtxTable);
return true;
}
bool HeaderInsertion::Commit()
{
int nRetVal = 0;
nRetVal = ioctl(m_fd, IPA_IOC_COMMIT_HDR);
LOG_IOCTL_RETURN_VALUE(nRetVal);
return true;
}
bool HeaderInsertion::Reset()
{
int nRetVal = 0;
nRetVal = ioctl(m_fd, IPA_IOC_RESET_HDR);
nRetVal |= ioctl(m_fd, IPA_IOC_COMMIT_HDR);
LOG_IOCTL_RETURN_VALUE(nRetVal);
return true;
}
bool HeaderInsertion::GetHeaderHandle(struct ipa_ioc_get_hdr *pHeaderStruct)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_GET_HDR, pHeaderStruct);
if (retval) {
printf(
"%s(), IPA_IOC_GET_HDR ioctl failed, routingTable =0x%p, retval=0x%x.\n"
, __func__,
pHeaderStruct,
retval);
return false;
}
printf(
"%s(), IPA_IOC_GET_HDR ioctl issued to IPA header insertion block.\n",
__func__);
return true;
}
bool HeaderInsertion::CopyHeader(struct ipa_ioc_copy_hdr *pCopyHeaderStruct)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_COPY_HDR, pCopyHeaderStruct);
if (retval) {
printf(
"%s(), IPA_IOC_COPY_HDR ioctl failed, retval=0x%x.\n",
__func__,
retval);
return false;
}
printf(
"%s(), IPA_IOC_COPY_HDR ioctl issued to IPA header insertion block.\n",
__func__);
return true;
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef HEADER_INSERTION_H_
#define HEADER_INSERTION_H_
#include <stdint.h>
#include "linux/msm_ipa.h"
class HeaderInsertion
{
private:
int m_fd;
public:
bool AddHeader(struct ipa_ioc_add_hdr *pHeaderTable);
bool DeleteHeader(struct ipa_ioc_del_hdr *pHeaderTable);
bool GetHeaderHandle(struct ipa_ioc_get_hdr *pHeaderStruct);
bool CopyHeader(struct ipa_ioc_copy_hdr *pCopyHeaderStruct);
// Processing context
bool AddProcCtx(struct ipa_ioc_add_hdr_proc_ctx *procCtxTable);
bool DeleteProcCtx(struct ipa_ioc_del_hdr_proc_ctx *procCtxTable);
bool Commit();
bool Reset();
HeaderInsertion();
~HeaderInsertion();
bool DeviceNodeIsOpened();
};
#endif

View File

@@ -0,0 +1,875 @@
/*
* Copyright (c) 2017-2018 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 "RoutingDriverWrapper.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
#include "hton.h" // for htonl
#include "TestsUtils.h"
#include <string.h>
#define IPV4_DST_ADDR_OFFSET (16)
class IPAHeaderInsertionTestFixture: public TestBase {
public:
IPAHeaderInsertionTestFixture() : m_uBufferSize(0)
{
memset(m_aBuffer, 0, sizeof(m_aBuffer));
m_testSuiteName.push_back("Insertion");
}
virtual bool AddRules() = 0;
virtual bool ModifyPackets() = 0;
virtual bool TestLogic() = 0;
bool Setup()
{
ConfigureScenario(PHASE_FIVE_TEST_CONFIGURATION);
m_producer.Open(INTERFACE0_TO_IPA_DATA_PATH,
INTERFACE0_FROM_IPA_DATA_PATH);
m_Consumer1.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_Consumer3.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;
}
if (!m_HeaderInsertion.DeviceNodeIsOpened())
{
LOG_MSG_ERROR("Header Insertion block is not ready for immediate commands!\n");
return false;
}
m_HeaderInsertion.Reset();// resetting this component will reset both Routing and Filtering tables.
return true;
} // Setup()
bool Run()
{
m_uBufferSize = BUFF_MAX_SIZE;
LOG_MSG_STACK("Entering Function");
// Add the relevant filtering rules
if (!AddRules()) {
LOG_MSG_ERROR("Failed adding filtering rules.");
return false;
}
// Load input data (IP packet) from file
if (!LoadDefaultPacket(m_eIP, m_aBuffer, m_uBufferSize)) {
LOG_MSG_ERROR("Failed default Packet");
return false;
}
if (!ModifyPackets()) {
LOG_MSG_ERROR("Failed to modify packets.");
return false;
}
if (!TestLogic()) {
LOG_MSG_ERROR("Test failed, Input and expected output mismatch.");
return false;
}
LOG_MSG_STACK("Leaving Function (Returning True)");
return true;
} // Run()
bool Teardown()
{
m_HeaderInsertion.Reset();// resetting this component will reset both Routing and Filtering tables.
m_producer.Close();
m_Consumer1.Close();
m_Consumer2.Close();
m_Consumer3.Close();
return true;
} // Teardown()
~IPAHeaderInsertionTestFixture() {}
static RoutingDriverWrapper m_Routing;
static Filtering m_Filtering;
static HeaderInsertion m_HeaderInsertion;
InterfaceAbstraction m_producer;
InterfaceAbstraction m_Consumer1;
InterfaceAbstraction m_Consumer2;
InterfaceAbstraction m_Consumer3;
protected:
static const size_t BUFF_MAX_SIZE = 1024;
static const uint8_t MAX_HEADER_SIZE = 64; // 64Bytes - Max Header Length
enum ipa_ip_type m_eIP;
uint8_t m_aBuffer[BUFF_MAX_SIZE]; // Input file \ IP packet
size_t m_uBufferSize;
};
RoutingDriverWrapper IPAHeaderInsertionTestFixture::m_Routing;
Filtering IPAHeaderInsertionTestFixture::m_Filtering;
HeaderInsertion IPAHeaderInsertionTestFixture::m_HeaderInsertion;
//---------------------------------------------------------------------------/
// Test002: Test that 802.3 header was inserted Correctly /
//---------------------------------------------------------------------------/
class IPAHeaderInsertionTest001: public IPAHeaderInsertionTestFixture {
public:
IPAHeaderInsertionTest001() {
m_name = "IPAHeaderInsertionTest001";
m_description =
"Header Insertion Test 001 - Test RMNet Header Insertion\
1. Generate and commit RMNet.3 header Insertion \
2. Generate and commit routing table containing bypass rule. \
3. Generate and commit bypass filtering rule. \
4. Send a packet, and verify that the RMNet.3 Header was inserted correctly.";
Register(*this);
uint8_t aRMNetHeader[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
m_nHeadertoAddSize = sizeof(aRMNetHeader);
memcpy(m_aHeadertoAdd, aRMNetHeader, m_nHeadertoAddSize);
}
// Test Description:
// 1. Generate and commit single bypass routing table.
virtual bool AddRules() {
m_eIP = IPA_IP_v4;
const char bypass0[20] = "Bypass0";
struct ipa_ioc_get_rt_tbl sRoutingTable;
bool bRetVal = true;
struct ipa_ioc_get_hdr sRetHeader;
IPAFilteringTable cFilterTable;
struct ipa_flt_rule_add sFilterRuleEntry;
uint32_t nRTTableHdl=0;
memset(&sRoutingTable, 0, sizeof(sRoutingTable));
memset(&sRetHeader, 0, sizeof(sRetHeader));
strlcpy(sRetHeader.name, "IEEE802_3", sizeof(sRetHeader.name));
LOG_MSG_STACK("Entering Function");
// Create Header:
// Allocate Memory, populate it, and add in to the Header Insertion.
struct ipa_ioc_add_hdr * pHeaderDescriptor = NULL;
pHeaderDescriptor = (struct ipa_ioc_add_hdr *) calloc(1,
sizeof(struct ipa_ioc_add_hdr)
+ 1 * sizeof(struct ipa_hdr_add));
if (!pHeaderDescriptor) {
LOG_MSG_ERROR("calloc failed to allocate pHeaderDescriptor");
bRetVal = false;
goto bail;
}
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
strlcpy(pHeaderDescriptor->hdr[0].name, sRetHeader.name, sizeof(pHeaderDescriptor->hdr[0].name));
memcpy(pHeaderDescriptor->hdr[0].hdr, m_aHeadertoAdd,
m_nHeadertoAddSize); //Header's Data
pHeaderDescriptor->hdr[0].hdr_len = m_nHeadertoAddSize;
pHeaderDescriptor->hdr[0].hdr_hdl = -1; //Return Value
pHeaderDescriptor->hdr[0].is_partial = false;
pHeaderDescriptor->hdr[0].status = -1; // Return Parameter
strlcpy(sRetHeader.name, pHeaderDescriptor->hdr[0].name, sizeof(sRetHeader.name));
if (!m_HeaderInsertion.AddHeader(pHeaderDescriptor))
{
LOG_MSG_ERROR("m_HeaderInsertion.AddHeader(pHeaderDescriptor) Failed.");
bRetVal = false;
goto bail;
}
if (!m_HeaderInsertion.GetHeaderHandle(&sRetHeader))
{
LOG_MSG_ERROR(" Failed");
bRetVal = false;
goto bail;
}
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, bypass0, IPA_CLIENT_TEST2_CONS,
sRetHeader.hdl,&nRTTableHdl)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
LOG_MSG_INFO("CreateBypassRoutingTable completed successfully");
sRoutingTable.ip = m_eIP;
strlcpy(sRoutingTable.name, bypass0, sizeof(sRoutingTable.name));
if (!m_Routing.GetRoutingTable(&sRoutingTable)) {
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&sRoutingTable=0x%p) Failed.", &sRoutingTable);
bRetVal = false;
goto bail;
}
// Creating Filtering Rules
cFilterTable.Init(m_eIP,IPA_CLIENT_TEST_PROD,false,1);
LOG_MSG_INFO("Creation of filtering table completed successfully");
// Configuring Filtering Rule No.1
cFilterTable.GeneratePresetRule(0,sFilterRuleEntry);
sFilterRuleEntry.at_rear = true;
sFilterRuleEntry.flt_rule_hdl = -1; // return Value
sFilterRuleEntry.status = -1; // return value
sFilterRuleEntry.rule.action = IPA_PASS_TO_ROUTING;
sFilterRuleEntry.rule.rt_tbl_hdl = nRTTableHdl; //put here the handle corresponding to Routing Rule 1
if (
((uint8_t)-1 == cFilterTable.AddRuleToTable(sFilterRuleEntry)) ||
!m_Filtering.AddFilteringRule(cFilterTable.GetFilteringTable())
)
{
LOG_MSG_ERROR ("Adding Rule (0) to Filtering block Failed.");
bRetVal = false;
goto bail;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable.ReadRuleFromTable(0)->flt_rule_hdl,cFilterTable.ReadRuleFromTable(0)->status);
}
bail:
Free(pHeaderDescriptor);
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddRules()
virtual bool ModifyPackets() {
// This test doesn't modify the original IP Packet.
return true;
} // ModifyPacktes ()
virtual bool TestLogic() {
memset(m_aExpectedBuffer, 0, sizeof(m_aExpectedBuffer));
m_aExpectedBufSize = 0;
memcpy(m_aExpectedBuffer, m_aHeadertoAdd, m_nHeadertoAddSize);
memcpy(m_aExpectedBuffer+m_nHeadertoAddSize,m_aBuffer,m_uBufferSize);
m_aExpectedBufSize = m_nHeadertoAddSize + m_uBufferSize;
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Consumer1, m_aExpectedBuffer, m_aExpectedBufSize)) {
LOG_MSG_ERROR("SendReceiveAndCompare failed.");
return false;
}
return true;
}
private:
uint8_t m_aExpectedBuffer[BUFF_MAX_SIZE]; // Input file / IP packet
size_t m_aExpectedBufSize;
uint8_t m_aHeadertoAdd[MAX_HEADER_SIZE];
size_t m_nHeadertoAddSize;
};
//---------------------------------------------------------------------------/
// Test002: Test that 802.3 header was inserted Correctly /
//---------------------------------------------------------------------------/
class IPAHeaderInsertionTest002: public IPAHeaderInsertionTestFixture {
public:
IPAHeaderInsertionTest002() {
m_name = "IPAHeaderInsertionTest002";
m_description =
"Header Insertion Test 002 - Test IEEE802.3 Header Insertion\
1. Generate and commit IEEE802.3 header Insertion \
2. Generate and commit routing table containing bypass rule. \
3. Generate and commit bypass filtering rule. \
4. Send a packet, and verify that the IEEE802.3 Header was inserted correctly \
and that the header Length was updated as well";
Register(*this);
uint8_t aIEEE802_3Header[22] = { 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x00, 0x46, 0xAE, 0xAF, 0xB0,// the correct size (00 46) is inserted here.
0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 };
m_nHeadertoAddSize = sizeof(aIEEE802_3Header);
memcpy(m_aHeadertoAdd, aIEEE802_3Header, m_nHeadertoAddSize);
}
// Test Description:
// 1. Generate and commit single bypass routing table.
virtual bool AddRules() {
m_eIP = IPA_IP_v4;
const char bypass0[20] = "Bypass0";
struct ipa_ioc_get_rt_tbl sRoutingTable;
bool bRetVal = true;
struct ipa_ioc_get_hdr sRetHeader;
IPAFilteringTable cFilterTable;
struct ipa_flt_rule_add sFilterRuleEntry;
uint32_t nRTTableHdl=0;
memset(&sRoutingTable, 0, sizeof(sRoutingTable));
memset(&sRetHeader, 0, sizeof(sRetHeader));
strlcpy(sRetHeader.name, "IEEE802_3", sizeof(sRetHeader.name));
LOG_MSG_STACK("Entering Function");
// Create Header:
// Allocate Memory, populate it, and add in to the Header Insertion.
struct ipa_ioc_add_hdr * pHeaderDescriptor = NULL;
pHeaderDescriptor = (struct ipa_ioc_add_hdr *) calloc(1,
sizeof(struct ipa_ioc_add_hdr)
+ 1 * sizeof(struct ipa_hdr_add));
if (!pHeaderDescriptor) {
LOG_MSG_ERROR("calloc failed to allocate pHeaderDescriptor");
bRetVal = false;
goto bail;
}
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
strlcpy(pHeaderDescriptor->hdr[0].name, sRetHeader.name, sizeof(pHeaderDescriptor->hdr[0].name)); // Header's Name
memcpy(pHeaderDescriptor->hdr[0].hdr, m_aHeadertoAdd,
m_nHeadertoAddSize); //Header's Data
pHeaderDescriptor->hdr[0].hdr[12] = 0x00; //set length to zero, to confirm if ipa updates or not
pHeaderDescriptor->hdr[0].hdr_len = m_nHeadertoAddSize;
pHeaderDescriptor->hdr[0].hdr_hdl = -1; //Return Value
pHeaderDescriptor->hdr[0].is_partial = false;
pHeaderDescriptor->hdr[0].status = -1; // Return Parameter
strlcpy(sRetHeader.name, pHeaderDescriptor->hdr[0].name, sizeof(sRetHeader.name));
if (!m_HeaderInsertion.AddHeader(pHeaderDescriptor))
{
LOG_MSG_ERROR("m_HeaderInsertion.AddHeader(pHeaderDescriptor) Failed.");
bRetVal = false;
goto bail;
}
if (!m_HeaderInsertion.GetHeaderHandle(&sRetHeader))
{
LOG_MSG_ERROR(" Failed");
bRetVal = false;
goto bail;
}
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, bypass0, IPA_CLIENT_TEST3_CONS,
sRetHeader.hdl,&nRTTableHdl)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
LOG_MSG_INFO("CreateBypassRoutingTable completed successfully");
sRoutingTable.ip = m_eIP;
strlcpy(sRoutingTable.name, bypass0, sizeof(sRoutingTable.name));
if (!m_Routing.GetRoutingTable(&sRoutingTable)) {
LOG_MSG_ERROR(
"m_routing.GetRoutingTable(&sRoutingTable=0x%p) Failed.", &sRoutingTable);
bRetVal = false;
goto bail;
}
// Creating Filtering Rules
cFilterTable.Init(m_eIP,IPA_CLIENT_TEST_PROD,false,1);
LOG_MSG_INFO("Creation of filtering table completed successfully");
// Configuring Filtering Rule No.1
cFilterTable.GeneratePresetRule(0,sFilterRuleEntry);
sFilterRuleEntry.at_rear = true;
sFilterRuleEntry.flt_rule_hdl = -1; // return Value
sFilterRuleEntry.status = -1; // return value
sFilterRuleEntry.rule.action = IPA_PASS_TO_ROUTING;
sFilterRuleEntry.rule.rt_tbl_hdl = nRTTableHdl; //put here the handle corresponding to Routing Rule 1
if (
((uint8_t)-1 == cFilterTable.AddRuleToTable(sFilterRuleEntry)) ||
!m_Filtering.AddFilteringRule(cFilterTable.GetFilteringTable())
)
{
LOG_MSG_ERROR ("Adding Rule (0) to Filtering block Failed.");
bRetVal = false;
goto bail;
} else
{
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable.ReadRuleFromTable(0)->flt_rule_hdl,cFilterTable.ReadRuleFromTable(0)->status);
}
bail:
Free(pHeaderDescriptor);
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddRules()
virtual bool ModifyPackets() {
// This test doesn't modify the original IP Packet.
return true;
} // ModifyPacktes ()
virtual bool TestLogic() {
memset(m_aExpectedBuffer, 0, sizeof(m_aExpectedBuffer));
m_aExpectedBufSize = 0;
memcpy(m_aExpectedBuffer, m_aHeadertoAdd, m_nHeadertoAddSize);
memcpy(m_aExpectedBuffer+m_nHeadertoAddSize,m_aBuffer,m_uBufferSize);
m_aExpectedBufSize = m_nHeadertoAddSize + m_uBufferSize;
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Consumer2, m_aExpectedBuffer, m_aExpectedBufSize)) {
LOG_MSG_ERROR("SendReceiveAndCompare failed.");
return false;
}
return true;
}
private:
uint8_t m_aExpectedBuffer[BUFF_MAX_SIZE]; // Input file / IP packet
size_t m_aExpectedBufSize;
uint8_t m_aHeadertoAdd[MAX_HEADER_SIZE];
size_t m_nHeadertoAddSize;
};
//---------------------------------------------------------------------------/
// Test003: Test Three Different Header Insertions /
//---------------------------------------------------------------------------/
class IPAHeaderInsertionTest003: public IPAHeaderInsertionTestFixture {
public:
IPAHeaderInsertionTest003() :
m_aExpectedBufSize(BUFF_MAX_SIZE),
m_nHeadertoAddSize1(0),
m_nHeadertoAddSize2(0),
m_nHeadertoAddSize3(0)
{
m_name = "IPAHeaderInsertionTest003";
m_description =
"Header Insertion Test 003 - Test RmNet,IEEE802.3 and IEEE802.3 with const (1) addition to the length field\
1. Generate and commit two types of header Insertion RmNet and IEE802.3 \
2. Generate and commit three routing tables. \
Each table contains a single \"bypass\" rule (all data goes to output pipe 0, 1 and 2 (accordingly)) \
Routing table 1 is used to add RmNet Header \
Routing table 2 is used to add IEEE802.3 Header (requires update of the Length field) \
Routing table 3 is used to add IEEE802.3 Header with additional const (1) to the length field \
3. Generate and commit Three filtering rules (MASK = 0xFF..FF). \
All DST_IP == 127.0.0.1 traffic goes to routing table 1 \
All DST_IP == 192.169.1.1 traffic goes to routing table 2 \
All DST_IP == 192.169.1.2 traffic goes to routing table 3";
Register(*this);
uint8_t aRMNetHeader[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
uint8_t aIEEE802_3Header1[22] = { 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x00, 0x46, 0xAE, 0xAF, 0xB0,
0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 };
uint8_t aIEEE802_3Header2[22] = { 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x00, 0x47, 0xAE, 0xAF, 0xB0,
0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 };
m_nHeadertoAddSize1 = sizeof(aRMNetHeader);
memcpy(m_aHeadertoAdd1, aRMNetHeader, m_nHeadertoAddSize1);
m_nHeadertoAddSize2 = sizeof(aIEEE802_3Header1);
memcpy(m_aHeadertoAdd2, aIEEE802_3Header1, m_nHeadertoAddSize2);
m_nHeadertoAddSize3 = sizeof(aIEEE802_3Header2);
memcpy(m_aHeadertoAdd3, aIEEE802_3Header2, m_nHeadertoAddSize3);
}
// Test Description:
// 1. Generate and commit single bypass routing table.
virtual bool AddRules() {
m_eIP = IPA_IP_v4;
const char aBypass1[20] = "Bypass1";
const char aBypass2[20] = "Bypass2";
const char aBypass3[20] = "Bypass3";
uint32_t nTableHdl01, nTableHdl02, nTableHdl03;
bool bRetVal = true;
IPAFilteringTable cFilterTable0;
struct ipa_flt_rule_add sFilterRuleEntry;
struct ipa_ioc_get_hdr sGetHeader1,sGetHeader2;
LOG_MSG_STACK("Entering Function");
memset(&sFilterRuleEntry, 0, sizeof(sFilterRuleEntry));
memset(&sGetHeader1, 0, sizeof(sGetHeader1));
memset(&sGetHeader2, 0, sizeof(sGetHeader2));
// Create Header:
// Allocate Memory, populate it, and add in to the Header Insertion.
struct ipa_ioc_add_hdr * pHeaderDescriptor = NULL;
pHeaderDescriptor = (struct ipa_ioc_add_hdr *) calloc(1,
sizeof(struct ipa_ioc_add_hdr)
+ 2 * sizeof(struct ipa_hdr_add));
if (!pHeaderDescriptor) {
LOG_MSG_ERROR("calloc failed to allocate pHeaderDescriptor");
bRetVal = false;
goto bail;
}
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 2;
// Adding Header No1.
strlcpy(pHeaderDescriptor->hdr[0].name, "RMNet", sizeof(pHeaderDescriptor->hdr[0].name)); // Header's Name
memcpy(pHeaderDescriptor->hdr[0].hdr, m_aHeadertoAdd1,
m_nHeadertoAddSize1); //Header's Data
pHeaderDescriptor->hdr[0].hdr_len = m_nHeadertoAddSize1;
pHeaderDescriptor->hdr[0].hdr_hdl = -1; //Return Value
pHeaderDescriptor->hdr[0].is_partial = false;
pHeaderDescriptor->hdr[0].status = -1; // Return Parameter
// Adding Header No2.
strlcpy(pHeaderDescriptor->hdr[1].name, "IEEE_802_3", sizeof(pHeaderDescriptor->hdr[1].name)); // Header's Name
memcpy(pHeaderDescriptor->hdr[1].hdr, m_aHeadertoAdd2,
m_nHeadertoAddSize2); //Header's Data
pHeaderDescriptor->hdr[1].hdr_len = m_nHeadertoAddSize2;
pHeaderDescriptor->hdr[1].hdr_hdl = -1; //Return Value
pHeaderDescriptor->hdr[1].is_partial = false;
pHeaderDescriptor->hdr[1].status = -1; // Return Parameter
strlcpy(sGetHeader1.name, pHeaderDescriptor->hdr[0].name, sizeof(sGetHeader1.name));
strlcpy(sGetHeader2.name, pHeaderDescriptor->hdr[1].name, sizeof(sGetHeader2.name));
if (!m_HeaderInsertion.AddHeader(pHeaderDescriptor))
{
LOG_MSG_ERROR("m_HeaderInsertion.AddHeader(pHeaderDescriptor) Failed.");
bRetVal = false;
goto bail;
}
if (!m_HeaderInsertion.GetHeaderHandle(&sGetHeader1))
{
LOG_MSG_ERROR(" Failed");
bRetVal = false;
goto bail;
}
LOG_MSG_DEBUG("Received Header1 Handle = 0x%x",sGetHeader1.hdl);
if (!m_HeaderInsertion.GetHeaderHandle(&sGetHeader2))
{
LOG_MSG_ERROR(" Failed");
bRetVal = false;
goto bail;
}
LOG_MSG_DEBUG("Received Header2 Handle = 0x%x",sGetHeader2.hdl);
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, aBypass1, IPA_CLIENT_TEST2_CONS,
sGetHeader1.hdl,&nTableHdl01)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, aBypass2, IPA_CLIENT_TEST3_CONS,
sGetHeader2.hdl,&nTableHdl02)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
if (!CreateBypassRoutingTable(&m_Routing, m_eIP, aBypass3, IPA_CLIENT_TEST4_CONS,
sGetHeader2.hdl,&nTableHdl03)) {
LOG_MSG_ERROR("CreateBypassRoutingTable Failed\n");
bRetVal = false;
goto bail;
}
LOG_MSG_INFO("Creation of three bypass routing tables completed successfully TblHdl1=0x%x, TblHdl2=0x%x, TblHdl3=0x%x",
nTableHdl01,nTableHdl02,nTableHdl03);
// Creating Filtering Rules
cFilterTable0.Init(m_eIP,IPA_CLIENT_TEST_PROD,false,3);
LOG_MSG_INFO("Creation of filtering table completed successfully");
// Configuring Filtering Rule No.1
cFilterTable0.GeneratePresetRule(1,sFilterRuleEntry);
sFilterRuleEntry.at_rear = true;
sFilterRuleEntry.flt_rule_hdl=-1; // return Value
sFilterRuleEntry.status = -1; // return value
sFilterRuleEntry.rule.action=IPA_PASS_TO_ROUTING;
sFilterRuleEntry.rule.rt_tbl_hdl=nTableHdl01; //put here the handle corresponding to Routing Rule 1
sFilterRuleEntry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; // Destination IP Based Filtering
sFilterRuleEntry.rule.attrib.u.v4.dst_addr_mask = 0xFF0000FF; // Mask
sFilterRuleEntry.rule.attrib.u.v4.dst_addr = 0x7F000001; // Filter DST_IP == 127.0.0.1.
if ((uint8_t)-1 == cFilterTable0.AddRuleToTable(sFilterRuleEntry))
{
LOG_MSG_ERROR ("Adding Rule (0) to Filtering table Failed.");
bRetVal = false;
goto bail;
}
// Configuring Filtering Rule No.2
sFilterRuleEntry.flt_rule_hdl=-1; // return Value
sFilterRuleEntry.status = -1; // return Value
sFilterRuleEntry.rule.rt_tbl_hdl=nTableHdl02; //put here the handle corresponding to Routing Rule 2
sFilterRuleEntry.rule.attrib.u.v4.dst_addr = 0xC0A80101; // Filter DST_IP == 192.168.1.1.
if ((uint8_t)-1 == cFilterTable0.AddRuleToTable(sFilterRuleEntry))
{
LOG_MSG_ERROR ("Adding Rule(1) to Filtering table Failed.");
bRetVal = false;
goto bail;
}
// Configuring Filtering Rule No.3
sFilterRuleEntry.flt_rule_hdl=-1; // return Value
sFilterRuleEntry.status = -1; // return value
sFilterRuleEntry.rule.rt_tbl_hdl=nTableHdl03; //put here the handle corresponding to Routing Rule 2
sFilterRuleEntry.rule.attrib.u.v4.dst_addr = 0xC0A80102; // Filter DST_IP == 192.168.1.2.
if ((uint8_t)-1 == cFilterTable0.AddRuleToTable(sFilterRuleEntry))
{
LOG_MSG_ERROR ("Adding Rule(2) to Filtering table Failed.");
bRetVal = false;
goto bail;
}
if (!m_Filtering.AddFilteringRule(cFilterTable0.GetFilteringTable())) {
LOG_MSG_ERROR ("Failed to commit Filtering rules");
bRetVal = false;
goto bail;
}
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable0.ReadRuleFromTable(0)->flt_rule_hdl,cFilterTable0.ReadRuleFromTable(0)->status);
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable0.ReadRuleFromTable(1)->flt_rule_hdl,cFilterTable0.ReadRuleFromTable(1)->status);
LOG_MSG_DEBUG("flt rule hdl0=0x%x, status=0x%x\n", cFilterTable0.ReadRuleFromTable(2)->flt_rule_hdl,cFilterTable0.ReadRuleFromTable(2)->status);
bail:
Free(pHeaderDescriptor);
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddRules()
virtual bool ModifyPackets() {
// This test doesn't modify the original IP Packet.
return true;
} // ModifyPacktes ()
virtual bool TestLogic() {
bool bRetVal = true;
m_aExpectedBufSize = 0;
uint32_t nIPv4DSTAddr;
LOG_MSG_STACK("Entering Function");
//Packet No. 1
memset(m_aExpectedBuffer, 0, sizeof(m_aExpectedBuffer));
nIPv4DSTAddr = ntohl(0x7F000001);
memcpy (&m_aBuffer[IPV4_DST_ADDR_OFFSET],&nIPv4DSTAddr,sizeof(nIPv4DSTAddr));
memcpy(m_aExpectedBuffer, m_aHeadertoAdd1, m_nHeadertoAddSize1);
memcpy(m_aExpectedBuffer+m_nHeadertoAddSize1,m_aBuffer,m_uBufferSize);
m_aExpectedBufSize = m_nHeadertoAddSize1 + m_uBufferSize;
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Consumer1, m_aExpectedBuffer, m_aExpectedBufSize))
{
LOG_MSG_ERROR("SendReceiveAndCompare failed.");
bRetVal=false;
}
//Packet No. 2
memset(m_aExpectedBuffer, 0, sizeof(m_aExpectedBuffer));
nIPv4DSTAddr = ntohl(0xC0A80101);//192.168.1.1
memcpy (&m_aBuffer[IPV4_DST_ADDR_OFFSET],&nIPv4DSTAddr,sizeof(nIPv4DSTAddr));
memcpy(m_aExpectedBuffer, m_aHeadertoAdd2, m_nHeadertoAddSize2);
memcpy(m_aExpectedBuffer+m_nHeadertoAddSize2,m_aBuffer,m_uBufferSize);
m_aExpectedBufSize = m_nHeadertoAddSize2 + m_uBufferSize;
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Consumer2, m_aExpectedBuffer, m_aExpectedBufSize))
{
LOG_MSG_ERROR("SendReceiveAndCompare failed.");
bRetVal=false;
}
//Packet No. 3
nIPv4DSTAddr = ntohl(0xC0A80102);//192.168.1.2
memcpy (&m_aBuffer[IPV4_DST_ADDR_OFFSET],&nIPv4DSTAddr,sizeof(nIPv4DSTAddr));
memcpy(m_aExpectedBuffer, m_aHeadertoAdd3, m_nHeadertoAddSize3);
memcpy(m_aExpectedBuffer+m_nHeadertoAddSize3,m_aBuffer,m_uBufferSize);
m_aExpectedBufSize = m_nHeadertoAddSize3 + m_uBufferSize;
if (!SendReceiveAndCompare(&m_producer, m_aBuffer, m_uBufferSize,
&m_Consumer3, m_aExpectedBuffer, m_aExpectedBufSize))
{
LOG_MSG_ERROR("SendReceiveAndCompare failed.");
bRetVal=false;
}
LOG_MSG_STACK("Leaving Function (Returning %s)",bRetVal?"True":"False");
return bRetVal;
}
private:
uint8_t m_aExpectedBuffer[BUFF_MAX_SIZE]; // Input file / IP packet
size_t m_aExpectedBufSize;
uint8_t m_aHeadertoAdd1[MAX_HEADER_SIZE],m_aHeadertoAdd2[MAX_HEADER_SIZE],m_aHeadertoAdd3[MAX_HEADER_SIZE];
size_t m_nHeadertoAddSize1,m_nHeadertoAddSize2,m_nHeadertoAddSize3;
};
class IPAHeaderInsertionTest004: public IPAHeaderInsertionTestFixture {
public:
IPAHeaderInsertionTest004() {
m_name = "IPAHeaderInsertionTest004";
m_description =
"Header Insertion Test 004 - Test header insertion with bad len values.";
Register(*this);
uint8_t aRMNetHeader[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
m_nHeadertoAddSize = sizeof(aRMNetHeader);
memcpy(m_aHeadertoAdd, aRMNetHeader, m_nHeadertoAddSize);
}
virtual bool AddRules() {
// Not adding any rules here.
return true;
} // AddRules()
virtual bool ModifyPackets() {
// This test doesn't modify the original IP Packet.
return true;
} // ModifyPacktes ()
bool AddSingleHeaderAndCheck(uint8_t len) {
m_eIP = IPA_IP_v4;
bool bRetVal = true;
struct ipa_ioc_get_hdr sRetHeader;
memset(&sRetHeader, 0, sizeof(sRetHeader));
strlcpy(sRetHeader.name, "Generic", sizeof(sRetHeader.name));
LOG_MSG_STACK("Entering Function");
// Create Header:
// Allocate Memory, populate it, and add in to the Header Insertion.
struct ipa_ioc_add_hdr * pHeaderDescriptor = NULL;
pHeaderDescriptor = (struct ipa_ioc_add_hdr *) calloc(1,
sizeof(struct ipa_ioc_add_hdr)
+ 1 * sizeof(struct ipa_hdr_add));
if (!pHeaderDescriptor) {
LOG_MSG_ERROR("calloc failed to allocate pHeaderDescriptor");
bRetVal = false;
goto bail;
}
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
strlcpy(pHeaderDescriptor->hdr[0].name, sRetHeader.name, sizeof(pHeaderDescriptor->hdr[0].name));
memcpy(pHeaderDescriptor->hdr[0].hdr, m_aHeadertoAdd,
m_nHeadertoAddSize); //Header's Data
pHeaderDescriptor->hdr[0].hdr_len = len;
pHeaderDescriptor->hdr[0].hdr_hdl = -1; //Return Value
pHeaderDescriptor->hdr[0].is_partial = false;
pHeaderDescriptor->hdr[0].status = -1; // Return Parameter
strlcpy(sRetHeader.name, pHeaderDescriptor->hdr[0].name, sizeof(sRetHeader.name));
if (!m_HeaderInsertion.AddHeader(pHeaderDescriptor))
{
LOG_MSG_ERROR("m_HeaderInsertion.AddHeader(pHeaderDescriptor) Failed.");
bRetVal = false;
goto bail;
}
if (!m_HeaderInsertion.GetHeaderHandle(&sRetHeader))
{
LOG_MSG_ERROR(" Failed");
bRetVal = false;
goto bail;
}
bail:
Free(pHeaderDescriptor);
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddSingleHeaderAndCheck()
virtual bool TestLogic() {
// Try to add headers with invalid values.
// Valid values are between 1 to IPA_HDR_MAX_SIZE (64).
// We expect the below functions to fail.
if (AddSingleHeaderAndCheck(0)) {
LOG_MSG_ERROR("This is unexpected, this can't succeed");
return false;
}
if (AddSingleHeaderAndCheck(MAX_HEADER_SIZE + 1)) {
LOG_MSG_ERROR("This is unexpected, this can't succeed");
return false;
}
// Add one header which is OK
if (!AddSingleHeaderAndCheck(m_nHeadertoAddSize)) {
LOG_MSG_ERROR("This is unexpected, this can't succeed");
return false;
}
return true;
}
private:
uint8_t m_aHeadertoAdd[MAX_HEADER_SIZE];
size_t m_nHeadertoAddSize;
};
class IPAHeaderInsertionTest005: public IPAHeaderInsertionTestFixture {
public:
IPAHeaderInsertionTest005() {
m_name = "IPAHeaderInsertionTest005";
m_description =
"Header Insertion Test 005 - Test Multiple RMNet Header Insertion\
- Stress test - Generate and commit multiple header Insertion";
this->m_runInRegression = false;
Register(*this);
uint8_t aRMNetHeader[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
m_nHeadertoAddSize = sizeof(aRMNetHeader);
memcpy(m_aHeadertoAdd, aRMNetHeader, m_nHeadertoAddSize);
}
// Test Description:
// 1. Generate and commit single bypass routing table.
virtual bool AddRules() {
m_eIP = IPA_IP_v4;
bool bRetVal = true;
struct ipa_ioc_get_hdr sRetHeader;
char Name[] = "IEEE802_3\0";
memset(&sRetHeader, 0, sizeof(sRetHeader));
strlcpy (sRetHeader.name, Name, sizeof(sRetHeader.name));
LOG_MSG_STACK("Entering Function");
// Create Header:
// Allocate Memory, populate it, and add in to the Header Insertion.
struct ipa_ioc_add_hdr * pHeaderDescriptor = NULL;
pHeaderDescriptor = (struct ipa_ioc_add_hdr *) calloc(1,
sizeof(struct ipa_ioc_add_hdr)
+ 1 * sizeof(struct ipa_hdr_add));
if (!pHeaderDescriptor) {
LOG_MSG_ERROR("calloc failed to allocate pHeaderDescriptor");
bRetVal = false;
goto bail;
}
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
strlcpy(pHeaderDescriptor->hdr[0].name, sRetHeader.name, sizeof(pHeaderDescriptor->hdr[0].name));
memcpy(pHeaderDescriptor->hdr[0].hdr, m_aHeadertoAdd,
m_nHeadertoAddSize); //Header's Data
pHeaderDescriptor->hdr[0].hdr_len = m_nHeadertoAddSize;
pHeaderDescriptor->hdr[0].hdr_hdl = -1; //Return Value
pHeaderDescriptor->hdr[0].is_partial = false;
pHeaderDescriptor->hdr[0].status = -1; // Return Parameter
strlcpy(sRetHeader.name, pHeaderDescriptor->hdr[0].name, sizeof(sRetHeader.name));
// stress test to check if the target crashes, failure is expected before reaching 500
for (int i = 0; i < 500; i++) {
LOG_MSG_DEBUG("IPAHeaderInsertionTest005::AddRules iter=%d\n",i);
if (!m_HeaderInsertion.AddHeader(pHeaderDescriptor))
{
LOG_MSG_ERROR("m_HeaderInsertion.AddHeader(pHeaderDescriptor) Failed on %d iteration.\n",i);
goto bail;
}
}
bail:
Free(pHeaderDescriptor);
LOG_MSG_STACK(
"Leaving Function (Returning %s)", bRetVal?"True":"False");
return bRetVal;
} // AddRules()
virtual bool ModifyPackets() {
// This test doesn't modify the original IP Packet.
return true;
} // ModifyPacktes ()
virtual bool TestLogic() {
return true;
}
private:
uint8_t m_aHeadertoAdd[MAX_HEADER_SIZE];
size_t m_nHeadertoAddSize;
};
static IPAHeaderInsertionTest001 ipaHeaderInsertionTest001;
static IPAHeaderInsertionTest002 ipaHeaderInsertionTest002;
static IPAHeaderInsertionTest003 ipaHeaderInsertionTest003;
static IPAHeaderInsertionTest004 ipaHeaderInsertionTest004;
static IPAHeaderInsertionTest005 ipaHeaderInsertionTest005;

View File

@@ -0,0 +1,618 @@
/*
* Copyright (c) 2017-2019 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 "HeaderProcessingContextTestFixture.h"
#include "TestsUtils.h"
const Byte IpaHdrProcCtxTestFixture::WLAN_ETH2_HDR[WLAN_ETH2_HDR_SIZE] =
{
// WLAN hdr - 4 bytes
0xa1, 0xb2, 0xc3, 0xd4,
// ETH2 - 14 bytes
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
const Byte IpaHdrProcCtxTestFixture::ETH2_HDR[ETH_HLEN] =
{
// ETH2 - 14 bytes
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
const Byte IpaHdrProcCtxTestFixture::ETH2_8021Q_HDR[ETH8021Q_HEADER_LEN] =
{
// 802_1Q - 18 bytes
// src and dst MAC - 6 + 6 bytes
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 802_1Q tag - VLAN ID 3
0x81, 0x00, 0x00, 0x03,
// ethertype
0x00, 0x00
};
const Byte IpaHdrProcCtxTestFixture::WLAN_802_3_HDR[WLAN_802_3_HDR_SIZE] =
{
// WLAN hdr - 4 bytes
0x0a, 0x0b, 0x0c, 0x0d,
// 802_3 - 26 bytes
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
IpaHdrProcCtxTestFixture::IpaHdrProcCtxTestFixture():
m_procCtxHandleId(PROC_CTX_HANDLE_ID_MAX),
m_pCurrentProducer(NULL),
m_pCurrentConsumer(NULL),
m_sendSize1 (m_BUFF_MAX_SIZE),
m_sendSize2 (m_BUFF_MAX_SIZE),
m_expectedBufferSize1(0),
m_IpaIPType(IPA_IP_v4)
{
memset(m_headerHandles, 0, sizeof(m_headerHandles));
memset(m_procCtxHHandles, 0, sizeof(m_procCtxHHandles));
memset(m_sendBuffer1, 0, sizeof(m_sendBuffer1));
memset(m_sendBuffer2, 0, sizeof(m_sendBuffer2));
memset(m_expectedBuffer1, 0, sizeof(m_expectedBuffer1));
m_testSuiteName.push_back("HdrProcCtx");
}
bool IpaHdrProcCtxTestFixture::Setup()
{
ConfigureScenario(PHASE_TWENTY_TEST_CONFIGURATION);
// init producers
m_rndisEth2Producer.Open(INTERFACE0_TO_IPA_DATA_PATH,
INTERFACE0_FROM_IPA_DATA_PATH);
m_wlanEth2producer.Open(INTERFACE4_TO_IPA_DATA_PATH,
INTERFACE4_FROM_IPA_DATA_PATH);
m_eth2Producer.Open(INTERFACE5_TO_IPA_DATA_PATH,
INTERFACE5_FROM_IPA_DATA_PATH);
// init consumers
m_defaultConsumer.Open(INTERFACE1_TO_IPA_DATA_PATH,
INTERFACE1_FROM_IPA_DATA_PATH);
m_rndisEth2Consumer.Open(INTERFACE2_TO_IPA_DATA_PATH,
INTERFACE2_FROM_IPA_DATA_PATH);
if (!m_headerInsertion.DeviceNodeIsOpened())
{
LOG_MSG_ERROR("HeaderInsertion block is not ready "
"for immediate commands!\n");
return false;
}
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;
}
// resetting this component will reset
// both Routing and Filtering tables
m_headerInsertion.Reset();
return true;
} // Setup()
bool IpaHdrProcCtxTestFixture::Teardown()
{
m_rndisEth2Producer.Close();
m_wlanEth2producer.Close();
m_eth2Producer.Close();
m_defaultConsumer.Close();
m_rndisEth2Consumer.Close();
return true;
} // Teardown()
void IpaHdrProcCtxTestFixture::AddAllHeaders()
{
for (int i = 0; i < HEADER_HANDLE_ID_MAX; i++) {
AddHeader(static_cast<HeaderHandleId>(i));
}
}
// Insert a single header
void IpaHdrProcCtxTestFixture::AddHeader(HeaderHandleId handleId)
{
static const int NUM_OF_HEADERS = 1;
struct ipa_ioc_add_hdr *hdrTable = NULL;
struct ipa_hdr_add *hdr = NULL;
// init hdr table
hdrTable = (struct ipa_ioc_add_hdr *) calloc(1,
sizeof(struct ipa_ioc_add_hdr)
+ NUM_OF_HEADERS * sizeof(struct ipa_hdr_add));
if (!hdrTable)
{
LOG_MSG_ERROR(
"calloc failed to allocate pHeaderDescriptor");
return;
}
hdrTable->commit = true;
hdrTable->num_hdrs = NUM_OF_HEADERS;
// init the hdr common fields
hdr = &hdrTable->hdr[0];
hdr->hdr_hdl = -1; //Return Value
hdr->is_partial = false;
hdr->status = -1; // Return Parameter
// init hdr specific fields
switch (handleId)
{
case HEADER_HANDLE_ID_WLAN_ETH2:
memcpy(hdr->hdr, WLAN_ETH2_HDR, WLAN_ETH2_HDR_SIZE);
hdr->hdr_len = WLAN_ETH2_HDR_SIZE;
strlcpy(hdr->name, "WLAN_ETH2", sizeof(hdr->name));
hdr->type = IPA_HDR_L2_ETHERNET_II;
break;
case HEADER_HANDLE_ID_RNDIS_ETH2:
if (!RNDISAggregationHelper::LoadRNDISEth2IP4Header(
hdr->hdr,
IPA_HDR_MAX_SIZE,
0,
(size_t*)&hdr->hdr_len))
return;
strlcpy(hdr->name, "RNDIS_ETH2", sizeof(hdr->name));
hdr->type = IPA_HDR_L2_ETHERNET_II;
break;
case HEADER_HANDLE_ID_ETH2:
strlcpy(hdr->name, "ETH2", sizeof(hdr->name));
memcpy(hdr->hdr, ETH2_HDR, ETH_HLEN);
hdr->type = IPA_HDR_L2_ETHERNET_II;
hdr->hdr_len = ETH_HLEN;
break;
case HEADER_HANDLE_ID_WLAN_802_3:
strlcpy(hdr->name, "WLAN_802_3", sizeof(hdr->name));
memcpy(hdr->hdr, WLAN_802_3_HDR, WLAN_802_3_HDR_SIZE);
hdr->type = IPA_HDR_L2_802_3;
hdr->hdr_len = WLAN_802_3_HDR_SIZE;
LOG_MSG_DEBUG(
"HEADER_HANDLE_ID_WLAN_802_3 NOT supported for now");
return;
break;
case HEADER_HANDLE_ID_VLAN_802_1Q:
strlcpy(hdr->name, "VLAN_8021Q", sizeof(hdr->name));
memcpy(hdr->hdr, ETH2_8021Q_HDR, ETH8021Q_HEADER_LEN);
hdr->type = IPA_HDR_L2_802_1Q;
hdr->hdr_len = ETH8021Q_HEADER_LEN;
break;
default:
LOG_MSG_ERROR("header handleId not supported.");
return;
}
// commit header to HW
if (!m_headerInsertion.AddHeader(hdrTable))
{
LOG_MSG_ERROR("m_headerInsertion.AddHeader() failed.");
return;
}
// save header handle
m_headerHandles[handleId] = hdr->hdr_hdl;
}
void IpaHdrProcCtxTestFixture::AddAllProcCtx()
{
for (int i = 0; i <PROC_CTX_HANDLE_ID_MAX; i++)
{
AddProcCtx(static_cast<ProcCtxHandleId>(i));
}
}
// Insert a single proc_ctx
void IpaHdrProcCtxTestFixture::AddProcCtx(ProcCtxHandleId handleId)
{
static const int NUM_OF_PROC_CTX = 1;
struct ipa_ioc_add_hdr_proc_ctx *procCtxTable = NULL;
struct ipa_hdr_proc_ctx_add *procCtx = NULL;
// init proc ctx table
procCtxTable = (struct ipa_ioc_add_hdr_proc_ctx *)calloc(1,
sizeof(struct ipa_ioc_add_hdr_proc_ctx)
+ NUM_OF_PROC_CTX *
sizeof(struct ipa_hdr_proc_ctx_add));
if (!procCtxTable)
{
LOG_MSG_ERROR("calloc failed to allocate procCtxTable");
return;
}
procCtxTable->commit = true;
procCtxTable->num_proc_ctxs = NUM_OF_PROC_CTX;
// init proc_ctx common fields
procCtx = &procCtxTable->proc_ctx[0];
procCtx->proc_ctx_hdl = -1; // return value
procCtx->status = -1; // Return parameter
// init proc_ctx specific fields
switch (handleId)
{
case PROC_CTX_HANDLE_ID_ETH2_2_WLAN_ETH2:
procCtx->type = IPA_HDR_PROC_ETHII_TO_ETHII;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_WLAN_ETH2];
break;
case PROC_CTX_HANDLE_ID_ETH2_2_RNDIS_ETH2:
procCtx->type = IPA_HDR_PROC_ETHII_TO_ETHII;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_RNDIS_ETH2];
break;
case PROC_CTX_HANDLE_ID_ETH2_ETH2_2_ETH2:
procCtx->type = IPA_HDR_PROC_ETHII_TO_ETHII;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_ETH2];
break;
case PROC_CTX_HANDLE_ID_WLAN_ETH2_2_802_3:
procCtx->type = IPA_HDR_PROC_ETHII_TO_802_3;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_WLAN_802_3];
break;
case PROC_CTX_HANDLE_ID_RNDIS_802_3_2_ETH2:
procCtx->type = IPA_HDR_PROC_802_3_TO_ETHII;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_RNDIS_ETH2];
break;
case PROC_CTX_HANDLE_ID_WLAN_802_3_2_ETH2:
procCtx->type = IPA_HDR_PROC_802_3_TO_802_3;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_WLAN_802_3];
break;
case PROC_CTX_HANDLE_ID_802_1Q_2_802_1Q:
procCtx->type = IPA_HDR_PROC_ETHII_TO_ETHII_EX;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_VLAN_802_1Q];
procCtx->generic_params.input_ethhdr_negative_offset = 18;
procCtx->generic_params.output_ethhdr_negative_offset = 18;
break;
case PROC_CTX_HANDLE_ID_802_1Q_2_ETH2:
procCtx->type = IPA_HDR_PROC_ETHII_TO_ETHII_EX;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_ETH2];
procCtx->generic_params.input_ethhdr_negative_offset = 18;
procCtx->generic_params.output_ethhdr_negative_offset = 14;
break;
case PROC_CTX_HANDLE_ID_ETH2_2_802_1Q:
procCtx->type = IPA_HDR_PROC_ETHII_TO_ETHII_EX;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_VLAN_802_1Q];
procCtx->generic_params.input_ethhdr_negative_offset = 14;
procCtx->generic_params.output_ethhdr_negative_offset = 18;
break;
case PROC_CTX_HANDLE_ID_ETH2_ETH2_2_ETH2_EX:
procCtx->type = IPA_HDR_PROC_ETHII_TO_ETHII_EX;
procCtx->hdr_hdl =
m_headerHandles[HEADER_HANDLE_ID_ETH2];
procCtx->generic_params.input_ethhdr_negative_offset = 14;
procCtx->generic_params.output_ethhdr_negative_offset = 14;
break;
default:
LOG_MSG_ERROR("proc ctx handleId %d not supported.", handleId);
return;
}
if (!m_headerInsertion.AddProcCtx(procCtxTable))
{
LOG_MSG_ERROR("m_headerInsertion.AddProcCtx(procCtxTable) failed.");
return;
}
// save proc_ctx handle
m_procCtxHHandles[handleId] = procCtx->proc_ctx_hdl;
}
void IpaHdrProcCtxTestFixture::AddRtBypassRule(uint32_t hdrHdl, uint32_t procCtxHdl)
{
static const char bypass0[] = "bypass0";
struct ipa_ioc_get_rt_tbl routing_table0;
if (!CreateIPv4BypassRoutingTable (
bypass0,
hdrHdl,
procCtxHdl))
{
LOG_MSG_ERROR("CreateIPv4BypassRoutingTable Failed\n");
return;
}
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() Failed.");
return;
}
m_routingTableHdl = routing_table0.hdl;
}
void IpaHdrProcCtxTestFixture::AddFltBypassRule()
{
IPAFilteringTable FilterTable0;
struct ipa_flt_rule_add flt_rule_entry;
FilterTable0.Init(IPA_IP_v4,m_currProducerClient,false,1);
printf("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_ROUTING;
flt_rule_entry.rule.rt_tbl_hdl=m_routingTableHdl;
flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; // Mask - Bypass rule
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x12345678; // Filter is irrelevant.
if (((uint8_t)-1 == FilterTable0.AddRuleToTable(flt_rule_entry)) ||
!m_filtering.AddFilteringRule(
FilterTable0.GetFilteringTable()))
{
LOG_MSG_ERROR(
"%s::m_filtering.AddFilteringRule() failed",
__FUNCTION__);
return;
}
else
{
printf("flt rule hdl0=0x%x, status=0x%x\n",
FilterTable0.ReadRuleFromTable(0)->flt_rule_hdl,
FilterTable0.ReadRuleFromTable(0)->status);
}
}
bool IpaHdrProcCtxTestFixture::ReceivePacketsAndCompare()
{
size_t receivedBufferSize1 = 0;
bool isSuccess = true;
// Receive results
Byte *receivedBuffer1 = new Byte[m_BUFF_MAX_SIZE];
if (NULL == receivedBuffer1)
{
printf("Memory allocation error.\n");
return false;
}
receivedBufferSize1 = m_pCurrentConsumer->ReceiveData(
receivedBuffer1,
m_BUFF_MAX_SIZE);
printf("Received %zu bytes on %s.\n",
receivedBufferSize1,
m_pCurrentConsumer->m_fromChannelName.c_str());
// Compare results
if (!CompareResultVsGolden(
m_expectedBuffer1,
m_expectedBufferSize1,
receivedBuffer1,
receivedBufferSize1))
{
printf("Comparison of Buffer Failed!\n");
isSuccess = false;
}
printf("Expected buffer 1 - %zu bytes\n", m_expectedBufferSize1);
print_buff(m_expectedBuffer1, m_expectedBufferSize1);
printf("Received buffer 1 - %zu bytes\n", receivedBufferSize1);
print_buff(receivedBuffer1, receivedBufferSize1);
delete[] receivedBuffer1;
return isSuccess;
}
// Create 1 IPv4 bypass routing entry and commits it
bool IpaHdrProcCtxTestFixture::CreateIPv4BypassRoutingTable (
const char *name,
uint32_t hdrHdl,
uint32_t procCtxHdl)
{
printf("Entering %s, %s()\n",__FUNCTION__, __FILE__);
struct ipa_ioc_add_rt_rule *rt_table = 0;
struct ipa_rt_rule_add *rt_rule_entry = NULL;
// Verify that only one is nonzero
if ((hdrHdl == 0 && procCtxHdl == 0) ||
(hdrHdl != 0 && procCtxHdl != 0))
{
LOG_MSG_ERROR("Error: hdrHdl = %u, procCtxHdl = %u\n");
return false;
}
rt_table = (struct ipa_ioc_add_rt_rule *)
calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1*sizeof(struct ipa_rt_rule_add));
if(!rt_table) {
LOG_MSG_ERROR("calloc failed to allocate rt_table\n");
return false;
}
rt_table->num_rules = 1;
rt_table->ip = IPA_IP_v4;
rt_table->commit = true;
strlcpy(rt_table->rt_tbl_name, name, sizeof(rt_table->rt_tbl_name));
rt_rule_entry = &rt_table->rules[0];
rt_rule_entry->at_rear = 0;
rt_rule_entry->rule.dst = m_currConsumerPipeNum;
rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
rt_rule_entry->rule.attrib.u.v4.dst_addr = 0xaabbccdd;
// All Packets will get a "Hit"
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0x00000000;
rt_rule_entry->rule.hdr_hdl = hdrHdl;
rt_rule_entry->rule.hdr_proc_ctx_hdl = procCtxHdl;
if (false == m_routing.AddRoutingRule(rt_table))
{
printf("Routing rule addition(rt_table) failed!\n");
Free (rt_table);
return false;
}
Free (rt_table);
printf("Leaving %s, %s()\n",__FUNCTION__, __FILE__);
return true;
}
bool IpaHdrProcCtxTestFixture::AddRules()
{
printf("Entering %s, %s()\n",__FUNCTION__, __FILE__);
if (m_procCtxHandleId == PROC_CTX_HANDLE_ID_MAX)
{
LOG_MSG_ERROR("Test developer didn't implement "
"AddRules() or didn't set m_procCtxHandleId");
return false;
}
AddAllHeaders();
AddAllProcCtx();
AddRtBypassRule(0, m_procCtxHHandles[m_procCtxHandleId]);
AddFltBypassRule();
printf("Leaving %s, %s()\n",__FUNCTION__, __FILE__);
return true;
}// AddRules()
bool IpaHdrProcCtxTestFixture::SendPackets()
{
bool isSuccess = false;
// Send first packet
isSuccess = m_pCurrentProducer->SendData(
m_sendBuffer1,
m_sendSize1);
if (false == isSuccess)
{
LOG_MSG_ERROR("SendPackets Buffer1 failed on client %d\n", m_currProducerClient);
return false;
}
return true;
}
bool IpaHdrProcCtxTestFixture::Run()
{
bool res = false;
bool isSuccess = false;
printf("Entering %s, %s()\n",__FUNCTION__, __FILE__);
res = AddRules();
if (false == res) {
printf("Failed adding filtering rules.\n");
return false;
}
// Load input data - IP packets
res = LoadPackets(m_IpaIPType);
if (false == res) {
printf("Failed loading packets.\n");
return false;
}
res = GenerateExpectedPackets();
if (false == res) {
printf("GenerateExpectedPackets failed\n");
return false;
}
res = SendPackets();
if (false == res) {
printf("SendPackets failed\n");
return false;
}
// Receive packets from the channels and compare results
isSuccess = ReceivePacketsAndCompare();
printf("Leaving %s, %s(), Returning %d\n",
__FUNCTION__,
__FILE__,
isSuccess);
return isSuccess;
} // Run()
IpaHdrProcCtxTestFixture::~IpaHdrProcCtxTestFixture()
{
m_sendSize1 = 0;
}
RoutingDriverWrapper IpaHdrProcCtxTestFixture::m_routing;
Filtering IpaHdrProcCtxTestFixture::m_filtering;
HeaderInsertion IpaHdrProcCtxTestFixture::m_headerInsertion;

View File

@@ -0,0 +1,218 @@
/*
* Copyright (c) 2017-2019 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 "HeaderInsertion.h"
#include "RoutingDriverWrapper.h"
#include "IPAFilteringTable.h"
/*
Processing context test design:
1. 1 Producer with RNDIS de-aggregation and ETH2 header removal.
2. 1 Producer with WLAN and ETH2 header removal.
3. 1 default consumer.
4. 1 RNDIS aggregation consumer.
5. 1 FLT rule – accept all - points to 1 RT rule.
6. 1 RT rule – accept all - points to specific test relevant proc_ctx.
7. All tests add all proc_ctx (for all tests).
8. Proc_ctx to be added: 1 for each test – 3 altogether.
Proc_ctx of test 01 and 03 are the same.
9. Each test will send 1 packet and check that the packet is good
except test 03.
10. Test 03 the same as Test 01 but will send multiple packets
and expect 1 (RNDIS aggregation test).
List of tests:
00. Header insertion scenario of [RNDIS][ETH_II][IP] -> [WLAN][ETH_II][IP]
01. Header insertion scenario of [WLAN][ETH_II][IP] -> [RNDIS][ETH_II][IP]
02. Header insertion scenario of [WLAN][ETH_II][IP] -> [WLAN’][ETH_II][IP]
03. Header insertion of [WLAN][ETH_II][IP] -> [RNDIS][ETH_II][IP]
with RNDIS aggregation.
04. Header insertion scenario when adding total header sizes > 2048
05. Header insertion scenario of [ETH_II][IP] -> [WLAN][ETH_II][IP]
06. Header insertion scenario of [WLAN][ETH_II][IP] -> [ETH_II][IP
07. Header insertion scenario of [ETH_II][IP] -> [ETH_II][IP]
08. Header insertion scenario of [RNDIS][ETH_II][IP] -> [WLAN][802.3][IP]
09. Header insertion scenario of [WLAN][802.3][IP] -> [RNDIS][ETH_II][IP]
10. Header insertion scenario of [ETH_II][IP] -> [WLAN][802.3][IP]
11. Header insertion scenario of [WLAN][802.3][IP] -> [WLAN’][802.3][IP]
*/
class IpaHdrProcCtxTestFixture : public TestBase
{
public:
enum HeaderHandleId
{
HEADER_HANDLE_ID_WLAN_ETH2,
HEADER_HANDLE_ID_RNDIS_ETH2,
HEADER_HANDLE_ID_ETH2,
HEADER_HANDLE_ID_WLAN_802_3,
HEADER_HANDLE_ID_VLAN_802_1Q,
HEADER_HANDLE_ID_MAX
};
enum ProcCtxHandleId
{
PROC_CTX_HANDLE_ID_ETH2_2_WLAN_ETH2,
PROC_CTX_HANDLE_ID_ETH2_2_RNDIS_ETH2,
PROC_CTX_HANDLE_ID_ETH2_ETH2_2_ETH2,
PROC_CTX_HANDLE_ID_WLAN_ETH2_2_802_3,
PROC_CTX_HANDLE_ID_RNDIS_802_3_2_ETH2,
PROC_CTX_HANDLE_ID_WLAN_802_3_2_ETH2,
PROC_CTX_HANDLE_ID_802_1Q_2_802_1Q,
PROC_CTX_HANDLE_ID_ETH2_2_802_1Q,
PROC_CTX_HANDLE_ID_802_1Q_2_ETH2,
PROC_CTX_HANDLE_ID_ETH2_ETH2_2_ETH2_EX,
PROC_CTX_HANDLE_ID_MAX
};
// header table consist of 9 bits and 4B units -> 2048
static const int m_ALL_HEADER_SIZE_LIMIT = 2048;
static const size_t m_BUFF_MAX_SIZE =
2 * RNDISAggregationHelper::RNDIS_AGGREGATION_BYTE_LIMIT;
// [WLAN][ETH2] header
static const Byte WLAN_ETH2_HDR[WLAN_ETH2_HDR_SIZE];
// [ETH2] header
static const Byte ETH2_HDR[ETH_HLEN];
// [ETH2_802_1Q] vlan header
static const Byte ETH2_8021Q_HDR[ETH8021Q_HEADER_LEN];
// [WLAN][802.3] header
static const Byte WLAN_802_3_HDR[WLAN_802_3_HDR_SIZE];
static Filtering m_filtering;
static RoutingDriverWrapper m_routing;
static HeaderInsertion m_headerInsertion;
// For each header type the handle is saved
// to be used by the processing context
uint32_t m_headerHandles[HEADER_HANDLE_ID_MAX];
// For each prco_ctx type the handle is saved
// to be used by the routing rule
uint32_t m_procCtxHHandles[PROC_CTX_HANDLE_ID_MAX];
// proc_ctx handle ID
ProcCtxHandleId m_procCtxHandleId;
// routing table handle
uint32_t m_routingTableHdl;
// Pipe with RNDIS and ETH2 header removal
InterfaceAbstraction m_rndisEth2Producer;
// Pipe with WLAN and ETH2 header removal
InterfaceAbstraction m_wlanEth2producer;
// Pipe with ETH2 header removal
InterfaceAbstraction m_eth2Producer;
// TODO: Pipe with WLAN and 802.3 header removal
InterfaceAbstraction m_wlan802_3producer;
// Pointer to current producer pipe used in the test
InterfaceAbstraction *m_pCurrentProducer;
ipa_client_type m_currProducerClient;
// Pipe of the WLAN ETH2 consumer
InterfaceAbstraction m_defaultConsumer;
// Pipe of the RNDIS ETH2 consumer
InterfaceAbstraction m_rndisEth2Consumer;
// Pointer to current consumer pipe used in the test
InterfaceAbstraction *m_pCurrentConsumer;
ipa_client_type m_currConsumerPipeNum;
// First input packet
Byte m_sendBuffer1[m_BUFF_MAX_SIZE];
size_t m_sendSize1;
// Second input packet
Byte m_sendBuffer2[m_BUFF_MAX_SIZE];
size_t m_sendSize2;
// First expected packet
Byte m_expectedBuffer1[m_BUFF_MAX_SIZE];
size_t m_expectedBufferSize1;
enum ipa_ip_type m_IpaIPType;
IpaHdrProcCtxTestFixture();
virtual bool Setup();
virtual bool Teardown();
virtual void AddAllHeaders();
// Insert a single header
virtual void AddHeader(HeaderHandleId handleId);
virtual void AddAllProcCtx();
// Insert a single proc_ctx
virtual void AddProcCtx(ProcCtxHandleId handleId);
virtual void AddRtBypassRule(uint32_t hdrHdl, uint32_t procCtxHdl);
virtual void AddFltBypassRule();
virtual bool LoadPackets(enum ipa_ip_type ip) = 0;
virtual bool ReceivePacketsAndCompare();
// Create 1 IPv4 bypass routing entry and commits it
virtual bool CreateIPv4BypassRoutingTable (
const char *name,
uint32_t hdrHdl,
uint32_t procCtxHdl);
virtual bool GenerateExpectedPackets() = 0;
virtual bool AddRules();
virtual bool SendPackets();
virtual bool Run();
~IpaHdrProcCtxTestFixture();
private:
};

View File

@@ -0,0 +1,780 @@
/*
* Copyright (c) 2017-2019 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 "HeaderProcessingContextTestFixture.h"
/*----------------------------------------------------------------------------*/
/* Test00: Header insertion scenario of [RNDIS][ETH_II][IP] -> */
/* [WLAN][ETH_II][IP] */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest00 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest00()
{
m_name = "IpaHdrProcCtxTest00";
m_description =
"Processing Context test 00 - \
of [RNDIS][ETH_II][IP] -> [WLAN][ETH_II][IP] \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST2. \
Routing rule will use processing context ETH2_2_WLAN_ETH2 \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_rndisEth2Producer;
m_currProducerClient = IPA_CLIENT_TEST_PROD;
m_pCurrentConsumer = &m_defaultConsumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST2_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_ETH2_2_WLAN_ETH2;
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
if (!RNDISAggregationHelper::LoadRNDISPacket(
ip,
m_sendBuffer1,
m_sendSize1))
{
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
printf ("Loaded %zu Bytes to Packet 1\n",m_sendSize1);
add_buff(m_sendBuffer1+RNDIS_HDR_SIZE, ETH_HLEN, 2);
print_buff(m_sendBuffer1, m_sendSize1);
return true;
}
virtual bool GenerateExpectedPackets()
{
m_expectedBufferSize1 = WLAN_ETH2_HDR_SIZE +
IP4_PACKET_SIZE;
// copy WLAN header to the beginning of the buffer
memcpy(m_expectedBuffer1, WLAN_ETH2_HDR, WLAN_HDR_SIZE);
// copy ETH+IP packet right after WLAN header
memcpy(m_expectedBuffer1 + WLAN_HDR_SIZE,
m_sendBuffer1 + RNDIS_HDR_SIZE,
ETH_HLEN + IP4_PACKET_SIZE);
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test01: Header insertion scenario of [WLAN][ETH_II][IP] -> */
/* [RNDIS][ETH_II][IP] */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest01 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest01()
{
m_name = "IpaHdrProcCtxTest01";
m_description =
"Processing context test 01 - \
of [WLAN][ETH_II][IP] -> [RNDIS][ETH_II][IP] \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST3. \
Routing rule will use processing context ETH2_2_RNDIS_ETH2 \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_wlanEth2producer;
m_currProducerClient = IPA_CLIENT_TEST2_PROD;
m_pCurrentConsumer = &m_rndisEth2Consumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST3_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_ETH2_2_RNDIS_ETH2;
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
// load WLAN ETH2 IP4 packet of size 1kB + 1 byte
// This size will trigger RNDIS aggregation later
m_sendSize1 =
RNDISAggregationHelper::RNDIS_AGGREGATION_BYTE_LIMIT + 1;
if (!WlanHelper::LoadWlanEth2IP4PacketByLength(
m_sendBuffer1,
m_BUFF_MAX_SIZE,
m_sendSize1,
0x01))
return false;
printf ("Loaded %zu Bytes to Packet 1\n",m_sendSize1);
add_buff(m_sendBuffer1+WLAN_HDR_SIZE, ETH_HLEN, 3);
print_buff(m_sendBuffer1, m_sendSize1);
return true;
}
virtual bool GenerateExpectedPackets()
{
size_t len = 0;
size_t eth2PacketSize = m_sendSize1 - WLAN_HDR_SIZE;
m_expectedBufferSize1 = eth2PacketSize + RNDIS_HDR_SIZE;
// copy RNDIS header
if (!RNDISAggregationHelper::LoadRNDISHeader(
m_expectedBuffer1,
m_BUFF_MAX_SIZE,
m_expectedBufferSize1,
&len))
{
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
// copy ETH2 packet after RNDIS header
memcpy(m_expectedBuffer1 + len,
m_sendBuffer1 + WLAN_HDR_SIZE,
eth2PacketSize);
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test02: Header insertion scenario of [WLAN][ETH_II][IP] -> */
/* [WLAN'][ETH_II][IP] */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest02 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest02()
{
m_name = "IpaHdrProcCtxTest02";
m_description =
"Processing context test 02 - \
of [WLAN][ETH_II][IP] -> [WLAN'][ETH_II][IP] \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST2. \
Routing rule will use processing context ETH2_2_WLAN_ETH2 \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_wlanEth2producer;
m_currProducerClient = IPA_CLIENT_TEST2_PROD;
m_pCurrentConsumer = &m_defaultConsumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST2_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_ETH2_2_WLAN_ETH2;
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
// load WLAN ETH2 IP4 packet of size 1kB
// This size will trigger RNDIS aggregation later
if (!WlanHelper::LoadWlanEth2IP4Packet(
m_sendBuffer1,
m_BUFF_MAX_SIZE,
&m_sendSize1))
return false;
printf ("Loaded %zu Bytes to Packet 1\n",m_sendSize1);
add_buff(m_sendBuffer1+WLAN_HDR_SIZE, ETH_HLEN, 5);
return true;
}
virtual bool GenerateExpectedPackets()
{
m_expectedBufferSize1 = m_sendSize1;
memcpy(m_expectedBuffer1, m_sendBuffer1, m_expectedBufferSize1);
memcpy(m_expectedBuffer1, WLAN_ETH2_HDR, WLAN_HDR_SIZE);
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test03: Header insertion scenario of [WLAN][ETH_II][IP] -> */
/* [RNDIS][ETH_II][IP] with RNDIS aggregation */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest03 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest03()
{
m_name = "IpaHdrProcCtxTest03";
m_description =
"Processing Context test 03 - \
of [RNDIS][ETH_II][IP] -> [WLAN][ETH_II][IP] \
with RNDIS aggregation \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST3. \
Routing rule will use processing context ETH2_2_RNDIS_ETH2 \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_wlanEth2producer;
m_currProducerClient = IPA_CLIENT_TEST2_PROD;
m_pCurrentConsumer = &m_rndisEth2Consumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST3_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_ETH2_2_RNDIS_ETH2;
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
// choose this size so that 2 such buffers would be aggregated
m_sendSize1 = RNDISAggregationHelper::
RNDIS_AGGREGATION_BYTE_LIMIT / 2 + 200;
if (!WlanHelper::LoadWlanEth2IP4PacketByLength(
m_sendBuffer1,
m_BUFF_MAX_SIZE,
m_sendSize1,
1))
return false;
printf ("Loaded %zu Bytes to Packet 1\n", m_sendSize1);
add_buff(m_sendBuffer1+WLAN_HDR_SIZE, ETH_HLEN, 7);
// choose this size so that 2 such buffers would be aggregated
m_sendSize2 = RNDISAggregationHelper::
RNDIS_AGGREGATION_BYTE_LIMIT / 2 + 200;
if (!WlanHelper::LoadWlanEth2IP4PacketByLength(
m_sendBuffer2,
m_BUFF_MAX_SIZE,
m_sendSize2,
2))
return false;
printf ("Loaded %zu Bytes to Packet 2\n", m_sendSize2);
add_buff(m_sendBuffer2+WLAN_HDR_SIZE, ETH_HLEN, 11);
return true;
}
virtual bool SendPackets()
{
bool isSuccess = false;
// Send packet 1
isSuccess = m_pCurrentProducer->SendData(
m_sendBuffer1,
m_sendSize1);
if (false == isSuccess)
{
LOG_MSG_ERROR(
"SendData Buffer 1 failed on producer %d\n", m_currProducerClient);
return false;
}
// Send packet 2
isSuccess = m_pCurrentProducer->SendData(
m_sendBuffer2,
m_sendSize2);
if (false == isSuccess)
{
LOG_MSG_ERROR(
"SendData Buffer 2 failed on producer %d\n", m_currProducerClient);
return false;
}
return true;
}
virtual bool GenerateExpectedPackets()
{
size_t len = 0;
size_t eth2PacketSize1 = m_sendSize1 - WLAN_HDR_SIZE;
size_t rndisPacketSize1 = eth2PacketSize1 + RNDIS_HDR_SIZE;
size_t eth2PacketSize2 = m_sendSize2 - WLAN_HDR_SIZE;
size_t rndisPacketSize2 = eth2PacketSize2 + RNDIS_HDR_SIZE;
Byte *currBuffLocation = NULL;
m_expectedBufferSize1 = rndisPacketSize1 + rndisPacketSize2;
currBuffLocation = m_expectedBuffer1;
// copy first RNDIS header
if (!RNDISAggregationHelper::LoadRNDISHeader(
currBuffLocation,
m_BUFF_MAX_SIZE,
rndisPacketSize1,
&len))
return false;
// copy ETH2 packet 1 after RNDIS header
currBuffLocation += len;
memcpy(currBuffLocation,
m_sendBuffer1 + WLAN_HDR_SIZE,
eth2PacketSize1);
// copy second RNDIS header
currBuffLocation += eth2PacketSize1;
if (!RNDISAggregationHelper::LoadRNDISHeader(
currBuffLocation,
m_BUFF_MAX_SIZE - rndisPacketSize1,
rndisPacketSize2,
&len))
return false;
// copy ETH2 packet 2 after RNDIS header
currBuffLocation += len;
memcpy(currBuffLocation,
m_sendBuffer2 + WLAN_HDR_SIZE,
eth2PacketSize2);
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test04: Header insertion scenario when adding total header sizes > 2048 */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest04 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest04()
{
m_name = "IpaHdrProcCtxTest04";
m_description =
"Processing context test 04 - \
Header insertion scenario when adding \
total header sizes > 2048 \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST2. \
Routing rule will use header WLAN_ETH2 \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_wlanEth2producer;
m_currProducerClient = IPA_CLIENT_TEST2_PROD;
m_pCurrentConsumer = &m_defaultConsumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST2_CONS;
m_minIPAHwType = IPA_HW_v2_5;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual void AddAllHeaders()
{
int cnt = 0;
int allHeadersSize = 0;
while (allHeadersSize <= m_ALL_HEADER_SIZE_LIMIT)
{
AddHeader(HEADER_HANDLE_ID_ETH2);
/* header bins are power of 2 */
allHeadersSize += ETH_HLEN + 2;
cnt++;
}
AddHeader(HEADER_HANDLE_ID_WLAN_ETH2);
}
virtual bool AddRules()
{
printf("Entering %s, %s()\n",__FUNCTION__, __FILE__);
AddAllHeaders();
AddRtBypassRule(m_headerHandles[HEADER_HANDLE_ID_WLAN_ETH2], 0);
AddFltBypassRule();
printf("Leaving %s, %s()\n",__FUNCTION__, __FILE__);
return true;
}// AddRules()
virtual bool LoadPackets(enum ipa_ip_type ip)
{
// load WLAN ETH2 IP4 packet of size 1kB
// This size will trigger RNDIS aggregation later
if (!WlanHelper::LoadWlanEth2IP4Packet(
m_sendBuffer1,
m_BUFF_MAX_SIZE,
&m_sendSize1))
return false;
printf ("Loaded %zu Bytes to Packet 1\n",m_sendSize1);
add_buff(m_sendBuffer1+WLAN_HDR_SIZE, ETH_HLEN, 13);
return true;
}
virtual bool GenerateExpectedPackets()
{
m_expectedBufferSize1 = m_sendSize1;
memcpy(m_expectedBuffer1, m_sendBuffer1, m_expectedBufferSize1);
memcpy(m_expectedBuffer1, WLAN_ETH2_HDR, WLAN_ETH2_HDR_SIZE);
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test05: Header insertion scenario of [ETH_II_802_1Q][IP] -> */
/* [ETH_II_802_1Q][IP] */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest05 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest05()
{
m_name = "IpaHdrProcCtxTest05";
m_description =
"Processing Context test 05 - \
of [ETH_II_802_1Q][IP] -> [ETH_II_802_1Q][IP] \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST2. \
Routing rule will use processing context 802_1Q_2_802_1Q \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
/*
* NOTE: we use the wlan + ETH header prod pipe since the header
* length shall be equal to 8021Q ETH_II length
*/
m_pCurrentProducer = &m_wlanEth2producer;
m_currProducerClient = IPA_CLIENT_TEST2_PROD;
m_pCurrentConsumer = &m_defaultConsumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST2_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_802_1Q_2_802_1Q;
m_minIPAHwType = IPA_HW_v4_0;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
if (!LoadDefault802_1Q(ip,
m_sendBuffer1,
m_sendSize1)) {
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
printf("Loaded %zu Bytes to Packet 1\n", m_sendSize1);
// modify the MAC addresses only
add_buff(m_sendBuffer1, 12, 14);
//change vlan ID to 9
m_sendBuffer1[15] = 0x9;
print_buff(m_sendBuffer1, m_sendSize1);
return true;
}
virtual bool GenerateExpectedPackets()
{
m_expectedBufferSize1 = m_sendSize1;
// we actually expect the same packet to come out (but after uCP)
memcpy(m_expectedBuffer1, m_sendBuffer1, m_expectedBufferSize1);
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test06: Header insertion scenario of [ETH_II][IP] -> */
/* [ETH_II_802_1Q][IP] */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest06 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest06()
{
m_name = "IpaHdrProcCtxTest06";
m_description =
"Processing Context test 06 - \
of [ETH_II][IP] -> [ETH_II_802_1Q][IP] \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST2. \
Routing rule will use processing context ETH2_2_802_1Q \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_eth2Producer;
m_currProducerClient = IPA_CLIENT_TEST3_PROD;
m_pCurrentConsumer = &m_defaultConsumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST2_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_ETH2_2_802_1Q;
m_minIPAHwType = IPA_HW_v4_0;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
if (!Eth2Helper::LoadEth2IP4Packet(
m_sendBuffer1,
m_BUFF_MAX_SIZE,
&m_sendSize1)) {
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
printf("Loaded %zu Bytes to Packet 1\n", m_sendSize1);
// modify the MAC addresses only
add_buff(m_sendBuffer1, 12, 15);
print_buff(m_sendBuffer1, m_sendSize1);
return true;
}
virtual bool GenerateExpectedPackets()
{
size_t len;
m_expectedBufferSize1 = ETH8021Q_HEADER_LEN +
IP4_PACKET_SIZE;
// copy the VLAN header to expected buffer
memcpy(m_expectedBuffer1, ETH2_8021Q_HDR, ETH8021Q_HEADER_LEN);
// fill src and dst mac and ethertype
memcpy(m_expectedBuffer1, m_sendBuffer1, 2 * ETH_ALEN);
memcpy(m_expectedBuffer1 + ETH8021Q_ETH_TYPE_OFFSET,
m_sendBuffer1 + ETH2_ETH_TYPE_OFFSET, ETH2_ETH_TYPE_LEN);
len = m_BUFF_MAX_SIZE - ETH8021Q_HEADER_LEN;
if (!LoadDefaultPacket(IPA_IP_v4,
m_expectedBuffer1 + ETH8021Q_HEADER_LEN,
len)) {
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test07: Header insertion scenario of [ETH_II_802_1Q][IP] -> */
/* [ETH_II][IP] */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest07 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest07()
{
m_name = "IpaHdrProcCtxTest07";
m_description =
"Processing Context test 07 - \
of [ETH_II_802_1Q][IP] -> [ETH_II][IP] \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST2. \
Routing rule will use processing context 802_1Q_2_ETH2 \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_wlanEth2producer;
m_currProducerClient = IPA_CLIENT_TEST2_PROD;
m_pCurrentConsumer = &m_defaultConsumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST2_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_802_1Q_2_ETH2;
m_minIPAHwType = IPA_HW_v4_0;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
if (!LoadDefault802_1Q(ip,
m_sendBuffer1,
m_sendSize1)) {
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
printf("Loaded %zu Bytes to Packet 1\n", m_sendSize1);
// modify the MAC addresses only
add_buff(m_sendBuffer1, ETH8021Q_METADATA_OFFSET, 16);
print_buff(m_sendBuffer1, m_sendSize1);
return true;
}
virtual bool GenerateExpectedPackets()
{
size_t len;
m_expectedBufferSize1 = m_sendSize1 - ETH8021Q_8021Q_TAG_LEN;
// copy the ETH2 header to expected buffer
memcpy(m_expectedBuffer1, ETH2_HDR, ETH_HLEN);
// fill src and dst mac and ethertype
memcpy(m_expectedBuffer1, m_sendBuffer1, 2 * ETH_ALEN);
memcpy(m_expectedBuffer1 + ETH2_ETH_TYPE_OFFSET,
m_sendBuffer1 + ETH8021Q_ETH_TYPE_OFFSET,
ETH2_ETH_TYPE_LEN);
len = m_BUFF_MAX_SIZE - ETH_HLEN;
if (!LoadDefaultPacket(IPA_IP_v4,
m_expectedBuffer1 + ETH_HLEN,
len)) {
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
return true;
} // GenerateExpectedPackets()
};
/*----------------------------------------------------------------------------*/
/* Test08: Header insertion scenario of [ETH_II][IP] -> */
/* [ETH_II][IP] with generic ucp command */
/*----------------------------------------------------------------------------*/
class IpaHdrProcCtxTest08 : public IpaHdrProcCtxTestFixture
{
public:
IpaHdrProcCtxTest08()
{
m_name = "IpaHdrProcCtxTest08";
m_description =
"Processing Context test 08 - \
of [ETH_II][IP] -> [ETH_II][IP] with generic ucp \
1. Generate and commit all headers for all tests. \
2. Generate and commit all processing context rules \
for all tests.\
3. Generate and commit routing table 0. \
The table contains 1 \"bypass\" rule. \
All data goes to output pipe TEST2. \
Routing rule will use processing context ETH2_2_ETH2_EX \
4. Generate and commit 1 filtering rule. \
All traffic goes to routing table 0";
m_pCurrentProducer = &m_eth2Producer;
m_currProducerClient = IPA_CLIENT_TEST3_PROD;
m_pCurrentConsumer = &m_defaultConsumer;
m_currConsumerPipeNum = IPA_CLIENT_TEST2_CONS;
m_procCtxHandleId = PROC_CTX_HANDLE_ID_ETH2_ETH2_2_ETH2_EX;
m_minIPAHwType = IPA_HW_v4_0;
m_maxIPAHwType = IPA_HW_MAX;
m_runInRegression = false;
Register(*this);
}
virtual bool LoadPackets(enum ipa_ip_type ip)
{
if (!Eth2Helper::LoadEth2IP4Packet(
m_sendBuffer1,
m_BUFF_MAX_SIZE,
&m_sendSize1)) {
LOG_MSG_ERROR("Failed default Packet\n");
return false;
}
printf("Loaded %zu Bytes to Packet 1\n", m_sendSize1);
// modify the MAC addresses only
add_buff(m_sendBuffer1, 12, 17);
print_buff(m_sendBuffer1, m_sendSize1);
return true;
}
virtual bool GenerateExpectedPackets()
{
m_expectedBufferSize1 = m_sendSize1;
// we actually expect the same packet to come out (but after uCP)
memcpy(m_expectedBuffer1, m_sendBuffer1, m_expectedBufferSize1);
return true;
} // GenerateExpectedPackets()
};
static IpaHdrProcCtxTest00 ipaHdrProcCtxTest00;
static IpaHdrProcCtxTest01 ipaHdrProcCtxTest01;
static IpaHdrProcCtxTest02 ipaHdrProcCtxTest02;
static IpaHdrProcCtxTest03 ipaHdrProcCtxTest03;
static IpaHdrProcCtxTest04 ipaHdrProcCtxTest04;
static IpaHdrProcCtxTest05 ipaHdrProcCtxTest05;
static IpaHdrProcCtxTest06 ipaHdrProcCtxTest06;
static IpaHdrProcCtxTest07 ipaHdrProcCtxTest07;
static IpaHdrProcCtxTest08 ipaHdrProcCtxTest08;

View File

@@ -0,0 +1,404 @@
/*
* Copyright (c) 2017 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;
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef _IPA_LINUX_TESTS_HR_TEST_FIXTURE_H_
#define _IPA_LINUX_TESTS_HR_TEST_FIXTURE_H_
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include "Constants.h"
#include "Logger.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "TestBase.h"
#include "Pipe.h"
#include "RoutingDriverWrapper.h"
#include "Filtering.h"
/*This class will be the base class of all HeaderRemoval tests.
*Any method other than the test case itself can
*be declared in this Fixture thus allowing the derived classes to
*implement only the test case.
*All the test of the HeaderRemovalTestFixture
*uses one input and two output.
*/
class HeaderRemovalTestFixture:public TestBase
{
public:
/*This Constructor will register each instance
* that it creates.*/
HeaderRemovalTestFixture();
/*This method will create and initialize two Pipe object for the USB
*(Ethernet) Pipes, one as input and the other as output.
*/
virtual bool Setup();
/*This method will destroy the pipes.*/
virtual bool Teardown();
/*The client type are set from the peripheral perspective
*(TODO Pipe:in case the Driver will change its perspective
*of ipa_connect this should be changed).
*/
static Pipe m_A2NDUNToIpaPipe;
/*from the test application into the IPA(DMUX header)*/
static Pipe m_IpaToUsbPipe;
/*from the IPA back to the test application(Ethernet header)*/
static Pipe m_IpaToA2NDUNPipe;
/*from the IPA back to the test application(DMUX header)*/
static Pipe m_IpaToQ6LANPipe;
static RoutingDriverWrapper m_routing;
static Filtering m_filtering;
protected:
unsigned char *CreateA2NDUNPacket(unsigned int magicNumber,
unsigned int ID,
string sPayloadFileName,
unsigned int *nTotalLength);
bool SetIPATablesToPassAllToSpecificClient(
enum ipa_client_type nClientTypeSrc,
enum ipa_client_type nClientTypeDst);
bool SetFilterTableToPassAllToSpecificClient(
enum ipa_client_type nClientType);
bool SetRoutingTableToPassAllToSpecificClient(
enum ipa_client_type nClientType);
bool SetHeaderInsertionTableAddEmptyHeaderForTheClient(
enum ipa_client_type nClientType);
bool CreateBypassRoutingTablesIPv4(
const char *bypass0,
enum ipa_client_type nClientType
);
bool ConfigureFilteringBlockWithMetaDataEq(
enum ipa_client_type nClientType,
unsigned int nMetaData,
unsigned int nMetaDataMask);
};
#endif

View File

@@ -0,0 +1,218 @@
/*
* Copyright (c) 2017 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 "HeaderRemovalTests.h"
#include "TestsUtils.h"
#include <stdio.h>
/////////////////////////////////////////////////////////////////////////////////
static const unsigned int HEADER_REMOVAL_TEST_MAX_PACKET_BYTE_SIZE = 1024;
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
HeaderRemovalTOSCheck::HeaderRemovalTOSCheck()
{
m_name = "HeaderRemovalTOSCheck";
m_description = "HeaderRemovalTOSCheck: Remove the header from the A2NDUN pipe and check the TOS field of the IP packet";
}
/////////////////////////////////////////////////////////////////////////////////
bool HeaderRemovalTOSCheck::Run()
{
bool bTestResult = true;
Byte pPacketReceiveBuffer[HEADER_REMOVAL_TEST_MAX_PACKET_BYTE_SIZE] = {0};//This buffer will be used in order to store the received packet.
unsigned int nMagicNumber = 0x12345678; //arbitrary number
unsigned int nChannelID = 0xABCD;//arbitrary number
unsigned int nA2NDUNPacketByteSize = 0;
unsigned int nBytesSent = 0;
int nBytesReceived = 0;
Byte *pA2NDUNPacket = CreateA2NDUNPacket(nMagicNumber, nChannelID, IPV4_FILE_PATH, &nA2NDUNPacketByteSize);
if(0 == pA2NDUNPacket) {
LOG_MSG_ERROR("Cannot load file to memory, exiting");
return false;
}
LOG_MSG_INFO("A2 Packet was successfully created (%d bytes)", nA2NDUNPacketByteSize);
if ( false == SetIPATablesToPassAllToSpecificClient(IPA_CLIENT_TEST2_PROD, IPA_CLIENT_TEST_CONS)) {
LOG_MSG_ERROR("SetIPATablesToPassAllToSpecificClient failed, exiting test case");
bTestResult = false;
goto bail;
}
LOG_MSG_INFO("All tables were configured in order to output the packet to the correct pipe");
LOG_MSG_INFO("Sending packet into the A2NDUN pipe(%d bytes) and the Pipe will add an header",
nA2NDUNPacketByteSize);
nBytesSent = m_A2NDUNToIpaPipe.Send(pA2NDUNPacket, nA2NDUNPacketByteSize);
if (nA2NDUNPacketByteSize != nBytesSent)
{
bTestResult = false;
goto bail;
}
//Receive the raw IP packet(which is a 4 arbitrary bytes) without header removal by the Pipe
LOG_MSG_INFO("Reading packet from the USB pipe");
nBytesReceived = m_IpaToUsbPipe.Receive(pPacketReceiveBuffer, HEADER_REMOVAL_TEST_MAX_PACKET_BYTE_SIZE);
//TODO Header Removal: at this point the success scenario is that data came to the correct pipe - change this to
//packet memory compare after header insertion is enabled.
if (0 == nBytesReceived)
{
bTestResult = false;
goto bail;
}
LOG_MSG_INFO("Read buffer : ");
//Print the output
for (int i = 0 ; i < nBytesReceived ; i++)
{
printf("0x%02x", pPacketReceiveBuffer[i]);
}
LOG_MSG_INFO("End of Read buffer.");
if(0 != memcmp((const void *)pPacketReceiveBuffer,
(const void *)(pA2NDUNPacket + (nBytesSent - nBytesReceived)),
nBytesReceived)) {
LOG_MSG_ERROR("Memory contains don't match");
bTestResult = false;
goto bail;
}
/* fall through */
bail:
delete pA2NDUNPacket;
return bTestResult;
}
HeaderRemovalMetaDataFiltering::HeaderRemovalMetaDataFiltering()
{
m_name = "HeaderRemovalMetaDataFiltering";
m_description =
"HeaderRemovalMetaDataFiltering: check meta data based filtering";
}
/////////////////////////////////////////////////////////////////////////////////
bool HeaderRemovalMetaDataFiltering::Run()
{
bool bTestResult = true;
Byte pPacketReceiveBuffer[HEADER_REMOVAL_TEST_MAX_PACKET_BYTE_SIZE] = {0};//This buffer will be used in order to store the received packet.
unsigned int nMagicNumber = 0x12345678; //arbitrary number
unsigned int nChannelID = 0xABCD;//arbitrary number
unsigned int nA2NDUNPacketByteSize = 0;
unsigned int nMetaData = 0;
unsigned int nMetaDataMask = 0xFFFF;
unsigned int nBytesSent = 0;
int nBytesReceived = 0;
Byte *pA2NDUNPacket = CreateA2NDUNPacket(nMagicNumber, nChannelID, IPV4_FILE_PATH, &nA2NDUNPacketByteSize);
if(0 == pA2NDUNPacket) {
LOG_MSG_ERROR("Cannot load file to memory, exiting");
return false;
}
nMetaData = (nChannelID << 16) | (0xFFFF & nA2NDUNPacketByteSize);
LOG_MSG_INFO("*************nMetaData == (0x%x)", nMetaData);
LOG_MSG_INFO("A2 Packet was successfully created (%d bytes)", nA2NDUNPacketByteSize);
SetRoutingTableToPassAllToSpecificClient(IPA_CLIENT_TEST_CONS);
SetHeaderInsertionTableAddEmptyHeaderForTheClient(IPA_CLIENT_TEST_CONS);
LOG_MSG_INFO("Configuring Filtering module...");
if (false ==
ConfigureFilteringBlockWithMetaDataEq(
IPA_CLIENT_TEST_CONS,
nMetaData,
nMetaDataMask)) {
bTestResult = false;
goto bail;
}
LOG_MSG_INFO("Sending packet into the A2NDUN pipe(%d bytes) and the Pipe will add an header",
nA2NDUNPacketByteSize);
nBytesSent = m_A2NDUNToIpaPipe.Send(pA2NDUNPacket, nA2NDUNPacketByteSize);
if (nA2NDUNPacketByteSize != nBytesSent) {
bTestResult = false;
goto bail;
}
//Receive the raw IP packet(which is a 4 arbitrary bytes) without header removal by the Pipe
LOG_MSG_INFO("Reading packet from the USB pipe");
nBytesReceived = m_IpaToUsbPipe.Receive(pPacketReceiveBuffer, HEADER_REMOVAL_TEST_MAX_PACKET_BYTE_SIZE);
//TODO Header Removal: at this point the success scenario is that data came to the correct pipe - change this to
//packet memory compare after header insertion is enabled.
if (0 == nBytesReceived) {
bTestResult = false;
goto bail;
}
LOG_MSG_INFO("Read buffer : ");
//Print the output
for (int i = 0 ; i < nBytesReceived ; i++) {
printf("0x%02x", pPacketReceiveBuffer[i]);
}
LOG_MSG_INFO("End of Read buffer.");
if(0 != memcmp((const void *)pPacketReceiveBuffer,
(const void *)(pA2NDUNPacket + (nBytesSent - nBytesReceived)),
nBytesReceived)) {
LOG_MSG_ERROR("Memory contains don't match");
bTestResult = false;
goto bail;
}
/* fall through */
bail:
delete pA2NDUNPacket;
return bTestResult;
}
static HeaderRemovalTOSCheck headerRemovalTOSCheck;
static HeaderRemovalMetaDataFiltering headerRemovalMetaDataFiltering;
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef _IPA_LINUX_TESTS_HR_TESTS_H_
#define _IPA_LINUX_TESTS_HR_TESTS_H_
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include "Constants.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "HeaderRemovalTestFixture.h"
/*This test will send a DMUX with IP packet and check it TOS field thus
*validating the the header was removed.
*/
class HeaderRemovalTOSCheck:public HeaderRemovalTestFixture
{
public:
/*This Constructor will be use to specify some test description.*/
HeaderRemovalTOSCheck();
/*This method will send a an IP packet with
* DMUX header and create a rule
* */
virtual bool Run();
};
/*This test will send a DMUX with IP packet and see if it filtered
*by meta data contained in link layer header as expected
*/
class HeaderRemovalMetaDataFiltering:HeaderRemovalTestFixture
{
public:
/* his Constructor will be use to specify
* some test description.*/
HeaderRemovalMetaDataFiltering();
virtual bool Run();
};
#endif

View File

@@ -0,0 +1,274 @@
/*
* 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 "IPAFilteringTable.h"
#include <cstring>
#include "TestsUtils.h"
IPAFilteringTable::IPAFilteringTable () : // C'tor
m_pFilteringTable(NULL),
nextRuleIndex(0) {}
bool IPAFilteringTable::Init(ipa_ip_type ipFamily, ipa_client_type pipeNo, uint8_t isGlobal, uint8_t numOfRulesInTable, uint8_t commit)
{
if (NULL != m_pFilteringTable) {
char message[256] = {0};
snprintf(message, sizeof(message), "Error in Function %s, m_pFilteringTable==0x%p, must be NULL, Please call D'tor prior to calling () %s.",
__FUNCTION__,m_pFilteringTable,__FUNCTION__);
ReportError(message);
return false;
}
if (numOfRulesInTable < 1) {
char message[256] = {0};
snprintf(message, sizeof(message),"Error in Function %s, numberOfRulesInTable==%d must be > 0",
__FUNCTION__,numOfRulesInTable);
ReportError(message);
return false;
}
m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
calloc(1, sizeof(struct ipa_ioc_add_flt_rule) +
numOfRulesInTable *sizeof(struct ipa_flt_rule_add));
if (NULL == m_pFilteringTable) {
char message[256] = {0};
snprintf(message, sizeof(message),"Error in Function %s, Failed to allocate %d filter rules in Filtering Table",__FUNCTION__,numOfRulesInTable);
ReportError(message);
return false;
}
m_pFilteringTable->commit = commit;
m_pFilteringTable->ep = pipeNo;
m_pFilteringTable->global = isGlobal;
m_pFilteringTable->ip = ipFamily;
m_pFilteringTable->num_rules = (uint8_t)(numOfRulesInTable);
return true;
}
bool IPAFilteringTable::GeneratePresetRule(uint8_t preset,ipa_flt_rule_add &flt_rule_entry)
{
memset(&flt_rule_entry,0,sizeof(ipa_flt_rule_add)); // Zero All Fields
switch (preset)
{
case 0: // in Preset 0 the Filtering Rule is matches all (bypass)
flt_rule_entry.flt_rule_hdl=-1; // return Value
flt_rule_entry.status = -1; // return value
break;
case 1:
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_PROTOCOL;
flt_rule_entry.rule.attrib.u.v4.protocol = 17; // Filter only UDP Packets.
break;
default:
char message[256] = {0};
snprintf(message, sizeof(message),"Error in Function %s, preset=%d, is not supported.",__FUNCTION__,preset);
ReportError(message);
return false;
}
return true;
}
uint8_t IPAFilteringTable::AddRuleToTable(ipa_flt_rule_add flt_rule_entry)
{
if (NULL == m_pFilteringTable) {
char message[256] = {0};
snprintf(message, sizeof(message),"Error in Function %s, m_pFilteringTable==NULL, Please call Init() prior to calling %s().",__FUNCTION__,__FUNCTION__);
ReportError(message);
return -1;
}
if (nextRuleIndex >= m_pFilteringTable->num_rules) {
char message[256] = {0};
snprintf(message, sizeof(message),"Error in Function %s, ruleIindex==%d while, No. of Rules in Filtering Table is %d. Please use IPAFilteringTable::WriteRule().",
__FUNCTION__,nextRuleIndex,m_pFilteringTable->num_rules);
ReportError(message);
return -1;
}
struct ipa_flt_rule_add *pFilteringRule = &(m_pFilteringTable->rules[nextRuleIndex]);
memcpy(pFilteringRule,&flt_rule_entry,sizeof(ipa_flt_rule_add));
nextRuleIndex++;
return(nextRuleIndex-1);
}
const ipa_flt_rule_add * IPAFilteringTable::ReadRuleFromTable(uint8_t index)
{
if (index < nextRuleIndex)
return (&(m_pFilteringTable->rules[index]));
return NULL;
}
// Function Not Implemented - Always returns FALSE
bool IPAFilteringTable::WriteRuleToTable(uint8_t index,ipa_flt_rule_add flt_rule_entry) {return false;}
//This Function Frees the Filtering Table and all it's content.
//This Function will always return TRUE;
void IPAFilteringTable::Destructor()
{
if (NULL != m_pFilteringTable) {
free (m_pFilteringTable);
printf("Filtering Table Freed\n");
}
m_pFilteringTable = NULL;
nextRuleIndex = 0;
}
IPAFilteringTable::~IPAFilteringTable()
{
Destructor();
}
/* V2 */
IPAFilteringTable_v2::IPAFilteringTable_v2() : // C'tor
m_pFilteringTable_v2(NULL),
nextRuleIndex(0)
{
}
bool IPAFilteringTable_v2::Init(ipa_ip_type ipFamily, ipa_client_type pipeNo, uint8_t isGlobal, uint8_t numOfRulesInTable, uint8_t commit)
{
if (NULL != m_pFilteringTable_v2) {
char message[256] = { 0 };
snprintf(message, sizeof(message), "Error in Function %s, m_pFilteringTable_v2==0x%p, must be NULL, Please call D'tor prior to calling () %s.",
__FUNCTION__, m_pFilteringTable_v2, __FUNCTION__);
ReportError(message);
return false;
}
if (numOfRulesInTable < 1) {
char message[256] = { 0 };
snprintf(message, sizeof(message), "Error in Function %s, numberOfRulesInTable==%d must be > 0",
__FUNCTION__, numOfRulesInTable);
ReportError(message);
return false;
}
m_pFilteringTable_v2 = (struct ipa_ioc_add_flt_rule_v2 *)
calloc(1, sizeof(struct ipa_ioc_add_flt_rule_v2));
m_pFilteringTable_v2->rules = (uint64_t)calloc(numOfRulesInTable, sizeof(struct ipa_flt_rule_add_v2));
if (NULL == m_pFilteringTable_v2) {
char message[256] = { 0 };
snprintf(message, sizeof(message), "Error in Function %s, Failed to allocate %d filter rules in Filtering Table V2", __FUNCTION__, numOfRulesInTable);
ReportError(message);
return false;
}
m_pFilteringTable_v2->commit = commit;
m_pFilteringTable_v2->ep = pipeNo;
m_pFilteringTable_v2->global = isGlobal;
m_pFilteringTable_v2->ip = ipFamily;
m_pFilteringTable_v2->num_rules = (uint8_t)(numOfRulesInTable);
m_pFilteringTable_v2->flt_rule_size = sizeof(struct ipa_flt_rule_add_v2);
return true;
}
bool IPAFilteringTable_v2::GeneratePresetRule(uint8_t preset, ipa_flt_rule_add_v2 &flt_rule_entry)
{
memset(&flt_rule_entry, 0, sizeof(ipa_flt_rule_add_v2)); // Zero All Fields
switch (preset) {
case 0: // in Preset 0 the Filtering Rule is matches all (bypass)
flt_rule_entry.flt_rule_hdl = -1; // return Value
flt_rule_entry.status = -1; // return value
break;
case 1:
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_PROTOCOL;
flt_rule_entry.rule.attrib.u.v4.protocol = 17; // Filter only UDP Packets.
break;
default:
char message[256] = { 0 };
snprintf(message, sizeof(message), "Error in Function %s, preset=%d, is not supported.", __FUNCTION__, preset);
ReportError(message);
return false;
}
return true;
}
uint8_t IPAFilteringTable_v2::AddRuleToTable(ipa_flt_rule_add_v2 flt_rule_entry)
{
if (NULL == m_pFilteringTable_v2) {
char message[256] = { 0 };
snprintf(message, sizeof(message), "Error in Function %s, m_pFilteringTable_v2==NULL, Please call Init() prior to calling %s().", __FUNCTION__, __FUNCTION__);
ReportError(message);
return -1;
}
if (nextRuleIndex >= m_pFilteringTable_v2->num_rules) {
char message[256] = { 0 };
snprintf(message, sizeof(message), "Error in Function %s, ruleIindex==%d while, No. of Rules in Filtering Table is %d. Please use IPAFilteringTable::WriteRule().",
__FUNCTION__, nextRuleIndex, m_pFilteringTable_v2->num_rules);
ReportError(message);
return -1;
}
struct ipa_flt_rule_add_v2 *pFilteringRule = &(((struct ipa_flt_rule_add_v2 *)(m_pFilteringTable_v2->rules))[nextRuleIndex]);
memcpy(pFilteringRule, &flt_rule_entry, sizeof(ipa_flt_rule_add_v2));
nextRuleIndex++;
return(nextRuleIndex - 1);
}
const ipa_flt_rule_add_v2 *IPAFilteringTable_v2::ReadRuleFromTable(uint8_t index)
{
if (index < nextRuleIndex)
return (&(((struct ipa_flt_rule_add_v2*)m_pFilteringTable_v2->rules)[index]));
return NULL;
}
// Function Not Implemented - Always returns FALSE
bool IPAFilteringTable_v2::WriteRuleToTable(uint8_t index, ipa_flt_rule_add_v2 flt_rule_entry) { return false; }
//This Function Frees the Filtering Table and all it's content.
//This Function will always return TRUE;
void IPAFilteringTable_v2::Destructor()
{
if (NULL != m_pFilteringTable_v2) {
free(m_pFilteringTable_v2);
printf("Filtering Table Freed\n");
}
m_pFilteringTable_v2 = NULL;
nextRuleIndex = 0;
}
IPAFilteringTable_v2::~IPAFilteringTable_v2()
{
Destructor();
}

View File

@@ -0,0 +1,149 @@
/*
* 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.
*/
#ifndef _FILTERING_TABLE_
#define _FILTERING_TABLE_
#include "Constants.h"
#include "Filtering.h"
/*This Class Encapsulate Filtering Table and Filtering Rules.
*It allows the user to easily manipulate rules and Tables.
*/
class IPAFilteringTable
{
public:
IPAFilteringTable();
~IPAFilteringTable();
bool Init(ipa_ip_type ipFamily,
ipa_client_type pipeNo,
uint8_t isGlobal,
uint8_t numOfRulesInTable,
uint8_t commit = true);
/*This Function Frees the Filtering Table and all it's content.
*This Function will always return TRUE;
*/
void Destructor();
bool GeneratePresetRule(
uint8_t preset,
ipa_flt_rule_add & flt_rule_entry);
bool GeneratePresetRule(
uint8_t preset,
ipa_flt_rule_add_v2 &flt_rule_entry);
uint8_t AddRuleToTable(
ipa_flt_rule_add flt_rule_entry);
uint8_t AddRuleToTable(
ipa_flt_rule_add_v2 flt_rule_entry);
bool WriteRuleToTable(
uint8_t index,
ipa_flt_rule_add flt_rule_entry);
/*Warning!!!
*Take care when using this function.
*The Returned pointer existence is guaranteed only as
*long as no other method of this class is called.
*/
const ipa_flt_rule_add *ReadRuleFromTable(uint8_t index);
/*Warning!!!
*Take care when using this function
*The Returned pointer existence is guaranteed only
*as long as no other method of this class is called.
*/
const ipa_ioc_add_flt_rule *GetFilteringTable()
{
return m_pFilteringTable;
}
private:
void ReportError(char *message)
{
printf("%s\n", message);
}
ipa_ioc_add_flt_rule *m_pFilteringTable;
uint8_t nextRuleIndex;
};
class IPAFilteringTable_v2 {
public:
IPAFilteringTable_v2();
~IPAFilteringTable_v2();
bool Init(ipa_ip_type ipFamily,
ipa_client_type pipeNo,
uint8_t isGlobal,
uint8_t numOfRulesInTable,
uint8_t commit = true);
/*This Function Frees the Filtering Table and all it's content.
*This Function will always return TRUE;
*/
void Destructor();
bool GeneratePresetRule(
uint8_t preset,
ipa_flt_rule_add_v2 &flt_rule_entry);
uint8_t AddRuleToTable(
ipa_flt_rule_add_v2 flt_rule_entry);
bool WriteRuleToTable(
uint8_t index,
ipa_flt_rule_add_v2 flt_rule_entry);
/*Warning!!!
*Take care when using this function.
*The Returned pointer existence is guaranteed only as
*long as no other method of this class is called.
*/
const ipa_flt_rule_add_v2 *ReadRuleFromTable(uint8_t index);
/*Warning!!!
*Take care when using this function
*The Returned pointer existence is guaranteed only
*as long as no other method of this class is called.
*/
const ipa_ioc_add_flt_rule_v2 *GetFilteringTable()
{
return m_pFilteringTable_v2;
}
private:
void ReportError(char *message)
{
printf("%s\n", message);
}
ipa_ioc_add_flt_rule_v2 *m_pFilteringTable_v2;
uint8_t nextRuleIndex;
};
#endif

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2017 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 "IPAInterruptsTestFixture.h"
/*define the static Pipes which will be used by all derived tests.*/
Pipe IPAInterruptsTestFixture::m_IpaToUsbPipe(IPA_CLIENT_TEST_CONS, IPA_TEST_CONFIGURATION_19);
Pipe IPAInterruptsTestFixture::m_UsbToIpaPipe(IPA_CLIENT_TEST_PROD, IPA_TEST_CONFIGURATION_19);
IPAInterruptsTestFixture::IPAInterruptsTestFixture()
{
m_testSuiteName.push_back("Interrupts");
}
bool IPAInterruptsTestFixture::Setup()
{
return true;
}
bool IPAInterruptsTestFixture::Run()
{
bool bTestResult = true;
Byte pIpPacket[] = { 0x01, 0x02, 0x03, 0x04 }; //This packet will be sent(It can be replaced by a real IP packet).
Byte pIpPacketReceive[sizeof(pIpPacket)] = { 0 }; //This buffer will be used in order to store the received packet.
//Send the raw IP packet(which is a 4 arbitrary bytes) without header addition by the Pipe
LOG_MSG_DEBUG(
"Sending packet into the USB pipe(%d bytes)\n", sizeof(pIpPacket));
int nBytesSent = m_UsbToIpaPipe.Send(pIpPacket, sizeof(pIpPacket));
if (sizeof(pIpPacket) != nBytesSent) {
return false;
}
//Receive the raw IP packet(which is a 4 arbitrary bytes) without header removal by the Pipe
LOG_MSG_DEBUG(
"Reading packet from the USB pipe(%d bytes should be there)\n", sizeof(pIpPacketReceive));
int nBytesReceived = m_IpaToUsbPipe.Receive(pIpPacketReceive,
sizeof(pIpPacketReceive));
if (sizeof(pIpPacketReceive) != nBytesReceived) {
LOG_MSG_DEBUG("sizes mismatch\n");
for (int i = 0; i < nBytesReceived && i < (int)sizeof(pIpPacketReceive) ; i++) {
LOG_MSG_DEBUG("0x%02x\n", pIpPacketReceive[i]);
}
return false;
}
for (int i = 0; i < nBytesReceived; i++) {
LOG_MSG_DEBUG("0x%02x\n", pIpPacketReceive[i]);
}
//Check that the sent IP packet is equal to the received IP packet.
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pIpPacket, pIpPacketReceive, sizeof(pIpPacket));
return bTestResult;
}
bool IPAInterruptsTestFixture::Teardown()
{
/* unregister the test framework suspend handler */
RegSuspendHandler(false, false, 0);
/*The Destroy method will close the inode.*/
m_IpaToUsbPipe.Destroy();
m_UsbToIpaPipe.Destroy();
ConfigureScenario(-1);
return true;
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2017 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 "Constants.h"
#include "Logger.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "TestBase.h"
#include "Pipe.h"
/*This class will be the base class of all Pipe tests.
*Any method other than the test case itself can be
*declared in this Fixture thus allowing the derived classes to
*implement only the test case.
*All the test of the pipe uses one input and one output in DMA mode.
*/
class IPAInterruptsTestFixture:public TestBase
{
public:
/*This Constructor will register each instance that it creates.*/
IPAInterruptsTestFixture();
/*This method will create and initialize two Pipe object for the USB
* (Ethernet) Pipes, one as input and the other as output.
*/
virtual bool Setup();
/*Run test logic*/
bool Run();
/*This method will destroy the pipes.*/
virtual bool Teardown();
/*The client type are set from the peripheral perspective
* (TODO Pipe:in case the Driver will change its perspective
* of ipa_connect this should be changed).
*/
static Pipe m_IpaToUsbPipe;
static Pipe m_UsbToIpaPipe;
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2017 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 "IPAInterruptsTestFixture.h"
#include "Constants.h"
#include "TestsUtils.h"
#include "linux/msm_ipa.h"
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class SuspendTestDeferred: public IPAInterruptsTestFixture {
public:
SuspendTestDeferred() {
m_name = "SuspendTestDeferred";
m_description = "This test will send data on a suspended pipe(Deferred context) ";
Register(*this);
}
bool Setup()
{
bool bRetVal = true;
/*Set the configuration to support USB->IPA and IPA->USB pipes.*/
ConfigureScenario(IPA_TEST_CONFIGURATION_19);
RegSuspendHandler(true,true,0);
/*Initialize the pipe for all the tests -
* this will open the inode which represents the pipe.
*/
bRetVal &= m_IpaToUsbPipe.Init();
bRetVal &= m_UsbToIpaPipe.Init();
return bRetVal;
}
};
class SuspendTest: public IPAInterruptsTestFixture {
public:
SuspendTest() {
m_name = "SuspendTest";
m_description = "This test will send data on a suspended pipe";
Register(*this);
}
bool Setup()
{
bool bRetVal = true;
/*Set the configuration to support USB->IPA and IPA->USB pipes.*/
ConfigureScenario(IPA_TEST_CONFIGURATION_19);
RegSuspendHandler(false,true,0);
/*Initialize the pipe for all the tests -
* this will open the inode which represents the pipe.
*/
bRetVal &= m_IpaToUsbPipe.Init();
bRetVal &= m_UsbToIpaPipe.Init();
return bRetVal;
}
};
static SuspendTest suspendTest;
static SuspendTestDeferred suspendTestDeferred;
/////////////////////////////////////////////////////////////////////////////////
// EOF ////
/////////////////////////////////////////////////////////////////////////////////

409
kernel-tests/IPv4Packet.cpp Normal file
View File

@@ -0,0 +1,409 @@
/*
* Copyright (c) 2017-2018 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 "TestsUtils.h"
#include "IPv4Packet.h"
#include "memory.h"
using namespace IPA;
static const unsigned char TCP_IP_PACKET_DUMP[] = { 0x45, // IPv4, IHL = 5
0x00, // ToS = 0
0x00, 0x28, // Total length
0x11, 0xc2, // ID
0x40, 0x00, //ID + Fragment Offset
0x80, // TTL
0x06, // Protocol = TCP
0x70, 0x3a, //Checksum
0x0a, 0x05, 0x07, 0x46, // Source IP 10.5.7.70
0x81, 0x2e, 0xe6, 0x5a, // Destination IP 129.46.230.90
0xf3, 0xa2, // Source Port 62370
0x01, 0xbd, // Destination Port 445
0x26, 0x26, 0x1d, 0x7d, // Seq Number
0x15, 0xaa, 0xbc, 0xdb, // Ack Num
0x50, 0x10, 0x80, 0xd4, // TCP Params
0xaa, 0xa3, // TCP Checksum
0x00, 0x00 // Urgent PTR
};
static const unsigned char UDP_IP_PACKET_DUMP[] = {
0x45, // IPv4, IHL = 5
0x00, // ToS = 0
0x00,
0x34, // Total Length
0x12,
0xa2, // ID
0x00,
0x00, //ID + fragment offset
0x80, // TTL
0x11, // Protocol = UDP
0xe4,
0x92, // Checksum
0x0a, 0x05, 0x07,
0x46, // Source IP 10.5.7.70
0x0a, 0x2b, 0x28,
0x0f, // Destination IP 10.43.40.15
0x03,
0x4a, // Source port 842
0x1b,
0x4f, // Destination Port 6991
0x00,
0x20, // UDP length
0x36,
0xac, // UDP checksum
0x00, 0x05, 0x20,
0x6d, // Data
0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x13, 0x05, 0x20, 0x6c };
static unsigned char ICMP_IP_PACKET_DUMP[] = {
//IP
0x45, 0x00, 0x00, 0xdc, 0x03, 0xfe, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
0x81, 0x2e, 0xe4, 0xf6, 0x81, 0x2e, 0xe6, 0xd4,
//ICMP
0x00, 0x00, 0xa9, 0xcd, 0x28, 0xa3, 0x01, 0x00,
//DATA
0xee, 0x7c, 0xf7, 0x90, 0x39, 0x06, 0xd4, 0x41, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51 };
static void LittleToBigEndianUint32(unsigned char *pBigEndianBuffer,
unsigned int nUint32LittleEndianValue) {
unsigned char nLsb = nUint32LittleEndianValue & 0xff;
unsigned char nLsbMsbLow = (nUint32LittleEndianValue >> 8) & 0xff;
unsigned char nLsbMsbHigh = (nUint32LittleEndianValue >> 16) & 0xff;
unsigned char nMsb = (nUint32LittleEndianValue >> 24) & 0xff;
pBigEndianBuffer[0] = nMsb;
pBigEndianBuffer[1] = nLsbMsbHigh;
pBigEndianBuffer[2] = nLsbMsbLow;
pBigEndianBuffer[3] = nLsb;
}
static unsigned short BigToLittleEndianUint16(unsigned char *pBigEndianStart) {
unsigned char nMsb = pBigEndianStart[0];
unsigned char nLsb = pBigEndianStart[1];
return (nMsb << 8 | nLsb << 0);
}
static unsigned int BigToLittleEndianUint32(unsigned char *pBigEndianStart) {
unsigned char nMsb = pBigEndianStart[0];
unsigned char nMsbLsbHigh = pBigEndianStart[1];
unsigned char nMsbLsbLow = pBigEndianStart[2];
unsigned char nLsb = pBigEndianStart[3];
return (nMsb << 24 | nMsbLsbHigh << 16 | nMsbLsbLow << 8 | nLsb << 0);
}
static void LittleToBigEndianUint16(unsigned char *pBigEndianBuffer,
unsigned int nUint16LittleEndianValue) {
unsigned char nLsb = nUint16LittleEndianValue & 0xff;
unsigned char nMsb = (nUint16LittleEndianValue >> 8) & 0xff;
pBigEndianBuffer[0] = nMsb;
pBigEndianBuffer[1] = nLsb;
}
static unsigned short Get2BBIGEndian(const unsigned char *pBuff, int offset) {
unsigned char upperByte = 0;
unsigned char lowerByte = 0;
memcpy(&upperByte, pBuff + offset, 1);
memcpy(&lowerByte, pBuff + offset + 1, 1);
return (upperByte << 8 | lowerByte);
}
IPv4Packet::IPv4Packet(unsigned int size) :
m_PacketSize(size) {
}
IPv4Packet::~IPv4Packet(void) {
if (0 != m_Packet) {
delete[] m_Packet;
m_Packet = 0;
}
}
void IPv4Packet::ToNetworkByteStream(unsigned char *buffer) {
if (0 == buffer) {
LOG_MSG_ERROR("IPv4Packet::ToNetworkByteStream : NULL arguments");
return;
}
memcpy(buffer, m_Packet, GetSize());
}
unsigned int IPv4Packet::GetSrcAddr(void) {
return BigToLittleEndianUint32(m_Packet + 12);
}
void IPv4Packet::SetSrcAddr(unsigned int addr) {
LittleToBigEndianUint32(m_Packet + 12, addr);
RecalculateChecksum();
}
unsigned int IPv4Packet::GetDstAddr(void) {
return BigToLittleEndianUint32(m_Packet + 16);
}
void IPv4Packet::SetDstAddr(unsigned int addr) {
LittleToBigEndianUint32(m_Packet + 16, addr);
RecalculateChecksum();
}
unsigned char IPv4Packet::GetProtocol(void) {
unsigned char retVal = 0;
memcpy(&retVal, m_Packet + 9, sizeof(unsigned char));
return retVal;
}
unsigned short IPv4Packet::GetSrcPort(void) {
return BigToLittleEndianUint16(m_Packet + 20);
}
unsigned short IPv4Packet::GetDstPort(void) {
return BigToLittleEndianUint16(m_Packet + 22);
}
void IPv4Packet::SetDstPort(unsigned short port) {
LittleToBigEndianUint16(m_Packet + 22, port);
RecalculateChecksum();
}
void IPv4Packet::SetSrcPort(unsigned short port) {
LittleToBigEndianUint16(m_Packet + 20, port);
RecalculateChecksum();
}
///////////////////////////////////////////////////////////////////////////////
//Set the third MSB bit of the IPV4_FLAGS_BYTE_OFFSET's byte
void IPv4Packet::SetMF(bool bValue) {
Byte * pFlags = m_Packet + IPV4_FLAGS_BYTE_OFFSET;
//clear the bit
if (true == bValue) {
*pFlags |= (0x20);
} else {
*pFlags &= (~0x20);
}
}
///////////////////////////////////////////////////////////////////////////////
void IPv4Packet::RecalculateChecksum(void) {
RecalculateIPChecksum();
RecalculateTCPChecksum();
RecalculateUDPChecksum();
}
void IPv4Packet::RecalculateIPChecksum(void) {
unsigned short pUint16[100];
int headerLen = (m_Packet[0] & 0x0F) * 2;
int checksum = 0;
unsigned short result = 0;
memset(&pUint16, 0, 100 * sizeof(unsigned short));
//clear the IP checksum field first
memset(m_Packet + 10, 0, sizeof(unsigned short));
memcpy(&pUint16, m_Packet, headerLen * sizeof(unsigned short));
for (int i = 0; i < headerLen; i++) {
checksum += pUint16[i];
checksum = (checksum & 0xFFFF) + (checksum >> 16);
}
result = (~checksum & 0xFFFF);
memcpy(m_Packet + 10, &result, sizeof(unsigned short));
return;
}
void TCPPacket::RecalculateTCPChecksum(void) {
unsigned short *pUint16 = new unsigned short[100];
int checksum = 0;
int headerLen = 0;
unsigned short *pTemp = 0;
unsigned short result = 0;
headerLen = Get2BBIGEndian(m_Packet, 2) - (m_Packet[0] & 0x0F) * 4;
memset(pUint16, 0, 100);
//clear the TCP checksum field first
memset(m_Packet + 36, 0, sizeof(unsigned short));
memcpy(pUint16, m_Packet, headerLen * sizeof(unsigned short));
pTemp = pUint16;
// Pseudo Header
pUint16 += 6; // Source IP
for (int i = 0; i < 4; i++) {
checksum += pUint16[i];
checksum = (checksum & 0xFFFF) + (checksum >> 16);
}
checksum += 0x0600; // TCP Protocol
checksum += Get2BBIGEndian((unsigned char*) &headerLen, 0);
pUint16 = pTemp + (m_Packet[0] & 0x0F) * 2;
headerLen /= 2;
for (int i = 0; i < headerLen; i++) {
checksum += pUint16[i];
checksum = (checksum & 0xFFFF) + (checksum >> 16);
}
result = (~checksum & 0xFFFF);
memcpy(m_Packet + 36, &result, sizeof(unsigned short));
delete[] pTemp;
return;
}
void UDPPacket::RecalculateUDPChecksum(void) {
unsigned short *pUint16 = new unsigned short[100];
int checksum = 0;
int headerLen = 0;
unsigned short *pTemp = 0;
unsigned short result = 0;
headerLen = Get2BBIGEndian(m_Packet, (m_Packet[0] & 0x0F) * 4 + 4);
memset(pUint16, 0, 100);
//clear the UDP checksum field first
memset(m_Packet + 26, 0, sizeof(unsigned short));
memcpy(pUint16, m_Packet, headerLen * sizeof(unsigned short));
pTemp = pUint16;
// Pseudo Header
pUint16 += 6; // Source IP
for (int i = 0; i < 4; i++) {
checksum += pUint16[i];
checksum = (checksum & 0xFFFF) + (checksum >> 16);
}
checksum += 0x1100; // UDP Protocol
checksum += Get2BBIGEndian((unsigned char*) &headerLen, 0);
pUint16 = pTemp + (m_Packet[0] & 0x0F) * 2;
headerLen /= 2;
for (int i = 0; i < headerLen; i++) {
checksum += pUint16[i];
checksum = (checksum & 0xFFFF) + (checksum >> 16);
}
result = (~checksum & 0xFFFF);
memcpy(m_Packet + 26, &result, sizeof(unsigned short));
delete[] pTemp;
return;
}
TCPPacket::TCPPacket(void) :
IPv4Packet(sizeof(TCP_IP_PACKET_DUMP)) {
size_t length = GetSize();
m_Packet = new unsigned char[length];
if (0 == m_Packet) {
LOG_MSG_ERROR("TCPPacket : packet allocation failed");
return;
}
memcpy(m_Packet, TCP_IP_PACKET_DUMP, length);
}
UDPPacket::UDPPacket(void) :
IPv4Packet(sizeof(UDP_IP_PACKET_DUMP)) {
size_t length = GetSize();
m_Packet = new unsigned char[length];
if (0 == m_Packet) {
LOG_MSG_ERROR("UDPPacket : packet allocation failed");
return;
}
memcpy(m_Packet, UDP_IP_PACKET_DUMP, length);
}
ICMPPacket::ICMPPacket(void) :
IPv4Packet(sizeof(ICMP_IP_PACKET_DUMP)) {
size_t length = GetSize();
m_Packet = new unsigned char[length];
if (0 == m_Packet) {
LOG_MSG_ERROR("ICMPPacket : packet allocation failed");
return;
}
memcpy(m_Packet, ICMP_IP_PACKET_DUMP, length);
}
unsigned short ICMPPacket::GetSrcPort(void) {
return 0;
}
unsigned short ICMPPacket::GetDstPort(void) {
return 0;
}
void ICMPPacket::SetDstPort(unsigned short port) {
(void) port;
return;
}
void ICMPPacket::SetSrcPort(unsigned short port) {
(void) port;
return;
}

179
kernel-tests/IPv4Packet.h Normal file
View File

@@ -0,0 +1,179 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef __IPA_TESTS_IPV4_PACKET__H__
#define __IPA_TESTS_IPV4_PACKET__H__
namespace IPA
{
#define IPV4_FLAGS_BYTE_OFFSET 6
/**
@brief
IPv4Packet abstract class.
@details
new setters should call to RecalculateChecksum();
*/
class IPv4Packet
{
public:
IPv4Packet(unsigned int size);
virtual ~IPv4Packet(void) = 0;
void ToNetworkByteStream(unsigned char *addr);
unsigned int GetSrcAddr(void);
void SetSrcAddr(unsigned int addr);
unsigned int GetDstAddr(void);
void SetDstAddr(unsigned int addr);
unsigned char GetProtocol(void);
unsigned int GetSize(void)
{
return m_PacketSize;
}
virtual unsigned short GetSrcPort(void);
virtual unsigned short GetDstPort(void);
virtual void SetDstPort(unsigned short port);
virtual void SetSrcPort(unsigned short port);
void SetMF(bool bValue);
protected:
virtual void RecalculateTCPChecksum(void) {}
virtual void RecalculateUDPChecksum(void) {}
virtual void RecalculateICMPChecksum(void) {}
unsigned char *m_Packet;
private:
unsigned int m_PacketSize;
void RecalculateChecksum(void);
void RecalculateIPChecksum(void);
};
/**
@brief
TCPPacket implementation.
@details
new setters should call to RecalculateChecksum();
*/
class TCPPacket:public IPv4Packet
{
public:
TCPPacket(void);
~TCPPacket(void) {}
protected:
virtual void RecalculateTCPChecksum(void);
};
/**
@brief
UDPPacket implementation.
@details
new setters should call to RecalculateChecksum();
*/
class UDPPacket:public IPv4Packet
{
public:
UDPPacket(void);
~UDPPacket(void) {}
protected:
virtual void RecalculateUDPChecksum(void);
};
/**
@brief
ICMPPacket implementation.
@details
new setters should call to RecalculateChecksum();
*/
class ICMPPacket:public IPv4Packet
{
public:
ICMPPacket(void);
~ICMPPacket(void) {}
virtual unsigned short GetSrcPort(void);
virtual unsigned short GetDstPort(void);
virtual void SetDstPort(unsigned short port);
virtual void SetSrcPort(unsigned short port);
protected:
/**
@brief
RecalculateICMPChecksum method.
@details
ICMP checksum recalculation is not needed now
and by so is not implemented yet
TODO: implement if needed
*/
virtual void RecalculateICMPChecksum(void)
{
return;
}
};
} /* namespace IPA */
#endif

1781
kernel-tests/IPv6CTTest.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,155 @@
/*
* Copyright (c) 2017 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 <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "InterfaceAbstraction.h"
#define MAX_OPEN_RETRY 10000
bool InterfaceAbstraction::Open(const char * toIPAPath, const char * fromIPAPath)
{
int tries_cnt = MAX_OPEN_RETRY;
if (NULL == toIPAPath && NULL == fromIPAPath)
{
printf("InterfaceAbstraction constructor got 2 null arguments.\n");
exit(0);
}
if (NULL != toIPAPath) {
while (tries_cnt > 0) {
printf("trying to open %s %d/%d\n", toIPAPath, MAX_OPEN_RETRY - tries_cnt, MAX_OPEN_RETRY);
// Sleep for 5 msec
usleep(5000);
m_toIPADescriptor = open(toIPAPath, O_WRONLY);
if (-1 != m_toIPADescriptor) {
printf("Success!\n");
break;
}
tries_cnt--;
}
printf("open retries_cnt=%d\n", MAX_OPEN_RETRY - tries_cnt);
if (-1 == m_toIPADescriptor) {
printf("InterfaceAbstraction failed while opening %s.\n", toIPAPath);
exit(0);
}
m_toChannelName = toIPAPath;
printf("%s device node opened, fd = %d.\n", toIPAPath, m_toIPADescriptor);
}
tries_cnt = MAX_OPEN_RETRY;
if (NULL != fromIPAPath) {
while (tries_cnt > 0) {
printf("trying to open %s %d/%d\n", fromIPAPath, MAX_OPEN_RETRY - tries_cnt, MAX_OPEN_RETRY);
// Sleep for 5 msec
usleep(5000);
m_fromIPADescriptor = open(fromIPAPath, O_RDONLY);
if (-1 != m_fromIPADescriptor) {
printf("Success!\n");
break;
}
tries_cnt--;
}
printf("open retries_cnt=%d\n", MAX_OPEN_RETRY - tries_cnt);
if (-1 == m_fromIPADescriptor)
{
printf("InterfaceAbstraction failed on opening %s.\n", fromIPAPath);
exit(0);
}
m_fromChannelName = fromIPAPath;
printf("%s device node opened, fd = %d.\n", fromIPAPath, m_fromIPADescriptor);
}
return true;
}/*Ctor*/
void InterfaceAbstraction::Close()
{
close(m_toIPADescriptor);
close(m_fromIPADescriptor);
}
bool InterfaceAbstraction::SendData(unsigned char *buf, size_t size)
{
int bytesWritten = 0;
printf("Trying to write %zu bytes to %d.\n", size, m_toIPADescriptor);
bytesWritten = write(m_toIPADescriptor, buf, size);
if (-1 == bytesWritten)
{
int err = errno;
printf(
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
printf(
"Failed to execute command\n write(m_toIPADescriptor, buf, size);\n "
"m_toIPADescriptor=%d, buf=0x%p, size=%zu",m_toIPADescriptor,
buf,
size);
printf("Error on write execution, errno=%d, Quitting!\n", err);
printf(
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
exit(-1);
}
printf("bytesWritten = %d.\n", bytesWritten);
return bytesWritten;
}
int InterfaceAbstraction::ReceiveData(unsigned char *buf, size_t size)
{
size_t bytesRead = 0;
size_t totalBytesRead = 0;
bool continueRead = false;
do
{
printf("Trying to read %zu bytes from %d.\n", size, m_fromIPADescriptor);
bytesRead = read(m_fromIPADescriptor, (void*)buf, size);
printf("Read %zu bytes.\n", bytesRead);
totalBytesRead += bytesRead;
if (bytesRead == size)
continueRead = true;
else
continueRead = false;
} while (continueRead);
return totalBytesRead;
}
InterfaceAbstraction::~InterfaceAbstraction()
{
close(m_fromIPADescriptor);
m_fromChannelName = "";
close(m_toIPADescriptor);
m_toChannelName = "";
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef INTERFACE_ABSTRACTION_H_
#define INTERFACE_ABSTRACTION_H_
#include <stdio.h>
#include <stdlib.h>
#include <string>
typedef unsigned char Byte;
using namespace std;
class InterfaceAbstraction
{
public:
~InterfaceAbstraction();
bool Open(const char *toIPAPath, const char *fromIPAPath);
void Close();
bool SendData(unsigned char *buffer, size_t size);
int ReceiveData(unsigned char *buf, size_t size);
string m_toChannelName;
string m_fromChannelName;
private:
int m_toIPADescriptor;
int m_fromIPADescriptor;
};
#endif

59
kernel-tests/Logger.cpp Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2017 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 "Logger.h"
////////////////////////////////////////////////////////////////////////////
//The trace level of the system will be used to choose the system printing level
Logger::Logger(TraceLevel nTraceLevel)
{
m_nTraceLevelToPresent = nTraceLevel;
}
////////////////////////////////////////////////////////////////////////////
//This method will be use to print messages. it will also gie a trace level for each message.
void Logger::AddMessage(TraceLevel nTraceLevel, const char *format, ...)
{
//in case the trace level is not "high" no print should be made.
if (nTraceLevel < m_nTraceLevelToPresent)
{
return;
}
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
}
////////////////////////////////////////////////////////////////////////////

60
kernel-tests/Logger.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef LOGGER_H_
#define LOGGER_H_
#include <stdio.h>
#include <stdarg.h>
using namespace std;
typedef enum{
LOG_DEVELOPMENT = 0,
LOG_ERROR = 0,
LOG_VERBOSE = 1
} TraceLevel;
/*This class will controll all the printing in the test application
*In each test there will be many printing while each
*specific print will define it's "importancy"(TraceLevel)
*During the development of the test it is
*strongly suggested to use LOG_DEVELOPMENT.
*/
class Logger
{
public:
Logger(TraceLevel nTraceLevelToPresent);
void AddMessage(TraceLevel nTraceLevel, const char *format, ...);
private:
int m_nTraceLevelToPresent;
};
#endif /* LOGGER_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
/*
* 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 "Constants.h"
#include "Logger.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "TestBase.h"
#include "Pipe.h"
#include "RoutingDriverWrapper.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
#define NUM_PACKETS 5
#define NUM_PACKETS_FC 4
#define MAX_PACKET_SIZE 1024
#define MAX_PACKETS_IN_MBIM_TESTS 10
#define MAX_PACKETS_IN_NDP 8
#define MAX_NDPS_IN_PACKET 8
/*This class will be the base class of MBIM Aggregation tests.
*Any method other than the test case itself
*can be declared in this Fixture thus allowing the derived classes to
*implement only the test case.
*All the test of the Aggregation uses one input and one output in DMA mode.
*/
class MBIMAggregationTestFixtureConf11:public TestBase
{
public:
/*This Constructor will register each instance that it creates.*/
MBIMAggregationTestFixtureConf11(bool generic_agg);
virtual int SetupKernelModule();
/*This method will create and initialize two Pipe object
*for the USB (Ethernet) Pipes, one
*for as input and the other as output.
*/
virtual bool Setup();
/*This method will destroy the pipes.*/
virtual bool Teardown();
virtual bool Run();
virtual bool AddRules() = 0;
virtual bool TestLogic() = 0;
bool AddRules1HeaderAggregation();
bool AddRules1HeaderAggregation(bool bAggForceClose);
bool AddRulesDeaggregation();
bool AddRules1HeaderAggregationTime();
bool AddRules1HeaderAggregation0Limits();
bool AddRulesAggDualFC(Pipe *input, Pipe *output1, Pipe *output2);
bool AddRulesAggDualFcRoutingBased(Pipe *input, Pipe *output1, Pipe *output2);
/*The client type are set from the
* peripheral perspective
*/
static Pipe m_IpaToUsbPipeAgg;
static Pipe m_UsbToIpaPipe;
static Pipe m_IpaToUsbPipe;
static Pipe m_UsbToIpaPipeDeagg;
static Pipe m_IpaToUsbPipeAggTime;
static Pipe m_IpaToUsbPipeAgg0Limits;
static RoutingDriverWrapper m_Routing;
static Filtering m_Filtering;
static HeaderInsertion m_HeaderInsertion;
protected:
enum ipa_ip_type m_eIP;
bool mGenericAgg;
};

File diff suppressed because it is too large Load Diff

51
kernel-tests/Makefile.am Normal file
View File

@@ -0,0 +1,51 @@
ACLOCAL_AMFLAGS = -Im4
EXTRA_CFLAGS = -DDEBUG
AM_CXXFLAGS = -Wall -Wundef -Wno-trigraphs -Werror
if USE_GLIB
ipa_kernel_tests_CPPFLAGS = $(AM_CFLAGS) -DUSE_GLIB -Dstrlcpy=g_strlcpy @GLIB_CFLAGS@
ipa_kernel_tests_LDFLAGS = -lpthread @GLIB_LIBS@
endif
requiredlibs = -lipanat
ipa_kernel_tests_LDADD = $(requiredlibs)
ipa_kernel_testsdir = $(prefix)
ipa_kernel_tests_PROGRAMS = ipa_kernel_tests
dist_ipa_kernel_tests_SCRIPTS = run.sh
ipa_kernel_tests_SOURCES =\
TestManager.cpp \
TestBase.cpp \
InterfaceAbstraction.cpp \
Pipe.cpp \
PipeTestFixture.cpp \
PipeTests.cpp \
TLPAggregationTestFixture.cpp \
TLPAggregationTests.cpp \
MBIMAggregationTestFixtureConf11.cpp \
MBIMAggregationTests.cpp \
Logger.cpp \
RoutingDriverWrapper.cpp \
RoutingTests.cpp \
IPAFilteringTable.cpp \
Filtering.cpp \
FilteringTest.cpp \
HeaderInsertion.cpp \
HeaderInsertionTests.cpp \
TestsUtils.cpp \
HeaderRemovalTestFixture.cpp \
HeaderRemovalTests.cpp \
IPv4Packet.cpp \
RNDISAggregationTestFixture.cpp \
RNDISAggregationTests.cpp \
DataPathTestFixture.cpp \
DataPathTests.cpp \
IPAInterruptsTestFixture.cpp \
IPAInterruptsTests.cpp \
HeaderProcessingContextTestFixture.cpp \
HeaderProcessingContextTests.cpp \
FilteringEthernetBridgingTestFixture.cpp \
FilteringEthernetBridgingTests.cpp \
NatTest.cpp \
IPv6CTTest.cpp \
main.cpp

26
kernel-tests/NOTICE Normal file
View File

@@ -0,0 +1,26 @@
Copyright (c) 2021 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.

4288
kernel-tests/NatTest.cpp Normal file

File diff suppressed because it is too large Load Diff

729
kernel-tests/Pipe.cpp Normal file
View File

@@ -0,0 +1,729 @@
/*
* Copyright (c) 2017-2018,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 "Pipe.h"
#include "TestsUtils.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//Do not change those default values due to the fact that some test may relay on those default values.
//In case you need a change of the field do this in a derived class.
//Dest MAC(6 bytes) Src MAC(6 Bytes) EtherType(2 Bytes)
unsigned char Pipe::m_pUsbHeader[] = { 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xB1, 0xB2,
0xB3, 0xB4, 0xB5, 0xB6, 0xC1, 0xC2 };
unsigned char Pipe::m_pA2NDUNHeader[] =
{ 0xA1, 0xA2, 0xA3, 0xA4, 0xB1, 0xB2, 0xC1, 0xC2 };
//unsigned char Pipe::m_pA2DUNHeader[] = {};
//unsigned char Pipe::m_pQ6LANHeader[] = {};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
Pipe::Pipe(enum ipa_client_type nClientType,
IPATestConfiguration eConfiguration) :
m_Fd(-1), m_nHeaderLengthRemove(0),
m_nHeaderLengthAdd(0), m_pHeader(NULL), m_pInodePath(NULL),
m_bInitialized(false), m_ExceptionPipe(false) {
m_nClientType = nClientType;
m_eConfiguration = eConfiguration;
}
Pipe::Pipe(IPATestConfiguration eConfiguration) :
m_Fd(-1), m_nHeaderLengthRemove(0),
m_nHeaderLengthAdd(0), m_pHeader(NULL), m_pInodePath(NULL),
m_bInitialized(false), m_ExceptionPipe(true) {
m_eConfiguration = eConfiguration;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
Pipe::~Pipe() {
//Nothing to be done at this point...
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Pipe::Init() {
int tries_cnt = 1;
SetSpecificClientParameters(m_nClientType, m_eConfiguration);
//By examining the Client type we will map the inode device name
while (tries_cnt <= 10000) {
m_Fd = open(m_pInodePath, O_RDWR);
if (-1 != m_Fd)
break;
// Sleep for 5 msec
usleep(5000);
++tries_cnt;
}
LOG_MSG_DEBUG("open retries_cnt=%d\n", tries_cnt);
if (-1 == m_Fd) {
LOG_MSG_ERROR("Failed to open %s", m_pInodePath);
return false;
}
m_bInitialized = true;
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void Pipe::Destroy() {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return;
}
close(m_Fd);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int Pipe::Send(unsigned char * pBuffer, size_t nBytesToSend) {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return 0;
}
size_t nBytesWritten = 0;
nBytesWritten = write(m_Fd, pBuffer, nBytesToSend);
return nBytesWritten;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int Pipe::AddHeaderAndSend(unsigned char * pIpPacket, size_t nIpPacketSize) {
int retval;
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return 0;
}
size_t nBytesToWrite = nIpPacketSize + m_nHeaderLengthAdd;
//Allocate new buffer for the Header and IP packet:
unsigned char *pLinkLayerAndIpPacket = new unsigned char[nBytesToWrite];
if (!pLinkLayerAndIpPacket) {
LOG_MSG_ERROR("Memory allocation failure.");
return 0;
}
//put the header first:
memcpy(pLinkLayerAndIpPacket, m_pHeader, m_nHeaderLengthAdd);
//Then add the IP packet:
memcpy(pLinkLayerAndIpPacket + m_nHeaderLengthAdd, pIpPacket,
nIpPacketSize);
//Call the Send method which will send the new created buffer(which contains the IP packet with the Header):
retval = Send(pLinkLayerAndIpPacket, nBytesToWrite);
delete[] pLinkLayerAndIpPacket;
return retval;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int Pipe::Receive(unsigned char *pBuffer, size_t nBytesToReceive) {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return 0;
}
size_t nBytesRead = 0;
nBytesRead = read(m_Fd, (void*) pBuffer, nBytesToReceive);
return nBytesRead;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int Pipe::ReceiveAndRemoveHeader(unsigned char *pIpPacket, size_t nIpPacketSize) {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return 0;
}
size_t nBytesToRead = nIpPacketSize + m_nHeaderLengthRemove;
unsigned char *pPacket = new unsigned char[nBytesToRead];
if (!pPacket) {
LOG_MSG_ERROR("Memory allocation failure.");
return 0;
}
size_t nReceivedBytes = Receive(pPacket, nBytesToRead);
if (nReceivedBytes != nBytesToRead) {
LOG_MSG_ERROR("Pipe was asked to receive an IP packet "
"of size %d, however only %d bytes were read "
"while the header size is %d",
nIpPacketSize,
nReceivedBytes,
m_nHeaderLengthRemove);
delete[] pPacket;
return nReceivedBytes - m_nHeaderLengthRemove;
}
memcpy(pIpPacket, pPacket + m_nHeaderLengthRemove, nIpPacketSize);
delete[] pPacket;
return (nReceivedBytes - m_nHeaderLengthRemove);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
enum ipa_client_type Pipe::GetClientType() {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return IPA_CLIENT_HSIC1_PROD;
}
return m_nClientType;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void Pipe::SetSpecificClientParameters(
enum ipa_client_type nClientType,
IPATestConfiguration eConfiguration) {
switch (eConfiguration) {
case IPA_TEST_CONFIFURATION_0:
break;
case IPA_TEST_CONFIFURATION_1:
switch (nClientType) {
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_1_FROM_USB1_TO_IPA_DMA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD ");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_1_FROM_IPA_TO_USB1_DMA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_1 switch in default "
"nClientType = %d is not supported ", nClientType);
break;
}
break;
case IPA_TEST_CONFIFURATION_2:
switch (nClientType) {
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_2_FROM_USB_TO_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD");
break;
case (IPA_CLIENT_TEST2_CONS):
m_pInodePath = CONFIG_2_FROM_IPA_TO_A2_NDUN;
m_nHeaderLengthAdd = sizeof(m_pA2NDUNHeader);
m_nHeaderLengthRemove = sizeof(m_pA2NDUNHeader);
m_pHeader = m_pA2NDUNHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_CONS");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_2 switch in default "
"nClientType = %d is not supported ", nClientType);
break;
}
break;
case IPA_TEST_CONFIFURATION_3:
switch (nClientType) {
case IPA_CLIENT_TEST2_PROD:
m_pInodePath = CONFIG_3_FROM_A2_NDUN_TO_IPA;
m_nHeaderLengthAdd = sizeof(m_pA2NDUNHeader);
m_nHeaderLengthRemove = sizeof(m_pA2NDUNHeader);
m_pHeader = m_pA2NDUNHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_PROD");
break;
case IPA_CLIENT_TEST_CONS:
m_pInodePath = CONFIG_3_FROM_IPA_TO_USB1;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
case IPA_CLIENT_TEST2_CONS:
m_pInodePath = CONFIG_3_FROM_IPA_TO_A2_NDUN;
m_nHeaderLengthAdd = sizeof(m_pA2NDUNHeader);
m_nHeaderLengthRemove = sizeof(m_pA2NDUNHeader);
m_pHeader = m_pA2NDUNHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_CONS");
break;
case IPA_CLIENT_TEST4_CONS:
//TODO add when applicable
m_pInodePath = CONFIG_3_FROM_IPA_TO_Q6_LAN;
m_nHeaderLengthAdd = 0;
m_nHeaderLengthRemove = 0;
m_pHeader = 0;
LOG_MSG_INFO("IPA_CLIENT_TEST4_CONS is not supported yet");
break;
default:
LOG_MSG_INFO("IPA_TEST_CONFIFURATION_3 switch in default "
"nClientType = %d is not supported ", nClientType);
break;
}
break;
case IPA_TEST_CONFIFURATION_7:
if (m_ExceptionPipe) {
m_pInodePath = CONFIG_7_FROM_IPA_TO_A5_EXCEPTION;
m_nHeaderLengthAdd = 0; //No send
m_nHeaderLengthRemove = 8; //A5Mux header size without retained source header
m_pHeader = NULL; //No header to send
LOG_MSG_INFO("Setting parameters for A5_Exception ");
break;
}
if (nClientType == IPA_CLIENT_TEST_PROD) {
m_pInodePath = CONFIG_7_FROM_USB1_TO_IPA;
m_nHeaderLengthAdd = 0;
m_nHeaderLengthRemove = 0;
m_pHeader = NULL;
LOG_MSG_INFO(
"Setting parameters for FROM_USB1_TO_IPA - no header addition/removal");
} else {
LOG_MSG_INFO("IPA_TEST_CONFIFURATION_7 switch in default "
"nClientType = %d is not supported ", nClientType);
}
break;
case IPA_TEST_CONFIGURATION_8:
switch(nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_8_DEAGG_TO_IPA_NO_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD ");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_8_FROM_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
case (IPA_CLIENT_TEST3_PROD):
m_pInodePath = CONFIG_8_NO_AGG_TO_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_PROD ");
break;
case (IPA_CLIENT_TEST3_CONS):
m_pInodePath = CONFIG_8_FROM_IPA_NO_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_CONS");
break;
case (IPA_CLIENT_TEST2_PROD):
m_pInodePath = CONFIG_8_DEAGG_TO_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_PROD");
break;
case (IPA_CLIENT_TEST2_CONS):
m_pInodePath = CONFIG_8_DEAGG_FROM_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_CONS");
break;
case (IPA_CLIENT_TEST4_PROD):
m_pInodePath = CONFIG_8_NO_AGG_TO_IPA_AGG_TIME;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST4_PROD");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_8 switch in default "
"nClientType = %d is not supported ",
nClientType);
break;
}
break;
case IPA_TEST_CONFIGURATION_9:
switch(nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_9_DEAGG_TO_IPA_NO_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD ");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_9_FROM_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
case (IPA_CLIENT_TEST3_PROD):
m_pInodePath = CONFIG_9_NO_AGG_TO_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_PROD ");
break;
case (IPA_CLIENT_TEST3_CONS):
m_pInodePath = CONFIG_9_FROM_IPA_NO_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_CONS");
break;
case (IPA_CLIENT_TEST2_PROD):
m_pInodePath = CONFIG_9_DEAGG_TO_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_PROD");
break;
case (IPA_CLIENT_TEST2_CONS):
m_pInodePath = CONFIG_9_DEAGG_FROM_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_CONS");
break;
case (IPA_CLIENT_TEST4_PROD):
m_pInodePath = CONFIG_9_NO_AGG_TO_IPA_AGG_TIME;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST4_PROD");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_9 switch in default "
"nClientType = %d is not supported ",
nClientType);
break;
}
break;
case IPA_TEST_CONFIGURATION_10:
switch(nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_10_TO_IPA_AGG_ZERO_LIMITS;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_10_FROM_IPA_AGG_ZERO_LIMITS;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_10 switch in default "
"nClientType = %d is not supported ",
nClientType);
break;
}
break;
case IPA_TEST_CONFIGURATION_11:
switch(nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_11_TO_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD");
break;
case (IPA_CLIENT_TEST2_CONS):
m_pInodePath = CONFIG_11_FROM_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_CONS");
break;
case (IPA_CLIENT_TEST2_PROD):
m_pInodePath = CONFIG_11_TO_IPA_DEAGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_PROD");
break;
case (IPA_CLIENT_TEST3_CONS):
m_pInodePath = CONFIG_11_FROM_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_CONS");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_11_FROM_IPA_AGG_TIME;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
case (IPA_CLIENT_TEST4_CONS):
m_pInodePath = CONFIG_11_FROM_IPA_ZERO_LIMITS;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST4_CONS");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_11 switch in default "
"nClientType = %d is not supported ",
nClientType);
break;
}
break;
case IPA_TEST_CONFIGURATION_12:
switch(nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_12_TO_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD");
break;
case (IPA_CLIENT_TEST2_CONS):
m_pInodePath = CONFIG_12_FROM_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_CONS");
break;
case (IPA_CLIENT_TEST2_PROD):
m_pInodePath = CONFIG_12_TO_IPA_DEAGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_PROD");
break;
case (IPA_CLIENT_TEST3_CONS):
m_pInodePath = CONFIG_12_FROM_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_CONS");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_12_FROM_IPA_AGG_TIME;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
case (IPA_CLIENT_TEST4_CONS):
m_pInodePath = CONFIG_12_FROM_IPA_ZERO_LIMITS;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST4_CONS");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_12 switch in default "
"nClientType = %d is not supported ",
nClientType);
break;
}
break;
case IPA_TEST_CONFIGURATION_17:
switch(nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_17_TO_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD ");
break;
case (IPA_CLIENT_TEST3_PROD):
m_pInodePath = CONFIG_17_TO_IPA_NO_HDR;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_PROD ");
break;
case (IPA_CLIENT_TEST2_CONS):
m_pInodePath = CONFIG_17_FROM_IPA_AGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_CONS");
break;
case (IPA_CLIENT_TEST2_PROD):
m_pInodePath = CONFIG_17_TO_IPA_DEAGG;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_PROD ");
break;
case (IPA_CLIENT_TEST3_CONS):
m_pInodePath = CONFIG_17_FROM_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST3_CONS");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_17_FROM_IPA_AGG_TIME;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
case (IPA_CLIENT_TEST4_CONS):
m_pInodePath = CONFIG_17_FROM_IPA_ZERO_LIMITS;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST4_CONS");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_17 switch in default "
"nClientType = %d is not supported ",
nClientType);
break;
}
break;
case IPA_TEST_CONFIGURATION_18:
switch (nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_18_TO_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD ");
break;
case (IPA_CLIENT_TEST2_PROD):
m_pInodePath = CONFIG_18_DUMMY_ENDPOINT;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST2_PROD ");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_18_FROM_IPA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_CONS");
break;
default:
LOG_MSG_ERROR(
"IPA_TEST_CONFIFURATION_18 switch in default "
"nClientType = %d is not supported ",
nClientType);
break;
}
break;
case IPA_TEST_CONFIGURATION_19:
switch (nClientType)
{
case (IPA_CLIENT_TEST_PROD):
m_pInodePath = CONFIG_19_FROM_USB_TO_IPA_DMA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for IPA_CLIENT_TEST_PROD ");
break;
case (IPA_CLIENT_TEST_CONS):
m_pInodePath = CONFIG_19_FROM_IPA_TO_USB_DMA;
m_nHeaderLengthAdd = sizeof(m_pUsbHeader);
m_nHeaderLengthRemove = sizeof(m_pUsbHeader);
m_pHeader = m_pUsbHeader;
LOG_MSG_INFO("Setting parameters for TEST_CONS");
break;
default:
LOG_MSG_ERROR("IPA_TEST_CONFIFURATION_19 switch in default "
"nClientType = %d is not supported ", nClientType);
break;
}
break;
default:
LOG_MSG_ERROR("Pipe::SetSpecificClientParameters "
"switch in default eConfiguration = %d ", eConfiguration);
break;
}
}/* Pipe::SetSpecificClientParameters() */
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int Pipe::GetHeaderLengthAdd() {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return 0;
}
return m_nHeaderLengthAdd;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int Pipe::GetHeaderLengthRemove() {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return 0;
}
return m_nHeaderLengthRemove;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Pipe::ConfigureHolb(unsigned short enable, unsigned timerValue) {
if (false == m_bInitialized) {
LOG_MSG_ERROR("Pipe is being used without being initialized!");
return false;
}
if (IPA_CLIENT_IS_PROD(m_nClientType)) {
LOG_MSG_ERROR("Can't configure HOLB on a producer pipe!");
return false;
}
struct ipa_test_holb_config test_holb_config;
test_holb_config.client = m_nClientType;
test_holb_config.tmr_val = timerValue;
test_holb_config.en = enable;
LOG_MSG_DEBUG("Sending: client=%d tmr_val=%d en=%d",
test_holb_config.client,
test_holb_config.tmr_val,
test_holb_config.en);
return configure_holb(&test_holb_config);
}
bool Pipe::EnableHolb(unsigned timerValue) {
return ConfigureHolb(1, timerValue);
}
bool Pipe::DisableHolb() {
return ConfigureHolb(0, 0);
}

151
kernel-tests/Pipe.h Normal file
View File

@@ -0,0 +1,151 @@
/*
* 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.
*/
#ifndef _PIPE_H_
#define _PIPE_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include "linux/msm_ipa.h"
#include "Constants.h"
#include "Logger.h"
using namespace std;
/*This class will be used to interact with the system pipes
*by only referring to Client type.
*It will allow "raw" data transfer to/from the IPA and
*will allow a encapsulation of the header addition/
*removal of a packets thus allowing
*the test to deal only with IP packet.
*/
class Pipe
{
public:
/* see Constants.h for nClientType / eConfiguration */
Pipe(enum ipa_client_type nClientType,
IPATestConfiguration eConfiguration);
/* exception pipe Ctor */
Pipe(IPATestConfiguration eConfiguration);
~Pipe();
/*In this method the actual inode openning will occur.*/
bool Init();
/*The close of the inode*/
void Destroy();
/*Send the pBuffer(which is an ip[ packet)
*after adding the header to the packet.*/
int AddHeaderAndSend(
unsigned char *pBuffer,
size_t nIPPacketSize);
/*Send raw data as is - no header removal
*- nBytesToSend bytes will be added*/
int Send(
unsigned char *pBuffer,
size_t nBytesToSend);
/*Receive data from the IPA and remove its header*/
int ReceiveAndRemoveHeader(
unsigned char *pBuffer,
size_t nIPPacketSize);
/*Receive data from the IPA as is*/
int Receive(unsigned char *pBuffer, size_t nBytesToReceive);
/*return the Client type of this pipe.*/
enum ipa_client_type GetClientType();
/*Return the length of the header to be added to an
*IP packet before it is being sent to the pipe
*(This length will be determine by the Pipe's ClientType).
*/
int GetHeaderLengthAdd();
/*Return the length of the header to be removed from a
*packet before it is being sent to the user
*(thus returning only the IP packet).
*(This length will be determine by the Pipe's ClientType).
*/
int GetHeaderLengthRemove();
bool EnableHolb(unsigned timerValue);
bool DisableHolb();
private:
void SetSpecificClientParameters(
enum ipa_client_type nClientType,
IPATestConfiguration eConfiguration);
bool ConfigureHolb(unsigned short enable, unsigned timerValue);
public:
/*efault Headers(Can be changed in Derived classes).*/
static unsigned char m_pUsbHeader[];
static unsigned char m_pHSICHeader[];
static unsigned char m_pA2DUNHeader[];
static unsigned char m_pA2NDUNHeader[];
static unsigned char m_pQ6LANHeader[];
private:
int m_Fd;
/*The file descriptor which will be used to transfer data
* via the inode(this inode will be created by the ITAKEM)
*/
enum ipa_client_type m_nClientType;
int m_nHeaderLengthRemove;
/*this length will be set in the
* constructor in corresponds to m_nClientType
*/
int m_nHeaderLengthAdd;
/*this length will be set in the constructor
* in corresponds to m_nClientType
*/
unsigned char *m_pHeader;
/*this pointer will be set to the current pipe used*/
const char *m_pInodePath;
/*this pointer will be set to the current pipe used*/
bool m_bInitialized;
IPATestConfiguration m_eConfiguration;
/*The Pipes configuration env*/
bool m_ExceptionPipe;
/* Is this the exception pipe */
};
#endif

View File

@@ -0,0 +1,107 @@
/*
* 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 "PipeTestFixture.h"
extern Logger g_Logger;
/*define the static Pipes which will be used by all derived tests.*/
Pipe PipeTestFixture::m_IpaToUsbPipe(IPA_CLIENT_TEST_CONS, IPA_TEST_CONFIFURATION_1);
Pipe PipeTestFixture::m_UsbToIpaPipe(IPA_CLIENT_TEST_PROD, IPA_TEST_CONFIFURATION_1);
PipeTestFixture::PipeTestFixture()
{
m_testSuiteName.push_back("Pipes");
Register(*this);
}
static int SetupKernelModule(void)
{
int retval;
struct ipa_channel_config from_ipa_0 = {0};
struct test_ipa_ep_cfg from_ipa_0_cfg;
struct ipa_channel_config to_ipa_0 = {0};
struct test_ipa_ep_cfg to_ipa_0_cfg;
struct ipa_test_config_header header = {0};
struct ipa_channel_config *to_ipa_array[1];
struct ipa_channel_config *from_ipa_array[1];
/* From ipa configurations - 1 pipes */
memset(&from_ipa_0_cfg, 0 , sizeof(from_ipa_0_cfg));
prepare_channel_struct(&from_ipa_0,
header.from_ipa_channels_num++,
IPA_CLIENT_TEST_CONS,
(void *)&from_ipa_0_cfg,
sizeof(from_ipa_0_cfg));
from_ipa_array[0] = &from_ipa_0;
/* To ipa configurations - 1 pipes */
memset(&to_ipa_0_cfg, 0 , sizeof(to_ipa_0_cfg));
to_ipa_0_cfg.mode.mode = IPA_DMA;
to_ipa_0_cfg.mode.dst = IPA_CLIENT_TEST_CONS;
prepare_channel_struct(&to_ipa_0,
header.to_ipa_channels_num++,
IPA_CLIENT_TEST_PROD,
(void *)&to_ipa_0_cfg,
sizeof(to_ipa_0_cfg));
to_ipa_array[0] = &to_ipa_0;
prepare_header_struct(&header, from_ipa_array, to_ipa_array);
retval = GenericConfigureScenario(&header);
return retval;
}
bool PipeTestFixture::Setup()
{
bool bRetVal = true;
if (SetupKernelModule() == false)
return false;
/*Initialize the pipe for all the tests -
* this will open the inode which represents the pipe.
*/
bRetVal &= m_IpaToUsbPipe.Init();
bRetVal &= m_UsbToIpaPipe.Init();
return bRetVal;
}
bool PipeTestFixture::Teardown()
{
/*The Destroy method will close the inode.*/
m_IpaToUsbPipe.Destroy();
m_UsbToIpaPipe.Destroy();
return true;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2017 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 "Constants.h"
#include "Logger.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "TestBase.h"
#include "Pipe.h"
/*This class will be the base class of all Pipe tests.
*Any method other than the test case itself can be
*declared in this Fixture thus allowing the derived classes to
*implement only the test case.
*All the test of the pipe uses one input and one output in DMA mode.
*/
class PipeTestFixture:public TestBase
{
public:
/*This Constructor will register each instance that it creates.*/
PipeTestFixture();
/*This method will create and initialize two Pipe object for the USB
* (Ethernet) Pipes, one as input and the other as output.
*/
virtual bool Setup();
/*This method will destroy the pipes.*/
virtual bool Teardown();
/*The client type are set from the peripheral perspective
* (TODO Pipe:in case the Driver will change its perspective
* of ipa_connect this should be changed).
*/
static Pipe m_IpaToUsbPipe;
static Pipe m_UsbToIpaPipe;
};

478
kernel-tests/PipeTests.cpp Normal file
View File

@@ -0,0 +1,478 @@
/*
* 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 "PipeTestFixture.h"
#include "Constants.h"
#include "TestsUtils.h"
#include "linux/msm_ipa.h"
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class PipeTestRawTransfer: public PipeTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
PipeTestRawTransfer() {
m_name = "PipeTestRawTransfer";
m_description = "This test will be using the Pipe raw transfer ability";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run() {
bool bTestResult = true;
Byte pIpPacket[] = { 0x01, 0x02, 0x03, 0x04 }; //This packet will be sent(It can be replaced by a real IP packet).
Byte pIpPacketReceive[sizeof(pIpPacket)] = { 0 }; //This buffer will be used in order to store the received packet.
//Send the raw IP packet(which is a 4 arbitrary bytes) without header addition by the Pipe
LOG_MSG_DEBUG(
"Sending packet into the USB pipe(%d bytes)\n", sizeof(pIpPacket));
int nBytesSent = m_UsbToIpaPipe.Send(pIpPacket, sizeof(pIpPacket));
if (sizeof(pIpPacket) != nBytesSent) {
return false;
}
//Receive the raw IP packet(which is a 4 arbitrary bytes) without header removal by the Pipe
LOG_MSG_DEBUG(
"Reading packet from the USB pipe(%d bytes should be there)\n", sizeof(pIpPacketReceive));
int nBytesReceived = m_IpaToUsbPipe.Receive(pIpPacketReceive,
sizeof(pIpPacketReceive));
if (sizeof(pIpPacketReceive) != nBytesReceived) {
return false;
}
for (int i = 0; i < nBytesReceived; i++) {
LOG_MSG_DEBUG("0x%02x\n", pIpPacketReceive[i]);
}
//Check that the sent IP packet is equal to the received IP packet.
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pIpPacket, pIpPacketReceive, sizeof(pIpPacket));
return bTestResult;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//This test will be using the Pipe Add-Header transfer ability(and not header insertion
class PipeTestAddHeader: public PipeTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
PipeTestAddHeader() {
m_name = "PipeTestAddHeader";
m_description = "Add header to USB pipe and receive it without removing the header";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run() {
Byte pIpPacketSend[4] = { 0x01, 0x02, 0x03, 0x04 };
int nReceivedPacketSize = sizeof(pIpPacketSend)
+ m_IpaToUsbPipe.GetHeaderLengthAdd();
Byte *pPacketReceive = new Byte[nReceivedPacketSize];
LOG_MSG_DEBUG("Sending packet into the USB pipe(%d bytes - no header size)\n", sizeof(pIpPacketSend));
int nRetValSend = m_UsbToIpaPipe.AddHeaderAndSend(pIpPacketSend,
sizeof(pIpPacketSend));
LOG_MSG_DEBUG("Result of AddHeaderAndSend = %d\n", nRetValSend);
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes - including header)\n", nReceivedPacketSize);
int nRetValReceive = m_IpaToUsbPipe.Receive(pPacketReceive,
nReceivedPacketSize);
LOG_MSG_DEBUG("Result of Receive = %d\n", nRetValReceive);
if (nReceivedPacketSize != nRetValReceive) {
delete[] pPacketReceive;
LOG_MSG_ERROR(
"Size of received packet is not as expected - %d\n", nRetValReceive);
return false;
}
bool bHeaderCmp = !memcmp(pPacketReceive, Pipe::m_pUsbHeader,
m_IpaToUsbPipe.GetHeaderLengthAdd());
LOG_MSG_DEBUG("bHeaderCmp - %s\n", bHeaderCmp ? "True" : "False");
bool bIpCmp = !memcmp(pPacketReceive + m_IpaToUsbPipe.GetHeaderLengthAdd(),
pIpPacketSend, sizeof(pIpPacketSend));
LOG_MSG_DEBUG("bIpCmp - %s\n", bIpCmp ? "True" : "False");
delete[] pPacketReceive;
return bHeaderCmp && bIpCmp;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//This test will be using the Pipe Remove-Header transfer ability(and header addition)
class PipeTestAddAndRemoveHeader: public PipeTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
PipeTestAddAndRemoveHeader() {
m_name = "PipeTestAddAndRemoveHeader";
m_description = "This test will be using the Pipe Remove-Header transfer ability(and header addition)";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run() {
Byte pIpPacketSend[4] = { 0x01, 0x02, 0x03, 0x04 };
int nToBeReceivedPacketSize = sizeof(pIpPacketSend)
+ m_IpaToUsbPipe.GetHeaderLengthAdd();
Byte *pPacketReceive = new Byte[nToBeReceivedPacketSize];
LOG_MSG_DEBUG("Sending packet into the USB pipe(%d bytes - no header size)\n", sizeof(pIpPacketSend));
int nBytesSent = m_UsbToIpaPipe.AddHeaderAndSend(pIpPacketSend,
sizeof(pIpPacketSend));
LOG_MSG_DEBUG("nBytesSent of AddHeaderAndSend = %d\n", nBytesSent);
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes - including header)\n", nToBeReceivedPacketSize);
int nBytesReceived = m_IpaToUsbPipe.Receive(pPacketReceive,
nToBeReceivedPacketSize);
LOG_MSG_DEBUG("nBytesReceived = %d\n", nBytesReceived);
if (nToBeReceivedPacketSize != nBytesReceived) {
delete[] pPacketReceive;
LOG_MSG_ERROR("Size of received packet is not as expected - %d\n", nBytesReceived);
return false;
}
bool bHeaderCmp = !memcmp(pPacketReceive, Pipe::m_pUsbHeader,
m_IpaToUsbPipe.GetHeaderLengthAdd());
LOG_MSG_DEBUG("bHeaderCmp - %s\n", bHeaderCmp ? "True" : "False");
bool bIpCmp = !memcmp(pPacketReceive + m_IpaToUsbPipe.GetHeaderLengthAdd(),
pIpPacketSend, sizeof(pIpPacketSend));
LOG_MSG_DEBUG("bIpCmp - %s\n", bIpCmp ? "True" : "False");
delete[] pPacketReceive;
return bHeaderCmp && bIpCmp;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//This test will try to send big chuck of data and check if the Data FIFO is working correct
class PipeTestDataFifoOverflow: public PipeTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
PipeTestDataFifoOverflow() {
m_name = "PipeTestDataFifoOverflow";
m_description = "Send many big packets over the IPA. there will be toggle of send/receive";
m_runInRegression = false; // Test is very long thus makes a problem in regression testing
}
/////////////////////////////////////////////////////////////////////////////////
bool Run() {
bool bTestResult = true;
int nPacketByteSize;
int nTotalDataSent = 0;
int nTestsMaxDataSend = 3 * 0x6400;
int nIterationNumber = 0;
Byte *pIpPacket;
Byte *pIpPacketReceive;
srand(123); //set some constant seed value in order to be able to reproduce problems.
//send and receive many packets(nIterations)
while (nTotalDataSent < nTestsMaxDataSend) {
//get random values for this packet.
nPacketByteSize = (rand() % 400) + 200;
pIpPacket = new Byte[nPacketByteSize];
for (int j = 0; j < nPacketByteSize; j++) {
pIpPacket[j] = rand() % 0x100;
}
//Send the raw IP packet(which is a 4 arbitrary bytes) without header addition by the Pipe
LOG_MSG_DEBUG(
"Iteration number %d(0x%08x/0x%08x data):\n", nIterationNumber++, nTotalDataSent, nTestsMaxDataSend);
LOG_MSG_DEBUG(
"Sending packet into the USB pipe(%d bytes)\n", nPacketByteSize);
int nBytesSent = m_UsbToIpaPipe.Send(pIpPacket, nPacketByteSize);
if (nPacketByteSize != nBytesSent) {
delete[] pIpPacket;
LOG_MSG_ERROR("Could not send the whole packet - nTotalDataSent = 0x%08x\n", nTotalDataSent);
return false;
}
//Receive the raw IP packet(which is a 4 arbitrary bytes) without header removal by the Pipe
pIpPacketReceive = new Byte[nPacketByteSize];
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be there)\n", nPacketByteSize);
int nBytesReceived = m_IpaToUsbPipe.Receive(pIpPacketReceive,
nPacketByteSize);
if (nPacketByteSize != nBytesReceived) {
delete[] pIpPacket;
delete[] pIpPacketReceive;
LOG_MSG_ERROR("Could not read the whole packet - nTotalDataSent = 0x%08x\n", nTotalDataSent);
return false;
}
for (int j = 0; j < nBytesReceived; j++) {
LOG_MSG_DEBUG("0x%02x\n", pIpPacketReceive[j]);
}
//Check that the sent IP packet is equal to the received IP packet.
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pIpPacket, pIpPacketReceive,
nPacketByteSize);
if (true != bTestResult) {
delete[] pIpPacketReceive;
delete[] pIpPacket;
LOG_MSG_ERROR("Send != Received - nTotalDataSent = 0x%08x\n", nTotalDataSent);
return false;
}
nTotalDataSent += nPacketByteSize;
delete[] pIpPacket;
delete[] pIpPacketReceive;
}
LOG_MSG_DEBUG("Great success - nTotalDataSent = 0x%08x\n", nTotalDataSent);
return true;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//This test will try to many little chuck of data and check if the Descriptor FIFO is working correct
class PipeTestDescriptorFifoOverflow: public PipeTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
PipeTestDescriptorFifoOverflow() {
m_name = "PipeTestDescriptorFifoOverflow";
m_description = "Send many small packets over the IPA. there will be toggle of send/receive";
m_runInRegression = false; // Test is very long thus makes a problem in regression testing
}
/////////////////////////////////////////////////////////////////////////////////
bool Run() {
bool bTestResult = true;
int nPacketByteSize;
int nTotalPacketSent = 0;
int nTestsMaxDescriptors = 3 * 0x1000;
int nIterationNumber = 0;
Byte *pIpPacket;
Byte *pIpPacketReceive;
srand(123); //set some constant seed value in order to be able to reproduce problems.
//send and receive many packets(nIterations)
while (nTotalPacketSent < nTestsMaxDescriptors) {
//get random values for this packet.
nPacketByteSize = (rand() % 10) + 1;
pIpPacket = new Byte[nPacketByteSize];
for (int j = 0; j < nPacketByteSize; j++) {
pIpPacket[j] = rand() % 0x100;
}
//Send the raw IP packet(which is a 4 arbitrary bytes) without header addition by the Pipe
LOG_MSG_DEBUG("Iteration number %d(0x%08x/0x%08x packets):\n", nIterationNumber++, nTotalPacketSent, nTestsMaxDescriptors);
LOG_MSG_DEBUG("Sending packet into the USB pipe(%d bytes)\n", nPacketByteSize);
int nBytesSent = m_UsbToIpaPipe.Send(pIpPacket, nPacketByteSize);
if (nPacketByteSize != nBytesSent) {
delete[] pIpPacket;
LOG_MSG_ERROR("Could not send the whole packet - nTotalPacketSent = 0x%08x\n", nTotalPacketSent);
return false;
}
//Receive the raw IP packet(which is a 4 arbitrary bytes) without header removal by the Pipe
pIpPacketReceive = new Byte[nPacketByteSize];
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be there)\n", nPacketByteSize);
int nBytesReceived = m_IpaToUsbPipe.Receive(pIpPacketReceive,
nPacketByteSize);
if (nPacketByteSize != nBytesReceived) {
delete[] pIpPacketReceive;
LOG_MSG_ERROR("Could not read the whole packet - nTotalPacketSent = 0x%08x\n", nTotalPacketSent);
return false;
}
for (int j = 0; j < nBytesReceived; j++) {
LOG_MSG_DEBUG("0x%02x\n", pIpPacketReceive[j]);
}
//Check that the sent IP packet is equal to the received IP packet.
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pIpPacket, pIpPacketReceive,
nPacketByteSize);
if (true != bTestResult) {
delete[] pIpPacketReceive;
delete[] pIpPacket;
LOG_MSG_ERROR("Send != Received - nTotalPacketSent = 0x%08x\n", nTotalPacketSent);
return false;
}
nTotalPacketSent++;
delete[] pIpPacket;
delete[] pIpPacketReceive;
}
LOG_MSG_DEBUG("Great success - nTotalPacketSent = 0x%08x\n", nTotalPacketSent);
return true;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
#define HOLB_TEST_PACKETS_MAX_NUM 50
class PipeTestHolb: public PipeTestFixture {
public:
PipeTestHolb() {
m_name = "PipeTestHolb";
m_description = "This test will check the HOLB function";
}
bool Run() {
int nPacketsToSend = HOLB_TEST_PACKETS_MAX_NUM;
int nBytesReceived;
int nBytesSentInLastPacket;
int i;
Byte pIpPacket[] = { 0x01, 0x02, 0x03, 0x04 }; //This packet will be sent(It can be replaced by a real IP packet).
Byte pIpPacketReceive[sizeof(pIpPacket) * HOLB_TEST_PACKETS_MAX_NUM] = { 0 }; //This buffer will be used in order to store the received packet.
m_IpaToUsbPipe.DisableHolb();
//Send the IP packets
LOG_MSG_DEBUG("Sending %d packets of %d bytes into the USB pipe\n",
nPacketsToSend, sizeof(pIpPacket));
for (i = 0; i < nPacketsToSend; i++) {
nBytesSentInLastPacket = m_UsbToIpaPipe.Send(pIpPacket, sizeof(pIpPacket));
if (sizeof(pIpPacket) != nBytesSentInLastPacket) {
LOG_MSG_ERROR("Failed sending the packet %d to m_UsbToIpaPipe", i);
return false;
}
}
//Receive all the raw IP packets (which are a 4 arbitrary bytes)
LOG_MSG_DEBUG(
"Reading packets from the USB pipe (%dx%d bytes should be there)\n",
sizeof(pIpPacket), nPacketsToSend);
for (i = 0; i < nPacketsToSend; i++) {
nBytesReceived = m_IpaToUsbPipe.Receive(pIpPacketReceive, sizeof(pIpPacketReceive));
if ((int)sizeof(pIpPacket) != nBytesReceived) {
LOG_MSG_ERROR("Failed with HOLB disabled! Packet #%d: Expected %d Bytes, got %d Bytes",
i, sizeof(pIpPacket), nBytesReceived);
return false;
}
}
// Enable HOLB
m_IpaToUsbPipe.EnableHolb(0);
//Send the IP packets
LOG_MSG_DEBUG("Sending %d packets of %d bytes into the USB pipe\n",
nPacketsToSend, sizeof(pIpPacket));
for (i = 0; i < nPacketsToSend; i++) {
nBytesSentInLastPacket = m_UsbToIpaPipe.Send(pIpPacket, sizeof(pIpPacket));
if (sizeof(pIpPacket) != nBytesSentInLastPacket) {
LOG_MSG_ERROR("Failed sending the packet %d to m_UsbToIpaPipe", i);
return false;
}
}
// Receive the raw IP packets (which are a 4 arbitrary bytes)
// that fit into the FIFO before the HOLB started dropping
// and fail to receive the rest
LOG_MSG_DEBUG(
"Reading packets from the USB pipe(%dx%d bytes should be there)\n",
sizeof(pIpPacket), nPacketsToSend);
for (i = 0; i < nPacketsToSend; i++) {
int nBytesReceived = m_IpaToUsbPipe.Receive(pIpPacketReceive,
sizeof(pIpPacketReceive));
if ((int)sizeof(pIpPacket) != nBytesReceived) {
if (i == 0) {
LOG_MSG_ERROR("First packet failed to receive ! Expected %d Bytes, got %d Bytes",
sizeof(pIpPacket), nBytesReceived);
return false;
} else
// Failed to receive a packet, but not the first one.
// This is the desired result.
return true;
}
}
LOG_MSG_ERROR("All packets were received successfully, which means the HOLB didn't work.");
return false;
}
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//Those tests should be run with configuration number 1 which has one input pipe and
//one output pipe.
//Please look at the Fixture for more configurations update.
static PipeTestRawTransfer pipeTestRawTransfer;
static PipeTestAddHeader pipeTestAddHeader;
static PipeTestAddAndRemoveHeader pipeTestAddAndRemoveHeader;
static PipeTestHolb pipeTestHolb;
//DO NOT UNCOMMENT THOSE LINES UNLESS YOU KNOW WHAT YOU ARE DOING!!!
//those test takes 4ever and should be use for specific usecase!
//static PipeTestDataFifoOverflow pipeTestDataFifoOverflow;
//static PipeTestDescriptorFifoOverflow pipeTestDescriptorFifoOverflow;
/////////////////////////////////////////////////////////////////////////////////
// EOF ////
/////////////////////////////////////////////////////////////////////////////////

11
kernel-tests/README.txt Normal file
View File

@@ -0,0 +1,11 @@
Subsystem: ipa-kernel-tests
Parameters:
-n: Nominal test case (tests all the different use cases for ip_accelerator)
-a: Adversarial test case (Currently holds no tests)
-r: Repeatability test case (Currently holds no tests)
-s: Stress test case (invokes many simultaneous threads that all try and access the device at once)
--help: Specifies the params for run.sh
Description:
This test module tests IPA driver, it holds a userspace module and a kernel space module.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
/*
* 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 <linux/if_ether.h>
#include "Constants.h"
#include "Logger.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "TestBase.h"
#include "Pipe.h"
#include "RoutingDriverWrapper.h"
#include "HeaderInsertion.h"
#include "Filtering.h"
#include "IPAFilteringTable.h"
#define MAX_PACKET_SIZE 1024
/*This class will be the base class of RNDIS Aggregation tests.
*Any method other than the test case itself can be
*declared in this Fixture thus allowing the derived classes to
*implement only the test case.
*All the test of the Aggregation uses one input and one output in DMA mode.
*/
class RNDISAggregationTestFixture:public TestBase
{
public:
/*This Constructor will register each instance that it creates.*/
RNDISAggregationTestFixture();
/*This method will create and initialize two Pipe object for the USB
*(Ethernet) Pipes, one as input and the other as output.
*/
virtual bool Setup();
/*This method will destroy the pipes.*/
virtual bool Teardown();
virtual bool Run();
virtual bool AddRules() = 0;
virtual bool TestLogic() = 0;
bool AddRulesNoAgg();
bool AddRulesDeAggEther();
bool AddRulesAggTimeLimit();
bool AddRulesAggByteLimit();
bool AddRulesAggByteLimit(bool bAggForceClose);
bool AddRulesAggPacketLimit();
bool AddRulesAggDualFC();
bool AddRulesAggDualFcRoutingBased();
/*The client type are set from the peripheral perspective*/
static Pipe m_IpaToUsbPipeAgg;
/*IPA_CLIENT_TEST2_CONS (pipe_num = 7)*/
static Pipe m_UsbToIpaPipe;
/* IPA_CLIENT_TEST_PROD (pipe_num = 11)*/
static Pipe m_IpaToUsbPipe;
/* IPA_CLIENT_TEST3_CONS (pipe_num = 9)*/
static Pipe m_UsbToIpaPipeDeagg;
/* IPA_CLIENT_TEST2_PROD (pipe_num = 6)*/
static Pipe m_IpaToUsbPipeAggTime;
/* IPA_CLIENT_TEST_CONS (pipe_num = 10)*/
static Pipe m_IpaToUsbPipeAggPktLimit;
/* IPA_CLIENT_TEST4_CONS (pipe_num = 4)*/
static Pipe m_HsicToIpaPipe;
/* IPA_CLIENT_TEST3_PROD (pipe_num = 13)*/
static RoutingDriverWrapper m_Routing;
static Filtering m_Filtering;
static HeaderInsertion m_HeaderInsertion;
protected:
enum ipa_ip_type m_eIP;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,183 @@
/*
* 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 <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include "RoutingDriverWrapper.h"
#include "TestsUtils.h"
const char* RoutingDriverWrapper::DEVICE_NAME = "/dev/ipa";
RoutingDriverWrapper::RoutingDriverWrapper()
{
m_fd = open(DEVICE_NAME, O_RDWR);
if (0 == m_fd) {
printf("Failed opening %s.\n", DEVICE_NAME);
}
}
RoutingDriverWrapper::~RoutingDriverWrapper()
{
close(m_fd);
}
bool RoutingDriverWrapper::DeviceNodeIsOpened()
{
int res = fcntl(m_fd, F_GETFL);
if (m_fd > 0 && res >=0)
return true;
else
return false;
}
bool RoutingDriverWrapper::AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_ADD_RT_RULE, ruleTable);
if (retval) {
printf("%s(), failed adding routing rule table %p\n", __FUNCTION__, ruleTable);
return false;
}
printf("%s(), Added routing rule table %p\n", __FUNCTION__, ruleTable);
return true;
}
bool RoutingDriverWrapper::AddRoutingRule(struct ipa_ioc_add_rt_rule_v2 *ruleTable_v2)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_ADD_RT_RULE_V2, ruleTable_v2);
if (retval) {
printf("%s(), failed adding routing rule table %p\n", __FUNCTION__, ruleTable_v2);
return false;
}
printf("%s(), Added routing rule table %p\n", __FUNCTION__, ruleTable_v2);
return true;
}
bool RoutingDriverWrapper::DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_DEL_RT_RULE, ruleTable);
if (retval) {
printf("%s(), failed deleting routing rule table %p\n", __FUNCTION__, ruleTable);
return false;
}
printf("%s(), Deleted routing rule table %p\n", __FUNCTION__, ruleTable);
return true;
}
bool RoutingDriverWrapper::Commit(enum ipa_ip_type ip)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_COMMIT_RT, ip);
if (retval) {
printf("%s(), failed commiting routing rules.\n", __FUNCTION__);
return false;
}
printf("%s(), Commited routing rules to IPA HW.\n", __FUNCTION__);
return true;
}
bool RoutingDriverWrapper::Reset(enum ipa_ip_type ip)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_RESET_RT, ip);
retval |= ioctl(m_fd, IPA_IOC_COMMIT_RT, ip);
if (retval) {
printf("%s(), failed reseting routing block.\n", __FUNCTION__);
return false;
}
printf("%s(), Reset command issued to IPA routing block.\n", __FUNCTION__);
return true;
}
bool RoutingDriverWrapper::GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_GET_RT_TBL, routingTable);
if (retval) {
printf("%s(), IPA_IOCTL_GET_RT_TBL ioctl failed, routingTable =0x%p, retval=0x%x.\n", __FUNCTION__, routingTable, retval);
return false;
}
printf("%s(), IPA_IOCTL_GET_RT_TBL ioctl issued to IPA routing block.\n", __FUNCTION__);
return true;
}
bool RoutingDriverWrapper::PutRoutingTable(uint32_t routingTableHandle)
{
int retval = 0;
if (!DeviceNodeIsOpened())
return false;
retval = ioctl(m_fd, IPA_IOC_PUT_RT_TBL, routingTableHandle);
if (retval) {
printf("%s(), IPA_IOCTL_PUT_RT_TBL ioctl failed.\n", __FUNCTION__);
return false;
}
printf("%s(), IPA_IOCTL_PUT_RT_TBL ioctl issued to IPA routing block.\n", __FUNCTION__);
return true;
}

View File

@@ -0,0 +1,63 @@
/*
* 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.
*/
#ifndef ROUTING_H_
#define ROUTING_H_
#include <stdint.h>
#include "linux/msm_ipa.h"
using namespace std;
class RoutingDriverWrapper
{
public:
RoutingDriverWrapper();
~RoutingDriverWrapper();
bool AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable);
bool AddRoutingRule(ipa_ioc_add_rt_rule_v2 *ruleTable_v2);
bool DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable);
bool Commit(enum ipa_ip_type ip);
bool Reset(enum ipa_ip_type ip);
bool GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable);
bool PutRoutingTable(uint32_t routingTableHandle);
bool DeviceNodeIsOpened();
private:
static const char *DEVICE_NAME;
/* File descriptor of the IPA device node /dev/ipa*/
int m_fd;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2017 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 "TLPAggregationTestFixture.h"
/////////////////////////////////////////////////////////////////////////////////
//define the static Pipes which will be used by all derived tests.
Pipe TLPAggregationTestFixture::m_IpaToUsbPipeNoAgg(IPA_CLIENT_TEST3_CONS,
IPA_TEST_CONFIGURATION_8);
Pipe TLPAggregationTestFixture::m_IpaToUsbPipeAggr(IPA_CLIENT_TEST_CONS,
IPA_TEST_CONFIGURATION_8);
Pipe TLPAggregationTestFixture::m_UsbNoAggToIpaPipeAgg(IPA_CLIENT_TEST3_PROD,
IPA_TEST_CONFIGURATION_8);
Pipe TLPAggregationTestFixture::m_UsbDeaggToIpaPipeNoAgg(IPA_CLIENT_TEST_PROD,
IPA_TEST_CONFIGURATION_8);
Pipe TLPAggregationTestFixture::m_UsbDeaggToIpaPipeAgg(IPA_CLIENT_TEST2_PROD,
IPA_TEST_CONFIGURATION_8);
Pipe TLPAggregationTestFixture::m_IpaToUsbPipeAggTime(IPA_CLIENT_TEST2_CONS,
IPA_TEST_CONFIGURATION_8);
Pipe TLPAggregationTestFixture::m_UsbNoAggToIpaPipeAggTime(IPA_CLIENT_TEST4_PROD,
IPA_TEST_CONFIGURATION_8);
/////////////////////////////////////////////////////////////////////////////////
TLPAggregationTestFixture::TLPAggregationTestFixture()
{
m_testSuiteName.push_back("TLPAgg");
m_maxIPAHwType = IPA_HW_v2_6L;
Register(*this);
}
/////////////////////////////////////////////////////////////////////////////////
bool TLPAggregationTestFixture::Setup()
{
bool bRetVal = true;
//Set the configuration to support USB->IPA and IPA->USB pipes.
ConfigureScenario(8);
//Initialize the pipe for all the tests - this will open the inode which represents the pipe.
bRetVal &= m_IpaToUsbPipeNoAgg.Init();
bRetVal &= m_IpaToUsbPipeAggr.Init();
bRetVal &= m_UsbNoAggToIpaPipeAgg.Init();
bRetVal &= m_UsbDeaggToIpaPipeNoAgg.Init();
bRetVal &= m_UsbDeaggToIpaPipeAgg.Init();
bRetVal &= m_IpaToUsbPipeAggTime.Init();
bRetVal &= m_UsbNoAggToIpaPipeAggTime.Init();
return bRetVal;
}
/////////////////////////////////////////////////////////////////////////////////
bool TLPAggregationTestFixture::Teardown()
{
//The Destroy method will close the inode.
m_IpaToUsbPipeNoAgg.Destroy();
m_IpaToUsbPipeAggr.Destroy();
m_UsbNoAggToIpaPipeAgg.Destroy();
m_UsbDeaggToIpaPipeNoAgg.Destroy();
m_UsbDeaggToIpaPipeAgg.Destroy();
m_IpaToUsbPipeAggTime.Destroy();
m_UsbNoAggToIpaPipeAggTime.Destroy();
return true;
}
/////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2017 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 "Constants.h"
#include "Logger.h"
#include "linux/msm_ipa.h"
#include "TestsUtils.h"
#include "TestBase.h"
#include "Pipe.h"
/*This class will be the base class of all TLP Aggregation tests.
*Any method other than the test case itself can be declared in
*this Fixture thus allowing the derived classes to
*implement only the test case.
*All the test of the Aggregation uses one
*input and one output in DMA mode.
*/
class TLPAggregationTestFixture:public TestBase
{
public:
/*This Constructor will register each instance that it creates.*/
TLPAggregationTestFixture();
/*This method will create and initialize two Pipe object for the
*USB (Ethernet) Pipes, one as input and the other as output.
*/
virtual bool Setup();
/*This method will destroy the pipes.*/
virtual bool Teardown();
/*The client type are set from the peripheral perspective*/
static Pipe m_IpaToUsbPipeNoAgg;
static Pipe m_IpaToUsbPipeAggr;
static Pipe m_UsbNoAggToIpaPipeAgg;
static Pipe m_UsbDeaggToIpaPipeNoAgg;
static Pipe m_UsbDeaggToIpaPipeAgg;
static Pipe m_IpaToUsbPipeAggTime;
static Pipe m_UsbNoAggToIpaPipeAggTime;
};

View File

@@ -0,0 +1,946 @@
/*
* Copyright (c) 2017 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 "TLPAggregationTestFixture.h"
#include "Constants.h"
#include "TestsUtils.h"
#include "linux/msm_ipa.h"
#define NUM_PACKETS 5
#define TIME_LIMIT_NUM_PACKETS 1
#define MAX_PACKET_SIZE 1024
#define AGGREGATION_LOOP 4
int test_num = 0;
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPAggregationTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPAggregationTest()
{
m_name = "TLPAggregationTest";
m_description = "TLP Aggregation test - sends 5 packets and receives 1 "
"aggregated packet";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
bool bTestResult = true;
//The packets that will be sent
Byte pPackets[NUM_PACKETS][MAX_PACKET_SIZE];
//The real sizes of the packets that will be sent
int pPacketsSizes[NUM_PACKETS];
//Buffer for the packet that will be received
Byte pReceivedPacket[MAX_PACKET_SIZE];
//Total size of all sent packets (this is the max size of the aggregated packet
//minus 2 bytes for each packet in the aggregated packet)
int nTotalPacketsSize = MAX_PACKET_SIZE - (2 * NUM_PACKETS);
//The expected aggregated packet
Byte pExpectedAggregatedPacket[MAX_PACKET_SIZE] = {0};
//initialize the packets
//example: for NUM_PACKETS = 5 and MAX_PACKET_SIZE = 1024:
//nTotalPacketsSize will be 1024 - 5*2 = 1014
//packets[0] size will be 1014/5 = 202 bytes of 0
//packets[1] size will be (1014 - 202) / 5 = 162 bytes of 1
//packets[2] size will be (1014 - 201 - 162) / 5 = 130 bytes of 2
//packets[3] size will be (1014 - 201 - 162 - 130) / 5 = 104 bytes of 3
//packets[4] size will be 1014 - 201 - 162 - 130 - 104 = 416 bytes of 4
for (int i = 0; i < NUM_PACKETS; i++)
{
if (NUM_PACKETS - 1 == i)
pPacketsSizes[i] = nTotalPacketsSize;
else
pPacketsSizes[i] = nTotalPacketsSize / NUM_PACKETS;
nTotalPacketsSize -= pPacketsSizes[i];
for (int j = 0; j < pPacketsSizes[i]; j++)
pPackets[i][j] = i + 16*test_num;
}
test_num++;
//send the packets
for (int i = 0; i < NUM_PACKETS; i++)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes)\n", i,
pPacketsSizes[i]);
int nBytesSent = m_UsbNoAggToIpaPipeAgg.Send(pPackets[i],
pPacketsSizes[i]);
if (pPacketsSizes[i] != nBytesSent)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes) "
"failed!\n", i, pPacketsSizes[i]);
return false;
}
}
//receive the aggregated packet
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be "
"there)\n", MAX_PACKET_SIZE);
int nBytesReceived = m_IpaToUsbPipeAggr.Receive(pReceivedPacket,
MAX_PACKET_SIZE);
if (MAX_PACKET_SIZE != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving aggregated packet from the USB pipe(%d "
"bytes) failed!\n", MAX_PACKET_SIZE);
print_buff(pReceivedPacket, nBytesReceived);
return false;
}
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < NUM_PACKETS; i++)
{
//the first 2 bytes are the packet length in little endian
pExpectedAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pExpectedAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pExpectedAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pExpectedAggregatedPacket, pReceivedPacket,
sizeof(pReceivedPacket));
return bTestResult;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPDeaggregationTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPDeaggregationTest()
{
m_name = "TLPDeaggregationTest";
m_description = "TLP Deaggregation test - sends an aggregated packet made from"
"5 packets and receives 5 packets";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
bool bTestResult = true;
//The packets that the aggregated packet will be made of
Byte pExpectedPackets[NUM_PACKETS][MAX_PACKET_SIZE];
//The real sizes of the packets that the aggregated packet will be made of
int pPacketsSizes[NUM_PACKETS];
//Buffers for the packets that will be received
Byte pReceivedPackets[NUM_PACKETS][MAX_PACKET_SIZE];
//Total size of all the packets that the aggregated packet will be made of
//(this is the max size of the aggregated packet
//minus 2 bytes for each packet in the aggregated packet)
int nTotalPacketsSize = MAX_PACKET_SIZE - (2 * NUM_PACKETS);
//The aggregated packet that will be sent
Byte pAggregatedPacket[MAX_PACKET_SIZE] = {0};
//initialize the packets
//example: for NUM_PACKETS = 5 and MAX_PACKET_SIZE = 1024:
//nTotalPacketsSize will be 1024 - 5*2 = 1014
//packets[0] size will be 1014/5 = 202 bytes of 0
//packets[1] size will be (1014 - 202) / 5 = 162 bytes of 1
//packets[2] size will be (1014 - 201 - 162) / 5 = 130 bytes of 2
//packets[3] size will be (1014 - 201 - 162 - 130) / 5 = 104 bytes of 3
//packets[4] size will be 1014 - 201 - 162 - 130 - 104 = 416 bytes of 4
for (int i = 0; i < NUM_PACKETS; i++)
{
if (NUM_PACKETS - 1 == i)
pPacketsSizes[i] = nTotalPacketsSize;
else
pPacketsSizes[i] = nTotalPacketsSize / NUM_PACKETS;
nTotalPacketsSize -= pPacketsSizes[i];
for (int j = 0; j < pPacketsSizes[i]; j++)
pExpectedPackets[i][j] = i+ 16*test_num;
}
test_num++;
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < NUM_PACKETS; i++)
{
//the first 2 bytes are the packet length in little endian
pAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pAggregatedPacket[k] = pExpectedPackets[i][j];
k++;
}
}
//send the aggregated packet
LOG_MSG_DEBUG("Sending aggregated packet into the USB pipe(%d bytes)\n",
sizeof(pAggregatedPacket));
int nBytesSent = m_UsbDeaggToIpaPipeNoAgg.Send(pAggregatedPacket,
sizeof(pAggregatedPacket));
if (sizeof(pAggregatedPacket) != nBytesSent)
{
LOG_MSG_DEBUG("Sending aggregated packet into the USB pipe(%d bytes) "
"failed!\n", sizeof(pAggregatedPacket));
return false;
}
//receive the packets
for (int i = 0; i < NUM_PACKETS; i++)
{
LOG_MSG_DEBUG("Reading packet %d from the USB pipe(%d bytes should be "
"there)\n", i, pPacketsSizes[i]);
int nBytesReceived = m_IpaToUsbPipeNoAgg.Receive(pReceivedPackets[i],
pPacketsSizes[i]);
if (pPacketsSizes[i] != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving packet %d from the USB pipe(%d bytes) "
"failed!\n", i, pPacketsSizes[i]);
print_buff(pReceivedPackets[i], nBytesReceived);
return false;
}
}
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
for (int i = 0; i < NUM_PACKETS; i++)
bTestResult &= !memcmp(pExpectedPackets[i], pReceivedPackets[i], pPacketsSizes[i]);
return bTestResult;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPDeaggregationAndAggregationTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPDeaggregationAndAggregationTest()
{
m_name = "TLPDeaggregationAndAggregationTest";
m_description = "TLP Deaggregation and Aggregation test - sends an aggregated "
"packet made from 5 packets and receives the same aggregated packet";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
bool bTestResult = true;
//The packets that the aggregated packet will be made of
Byte pPackets[NUM_PACKETS][MAX_PACKET_SIZE];
//The real sizes of the packets that the aggregated packet will be made of
int pPacketsSizes[NUM_PACKETS];
//Buffers for the packets that will be received
Byte pReceivedPacket[MAX_PACKET_SIZE];
//Total size of all the packets that the aggregated packet will be made of
//(this is the max size of the aggregated packet
//minus 2 bytes for each packet in the aggregated packet)
int nTotalPacketsSize = MAX_PACKET_SIZE - (2 * NUM_PACKETS);
//The aggregated packet that will be sent
Byte pAggregatedPacket[MAX_PACKET_SIZE] = {0};
//initialize the packets
//example: for NUM_PACKETS = 5 and MAX_PACKET_SIZE = 1024:
//nTotalPacketsSize will be 1024 - 5*2 = 1014
//packets[0] size will be 1014/5 = 202 bytes of 0
//packets[1] size will be (1014 - 202) / 5 = 162 bytes of 1
//packets[2] size will be (1014 - 201 - 162) / 5 = 130 bytes of 2
//packets[3] size will be (1014 - 201 - 162 - 130) / 5 = 104 bytes of 3
//packets[4] size will be 1014 - 201 - 162 - 130 - 104 = 416 bytes of 4
for (int i = 0; i < NUM_PACKETS; i++)
{
if (NUM_PACKETS - 1 == i)
pPacketsSizes[i] = nTotalPacketsSize;
else
pPacketsSizes[i] = nTotalPacketsSize / NUM_PACKETS;
nTotalPacketsSize -= pPacketsSizes[i];
for (int j = 0; j < pPacketsSizes[i]; j++)
pPackets[i][j] = i+ 16*test_num;
}
test_num++;
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < NUM_PACKETS; i++)
{
//the first 2 bytes are the packet length in little endian
pAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
//send the aggregated packet
LOG_MSG_DEBUG("Sending aggregated packet into the USB pipe(%d bytes)\n",
sizeof(pAggregatedPacket));
int nBytesSent = m_UsbDeaggToIpaPipeAgg.Send(pAggregatedPacket,
sizeof(pAggregatedPacket));
if (sizeof(pAggregatedPacket) != nBytesSent)
{
LOG_MSG_DEBUG("Sending aggregated packet into the USB pipe(%d bytes)"
" failed!\n", sizeof(pAggregatedPacket));
return false;
}
//receive the aggregated packet
LOG_MSG_DEBUG("Reading aggregated packet from the USB pipe(%d bytes "
"should be there)\n", sizeof(pAggregatedPacket));
int nBytesReceived = m_IpaToUsbPipeAggr.Receive(pReceivedPacket,
sizeof(pAggregatedPacket));
if (sizeof(pAggregatedPacket) != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving aggregated packet from the USB pipe(%d "
"bytes) failed!\n", sizeof(pAggregatedPacket));
LOG_MSG_DEBUG("Received %d bytes\n", nBytesReceived);
print_buff(pReceivedPacket, nBytesReceived);
return false;
}
print_buff(pReceivedPacket, nBytesReceived);
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pAggregatedPacket, pReceivedPacket,
sizeof(pReceivedPacket));
return bTestResult;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPAggregationLoopTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPAggregationLoopTest()
{
m_name = "TLPAggregationLoopTest";
m_description = "TLP Aggregation Loop test - sends 5 packets and expects to"
"receives 1 aggregated packet a few times";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
//The packets that will be sent
Byte pPackets[NUM_PACKETS][MAX_PACKET_SIZE];
//The real sizes of the packets that will be sent
int pPacketsSizes[NUM_PACKETS];
//Buffer for the packet that will be received
Byte pReceivedPacket[MAX_PACKET_SIZE];
//Total size of all sent packets (this is the max size of the aggregated packet
//minus 2 bytes for each packet in the aggregated packet)
int nTotalPacketsSize = MAX_PACKET_SIZE - (2 * NUM_PACKETS);
//The expected aggregated packet
Byte pExpectedAggregatedPacket[MAX_PACKET_SIZE] = {0};
//initialize the packets
//example: for NUM_PACKETS = 5 and MAX_PACKET_SIZE = 1024:
//nTotalPacketsSize will be 1024 - 5*2 = 1014
//packets[0] size will be 1014/5 = 202 bytes of 0
//packets[1] size will be (1014 - 202) / 5 = 162 bytes of 1
//packets[2] size will be (1014 - 201 - 162) / 5 = 130 bytes of 2
//packets[3] size will be (1014 - 201 - 162 - 130) / 5 = 104 bytes of 3
//packets[4] size will be 1014 - 201 - 162 - 130 - 104 = 416 bytes of 4
for (int i = 0; i < NUM_PACKETS; i++)
{
if (NUM_PACKETS - 1 == i)
pPacketsSizes[i] = nTotalPacketsSize;
else
pPacketsSizes[i] = nTotalPacketsSize / NUM_PACKETS;
nTotalPacketsSize -= pPacketsSizes[i];
for (int j = 0; j < pPacketsSizes[i]; j++)
pPackets[i][j] = i+ 16*test_num;
}
test_num++;
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < NUM_PACKETS; i++)
{
//the first 2 bytes are the packet length in little endian
pExpectedAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pExpectedAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pExpectedAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
for (int j = 0; j < AGGREGATION_LOOP; j++)
{
//send the packets
for (int i = 0; i < NUM_PACKETS; i++)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes)\n",
i, pPacketsSizes[i]);
int nBytesSent = m_UsbNoAggToIpaPipeAgg.Send(pPackets[i],
pPacketsSizes[i]);
if (pPacketsSizes[i] != nBytesSent)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes) "
"failed!\n", i, pPacketsSizes[i]);
return false;
}
}
memset(pReceivedPacket, 0, sizeof(pReceivedPacket));
//receive the aggregated packet
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be "
"there)\n", MAX_PACKET_SIZE);
int nBytesReceived = m_IpaToUsbPipeAggr.Receive(pReceivedPacket,
MAX_PACKET_SIZE);
if (MAX_PACKET_SIZE != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving aggregated packet from the USB pipe(%d "
"bytes) failed!\n", MAX_PACKET_SIZE);
return false;
}
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
if (0 != memcmp(pExpectedAggregatedPacket, pReceivedPacket,
sizeof(pReceivedPacket)))
{
LOG_MSG_DEBUG("Comparison of packet %d failed!\n", j);
return false;
}
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPAggregationTimeLimitTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPAggregationTimeLimitTest()
{
m_name = "TLPAggregationTimeLimitTest";
m_description = "TLP Aggregation time limit test - sends 1 packet "
"smaller than the byte limit and receives 1 aggregated packet";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
bool bTestResult = true;
//The packets that will be sent
Byte pPackets[TIME_LIMIT_NUM_PACKETS][MAX_PACKET_SIZE];
//The real sizes of the packets that will be sent
int pPacketsSizes[TIME_LIMIT_NUM_PACKETS];
//Buffer for the packet that will be received
Byte pReceivedPacket[MAX_PACKET_SIZE] = {0};
//The expected aggregated packet
Byte pExpectedAggregatedPacket[MAX_PACKET_SIZE] = {0};
//Size of aggregated packet
int nTotalPacketsSize = 0;
//initialize the packets
for (int i = 0; i < TIME_LIMIT_NUM_PACKETS; i++)
{
pPacketsSizes[i] = i + 1;
nTotalPacketsSize += pPacketsSizes[i] + 2; //size of the packet + 2 bytes for length
for (int j = 0; j < pPacketsSizes[i]; j++)
pPackets[i][j] = i+ 16*test_num;
}
test_num++;
//send the packets
for (int i = 0; i < TIME_LIMIT_NUM_PACKETS; i++)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes)\n", i,
pPacketsSizes[i]);
int nBytesSent = m_UsbNoAggToIpaPipeAggTime.Send(pPackets[i],
pPacketsSizes[i]);
if (pPacketsSizes[i] != nBytesSent)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes) "
"failed!\n", i, pPacketsSizes[i]);
return false;
}
}
//receive the aggregated packet
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be "
"there)\n", nTotalPacketsSize);
int nBytesReceived = m_IpaToUsbPipeAggTime.Receive(pReceivedPacket,
nTotalPacketsSize);
if (nTotalPacketsSize != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving aggregated packet from the USB pipe(%d "
"bytes) failed!\n", nTotalPacketsSize);
print_buff(pReceivedPacket, nBytesReceived);
return false;
}
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < TIME_LIMIT_NUM_PACKETS; i++)
{
//the first 2 bytes are the packet length in little endian
pExpectedAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pExpectedAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pExpectedAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pExpectedAggregatedPacket, pReceivedPacket,
sizeof(pReceivedPacket));
return bTestResult;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPAggregationByteLimitTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPAggregationByteLimitTest()
{
m_name = "TLPAggregationByteLimitTest";
m_description = "TLP Aggregation byte limit test - sends 2 packets that together "
"are larger than the byte limit ";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
bool bTestResult = true;
//The packets that will be sent
Byte pPackets[2][MAX_PACKET_SIZE];
//The real sizes of the packets that will be sent
int pPacketsSizes[2];
//Buffer for the packet that will be received
Byte pReceivedPacket[2*MAX_PACKET_SIZE] = {0};
//The expected aggregated packet
Byte pExpectedAggregatedPacket[2*MAX_PACKET_SIZE] = {0};
//Size of aggregated packet
int nTotalPacketsSize = 0;
//initialize the packets
for (int i = 0; i < 2; i++)
{
pPacketsSizes[i] = (MAX_PACKET_SIZE / 2) + 10;
nTotalPacketsSize += pPacketsSizes[i] + 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
pPackets[i][j] = i+ 16*test_num;
}
test_num++;
//send the packets
for (int i = 0; i < 2; i++)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes)\n", i,
pPacketsSizes[i]);
int nBytesSent = m_UsbNoAggToIpaPipeAgg.Send(pPackets[i],
pPacketsSizes[i]);
if (pPacketsSizes[i] != nBytesSent)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes) "
"failed!\n", i, pPacketsSizes[i]);
return false;
}
}
//receive the aggregated packet
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be "
"there)\n", nTotalPacketsSize);
int nBytesReceived = m_IpaToUsbPipeAggr.Receive(pReceivedPacket,
nTotalPacketsSize);
if (nTotalPacketsSize != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving aggregated packet from the USB pipe(%d"
" bytes) failed!\n", nTotalPacketsSize);
print_buff(pReceivedPacket, nBytesReceived);
return false;
}
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < 2; i++)
{
//the first 2 bytes are the packet length in little endian
pExpectedAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pExpectedAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pExpectedAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pExpectedAggregatedPacket, pReceivedPacket,
sizeof(pReceivedPacket));
return bTestResult;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPAggregation2PipesTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPAggregation2PipesTest()
{
m_name = "TLPAggregation2PipesTest";
m_description = "TLP Aggregation 2 pipes test - sends 3 packets from one pipe"
"and an aggregated packet made of 2 packets from another pipe and "
"receives 1 aggregated packet made of all 5 packets";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
bool bTestResult = true;
//The packets that will be sent
Byte pPackets[NUM_PACKETS][MAX_PACKET_SIZE];
//The real sizes of the packets that will be sent
int pPacketsSizes[NUM_PACKETS];
//Buffer for the packet that will be received
Byte pReceivedPacket[MAX_PACKET_SIZE];
//Total size of all sent packets (this is the max size of the aggregated packet
//minus 2 bytes for each packet in the aggregated packet)
int nTotalPacketsSize = MAX_PACKET_SIZE - (2 * NUM_PACKETS);
//The expected aggregated packet
Byte pExpectedAggregatedPacket[MAX_PACKET_SIZE] = {0};
//The aggregated packet that will be sent
Byte pAggregatedPacket[MAX_PACKET_SIZE] = {0};
//The size of the sent aggregated packet
int nAggregatedPacketSize = 0;
//initialize the packets
//example: for NUM_PACKETS = 5 and MAX_PACKET_SIZE = 1024:
//nTotalPacketsSize will be 1024 - 5*2 = 1014
//packets[0] size will be 1014/5 = 202 bytes of 0
//packets[1] size will be (1014 - 202) / 5 = 162 bytes of 1
//packets[2] size will be (1014 - 201 - 162) / 5 = 130 bytes of 2
//packets[3] size will be (1014 - 201 - 162 - 130) / 5 = 104 bytes of 3
//packets[4] size will be 1014 - 201 - 162 - 130 - 104 = 416 bytes of 4
for (int i = 0; i < NUM_PACKETS; i++)
{
if (NUM_PACKETS - 1 == i)
pPacketsSizes[i] = nTotalPacketsSize;
else
pPacketsSizes[i] = nTotalPacketsSize / NUM_PACKETS;
nTotalPacketsSize -= pPacketsSizes[i];
for (int j = 0; j < pPacketsSizes[i]; j++)
pPackets[i][j] = i+ 16*test_num;
}
test_num++;
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < 2; i++)
{
nAggregatedPacketSize += pPacketsSizes[i] + 2;
//the first 2 bytes are the packet length in little endian
pAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
//send the aggregated packet
LOG_MSG_DEBUG("Sending aggregated packet into the USB pipe(%d "
"bytes)\n", nAggregatedPacketSize);
int nBytesSent = m_UsbDeaggToIpaPipeAgg.Send(pAggregatedPacket,
nAggregatedPacketSize);
if (nAggregatedPacketSize != nBytesSent)
{
LOG_MSG_DEBUG("Sending aggregated packet into the USB pipe(%d "
"bytes) failed!\n", nAggregatedPacketSize);
return false;
}
//send the packets
for (int i = 2; i < NUM_PACKETS; i++)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes)\n", i,
pPacketsSizes[i]);
int nBytesSent = m_UsbNoAggToIpaPipeAgg.Send(pPackets[i],
pPacketsSizes[i]);
if (pPacketsSizes[i] != nBytesSent)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes) "
"failed!\n", i, pPacketsSizes[i]);
return false;
}
}
//receive the aggregated packet
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be "
"there)\n", MAX_PACKET_SIZE);
int nBytesReceived = m_IpaToUsbPipeAggr.Receive(pReceivedPacket,
MAX_PACKET_SIZE);
if (MAX_PACKET_SIZE != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving aggregated packet from the USB pipe(%d "
"bytes) failed!\n", MAX_PACKET_SIZE);
print_buff(pReceivedPacket, nBytesReceived);
return false;
}
//initializing the aggregated packet
k = 0;
for (int i = 0; i < NUM_PACKETS; i++)
{
//the first 2 bytes are the packet length in little endian
pExpectedAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pExpectedAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pExpectedAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
bTestResult &= !memcmp(pExpectedAggregatedPacket, pReceivedPacket,
sizeof(pReceivedPacket));
return bTestResult;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class TLPAggregationTimeLimitLoopTest: public TLPAggregationTestFixture {
public:
/////////////////////////////////////////////////////////////////////////////////
TLPAggregationTimeLimitLoopTest()
{
m_name = "TLPAggregationTimeLimitLoopTest";
m_description = "TLP Aggregation time limit loop test - sends 1 packet "
"smaller than the byte limit and receives 1 aggregated packets";
}
/////////////////////////////////////////////////////////////////////////////////
bool Run()
{
//The packets that will be sent
Byte pPackets[TIME_LIMIT_NUM_PACKETS][MAX_PACKET_SIZE];
//The real sizes of the packets that will be sent
int pPacketsSizes[TIME_LIMIT_NUM_PACKETS];
//Buffer for the packet that will be received
Byte pReceivedPacket[MAX_PACKET_SIZE] = {0};
//The expected aggregated packet
Byte pExpectedAggregatedPacket[MAX_PACKET_SIZE] = {0};
//Size of aggregated packet
int nTotalPacketsSize = 0;
//initialize the packets
for (int i = 0; i < TIME_LIMIT_NUM_PACKETS; i++)
{
pPacketsSizes[i] = i + 1;
nTotalPacketsSize += pPacketsSizes[i] + 2; //size of the packet + 2 bytes for length
for (int j = 0; j < pPacketsSizes[i]; j++)
pPackets[i][j] = i+ 16*test_num;
}
test_num++;
for (int n = 0; n < NUM_PACKETS; n++)
{
//send the packets
for (int i = 0; i < TIME_LIMIT_NUM_PACKETS; i++)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d bytes)\n",
i, pPacketsSizes[i]);
int nBytesSent = m_UsbNoAggToIpaPipeAggTime.Send(pPackets[i],
pPacketsSizes[i]);
if (pPacketsSizes[i] != nBytesSent)
{
LOG_MSG_DEBUG("Sending packet %d into the USB pipe(%d "
"bytes) failed!\n", i, pPacketsSizes[i]);
return false;
}
}
//receive the aggregated packet
LOG_MSG_DEBUG("Reading packet from the USB pipe(%d bytes should be "
"there)\n", nTotalPacketsSize);
int nBytesReceived = m_IpaToUsbPipeAggTime.Receive(pReceivedPacket,
nTotalPacketsSize);
if (nTotalPacketsSize != nBytesReceived)
{
LOG_MSG_DEBUG("Receiving aggregated packet from the USB pipe(%d "
"bytes) failed!\n", nTotalPacketsSize);
print_buff(pReceivedPacket, nBytesReceived);
return false;
}
//initializing the aggregated packet
int k = 0;
for (int i = 0; i < TIME_LIMIT_NUM_PACKETS; i++)
{
//the first 2 bytes are the packet length in little endian
pExpectedAggregatedPacket[k] = pPacketsSizes[i] & 0x00FF;
pExpectedAggregatedPacket[k+1] = pPacketsSizes[i] >> 8;
k += 2;
for (int j = 0; j < pPacketsSizes[i]; j++)
{
pExpectedAggregatedPacket[k] = pPackets[i][j];
k++;
}
}
//comparing the received packet to the aggregated packet
LOG_MSG_DEBUG("Checking sent.vs.received packet\n");
if (0 != memcmp(pExpectedAggregatedPacket, pReceivedPacket,
sizeof(pReceivedPacket)))
{
LOG_MSG_DEBUG("Comparison of packet %d failed!\n", n);
return false;
}
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//Those tests should be run with configuration number 8.
//Please look at the Fixture for more configurations update.
static TLPAggregationTest tlpAggregationTest;
static TLPDeaggregationTest tlpDeaggregationTest;
static TLPAggregationLoopTest tlpAggregationLoopTest;
static TLPAggregationTimeLimitTest tlpAggregationTimeLimitTest;
static TLPAggregationByteLimitTest tlpAggregationByteLimitTest;
static TLPAggregation2PipesTest tlpAggregation2PipesTest;
static TLPAggregationTimeLimitLoopTest tlpAggregationTimeLimitLoopTest;
static TLPDeaggregationAndAggregationTest tlpDeaggregationAndAggregationTest;
/////////////////////////////////////////////////////////////////////////////////
// EOF ////
/////////////////////////////////////////////////////////////////////////////////

74
kernel-tests/TestBase.cpp Normal file
View File

@@ -0,0 +1,74 @@
/*
* 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 "TestBase.h"
#include "TestManager.h"
#include "linux/msm_ipa.h"
//////////////////////////////////////////////////////////////////////
TestBase::TestBase() :
m_runInRegression(true),
m_minIPAHwType(IPA_HW_v1_1),
m_maxIPAHwType(IPA_HW_MAX)
{
m_mem_type = DFLT_NAT_MEM_TYPE;
}
//////////////////////////////////////////////////////////////////////
void TestBase::Register(TestBase &test)
{
TestManager::GetInstance()->Register(test);
}
//////////////////////////////////////////////////////////////////////
//Empty default implementation, a test does not have to implement Setup()
bool TestBase::Setup()
{
return true;
}
//////////////////////////////////////////////////////////////////////
//Empty default implementation, a test does not have to implement Teardown()
bool TestBase::Teardown()
{
return true;
}
//////////////////////////////////////////////////////////////////////
TestBase::~TestBase()
{
}
//////////////////////////////////////////////////////////////////////

74
kernel-tests/TestBase.h Normal file
View File

@@ -0,0 +1,74 @@
/*
* 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.
*/
#ifndef _TEST_BASE_H_
#define _TEST_BASE_H_
#include <string>
#include <vector>
#define DFLT_NAT_MEM_TYPE "HYBRID"
using namespace std;
class TestBase
{
public:
virtual bool Setup();
/* Empty default implementation,
* a test does not have to implement Setup()
*/
virtual bool Run() = 0;
/* A test must implement Run() */
virtual bool Teardown();
/* Empty default implementation,
* a test does not have to implement Teardown()
*/
void Register(TestBase & test);
virtual ~TestBase();
TestBase();
void SetMemType(
const char* mem_type = DFLT_NAT_MEM_TYPE)
{
m_mem_type = mem_type;
}
const char* m_mem_type;
string m_name;
string m_description;
vector < string > m_testSuiteName;
/* Every test can belong to multiple test suites */
bool m_runInRegression;
/* Should this test be run in a regression test ? (Default is yes) */
int m_minIPAHwType;
/* The minimal IPA HW version which this test can run on */
int m_maxIPAHwType;
/* The maximal IPA HW version which this test can run on */
};
#endif

View File

@@ -0,0 +1,396 @@
/*
* Copyright (c) 2017-2018,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 <algorithm> // std::find
#include <vector> // std::vector
#include <string>
#include <errno.h>
#include <ctime>
#include <sstream>
#include "TestManager.h"
#include "TestsUtils.h"
#include <fcntl.h>
#include <unistd.h>
#include "ipa_test_module.h"
#include <sys/ioctl.h>
using namespace std;
/* Global static pointer used to ensure a single instance of the class. */
TestManager* TestManager::m_instance = NULL;
#ifdef HAVE_LIBXML
TestsXMLResult::TestsXMLResult()
{
xmlNodePtr node;
// initialize xml report document and add a root to node it
m_XML_doc_ptr = xmlNewDoc(BAD_CAST "1.0");
if (m_XML_doc_ptr == NULL){
printf("error on allocation xml doc\n");
exit(-1);
}
node = xmlNewNode(NULL, BAD_CAST "testsuites");
if (!node) {
printf("failed to allocate XML node\n");
exit (-1);
}
xmlDocSetRootElement(m_XML_doc_ptr, node);
}
TestsXMLResult::~TestsXMLResult()
{
if (m_XML_doc_ptr)
xmlFreeDoc(m_XML_doc_ptr);
xmlCleanupParser();
}
/*
* Returns xmlPtr to testsuite element node, if doesn't exist
* creates one by that name
*/
xmlNodePtr TestsXMLResult::GetSuiteElement(const string& suite_name)
{
xmlNodePtr root_node, suite_node, new_child_node;
if (!m_XML_doc_ptr) {
printf("no xml document\n");
return NULL;
}
root_node = xmlDocGetRootElement(m_XML_doc_ptr);
suite_node = xmlFirstElementChild(root_node);
while (suite_node)
{
/* get suite name */
xmlChar *val = xmlGetProp(suite_node, BAD_CAST "name");
/* change xmlCHar* to string */
string node_suite_name(reinterpret_cast<char*>(val));
xmlFree(val); //free val allocated memory
if (node_suite_name == suite_name)
return suite_node;
else suite_node = suite_node->next;
}
/* If we got here no suitable suite name was found,
* so we create a new suite element and return it
*/
new_child_node = xmlNewChild(root_node, NULL, BAD_CAST "testsuite", BAD_CAST "");
if (!new_child_node) {
printf("failed creating new XML node\n");
return NULL;
}
xmlSetProp(new_child_node, BAD_CAST "name", BAD_CAST suite_name.c_str());
return xmlGetLastChild(root_node);
}
/*
* Creates new testcase element
*/
void TestsXMLResult::AddTestcase(const string &suite_nm, const string &test_nm,
double runtime, bool pass)
{
xmlNodePtr suite_node, new_testcase, fail_node;
ostringstream runtime_str;
if (!suite_nm.size() || !test_nm.size()) {
printf("Input error: suite_nm size %d , test_nm size %d",
suite_nm.size(), test_nm.size());
exit(-1);
}
suite_node = GetSuiteElement(suite_nm);
if (!suite_node) {
printf("failed getting suite element\n");
exit(-1);
}
/* Create new testcase element as son to suite element */
new_testcase = xmlNewChild(suite_node, NULL, BAD_CAST "testcase", NULL);
if (!new_testcase) {
printf("failed creating XML new child for testcase\n");
exit(-1);
}
xmlSetProp(new_testcase, BAD_CAST "name", BAD_CAST test_nm.c_str());
runtime_str << runtime;
xmlSetProp(new_testcase, BAD_CAST "time", BAD_CAST runtime_str.str().c_str());
if (!pass) {
fail_node = xmlNewChild(new_testcase, NULL, BAD_CAST "failure", NULL);
if (!fail_node) {
printf("failed creating fail node\n");
exit(-1);
}
}
}
/*
* Prints the XML tree to file
*/
void TestsXMLResult::GenerateXMLReport(void)
{
if (!m_XML_doc_ptr) {
printf("no xml document\n");
return;
}
xmlSaveFormatFileEnc(XUNIT_REPORT_PATH_AND_NAME, m_XML_doc_ptr, "UTF-8", 1);
}
#else /* HAVE_LIBXML */
TestsXMLResult::TestsXMLResult() {}
TestsXMLResult::~TestsXMLResult() {}
void TestsXMLResult::AddTestcase(const string &suite_nm, const string &test_nm,
double runtime, bool pass) {}
void TestsXMLResult::GenerateXMLReport(void)
{
printf("No XML support\n");
}
#endif /* HAVE_LIBXML */
TestManager::TestManager(
const char* nat_mem_type_ptr)
{
m_testList.clear();
m_failedTestsNames.clear();
m_numTestsFailed = 0;
m_numTestsRun = 0;
FetchIPAHwType();
m_nat_mem_type_ptr = nat_mem_type_ptr;
}
////////////////////////////////////////////////////////////////////////////////////////////
TestManager::~TestManager()
{
m_testList.clear();
}
////////////////////////////////////////////////////////////////////////////////////////////
TestManager* TestManager::GetInstance(
const char* nat_mem_type_ptr)
{
if (!m_instance) // Only allow one instance of class to be generated.
m_instance = new TestManager(nat_mem_type_ptr);
return m_instance;
}
////////////////////////////////////////////////////////////////////////////////////////////
void TestManager::Register(TestBase &test)
{
m_testList.push_back(&test);
}
////////////////////////////////////////////////////////////////////////////////////////////
bool TestManager::Run(vector<string> testSuiteList, vector<string> testNameList)
{
TestBase *test = NULL;
bool pass = true;
vector<string>::iterator testIter;
vector<string>::iterator testSuiteIter;
bool runTest = false;
clock_t begin_test_clk, end_test_clk;
double test_runtime_sec = 0, total_time_sec = 0;
TestsXMLResult xml_res;
if (m_testList.size() == 0)
return false;
/* PrintRegisteredTests(); */
for (unsigned int i = 0 ; i < m_testList.size() ; i++ , runTest = false) {
pass = true;
test = m_testList[i];
// Run only tests from the list of test suites which is stated in the command
// line. In case the list is empty, run all tests.
if (testSuiteList.size() > 0) {
for (unsigned int j = 0; j < test->m_testSuiteName.size(); j++) {
testSuiteIter = find(testSuiteList.begin(), testSuiteList.end(), test->m_testSuiteName[j]);
if (testSuiteIter != testSuiteList.end()) {
runTest = true;
}
}
}
// We also support test by name
if (testNameList.size() > 0) {
testIter = find(testNameList.begin(), testNameList.end(), test->m_name);
if (testIter != testNameList.end())
runTest = true;
}
// Run the test only if it's applicable to the current IPA HW type / version
if (runTest) {
if (!(m_IPAHwType >= test->m_minIPAHwType && m_IPAHwType <= test->m_maxIPAHwType))
runTest = false;
}
if (!runTest)
continue;
printf("\n\nExecuting test %s\n", test->m_name.c_str());
printf("Description: %s\n", test->m_description.c_str());
printf("Setup()\n");
begin_test_clk = clock();
test->SetMemType(GetMemType());
pass &= test->Setup();
//In case the test's setup did not go well it will be a bad idea to try and run it.
if (true == pass)
{
printf("Run()\n");
pass &= test->Run();
}
printf("Teardown()\n");
pass &= test->Teardown();
end_test_clk = clock();
test_runtime_sec = double(end_test_clk - begin_test_clk) / CLOCKS_PER_SEC;
total_time_sec += test_runtime_sec;
if (pass)
{
m_numTestsRun++;
PrintSeparator(test->m_name.size());
printf("Test %s PASSED ! time:%g\n", test->m_name.c_str(), test_runtime_sec);
PrintSeparator(test->m_name.size());
}
else
{
m_numTestsRun++;
m_numTestsFailed++;
m_failedTestsNames.push_back(test->m_name);
PrintSeparator(test->m_name.size());
printf("Test %s FAILED ! time:%g\n", test->m_name.c_str(), test_runtime_sec);
PrintSeparator(test->m_name.size());
}
xml_res.AddTestcase(test->m_testSuiteName[0], test->m_name, test_runtime_sec, pass);
} // for
// Print summary
printf("\n\n");
printf("==================== RESULTS SUMMARY ========================\n");
printf("%zu tests were run, %zu failed, total time:%g.\n", m_numTestsRun, m_numTestsFailed, total_time_sec);
if (0 != m_numTestsFailed) {
printf("Failed tests list:\n");
for (size_t i = 0; i < m_numTestsFailed; i++) {
printf(" %s\n", m_failedTestsNames[i].c_str());
m_failedTestsNames.pop_back();
}
}
printf("=============================================================\n");
xml_res.GenerateXMLReport();
return pass;
}
////////////////////////////////////////////////////////////////////////////////////////////
void TestManager::PrintSeparator(size_t len)
{
string separator;
for (size_t i = 0; i < len + 15; i++) {
separator += "-";
}
printf("%s\n", separator.c_str());
}
////////////////////////////////////////////////////////////////////////////////////////////
TestManager::TestManager(TestManager const&)
{
}
////////////////////////////////////////////////////////////////////////////////////////////
TestManager& TestManager::operator=(TestManager const&)
{
return *m_instance;
}
////////////////////////////////////////////////////////////////////////////////////////////
void TestManager::PrintRegisteredTests()
{
printf("Test list: (%zu registered)\n", m_testList.size());
for (unsigned int i = 0; i < m_testList.size(); i++) {
printf("%d) name = %s, suite name = %s, regression = %d\n", i, m_testList[i]->m_name.c_str(),
m_testList[i]->m_testSuiteName[0].c_str(), m_testList[i]->m_runInRegression);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
void TestManager::FetchIPAHwType()
{
int fd;
// Open ipa_test device node
fd = open("/dev/ipa_test" , O_RDONLY);
if (fd < 0) {
printf("Failed opening %s. errno %d: %s\n", "/dev/ipa_test", errno, strerror(errno));
m_IPAHwType = IPA_HW_None;
return;
}
printf("%s(), fd is %d\n", __FUNCTION__, fd);
m_IPAHwType = (enum ipa_hw_type)ioctl(fd, IPA_TEST_IOC_GET_HW_TYPE);
if (-1 == m_IPAHwType) {
printf("%s(), IPA_TEST_IOC_GET_HW_TYPE ioctl failed\n", __FUNCTION__);
m_IPAHwType = IPA_HW_None;
}
printf("%s(), IPA HW type (version) = %d\n", __FUNCTION__, m_IPAHwType);
close(fd);
}
////////////////////////////////////////////////////////////////////////////////////////////

103
kernel-tests/TestManager.h Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2017-2018,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.
*/
#ifndef _TEST_MANAGER_H_
#define _TEST_MANAGER_H_
#include "TestBase.h"
#include <vector>
#include <string>
#include "linux/msm_ipa.h"
#ifdef HAVE_LIBXML
#include <libxml/parser.h>
#include <libxml/tree.h>
#endif
using namespace std;
class TestsXMLResult
{
public:
TestsXMLResult();
~TestsXMLResult();
void AddTestcase(const string &suite_nm, const string &test_nm,
double runtime, bool pass);
void GenerateXMLReport(void);
private:
#ifdef HAVE_LIBXML
xmlNodePtr GetSuiteElement(const string& suite_name);
xmlDocPtr m_XML_doc_ptr;
#endif
};
class TestManager /* Singleton */
{
public:
static TestManager *GetInstance(
const char* nat_mem_type_ptr = DFLT_NAT_MEM_TYPE);
~TestManager();
void Register(TestBase & test);
bool Setup();
/* This is the place to put initialization
* for the whole test framework
*/
bool Run(vector <string> testSuiteList,
vector <string> testNameList);
/* This function will run all the tests in the system */
bool Teardown();
/* This is the place to put tear-down for the whole test framework */
vector < TestBase * > m_testList;
/* Holds pointers to all of the tests in the system */
enum ipa_hw_type GetIPAHwType() {return m_IPAHwType;}
const char* GetMemType() { return m_nat_mem_type_ptr; }
private:
TestManager(
const char* nat_mem_type_ptr = DFLT_NAT_MEM_TYPE);
TestManager(TestManager const &);
TestManager & operator = (TestManager const &);
void PrintSeparator(size_t len);
void PrintRegisteredTests();
void BuildRegressionTestSuite();
void FetchIPAHwType();
static TestManager *m_instance;
size_t m_numTestsRun;
size_t m_numTestsFailed;
enum ipa_hw_type m_IPAHwType;
const char* m_nat_mem_type_ptr;
vector < string > m_failedTestsNames;
};
#endif

1814
kernel-tests/TestsUtils.cpp Normal file

File diff suppressed because it is too large Load Diff

798
kernel-tests/TestsUtils.h Normal file
View File

@@ -0,0 +1,798 @@
/*
* 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.
*/
#ifndef __TESTS_UTILS__H__
#define __TESTS_UTILS__H__
#include <stdarg.h>
#include <vector>
#include <string>
#include <linux/if_ether.h>
#include <linux/msm_ipa.h>
#include "TestBase.h"
#include "Constants.h"
#include "RoutingDriverWrapper.h"
#include "InterfaceAbstraction.h"
#include "ipa_test_module.h"
#include "TestManager.h"
#include "Logger.h"
#include "Constants.h"
extern "C" {
#include "ipa_nat_utils.h"
}
using namespace std;
#define TEST_APP_VERSION "2.00"
#define Free(x) do { if (x) {free(x); x = NULL; } } while (0)
#define MAX3(_X, _Y, _Z) max(max((_X), (_Y)), (_Z))
#define ETH2_DST_ADDR_OFFSET (0)
#define ETH2_SRC_ADDR_OFFSET (ETH_ALEN)
#define ETH2_ETH_TYPE_OFFSET (ETH2_SRC_ADDR_OFFSET + ETH_ALEN)
#define ETH2_ETH_TYPE_LEN (2)
#define ETH2_PAYLOAD_OFFSET (ETH2_ETH_TYPE_OFFSET + ETH2_ETH_TYPE_LEN)
#define ETH8021Q_HEADER_LEN (18)
#define ETH8021Q_METADATA_OFFSET (12)
#define ETH8021Q_8021Q_TAG_LEN (4)
#define ETH8021Q_ETH_TYPE_OFFSET (ETH8021Q_METADATA_OFFSET + ETH8021Q_8021Q_TAG_LEN)
#define WLAN_HDR_SIZE (4)
#define RNDIS_HDR_SIZE (44)
// 26 ROME WLAN Frame =
// 4 ROME WLAN header +
// 14 IEEE 802.3 +
// 8 802.2 LLC/SNAP
#define _802_3_HDR_SIZE (26)
// [WLAN][ETH2] header
#define WLAN_ETH2_HDR_SIZE (WLAN_HDR_SIZE + ETH_HLEN)
// [RNDIS][ETH2] header
#define RNDIS_ETH2_HDR_SIZE (RNDIS_HDR_SIZE + ETH_HLEN)
#define IP4_PACKET_SIZE (70) // Arbitrary number
// OFFSET = sizeof(struct rndis_pkt_hdr) - RNDIS_HDR_OFST(data_ofst)
#define RNDIS_DATA_OFFSET (36)
// [WLAN][802.3] header
#define WLAN_802_3_HDR_SIZE (WLAN_HDR_SIZE + _802_3_HDR_SIZE)
#define IPA_CLIENT_IS_PROD(x) \
(x < IPA_CLIENT_MAX && (x & 0x1) == 0)
#define IPA_CLIENT_IS_CONS(x) \
(x < IPA_CLIENT_MAX && (x & 0x1) == 1)
enum msgType {
ERROR = 0,
DEBUG,
INFO,
STACK
};
/**
@brief
Do not Use this function. Use MACROs instead.
@details
Do not Use this function.
Instead use the MACROs: LOG_MSG_ERROR, LOG_MSG_INFO & LOG_MSG_DEBUG
*/
void __log_msg(enum msgType,
const char *filename,
int line, const char *function,
const char *format, ...);
#define LOG_MSG_ERROR(...) \
__log_msg(ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define LOG_MSG_DEBUG(...) \
__log_msg(DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define LOG_MSG_INFO(...) \
__log_msg(INFO, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define LOG_MSG_STACK(...) \
__log_msg(STACK, __FILE__, __LINE__, __func__, __VA_ARGS__)
/*#define LOG_MSG_ERROR(x...)
__log_msg(ERROR, __FILE__, __LINE__, __func__, x)
#define LOG_MSG_DEBUG(x...)
__log_msg(DEBUG, __FILE__, __LINE__, __func__, x)
#define LOG_MSG_INFO(x...)
__log_msg(INFO, __FILE__, __LINE__, __func__, x)
#define LOG_MSG_STACK(x...)
__log_msg(STACK, __FILE__, __LINE__, __func__, x)*/
/**
@brief
Function loads a default IPv4 / IPv6 Packet
@param [in] eIP - Type of Packet to load (IPA_IP_v4 / IPA_IP_v6)
@param [in] pBuffer - pointer to the destination buffer
@param [in,out] nMaxSize - The size of the buffer.
Upon function return,
the total number of bytes copied will be stored in this parameter.
@return boolean indicating whether the
operation completed successfully or not.
@details
Function loads a default IPv4 / IPv6 packet into pBuffer.
*/
bool LoadDefaultPacket(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
bool LoadDefaultEth2Packet(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
bool LoadDefaultWLANEth2Packet(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
bool LoadDefaultWLAN802_32Packet(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
bool LoadNoPayloadPacket(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
bool LoadDefault802_1Q(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
/**
@brief
Function loads a default IPv4 / IPv6 Packet
@param [in] eIP - Type of Packet to load (IPA_IP_v4 / IPA_IP_v6)
@param [in] extHdrType - Type of IPV6 extension header(FRAGMENT / NONE)
@param [in] pBuffer - pointer to the destination buffer
@param [in,out] nMaxSize - The size of the buffer.
Upon function return,
the total number of bytes copied will be stored in this parameter.
@return boolean indicating whether the
operation completed successfully or not.
@details
Function loads a default IPv4 / IPv6 packet into pBuffer.
*/
bool LoadDefaultPacket(
enum ipa_ip_type eIP,
enum ipv6_ext_hdr_type extHdrType,
uint8_t *pBuffer,
size_t &nMaxSize);
/**
@brief
Function Sends a Packet, Receive a packet
and compares the received result with an expected buffer
@param [in] pSink - Destination to which a packet will be sent.
@param [in] pSendBuffer -
Pointer to a buffer containing the packet that will be sent.
@param [in] nSendBuffSize - The size of the data in the packet.
@param [in] pSource - Source from which a packet will be received.
@param [in] pExpectedBuffer - Pointer a
buffer containing the expected packet (from the receiver)
@param [in] nExpectedBuffSize - The size of
valid data within pExpectedBuffer.
@return Boolean indicating whether the operation
completed successfully and the buffers matching or not.
@details
Function sends a packet to pSink, and receives a packet from pSource.
The packet received from pSource
is compared to the expected data from pExpectedBuffer.
If ExpectData is identical to the
received data, the function returns TRUE.
*/
bool SendReceiveAndCompare(
InterfaceAbstraction * pSink,
uint8_t *pSendBuffer,
size_t nSendBuffSize,
InterfaceAbstraction * pSource,
uint8_t *pExpectedBuffer,
size_t nExpectedBuffSize);
/**
@brief
This function creates a bypass rule within a table in the Routing block
@param [in] pRouting - pointer to the Routing Class
@param [in] eIP - Type of Packet to load (IPA_IP_v4 / IPA_IP_v6)
@param [in] pTableName - pointer to the Table's Name.
@param [in] eRuleDestination - destination of the bypass rule.
@param [in] uHeaderHandle -
handle to the Header that should be Added (0 should be used as default).
@param [out] pTableHdl -
pointer to the table Handle (Can be Null)
@return boolean indicating whether
the operation completed successfully or not.
@details
This function creates bypass rule within a table in the Routing block.
*/
bool CreateBypassRoutingTable(
RoutingDriverWrapper * pRouting,
enum ipa_ip_type eIP,
const char *pTableName,
enum ipa_client_type eRuleDestination,
uint32_t uHeaderHandle,
uint32_t *pTableHdl);
/**
@brief
This function creates a bypass rule within a table in the Routing block
@param [in] pRouting - pointer to the Routing Class
@param [in] eIP - Type of Packet to load (IPA_IP_v4 / IPA_IP_v6)
@param [in] pTableName - pointer to the Table's Name.
@param [in] eRuleDestination - destination of the bypass rule.
@param [in] uHeaderHandle -
handle to the Header that should be Added (0 should be used as default).
@param [out] pTableHdl -
pointer to the table Handle (Can be Null)
@return boolean indicating whether
the operation completed successfully or not.
@details
This function creates bypass rule within a table in the Routing block.
*/
bool CreateBypassRoutingTable_v2(
RoutingDriverWrapper * pRouting,
enum ipa_ip_type eIP,
const char *pTableName,
enum ipa_client_type eRuleDestination,
uint32_t uHeaderHandle,
uint32_t *pTableHdl,
uint8_t uClsAggrIrqMod);
/**
@brief
Configures the sytem to one of the pre-determined
configurations.
@param [in] testConfiguration - Configuration number
@param [in] params - additional parameters
@return void
@details
Writes the configuration index to /dev/ipa_test. In case
the system has already been configured, returns.
*/
void ConfigureScenario(int testConfiguration);
void ConfigureScenario(int testConfiguration, const char *params);
int GenericConfigureScenario(struct ipa_test_config_header *header);
int GenericConfigureScenarioDestory(void);
int ConfigureSystem(int testConfiguration, int fd);
int ConfigureSystem(int testConfiguration, int fd, const char *params);
void prepare_channel_struct(struct ipa_channel_config *channel,
int index,
enum ipa_client_type client,
void *cfg,
size_t config_size,
bool en_status = 0);
void prepare_header_struct(struct ipa_test_config_header *header,
struct ipa_channel_config **from,
struct ipa_channel_config **to);
/**
@brief
Compares two data buffers.
@param [in] goldenBuffer - Pointer to the first data
buffer
@param [in] goldenSize - First data buffer size
@param [in] receivedBuffer - Pointer to the second data
buffer
@param [in] receivedSize - Second data buffer size
@return True - the buffers are identical. False
otherwise.
@details
In case the sizes are differnt, false is returned.
*/
bool CompareResultVsGolden(
unsigned char *goldenBuffer,
unsigned int goldenSize,
unsigned char *receivedBuffer,
unsigned int receivedSize);
/**
@brief
Compares two data buffers considering the returned status.
@param [in] goldenBuffer - Pointer to the first data
buffer
@param [in] goldenSize - First data buffer size
@param [in] receivedBuffer - Pointer to the second data
buffer
@param [in] receivedSize - Second data buffer size
@return True - the buffers are identical. False
otherwise.
@details
In case the sizes are differnt, false is returned.
*/
bool CompareResultVsGolden_w_Status(
Byte *goldenBuffer,
unsigned int goldenSize,
Byte *receivedBuffer,
unsigned int receivedSize);
/**
@brief
Loads a file to memory
@param [in] fileFullPath
@param [inout] sizeLoaded - returns the number of bytes
which were read from the file
@return Address of the loaded data buffer
@details
Allocates memory by itself, user should free the memory
*/
unsigned char *LoadFileToMemory(
const string & fileFullPath,
unsigned int *sizeLoaded);
/**
@brief
Checks whether a file exists on disk
@param [in] filename
@return True if the file exists, false otherwise.
@details
*/
bool file_exists(const char *filename);
/**
@brief
Prints a data buffer.
@param [in] data - Pointer to the data
@param [in] size - How many bytes to print
@return void
@details
*/
void print_buff(void *data, size_t size);
void add_buff(uint8_t *data, size_t size, uint8_t val);
/**
@brief
Performes ep control of a specific endpoint.
@param [in] ep_ctrl - Pointer to ipa_test_ep_ctrl struct with
the data of the requested operation
@return bool
@details
Suspend\Unsuspends\Delays\resumes an endpoint.
*/
bool configure_ep_ctrl(struct ipa_test_ep_ctrl *ep_ctrl);
/**
@brief
Performes holb config of a specific pipe.
* @param [in] test_holb_config - Pointer to
* ipa_test_holb_config struct with the data of
* the requested operation
@return bool
@details
Configures HOLB parameters on a pipe.
*/
bool configure_holb(struct ipa_test_holb_config *test_holb_config);
/**
@brief
Register an alternative suspend handler
@param [in] deferred_flag - should the handler execute in defer mode
@param [in] reg - register or unregister the suspend handler
@param [in] DevNum - the index of the ep that the handler is registered to
@return bool
@details
Register the test framework suspend handler for a given endpoint
*/
bool RegSuspendHandler(bool deferred_flag, bool reg, int DevNum);
class Eth2Helper {
public:
static const Byte m_ETH2_IP4_HDR[ETH_HLEN];
static bool LoadEth2IP4Header(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
static bool LoadEth2IP6Header(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
static bool LoadEth2IP4Packet(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
static bool LoadEth2IP6Packet(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
};
class WlanHelper {
public:
static const Byte m_WLAN_HDR[WLAN_HDR_SIZE];
static bool LoadWlanHeader(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
static bool LoadWlanEth2IP4Header(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
static bool LoadWlanEth2IP6Header(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
static bool LoadWlanEth2IP4Packet(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
static bool LoadWlanEth2IP4PacketByLength(
uint8_t *pBuffer,
size_t bufferSize,
size_t len,
uint8_t padValue);
static bool LoadWlanEth2IP6Packet(
uint8_t *pBuffer,
size_t bufferSize,
size_t *pLen);
};
#pragma pack(push) /* push current alignment to stack */
#pragma pack(1) /* set alignment to 1 byte boundary */
struct RndisHeader {
uint32_t MessageType;
uint32_t MessageLength;
uint32_t DataOffset;
uint32_t DataLength;
uint32_t OOBDataOffset;
uint32_t OOBDataLength;
uint32_t OOBNumber;
uint32_t PacketInfoOffset;
uint32_t PacketInfoLength;
uint64_t Reserved;
};
struct RndisEtherHeader {
struct RndisHeader rndisHeader;
struct ethhdr etherHeader;
};
#pragma pack(pop) /* restore original alignment from stack */
class RNDISAggregationHelper {
public:
static const size_t RNDIS_AGGREGATION_BYTE_LIMIT = 1024;
static bool LoadRNDISHeader(
uint8_t *pBuffer,
size_t bufferSize,
uint32_t messageLength,
size_t *pLen);
static bool LoadRNDISEth2IP4Header(
uint8_t *pBuffer,
size_t bufferSize,
uint32_t messageLength,
size_t *pLen);
static bool LoadRNDISPacket(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
static bool LoadEtherPacket(
enum ipa_ip_type eIP,
uint8_t *pBuffer,
size_t &nMaxSize);
static bool ComparePackets(
Byte *pPacket1,
int pPacket1Size,
Byte *pPacket2,
int pPacket2Size);
static bool CompareEthervsRNDISPacket(
Byte *pIPPacket,
size_t ipPacketSize,
Byte *pRNDISPacket,
size_t rndisPacketSize);
static bool CompareIPvsRNDISPacket(
Byte *pIPPacket,
int ipPacketSize,
Byte *pRNDISPacket,
size_t rndisPacketSize);
};
enum ipa_nat_en_type {
IPA_BYPASS_NAT,
IPA_SRC_NAT,
IPA_DST_NAT,
};
enum ipa_ipv6ct_en_type {
IPA_BYPASS_IPV6CT,
IPA_ENABLE_IPV6CT,
};
enum ipa_mode_type {
IPA_BASIC,
IPA_ENABLE_FRAMING_HDLC,
IPA_ENABLE_DEFRAMING_HDLC,
IPA_DMA,
};
enum ipa_aggr_en_type {
IPA_BYPASS_AGGR,
IPA_ENABLE_AGGR,
IPA_ENABLE_DEAGGR,
};
enum ipa_aggr_type {
IPA_MBIM_16 = 0,
IPA_HDLC = 1,
IPA_TLP = 2,
IPA_RNDIS = 3,
IPA_GENERIC = 4,
IPA_QCMAP = 6,
};
enum ipa_aggr_mode {
IPA_MBIM_AGGR,
IPA_QCNCM_AGGR,
};
enum hdr_total_len_or_pad_type {
IPA_HDR_PAD = 0,
IPA_HDR_TOTAL_LEN = 1,
};
struct ipa_ep_cfg_nat {
enum ipa_nat_en_type nat_en;
};
struct ipa_ep_cfg_conn_track {
enum ipa_ipv6ct_en_type conn_track_en;
};
struct ipa_ep_cfg_hdr {
uint32_t hdr_len;
uint32_t hdr_ofst_metadata_valid;
uint32_t hdr_ofst_metadata;
uint32_t hdr_additional_const_len;
uint32_t hdr_ofst_pkt_size_valid;
uint32_t hdr_ofst_pkt_size;
uint32_t hdr_a5_mux;
uint32_t hdr_remove_additional;
uint32_t hdr_metadata_reg_valid;
};
struct ipa_ep_cfg_hdr_ext {
uint32_t hdr_pad_to_alignment;
uint32_t hdr_total_len_or_pad_offset;
bool hdr_payload_len_inc_padding;
enum hdr_total_len_or_pad_type hdr_total_len_or_pad;
bool hdr_total_len_or_pad_valid;
bool hdr_little_endian;
struct ipa_ep_cfg_hdr *hdr;
bool hdr_bytes_to_remove_valid;
uint32_t hdr_bytes_to_remove;
};
struct ipa_ep_cfg_mode {
enum ipa_mode_type mode;
enum ipa_client_type dst;
};
struct ipa_ep_cfg_aggr {
enum ipa_aggr_en_type aggr_en;
enum ipa_aggr_type aggr;
uint32_t aggr_byte_limit;
uint32_t aggr_time_limit;
uint32_t aggr_pkt_limit;
uint32_t aggr_hard_byte_limit_en;
bool aggr_sw_eof_active;
uint8_t pulse_generator;
uint8_t scaled_time;
};
struct ipa_ep_cfg_route {
uint32_t rt_tbl_hdl;
};
struct ipa_ep_cfg_deaggr {
uint32_t deaggr_hdr_len;
bool syspipe_err_detection;
bool packet_offset_valid;
uint32_t packet_offset_location;
bool ignore_min_pkt_err;
uint32_t max_packet_len;
};
enum ipa_cs_offload {
IPA_DISABLE_CS_OFFLOAD,
IPA_ENABLE_CS_OFFLOAD_UL,
IPA_ENABLE_CS_OFFLOAD_DL,
IPA_CS_RSVD
};
struct ipa_ep_cfg_cfg {
bool frag_offload_en;
enum ipa_cs_offload cs_offload_en;
uint8_t cs_metadata_hdr_offset;
uint8_t gen_qmb_master_sel;
uint8_t tx_instance;
};
struct ipa_ep_cfg_metadata_mask {
uint32_t metadata_mask;
};
struct ipa_ep_cfg_metadata {
uint32_t qmap_id;
};
struct ipa_ep_cfg_seq {
bool set_dynamic;
int seq_type;
};
struct ipa_ep_cfg_holb {
uint32_t tmr_val;
uint32_t base_val;
uint32_t scale;
uint16_t en;
uint8_t pulse_generator;
uint8_t scaled_time;
};
/*
* This struct is a mirroring of the ipa struct
* the test module expect to get from user-space the
* exact same struct as IPA driver defined.
* In case of any change to IPA driver struct
* this struct should be updated as well!
*/
struct test_ipa_ep_cfg {
struct ipa_ep_cfg_nat nat;
struct ipa_ep_cfg_conn_track conn_track;
struct ipa_ep_cfg_hdr hdr;
struct ipa_ep_cfg_hdr_ext hdr_ext;
struct ipa_ep_cfg_mode mode;
struct ipa_ep_cfg_aggr aggr;
struct ipa_ep_cfg_deaggr deaggr;
struct ipa_ep_cfg_route route;
struct ipa_ep_cfg_cfg cfg;
struct ipa_ep_cfg_metadata_mask metadata_mask;
struct ipa_ep_cfg_metadata meta;
struct ipa_ep_cfg_seq seq;
};
/*! @brief Struct for the IPAv3.0 UL packet status header */
struct ipa3_hw_pkt_status {
uint64_t status_opcode:8;
uint64_t exception:8;
uint64_t status_mask:16;
uint64_t pkt_len:16;
uint64_t endp_src_idx:5;
uint64_t reserved_1:3;
uint64_t endp_dest_idx:5;
uint64_t reserved_2:3;
uint64_t metadata:32;
uint64_t filt_local:1;
uint64_t filt_hash:1;
uint64_t filt_global:1;
uint64_t ret_hdr:1;
uint64_t filt_rule_id:10;
uint64_t route_local:1;
uint64_t route_hash:1;
uint64_t ucp:1;
uint64_t route_tbl_idx:5;
uint64_t route_rule_id:10;
uint64_t nat_hit:1;
uint64_t nat_tbl_idx:13;
uint64_t nat_type:2;
uint64_t tag:48;
uint64_t seq_num:8;
uint64_t time_day_ctr:24;
uint64_t hdr_local:1;
uint64_t hdr_offset:10;
uint64_t frag_hit:1;
uint64_t frag_rule:4;
uint64_t reserved_4:16;
};
struct ipa3_hw_pkt_status_hw_v5_0 {
uint64_t status_opcode : 8;
uint64_t exception : 8;
uint64_t status_mask : 16;
uint64_t pkt_len : 16;
uint64_t endp_src_idx : 8;
uint64_t reserved_1 : 3;
uint64_t route_local : 1;
uint64_t route_hash : 1;
uint64_t reserved_2 : 3;
uint64_t metadata : 32;
uint64_t filt_local : 1;
uint64_t filt_hash : 1;
uint64_t filt_global : 1;
uint64_t ret_hdr : 1;
uint64_t filt_rule_id : 10;
uint64_t route_tbl_idx : 8;
uint64_t route_rule_id : 10;
uint64_t nat_hit : 1;
uint64_t nat_tbl_idx : 13;
uint64_t nat_type : 2;
uint64_t tag : 48;
uint64_t seq_num : 8;
uint64_t time_day_ctr : 24;
uint64_t hdr_local : 1;
uint64_t hdr_offset : 10;
uint64_t frag_hit : 1;
uint64_t frag_rule : 4;
uint64_t endp_dest_idx : 8;
uint64_t reserved_4 : 7;
uint64_t ucp : 1;
};
#endif

12
kernel-tests/autogen.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
# autogen.sh -- Autotools bootstrapping
#
AUTO_TOOLS_VER=$(automake --version | grep ^automake | sed 's/^.* //g' | cut -d'.' -f1-2)
aclocal-${AUTO_TOOLS_VER} &&\
autoheader &&\
autoconf &&\
automake-${AUTO_TOOLS_VER} --add-missing --copy

View File

@@ -0,0 +1,129 @@
#! /usr/bin/env python
# Copyright (c) 2021, 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.
import os
import os.path
import subprocess
import sys
import shutil
install_dir = '/ipa-kernel-tests' # unlikely to ever change, so 'file constant'
def get_args():
class Args:
pass
args = Args()
try:
args.cc_path = os.path.dirname(os.environ['CROSS_COMPILE'])
except:
args.cc_path = None
try:
args.arch = os.environ['ARCH']
except:
raise Exception("ARCH must be set")
try:
args.kdir = os.environ['KDIR']
except:
raise Exception("KDIR must be set")
try:
args.dest = os.environ['DESTDIR']
except:
raise Exception("DESTDIR must be set")
return args
def do(cmd, wdir=None):
cwd = None
if wdir:
cwd = os.getcwd()
os.chdir(wdir)
subprocess.check_call(cmd)
if cwd:
os.chdir(cwd)
def build(args):
if args.cc_path:
os.environ['PATH'] = args.cc_path + ':' + os.environ['PATH']
args.uapi = args.kdir + '/usr/include'
args.src = args.kdir + '/techpack/dataipa/kernel-tests'
args.inc = args.kdir + '/techpack/dataipa/drivers/platform/msm/ipa/ipa_test_module'
full_uapi = os.path.abspath(args.uapi)
os.environ['CPPFLAGS'] = ('-I' + full_uapi)
full_inc = os.path.abspath(args.inc)
os.environ['CPPFLAGS'] += (' -I' + full_inc)
configure(args, args.src)
do(['make'], args.src)
do(['make', 'DESTDIR=' + args.dest, 'install'], args.src)
def configure(args, wdir):
if os.path.isfile(os.path.join(wdir, 'config.h')):
return
do(['libtoolize'], wdir)
do(['./autogen.sh'], wdir)
full_idir = os.path.abspath(os.path.join(wdir, install_dir))
host_str = 'arm-linux-gnueabihf'
config_extra = ''
if args.arch == 'arm64':
host_str = 'aarch64-linux-gnu'
config_extra = '--disable-swp'
do(['./configure',
'--host=' + host_str,
'--prefix=' + full_idir,
config_extra], wdir)
def main():
rc = 0
try:
args = get_args()
build(args)
except Exception as e:
rc = 1
print(e)
sys.exit(rc)
if __name__ == '__main__':
main()

56
kernel-tests/configure.ac Normal file
View File

@@ -0,0 +1,56 @@
AC_PREREQ(2.64)
AC_INIT([ipa-kernel-tests],[1.0.0])
AM_INIT_AUTOMAKE([-Wall -Werror gnu foreign])
AM_MAINTAINER_MODE
AC_CONFIG_HEADER([config.h])
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_CXX
AS_CASE([$host],
[aarch64*], [ARM64=yes],
[ARM64=no]
)
AM_CONDITIONAL(ARM64, [test "x$ARM64" = "xyes"])
AC_ARG_WITH([glib],
AC_HELP_STRING([--with-glib],
[enable glib, building HLOS systems which use glib]))
AC_ARG_WITH(ipanat-headers,
AS_HELP_STRING([--with-ipanat-headers=DIR],
[Specify the location of the ipanat headers]),
[CPPFLAGS="$CPPFLAGS -idirafter $withval"])
if (test "x${with_glib}" = "xyes"); then
AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
AC_MSG_ERROR(GThread >= 2.16 is required))
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
AC_MSG_ERROR(GLib >= 2.16 is required))
GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
fi
AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
AC_CONFIG_FILES([
Makefile
])
AC_OUTPUT

80
kernel-tests/create_symlinks.sh Executable file
View File

@@ -0,0 +1,80 @@
# Copyright (c) 2021, 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.
# This script creates symlinks for tests that are compiled as Soong modules, so
# that they may be accessed from their old location in /data/kernel-tests
#!/bin/sh
NTEST_PATH="/data/nativetest"
KTEST_PATH="/data/kernel-tests"
# Any test that is compiled as a cc_test module (which applies to any Soong
# module in kernel-tests-internal) is given a directory, in to which the
# compiled test and its supporting files are placed. This function iterates
# over the test directories in $1 and creates symlinks to all the files
# contained within a given test directory. $2 and later arguemnts can be used to
# specify directores to skip.
create_links()
{
BASE_PATH="$1"
shift
SKIP_FILES=$@ # These can also be directories
for TEST_DIR in `ls "$BASE_PATH"`; do
# Filter out any file / directory in SKIP_FILES.
SHOULD_SKIP=""
for i in $SKIP_FILES; do
if [ "$TEST_DIR" = "$i" ]; then
SHOULD_SKIP="TRUE"
break
fi
done
if [ ! "$SHOULD_SKIP" = "" ]; then
continue
fi
# Filter out any files that aren't directories (since every test we
# compile is given a directory)
if [ ! -d "$BASE_PATH/$TEST_DIR" ]; then
continue
fi
# Now, create the symlinks for each test file inside of TEST_DIR
for TEST_FILE in `ls "$BASE_PATH/$TEST_DIR"`; do
ln -fs "$BASE_PATH/$TEST_DIR/$TEST_FILE" "$KTEST_PATH/$TEST_FILE"
done
done
}
# Create /data/kernel-tests, if it doesn't exist already
mkdir -p "$KTEST_PATH"
# Create the symlinks
create_links "$NTEST_PATH" "vendor"
create_links "$NTEST_PATH/vendor"

39
kernel-tests/hton.h Normal file
View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef HTON_H_
#define HTON_H_
#include <stdint.h>
#include "linux/msm_ipa.h"
#include <netinet/in.h>
#endif

388
kernel-tests/main.cpp Normal file
View File

@@ -0,0 +1,388 @@
/*
* Copyright (c) 2017-2018,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 <getopt.h>
#include "Logger.h"
#include "TestManager.h"
#include "TestsUtils.h"
#include <stdio.h>
#include <iostream>
#include <set>
///////////////////////////////////////////////////////////
Logger g_Logger(LOG_ERROR);
#define CHOOSER_MODE "--chooser"
#define SHOW_TEST_FLAG "--show_tests"
#define SHOW_SUIT_FLAG "--show_suites"
#define RUN_TEST_FLAG "--test"
#define RUN_SUIT_FLAG "--suite"
string sFormat = "ip_accelerator <control_flag> <suit/name>, ..., <suit/name>\n"
"contorl_flag = " RUN_TEST_FLAG " or " RUN_SUIT_FLAG "\n"
"ip_accelerator " SHOW_TEST_FLAG "\n"
"ip_accelerator " SHOW_SUIT_FLAG "\n"
"or ip_accelerator --chooser "
"for menu chooser interface\n";
#define MAX_SUITES 15
#undef strcasesame
#define strcasesame(x, y) \
(! strcasecmp((x), (y)))
#undef legal_nat_mem_type
#define legal_nat_mem_type(mt) \
( strcasesame(mt, "DDR") || \
strcasesame(mt, "SRAM") || \
strcasesame(mt, "HYBRID") )
TestManager *testmanager = NULL;
enum ipa_test_type{
TEST = 1,
SUITE,
EXIT,
MAX_TYPE
};
const char *ipa_hw_type_name[] = {
"None",
"1.0",
"1.1",
"2.0",
"2.1",
"2.5/2.6",
"2.6L",
"Unused",
"Unused",
"Unused",
"3.0",
"3.1",
"3.5",
"3.5.1",
"4.0",
"4.1",
"4.2",
"4.5",
"4.9",
"5.0",
"MAX"
};
void BuildRegressionTestSuite()
{
TestBase *test;
for (unsigned int i = 0; i < testmanager->m_testList.size(); i++) {
test = testmanager->m_testList[i];
if (test->m_runInRegression) {
test->m_testSuiteName.push_back("Regression");
}
}
}
///////////////////////////////////////////////////////////
void showTests()
{
TestBase *test = testmanager->m_testList[0];
for (unsigned i = 0; i < testmanager->m_testList.size(); i++) {
test = testmanager->m_testList[i];
string name = test->m_name, index = test->m_testSuiteName[0];
printf("%d) %s (part of %s suite" ,i+1, name.c_str(), index.c_str());
for (unsigned j = 0; j < test->m_testSuiteName.size(); ++j) {
if ( test->m_testSuiteName[j] == index)
continue;
printf(", %s suite",
test->m_testSuiteName[j].c_str());
index = test->m_testSuiteName[j];
}
printf("), (%s <= HW Version <= %s)\n",
ipa_hw_type_name[test->m_minIPAHwType],
ipa_hw_type_name[test->m_maxIPAHwType]);
}
// Example:
// 15) DmaModeMBIMggregationLoopTest (part of DmaMbim16Agg suite), (1.0 <= HW Version <= 2.1)
}
void showSuits()
{
TestBase *test;
std::set<string> suiteSet;
int suiteIndex = 1;
test = testmanager->m_testList[0];
for (unsigned i = 0; i < testmanager->m_testList.size(); i++) {
test = testmanager->m_testList[i];
for (unsigned j = 0; j < test->m_testSuiteName.size() ; j++)
suiteSet.insert(test->m_testSuiteName[j]);
}
for (std::set<string>::iterator i = suiteSet.begin();
i != suiteSet.end(); suiteIndex++) {
printf("%d) %s\n", suiteIndex, (*i).c_str());
++i;
}
}
void preparTests(int argc, char* argv[],
vector<string>& list)
{
for (int i = 2; i < argc; i++)
list.push_back(argv[i]);
}
const char* getSuite(int suite_num) {
int count = 0, suiteIndex = 1;
string result = "error";
TestBase *test = testmanager->m_testList[0];
set<string> suiteSet;
if (testmanager->m_testList.size() < 1)
return NULL;
if (count == suite_num)
return testmanager->m_testList[0]->m_testSuiteName[0].c_str();
for (unsigned i = 0; i < testmanager->m_testList.size(); i++) {
test = testmanager->m_testList[i];
for (unsigned j = 0; j < test->m_testSuiteName.size() ; j++)
suiteSet.insert(test->m_testSuiteName[j]);
}
for (std::set<string>::iterator i = suiteSet.begin();
i != suiteSet.end(); suiteIndex++) {
printf("%d) %s\n", suiteIndex, (*i).c_str());
if (suiteIndex == suite_num)
return (*i).c_str();
++i;
}
return NULL;
}
int chooserMode() {
vector<string> testSuiteList;
vector<string> testNameList;
unsigned int test_num;
int suite_num;
int type;
TestBase *test;
const char* res;
int result = 0;
char input_str[4];
printf("Welcome to the ip_accelerator\nChoose an option:\n");
printf("1) Run tests\n2) Run suites\n3) Exit\nChoose an option: ");
res = fgets(input_str, sizeof(input_str), stdin);
type = atoi(input_str);
switch((enum ipa_test_type)type) {
case TEST:
BuildRegressionTestSuite();
showTests();
printf("Choose which test you wish to run: \n");
fflush(stdin);
res = fgets(input_str, sizeof(input_str), stdin);
test_num = atoi(input_str);
if ( test_num > testmanager->m_testList.size()) {
printf("Invalid test number. Try again\n");
result = -1;
break;
}
test = testmanager->m_testList[test_num-1];
printf("Running Test %s\n",
test->m_name.
c_str());
testNameList.push_back(test->m_name.c_str());
BuildRegressionTestSuite();
testmanager->Run(testSuiteList, testNameList);
testNameList.clear();
break;
case SUITE:
BuildRegressionTestSuite();
showSuits();
printf("Choose which suite you wish to run: \n");
fflush(stdin);
res = fgets(input_str, sizeof(input_str), stdin);
suite_num = atoi(input_str);
if (suite_num < 0 || suite_num > MAX_SUITES) {
printf("Invalid test number. Try again\n");
result = -1;
break;
}
res = getSuite(suite_num);
if (!res) {
printf("Error in getSuite. Exiting\n");
result = -1;
break;
}
testSuiteList.push_back(res);
testmanager->Run(testSuiteList, testNameList);
testSuiteList.clear();
break;
default:
printf("Exiting\n");
break;
}
return result;
}
int scriptMode(int argc, char* argv[]) {
vector<string> testSuiteList;
vector<string> testNameList;
string sControlFlag;
if (argc < 2) {
printf("please use correct format:\n%s", sFormat.c_str());
return -1;
}
sControlFlag = argv[1];
if (sControlFlag.find("--") == string::npos) {
printf("please use correct format:\n%s", sFormat.c_str());
return -1;
}
BuildRegressionTestSuite();
if (sControlFlag.compare(SHOW_TEST_FLAG) == 0) {
showTests();
return 0;
} else if (sControlFlag.compare(SHOW_SUIT_FLAG) == 0) {
showSuits();
return 0;
}
if (sControlFlag.compare(RUN_TEST_FLAG) == 0) {
preparTests(argc, argv, testNameList);
} else if (sControlFlag.compare(RUN_SUIT_FLAG) == 0) {
preparTests(argc, argv, testSuiteList);
} else {
printf("please use correct format:\n%s", sFormat.c_str());
return -1;
}
testmanager->Run(testSuiteList, testNameList);
return 0;
}
int main(int argc, char* argv[])
{
string nat_mem_type = DFLT_NAT_MEM_TYPE;
int c, result = 0, what = 0;
int opt_idx = 0;
struct option opts[] = {
/* These options set a flag. */
{"chooser", no_argument, &what, 1},
{"show_tests", no_argument, &what, 2},
{"show_suites", no_argument, &what, 3},
{"test", no_argument, &what, 4},
{"suite", no_argument, &what, 5},
{"mem", required_argument, 0, 'm'},
{0, 0, 0, 0}
};
if (argc <= 1) {
printf("please use correct format:\n%s", sFormat.c_str());
return -1;
}
while ( (c = getopt_long(argc, argv, "", opts, &opt_idx)) != -1 )
{
switch ( c )
{
case 0:
break;
case 'm':
if ( legal_nat_mem_type(optarg) )
{
nat_mem_type = optarg;
}
else
{
fprintf(stderr, "Illegal: --mem %s\n", optarg);
exit(1);
}
break;
default:
fprintf(stderr, "Illegal command line argument passed\n");
printf("please use correct format:\n%s", sFormat.c_str());
exit(1);
}
}
if ( what == 0 ) {
printf("please use correct format:\n%s", sFormat.c_str());
return -1;
}
argc = 2;
switch ( what )
{
case 1:
argv[1] = (char*) CHOOSER_MODE;
break;
case 2:
argv[1] = (char*) SHOW_TEST_FLAG;
break;
case 3:
argv[1] = (char*) SHOW_SUIT_FLAG;
break;
case 4:
argv[1] = (char*) RUN_TEST_FLAG;
break;
case 5:
argv[1] = (char*) RUN_SUIT_FLAG;
break;
default:
printf("please use correct format:\n%s", sFormat.c_str());
exit(1);
}
testmanager = TestManager::GetInstance(nat_mem_type.c_str());
string sControlFlag = argv[1];
if (sControlFlag.compare(CHOOSER_MODE) == 0) {
result = chooserMode();
} else {
result = scriptMode(argc, argv);
}
return result;
}//main
////////////////////////////////////////////////////////////////////

64
kernel-tests/run.sh Normal file
View File

@@ -0,0 +1,64 @@
#! /bin/sh
# Copyright (c) 2014,2017,2021, 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.
set -e
./test_env_setup.sh
echo "Starting test"
if [ $# -eq 0 ]; then
echo "No args\n"
exec ./ipa_kernel_tests --suite_name Regression
fi
#Parse the args for valid switches
while [ $# -gt 0 ]; do
case $1 in
-n | --nominal)
echo "Nominal\n"
exec ./ipa_kernel_tests --suite_name Regression
exit 0
;;
-a | --adversarial)
echo "adversarial\n"
echo "Currently no adversarial tests"
exit 0
;;
-r | --repeatability)
echo "Currently no repeatability tests"
-s | --stress)
echo "Currently no stress tests"
exit 0
;;
-h | --help | *)
echo "Usage: ./run.sh -[n][a][r][s]"
exit 1
;;
esac
done