From 3d83601661b1bda4c1924c6a7a1bb6cbc639154a Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 13 Sep 2018 15:09:26 +0300 Subject: [PATCH] samples: net: echo_server: Add VLAN support If user enables VLAN support, then the sample application will create two extra VLAN network interfaces for testing purposes. The application can be compiled like this for VLAN support: cmake -DBOARD=qemu_x86 -DOVERLAY_CONFIG=overlay-vlan.conf .. Signed-off-by: Jukka Rissanen --- samples/net/echo_server/CMakeLists.txt | 3 + samples/net/echo_server/Kconfig | 49 +++++++++ samples/net/echo_server/overlay-vlan.conf | 26 +++++ samples/net/echo_server/src/common.h | 9 ++ samples/net/echo_server/src/echo-server.c | 2 + samples/net/echo_server/src/vlan.c | 116 ++++++++++++++++++++++ 6 files changed, 205 insertions(+) create mode 100644 samples/net/echo_server/Kconfig create mode 100644 samples/net/echo_server/overlay-vlan.conf create mode 100644 samples/net/echo_server/src/vlan.c diff --git a/samples/net/echo_server/CMakeLists.txt b/samples/net/echo_server/CMakeLists.txt index ffb4bfdeeb0384..96bb94a671a165 100644 --- a/samples/net/echo_server/CMakeLists.txt +++ b/samples/net/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}/prj_${BOARD}.conf) set(CONF_FILE "${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf") @@ -16,5 +18,6 @@ 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/echo_server/Kconfig b/samples/net/echo_server/Kconfig new file mode 100644 index 00000000000000..1cb9397f6bfefd --- /dev/null +++ b/samples/net/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/echo_server/overlay-vlan.conf b/samples/net/echo_server/overlay-vlan.conf new file mode 100644 index 00000000000000..014523b7fd5cc6 --- /dev/null +++ b/samples/net/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/echo_server/src/common.h b/samples/net/echo_server/src/common.h index 9737d823a6ab44..11276872f96ed1 100644 --- a/samples/net/echo_server/src/common.h +++ b/samples/net/echo_server/src/common.h @@ -22,3 +22,12 @@ void pkt_sent(struct net_app_ctx *ctx, int status, void *token, void *user_data); void panic(const char *msg); 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/echo_server/src/echo-server.c b/samples/net/echo_server/src/echo-server.c index 5755f2817e5ecf..21eb4e1cb3d337 100644 --- a/samples/net/echo_server/src/echo-server.c +++ b/samples/net/echo_server/src/echo-server.c @@ -121,6 +121,8 @@ static inline int init_app(void) { k_sem_init(&quit_lock, 0, UINT_MAX); + init_vlan(); + return 0; } diff --git a/samples/net/echo_server/src/vlan.c b/samples/net/echo_server/src/vlan.c new file mode 100644 index 00000000000000..28e89a2cc90d58 --- /dev/null +++ b/samples/net/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; +}