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(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)16 static int virtual_interface_set_config(uint32_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, &params->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, &params->link_types,
62 		       sizeof(config.link_types));
63 		type = VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE;
64 	} else {
65 		return -EINVAL;
66 	}
67 
68 	return api->set_config(iface, type, &config);
69 }
70 
71 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
72 				  virtual_interface_set_config);
73 
74 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU,
75 				  virtual_interface_set_config);
76 
77 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_LINK_TYPE,
78 				  virtual_interface_set_config);
79 
virtual_interface_get_config(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)80 static int virtual_interface_get_config(uint32_t mgmt_request,
81 					struct net_if *iface,
82 					void *data, size_t len)
83 {
84 	struct virtual_interface_req_params *params =
85 				(struct virtual_interface_req_params *)data;
86 	const struct device *dev = net_if_get_device(iface);
87 	const struct virtual_interface_api *api = dev->api;
88 	struct virtual_interface_config config = { 0 };
89 	enum virtual_interface_config_type type;
90 	int ret = 0;
91 
92 	if (!api) {
93 		return -ENOENT;
94 	}
95 
96 	if (!api->get_config) {
97 		return -ENOTSUP;
98 	}
99 
100 	if (!data || (len != sizeof(struct virtual_interface_req_params))) {
101 		return -EINVAL;
102 	}
103 
104 	if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_PEER_ADDRESS) {
105 		type = VIRTUAL_INTERFACE_CONFIG_TYPE_PEER_ADDRESS;
106 
107 		ret = api->get_config(iface, type, &config);
108 		if (ret) {
109 			return ret;
110 		}
111 
112 		params->family = config.family;
113 		memcpy(&params->peer6addr, &config.peer6addr,
114 		       sizeof(params->peer6addr));
115 
116 	} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU) {
117 		type = VIRTUAL_INTERFACE_CONFIG_TYPE_MTU;
118 
119 		ret = api->get_config(iface, type, &config);
120 		if (ret) {
121 			return ret;
122 		}
123 
124 		params->mtu = config.mtu;
125 
126 	} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_LINK_TYPE) {
127 		type = VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE;
128 
129 		ret = api->get_config(iface, type, &config);
130 		if (ret) {
131 			return ret;
132 		}
133 
134 		memcpy(&params->link_types, &config.link_types,
135 		       sizeof(params->link_types));
136 	} else {
137 		return -EINVAL;
138 	}
139 
140 	return ret;
141 }
142 
143 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_PEER_ADDRESS,
144 				  virtual_interface_get_config);
145 
146 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU,
147 				  virtual_interface_get_config);
148 
149 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_LINK_TYPE,
150 				  virtual_interface_get_config);
151