1. all cleanup actions (like free()) now located at the end of function
2. in case of error or EOF, *buf and *creds (if given) set to NULL
This protect from invalid code at user's side, like:
char *buf;
x = nl_recv(..., &buf, ...);
if (x<=0)
goto cleanup;
cleanup:
free(buf);
3. all intermediate buffers are stored into local variables, and user's
variables only touches at the end.
Based on clang diagnostics:
1. lib/nl.c: recvmsgs(): nla filling with zeros commented.
2. lib/route/classid.c: & lib/route/pktloc.c:
remove zero-filling of struct stat
3. lib/route/qdisc/htb.c: Fix htb_qdisc_msg_fill(): fix zero-filling
4. ematch/container.c: container_parse:
commented why only 4 bytes are copied
len marked as unused to eliminate compiler warning
"-" was never used in the names of the flags. "_" was used in all places
of the library. So, I just changed the undescore to the minus.
Automatic indentation can insert spaces on either side of the minus,
so the library will be compiled, but will not be usable (in this part of the code),
as the parser will split words by white space, and the flag "admin - perm"
will never work.
New functions:
rtnl_link_set_group(link, group)
rtnl_link_get_group(link)
The group identifier is printed in the brief section as "group N"
Signed-off-by: Thomas Graf <tgraf@redhat.com>
1. According to man asprintf:
If memory allocation wasn't possible, or some other error occurs,
these functions will return -1, and the contents of strp is undefined.
2. Sometimes, errp was not filled at all. In high-level code, free(errp)
will called, so segmantation fault may appear in case of error in parser
3. The most cases of using asprintf is to report about allocation fail.
So, probability of allocation of asprintf buffer is very high. And that
will lead to trash in errp.
4. For simple casses I decide to replace asprintf with strdup
This may happen when passing connected socket to nl_cache_mngr_alloc().
Now, nl_connect() will return error trying to connect already connected socket.
Also, dont call close(-1) if socket() fails.
Also, change internal variables type from uint32_t to unsigned int.
Correct scanf format string should contain "SCNx32" instead of just "x",
but I decide not to fix that and just changed variable type.
On some architectures, uint64_t is defined as:
typedef unsigned long long int __u64;
on another architectures as:
typedef unsigned long int __u64;
So, according to man 3 printf,
uint64_t should be printed as "%llu" on some architectures, and as "%lu" on another. The same for scanf.
To eliminate that challenge, there is inttypes.h, in which appropriate constants
are defined for current architecture.
32-bit types (and even 16 and 8 bit types) should be printed using such constants if
printed variable defined as uint_XXXt or intXXXt type. But in reality 32-bit and less
types does not gain run-time error (except in scanf), because they pushed to stack as
32-bit values at least. So, I decide not to fix that.
Run-time version information is available as exported four integers:
- const int nl_ver_num = LIBNL_VER_NUM;
- const int nl_ver_maj = LIBNL_VER_MAJ;
- const int nl_ver_min = LIBNL_VER_MIN;
- const int nl_ver_mic = LIBNL_VER_MIC;
The purpose of this is to get version of compiled library as run time.
Use cases:
- To know exact version of the library in Python's ctypes module,
Say, to find out if nl_cache_mngr_alloc() allow sk=NULL
- To make sure that the version of the loaded library corresponds to the
version of headers (for the paranoid). Say, to check:
if (LIBNL_VER_NUM != nl_ver_num)
exit(1);
I ran into a bug today related to how Linux handles a route's nexthop
flags when there is just one nexthop. Namely Linux expects the flags
to be OR'd into the rtm_flags field when there is only one nexthop and
so rtnl_route_build_msg needs to check the number of nexthops and
store the nexthops flags into this field prior to calling
nlmsg_append(...&rtmsg).
Conversely the rtnl_route_parse function needs to pull these lower
0xff bits when a single nexthop is detected.
Attached is my patch. I don't like the slight duplication of doing
the rtnl_route_get_nnexthops check twice but it seemed to be the least
turmoil of any solution I thought of.
I found a small bug in the nl_addr_parse function when being passed the
strings "default", "any", or "all". Currently nl_addr_parse will create
a zeroed nl_addr with a length corresponding to the family/hint or
AF_INET if omitted. This behavior when used in conjunction with the
libnl-route library to add default routes to the system has the side
effect of creating a route to the host address 0.0.0.0/32.
Attached is a patch that matches the iproute2 behavior more closely
where we do set the family but the length of the nl_addr is set to 0.
Commit 25d640da4a caused the following build warning:
../include/netlink/utils.h:47:15: note: expected 'const char **' but argument is of type 'char **'
route/link/inet6.c:300:11: warning: passing argument 2 of 'nl_cancel_down_bytes' from incompatible pointer type [enabled by default]
Revert the const char ** change.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Since about 2.6.27 kernel, stats are not enabled by default.
Stats can be enabled using sysctl named
net.netfilter.nf_conntrack_acct
So, do not print zeroes in stats if it's not available.
When not checked, trash may appear in output
1. Fix some places where unsigned value compared < 0
2. Fix obsolete %Z specifier to more portable %z
3. Some erroneous types substitution
4. nl_msec2str() - 64-bit msec is now properly used,
Only safe changes. I mean int <--> uint32_t and signed/unsigned fixes.
Some functinos require size_t argument instead of int, but changes of
signatures of that functions is terrible thing.
Also, I do not pretend for a full list of fixes.
Just to shut up clang -Wall -Wextra
One more thing. ifindex. I don't change that because changes will
be too big for simple fix.
Currently, rtnl_tc_handle2str understands the ingress handle but
rtnl_tc_str2handle does not. This change lets rtnl_tc_str2handle
recognize 'ingress' as a valid handle as well.
Generic netlink has the ability to autoload modules in response to a request for
a family. Currently libnl uses a GETFAMILY call with the NLM_F_DUMP flag to
list all the available families, but doing so neglects the possibility of an
autoloaded module. This patch modifies the genl code to probe the kernel for a
specific family rather than dumping a list of all the currenlty available ones,
making autoload work properly.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Thomas Graf <tgraf@redhat.com>
Introduces the functions genl_register_family() and
genl_unregister_family() to register a Generic Netlink family
which does not implement a cachable type.
API users can direct received messages into genl_handle_msg() which
will validate the messages and call the callback functions defined
in the commands definition.
See test/test-genl.c for an example on how to use it.
These functions deprecate the function genlmsg_data() which did not
allow to specify the length of the user header. Use of the new API
will make code much clearer. The old function is still kept around
for backwards compatibility but marked deprecated in the API reference.