1 /*
2 * Copyright (c) 2021 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_virtual_mgmt, CONFIG_NET_L2_VIRTUAL_LOG_LEVEL);
9
10 #include <errno.h>
11
12 #include <zephyr/net/net_core.h>
13 #include <zephyr/net/net_if.h>
14 #include <zephyr/net/virtual_mgmt.h>
15
virtual_interface_set_config(uint64_t mgmt_request,struct net_if * iface,void * data,size_t len)16 static int virtual_interface_set_config(uint64_t mgmt_request,
17 struct net_if *iface,
18 void *data, size_t len)
19 {
20 struct virtual_interface_req_params *params =
21 (struct virtual_interface_req_params *)data;
22 const struct device *dev = net_if_get_device(iface);
23 const struct virtual_interface_api *api = dev->api;
24 struct virtual_interface_config config = { 0 };
25 enum virtual_interface_config_type type;
26
27 if (!api) {
28 return -ENOENT;
29 }
30
31 if (!api->set_config) {
32 return -ENOTSUP;
33 }
34
35 if (!data || (len != sizeof(struct virtual_interface_req_params))) {
36 return -EINVAL;
37 }
38
39 if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS) {
40 if (net_if_is_up(iface)) {
41 return -EACCES;
42 }
43
44 config.family = params->family;
45 memcpy(&config.peer6addr, ¶ms->peer6addr,
46 sizeof(config.peer6addr));
47 type = VIRTUAL_INTERFACE_CONFIG_TYPE_PEER_ADDRESS;
48
49 } else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU) {
50 if (net_if_is_up(iface)) {
51 return -EACCES;
52 }
53
54 config.family = params->family;
55 config.mtu = params->mtu;
56 type = VIRTUAL_INTERFACE_CONFIG_TYPE_MTU;
57
58 } else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_LINK_TYPE) {
59 /* We can update the link types even if the interface is up */
60 config.family = params->family;
61 memcpy(&config.link_types, ¶ms->link_types,
62 sizeof(config.link_types));
63 type = VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE;
64
65 } else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_PRIVATE_KEY) {
66 if (net_if_is_up(iface)) {
67 return -EACCES;
68 }
69
70 config.private_key.len = params->private_key.len;
71 config.private_key.data = params->private_key.data;
72 type = VIRTUAL_INTERFACE_CONFIG_TYPE_PRIVATE_KEY;
73 } else {
74 return -EINVAL;
75 }
76
77 return api->set_config(iface, type, &config);
78 }
79
80 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
81 virtual_interface_set_config);
82
83 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU,
84 virtual_interface_set_config);
85
86 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_LINK_TYPE,
87 virtual_interface_set_config);
88
89 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_PRIVATE_KEY,
90 virtual_interface_set_config);
91
virtual_interface_get_config(uint64_t mgmt_request,struct net_if * iface,void * data,size_t len)92 static int virtual_interface_get_config(uint64_t mgmt_request,
93 struct net_if *iface,
94 void *data, size_t len)
95 {
96 struct virtual_interface_req_params *params =
97 (struct virtual_interface_req_params *)data;
98 const struct device *dev = net_if_get_device(iface);
99 const struct virtual_interface_api *api = dev->api;
100 struct virtual_interface_config config = { 0 };
101 enum virtual_interface_config_type type;
102 int ret = 0;
103
104 if (!api) {
105 return -ENOENT;
106 }
107
108 if (!api->get_config) {
109 return -ENOTSUP;
110 }
111
112 if (!data || (len != sizeof(struct virtual_interface_req_params))) {
113 return -EINVAL;
114 }
115
116 if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_PEER_ADDRESS) {
117 type = VIRTUAL_INTERFACE_CONFIG_TYPE_PEER_ADDRESS;
118
119 ret = api->get_config(iface, type, &config);
120 if (ret) {
121 return ret;
122 }
123
124 params->family = config.family;
125 memcpy(¶ms->peer6addr, &config.peer6addr,
126 sizeof(params->peer6addr));
127
128 } else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU) {
129 type = VIRTUAL_INTERFACE_CONFIG_TYPE_MTU;
130
131 ret = api->get_config(iface, type, &config);
132 if (ret) {
133 return ret;
134 }
135
136 params->mtu = config.mtu;
137
138 } else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_LINK_TYPE) {
139 type = VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE;
140
141 ret = api->get_config(iface, type, &config);
142 if (ret) {
143 return ret;
144 }
145
146 memcpy(¶ms->link_types, &config.link_types,
147 sizeof(params->link_types));
148
149 } else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_PUBLIC_KEY) {
150 type = VIRTUAL_INTERFACE_CONFIG_TYPE_PUBLIC_KEY;
151
152 ret = api->get_config(iface, type, &config);
153 if (ret) {
154 return ret;
155 }
156
157 params->public_key.len = config.public_key.len;
158 memcpy(¶ms->public_key.data, &config.public_key.data,
159 MIN(sizeof(params->public_key.data),
160 params->public_key.len));
161 } else {
162 return -EINVAL;
163 }
164
165 return ret;
166 }
167
168 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_PEER_ADDRESS,
169 virtual_interface_get_config);
170
171 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU,
172 virtual_interface_get_config);
173
174 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_LINK_TYPE,
175 virtual_interface_get_config);
176
177 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_PUBLIC_KEY,
178 virtual_interface_get_config);
179