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