1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2003-2008 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker * @ingroup core
8*4dc78e53SAndroid Build Coastguard Worker * @defgroup cb Callbacks/Customization
9*4dc78e53SAndroid Build Coastguard Worker *
10*4dc78e53SAndroid Build Coastguard Worker * Related sections in the development guide:
11*4dc78e53SAndroid Build Coastguard Worker * - @core_doc{core_cb, Callback Configuration}
12*4dc78e53SAndroid Build Coastguard Worker *
13*4dc78e53SAndroid Build Coastguard Worker * @{
14*4dc78e53SAndroid Build Coastguard Worker *
15*4dc78e53SAndroid Build Coastguard Worker * Header
16*4dc78e53SAndroid Build Coastguard Worker * ------
17*4dc78e53SAndroid Build Coastguard Worker * ~~~~{.c}
18*4dc78e53SAndroid Build Coastguard Worker * #include <netlink/handlers.h>
19*4dc78e53SAndroid Build Coastguard Worker * ~~~~
20*4dc78e53SAndroid Build Coastguard Worker */
21*4dc78e53SAndroid Build Coastguard Worker
22*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
23*4dc78e53SAndroid Build Coastguard Worker
24*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
25*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
26*4dc78e53SAndroid Build Coastguard Worker #include <netlink/msg.h>
27*4dc78e53SAndroid Build Coastguard Worker #include <netlink/handlers.h>
28*4dc78e53SAndroid Build Coastguard Worker
29*4dc78e53SAndroid Build Coastguard Worker #include "nl-core.h"
30*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/nl-core.h"
31*4dc78e53SAndroid Build Coastguard Worker
print_header_content(FILE * ofd,struct nlmsghdr * n)32*4dc78e53SAndroid Build Coastguard Worker static void print_header_content(FILE *ofd, struct nlmsghdr *n)
33*4dc78e53SAndroid Build Coastguard Worker {
34*4dc78e53SAndroid Build Coastguard Worker char flags[128];
35*4dc78e53SAndroid Build Coastguard Worker char type[32];
36*4dc78e53SAndroid Build Coastguard Worker
37*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "type=%s length=%u flags=<%s> sequence-nr=%u pid=%u",
38*4dc78e53SAndroid Build Coastguard Worker nl_nlmsgtype2str(n->nlmsg_type, type, sizeof(type)),
39*4dc78e53SAndroid Build Coastguard Worker n->nlmsg_len, nl_nlmsg_flags2str(n->nlmsg_flags, flags,
40*4dc78e53SAndroid Build Coastguard Worker sizeof(flags)), n->nlmsg_seq, n->nlmsg_pid);
41*4dc78e53SAndroid Build Coastguard Worker }
42*4dc78e53SAndroid Build Coastguard Worker
nl_valid_handler_verbose(struct nl_msg * msg,void * arg)43*4dc78e53SAndroid Build Coastguard Worker static int nl_valid_handler_verbose(struct nl_msg *msg, void *arg)
44*4dc78e53SAndroid Build Coastguard Worker {
45*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stdout;
46*4dc78e53SAndroid Build Coastguard Worker
47*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Warning: unhandled valid message: ");
48*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, nlmsg_hdr(msg));
49*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
50*4dc78e53SAndroid Build Coastguard Worker
51*4dc78e53SAndroid Build Coastguard Worker return NL_OK;
52*4dc78e53SAndroid Build Coastguard Worker }
53*4dc78e53SAndroid Build Coastguard Worker
nl_invalid_handler_verbose(struct nl_msg * msg,void * arg)54*4dc78e53SAndroid Build Coastguard Worker static int nl_invalid_handler_verbose(struct nl_msg *msg, void *arg)
55*4dc78e53SAndroid Build Coastguard Worker {
56*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
57*4dc78e53SAndroid Build Coastguard Worker
58*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Error: Invalid message: ");
59*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, nlmsg_hdr(msg));
60*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
61*4dc78e53SAndroid Build Coastguard Worker
62*4dc78e53SAndroid Build Coastguard Worker return NL_STOP;
63*4dc78e53SAndroid Build Coastguard Worker }
64*4dc78e53SAndroid Build Coastguard Worker
nl_overrun_handler_verbose(struct nl_msg * msg,void * arg)65*4dc78e53SAndroid Build Coastguard Worker static int nl_overrun_handler_verbose(struct nl_msg *msg, void *arg)
66*4dc78e53SAndroid Build Coastguard Worker {
67*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
68*4dc78e53SAndroid Build Coastguard Worker
69*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Error: Netlink Overrun: ");
70*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, nlmsg_hdr(msg));
71*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
72*4dc78e53SAndroid Build Coastguard Worker
73*4dc78e53SAndroid Build Coastguard Worker return NL_STOP;
74*4dc78e53SAndroid Build Coastguard Worker }
75*4dc78e53SAndroid Build Coastguard Worker
nl_error_handler_verbose(struct sockaddr_nl * who,struct nlmsgerr * e,void * arg)76*4dc78e53SAndroid Build Coastguard Worker static int nl_error_handler_verbose(struct sockaddr_nl *who,
77*4dc78e53SAndroid Build Coastguard Worker struct nlmsgerr *e, void *arg)
78*4dc78e53SAndroid Build Coastguard Worker {
79*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
80*4dc78e53SAndroid Build Coastguard Worker
81*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Error received: %s\n-- Original message: ",
82*4dc78e53SAndroid Build Coastguard Worker nl_strerror_l(-e->error));
83*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, &e->msg);
84*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
85*4dc78e53SAndroid Build Coastguard Worker
86*4dc78e53SAndroid Build Coastguard Worker return -nl_syserr2nlerr(e->error);
87*4dc78e53SAndroid Build Coastguard Worker }
88*4dc78e53SAndroid Build Coastguard Worker
nl_valid_handler_debug(struct nl_msg * msg,void * arg)89*4dc78e53SAndroid Build Coastguard Worker static int nl_valid_handler_debug(struct nl_msg *msg, void *arg)
90*4dc78e53SAndroid Build Coastguard Worker {
91*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
92*4dc78e53SAndroid Build Coastguard Worker
93*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Debug: Unhandled Valid message: ");
94*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, nlmsg_hdr(msg));
95*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
96*4dc78e53SAndroid Build Coastguard Worker
97*4dc78e53SAndroid Build Coastguard Worker return NL_OK;
98*4dc78e53SAndroid Build Coastguard Worker }
99*4dc78e53SAndroid Build Coastguard Worker
nl_finish_handler_debug(struct nl_msg * msg,void * arg)100*4dc78e53SAndroid Build Coastguard Worker static int nl_finish_handler_debug(struct nl_msg *msg, void *arg)
101*4dc78e53SAndroid Build Coastguard Worker {
102*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
103*4dc78e53SAndroid Build Coastguard Worker
104*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Debug: End of multipart message block: ");
105*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, nlmsg_hdr(msg));
106*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
107*4dc78e53SAndroid Build Coastguard Worker
108*4dc78e53SAndroid Build Coastguard Worker return NL_STOP;
109*4dc78e53SAndroid Build Coastguard Worker }
110*4dc78e53SAndroid Build Coastguard Worker
nl_msg_in_handler_debug(struct nl_msg * msg,void * arg)111*4dc78e53SAndroid Build Coastguard Worker static int nl_msg_in_handler_debug(struct nl_msg *msg, void *arg)
112*4dc78e53SAndroid Build Coastguard Worker {
113*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
114*4dc78e53SAndroid Build Coastguard Worker
115*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Debug: Received Message:\n");
116*4dc78e53SAndroid Build Coastguard Worker nl_msg_dump(msg, ofd);
117*4dc78e53SAndroid Build Coastguard Worker
118*4dc78e53SAndroid Build Coastguard Worker return NL_OK;
119*4dc78e53SAndroid Build Coastguard Worker }
120*4dc78e53SAndroid Build Coastguard Worker
nl_msg_out_handler_debug(struct nl_msg * msg,void * arg)121*4dc78e53SAndroid Build Coastguard Worker static int nl_msg_out_handler_debug(struct nl_msg *msg, void *arg)
122*4dc78e53SAndroid Build Coastguard Worker {
123*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
124*4dc78e53SAndroid Build Coastguard Worker
125*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Debug: Sent Message:\n");
126*4dc78e53SAndroid Build Coastguard Worker nl_msg_dump(msg, ofd);
127*4dc78e53SAndroid Build Coastguard Worker
128*4dc78e53SAndroid Build Coastguard Worker return NL_OK;
129*4dc78e53SAndroid Build Coastguard Worker }
130*4dc78e53SAndroid Build Coastguard Worker
nl_skipped_handler_debug(struct nl_msg * msg,void * arg)131*4dc78e53SAndroid Build Coastguard Worker static int nl_skipped_handler_debug(struct nl_msg *msg, void *arg)
132*4dc78e53SAndroid Build Coastguard Worker {
133*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
134*4dc78e53SAndroid Build Coastguard Worker
135*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Debug: Skipped message: ");
136*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, nlmsg_hdr(msg));
137*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
138*4dc78e53SAndroid Build Coastguard Worker
139*4dc78e53SAndroid Build Coastguard Worker return NL_SKIP;
140*4dc78e53SAndroid Build Coastguard Worker }
141*4dc78e53SAndroid Build Coastguard Worker
nl_ack_handler_debug(struct nl_msg * msg,void * arg)142*4dc78e53SAndroid Build Coastguard Worker static int nl_ack_handler_debug(struct nl_msg *msg, void *arg)
143*4dc78e53SAndroid Build Coastguard Worker {
144*4dc78e53SAndroid Build Coastguard Worker FILE *ofd = arg ? arg : stderr;
145*4dc78e53SAndroid Build Coastguard Worker
146*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "-- Debug: ACK: ");
147*4dc78e53SAndroid Build Coastguard Worker print_header_content(ofd, nlmsg_hdr(msg));
148*4dc78e53SAndroid Build Coastguard Worker fprintf(ofd, "\n");
149*4dc78e53SAndroid Build Coastguard Worker
150*4dc78e53SAndroid Build Coastguard Worker return NL_STOP;
151*4dc78e53SAndroid Build Coastguard Worker }
152*4dc78e53SAndroid Build Coastguard Worker
153*4dc78e53SAndroid Build Coastguard Worker static nl_recvmsg_msg_cb_t cb_def[NL_CB_TYPE_MAX+1][NL_CB_KIND_MAX+1] = {
154*4dc78e53SAndroid Build Coastguard Worker [NL_CB_VALID] = {
155*4dc78e53SAndroid Build Coastguard Worker [NL_CB_VERBOSE] = nl_valid_handler_verbose,
156*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_valid_handler_debug,
157*4dc78e53SAndroid Build Coastguard Worker },
158*4dc78e53SAndroid Build Coastguard Worker [NL_CB_FINISH] = {
159*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_finish_handler_debug,
160*4dc78e53SAndroid Build Coastguard Worker },
161*4dc78e53SAndroid Build Coastguard Worker [NL_CB_INVALID] = {
162*4dc78e53SAndroid Build Coastguard Worker [NL_CB_VERBOSE] = nl_invalid_handler_verbose,
163*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_invalid_handler_verbose,
164*4dc78e53SAndroid Build Coastguard Worker },
165*4dc78e53SAndroid Build Coastguard Worker [NL_CB_MSG_IN] = {
166*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_msg_in_handler_debug,
167*4dc78e53SAndroid Build Coastguard Worker },
168*4dc78e53SAndroid Build Coastguard Worker [NL_CB_MSG_OUT] = {
169*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_msg_out_handler_debug,
170*4dc78e53SAndroid Build Coastguard Worker },
171*4dc78e53SAndroid Build Coastguard Worker [NL_CB_OVERRUN] = {
172*4dc78e53SAndroid Build Coastguard Worker [NL_CB_VERBOSE] = nl_overrun_handler_verbose,
173*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_overrun_handler_verbose,
174*4dc78e53SAndroid Build Coastguard Worker },
175*4dc78e53SAndroid Build Coastguard Worker [NL_CB_SKIPPED] = {
176*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_skipped_handler_debug,
177*4dc78e53SAndroid Build Coastguard Worker },
178*4dc78e53SAndroid Build Coastguard Worker [NL_CB_ACK] = {
179*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_ack_handler_debug,
180*4dc78e53SAndroid Build Coastguard Worker },
181*4dc78e53SAndroid Build Coastguard Worker };
182*4dc78e53SAndroid Build Coastguard Worker
183*4dc78e53SAndroid Build Coastguard Worker static nl_recvmsg_err_cb_t cb_err_def[NL_CB_KIND_MAX+1] = {
184*4dc78e53SAndroid Build Coastguard Worker [NL_CB_VERBOSE] = nl_error_handler_verbose,
185*4dc78e53SAndroid Build Coastguard Worker [NL_CB_DEBUG] = nl_error_handler_verbose,
186*4dc78e53SAndroid Build Coastguard Worker };
187*4dc78e53SAndroid Build Coastguard Worker
188*4dc78e53SAndroid Build Coastguard Worker /**
189*4dc78e53SAndroid Build Coastguard Worker * @name Callback Handle Management
190*4dc78e53SAndroid Build Coastguard Worker * @{
191*4dc78e53SAndroid Build Coastguard Worker */
192*4dc78e53SAndroid Build Coastguard Worker
193*4dc78e53SAndroid Build Coastguard Worker /**
194*4dc78e53SAndroid Build Coastguard Worker * Allocate a new callback handle
195*4dc78e53SAndroid Build Coastguard Worker * @arg kind callback kind to be used for initialization
196*4dc78e53SAndroid Build Coastguard Worker * @return Newly allocated callback handle or NULL
197*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_alloc(enum nl_cb_kind kind)198*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind)
199*4dc78e53SAndroid Build Coastguard Worker {
200*4dc78e53SAndroid Build Coastguard Worker int i;
201*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *cb;
202*4dc78e53SAndroid Build Coastguard Worker
203*4dc78e53SAndroid Build Coastguard Worker if ((unsigned int) kind > NL_CB_KIND_MAX)
204*4dc78e53SAndroid Build Coastguard Worker return NULL;
205*4dc78e53SAndroid Build Coastguard Worker
206*4dc78e53SAndroid Build Coastguard Worker cb = calloc(1, sizeof(*cb));
207*4dc78e53SAndroid Build Coastguard Worker if (!cb)
208*4dc78e53SAndroid Build Coastguard Worker return NULL;
209*4dc78e53SAndroid Build Coastguard Worker
210*4dc78e53SAndroid Build Coastguard Worker cb->cb_refcnt = 1;
211*4dc78e53SAndroid Build Coastguard Worker cb->cb_active = NL_CB_TYPE_MAX + 1;
212*4dc78e53SAndroid Build Coastguard Worker
213*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i <= NL_CB_TYPE_MAX; i++)
214*4dc78e53SAndroid Build Coastguard Worker nl_cb_set(cb, i, kind, NULL, NULL);
215*4dc78e53SAndroid Build Coastguard Worker
216*4dc78e53SAndroid Build Coastguard Worker nl_cb_err(cb, kind, NULL, NULL);
217*4dc78e53SAndroid Build Coastguard Worker
218*4dc78e53SAndroid Build Coastguard Worker return cb;
219*4dc78e53SAndroid Build Coastguard Worker }
220*4dc78e53SAndroid Build Coastguard Worker
221*4dc78e53SAndroid Build Coastguard Worker /**
222*4dc78e53SAndroid Build Coastguard Worker * Clone an existing callback handle
223*4dc78e53SAndroid Build Coastguard Worker * @arg orig original callback handle
224*4dc78e53SAndroid Build Coastguard Worker * @return Newly allocated callback handle being a duplicate of
225*4dc78e53SAndroid Build Coastguard Worker * orig or NULL
226*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_clone(struct nl_cb * orig)227*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *nl_cb_clone(struct nl_cb *orig)
228*4dc78e53SAndroid Build Coastguard Worker {
229*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *cb;
230*4dc78e53SAndroid Build Coastguard Worker
231*4dc78e53SAndroid Build Coastguard Worker cb = nl_cb_alloc(NL_CB_DEFAULT);
232*4dc78e53SAndroid Build Coastguard Worker if (!cb)
233*4dc78e53SAndroid Build Coastguard Worker return NULL;
234*4dc78e53SAndroid Build Coastguard Worker
235*4dc78e53SAndroid Build Coastguard Worker memcpy(cb, orig, sizeof(*orig));
236*4dc78e53SAndroid Build Coastguard Worker cb->cb_refcnt = 1;
237*4dc78e53SAndroid Build Coastguard Worker
238*4dc78e53SAndroid Build Coastguard Worker return cb;
239*4dc78e53SAndroid Build Coastguard Worker }
240*4dc78e53SAndroid Build Coastguard Worker
nl_cb_get(struct nl_cb * cb)241*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *nl_cb_get(struct nl_cb *cb)
242*4dc78e53SAndroid Build Coastguard Worker {
243*4dc78e53SAndroid Build Coastguard Worker cb->cb_refcnt++;
244*4dc78e53SAndroid Build Coastguard Worker
245*4dc78e53SAndroid Build Coastguard Worker return cb;
246*4dc78e53SAndroid Build Coastguard Worker }
247*4dc78e53SAndroid Build Coastguard Worker
nl_cb_put(struct nl_cb * cb)248*4dc78e53SAndroid Build Coastguard Worker void nl_cb_put(struct nl_cb *cb)
249*4dc78e53SAndroid Build Coastguard Worker {
250*4dc78e53SAndroid Build Coastguard Worker if (!cb)
251*4dc78e53SAndroid Build Coastguard Worker return;
252*4dc78e53SAndroid Build Coastguard Worker
253*4dc78e53SAndroid Build Coastguard Worker cb->cb_refcnt--;
254*4dc78e53SAndroid Build Coastguard Worker
255*4dc78e53SAndroid Build Coastguard Worker if (cb->cb_refcnt < 0)
256*4dc78e53SAndroid Build Coastguard Worker BUG();
257*4dc78e53SAndroid Build Coastguard Worker
258*4dc78e53SAndroid Build Coastguard Worker if (cb->cb_refcnt <= 0)
259*4dc78e53SAndroid Build Coastguard Worker free(cb);
260*4dc78e53SAndroid Build Coastguard Worker }
261*4dc78e53SAndroid Build Coastguard Worker
262*4dc78e53SAndroid Build Coastguard Worker /**
263*4dc78e53SAndroid Build Coastguard Worker * Obtain type of current active callback
264*4dc78e53SAndroid Build Coastguard Worker * @arg cb callback to query
265*4dc78e53SAndroid Build Coastguard Worker *
266*4dc78e53SAndroid Build Coastguard Worker * @return type or __NL_CB_TYPE_MAX if none active
267*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_active_type(struct nl_cb * cb)268*4dc78e53SAndroid Build Coastguard Worker enum nl_cb_type nl_cb_active_type(struct nl_cb *cb)
269*4dc78e53SAndroid Build Coastguard Worker {
270*4dc78e53SAndroid Build Coastguard Worker return cb->cb_active;
271*4dc78e53SAndroid Build Coastguard Worker }
272*4dc78e53SAndroid Build Coastguard Worker
273*4dc78e53SAndroid Build Coastguard Worker /** @} */
274*4dc78e53SAndroid Build Coastguard Worker
275*4dc78e53SAndroid Build Coastguard Worker /**
276*4dc78e53SAndroid Build Coastguard Worker * @name Callback Setup
277*4dc78e53SAndroid Build Coastguard Worker * @{
278*4dc78e53SAndroid Build Coastguard Worker */
279*4dc78e53SAndroid Build Coastguard Worker
280*4dc78e53SAndroid Build Coastguard Worker /**
281*4dc78e53SAndroid Build Coastguard Worker * Set up a callback
282*4dc78e53SAndroid Build Coastguard Worker * @arg cb callback set
283*4dc78e53SAndroid Build Coastguard Worker * @arg type callback to modify
284*4dc78e53SAndroid Build Coastguard Worker * @arg kind kind of implementation
285*4dc78e53SAndroid Build Coastguard Worker * @arg func callback function (NL_CB_CUSTOM)
286*4dc78e53SAndroid Build Coastguard Worker * @arg arg argument passed to callback
287*4dc78e53SAndroid Build Coastguard Worker *
288*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code
289*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_set(struct nl_cb * cb,enum nl_cb_type type,enum nl_cb_kind kind,nl_recvmsg_msg_cb_t func,void * arg)290*4dc78e53SAndroid Build Coastguard Worker int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind,
291*4dc78e53SAndroid Build Coastguard Worker nl_recvmsg_msg_cb_t func, void *arg)
292*4dc78e53SAndroid Build Coastguard Worker {
293*4dc78e53SAndroid Build Coastguard Worker if ((unsigned int) type > NL_CB_TYPE_MAX)
294*4dc78e53SAndroid Build Coastguard Worker return -NLE_RANGE;
295*4dc78e53SAndroid Build Coastguard Worker
296*4dc78e53SAndroid Build Coastguard Worker if ((unsigned int) kind > NL_CB_KIND_MAX)
297*4dc78e53SAndroid Build Coastguard Worker return -NLE_RANGE;
298*4dc78e53SAndroid Build Coastguard Worker
299*4dc78e53SAndroid Build Coastguard Worker if (kind == NL_CB_CUSTOM) {
300*4dc78e53SAndroid Build Coastguard Worker cb->cb_set[type] = func;
301*4dc78e53SAndroid Build Coastguard Worker cb->cb_args[type] = arg;
302*4dc78e53SAndroid Build Coastguard Worker } else {
303*4dc78e53SAndroid Build Coastguard Worker cb->cb_set[type] = cb_def[type][kind];
304*4dc78e53SAndroid Build Coastguard Worker cb->cb_args[type] = arg;
305*4dc78e53SAndroid Build Coastguard Worker }
306*4dc78e53SAndroid Build Coastguard Worker
307*4dc78e53SAndroid Build Coastguard Worker return 0;
308*4dc78e53SAndroid Build Coastguard Worker }
309*4dc78e53SAndroid Build Coastguard Worker
310*4dc78e53SAndroid Build Coastguard Worker /**
311*4dc78e53SAndroid Build Coastguard Worker * Set up a all callbacks
312*4dc78e53SAndroid Build Coastguard Worker * @arg cb callback set
313*4dc78e53SAndroid Build Coastguard Worker * @arg kind kind of callback
314*4dc78e53SAndroid Build Coastguard Worker * @arg func callback function
315*4dc78e53SAndroid Build Coastguard Worker * @arg arg argument to be passwd to callback function
316*4dc78e53SAndroid Build Coastguard Worker *
317*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code
318*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_set_all(struct nl_cb * cb,enum nl_cb_kind kind,nl_recvmsg_msg_cb_t func,void * arg)319*4dc78e53SAndroid Build Coastguard Worker int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind,
320*4dc78e53SAndroid Build Coastguard Worker nl_recvmsg_msg_cb_t func, void *arg)
321*4dc78e53SAndroid Build Coastguard Worker {
322*4dc78e53SAndroid Build Coastguard Worker int i, err;
323*4dc78e53SAndroid Build Coastguard Worker
324*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i <= NL_CB_TYPE_MAX; i++) {
325*4dc78e53SAndroid Build Coastguard Worker err = nl_cb_set(cb, i, kind, func, arg);
326*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
327*4dc78e53SAndroid Build Coastguard Worker return err;
328*4dc78e53SAndroid Build Coastguard Worker }
329*4dc78e53SAndroid Build Coastguard Worker
330*4dc78e53SAndroid Build Coastguard Worker return 0;
331*4dc78e53SAndroid Build Coastguard Worker }
332*4dc78e53SAndroid Build Coastguard Worker
333*4dc78e53SAndroid Build Coastguard Worker /**
334*4dc78e53SAndroid Build Coastguard Worker * Set up an error callback
335*4dc78e53SAndroid Build Coastguard Worker * @arg cb callback set
336*4dc78e53SAndroid Build Coastguard Worker * @arg kind kind of callback
337*4dc78e53SAndroid Build Coastguard Worker * @arg func callback function
338*4dc78e53SAndroid Build Coastguard Worker * @arg arg argument to be passed to callback function
339*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_err(struct nl_cb * cb,enum nl_cb_kind kind,nl_recvmsg_err_cb_t func,void * arg)340*4dc78e53SAndroid Build Coastguard Worker int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind,
341*4dc78e53SAndroid Build Coastguard Worker nl_recvmsg_err_cb_t func, void *arg)
342*4dc78e53SAndroid Build Coastguard Worker {
343*4dc78e53SAndroid Build Coastguard Worker if ((unsigned int) kind > NL_CB_KIND_MAX)
344*4dc78e53SAndroid Build Coastguard Worker return -NLE_RANGE;
345*4dc78e53SAndroid Build Coastguard Worker
346*4dc78e53SAndroid Build Coastguard Worker if (kind == NL_CB_CUSTOM) {
347*4dc78e53SAndroid Build Coastguard Worker cb->cb_err = func;
348*4dc78e53SAndroid Build Coastguard Worker cb->cb_err_arg = arg;
349*4dc78e53SAndroid Build Coastguard Worker } else {
350*4dc78e53SAndroid Build Coastguard Worker cb->cb_err = cb_err_def[kind];
351*4dc78e53SAndroid Build Coastguard Worker cb->cb_err_arg = arg;
352*4dc78e53SAndroid Build Coastguard Worker }
353*4dc78e53SAndroid Build Coastguard Worker
354*4dc78e53SAndroid Build Coastguard Worker return 0;
355*4dc78e53SAndroid Build Coastguard Worker }
356*4dc78e53SAndroid Build Coastguard Worker
357*4dc78e53SAndroid Build Coastguard Worker /** @} */
358*4dc78e53SAndroid Build Coastguard Worker
359*4dc78e53SAndroid Build Coastguard Worker /**
360*4dc78e53SAndroid Build Coastguard Worker * @name Overwriting
361*4dc78e53SAndroid Build Coastguard Worker * @{
362*4dc78e53SAndroid Build Coastguard Worker */
363*4dc78e53SAndroid Build Coastguard Worker
364*4dc78e53SAndroid Build Coastguard Worker /**
365*4dc78e53SAndroid Build Coastguard Worker * Overwrite internal calls to nl_recvmsgs()
366*4dc78e53SAndroid Build Coastguard Worker * @arg cb callback set
367*4dc78e53SAndroid Build Coastguard Worker * @arg func replacement callback for nl_recvmsgs()
368*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_overwrite_recvmsgs(struct nl_cb * cb,int (* func)(struct nl_sock *,struct nl_cb *))369*4dc78e53SAndroid Build Coastguard Worker void nl_cb_overwrite_recvmsgs(struct nl_cb *cb,
370*4dc78e53SAndroid Build Coastguard Worker int (*func)(struct nl_sock *, struct nl_cb *))
371*4dc78e53SAndroid Build Coastguard Worker {
372*4dc78e53SAndroid Build Coastguard Worker cb->cb_recvmsgs_ow = func;
373*4dc78e53SAndroid Build Coastguard Worker }
374*4dc78e53SAndroid Build Coastguard Worker
375*4dc78e53SAndroid Build Coastguard Worker /**
376*4dc78e53SAndroid Build Coastguard Worker * Overwrite internal calls to nl_recv()
377*4dc78e53SAndroid Build Coastguard Worker * @arg cb callback set
378*4dc78e53SAndroid Build Coastguard Worker * @arg func replacement callback for nl_recv()
379*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_overwrite_recv(struct nl_cb * cb,int (* func)(struct nl_sock *,struct sockaddr_nl *,unsigned char **,struct ucred **))380*4dc78e53SAndroid Build Coastguard Worker void nl_cb_overwrite_recv(struct nl_cb *cb,
381*4dc78e53SAndroid Build Coastguard Worker int (*func)(struct nl_sock *, struct sockaddr_nl *,
382*4dc78e53SAndroid Build Coastguard Worker unsigned char **, struct ucred **))
383*4dc78e53SAndroid Build Coastguard Worker {
384*4dc78e53SAndroid Build Coastguard Worker cb->cb_recv_ow = func;
385*4dc78e53SAndroid Build Coastguard Worker }
386*4dc78e53SAndroid Build Coastguard Worker
387*4dc78e53SAndroid Build Coastguard Worker /**
388*4dc78e53SAndroid Build Coastguard Worker * Overwrite internal calls to nl_send()
389*4dc78e53SAndroid Build Coastguard Worker * @arg cb callback set
390*4dc78e53SAndroid Build Coastguard Worker * @arg func replacement callback for nl_send()
391*4dc78e53SAndroid Build Coastguard Worker */
nl_cb_overwrite_send(struct nl_cb * cb,int (* func)(struct nl_sock *,struct nl_msg *))392*4dc78e53SAndroid Build Coastguard Worker void nl_cb_overwrite_send(struct nl_cb *cb,
393*4dc78e53SAndroid Build Coastguard Worker int (*func)(struct nl_sock *, struct nl_msg *))
394*4dc78e53SAndroid Build Coastguard Worker {
395*4dc78e53SAndroid Build Coastguard Worker cb->cb_send_ow = func;
396*4dc78e53SAndroid Build Coastguard Worker }
397*4dc78e53SAndroid Build Coastguard Worker
398*4dc78e53SAndroid Build Coastguard Worker /** @} */
399*4dc78e53SAndroid Build Coastguard Worker
400*4dc78e53SAndroid Build Coastguard Worker /** @} */
401