diff --git a/samples/net/sockets/echo_server/CMakeLists.txt b/samples/net/sockets/echo_server/CMakeLists.txt index 99f1df7be0b..8551eda27c4 100644 --- a/samples/net/sockets/echo_server/CMakeLists.txt +++ b/samples/net/sockets/echo_server/CMakeLists.txt @@ -1,4 +1,6 @@ cmake_minimum_required(VERSION 3.8.2) +set(KCONFIG_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/Kconfig) + macro(set_conf_file) if(EXISTS ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf) set(CONF_FILE "prj.conf ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf") @@ -13,6 +15,7 @@ project(NONE) target_sources( app PRIVATE src/echo-server.c) target_sources_ifdef(CONFIG_NET_UDP app PRIVATE src/udp.c) target_sources_ifdef(CONFIG_NET_TCP app PRIVATE src/tcp.c) +target_sources_ifdef(CONFIG_NET_VLAN app PRIVATE src/vlan.c) include($ENV{ZEPHYR_BASE}/samples/net/common/common.cmake) diff --git a/samples/net/sockets/echo_server/Kconfig b/samples/net/sockets/echo_server/Kconfig new file mode 100644 index 00000000000..1cb9397f6bf --- /dev/null +++ b/samples/net/sockets/echo_server/Kconfig @@ -0,0 +1,49 @@ +# Kconfig - Private config options for echo-server sample app + +# +# Copyright (c) 2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +mainmenu "Networking echo-server sample application" + +config NET_SAMPLE_IFACE2_MY_IPV6_ADDR + string "My IPv6 address for second interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE2_MY_IPV4_ADDR + string "My IPv4 address for second interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE2_VLAN_TAG + int "VLAN tag for second interface" + default 100 + range 0 4094 + depends on NET_VLAN + help + Set VLAN (virtual LAN) tag (id) that is used in the sample + application. + +config NET_SAMPLE_IFACE3_MY_IPV6_ADDR + string "My IPv6 address for third interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE3_MY_IPV4_ADDR + string "My IPv4 address for third interface" + help + The value depends on your network setup. + +config NET_SAMPLE_IFACE3_VLAN_TAG + int "VLAN tag for third interface" + default 200 + range 0 4094 + depends on NET_VLAN + help + Set VLAN (virtual LAN) tag (id) that is used in the sample + application. + +source "$(ZEPHYR_BASE)/Kconfig.zephyr" diff --git a/samples/net/sockets/echo_server/overlay-vlan.conf b/samples/net/sockets/echo_server/overlay-vlan.conf new file mode 100644 index 00000000000..014523b7fd5 --- /dev/null +++ b/samples/net/sockets/echo_server/overlay-vlan.conf @@ -0,0 +1,26 @@ +CONFIG_NET_VLAN=y + +# We have one non-vlan interface and two VLAN interfaces +CONFIG_NET_VLAN_COUNT=3 + +# There will be three network interfaces. + +# First ethernet interface will use these settings +CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" +CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" + +# Second ethernet interface will have these settings +CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR="2001:db8:100::1" +# TEST-NET-2 from RFC 5737 +CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR="198.51.100.1" +# VLAN tag for the second interface +CONFIG_NET_SAMPLE_IFACE2_VLAN_TAG=100 + +# Settings for the third network interface +CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR="2001:db8:200::1" +# TEST-NET-3 from RFC 5737 +CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR="203.0.113.1" +# VLAN tag for the second interface +CONFIG_NET_SAMPLE_IFACE3_VLAN_TAG=200 diff --git a/samples/net/sockets/echo_server/src/common.h b/samples/net/sockets/echo_server/src/common.h index 5def7acf7ba..c3fdcde9851 100644 --- a/samples/net/sockets/echo_server/src/common.h +++ b/samples/net/sockets/echo_server/src/common.h @@ -45,3 +45,12 @@ void start_tcp(void); void stop_tcp(void); void quit(void); + +#if defined(CONFIG_NET_VLAN) +int init_vlan(void); +#else +static inline int init_vlan(void) +{ + return 0; +} +#endif /* CONFIG_NET_VLAN */ diff --git a/samples/net/sockets/echo_server/src/echo-server.c b/samples/net/sockets/echo_server/src/echo-server.c index 9a3db61a806..df963f150c4 100644 --- a/samples/net/sockets/echo_server/src/echo-server.c +++ b/samples/net/sockets/echo_server/src/echo-server.c @@ -64,6 +64,8 @@ static void init_app(void) NET_ERR("Failed to register private key: %d", err); } #endif + + init_vlan(); } void main(void) diff --git a/samples/net/sockets/echo_server/src/vlan.c b/samples/net/sockets/echo_server/src/vlan.c new file mode 100644 index 00000000000..28e89a2cc90 --- /dev/null +++ b/samples/net/sockets/echo_server/src/vlan.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2018 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define SYS_LOG_DOMAIN "echo-server" +#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG +#define NET_LOG_ENABLED 1 + +#include + +#include + +/* User data for the interface callback */ +struct ud { + struct net_if *first; + struct net_if *second; + struct net_if *third; +}; + +static void iface_cb(struct net_if *iface, void *user_data) +{ + struct ud *ud = user_data; + + if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { + return; + } + + if (!ud->first) { + ud->first = iface; + return; + } + + if (!ud->second) { + ud->second = iface; + return; + } + + if (!ud->third) { + ud->third = iface; + return; + } +} + +static int setup_iface(struct net_if *iface, const char *ipv6_addr, + const char *ipv4_addr, u16_t vlan_tag) +{ + struct net_if_addr *ifaddr; + struct in_addr addr4; + struct in6_addr addr6; + int ret; + + ret = net_eth_vlan_enable(iface, vlan_tag); + if (ret < 0) { + NET_ERR("Cannot enable VLAN for tag %d (%d)", vlan_tag, ret); + } + + if (net_addr_pton(AF_INET6, ipv6_addr, &addr6)) { + NET_ERR("Invalid address: %s", ipv6_addr); + return -EINVAL; + } + + ifaddr = net_if_ipv6_addr_add(iface, &addr6, NET_ADDR_MANUAL, 0); + if (!ifaddr) { + NET_ERR("Cannot add %s to interface %p", ipv6_addr, iface); + return -EINVAL; + } + + if (net_addr_pton(AF_INET, ipv4_addr, &addr4)) { + NET_ERR("Invalid address: %s", ipv6_addr); + return -EINVAL; + } + + ifaddr = net_if_ipv4_addr_add(iface, &addr4, NET_ADDR_MANUAL, 0); + if (!ifaddr) { + NET_ERR("Cannot add %s to interface %p", ipv4_addr, iface); + return -EINVAL; + } + + NET_DBG("Interface %p VLAN tag %d setup done.", iface, vlan_tag); + + return 0; +} + +int init_vlan(void) +{ + struct ud ud; + int ret; + + memset(&ud, 0, sizeof(ud)); + + net_if_foreach(iface_cb, &ud); + + /* This sample has two VLANs. For the second one we need to manually + * create IP address for this test. But first the VLAN needs to be + * added to the interface so that IPv6 DAD can work properly. + */ + ret = setup_iface(ud.second, + CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR, + CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR, + CONFIG_NET_SAMPLE_IFACE2_VLAN_TAG); + if (ret < 0) { + return ret; + } + + ret = setup_iface(ud.third, + CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR, + CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR, + CONFIG_NET_SAMPLE_IFACE3_VLAN_TAG); + if (ret < 0) { + return ret; + } + + return 0; +}