1 /*
2 * Copyright (c) 2020 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(net_txtime_sample, LOG_LEVEL_DBG);
9
10 #include <zephyr/kernel.h>
11
12 #include <zephyr/net/ethernet.h>
13
14 /* User data for the interface callback */
15 struct ud {
16 struct net_if *first;
17 struct net_if *second;
18 };
19
iface_cb(struct net_if * iface,void * user_data)20 static void iface_cb(struct net_if *iface, void *user_data)
21 {
22 struct ud *ud = user_data;
23
24 if (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL)) {
25 return;
26 }
27
28 if (!ud->first) {
29 ud->first = iface;
30 return;
31 }
32
33 if (!ud->second) {
34 ud->second = iface;
35 return;
36 }
37 }
38
setup_iface(struct net_if * eth_iface,struct net_if * iface,const char * ipv6_addr,const char * ipv4_addr,uint16_t vlan_tag)39 static int setup_iface(struct net_if *eth_iface,
40 struct net_if *iface,
41 const char *ipv6_addr,
42 const char *ipv4_addr,
43 uint16_t vlan_tag)
44 {
45 struct net_if_addr *ifaddr;
46 struct in_addr addr4;
47 struct in6_addr addr6;
48 int ret;
49
50 if (!iface) {
51 LOG_DBG("VLAN interface not set");
52 return -ENOENT;
53 }
54
55 ret = net_eth_vlan_enable(eth_iface, vlan_tag);
56 if (ret < 0) {
57 LOG_ERR("Cannot enable VLAN for tag %d (%d)", vlan_tag, ret);
58 }
59
60 if (IS_ENABLED(CONFIG_NET_IPV6)) {
61 if (net_addr_pton(AF_INET6, ipv6_addr, &addr6)) {
62 LOG_ERR("Invalid address: %s", ipv6_addr);
63 return -EINVAL;
64 }
65
66 ifaddr = net_if_ipv6_addr_add(iface, &addr6,
67 NET_ADDR_MANUAL, 0);
68 if (!ifaddr) {
69 LOG_ERR("Cannot add %s to interface %p",
70 ipv6_addr, iface);
71 return -EINVAL;
72 }
73 }
74
75 if (IS_ENABLED(CONFIG_NET_IPV4)) {
76 if (net_addr_pton(AF_INET, ipv4_addr, &addr4)) {
77 LOG_ERR("Invalid address: %s", ipv6_addr);
78 return -EINVAL;
79 }
80
81 ifaddr = net_if_ipv4_addr_add(iface, &addr4,
82 NET_ADDR_MANUAL, 0);
83 if (!ifaddr) {
84 LOG_ERR("Cannot add %s to interface %p",
85 ipv4_addr, iface);
86 return -EINVAL;
87 }
88 }
89
90 LOG_DBG("Interface %p VLAN tag %d setup done.", iface, vlan_tag);
91
92 return 0;
93 }
94
init_vlan(void)95 int init_vlan(void)
96 {
97 struct net_if *iface;
98 enum ethernet_hw_caps caps;
99 struct ud ud;
100 int ret;
101
102 iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET));
103 if (!iface) {
104 LOG_ERR("No ethernet interfaces found.");
105 return -ENOENT;
106 }
107
108 memset(&ud, 0, sizeof(ud));
109
110 net_if_foreach(iface_cb, &ud);
111
112 caps = net_eth_get_hw_capabilities(iface);
113 if (!(caps & ETHERNET_HW_VLAN)) {
114 LOG_DBG("Interface %p does not support %s", iface, "VLAN");
115 return -ENOENT;
116 }
117
118 ret = setup_iface(iface, ud.first,
119 CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR,
120 CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR,
121 CONFIG_NET_SAMPLE_IFACE2_VLAN_TAG);
122 if (ret < 0) {
123 return ret;
124 }
125
126 ret = setup_iface(iface, ud.second,
127 CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR,
128 CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR,
129 CONFIG_NET_SAMPLE_IFACE3_VLAN_TAG);
130 if (ret < 0) {
131 return ret;
132 }
133
134 /* Bring up the VLAN interface automatically */
135 net_if_up(ud.first);
136 net_if_up(ud.second);
137
138 return 0;
139 }
140