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