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