/* * Copyright (c) 2018 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include LOG_MODULE_DECLARE(net_echo_server_sample, LOG_LEVEL_DBG); #include #include /* User data for the interface callback */ struct ud { struct net_if *first; struct net_if *second; struct net_if *eth; }; 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) && ud->eth == NULL) { ud->eth = iface; return; } if (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL)) { return; } if (!ud->first) { ud->first = iface; return; } if (!ud->second) { ud->second = iface; return; } } static int setup_iface(struct net_if *iface, struct net_if *vlan, const char *ipv6_addr, const char *ipv4_addr, const char *netmask, uint16_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) { LOG_ERR("Cannot enable VLAN for tag %d (%d)", vlan_tag, ret); } if (IS_ENABLED(CONFIG_NET_IPV6)) { if (net_addr_pton(AF_INET6, ipv6_addr, &addr6)) { LOG_ERR("Invalid address: %s", ipv6_addr); return -EINVAL; } ifaddr = net_if_ipv6_addr_add(vlan, &addr6, NET_ADDR_MANUAL, 0); if (!ifaddr) { LOG_ERR("Cannot add %s to interface %p", ipv6_addr, vlan); return -EINVAL; } } if (IS_ENABLED(CONFIG_NET_IPV4)) { if (net_addr_pton(AF_INET, ipv4_addr, &addr4)) { LOG_ERR("Invalid address: %s", ipv4_addr); return -EINVAL; } ifaddr = net_if_ipv4_addr_add(vlan, &addr4, NET_ADDR_MANUAL, 0); if (!ifaddr) { LOG_ERR("Cannot add %s to interface %p", ipv4_addr, vlan); return -EINVAL; } if (netmask && netmask[0]) { struct in_addr nm; if (net_addr_pton(AF_INET, netmask, &nm)) { LOG_ERR("Invalid netmask: %s", ipv4_addr); return -EINVAL; } net_if_ipv4_set_netmask_by_addr(vlan, &addr4, &nm); } } LOG_DBG("Interface %p VLAN tag %d setup done.", vlan, 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.eth, ud.first, CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR, CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR, CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_NETMASK, CONFIG_NET_SAMPLE_IFACE2_VLAN_TAG); if (ret < 0) { return ret; } ret = setup_iface(ud.eth, ud.second, CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR, CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR, CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_NETMASK, CONFIG_NET_SAMPLE_IFACE3_VLAN_TAG); if (ret < 0) { return ret; } return 0; }