1 /******************************************************************************
2 
3 			  L I B R M N E T C T L . H
4 
5 Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10 	* Redistributions of source code must retain the above copyright
11 	  notice, this list of conditions and the following disclaimer.
12 	* Redistributions in binary form must reproduce the above
13 	  copyright notice, this list of conditions and the following
14 	  disclaimer in the documentation and/or other materials provided
15 	  with the distribution.
16 	* Neither the name of The Linux Foundation nor the names of its
17 	  contributors may be used to endorse or promote products derived
18 	  from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 
32 ******************************************************************************/
33 
34 /*!
35 *  @file    librmnetctl.h
36 *  @brief   rmnet control API's header file
37 */
38 
39 #ifndef LIBRMNETCTL_H
40 #define LIBRMNETCTL_H
41 
42 /* RMNET API succeeded */
43 #define RMNETCTL_SUCCESS 0
44 /* RMNET API encountered an error while executing within the library. Check the
45 * error code in this case */
46 #define RMNETCTL_LIB_ERR 1
47 /* RMNET API encountered an error while executing in the kernel. Check the
48 * error code in this case */
49 #define RMNETCTL_KERNEL_ERR 2
50 /* RMNET API encountered an error because of invalid arguments*/
51 #define RMNETCTL_INVALID_ARG 3
52 
53 /* Flag to associate a network device*/
54 #define RMNETCTL_DEVICE_ASSOCIATE 1
55 /* Flag to unassociate a network device*/
56 #define RMNETCTL_DEVICE_UNASSOCIATE 0
57 /* Flag to create a new virtual network device*/
58 #define RMNETCTL_NEW_VND 1
59 /* Flag to free a new virtual network device*/
60 #define RMNETCTL_FREE_VND 0
61 /* Flag to add a new flow*/
62 #define RMNETCTL_ADD_FLOW 1
63 /* Flag to delete an existing flow*/
64 #define RMNETCTL_DEL_FLOW 0
65 
66 enum rmnetctl_error_codes_e {
67 	/* API succeeded. This should always be the first element. */
68 	RMNETCTL_API_SUCCESS,
69 
70 	RMNETCTL_API_FIRST_ERR,
71 	/* API failed because not enough memory to create buffer to send
72 	 * message */
73 	RMNETCTL_API_ERR_REQUEST_INVALID = RMNETCTL_API_FIRST_ERR,
74 	/* API failed because not enough memory to create buffer for the
75 	 *  response message */
76 	RMNETCTL_API_ERR_RESPONSE_INVALID,
77 	/* API failed because could not send the message to kernel */
78 	RMNETCTL_API_ERR_MESSAGE_SEND,
79 	/* API failed because could not receive message from the kernel */
80 	RMNETCTL_API_ERR_MESSAGE_RECEIVE,
81 
82 	RMNETCTL_INIT_FIRST_ERR,
83 	/* Invalid process id. So return an error. */
84 	RMNETCTL_INIT_ERR_PROCESS_ID = RMNETCTL_INIT_FIRST_ERR,
85 	/* Invalid socket descriptor id. So return an error. */
86 	RMNETCTL_INIT_ERR_NETLINK_FD,
87 	/* Could not bind the socket to the Netlink file descriptor */
88 	RMNETCTL_INIT_ERR_BIND,
89 	/* Invalid user id. Only root has access to this function. (NA) */
90 	RMNETCTL_INIT_ERR_INVALID_USER,
91 
92 	RMNETCTL_API_SECOND_ERR,
93 	/* API failed because the RmNet handle for the transaction was NULL */
94 	RMNETCTL_API_ERR_HNDL_INVALID = RMNETCTL_API_SECOND_ERR,
95 	/* API failed because the request buffer for the transaction was NULL */
96 	RMNETCTL_API_ERR_REQUEST_NULL,
97 	/* API failed because the response buffer for the transaction was NULL*/
98 	RMNETCTL_API_ERR_RESPONSE_NULL,
99 	/* API failed because the request and response type do not match*/
100 	RMNETCTL_API_ERR_MESSAGE_TYPE,
101 	/* API failed because the return type is invalid */
102 	RMNETCTL_API_ERR_RETURN_TYPE,
103 	/* API failed because the string was truncated */
104 	RMNETCTL_API_ERR_STRING_TRUNCATION,
105 
106 	/* These error are 1-to-1 with rmnet_data config errors in rmnet_data.h
107 	   for each conversion.
108 	   please keep the enums synced.
109 	*/
110 	RMNETCTL_KERNEL_FIRST_ERR,
111 	/* No error */
112 	RMNETCTL_KERNEL_ERROR_NO_ERR = RMNETCTL_KERNEL_FIRST_ERR,
113 	/* Invalid / unsupported message */
114 	RMNETCTL_KERNEL_ERR_UNKNOWN_MESSAGE,
115 	/* Internal problem in the kernel modeule */
116 	RMNETCTL_KERNEL_ERR_INTERNAL,
117 	/* Kernel is temporarely out of memory */
118 	RMNETCTL_KERNEL_ERR_OUT_OF_MEM,
119 	/* Device already exists / Still in use */
120 	RMETNCTL_KERNEL_ERR_DEVICE_IN_USE,
121 	/* Invalid request / Unsupported scenario */
122 	RMNETCTL_KERNEL_ERR_INVALID_REQUEST,
123 	/* Device doesn't exist */
124 	RMNETCTL_KERNEL_ERR_NO_SUCH_DEVICE,
125 	/* One or more of the arguments is invalid */
126 	RMNETCTL_KERNEL_ERR_BAD_ARGS,
127 	/* Egress device is invalid */
128 	RMNETCTL_KERNEL_ERR_BAD_EGRESS_DEVICE,
129 	/* TC handle is full */
130 	RMNETCTL_KERNEL_ERR_TC_HANDLE_FULL,
131 
132 	/* This should always be the last element */
133 	RMNETCTL_API_ERR_ENUM_LENGTH
134 };
135 
136 #define RMNETCTL_ERR_MSG_SIZE 100
137 
138 /*!
139 * @brief Contains a list of error message from API
140 */
141 char rmnetctl_error_code_text
142 [RMNETCTL_API_ERR_ENUM_LENGTH][RMNETCTL_ERR_MSG_SIZE] = {
143 	"ERROR: API succeeded\n",
144 	"ERROR: Unable to allocate the buffer to send message\n",
145 	"ERROR: Unable to allocate the buffer to receive message\n",
146 	"ERROR: Could not send the message to kernel\n",
147 	"ERROR: Unable to receive message from the kernel\n",
148 	"ERROR: Invalid process id\n",
149 	"ERROR: Invalid socket descriptor id\n",
150 	"ERROR: Could not bind to netlink socket\n",
151 	"ERROR: Only root can access this API\n",
152 	"ERROR: RmNet handle for the transaction was NULL\n",
153 	"ERROR: Request buffer for the transaction was NULL\n",
154 	"ERROR: Response buffer for the transaction was NULL\n",
155 	"ERROR: Request and response type do not match\n",
156 	"ERROR: Return type is invalid\n",
157 	"ERROR: String was truncated\n",
158 	/* Kernel errors */
159 	"ERROR: Kernel call succeeded\n",
160 	"ERROR: Invalid / Unsupported directive\n",
161 	"ERROR: Internal problem in the kernel module\n",
162 	"ERROR: The kernel is temporarely out of memory\n",
163 	"ERROR: Device already exists / Still in use\n",
164 	"ERROR: Invalid request / Unsupported scenario\n",
165 	"ERROR: Device doesn't exist\n",
166 	"ERROR: One or more of the arguments is invalid\n",
167 	"ERROR: Egress device is invalid\n",
168 	"ERROR: TC handle is full\n"
169 };
170 
171 /*===========================================================================
172 			 DEFINITIONS AND DECLARATIONS
173 ===========================================================================*/
174 typedef struct rmnetctl_hndl_s rmnetctl_hndl_t;
175 
176 /*!
177 * @brief Public API to initialize the RMNET control driver
178 * @details Allocates memory for the RmNet handle. Creates and binds to a   and
179 * netlink socket if successful
180 * @param **rmnetctl_hndl_t_val RmNet handle to be initialized
181 * @return RMNETCTL_SUCCESS if successful
182 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
183 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
184 * Check error_code
185 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
186 */
187 int rmnetctl_init(rmnetctl_hndl_t **hndl, uint16_t *error_code);
188 
189 /*!
190 * @brief Public API to clean up the RmNeT control handle
191 * @details Close the socket and free the RmNet handle
192 * @param *rmnetctl_hndl_t_val RmNet handle to be initialized
193 * @return void
194 */
195 void rmnetctl_cleanup(rmnetctl_hndl_t *hndl);
196 
197 /*!
198 * @brief Public API to register/unregister a RMNET driver on a particular device
199 * @details Message type is RMNET_NETLINK_ASSOCIATE_NETWORK_DEVICE or
200 * RMNET_NETLINK_UNASSOCIATE_NETWORK_DEVICE based on the flag for assoc_dev
201 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
202 * @param dev_name Device on which to register the RmNet driver
203 * @param error_code Status code of this operation
204 * @param assoc_dev registers the device if RMNETCTL_DEVICE_ASSOCIATE or
205 * unregisters the device if RMNETCTL_DEVICE_UNASSOCIATE
206 * @return RMNETCTL_SUCCESS if successful
207 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
208 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
209 * Check error_code
210 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
211 */
212 int rmnet_associate_network_device(rmnetctl_hndl_t *hndl,
213 				   const char *dev_name,
214 				   uint16_t *error_code,
215 				   uint8_t assoc_dev);
216 
217 /*!
218 * @brief Public API to get if a RMNET driver is registered on a particular
219 * device
220 * @details Message type is RMNET_NETLINK_GET_NETWORK_DEVICE_ASSOCIATED.
221 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
222 * @param dev_name Device on which to check if the RmNet driver is registered
223 * @param register_status 1 if RmNet data driver is registered on a particular
224 * device, 0 if not
225 * @param error_code Status code of this operation
226 * @return RMNETCTL_SUCCESS if successful
227 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
228 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
229 * Check error_code
230 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
231 */
232 int rmnet_get_network_device_associated(rmnetctl_hndl_t *hndl,
233 					const char *dev_name,
234 					int *register_status,
235 					uint16_t *error_code);
236 
237 /*!
238 * @brief Public API to set the egress data format for a particular link.
239 * @details Message type is RMNET_NETLINK_SET_LINK_EGRESS_DATA_FORMAT.
240 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
241 * @param egress_flags Egress flags to be set on the device
242 * @param agg_size Max size of aggregated packets
243 * @param agg_count Number of packets to be aggregated
244 * @param dev_name Device on which to set the egress data format
245 * @param error_code Status code of this operation returned from the kernel
246 * @return RMNETCTL_SUCCESS if successful
247 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
248 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
249 * Check error_code
250 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
251 */
252 int rmnet_set_link_egress_data_format(rmnetctl_hndl_t *hndl,
253 				      uint32_t egress_flags,
254 				      uint16_t agg_size,
255 				      uint16_t agg_count,
256 				      const char *dev_name,
257 				      uint16_t *error_code);
258 
259 /*!
260 * @brief Public API to get the egress data format for a particular link.
261 * @details Message type is RMNET_NETLINK_GET_LINK_EGRESS_DATA_FORMAT.
262 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
263 * @param dev_name Device on which to get the egress data format
264 * @param egress_flags Egress flags from the device
265 * @param agg_count Number of packets to be aggregated
266 * @param error_code Status code of this operation returned from the kernel
267 * @return RMNETCTL_SUCCESS if successful
268 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
269 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
270 * Check error_code
271 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
272 */
273 int rmnet_get_link_egress_data_format(rmnetctl_hndl_t *hndl,
274 				      const char *dev_name,
275 				      uint32_t *egress_flags,
276 				      uint16_t *agg_size,
277 				      uint16_t *agg_count,
278 				      uint16_t *error_code);
279 
280 /*!
281 * @brief Public API to set the ingress data format for a particular link.
282 * @details Message type is RMNET_NETLINK_SET_LINK_INGRESS_DATA_FORMAT.
283 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
284 * @param ingress_flags Ingress flags from the device
285 * @param tail_spacing Tail spacing needed for the packet
286 * @param dev_name Device on which to set the ingress data format
287 * @param error_code Status code of this operation returned from the kernel
288 * @return RMNETCTL_SUCCESS if successful
289 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
290 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
291 * Check error_code
292 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
293 */
294 int rmnet_set_link_ingress_data_format_tailspace(rmnetctl_hndl_t *hndl,
295 						 uint32_t ingress_flags,
296 						 uint8_t  tail_spacing,
297 						 const char *dev_name,
298 						 uint16_t *error_code);
299 
300 /*!
301 * @brief Public API to get the ingress data format for a particular link.
302 * @details Message type is RMNET_NETLINK_GET_LINK_INGRESS_DATA_FORMAT.
303 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
304 * @param dev_name Device on which to get the ingress data format
305 * @param ingress_flags Ingress flags from the device
306 * @param tail_spacing Tail spacing needed for the packet
307 * @param error_code Status code of this operation returned from the kernel
308 * @return RMNETCTL_SUCCESS if successful
309 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
310 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
311 * Check error_code
312 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
313 */
314 int rmnet_get_link_ingress_data_format_tailspace(rmnetctl_hndl_t *hndl,
315 						const char *dev_name,
316 						uint32_t *ingress_flags,
317 						uint8_t  *tail_spacing,
318 						uint16_t *error_code);
319 
rmnet_set_link_ingress_data_format(rmnetctl_hndl_t * hndl,uint32_t ingress_flags,const char * dev_name,uint16_t * error_code)320 inline int rmnet_set_link_ingress_data_format(rmnetctl_hndl_t *hndl,
321 					      uint32_t ingress_flags,
322 					      const char *dev_name,
323 					      uint16_t *error_code)
324 {
325 	return rmnet_set_link_ingress_data_format_tailspace(hndl,
326 							    ingress_flags,
327 							    0,
328 							    dev_name,
329 							    error_code);
330 }
331 
rmnet_get_link_ingress_data_format(rmnetctl_hndl_t * hndl,const char * dev_name,uint32_t * ingress_flags,uint16_t * error_code)332 inline int rmnet_get_link_ingress_data_format(rmnetctl_hndl_t *hndl,
333 					      const char *dev_name,
334 					      uint32_t *ingress_flags,
335 					      uint16_t *error_code)
336 {
337 	return rmnet_get_link_ingress_data_format_tailspace(hndl,
338 							    dev_name,
339 							    ingress_flags,
340 							    0,
341 							    error_code);
342 }
343 
344 /*!
345 * @brief Public API to set the logical endpoint configuration for a
346 * particular link.
347 * @details Message type is RMNET_NETLINK_SET_LOGICAL_EP_CONFIG.
348 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
349 * @param logical_ep_id Logical end point id on which the configuration is to be
350 * set
351 * @param rmnet_mode RmNet mode to be set on the device
352 * @param dev_name Device on which to set the logical end point configuration
353 * @param egress_dev_name Egress Device if operating in bridge mode
354 * @param error_code Status code of this operation returned from the kernel
355 * @return RMNETCTL_SUCCESS if successful
356 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
357 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
358 * Check error_code
359 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
360 */
361 int rmnet_set_logical_ep_config(rmnetctl_hndl_t *hndl,
362 				int32_t ep_id,
363 				uint8_t operating_mode,
364 				const char *dev_name,
365 				const char *next_dev,
366 				uint16_t *error_code);
367 
368 /*!
369 * @brief Public API to un-set the logical endpoint configuration for a
370 * particular link.
371 * @details Message type is RMNET_NETLINK_UNSET_LOGICAL_EP_CONFIG.
372 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
373 * @param logical_ep_id Logical end point id on which the configuration is to be
374 * un-set
375 * @param dev_name Device on which to un-set the logical end point configuration
376 * @param error_code Status code of this operation returned from the kernel
377 * @return RMNETCTL_SUCCESS if successful
378 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
379 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
380 * Check error_code
381 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
382 */
383 int rmnet_unset_logical_ep_config(rmnetctl_hndl_t *hndl,
384 				  int32_t ep_id,
385 				  const char *dev_name,
386 				  uint16_t *error_code);
387 /*!
388 * @brief Public API to get the logical endpoint configuration for a
389 * particular link.
390 * @details Message type is RMNET_NETLINK_GET_LOGICAL_EP_CONFIG.
391 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
392 * @param logical_ep_id Logical end point id from which to get the configuration
393 * @param dev_name Device on which to get the logical end point configuration
394 * @param rmnet_mode RmNet mode from the device
395 * @param next_dev Egress Device name
396 * @param next_dev_len Egress Device I/O string len
397 * @param error_code Status code of this operation returned from the kernel
398 * @return RMNETCTL_SUCCESS if successful
399 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
400 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
401 * Check error_code
402 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
403 */
404 int rmnet_get_logical_ep_config(rmnetctl_hndl_t *hndl,
405 				int32_t ep_id,
406 				const char *dev_name,
407 				uint8_t *operating_mode,
408 				char **next_dev,
409 				uint32_t next_dev_len,
410 				uint16_t *error_code);
411 
412 /*!
413 * @brief Public API to create a new virtual device node
414 * @details Message type is RMNET_NETLINK_NEW_VND or
415 * RMNETCTL_FREE_VND based on the flag for new_vnd
416 * @param hndl RmNet handle for the Netlink message
417 * @param id Node number to create the virtual network device node
418 * @param error_code Status code of this operation returned from the kernel
419 * @param new_vnd creates a new virtual network device if  RMNETCTL_NEW_VND or
420 * frees the device if RMNETCTL_FREE_VND
421 * @return RMNETCTL_SUCCESS if successful
422 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
423 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
424 * Check error_code
425 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
426 */
427 int rmnet_new_vnd(rmnetctl_hndl_t *hndl,
428 		  uint32_t id,
429 		  uint16_t *error_code,
430 		  uint8_t new_vnd);
431 
432 /*!
433  * @brief Public API to create a new virtual device node with a custom prefix
434  * @details Message type is RMNET_NETLINK_NEW_VND or
435  * RMNETCTL_FREE_VND based on the flag for new_vnd
436  * @param hndl RmNet handle for the Netlink message
437  * @param id Node number to create the virtual network device node
438  * @param error_code Status code of this operation returned from the kernel
439  * @param new_vnd creates a new virtual network device if  RMNETCTL_NEW_VND or
440  * frees the device if RMNETCTL_FREE_VND
441  * @param prefix Prefix to be used when naming the network interface
442  * @return RMNETCTL_SUCCESS if successful
443  * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
444  * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
445  * Check error_code
446  * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
447  */
448 int rmnet_new_vnd_prefix(rmnetctl_hndl_t *hndl,
449 			 uint32_t id,
450 			 uint16_t *error_code,
451 			 uint8_t new_vnd,
452 			 const char *prefix);
453 /*!
454  * @brief API to get the ASCII name of a virtual network device from its ID
455  * @param hndl RmNet handle for the Netlink message
456  * @param id Node number to create the virtual network device node
457  * @param error_code Status code of this operation returned from the kernel
458  * @param buf Buffer to store ASCII representation of device name
459  * @param buflen Length of the buffer
460  * @param prefix Prefix to be used when naming the network interface
461  * @return RMNETCTL_SUCCESS if successful
462  * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
463  * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
464  * Check error_code
465  * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
466  */
467 
468 int rmnet_get_vnd_name(rmnetctl_hndl_t *hndl,
469                       uint32_t id,
470                       uint16_t *error_code,
471                       char *buf,
472                       uint32_t buflen);
473 
474 /*!
475 * @brief Public API to set or clear a flow
476 * @details Message type is RMNET_NETLINK_ADD_VND_TC_FLOW or
477 * RMNET_NETLINK_DEL_VND_TC_FLOW based on the flag for set_flow
478 * @param *rmnetctl_hndl_t_val RmNet handle for the Netlink message
479 * @param id Node number to set or clear the flow on the virtual network
480 * device node
481 * @param map_flow_id Flow handle of the modem
482 * @param tc_flow_id Software flow handle
483 * @param set_flow sets the flow if  RMNET_NETLINK_SET_FLOW or
484 * clears the flow if RMNET_NETLINK_CLEAR_FLOW
485 * @return RMNETCTL_SUCCESS if successful
486 * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
487 * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
488 * Check error_code
489 * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
490 */
491 int rmnet_add_del_vnd_tc_flow(rmnetctl_hndl_t *hndl,
492 			      uint32_t id,
493 			      uint32_t map_flow_id,
494 			      uint32_t tc_flow_id,
495 			      uint8_t set_flow,
496 			      uint16_t *error_code);
497 
498 #endif /* not defined LIBRMNETCTL_H */
499 
500