From ad4a267cbdbae616c8c45174f8daf716203e42d4 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 28 Feb 2020 10:31:03 +0200 Subject: [PATCH] tests: net: af_packet: Add test for binding with multiple interfaces Add a simple test to verify that the bind() can be called multiple times if AF_PACKET is set and there are multiple network interfaces in the system. Signed-off-by: Jukka Rissanen --- tests/net/socket/af_packet/CMakeLists.txt | 9 ++ tests/net/socket/af_packet/prj.conf | 25 ++++ tests/net/socket/af_packet/src/main.c | 149 ++++++++++++++++++++++ tests/net/socket/af_packet/testcase.yaml | 6 + 4 files changed, 189 insertions(+) create mode 100644 tests/net/socket/af_packet/CMakeLists.txt create mode 100644 tests/net/socket/af_packet/prj.conf create mode 100644 tests/net/socket/af_packet/src/main.c create mode 100644 tests/net/socket/af_packet/testcase.yaml diff --git a/tests/net/socket/af_packet/CMakeLists.txt b/tests/net/socket/af_packet/CMakeLists.txt new file mode 100644 index 00000000000..06576e141f3 --- /dev/null +++ b/tests/net/socket/af_packet/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13.1) +include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) +project(socket_udp) + +target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/subsys/net/ip) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/socket/af_packet/prj.conf b/tests/net/socket/af_packet/prj.conf new file mode 100644 index 00000000000..a8f4e1a8684 --- /dev/null +++ b/tests/net/socket/af_packet/prj.conf @@ -0,0 +1,25 @@ +# Networking config +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=n +CONFIG_NET_IPV6=n +CONFIG_NET_UDP=n +CONFIG_NET_TCP=n +CONFIG_NET_SOCKETS=y +CONFIG_NET_SOCKETS_POSIX_NAMES=y +CONFIG_NET_SOCKETS_PACKET=y +CONFIG_POSIX_MAX_FDS=2 +CONFIG_NET_IPV6_DAD=n +CONFIG_NET_IPV6_MLD=n + +# Network driver config +CONFIG_NET_L2_ETHERNET=y +CONFIG_TEST_RANDOM_GENERATOR=y + +# Network address config +CONFIG_NET_CONFIG_SETTINGS=n +CONFIG_NET_CONFIG_NEED_IPV4=n +CONFIG_NET_CONFIG_NEED_IPV6=n + +CONFIG_ZTEST=y +CONFIG_NET_TEST=y +CONFIG_TEST_USERSPACE=y diff --git a/tests/net/socket/af_packet/src/main.c b/tests/net/socket/af_packet/src/main.c new file mode 100644 index 00000000000..82bc4466f56 --- /dev/null +++ b/tests/net/socket/af_packet/src/main.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); + +#include +#include +#include + +#include +#include + +#if defined(CONFIG_NET_SOCKETS_LOG_LEVEL_DBG) +#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +#define DBG(fmt, ...) +#endif + +static u8_t lladdr1[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; +static u8_t lladdr2[] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; + +struct eth_fake_context { + struct net_if *iface; + u8_t *mac_address; +}; + +static struct eth_fake_context eth_fake_data1 = { + .mac_address = lladdr1 +}; +static struct eth_fake_context eth_fake_data2 = { + .mac_address = lladdr2 +}; + +static int eth_fake_send(struct device *dev, struct net_pkt *pkt) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pkt); + + return 0; +} + +static void eth_fake_iface_init(struct net_if *iface) +{ + struct device *dev = net_if_get_device(iface); + struct eth_fake_context *ctx = dev->driver_data; + + ctx->iface = iface; + + net_if_set_link_addr(iface, ctx->mac_address, 6, NET_LINK_ETHERNET); + + ethernet_init(iface); +} + +static struct ethernet_api eth_fake_api_funcs = { + .iface_api.init = eth_fake_iface_init, + .send = eth_fake_send, +}; + +static int eth_fake_init(struct device *dev) +{ + ARG_UNUSED(dev); + + return 0; +} + +ETH_NET_DEVICE_INIT(eth_fake1, "eth_fake1", eth_fake_init, ð_fake_data1, + NULL, CONFIG_ETH_INIT_PRIORITY, ð_fake_api_funcs, + NET_ETH_MTU); + +ETH_NET_DEVICE_INIT(eth_fake2, "eth_fake2", eth_fake_init, ð_fake_data2, + NULL, CONFIG_ETH_INIT_PRIORITY, ð_fake_api_funcs, + NET_ETH_MTU); + +static int setup_socket(struct net_if *iface) +{ + int sock; + + sock = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + zassert_true(sock >= 0, "Cannot create packet socket (%d)", sock); + + return sock; +} + +static int bind_socket(int sock, struct net_if *iface) +{ + struct sockaddr_ll addr; + + memset(&addr, 0, sizeof(addr)); + + addr.sll_ifindex = net_if_get_by_iface(iface); + addr.sll_family = AF_PACKET; + + return bind(sock, (struct sockaddr *)&addr, sizeof(addr)); +} + +struct user_data { + struct net_if *first; + struct net_if *second; +}; + +static void iface_cb(struct net_if *iface, void *user_data) +{ + struct user_data *ud = user_data; + + if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { + return; + } + + if (ud->first == NULL) { + ud->first = iface; + return; + } + + ud->second = iface; +} + +static void test_packet_sockets(void) +{ + struct user_data ud = { 0 }; + int ret, sock1, sock2; + + net_if_foreach(iface_cb, &ud); + + zassert_not_null(ud.first, "1st Ethernet interface not found"); + zassert_not_null(ud.second, "2nd Ethernet interface not found"); + + sock1 = setup_socket(ud.first); + zassert_true(sock1 >= 0, "Cannot create 1st socket (%d)", sock1); + + sock2 = setup_socket(ud.second); + zassert_true(sock2 >= 0, "Cannot create 2nd socket (%d)", sock2); + + ret = bind_socket(sock1, ud.first); + zassert_equal(ret, 0, "Cannot bind 1st socket (%d)", -errno); + + ret = bind_socket(sock2, ud.second); + zassert_equal(ret, 0, "Cannot bind 2nd socket (%d)", -errno); +} + +void test_main(void) +{ + ztest_test_suite(socket_packet, + ztest_unit_test(test_packet_sockets)); + ztest_run_test_suite(socket_packet); +} diff --git a/tests/net/socket/af_packet/testcase.yaml b/tests/net/socket/af_packet/testcase.yaml new file mode 100644 index 00000000000..0545aa8b725 --- /dev/null +++ b/tests/net/socket/af_packet/testcase.yaml @@ -0,0 +1,6 @@ +common: + depends_on: netif + tags: net socket af_packet +tests: + net.socket.packet: + min_ram: 21