Tizen 2.1 base
[platform/upstream/libnl2.git] / lib / nl.c
1 /*
2  * lib/nl.c             Core Netlink Interface
3  *
4  *      This library is free software; you can redistribute it and/or
5  *      modify it under the terms of the GNU Lesser General Public
6  *      License as published by the Free Software Foundation version 2.1
7  *      of the License.
8  *
9  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
10  */
11
12 /**
13  * @defgroup core Core
14  *
15  * @details
16  * @par 1) Connecting the socket
17  * @code
18  * // Bind and connect the socket to a protocol, NETLINK_ROUTE in this example.
19  * nl_connect(sk, NETLINK_ROUTE);
20  * @endcode
21  *
22  * @par 2) Sending data
23  * @code
24  * // The most rudimentary method is to use nl_sendto() simply pushing
25  * // a piece of data to the other netlink peer. This method is not
26  * // recommended.
27  * const char buf[] = { 0x01, 0x02, 0x03, 0x04 };
28  * nl_sendto(sk, buf, sizeof(buf));
29  *
30  * // A more comfortable interface is nl_send() taking a pointer to
31  * // a netlink message.
32  * struct nl_msg *msg = my_msg_builder();
33  * nl_send(sk, nlmsg_hdr(msg));
34  *
35  * // nl_sendmsg() provides additional control over the sendmsg() message
36  * // header in order to allow more specific addressing of multiple peers etc.
37  * struct msghdr hdr = { ... };
38  * nl_sendmsg(sk, nlmsg_hdr(msg), &hdr);
39  *
40  * // You're probably too lazy to fill out the netlink pid, sequence number
41  * // and message flags all the time. nl_send_auto_complete() automatically
42  * // extends your message header as needed with an appropriate sequence
43  * // number, the netlink pid stored in the netlink socket and the message
44  * // flags NLM_F_REQUEST and NLM_F_ACK (if not disabled in the socket)
45  * nl_send_auto_complete(sk, nlmsg_hdr(msg));
46  *
47  * // Simple protocols don't require the complex message construction interface
48  * // and may favour nl_send_simple() to easly send a bunch of payload
49  * // encapsulated in a netlink message header.
50  * nl_send_simple(sk, MY_MSG_TYPE, 0, buf, sizeof(buf));
51  * @endcode
52  *
53  * @par 3) Receiving data
54  * @code
55  * // nl_recv() receives a single message allocating a buffer for the message
56  * // content and gives back the pointer to you.
57  * struct sockaddr_nl peer;
58  * unsigned char *msg;
59  * nl_recv(sk, &peer, &msg);
60  *
61  * // nl_recvmsgs() receives a bunch of messages until the callback system
62  * // orders it to state, usually after receving a compolete multi part
63  * // message series.
64  * nl_recvmsgs(sk, my_callback_configuration);
65  *
66  * // nl_recvmsgs_default() acts just like nl_recvmsg() but uses the callback
67  * // configuration stored in the socket.
68  * nl_recvmsgs_default(sk);
69  *
70  * // In case you want to wait for the ACK to be recieved that you requested
71  * // with your latest message, you can call nl_wait_for_ack()
72  * nl_wait_for_ack(sk);
73  * @endcode
74  *
75  * @par 4) Closing
76  * @code
77  * // Close the socket first to release kernel memory
78  * nl_close(sk);
79  * @endcode
80  * 
81  * @{
82  */
83
84 #include <netlink-local.h>
85 #include <netlink/netlink.h>
86 #include <netlink/utils.h>
87 #include <netlink/handlers.h>
88 #include <netlink/msg.h>
89 #include <netlink/attr.h>
90
91 /**
92  * @name Connection Management
93  * @{
94  */
95
96 /**
97  * Create and connect netlink socket.
98  * @arg sk              Netlink socket.
99  * @arg protocol        Netlink protocol to use.
100  *
101  * Creates a netlink socket using the specified protocol, binds the socket
102  * and issues a connection attempt.
103  *
104  * @return 0 on success or a negative error code.
105  */
106 int nl_connect(struct nl_sock *sk, int protocol)
107 {
108         int err;
109         socklen_t addrlen;
110
111         sk->s_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
112         if (sk->s_fd < 0) {
113                 err = -nl_syserr2nlerr(errno);
114                 goto errout;
115         }
116
117         if (!(sk->s_flags & NL_SOCK_BUFSIZE_SET)) {
118                 err = nl_socket_set_buffer_size(sk, 0, 0);
119                 if (err < 0)
120                         goto errout;
121         }
122
123         err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
124                    sizeof(sk->s_local));
125         if (err < 0) {
126                 err = -nl_syserr2nlerr(errno);
127                 goto errout;
128         }
129
130         addrlen = sizeof(sk->s_local);
131         err = getsockname(sk->s_fd, (struct sockaddr *) &sk->s_local,
132                           &addrlen);
133         if (err < 0) {
134                 err = -nl_syserr2nlerr(errno);
135                 goto errout;
136         }
137
138         if (addrlen != sizeof(sk->s_local)) {
139                 err = -NLE_NOADDR;
140                 goto errout;
141         }
142
143         if (sk->s_local.nl_family != AF_NETLINK) {
144                 err = -NLE_AF_NOSUPPORT;
145                 goto errout;
146         }
147
148         sk->s_proto = protocol;
149
150         return 0;
151 errout:
152         close(sk->s_fd);
153         sk->s_fd = -1;
154
155         return err;
156 }
157
158 /**
159  * Close/Disconnect netlink socket.
160  * @arg sk              Netlink socket.
161  */
162 void nl_close(struct nl_sock *sk)
163 {
164         if (sk->s_fd >= 0) {
165                 close(sk->s_fd);
166                 sk->s_fd = -1;
167         }
168
169         sk->s_proto = 0;
170 }
171
172 /** @} */
173
174 /**
175  * @name Send
176  * @{
177  */
178
179 /**
180  * Send raw data over netlink socket.
181  * @arg sk              Netlink socket.
182  * @arg buf             Data buffer.
183  * @arg size            Size of data buffer.
184  * @return Number of characters written on success or a negative error code.
185  */
186 int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
187 {
188         int ret;
189
190         ret = sendto(sk->s_fd, buf, size, 0, (struct sockaddr *)
191                      &sk->s_peer, sizeof(sk->s_peer));
192         if (ret < 0)
193                 return -nl_syserr2nlerr(errno);
194
195         return ret;
196 }
197
198 /**
199  * Send netlink message with control over sendmsg() message header.
200  * @arg sk              Netlink socket.
201  * @arg msg             Netlink message to be sent.
202  * @arg hdr             Sendmsg() message header.
203  * @return Number of characters sent on sucess or a negative error code.
204  */
205 int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
206 {
207         struct nl_cb *cb;
208         int ret;
209
210         nlmsg_set_src(msg, &sk->s_local);
211
212         cb = sk->s_cb;
213         if (cb->cb_set[NL_CB_MSG_OUT])
214                 if (nl_cb_call(cb, NL_CB_MSG_OUT, msg) != NL_OK)
215                         return 0;
216
217         ret = sendmsg(sk->s_fd, hdr, 0);
218         if (ret < 0)
219                 return -nl_syserr2nlerr(errno);
220
221         NL_DBG(4, "sent %d bytes\n", ret);
222         return ret;
223 }
224
225
226 /**
227  * Send netlink message.
228  * @arg sk              Netlink socket.
229  * @arg msg             Netlink message to be sent.
230  * @arg iov             iovec to be sent.
231  * @arg iovlen          number of struct iovec to be sent.
232  * @see nl_sendmsg()
233  * @return Number of characters sent on success or a negative error code.
234  */
235 int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
236 {
237         struct sockaddr_nl *dst;
238         struct ucred *creds;
239         struct msghdr hdr = {
240                 .msg_name = (void *) &sk->s_peer,
241                 .msg_namelen = sizeof(struct sockaddr_nl),
242                 .msg_iov = iov,
243                 .msg_iovlen = iovlen,
244         };
245
246         /* Overwrite destination if specified in the message itself, defaults
247          * to the peer address of the socket.
248          */
249         dst = nlmsg_get_dst(msg);
250         if (dst->nl_family == AF_NETLINK)
251                 hdr.msg_name = dst;
252
253         /* Add credentials if present. */
254         creds = nlmsg_get_creds(msg);
255         if (creds != NULL) {
256                 char buf[CMSG_SPACE(sizeof(struct ucred))];
257                 struct cmsghdr *cmsg;
258
259                 hdr.msg_control = buf;
260                 hdr.msg_controllen = sizeof(buf);
261
262                 cmsg = CMSG_FIRSTHDR(&hdr);
263                 cmsg->cmsg_level = SOL_SOCKET;
264                 cmsg->cmsg_type = SCM_CREDENTIALS;
265                 cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
266                 memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred));
267         }
268
269         return nl_sendmsg(sk, msg, &hdr);
270 }
271
272
273
274 /**
275 * Send netlink message.
276 * @arg sk               Netlink socket.
277 * @arg msg              Netlink message to be sent.
278 * @see nl_sendmsg()
279 * @return Number of characters sent on success or a negative error code.
280 */
281 int nl_send(struct nl_sock *sk, struct nl_msg *msg)
282 {
283         struct iovec iov = {
284                 .iov_base = (void *) nlmsg_hdr(msg),
285                 .iov_len = nlmsg_hdr(msg)->nlmsg_len,
286         };
287
288         return nl_send_iovec(sk, msg, &iov, 1);
289 }
290
291 void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
292 {
293         struct nlmsghdr *nlh;
294
295         nlh = nlmsg_hdr(msg);
296         if (nlh->nlmsg_pid == 0)
297                 nlh->nlmsg_pid = sk->s_local.nl_pid;
298
299         if (nlh->nlmsg_seq == 0)
300                 nlh->nlmsg_seq = sk->s_seq_next++;
301
302         if (msg->nm_protocol == -1)
303                 msg->nm_protocol = sk->s_proto;
304
305         nlh->nlmsg_flags |= NLM_F_REQUEST;
306
307         if (!(sk->s_flags & NL_NO_AUTO_ACK))
308                 nlh->nlmsg_flags |= NLM_F_ACK;
309 }
310
311 /**
312  * Send netlink message and check & extend header values as needed.
313  * @arg sk              Netlink socket.
314  * @arg msg             Netlink message to be sent.
315  *
316  * Checks the netlink message \c nlh for completness and extends it
317  * as required before sending it out. Checked fields include pid,
318  * sequence nr, and flags.
319  *
320  * @see nl_send()
321  * @return Number of characters sent or a negative error code.
322  */
323 int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
324 {
325         struct nl_cb *cb = sk->s_cb;
326
327         nl_auto_complete(sk, msg);
328
329         if (cb->cb_send_ow)
330                 return cb->cb_send_ow(sk, msg);
331         else
332                 return nl_send(sk, msg);
333 }
334
335 /**
336  * Send simple netlink message using nl_send_auto_complete()
337  * @arg sk              Netlink socket.
338  * @arg type            Netlink message type.
339  * @arg flags           Netlink message flags.
340  * @arg buf             Data buffer.
341  * @arg size            Size of data buffer.
342  *
343  * Builds a netlink message with the specified type and flags and
344  * appends the specified data as payload to the message.
345  *
346  * @see nl_send_auto_complete()
347  * @return Number of characters sent on success or a negative error code.
348  */
349 int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
350                    size_t size)
351 {
352         int err;
353         struct nl_msg *msg;
354
355         msg = nlmsg_alloc_simple(type, flags);
356         if (!msg)
357                 return -NLE_NOMEM;
358
359         if (buf && size) {
360                 err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
361                 if (err < 0)
362                         goto errout;
363         }
364         
365
366         err = nl_send_auto_complete(sk, msg);
367 errout:
368         nlmsg_free(msg);
369
370         return err;
371 }
372
373 /** @} */
374
375 /**
376  * @name Receive
377  * @{
378  */
379
380 /**
381  * Receive data from netlink socket
382  * @arg sk              Netlink socket.
383  * @arg nla             Destination pointer for peer's netlink address.
384  * @arg buf             Destination pointer for message content.
385  * @arg creds           Destination pointer for credentials.
386  *
387  * Receives a netlink message, allocates a buffer in \c *buf and
388  * stores the message content. The peer's netlink address is stored
389  * in \c *nla. The caller is responsible for freeing the buffer allocated
390  * in \c *buf if a positive value is returned.  Interrupted system calls
391  * are handled by repeating the read. The input buffer size is determined
392  * by peeking before the actual read is done.
393  *
394  * A non-blocking sockets causes the function to return immediately with
395  * a return value of 0 if no data is available.
396  *
397  * @return Number of octets read, 0 on EOF or a negative error code.
398  */
399 int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
400             unsigned char **buf, struct ucred **creds)
401 {
402         int n;
403         int flags = 0;
404         static int page_size = 0;
405         struct iovec iov;
406         struct msghdr msg = {
407                 .msg_name = (void *) nla,
408                 .msg_namelen = sizeof(struct sockaddr_nl),
409                 .msg_iov = &iov,
410                 .msg_iovlen = 1,
411                 .msg_control = NULL,
412                 .msg_controllen = 0,
413                 .msg_flags = 0,
414         };
415         struct cmsghdr *cmsg;
416
417         if (sk->s_flags & NL_MSG_PEEK)
418                 flags |= MSG_PEEK;
419
420         if (page_size == 0)
421                 page_size = getpagesize();
422
423         iov.iov_len = page_size;
424         iov.iov_base = *buf = malloc(iov.iov_len);
425
426         if (sk->s_flags & NL_SOCK_PASSCRED) {
427                 msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
428                 msg.msg_control = calloc(1, msg.msg_controllen);
429         }
430 retry:
431
432         n = recvmsg(sk->s_fd, &msg, flags);
433         if (!n)
434                 goto abort;
435         else if (n < 0) {
436                 if (errno == EINTR) {
437                         NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
438                         goto retry;
439                 } else if (errno == EAGAIN) {
440                         NL_DBG(3, "recvmsg() returned EAGAIN, aborting\n");
441                         goto abort;
442                 } else {
443                         free(msg.msg_control);
444                         free(*buf);
445                         return -nl_syserr2nlerr(errno);
446                 }
447         }
448
449         if (iov.iov_len < n ||
450             msg.msg_flags & MSG_TRUNC) {
451                 /* Provided buffer is not long enough, enlarge it
452                  * and try again. */
453                 iov.iov_len *= 2;
454                 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
455                 goto retry;
456         } else if (msg.msg_flags & MSG_CTRUNC) {
457                 msg.msg_controllen *= 2;
458                 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
459                 goto retry;
460         } else if (flags != 0) {
461                 /* Buffer is big enough, do the actual reading */
462                 flags = 0;
463                 goto retry;
464         }
465
466         if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
467                 free(msg.msg_control);
468                 free(*buf);
469                 return -NLE_NOADDR;
470         }
471
472         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
473                 if (cmsg->cmsg_level == SOL_SOCKET &&
474                     cmsg->cmsg_type == SCM_CREDENTIALS) {
475                         *creds = calloc(1, sizeof(struct ucred));
476                         memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
477                         break;
478                 }
479         }
480
481         free(msg.msg_control);
482         return n;
483
484 abort:
485         free(msg.msg_control);
486         free(*buf);
487         return 0;
488 }
489
490 #define NL_CB_CALL(cb, type, msg) \
491 do { \
492         err = nl_cb_call(cb, type, msg); \
493         switch (err) { \
494         case NL_OK: \
495                 err = 0; \
496                 break; \
497         case NL_SKIP: \
498                 goto skip; \
499         case NL_STOP: \
500                 goto stop; \
501         default: \
502                 goto out; \
503         } \
504 } while (0)
505
506 static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
507 {
508         int n, err = 0, multipart = 0;
509         unsigned char *buf = NULL;
510         struct nlmsghdr *hdr;
511         struct sockaddr_nl nla = {0};
512         struct nl_msg *msg = NULL;
513         struct ucred *creds = NULL;
514
515 continue_reading:
516         NL_DBG(3, "Attempting to read from %p\n", sk);
517         if (cb->cb_recv_ow)
518                 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
519         else
520                 n = nl_recv(sk, &nla, &buf, &creds);
521
522         if (n <= 0)
523                 return n;
524
525         NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);
526
527         hdr = (struct nlmsghdr *) buf;
528         while (nlmsg_ok(hdr, n)) {
529                 NL_DBG(3, "recgmsgs(%p): Processing valid message...\n", sk);
530
531                 nlmsg_free(msg);
532                 msg = nlmsg_convert(hdr);
533                 if (!msg) {
534                         err = -NLE_NOMEM;
535                         goto out;
536                 }
537
538                 nlmsg_set_proto(msg, sk->s_proto);
539                 nlmsg_set_src(msg, &nla);
540                 if (creds)
541                         nlmsg_set_creds(msg, creds);
542
543                 /* Raw callback is the first, it gives the most control
544                  * to the user and he can do his very own parsing. */
545                 if (cb->cb_set[NL_CB_MSG_IN])
546                         NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
547
548                 /* Sequence number checking. The check may be done by
549                  * the user, otherwise a very simple check is applied
550                  * enforcing strict ordering */
551                 if (cb->cb_set[NL_CB_SEQ_CHECK])
552                         NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
553                 else if (hdr->nlmsg_seq != sk->s_seq_expect) {
554                         if (cb->cb_set[NL_CB_INVALID])
555                                 NL_CB_CALL(cb, NL_CB_INVALID, msg);
556                         else {
557                                 err = -NLE_SEQ_MISMATCH;
558                                 goto out;
559                         }
560                 }
561
562                 if (hdr->nlmsg_type == NLMSG_DONE ||
563                     hdr->nlmsg_type == NLMSG_ERROR ||
564                     hdr->nlmsg_type == NLMSG_NOOP ||
565                     hdr->nlmsg_type == NLMSG_OVERRUN) {
566                         /* We can't check for !NLM_F_MULTI since some netlink
567                          * users in the kernel are broken. */
568                         sk->s_seq_expect++;
569                         NL_DBG(3, "recvmsgs(%p): Increased expected " \
570                                "sequence number to %d\n",
571                                sk, sk->s_seq_expect);
572                 }
573
574                 if (hdr->nlmsg_flags & NLM_F_MULTI)
575                         multipart = 1;
576         
577                 /* Other side wishes to see an ack for this message */
578                 if (hdr->nlmsg_flags & NLM_F_ACK) {
579                         if (cb->cb_set[NL_CB_SEND_ACK])
580                                 NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
581                         else {
582                                 /* FIXME: implement */
583                         }
584                 }
585
586                 /* messages terminates a multpart message, this is
587                  * usually the end of a message and therefore we slip
588                  * out of the loop by default. the user may overrule
589                  * this action by skipping this packet. */
590                 if (hdr->nlmsg_type == NLMSG_DONE) {
591                         multipart = 0;
592                         if (cb->cb_set[NL_CB_FINISH])
593                                 NL_CB_CALL(cb, NL_CB_FINISH, msg);
594                 }
595
596                 /* Message to be ignored, the default action is to
597                  * skip this message if no callback is specified. The
598                  * user may overrule this action by returning
599                  * NL_PROCEED. */
600                 else if (hdr->nlmsg_type == NLMSG_NOOP) {
601                         if (cb->cb_set[NL_CB_SKIPPED])
602                                 NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
603                         else
604                                 goto skip;
605                 }
606
607                 /* Data got lost, report back to user. The default action is to
608                  * quit parsing. The user may overrule this action by retuning
609                  * NL_SKIP or NL_PROCEED (dangerous) */
610                 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
611                         if (cb->cb_set[NL_CB_OVERRUN])
612                                 NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
613                         else {
614                                 err = -NLE_MSG_OVERFLOW;
615                                 goto out;
616                         }
617                 }
618
619                 /* Message carries a nlmsgerr */
620                 else if (hdr->nlmsg_type == NLMSG_ERROR) {
621                         struct nlmsgerr *e = nlmsg_data(hdr);
622
623                         if (hdr->nlmsg_len < nlmsg_msg_size(sizeof(*e))) {
624                                 /* Truncated error message, the default action
625                                  * is to stop parsing. The user may overrule
626                                  * this action by returning NL_SKIP or
627                                  * NL_PROCEED (dangerous) */
628                                 if (cb->cb_set[NL_CB_INVALID])
629                                         NL_CB_CALL(cb, NL_CB_INVALID, msg);
630                                 else {
631                                         err = -NLE_MSG_TRUNC;
632                                         goto out;
633                                 }
634                         } else if (e->error) {
635                                 /* Error message reported back from kernel. */
636                                 if (cb->cb_err) {
637                                         err = cb->cb_err(&nla, e,
638                                                            cb->cb_err_arg);
639                                         if (err < 0)
640                                                 goto out;
641                                         else if (err == NL_SKIP)
642                                                 goto skip;
643                                         else if (err == NL_STOP) {
644                                                 err = -nl_syserr2nlerr(e->error);
645                                                 goto out;
646                                         }
647                                 } else {
648                                         err = -nl_syserr2nlerr(e->error);
649                                         goto out;
650                                 }
651                         } else if (cb->cb_set[NL_CB_ACK])
652                                 NL_CB_CALL(cb, NL_CB_ACK, msg);
653                 } else {
654                         /* Valid message (not checking for MULTIPART bit to
655                          * get along with broken kernels. NL_SKIP has no
656                          * effect on this.  */
657                         if (cb->cb_set[NL_CB_VALID])
658                                 NL_CB_CALL(cb, NL_CB_VALID, msg);
659                 }
660 skip:
661                 err = 0;
662                 hdr = nlmsg_next(hdr, &n);
663         }
664         
665         nlmsg_free(msg);
666         free(buf);
667         free(creds);
668         buf = NULL;
669         msg = NULL;
670         creds = NULL;
671
672         if (multipart) {
673                 /* Multipart message not yet complete, continue reading */
674                 goto continue_reading;
675         }
676 stop:
677         err = 0;
678 out:
679         nlmsg_free(msg);
680         free(buf);
681         free(creds);
682
683         return err;
684 }
685
686 /**
687  * Receive a set of messages from a netlink socket.
688  * @arg sk              Netlink socket.
689  * @arg cb              set of callbacks to control behaviour.
690  *
691  * Repeatedly calls nl_recv() or the respective replacement if provided
692  * by the application (see nl_cb_overwrite_recv()) and parses the
693  * received data as netlink messages. Stops reading if one of the
694  * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
695  *
696  * A non-blocking sockets causes the function to return immediately if
697  * no data is available.
698  *
699  * @return 0 on success or a negative error code from nl_recv().
700  */
701 int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
702 {
703         if (cb->cb_recvmsgs_ow)
704                 return cb->cb_recvmsgs_ow(sk, cb);
705         else
706                 return recvmsgs(sk, cb);
707 }
708
709 /**
710  * Receive a set of message from a netlink socket using handlers in nl_sock.
711  * @arg sk              Netlink socket.
712  *
713  * Calls nl_recvmsgs() with the handlers configured in the netlink socket.
714  */
715 int nl_recvmsgs_default(struct nl_sock *sk)
716 {
717         return nl_recvmsgs(sk, sk->s_cb);
718
719 }
720
721 static int ack_wait_handler(struct nl_msg *msg, void *arg)
722 {
723         return NL_STOP;
724 }
725
726 /**
727  * Wait for ACK.
728  * @arg sk              Netlink socket.
729  * @pre The netlink socket must be in blocking state.
730  *
731  * Waits until an ACK is received for the latest not yet acknowledged
732  * netlink message.
733  */
734 int nl_wait_for_ack(struct nl_sock *sk)
735 {
736         int err;
737         struct nl_cb *cb;
738
739         cb = nl_cb_clone(sk->s_cb);
740         if (cb == NULL)
741                 return -NLE_NOMEM;
742
743         nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
744         err = nl_recvmsgs(sk, cb);
745         nl_cb_put(cb);
746
747         return err;
748 }
749
750 /** @} */
751
752 /** @} */