1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Network Management API public header
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_NET_NET_MGMT_H_
13 #define ZEPHYR_INCLUDE_NET_NET_MGMT_H_
14 
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/net/net_core.h>
17 #include <zephyr/net/net_event.h>
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 /**
24  * @brief Network Management
25  * @defgroup net_mgmt Network Management
26  * @ingroup networking
27  * @{
28  */
29 
30 struct net_if;
31 
32 /** @cond INTERNAL_HIDDEN */
33 /**
34  * @brief NET MGMT event mask basics, normalizing parts of bit fields
35  */
36 #define NET_MGMT_EVENT_MASK		0x80000000
37 #define NET_MGMT_ON_IFACE_MASK		0x40000000
38 #define NET_MGMT_LAYER_MASK		0x30000000
39 #define NET_MGMT_SYNC_EVENT_MASK	0x08000000
40 #define NET_MGMT_LAYER_CODE_MASK	0x07FF0000
41 #define NET_MGMT_COMMAND_MASK		0x0000FFFF
42 
43 #define NET_MGMT_EVENT_BIT		BIT(31)
44 #define NET_MGMT_IFACE_BIT		BIT(30)
45 #define NET_MGMT_SYNC_EVENT_BIT		BIT(27)
46 
47 #define NET_MGMT_LAYER(_layer)		(_layer << 28)
48 #define NET_MGMT_LAYER_CODE(_code)	(_code << 16)
49 
50 #define NET_MGMT_EVENT(mgmt_request)		\
51 	(mgmt_request & NET_MGMT_EVENT_MASK)
52 
53 #define NET_MGMT_ON_IFACE(mgmt_request)		\
54 	(mgmt_request & NET_MGMT_ON_IFACE_MASK)
55 
56 #define NET_MGMT_EVENT_SYNCHRONOUS(mgmt_request)	\
57 	(mgmt_request & NET_MGMT_SYNC_EVENT_MASK)
58 
59 #define NET_MGMT_GET_LAYER(mgmt_request)	\
60 	((mgmt_request & NET_MGMT_LAYER_MASK) >> 28)
61 
62 #define NET_MGMT_GET_LAYER_CODE(mgmt_request)	\
63 	((mgmt_request & NET_MGMT_LAYER_CODE_MASK) >> 16)
64 
65 #define NET_MGMT_GET_COMMAND(mgmt_request)	\
66 	(mgmt_request & NET_MGMT_COMMAND_MASK)
67 
68 
69 /* Useful generic definitions */
70 #define NET_MGMT_LAYER_L2		1
71 #define NET_MGMT_LAYER_L3		2
72 #define NET_MGMT_LAYER_L4		3
73 
74 /** @endcond */
75 
76 
77 /**
78  * @typedef net_mgmt_request_handler_t
79  * @brief Signature which all Net MGMT request handler need to follow
80  * @param mgmt_request The exact request value the handler is being called
81  *        through
82  * @param iface A valid pointer on struct net_if if the request is meant
83  *        to be tight to a network interface. NULL otherwise.
84  * @param data A valid pointer on a data understood by the handler.
85  *        NULL otherwise.
86  * @param len Length in byte of the memory pointed by data.
87  */
88 typedef int (*net_mgmt_request_handler_t)(uint32_t mgmt_request,
89 					  struct net_if *iface,
90 					  void *data, size_t len);
91 
92 #define net_mgmt(_mgmt_request, _iface, _data, _len)			\
93 	net_mgmt_##_mgmt_request(_mgmt_request, _iface, _data, _len)
94 
95 #define NET_MGMT_DEFINE_REQUEST_HANDLER(_mgmt_request)			\
96 	extern int net_mgmt_##_mgmt_request(uint32_t mgmt_request,	\
97 					    struct net_if *iface,	\
98 					    void *data, size_t len)
99 
100 #define NET_MGMT_REGISTER_REQUEST_HANDLER(_mgmt_request, _func)	\
101 	FUNC_ALIAS(_func, net_mgmt_##_mgmt_request, int)
102 
103 struct net_mgmt_event_callback;
104 
105 /**
106  * @typedef net_mgmt_event_handler_t
107  * @brief Define the user's callback handler function signature
108  * @param cb Original struct net_mgmt_event_callback owning this handler.
109  * @param mgmt_event The network event being notified.
110  * @param iface A pointer on a struct net_if to which the the event belongs to,
111  *        if it's an event on an iface. NULL otherwise.
112  */
113 typedef void (*net_mgmt_event_handler_t)(struct net_mgmt_event_callback *cb,
114 					 uint32_t mgmt_event,
115 					 struct net_if *iface);
116 
117 /**
118  * @brief Network Management event callback structure
119  * Used to register a callback into the network management event part, in order
120  * to let the owner of this struct to get network event notification based on
121  * given event mask.
122  */
123 struct net_mgmt_event_callback {
124 	/** Meant to be used internally, to insert the callback into a list.
125 	 * So nobody should mess with it.
126 	 */
127 	sys_snode_t node;
128 
129 	union {
130 		/** Actual callback function being used to notify the owner
131 		 */
132 		net_mgmt_event_handler_t handler;
133 		/** Semaphore meant to be used internally for the synchronous
134 		 * net_mgmt_event_wait() function.
135 		 */
136 		struct k_sem *sync_call;
137 	};
138 
139 #ifdef CONFIG_NET_MGMT_EVENT_INFO
140 	const void *info;
141 	size_t info_length;
142 #endif
143 
144 	/** A mask of network events on which the above handler should be
145 	 * called in case those events come. Such mask can be modified
146 	 * whenever necessary by the owner, and thus will affect the handler
147 	 * being called or not.
148 	 */
149 	union {
150 		/** A mask of network events on which the above handler should
151 		 * be called in case those events come.
152 		 * Note that only the command part is treated as a mask,
153 		 * matching one to several commands. Layer and layer code will
154 		 * be made of an exact match. This means that in order to
155 		 * receive events from multiple layers, one must have multiple
156 		 * listeners registered, one for each layer being listened.
157 		 */
158 		uint32_t event_mask;
159 		/** Internal place holder when a synchronous event wait is
160 		 * successfully unlocked on a event.
161 		 */
162 		uint32_t raised_event;
163 	};
164 };
165 
166 /**
167  * @brief Helper to initialize a struct net_mgmt_event_callback properly
168  * @param cb A valid application's callback structure pointer.
169  * @param handler A valid handler function pointer.
170  * @param mgmt_event_mask A mask of relevant events for the handler
171  */
172 #ifdef CONFIG_NET_MGMT_EVENT
173 static inline
net_mgmt_init_event_callback(struct net_mgmt_event_callback * cb,net_mgmt_event_handler_t handler,uint32_t mgmt_event_mask)174 void net_mgmt_init_event_callback(struct net_mgmt_event_callback *cb,
175 				  net_mgmt_event_handler_t handler,
176 				  uint32_t mgmt_event_mask)
177 {
178 	__ASSERT(cb, "Callback pointer should not be NULL");
179 	__ASSERT(handler, "Handler pointer should not be NULL");
180 
181 	cb->handler = handler;
182 	cb->event_mask = mgmt_event_mask;
183 };
184 #else
185 #define net_mgmt_init_event_callback(...)
186 #endif
187 
188 /**
189  * @brief Add a user callback
190  * @param cb A valid pointer on user's callback to add.
191  */
192 #ifdef CONFIG_NET_MGMT_EVENT
193 void net_mgmt_add_event_callback(struct net_mgmt_event_callback *cb);
194 #else
195 #define net_mgmt_add_event_callback(...)
196 #endif
197 
198 /**
199  * @brief Delete a user callback
200  * @param cb A valid pointer on user's callback to delete.
201  */
202 #ifdef CONFIG_NET_MGMT_EVENT
203 void net_mgmt_del_event_callback(struct net_mgmt_event_callback *cb);
204 #else
205 #define net_mgmt_del_event_callback(...)
206 #endif
207 
208 /**
209  * @brief Used by the system to notify an event.
210  * @param mgmt_event The actual network event code to notify
211  * @param iface a valid pointer on a struct net_if if only the event is
212  *        based on an iface. NULL otherwise.
213  * @param info a valid pointer on the information you want to pass along
214  *        with the event. NULL otherwise. Note the data pointed there is
215  *        normalized by the related event.
216  * @param length size of the data pointed by info pointer.
217  *
218  * Note: info and length are disabled if CONFIG_NET_MGMT_EVENT_INFO
219  *       is not defined.
220  */
221 #ifdef CONFIG_NET_MGMT_EVENT
222 void net_mgmt_event_notify_with_info(uint32_t mgmt_event, struct net_if *iface,
223 				     const void *info, size_t length);
224 
net_mgmt_event_notify(uint32_t mgmt_event,struct net_if * iface)225 static inline void net_mgmt_event_notify(uint32_t mgmt_event,
226 					 struct net_if *iface)
227 {
228 	net_mgmt_event_notify_with_info(mgmt_event, iface, NULL, 0);
229 }
230 #else
231 #define net_mgmt_event_notify(...)
232 #define net_mgmt_event_notify_with_info(...)
233 #endif
234 
235 /**
236  * @brief Used to wait synchronously on an event mask
237  * @param mgmt_event_mask A mask of relevant events to wait on.
238  * @param raised_event a pointer on a uint32_t to get which event from
239  *        the mask generated the event. Can be NULL if the caller is not
240  *        interested in that information.
241  * @param iface a pointer on a place holder for the iface on which the
242  *        event has originated from. This is valid if only the event mask
243  *        has bit NET_MGMT_IFACE_BIT set relevantly, depending on events
244  *        the caller wants to listen to.
245  * @param info a valid pointer if user wants to get the information the
246  *        event might bring along. NULL otherwise.
247  * @param info_length tells how long the info memory area is. Only valid if
248  *        the info is not NULL.
249  * @param timeout A timeout delay. K_FOREVER can be used to wait indefinitely.
250  *
251  * @return 0 on success, a negative error code otherwise. -ETIMEDOUT will
252  *         be specifically returned if the timeout kick-in instead of an
253  *         actual event.
254  */
255 #ifdef CONFIG_NET_MGMT_EVENT
256 int net_mgmt_event_wait(uint32_t mgmt_event_mask,
257 			uint32_t *raised_event,
258 			struct net_if **iface,
259 			const void **info,
260 			size_t *info_length,
261 			k_timeout_t timeout);
262 #else
net_mgmt_event_wait(uint32_t mgmt_event_mask,uint32_t * raised_event,struct net_if ** iface,const void ** info,size_t * info_length,k_timeout_t timeout)263 static inline int net_mgmt_event_wait(uint32_t mgmt_event_mask,
264 				      uint32_t *raised_event,
265 				      struct net_if **iface,
266 				      const void **info,
267 				      size_t *info_length,
268 				      k_timeout_t timeout)
269 {
270 	return 0;
271 }
272 #endif
273 
274 /**
275  * @brief Used to wait synchronously on an event mask for a specific iface
276  * @param iface a pointer on a valid network interface to listen event to
277  * @param mgmt_event_mask A mask of relevant events to wait on. Listened
278  *        to events should be relevant to iface events and thus have the bit
279  *        NET_MGMT_IFACE_BIT set.
280  * @param raised_event a pointer on a uint32_t to get which event from
281  *        the mask generated the event. Can be NULL if the caller is not
282  *        interested in that information.
283  * @param info a valid pointer if user wants to get the information the
284  *        event might bring along. NULL otherwise.
285  * @param info_length tells how long the info memory area is. Only valid if
286  *        the info is not NULL.
287  * @param timeout A timeout delay. K_FOREVER can be used to wait indefinitely.
288  *
289  * @return 0 on success, a negative error code otherwise. -ETIMEDOUT will
290  *         be specifically returned if the timeout kick-in instead of an
291  *         actual event.
292  */
293 #ifdef CONFIG_NET_MGMT_EVENT
294 int net_mgmt_event_wait_on_iface(struct net_if *iface,
295 				 uint32_t mgmt_event_mask,
296 				 uint32_t *raised_event,
297 				 const void **info,
298 				 size_t *info_length,
299 				 k_timeout_t timeout);
300 #else
net_mgmt_event_wait_on_iface(struct net_if * iface,uint32_t mgmt_event_mask,uint32_t * raised_event,const void ** info,size_t * info_length,k_timeout_t timeout)301 static inline int net_mgmt_event_wait_on_iface(struct net_if *iface,
302 					       uint32_t mgmt_event_mask,
303 					       uint32_t *raised_event,
304 					       const void **info,
305 					       size_t *info_length,
306 					       k_timeout_t timeout)
307 {
308 	return 0;
309 }
310 #endif
311 
312 /**
313  * @brief Used by the core of the network stack to initialize the network
314  *        event processing.
315  */
316 #ifdef CONFIG_NET_MGMT_EVENT
317 void net_mgmt_event_init(void);
318 #else
319 #define net_mgmt_event_init(...)
320 #endif /* CONFIG_NET_MGMT_EVENT */
321 
322 /**
323  * @}
324  */
325 
326 #ifdef __cplusplus
327 }
328 #endif
329 
330 #endif /* ZEPHYR_INCLUDE_NET_NET_MGMT_H_ */
331