summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/netlink/utils.h8
-rw-r--r--lib/nl.c7
-rw-r--r--lib/utils.c2
3 files changed, 16 insertions, 1 deletions
diff --git a/include/netlink/utils.h b/include/netlink/utils.h
index ac448c5..c8b4d2e 100644
--- a/include/netlink/utils.h
+++ b/include/netlink/utils.h
@@ -135,6 +135,14 @@ enum {
NL_CAPABILITY_VERSION_3_2_26 = 7,
#define NL_CAPABILITY_VERSION_3_2_26 NL_CAPABILITY_VERSION_3_2_26
+ /**
+ * nl_recv() fails with NLE_MSG_TRUNC if a message got truncated
+ * with NL_MSG_PEEK disabled. Previously, the failed message was wrongly
+ * discarded and the next message received.
+ */
+ NL_CAPABILITY_NL_RECV_FAIL_TRUNK_NO_PEEK = 8,
+#define NL_CAPABILITY_NL_RECV_FAIL_TRUNK_NO_PEEK NL_CAPABILITY_NL_RECV_FAIL_TRUNK_NO_PEEK
+
__NL_CAPABILITY_MAX,
NL_CAPABILITY_MAX = (__NL_CAPABILITY_MAX - 1),
#define NL_CAPABILITY_MAX NL_CAPABILITY_MAX
diff --git a/lib/nl.c b/lib/nl.c
index 8fc9ec1..f06e9a0 100644
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -725,6 +725,13 @@ retry:
if (iov.iov_len < n || (msg.msg_flags & MSG_TRUNC)) {
void *tmp;
+
+ /* respond with error to an incomplete message */
+ if (!(sk->s_flags & NL_MSG_PEEK)) {
+ retval = -NLE_MSG_TRUNC;
+ goto abort;
+ }
+
/* Provided buffer is not long enough, enlarge it
* to size of n (which should be total length of the message)
* and try again. */
diff --git a/lib/utils.c b/lib/utils.c
index 82f14ac..aa0d1e1 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1150,7 +1150,7 @@ int nl_has_capability (int capability)
NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP,
NL_CAPABILITY_ROUTE_ADDR_COMPARE_CACHEINFO,
NL_CAPABILITY_VERSION_3_2_26,
- 0),
+ NL_CAPABILITY_NL_RECV_FAIL_TRUNK_NO_PEEK),
/* IMPORTANT: these capability numbers are intended to be universal and stable
* for libnl3. Don't allocate new numbers on your own that differ from upstream
* libnl3.