libnl 3.7.0
nl.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
4 */
5
6/**
7 * @defgroup core Core Library (libnl)
8 *
9 * Socket handling, connection management, sending and receiving of data,
10 * message construction and parsing, object caching system, ...
11 *
12 * This is the API reference of the core library. It is not meant as a guide
13 * but as a reference. Please refer to the core library guide for detailed
14 * documentation on the library architecture and examples:
15 *
16 * * @ref_asciidoc{core,_,Netlink Core Library Development Guide}
17 *
18 *
19 * @{
20 */
21
22#include <netlink-private/netlink.h>
23#include <netlink-private/socket.h>
24#include <netlink-private/utils.h>
25#include <netlink/netlink.h>
26#include <netlink/utils.h>
27#include <netlink/handlers.h>
28#include <netlink/msg.h>
29#include <netlink/attr.h>
30#include <linux/socket.h>
31
32/**
33 * @defgroup core_types Data Types
34 *
35 * Core library data types
36 * @{
37 * @}
38 *
39 * @defgroup send_recv Send & Receive Data
40 *
41 * Connection management, sending & receiving of data
42 *
43 * Related sections in the development guide:
44 * - @core_doc{core_send_recv, Sending & Receiving}
45 * - @core_doc{core_sockets, Sockets}
46 *
47 * @{
48 *
49 * Header
50 * ------
51 * ~~~~{.c}
52 * #include <netlink/netlink.h>
53 * ~~~~
54 */
55
56/**
57 * @name Connection Management
58 * @{
59 */
60
61/**
62 * Create file descriptor and bind socket.
63 * @arg sk Netlink socket (required)
64 * @arg protocol Netlink protocol to use (required)
65 *
66 * Creates a new Netlink socket using `socket()` and binds the socket to the
67 * protocol and local port specified in the `sk` socket object. Fails if
68 * the socket is already connected.
69 *
70 * @note If available, the `close-on-exec` (`SOCK_CLOEXEC`) feature is enabled
71 * automatically on the new file descriptor. This causes the socket to
72 * be closed automatically if any of the `exec` family functions succeed.
73 * This is essential for multi threaded programs.
74 *
75 * @note The local port (`nl_socket_get_local_port()`) is unspecified after
76 * creating a new socket. It only gets determined when accessing the
77 * port the first time or during `nl_connect()`. When nl_connect()
78 * fails during `bind()` due to `ADDRINUSE`, it will retry with
79 * different ports if the port is unspecified. Unless you want to enforce
80 * the use of a specific local port, don't access the local port (or
81 * reset it to `unspecified` by calling `nl_socket_set_local_port(sk, 0)`).
82 * This capability is indicated by
83 * `%NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE`.
84 *
85 * @note nl_connect() creates and sets the file descriptor. You can setup the file
86 * descriptor yourself by creating and binding it, and then calling
87 * nl_socket_set_fd(). The result will be the same.
88 *
89 * @see nl_socket_alloc()
90 * @see nl_close()
91 * @see nl_socket_set_fd()
92 *
93 * @return 0 on success or a negative error code.
94 *
95 * @retval -NLE_BAD_SOCK Socket is already connected
96 */
97int nl_connect(struct nl_sock *sk, int protocol)
98{
99 int err, flags = 0;
100 int errsv;
101 socklen_t addrlen;
102 struct sockaddr_nl local = { 0 };
103 int try_bind = 1;
104
105#ifdef SOCK_CLOEXEC
106 flags |= SOCK_CLOEXEC;
107#endif
108
109 if (sk->s_fd != -1)
110 return -NLE_BAD_SOCK;
111
112 sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
113 if (sk->s_fd < 0) {
114 errsv = errno;
115 NL_DBG(4, "nl_connect(%p): socket() failed with %d (%s)\n", sk, errsv,
116 nl_strerror_l(errsv));
117 err = -nl_syserr2nlerr(errsv);
118 goto errout;
119 }
120
121 err = nl_socket_set_buffer_size(sk, 0, 0);
122 if (err < 0)
123 goto errout;
124
125 if (_nl_socket_is_local_port_unspecified (sk)) {
126 uint32_t port;
127 uint32_t used_ports[32] = { 0 };
128 int ntries = 0;
129
130 while (1) {
131 if (ntries++ > 5) {
132 /* try only a few times. We hit this only if many ports are already in
133 * use but allocated *outside* libnl/generate_local_port(). */
134 _nl_socket_set_local_port_no_release (sk, 0);
135 break;
136 }
137
138 port = _nl_socket_set_local_port_no_release(sk, 1);
139 if (port == 0)
140 break;
141
142 err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
143 sizeof(sk->s_local));
144 if (err == 0) {
145 try_bind = 0;
146 break;
147 }
148
149 errsv = errno;
150 if (errsv == EADDRINUSE) {
151 NL_DBG(4, "nl_connect(%p): local port %u already in use. Retry.\n", sk, (unsigned) port);
152 _nl_socket_used_ports_set(used_ports, port);
153 } else {
154 NL_DBG(4, "nl_connect(%p): bind() for port %u failed with %d (%s)\n",
155 sk, (unsigned) port, errsv, nl_strerror_l(errsv));
156 _nl_socket_used_ports_release_all(used_ports);
157 err = -nl_syserr2nlerr(errsv);
158 goto errout;
159 }
160 }
161 _nl_socket_used_ports_release_all(used_ports);
162 }
163 if (try_bind) {
164 err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
165 sizeof(sk->s_local));
166 if (err != 0) {
167 errsv = errno;
168 NL_DBG(4, "nl_connect(%p): bind() failed with %d (%s)\n",
169 sk, errsv, nl_strerror_l(errsv));
170 err = -nl_syserr2nlerr(errsv);
171 goto errout;
172 }
173 }
174
175 addrlen = sizeof(local);
176 err = getsockname(sk->s_fd, (struct sockaddr *) &local,
177 &addrlen);
178 if (err < 0) {
179 NL_DBG(4, "nl_connect(%p): getsockname() failed with %d (%s)\n",
180 sk, errno, nl_strerror_l(errno));
181 err = -nl_syserr2nlerr(errno);
182 goto errout;
183 }
184
185 if (addrlen != sizeof(local)) {
186 err = -NLE_NOADDR;
187 goto errout;
188 }
189
190 if (local.nl_family != AF_NETLINK) {
191 err = -NLE_AF_NOSUPPORT;
192 goto errout;
193 }
194
195 if (sk->s_local.nl_pid != local.nl_pid) {
196 /* The port id is different. That can happen if the port id was zero
197 * and kernel assigned a local port. */
198 nl_socket_set_local_port (sk, local.nl_pid);
199 }
200 sk->s_local = local;
201 sk->s_proto = protocol;
202
203 return 0;
204errout:
205 if (sk->s_fd != -1) {
206 close(sk->s_fd);
207 sk->s_fd = -1;
208 }
209
210 return err;
211}
212
213/**
214 * Close Netlink socket
215 * @arg sk Netlink socket (required)
216 *
217 * Closes the Netlink socket using `close()`.
218 *
219 * @note The socket is closed automatically if a `struct nl_sock` object is
220 * freed using `nl_socket_free()`.
221 *
222 * @see nl_connect()
223 */
224void nl_close(struct nl_sock *sk)
225{
226 if (sk->s_fd >= 0) {
227 close(sk->s_fd);
228 sk->s_fd = -1;
229 }
230
231 sk->s_proto = 0;
232}
233
234/** @} */
235
236/**
237 * @name Send
238 * @{
239 */
240
241/**
242 * Transmit raw data over Netlink socket.
243 * @arg sk Netlink socket (required)
244 * @arg buf Buffer carrying data to send (required)
245 * @arg size Size of buffer (required)
246 *
247 * Transmits "raw" data over the specified Netlink socket. Unlike the other
248 * transmit functions it does not modify the data in any way. It directly
249 * passes the buffer \c buf of \c size to sendto().
250 *
251 * The message is addressed to the peer as specified in the socket by either
252 * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function.
253 *
254 * @note Because there is no indication on the message boundaries of the data
255 * being sent, the \c NL_CB_MSG_OUT callback handler will not be invoked
256 * for data that is being sent using this function.
257 *
258 * @see nl_socket_set_peer_port()
259 * @see nl_socket_set_peer_groups()
260 * @see nl_sendmsg()
261 *
262 * @return Number of bytes sent or a negative error code.
263 */
264int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
265{
266 int ret;
267
268 if (!buf)
269 return -NLE_INVAL;
270
271 if (sk->s_fd < 0)
272 return -NLE_BAD_SOCK;
273
274 ret = sendto(sk->s_fd, buf, size, 0, (struct sockaddr *)
275 &sk->s_peer, sizeof(sk->s_peer));
276 if (ret < 0) {
277 NL_DBG(4, "nl_sendto(%p): sendto() failed with %d (%s)\n",
278 sk, errno, nl_strerror_l(errno));
279 return -nl_syserr2nlerr(errno);
280 }
281
282 return ret;
283}
284
285/**
286 * Transmit Netlink message using sendmsg()
287 * @arg sk Netlink socket (required)
288 * @arg msg Netlink message to be sent (required)
289 * @arg hdr sendmsg() message header (required)
290 *
291 * Transmits the message specified in \c hdr over the Netlink socket using the
292 * sendmsg() system call.
293 *
294 * @attention
295 * The `msg` argument will *not* be used to derive the message payload that
296 * is being sent out. The `msg` argument is *only* passed on to the
297 * `NL_CB_MSG_OUT` callback. The caller is responsible to initialize the
298 * `hdr` struct properly and have it point to the message payload and
299 * socket address.
300 *
301 * @note
302 * This function uses `nlmsg_set_src()` to modify the `msg` argument prior to
303 * invoking the `NL_CB_MSG_OUT` callback to provide the local port number.
304 *
305 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
306 *
307 * @attention
308 * Think twice before using this function. It provides a low level access to
309 * the Netlink socket. Among other limitations, it does not add credentials
310 * even if enabled or respect the destination address specified in the `msg`
311 * object.
312 *
313 * @see nl_socket_set_local_port()
314 * @see nl_send_auto()
315 * @see nl_send_iovec()
316 *
317 * @return Number of bytes sent on success or a negative error code.
318 *
319 * @lowlevel
320 */
321int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
322{
323 struct nl_cb *cb;
324 int ret;
325
326 if (sk->s_fd < 0)
327 return -NLE_BAD_SOCK;
328
329 nlmsg_set_src(msg, &sk->s_local);
330
331 cb = sk->s_cb;
332 if (cb->cb_set[NL_CB_MSG_OUT])
333 if ((ret = nl_cb_call(cb, NL_CB_MSG_OUT, msg)) != NL_OK)
334 return ret;
335
336 ret = sendmsg(sk->s_fd, hdr, 0);
337 if (ret < 0) {
338 NL_DBG(4, "nl_sendmsg(%p): sendmsg() failed with %d (%s)\n",
339 sk, errno, nl_strerror_l(errno));
340 return -nl_syserr2nlerr(errno);
341 }
342
343 NL_DBG(4, "sent %d bytes\n", ret);
344 return ret;
345}
346
347
348/**
349 * Transmit Netlink message (taking IO vector)
350 * @arg sk Netlink socket (required)
351 * @arg msg Netlink message to be sent (required)
352 * @arg iov IO vector to be sent (required)
353 * @arg iovlen Number of struct iovec to be sent (required)
354 *
355 * This function is identical to nl_send() except that instead of taking a
356 * `struct nl_msg` object it takes an IO vector. Please see the description
357 * of `nl_send()`.
358 *
359 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
360 *
361 * @see nl_send()
362 *
363 * @return Number of bytes sent on success or a negative error code.
364 *
365 * @lowlevel
366 */
367int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
368{
369 struct sockaddr_nl *dst;
370 struct ucred *creds;
371 struct msghdr hdr = {
372 .msg_name = (void *) &sk->s_peer,
373 .msg_namelen = sizeof(struct sockaddr_nl),
374 .msg_iov = iov,
375 .msg_iovlen = iovlen,
376 };
377 char buf[CMSG_SPACE(sizeof(struct ucred))];
378
379 /* Overwrite destination if specified in the message itself, defaults
380 * to the peer address of the socket.
381 */
382 dst = nlmsg_get_dst(msg);
383 if (dst->nl_family == AF_NETLINK)
384 hdr.msg_name = dst;
385
386 /* Add credentials if present. */
387 creds = nlmsg_get_creds(msg);
388 if (creds != NULL) {
389 struct cmsghdr *cmsg;
390
391 hdr.msg_control = buf;
392 hdr.msg_controllen = sizeof(buf);
393
394 cmsg = CMSG_FIRSTHDR(&hdr);
395 cmsg->cmsg_level = SOL_SOCKET;
396 cmsg->cmsg_type = SCM_CREDENTIALS;
397 cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
398 memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred));
399 }
400
401 return nl_sendmsg(sk, msg, &hdr);
402}
403
404/**
405 * Transmit Netlink message
406 * @arg sk Netlink socket (required)
407 * @arg msg Netlink message (required)
408 *
409 * Transmits the Netlink message `msg` over the Netlink socket using the
410 * `sendmsg()` system call. This function is based on `nl_send_iovec()` but
411 * takes care of initializing a `struct iovec` based on the `msg` object.
412 *
413 * The message is addressed to the peer as specified in the socket by either
414 * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function.
415 * The peer address can be overwritten by specifying an address in the `msg`
416 * object using nlmsg_set_dst().
417 *
418 * If present in the `msg`, credentials set by the nlmsg_set_creds() function
419 * are added to the control buffer of the message.
420 *
421 * @par Overwriting Capability:
422 * Calls to this function can be overwritten by providing an alternative using
423 * the nl_cb_overwrite_send() function.
424 *
425 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
426 *
427 * @attention
428 * Unlike `nl_send_auto()`, this function does *not* finalize the message in
429 * terms of automatically adding needed flags or filling out port numbers.
430 *
431 * @see nl_send_auto()
432 * @see nl_send_iovec()
433 * @see nl_socket_set_peer_port()
434 * @see nl_socket_set_peer_groups()
435 * @see nlmsg_set_dst()
436 * @see nlmsg_set_creds()
437 * @see nl_cb_overwrite_send()
438 *
439 * @return Number of bytes sent on success or a negative error code.
440*/
441int nl_send(struct nl_sock *sk, struct nl_msg *msg)
442{
443 struct nl_cb *cb = sk->s_cb;
444
445 if (cb->cb_send_ow)
446 return cb->cb_send_ow(sk, msg);
447 else {
448 struct iovec iov = {
449 .iov_base = (void *) nlmsg_hdr(msg),
450 .iov_len = nlmsg_hdr(msg)->nlmsg_len,
451 };
452
453 return nl_send_iovec(sk, msg, &iov, 1);
454 }
455}
456
457/**
458 * Finalize Netlink message
459 * @arg sk Netlink socket (required)
460 * @arg msg Netlink message (required)
461 *
462 * This function finalizes a Netlink message by completing the message with
463 * desirable flags and values depending on the socket configuration.
464 *
465 * - If not yet filled out, the source address of the message (`nlmsg_pid`)
466 * will be set to the local port number of the socket.
467 * - If not yet specified, the next available sequence number is assigned
468 * to the message (`nlmsg_seq`).
469 * - If not yet specified, the protocol field of the message will be set to
470 * the protocol field of the socket.
471 * - The `NLM_F_REQUEST` Netlink message flag will be set.
472 * - The `NLM_F_ACK` flag will be set if Auto-ACK mode is enabled on the
473 * socket.
474 */
475void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
476{
477 struct nlmsghdr *nlh;
478
479 nlh = nlmsg_hdr(msg);
480 if (nlh->nlmsg_pid == NL_AUTO_PORT)
481 nlh->nlmsg_pid = nl_socket_get_local_port(sk);
482
483 if (nlh->nlmsg_seq == NL_AUTO_SEQ)
484 nlh->nlmsg_seq = sk->s_seq_next++;
485
486 if (msg->nm_protocol == -1)
487 msg->nm_protocol = sk->s_proto;
488
489 nlh->nlmsg_flags |= NLM_F_REQUEST;
490
491 if (!(sk->s_flags & NL_NO_AUTO_ACK))
492 nlh->nlmsg_flags |= NLM_F_ACK;
493}
494
495/**
496 * Finalize and transmit Netlink message
497 * @arg sk Netlink socket (required)
498 * @arg msg Netlink message (required)
499 *
500 * Finalizes the message by passing it to `nl_complete_msg()` and transmits it
501 * by passing it to `nl_send()`.
502 *
503 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
504 *
505 * @see nl_complete_msg()
506 * @see nl_send()
507 *
508 * @return Number of bytes sent or a negative error code.
509 */
510int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
511{
512 nl_complete_msg(sk, msg);
513
514 return nl_send(sk, msg);
515}
516
517/**
518 * Finalize and transmit Netlink message and wait for ACK or error message
519 * @arg sk Netlink socket (required)
520 * @arg msg Netlink message (required)
521 *
522 * Passes the `msg` to `nl_send_auto()` to finalize and transmit it. Frees the
523 * message and waits (sleeps) for the ACK or error message to be received.
524 *
525 * @attention
526 * Disabling Auto-ACK (nl_socket_disable_auto_ack()) will cause this function
527 * to return immediately after transmitting the message. However, the peer may
528 * still be returning an error message in response to the request. It is the
529 * responsibility of the caller to handle such messages.
530 *
531 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
532 *
533 * @attention
534 * This function frees the `msg` object after transmitting it by calling
535 * `nlmsg_free()`.
536 *
537 * @see nl_send_auto().
538 * @see nl_wait_for_ack()
539 *
540 * @return 0 on success or a negative error code.
541 */
542int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
543{
544 int err;
545
546 err = nl_send_auto(sk, msg);
547 nlmsg_free(msg);
548 if (err < 0)
549 return err;
550
551 return wait_for_ack(sk);
552}
553
554/**
555 * Construct and transmit a Netlink message
556 * @arg sk Netlink socket (required)
557 * @arg type Netlink message type (required)
558 * @arg flags Netlink message flags (optional)
559 * @arg buf Data buffer (optional)
560 * @arg size Size of data buffer (optional)
561 *
562 * Allocates a new Netlink message based on `type` and `flags`. If `buf`
563 * points to payload of length `size` that payload will be appended to the
564 * message.
565 *
566 * Sends out the message using `nl_send_auto()` and frees the message
567 * afterwards.
568 *
569 * @see nl_send_auto()
570 *
571 * @return Number of characters sent on success or a negative error code.
572 * @retval -NLE_NOMEM Unable to allocate Netlink message
573 */
574int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
575 size_t size)
576{
577 int err;
578 struct nl_msg *msg;
579
580 msg = nlmsg_alloc_simple(type, flags);
581 if (!msg)
582 return -NLE_NOMEM;
583
584 if (buf && size) {
585 err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
586 if (err < 0)
587 goto errout;
588 }
589
590 err = nl_send_auto(sk, msg);
591errout:
592 nlmsg_free(msg);
593
594 return err;
595}
596
597/** @} */
598
599/**
600 * @name Receive
601 * @{
602 */
603
604/**
605 * Receive data from netlink socket
606 * @arg sk Netlink socket (required)
607 * @arg nla Netlink socket structure to hold address of peer (required)
608 * @arg buf Destination pointer for message content (required)
609 * @arg creds Destination pointer for credentials (optional)
610 *
611 * Receives data from a connected netlink socket using recvmsg() and returns
612 * the number of bytes read. The read data is stored in a newly allocated
613 * buffer that is assigned to \c *buf. The peer's netlink address will be
614 * stored in \c *nla.
615 *
616 * This function blocks until data is available to be read unless the socket
617 * has been put into non-blocking mode using nl_socket_set_nonblocking() in
618 * which case this function will return immediately with a return value of
619 * -NLA_AGAIN (versions before 3.2.22 returned instead 0, in which case you
620 * should check first clear errno and then check for errno EAGAIN).
621 *
622 * The buffer size used when reading from the netlink socket and thus limiting
623 * the maximum size of a netlink message that can be read defaults to the size
624 * of a memory page (getpagesize()). The buffer size can be modified on a per
625 * socket level using the function nl_socket_set_msg_buf_size().
626 *
627 * If message peeking is enabled using nl_socket_enable_msg_peek() the size of
628 * the message to be read will be determined using the MSG_PEEK flag prior to
629 * performing the actual read. This leads to an additional recvmsg() call for
630 * every read operation which has performance implications and is not
631 * recommended for high throughput protocols.
632 *
633 * An eventual interruption of the recvmsg() system call is automatically
634 * handled by retrying the operation.
635 *
636 * If receiving of credentials has been enabled using the function
637 * nl_socket_set_passcred(), this function will allocate a new struct ucred
638 * filled with the received credentials and assign it to \c *creds. The caller
639 * is responsible for freeing the buffer.
640 *
641 * @note The caller is responsible to free the returned data buffer and if
642 * enabled, the credentials buffer.
643 *
644 * @see nl_socket_set_nonblocking()
645 * @see nl_socket_set_msg_buf_size()
646 * @see nl_socket_enable_msg_peek()
647 * @see nl_socket_set_passcred()
648 *
649 * @return Number of bytes read, 0 on EOF, 0 on no data event (non-blocking
650 * mode), or a negative error code.
651 */
652int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
653 unsigned char **buf, struct ucred **creds)
654{
655 ssize_t n;
656 int flags = 0;
657 static int page_size = 0;
658 struct iovec iov;
659 struct msghdr msg = {
660 .msg_name = (void *) nla,
661 .msg_namelen = sizeof(struct sockaddr_nl),
662 .msg_iov = &iov,
663 .msg_iovlen = 1,
664 };
665 struct ucred* tmpcreds = NULL;
666 int retval = 0;
667
668 if (!buf || !nla)
669 return -NLE_INVAL;
670
671 if ( (sk->s_flags & NL_MSG_PEEK)
672 || (!(sk->s_flags & NL_MSG_PEEK_EXPLICIT) && sk->s_bufsize == 0))
673 flags |= MSG_PEEK | MSG_TRUNC;
674
675 if (page_size == 0)
676 page_size = getpagesize() * 4;
677
678 iov.iov_len = sk->s_bufsize ? sk->s_bufsize : page_size;
679 iov.iov_base = malloc(iov.iov_len);
680
681 if (!iov.iov_base) {
682 retval = -NLE_NOMEM;
683 goto abort;
684 }
685
686 if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
687 msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
688 msg.msg_control = malloc(msg.msg_controllen);
689 if (!msg.msg_control) {
690 retval = -NLE_NOMEM;
691 goto abort;
692 }
693 }
694retry:
695
696 n = recvmsg(sk->s_fd, &msg, flags);
697 if (!n) {
698 retval = 0;
699 goto abort;
700 }
701 if (n < 0) {
702 if (errno == EINTR) {
703 NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
704 goto retry;
705 }
706
707 NL_DBG(4, "recvmsg(%p): nl_recv() failed with %d (%s)\n",
708 sk, errno, nl_strerror_l(errno));
709 retval = -nl_syserr2nlerr(errno);
710 goto abort;
711 }
712
713 if (msg.msg_flags & MSG_CTRUNC) {
714 void *tmp;
715
716 if (msg.msg_controllen == 0) {
717 retval = -NLE_MSG_TRUNC;
718 NL_DBG(4, "recvmsg(%p): Received unexpected control data", sk);
719 goto abort;
720 }
721
722 msg.msg_controllen *= 2;
723 tmp = realloc(msg.msg_control, msg.msg_controllen);
724 if (!tmp) {
725 retval = -NLE_NOMEM;
726 goto abort;
727 }
728 msg.msg_control = tmp;
729 goto retry;
730 }
731
732 if (iov.iov_len < n || (msg.msg_flags & MSG_TRUNC)) {
733 void *tmp;
734
735 /* respond with error to an incomplete message */
736 if (flags == 0) {
737 retval = -NLE_MSG_TRUNC;
738 goto abort;
739 }
740
741 /* Provided buffer is not long enough, enlarge it
742 * to size of n (which should be total length of the message)
743 * and try again. */
744 iov.iov_len = n;
745 tmp = realloc(iov.iov_base, iov.iov_len);
746 if (!tmp) {
747 retval = -NLE_NOMEM;
748 goto abort;
749 }
750 iov.iov_base = tmp;
751 flags = 0;
752 goto retry;
753 }
754
755 if (flags != 0) {
756 /* Buffer is big enough, do the actual reading */
757 flags = 0;
758 goto retry;
759 }
760
761 if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
762 retval = -NLE_NOADDR;
763 goto abort;
764 }
765
766 if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
767 struct cmsghdr *cmsg;
768
769 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
770 if (cmsg->cmsg_level != SOL_SOCKET)
771 continue;
772 if (cmsg->cmsg_type != SCM_CREDENTIALS)
773 continue;
774 tmpcreds = malloc(sizeof(*tmpcreds));
775 if (!tmpcreds) {
776 retval = -NLE_NOMEM;
777 goto abort;
778 }
779 memcpy(tmpcreds, CMSG_DATA(cmsg), sizeof(*tmpcreds));
780 break;
781 }
782 }
783
784 retval = n;
785abort:
786 free(msg.msg_control);
787
788 if (retval <= 0) {
789 free(iov.iov_base);
790 iov.iov_base = NULL;
791 free(tmpcreds);
792 tmpcreds = NULL;
793 } else
794 *buf = iov.iov_base;
795
796 if (creds)
797 *creds = tmpcreds;
798
799 return retval;
800}
801
802/** @cond SKIP */
803#define NL_CB_CALL(cb, type, msg) \
804do { \
805 err = nl_cb_call(cb, type, msg); \
806 switch (err) { \
807 case NL_OK: \
808 err = 0; \
809 break; \
810 case NL_SKIP: \
811 goto skip; \
812 case NL_STOP: \
813 goto stop; \
814 default: \
815 goto out; \
816 } \
817} while (0)
818/** @endcond */
819
820static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
821{
822 int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0;
823 unsigned char *buf = NULL;
824 struct nlmsghdr *hdr;
825
826 /*
827 nla is passed on to not only to nl_recv() but may also be passed
828 to a function pointer provided by the caller which may or may not
829 initialize the variable. Thomas Graf.
830 */
831 struct sockaddr_nl nla = {0};
832 struct nl_msg *msg = NULL;
833 struct ucred *creds = NULL;
834
835continue_reading:
836 NL_DBG(3, "Attempting to read from %p\n", sk);
837 if (cb->cb_recv_ow)
838 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
839 else
840 n = nl_recv(sk, &nla, &buf, &creds);
841
842 if (n <= 0)
843 return n;
844
845 NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);
846
847 hdr = (struct nlmsghdr *) buf;
848 while (nlmsg_ok(hdr, n)) {
849 NL_DBG(3, "recvmsgs(%p): Processing valid message...\n", sk);
850
851 nlmsg_free(msg);
852 msg = nlmsg_convert(hdr);
853 if (!msg) {
854 err = -NLE_NOMEM;
855 goto out;
856 }
857
858 nlmsg_set_proto(msg, sk->s_proto);
859 nlmsg_set_src(msg, &nla);
860 if (creds)
861 nlmsg_set_creds(msg, creds);
862
863 nrecv++;
864
865 /* Raw callback is the first, it gives the most control
866 * to the user and he can do his very own parsing. */
867 if (cb->cb_set[NL_CB_MSG_IN])
868 NL_CB_CALL(cb, NL_CB_MSG_IN, msg);
869
870 /* Sequence number checking. The check may be done by
871 * the user, otherwise a very simple check is applied
872 * enforcing strict ordering */
873 if (cb->cb_set[NL_CB_SEQ_CHECK]) {
874 NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);
875
876 /* Only do sequence checking if auto-ack mode is enabled */
877 } else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
878 if (hdr->nlmsg_seq != sk->s_seq_expect) {
879 if (cb->cb_set[NL_CB_INVALID])
880 NL_CB_CALL(cb, NL_CB_INVALID, msg);
881 else {
882 err = -NLE_SEQ_MISMATCH;
883 goto out;
884 }
885 }
886 }
887
888 if (hdr->nlmsg_type == NLMSG_DONE ||
889 hdr->nlmsg_type == NLMSG_ERROR ||
890 hdr->nlmsg_type == NLMSG_NOOP ||
891 hdr->nlmsg_type == NLMSG_OVERRUN) {
892 /* We can't check for !NLM_F_MULTI since some netlink
893 * users in the kernel are broken. */
894 sk->s_seq_expect++;
895 NL_DBG(3, "recvmsgs(%p): Increased expected " \
896 "sequence number to %d\n",
897 sk, sk->s_seq_expect);
898 }
899
900 if (hdr->nlmsg_flags & NLM_F_MULTI)
901 multipart = 1;
902
903 if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) {
904 if (cb->cb_set[NL_CB_DUMP_INTR])
905 NL_CB_CALL(cb, NL_CB_DUMP_INTR, msg);
906 else {
907 /*
908 * We have to continue reading to clear
909 * all messages until a NLMSG_DONE is
910 * received and report the inconsistency.
911 */
912 interrupted = 1;
913 }
914 }
915
916 /* Other side wishes to see an ack for this message */
917 if (hdr->nlmsg_flags & NLM_F_ACK) {
918 if (cb->cb_set[NL_CB_SEND_ACK])
919 NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
920 else {
921 /* FIXME: implement */
922 }
923 }
924
925 /* messages terminates a multipart message, this is
926 * usually the end of a message and therefore we slip
927 * out of the loop by default. the user may overrule
928 * this action by skipping this packet. */
929 if (hdr->nlmsg_type == NLMSG_DONE) {
930 multipart = 0;
931 if (cb->cb_set[NL_CB_FINISH])
932 NL_CB_CALL(cb, NL_CB_FINISH, msg);
933 }
934
935 /* Message to be ignored, the default action is to
936 * skip this message if no callback is specified. The
937 * user may overrule this action by returning
938 * NL_PROCEED. */
939 else if (hdr->nlmsg_type == NLMSG_NOOP) {
940 if (cb->cb_set[NL_CB_SKIPPED])
941 NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
942 else
943 goto skip;
944 }
945
946 /* Data got lost, report back to user. The default action is to
947 * quit parsing. The user may overrule this action by retuning
948 * NL_SKIP or NL_PROCEED (dangerous) */
949 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
950 if (cb->cb_set[NL_CB_OVERRUN])
951 NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
952 else {
953 err = -NLE_MSG_OVERFLOW;
954 goto out;
955 }
956 }
957
958 /* Message carries a nlmsgerr */
959 else if (hdr->nlmsg_type == NLMSG_ERROR) {
960 struct nlmsgerr *e = nlmsg_data(hdr);
961
962 if (hdr->nlmsg_len < nlmsg_size(sizeof(*e))) {
963 /* Truncated error message, the default action
964 * is to stop parsing. The user may overrule
965 * this action by returning NL_SKIP or
966 * NL_PROCEED (dangerous) */
967 if (cb->cb_set[NL_CB_INVALID])
968 NL_CB_CALL(cb, NL_CB_INVALID, msg);
969 else {
970 err = -NLE_MSG_TRUNC;
971 goto out;
972 }
973 } else if (e->error) {
974 NL_DBG(4, "recvmsgs(%p): RTNETLINK responded with %d (%s)\n",
975 sk, -e->error, nl_strerror_l(-e->error));
976
977 /* Error message reported back from kernel. */
978 if (cb->cb_err) {
979 err = cb->cb_err(&nla, e,
980 cb->cb_err_arg);
981 if (err < 0)
982 goto out;
983 else if (err == NL_SKIP)
984 goto skip;
985 else if (err == NL_STOP) {
986 err = -nl_syserr2nlerr(e->error);
987 goto out;
988 }
989 } else {
990 err = -nl_syserr2nlerr(e->error);
991 goto out;
992 }
993 } else if (cb->cb_set[NL_CB_ACK])
994 NL_CB_CALL(cb, NL_CB_ACK, msg);
995 } else {
996 /* Valid message (not checking for MULTIPART bit to
997 * get along with broken kernels. NL_SKIP has no
998 * effect on this. */
999 if (cb->cb_set[NL_CB_VALID])
1000 NL_CB_CALL(cb, NL_CB_VALID, msg);
1001 }
1002skip:
1003 err = 0;
1004 hdr = nlmsg_next(hdr, &n);
1005 }
1006
1007 nlmsg_free(msg);
1008 free(buf);
1009 free(creds);
1010 buf = NULL;
1011 msg = NULL;
1012 creds = NULL;
1013
1014 if (multipart) {
1015 /* Multipart message not yet complete, continue reading */
1016 goto continue_reading;
1017 }
1018stop:
1019 err = 0;
1020out:
1021 nlmsg_free(msg);
1022 free(buf);
1023 free(creds);
1024
1025 if (interrupted)
1026 err = -NLE_DUMP_INTR;
1027
1028 if (!err)
1029 err = nrecv;
1030
1031 return err;
1032}
1033
1034/**
1035 * Receive a set of messages from a netlink socket and report parsed messages
1036 * @arg sk Netlink socket.
1037 * @arg cb set of callbacks to control behaviour.
1038 *
1039 * This function is identical to nl_recvmsgs() to the point that it will
1040 * return the number of parsed messages instead of 0 on success.
1041 *
1042 * @see nl_recvmsgs()
1043 *
1044 * @return Number of received messages or a negative error code from nl_recv().
1045 */
1046int nl_recvmsgs_report(struct nl_sock *sk, struct nl_cb *cb)
1047{
1048 if (cb->cb_recvmsgs_ow)
1049 return cb->cb_recvmsgs_ow(sk, cb);
1050 else
1051 return recvmsgs(sk, cb);
1052}
1053
1054/**
1055 * Receive a set of messages from a netlink socket.
1056 * @arg sk Netlink socket.
1057 * @arg cb set of callbacks to control behaviour.
1058 *
1059 * Repeatedly calls nl_recv() or the respective replacement if provided
1060 * by the application (see nl_cb_overwrite_recv()) and parses the
1061 * received data as netlink messages. Stops reading if one of the
1062 * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
1063 *
1064 * A non-blocking sockets causes the function to return immediately if
1065 * no data is available.
1066 *
1067 * @see nl_recvmsgs_report()
1068 *
1069 * @return 0 on success or a negative error code from nl_recv().
1070 */
1071int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
1072{
1073 int err;
1074
1075 if ((err = nl_recvmsgs_report(sk, cb)) > 0)
1076 err = 0;
1077
1078 return err;
1079}
1080
1081/**
1082 * Receive a set of message from a netlink socket using handlers in nl_sock.
1083 * @arg sk Netlink socket.
1084 *
1085 * Calls nl_recvmsgs() with the handlers configured in the netlink socket.
1086 */
1087int nl_recvmsgs_default(struct nl_sock *sk)
1088{
1089 return nl_recvmsgs(sk, sk->s_cb);
1090
1091}
1092
1093static int ack_wait_handler(struct nl_msg *msg, void *arg)
1094{
1095 return NL_STOP;
1096}
1097
1098/**
1099 * Wait for ACK.
1100 * @arg sk Netlink socket.
1101 * @pre The netlink socket must be in blocking state.
1102 *
1103 * Waits until an ACK is received for the latest not yet acknowledged
1104 * netlink message.
1105 */
1106int nl_wait_for_ack(struct nl_sock *sk)
1107{
1108 int err;
1109 struct nl_cb *cb;
1110
1111 cb = nl_cb_clone(sk->s_cb);
1112 if (cb == NULL)
1113 return -NLE_NOMEM;
1114
1115 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
1116 err = nl_recvmsgs(sk, cb);
1117 nl_cb_put(cb);
1118
1119 return err;
1120}
1121
1122/** @cond SKIP */
1123struct pickup_param
1124{
1125 int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
1126 struct nlmsghdr *, struct nl_parser_param *);
1127 struct nl_object *result;
1128 int *syserror;
1129};
1130
1131static int __store_answer(struct nl_object *obj, struct nl_parser_param *p)
1132{
1133 struct pickup_param *pp = p->pp_arg;
1134 /*
1135 * the parser will put() the object at the end, expecting the cache
1136 * to take the reference.
1137 */
1138 nl_object_get(obj);
1139 pp->result = obj;
1140
1141 return 0;
1142}
1143
1144static int __pickup_answer(struct nl_msg *msg, void *arg)
1145{
1146 struct pickup_param *pp = arg;
1147 struct nl_parser_param parse_arg = {
1148 .pp_cb = __store_answer,
1149 .pp_arg = pp,
1150 };
1151
1152 return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
1153}
1154
1155static int __pickup_answer_syserr(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg)
1156{
1157 *(((struct pickup_param *) arg)->syserror) = nlerr->error;
1158
1159 return -nl_syserr2nlerr(nlerr->error);
1160}
1161
1162/** @endcond */
1163
1164/**
1165 * Pickup netlink answer, parse is and return object
1166 * @arg sk Netlink socket
1167 * @arg parser Parser function to parse answer
1168 * @arg result Result pointer to return parsed object
1169 *
1170 * @return 0 on success or a negative error code.
1171 */
1172int nl_pickup(struct nl_sock *sk,
1173 int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
1174 struct nlmsghdr *, struct nl_parser_param *),
1175 struct nl_object **result)
1176{
1177 return nl_pickup_keep_syserr(sk, parser, result, NULL);
1178}
1179
1180/**
1181 * Pickup netlink answer, parse is and return object with preserving system error
1182 * @arg sk Netlink socket
1183 * @arg parser Parser function to parse answer
1184 * @arg result Result pointer to return parsed object
1185 * @arg syserr Result pointer for the system error in case of failure
1186 *
1187 * @return 0 on success or a negative error code.
1188 */
1189int nl_pickup_keep_syserr(struct nl_sock *sk,
1190 int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
1191 struct nlmsghdr *, struct nl_parser_param *),
1192 struct nl_object **result,
1193 int *syserror)
1194{
1195 struct nl_cb *cb;
1196 int err;
1197 struct pickup_param pp = {
1198 .parser = parser,
1199 };
1200
1201 cb = nl_cb_clone(sk->s_cb);
1202 if (cb == NULL)
1203 return -NLE_NOMEM;
1204
1205 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp);
1206 if (syserror) {
1207 *syserror = 0;
1208 pp.syserror = syserror;
1209 nl_cb_err(cb, NL_CB_CUSTOM, __pickup_answer_syserr, &pp);
1210 }
1211
1212 err = nl_recvmsgs(sk, cb);
1213 if (err < 0)
1214 goto errout;
1215
1216 *result = pp.result;
1217errout:
1218 nl_cb_put(cb);
1219
1220 return err;
1221}
1222
1223/** @} */
1224
1225/**
1226 * @name Deprecated
1227 * @{
1228 */
1229
1230/**
1231 * @deprecated Please use nl_complete_msg()
1232 */
1233void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
1234{
1235 nl_complete_msg(sk, msg);
1236}
1237
1238/**
1239 * @deprecated Please use nl_send_auto()
1240 */
1241int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
1242{
1243 return nl_send_auto(sk, msg);
1244}
1245
1246
1247/** @} */
1248
1249/** @} */
1250
1251/** @} */
int 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)
Set up a callback.
Definition: handlers.c:287
struct nl_cb * nl_cb_clone(struct nl_cb *orig)
Clone an existing callback handle.
Definition: handlers.c:224
int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, nl_recvmsg_err_cb_t func, void *arg)
Set up an error callback.
Definition: handlers.c:337
@ NL_STOP
Stop parsing altogether and discard remaining messages.
Definition: handlers.h:62
@ NL_OK
Proceed with whatever would come next.
Definition: handlers.h:58
@ NL_SKIP
Skip this message.
Definition: handlers.h:60
@ NL_CB_SKIPPED
Message wants to be skipped.
Definition: handlers.h:95
@ NL_CB_FINISH
Last message in a series of multi part messages received.
Definition: handlers.h:91
@ NL_CB_MSG_OUT
Called for every message sent out except for nl_sendto()
Definition: handlers.h:101
@ NL_CB_DUMP_INTR
Flag NLM_F_DUMP_INTR is set in message.
Definition: handlers.h:109
@ NL_CB_MSG_IN
Called for every message received.
Definition: handlers.h:99
@ NL_CB_OVERRUN
Report received that data was lost.
Definition: handlers.h:93
@ NL_CB_VALID
Message is valid.
Definition: handlers.h:89
@ NL_CB_ACK
Message is an acknowledgement.
Definition: handlers.h:97
@ NL_CB_SEQ_CHECK
Called instead of internal sequence number checking.
Definition: handlers.h:105
@ NL_CB_SEND_ACK
Sending of an acknowledge message has been requested.
Definition: handlers.h:107
@ NL_CB_INVALID
Message is malformed and invalid.
Definition: handlers.h:103
@ NL_CB_CUSTOM
Customized handler specified by the user.
Definition: handlers.h:77
int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
check if the netlink message fits into the remaining bytes
Definition: msg.c:174
#define NL_AUTO_PORT
Will cause the netlink port to be set to the port assigned to the netlink icoket ust before sending t...
Definition: msg.h:29
struct nlmsghdr * nlmsg_hdr(struct nl_msg *n)
Return actual netlink message.
Definition: msg.c:536
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition: msg.c:341
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:100
struct nlmsghdr * nlmsg_next(struct nlmsghdr *nlh, int *remaining)
next netlink message in message stream
Definition: msg.c:189
struct nl_msg * nlmsg_convert(struct nlmsghdr *hdr)
Convert a netlink message received from a netlink socket to a nl_msg.
Definition: msg.c:379
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:558
#define NL_AUTO_SEQ
May be used to refer to a sequence number which should be automatically set just before sending the m...
Definition: msg.h:40
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition: msg.c:442
int nlmsg_size(int payload)
Calculates size of netlink message based on payload length.
Definition: msg.c:49
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:203
int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
Transmit Netlink message (taking IO vector)
Definition: nl.c:367
int nl_send(struct nl_sock *sk, struct nl_msg *msg)
Transmit Netlink message.
Definition: nl.c:441
int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla, unsigned char **buf, struct ucred **creds)
Receive data from netlink socket.
Definition: nl.c:652
int nl_recvmsgs_default(struct nl_sock *sk)
Receive a set of message from a netlink socket using handlers in nl_sock.
Definition: nl.c:1087
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message.
Definition: nl.c:510
void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
Finalize Netlink message.
Definition: nl.c:475
int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message and wait for ACK or error message.
Definition: nl.c:542
void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1233
int nl_connect(struct nl_sock *sk, int protocol)
Create file descriptor and bind socket.
Definition: nl.c:97
int nl_recvmsgs_report(struct nl_sock *sk, struct nl_cb *cb)
Receive a set of messages from a netlink socket and report parsed messages.
Definition: nl.c:1046
int nl_pickup_keep_syserr(struct nl_sock *sk, int(*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result, int *syserror)
Pickup netlink answer, parse is and return object with preserving system error.
Definition: nl.c:1189
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1241
int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
Receive a set of messages from a netlink socket.
Definition: nl.c:1071
int nl_pickup(struct nl_sock *sk, int(*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result)
Pickup netlink answer, parse is and return object.
Definition: nl.c:1172
void nl_close(struct nl_sock *sk)
Close Netlink socket.
Definition: nl.c:224
int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
Transmit Netlink message using sendmsg()
Definition: nl.c:321
int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
Transmit raw data over Netlink socket.
Definition: nl.c:264
int nl_wait_for_ack(struct nl_sock *sk)
Wait for ACK.
Definition: nl.c:1106
int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf, size_t size)
Construct and transmit a Netlink message.
Definition: nl.c:574
void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port)
Set local port of socket.
Definition: socket.c:398
int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf)
Set socket buffer size of netlink socket.
Definition: socket.c:807