backport retry on local port in use (rh #1097176) (3.2.24-3)
This commit is contained in:
parent
92602dbecc
commit
5e7332abc4
89
0002-rh1097176-nl-has-capability.patch
Normal file
89
0002-rh1097176-nl-has-capability.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From 6de4c9ea6c2ae4fa02f7f7b46f03e9df2ced157b Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Thu, 13 Mar 2014 13:16:05 +0100
|
||||
Subject: [PATCH 1/1] utils: add nl_has_capability() function
|
||||
|
||||
Acked-by: Thomas Graf <tgraf@suug.ch>
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit 68d6bd7f37dc9a0c004b4355770e9c475fb964cd)
|
||||
---
|
||||
include/netlink/utils.h | 8 ++++++++
|
||||
lib/utils.c | 43 +++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 51 insertions(+)
|
||||
|
||||
diff --git a/include/netlink/utils.h b/include/netlink/utils.h
|
||||
index 502341a..da46a55 100644
|
||||
--- a/include/netlink/utils.h
|
||||
+++ b/include/netlink/utils.h
|
||||
@@ -79,6 +79,14 @@ extern void nl_new_line(struct nl_dump_params *);
|
||||
extern void nl_dump(struct nl_dump_params *, const char *, ...);
|
||||
extern void nl_dump_line(struct nl_dump_params *, const char *, ...);
|
||||
|
||||
+enum {
|
||||
+ NL_CAPABILITY_NONE,
|
||||
+
|
||||
+ __NL_CAPABILITY_MAX
|
||||
+#define NL_CAPABILITY_MAX (__NL_CAPABILITY_MAX - 1)
|
||||
+};
|
||||
+int nl_has_capability (int capability);
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/lib/utils.c b/lib/utils.c
|
||||
index c04d83f..18bd950 100644
|
||||
--- a/lib/utils.c
|
||||
+++ b/lib/utils.c
|
||||
@@ -1111,6 +1111,49 @@ void dump_from_ops(struct nl_object *obj, struct nl_dump_params *params)
|
||||
obj->ce_ops->oo_dump[type](obj, params);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Check for library capabilities
|
||||
+ *
|
||||
+ * @arg capability capability identifier
|
||||
+ *
|
||||
+ * Check whether the loaded libnl library supports a certain capability.
|
||||
+ * This is useful so that applications can workaround known issues of
|
||||
+ * libnl that are fixed in newer library versions, without
|
||||
+ * having a hard dependency on the new version. It is also useful, for
|
||||
+ * capabilities that cannot easily be detected using autoconf tests.
|
||||
+ * The capabilities are integer constants with name NL_CAPABILITY_*.
|
||||
+ *
|
||||
+ * As this function is intended to detect capabilities at runtime,
|
||||
+ * you might not want to depend during compile time on the NL_CAPABILITY_*
|
||||
+ * names. Instead you can use their numeric values which are guaranteed not to
|
||||
+ * change meaning.
|
||||
+ *
|
||||
+ * @return non zero if libnl supports a certain capability, 0 otherwise.
|
||||
+ **/
|
||||
+int nl_has_capability (int capability)
|
||||
+{
|
||||
+ static const uint8_t caps[ ( NL_CAPABILITY_MAX + 7 ) / 8 ] = {
|
||||
+#define _NL_ASSERT(expr) ( 0 * sizeof(struct { unsigned int x: ( (!!(expr)) ? 1 : -1 ); }) )
|
||||
+#define _NL_SETV(i, r, v) \
|
||||
+ ( _NL_ASSERT( (v) == 0 || (i) * 8 + (r) == (v) - 1 ) + \
|
||||
+ ( (v) == 0 ? 0 : (1 << (r)) ) )
|
||||
+#define _NL_SET(i, v0, v1, v2, v3, v4, v5, v6, v7) \
|
||||
+ [(i)] = ( \
|
||||
+ _NL_SETV((i), 0, (v0)) | _NL_SETV((i), 4, (v4)) | \
|
||||
+ _NL_SETV((i), 1, (v1)) | _NL_SETV((i), 5, (v5)) | \
|
||||
+ _NL_SETV((i), 2, (v2)) | _NL_SETV((i), 6, (v6)) | \
|
||||
+ _NL_SETV((i), 3, (v3)) | _NL_SETV((i), 7, (v7)) )
|
||||
+#undef _NL_SET
|
||||
+#undef _NL_SETV
|
||||
+#undef _NL_ASSERT
|
||||
+ };
|
||||
+
|
||||
+ if (capability <= 0 || capability > NL_CAPABILITY_MAX)
|
||||
+ return 0;
|
||||
+ capability--;
|
||||
+ return (caps[capability / 8] & (1 << (capability % 8))) != 0;
|
||||
+}
|
||||
+
|
||||
/** @endcond */
|
||||
|
||||
/** @} */
|
||||
--
|
||||
1.9.0
|
||||
|
644
0003-rh1097176-retry-local-port.patch
Normal file
644
0003-rh1097176-retry-local-port.patch
Normal file
@ -0,0 +1,644 @@
|
||||
From b87aba5b8ddf0475854265fdbf93a02501ab0ffa Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Graf <tgraf@suug.ch>
|
||||
Date: Mon, 31 Mar 2014 13:21:06 +0200
|
||||
Subject: [PATCH 1/5] link: Catch missing io_free() implementations
|
||||
|
||||
Signed-off-by: Thomas Graf <tgraf@suug.ch>
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit 34bfce62150d07cf9894f2d9cbd0c989a203ea52)
|
||||
---
|
||||
include/netlink-private/netlink.h | 7 +++++++
|
||||
lib/route/link.c | 4 ++++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/include/netlink-private/netlink.h b/include/netlink-private/netlink.h
|
||||
index 2b1a68e..43ca804 100644
|
||||
--- a/include/netlink-private/netlink.h
|
||||
+++ b/include/netlink-private/netlink.h
|
||||
@@ -102,6 +102,13 @@ struct trans_list {
|
||||
assert(0); \
|
||||
} while (0)
|
||||
|
||||
+#define BUG_ON(condition) \
|
||||
+ do { \
|
||||
+ if (condition) \
|
||||
+ BUG(); \
|
||||
+ } while (0)
|
||||
+
|
||||
+
|
||||
#define APPBUG(msg) \
|
||||
do { \
|
||||
fprintf(stderr, "APPLICATION BUG: %s:%d:%s: %s\n", \
|
||||
diff --git a/lib/route/link.c b/lib/route/link.c
|
||||
index 9979b5b..85790e4 100644
|
||||
--- a/lib/route/link.c
|
||||
+++ b/lib/route/link.c
|
||||
@@ -194,6 +194,10 @@ static void release_link_info(struct rtnl_link *link)
|
||||
if (io != NULL) {
|
||||
if (io->io_free)
|
||||
io->io_free(link);
|
||||
+ else {
|
||||
+ /* Catch missing io_free() implementations */
|
||||
+ BUG_ON(link->l_info);
|
||||
+ }
|
||||
rtnl_link_info_ops_put(io);
|
||||
link->l_info_ops = NULL;
|
||||
}
|
||||
--
|
||||
1.9.0
|
||||
|
||||
|
||||
From 88d7ec560f358b23e071acfc41700101de4f673a Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Wed, 9 Apr 2014 12:08:50 +0200
|
||||
Subject: [PATCH 2/5] lib/socket: use proper typed constant UINT32_MAX for
|
||||
uint32_t typed port
|
||||
|
||||
This was a bug on architectures with native int type less then 32 bit.
|
||||
|
||||
Acked-by: Thomas Graf <tgraf@suug.ch>
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit 0fd510b3673f479637a6376db3d66dcb9f8911d0)
|
||||
---
|
||||
lib/socket.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/socket.c b/lib/socket.c
|
||||
index 00d8d6a..959b122 100644
|
||||
--- a/lib/socket.c
|
||||
+++ b/lib/socket.c
|
||||
@@ -82,7 +82,7 @@ static uint32_t generate_local_port(void)
|
||||
|
||||
nl_write_unlock(&port_map_lock);
|
||||
|
||||
- return pid + (n << 22);
|
||||
+ return pid + (((uint32_t)n) << 22);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,14 +90,14 @@ static uint32_t generate_local_port(void)
|
||||
|
||||
/* Out of sockets in our own PID namespace, what to do? FIXME */
|
||||
NL_DBG(1, "Warning: Ran out of unique local port namespace\n");
|
||||
- return UINT_MAX;
|
||||
+ return UINT32_MAX;
|
||||
}
|
||||
|
||||
static void release_local_port(uint32_t port)
|
||||
{
|
||||
int nr;
|
||||
|
||||
- if (port == UINT_MAX)
|
||||
+ if (port == UINT32_MAX)
|
||||
return;
|
||||
|
||||
nr = port >> 22;
|
||||
@@ -126,7 +126,7 @@ static struct nl_sock *__alloc_socket(struct nl_cb *cb)
|
||||
sk->s_peer.nl_family = AF_NETLINK;
|
||||
sk->s_seq_expect = sk->s_seq_next = time(0);
|
||||
sk->s_local.nl_pid = generate_local_port();
|
||||
- if (sk->s_local.nl_pid == UINT_MAX) {
|
||||
+ if (sk->s_local.nl_pid == UINT32_MAX) {
|
||||
nl_socket_free(sk);
|
||||
return NULL;
|
||||
}
|
||||
--
|
||||
1.9.0
|
||||
|
||||
|
||||
From e029e9d1632d7c76338ee366fba097ea2cb6dc8b Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Wed, 9 Apr 2014 12:08:51 +0200
|
||||
Subject: [PATCH 3/5] lib/socket: don't fail if no more local ports can be
|
||||
assigned in nl_socket_alloc
|
||||
|
||||
By failing inside of nl_socket_alloc(), the user can not even work around
|
||||
when running out of local ports. This patch changes that if there are no more
|
||||
local ports, we set the port to UINT32_MAX. This is a consistent behavior
|
||||
to calling nl_socket_set_local_port(sk, 0).
|
||||
|
||||
In general, since nl_socket_set_local_port() does not restict the generated
|
||||
ports in any way we cannot assume to have a valid port. So the check in
|
||||
the constructor was harmful and users who ever encountered it (because they
|
||||
created 1024 libnl3 sockets) could not even work around it.
|
||||
|
||||
Acked-by: Thomas Graf <tgraf@suug.ch>
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit 0271578987088210d7d2d68addbd5e8fe27d4383)
|
||||
---
|
||||
lib/socket.c | 4 ----
|
||||
1 file changed, 4 deletions(-)
|
||||
|
||||
diff --git a/lib/socket.c b/lib/socket.c
|
||||
index 959b122..eb4a978 100644
|
||||
--- a/lib/socket.c
|
||||
+++ b/lib/socket.c
|
||||
@@ -126,10 +126,6 @@ static struct nl_sock *__alloc_socket(struct nl_cb *cb)
|
||||
sk->s_peer.nl_family = AF_NETLINK;
|
||||
sk->s_seq_expect = sk->s_seq_next = time(0);
|
||||
sk->s_local.nl_pid = generate_local_port();
|
||||
- if (sk->s_local.nl_pid == UINT32_MAX) {
|
||||
- nl_socket_free(sk);
|
||||
- return NULL;
|
||||
- }
|
||||
|
||||
return sk;
|
||||
}
|
||||
--
|
||||
1.9.0
|
||||
|
||||
|
||||
From 02c22298f6a5b20ad67a90050fd91ca5b8f358fb Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Wed, 9 Apr 2014 12:08:52 +0200
|
||||
Subject: [PATCH 4/5] lib/socket: retry generate local port in nl_connect on
|
||||
ADDRINUSE
|
||||
|
||||
It can easily happen that the generated local netlink port is alrady in
|
||||
use. In that case bind will fail with ADDRINUSE.
|
||||
|
||||
Users of libnl3 could workaround this, by managing the local ports
|
||||
themselves, but sometimes these users are libraries too and they also
|
||||
don't know which ports might be used by other components.
|
||||
|
||||
This patch changes that nl_socket_alloc() no longer initilizes the local
|
||||
port id immediately. Instead it will be initialized when the user calls
|
||||
nl_socket_get_local_port() the first time and thereby shows interest in
|
||||
the value.
|
||||
|
||||
If bind() fails with ADDRINUSE, check if the user ever cared about the
|
||||
local port, i.e. whether the local port is still unset. If it is still
|
||||
unset, assume that libnl should choose a suitable port and retry until
|
||||
an unused port can be found.
|
||||
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit 4dd5fdd0af2c0b7ffe1dbc49313f263dbb2e906f)
|
||||
|
||||
Conflicts:
|
||||
include/netlink/utils.h
|
||||
lib/utils.c
|
||||
---
|
||||
include/Makefile.am | 1 +
|
||||
include/netlink-private/socket.h | 31 +++++++++++
|
||||
include/netlink/utils.h | 9 ++++
|
||||
lib/nl.c | 62 +++++++++++++++++++---
|
||||
lib/socket.c | 110 +++++++++++++++++++++++++++++++--------
|
||||
lib/utils.c | 9 ++++
|
||||
libnl.sym.in | 5 ++
|
||||
7 files changed, 199 insertions(+), 28 deletions(-)
|
||||
create mode 100644 include/netlink-private/socket.h
|
||||
|
||||
diff --git a/include/Makefile.am b/include/Makefile.am
|
||||
index 32f872f..ac5ce65 100644
|
||||
--- a/include/Makefile.am
|
||||
+++ b/include/Makefile.am
|
||||
@@ -138,6 +138,7 @@ noinst_HEADERS = \
|
||||
linux/tc_ematch/tc_em_meta.h \
|
||||
netlink-private/genl.h \
|
||||
netlink-private/netlink.h \
|
||||
+ netlink-private/socket.h \
|
||||
netlink-private/tc.h \
|
||||
netlink-private/types.h \
|
||||
netlink-private/cache-api.h \
|
||||
diff --git a/include/netlink-private/socket.h b/include/netlink-private/socket.h
|
||||
new file mode 100644
|
||||
index 0000000..86a440c
|
||||
--- /dev/null
|
||||
+++ b/include/netlink-private/socket.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+/*
|
||||
+ * netlink-private/socket.h Private declarations for socket
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation version 2.1
|
||||
+ * of the License.
|
||||
+ *
|
||||
+ * Copyright (c) 2014 Thomas Graf <tgraf@suug.ch>
|
||||
+ */
|
||||
+
|
||||
+#ifndef NETLINK_SOCKET_PRIV_H_
|
||||
+#define NETLINK_SOCKET_PRIV_H_
|
||||
+
|
||||
+#include <netlink-private/netlink.h>
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+int _nl_socket_is_local_port_unspecified (struct nl_sock *sk);
|
||||
+uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk);
|
||||
+
|
||||
+void _nl_socket_used_ports_release_all(const uint32_t *used_ports);
|
||||
+void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/include/netlink/utils.h b/include/netlink/utils.h
|
||||
index da46a55..e929cfd 100644
|
||||
--- a/include/netlink/utils.h
|
||||
+++ b/include/netlink/utils.h
|
||||
@@ -82,6 +82,15 @@ extern void nl_dump_line(struct nl_dump_params *, const char *, ...);
|
||||
enum {
|
||||
NL_CAPABILITY_NONE,
|
||||
|
||||
+ /**
|
||||
+ * Indicate that the local port is unspecified until the user accesses
|
||||
+ * it (via nl_socket_get_local_port()) or until nl_connect(). More importantly,
|
||||
+ * if the port is left unspecified, nl_connect() will retry generating another
|
||||
+ * port when bind() fails with ADDRINUSE.
|
||||
+ */
|
||||
+ NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE = 4,
|
||||
+#define NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE
|
||||
+
|
||||
__NL_CAPABILITY_MAX
|
||||
#define NL_CAPABILITY_MAX (__NL_CAPABILITY_MAX - 1)
|
||||
};
|
||||
diff --git a/lib/nl.c b/lib/nl.c
|
||||
index 4692490..25fd59c 100644
|
||||
--- a/lib/nl.c
|
||||
+++ b/lib/nl.c
|
||||
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <netlink-private/netlink.h>
|
||||
+#include <netlink-private/socket.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/handlers.h>
|
||||
@@ -75,6 +76,16 @@
|
||||
* be closed automatically if any of the `exec` family functions succeed.
|
||||
* This is essential for multi threaded programs.
|
||||
*
|
||||
+ * @note The local port (`nl_socket_get_local_port()`) is unspecified after
|
||||
+ * creating a new socket. It only gets determined when accessing the
|
||||
+ * port the first time or during `nl_connect()`. When nl_connect()
|
||||
+ * fails during `bind()` due to `ADDRINUSE`, it will retry with
|
||||
+ * different ports if the port is unspecified. Unless you want to enforce
|
||||
+ * the use of a specific local port, don't access the local port (or
|
||||
+ * reset it to `unspecified` by calling `nl_socket_set_local_port(sk, 0)`).
|
||||
+ * This capability is indicated by
|
||||
+ * `%NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE`.
|
||||
+ *
|
||||
* @see nl_socket_alloc()
|
||||
* @see nl_close()
|
||||
*
|
||||
@@ -85,6 +96,7 @@
|
||||
int nl_connect(struct nl_sock *sk, int protocol)
|
||||
{
|
||||
int err, flags = 0;
|
||||
+ int errsv;
|
||||
socklen_t addrlen;
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
@@ -96,7 +108,9 @@ int nl_connect(struct nl_sock *sk, int protocol)
|
||||
|
||||
sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
|
||||
if (sk->s_fd < 0) {
|
||||
- err = -nl_syserr2nlerr(errno);
|
||||
+ errsv = errno;
|
||||
+ NL_DBG(4, "nl_connect(%p): socket() failed with %d\n", sk, errsv);
|
||||
+ err = -nl_syserr2nlerr(errsv);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -106,11 +120,45 @@ int nl_connect(struct nl_sock *sk, int protocol)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
- err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
|
||||
- sizeof(sk->s_local));
|
||||
- if (err < 0) {
|
||||
- err = -nl_syserr2nlerr(errno);
|
||||
- goto errout;
|
||||
+ if (_nl_socket_is_local_port_unspecified (sk)) {
|
||||
+ uint32_t port;
|
||||
+ uint32_t used_ports[32] = { 0 };
|
||||
+
|
||||
+ while (1) {
|
||||
+ port = _nl_socket_generate_local_port_no_release(sk);
|
||||
+
|
||||
+ if (port == UINT32_MAX) {
|
||||
+ NL_DBG(4, "nl_connect(%p): no more unused local ports.\n", sk);
|
||||
+ _nl_socket_used_ports_release_all(used_ports);
|
||||
+ err = -NLE_EXIST;
|
||||
+ goto errout;
|
||||
+ }
|
||||
+ err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
|
||||
+ sizeof(sk->s_local));
|
||||
+ if (err == 0)
|
||||
+ break;
|
||||
+
|
||||
+ errsv = errno;
|
||||
+ if (errsv == EADDRINUSE) {
|
||||
+ NL_DBG(4, "nl_connect(%p): local port %u already in use. Retry.\n", sk, (unsigned) port);
|
||||
+ _nl_socket_used_ports_set(used_ports, port);
|
||||
+ } else {
|
||||
+ NL_DBG(4, "nl_connect(%p): bind() for port %u failed with %d\n", sk, (unsigned) port, errsv);
|
||||
+ _nl_socket_used_ports_release_all(used_ports);
|
||||
+ err = -nl_syserr2nlerr(errsv);
|
||||
+ goto errout;
|
||||
+ }
|
||||
+ }
|
||||
+ _nl_socket_used_ports_release_all(used_ports);
|
||||
+ } else {
|
||||
+ err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
|
||||
+ sizeof(sk->s_local));
|
||||
+ if (err != 0) {
|
||||
+ errsv = errno;
|
||||
+ NL_DBG(4, "nl_connect(%p): bind() failed with %d\n", sk, errsv);
|
||||
+ err = -nl_syserr2nlerr(errsv);
|
||||
+ goto errout;
|
||||
+ }
|
||||
}
|
||||
|
||||
addrlen = sizeof(sk->s_local);
|
||||
@@ -405,7 +453,7 @@ void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
|
||||
|
||||
nlh = nlmsg_hdr(msg);
|
||||
if (nlh->nlmsg_pid == NL_AUTO_PORT)
|
||||
- nlh->nlmsg_pid = sk->s_local.nl_pid;
|
||||
+ nlh->nlmsg_pid = nl_socket_get_local_port(sk);
|
||||
|
||||
if (nlh->nlmsg_seq == NL_AUTO_SEQ)
|
||||
nlh->nlmsg_seq = sk->s_seq_next++;
|
||||
diff --git a/lib/socket.c b/lib/socket.c
|
||||
index eb4a978..c08f053 100644
|
||||
--- a/lib/socket.c
|
||||
+++ b/lib/socket.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "defs.h"
|
||||
|
||||
#include <netlink-private/netlink.h>
|
||||
+#include <netlink-private/socket.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/handlers.h>
|
||||
@@ -96,17 +97,59 @@ static uint32_t generate_local_port(void)
|
||||
static void release_local_port(uint32_t port)
|
||||
{
|
||||
int nr;
|
||||
+ uint32_t mask;
|
||||
|
||||
if (port == UINT32_MAX)
|
||||
return;
|
||||
-
|
||||
+
|
||||
+ BUG_ON(port == 0);
|
||||
+
|
||||
nr = port >> 22;
|
||||
+ mask = 1UL << (nr % 32);
|
||||
+ nr /= 32;
|
||||
|
||||
nl_write_lock(&port_map_lock);
|
||||
- used_ports_map[nr / 32] &= ~(1 << (nr % 32));
|
||||
+ BUG_ON((used_ports_map[nr] & mask) != mask);
|
||||
+ used_ports_map[nr] &= ~mask;
|
||||
nl_write_unlock(&port_map_lock);
|
||||
}
|
||||
|
||||
+/** \cond skip */
|
||||
+void _nl_socket_used_ports_release_all(const uint32_t *used_ports)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 32; i++) {
|
||||
+ if (used_ports[i] != 0) {
|
||||
+ nl_write_lock(&port_map_lock);
|
||||
+ for (; i < 32; i++) {
|
||||
+ BUG_ON((used_ports_map[i] & used_ports[i]) != used_ports[i]);
|
||||
+ used_ports_map[i] &= ~(used_ports[i]);
|
||||
+ }
|
||||
+ nl_write_unlock(&port_map_lock);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port)
|
||||
+{
|
||||
+ int nr;
|
||||
+ int32_t mask;
|
||||
+
|
||||
+ nr = port >> 22;
|
||||
+ mask = 1UL << (nr % 32);
|
||||
+ nr /= 32;
|
||||
+
|
||||
+ /*
|
||||
+ BUG_ON(port == UINT32_MAX || port == 0 || (getpid() & 0x3FFFFF) != (port & 0x3FFFFF));
|
||||
+ BUG_ON(used_ports[nr] & mask);
|
||||
+ */
|
||||
+
|
||||
+ used_ports[nr] |= mask;
|
||||
+}
|
||||
+/** \endcond */
|
||||
+
|
||||
/**
|
||||
* @name Allocation
|
||||
* @{
|
||||
@@ -125,7 +168,9 @@ static struct nl_sock *__alloc_socket(struct nl_cb *cb)
|
||||
sk->s_local.nl_family = AF_NETLINK;
|
||||
sk->s_peer.nl_family = AF_NETLINK;
|
||||
sk->s_seq_expect = sk->s_seq_next = time(0);
|
||||
- sk->s_local.nl_pid = generate_local_port();
|
||||
+
|
||||
+ /* the port is 0 (unspecified), meaning NL_OWN_PORT */
|
||||
+ sk->s_flags = NL_OWN_PORT;
|
||||
|
||||
return sk;
|
||||
}
|
||||
@@ -261,6 +306,26 @@ void nl_socket_enable_auto_ack(struct nl_sock *sk)
|
||||
|
||||
/** @} */
|
||||
|
||||
+/** \cond skip */
|
||||
+int _nl_socket_is_local_port_unspecified(struct nl_sock *sk)
|
||||
+{
|
||||
+ return (sk->s_local.nl_pid == 0);
|
||||
+}
|
||||
+
|
||||
+uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk)
|
||||
+{
|
||||
+ uint32_t port;
|
||||
+
|
||||
+ /* reset the port to generate_local_port(), but do not release
|
||||
+ * the previously generated port. */
|
||||
+
|
||||
+ port = generate_local_port();
|
||||
+ sk->s_flags &= ~NL_OWN_PORT;
|
||||
+ sk->s_local.nl_pid = port;
|
||||
+ return port;
|
||||
+}
|
||||
+/** \endcond */
|
||||
+
|
||||
/**
|
||||
* @name Source Idenficiation
|
||||
* @{
|
||||
@@ -268,6 +333,18 @@ void nl_socket_enable_auto_ack(struct nl_sock *sk)
|
||||
|
||||
uint32_t nl_socket_get_local_port(const struct nl_sock *sk)
|
||||
{
|
||||
+ if (sk->s_local.nl_pid == 0) {
|
||||
+ /* modify the const argument sk. This is justified, because
|
||||
+ * nobody ever saw the local_port from externally. So, we
|
||||
+ * initilize it on first use.
|
||||
+ *
|
||||
+ * Note that this also means that you cannot call this function
|
||||
+ * from multiple threads without synchronization. But nl_sock
|
||||
+ * is not automatically threadsafe anyway, so the user is not
|
||||
+ * allowed to do that.
|
||||
+ */
|
||||
+ return _nl_socket_generate_local_port_no_release((struct nl_sock *) sk);
|
||||
+ }
|
||||
return sk->s_local.nl_pid;
|
||||
}
|
||||
|
||||
@@ -276,27 +353,18 @@ uint32_t nl_socket_get_local_port(const struct nl_sock *sk)
|
||||
* @arg sk Netlink socket.
|
||||
* @arg port Local port identifier
|
||||
*
|
||||
- * Assigns a local port identifier to the socket. If port is 0
|
||||
- * a unique port identifier will be generated automatically.
|
||||
+ * Assigns a local port identifier to the socket.
|
||||
+ *
|
||||
+ * If port is 0, the port is reset to 'unspecified' as it is after newly
|
||||
+ * calling nl_socket_alloc().
|
||||
+ * Unspecified means, that the port will be generated automatically later
|
||||
+ * on first use (either on nl_socket_get_local_port() or nl_connect()).
|
||||
*/
|
||||
void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port)
|
||||
{
|
||||
- if (port == 0) {
|
||||
- port = generate_local_port();
|
||||
- /*
|
||||
- * Release local port after generation of a new one to be
|
||||
- * able to change local port using nl_socket_set_local_port(, 0)
|
||||
- */
|
||||
- if (!(sk->s_flags & NL_OWN_PORT))
|
||||
- release_local_port(sk->s_local.nl_pid);
|
||||
- else
|
||||
- sk->s_flags &= ~NL_OWN_PORT;
|
||||
- } else {
|
||||
- if (!(sk->s_flags & NL_OWN_PORT))
|
||||
- release_local_port(sk->s_local.nl_pid);
|
||||
- sk->s_flags |= NL_OWN_PORT;
|
||||
- }
|
||||
-
|
||||
+ if (!(sk->s_flags & NL_OWN_PORT))
|
||||
+ release_local_port(sk->s_local.nl_pid);
|
||||
+ sk->s_flags |= NL_OWN_PORT;
|
||||
sk->s_local.nl_pid = port;
|
||||
}
|
||||
|
||||
diff --git a/lib/utils.c b/lib/utils.c
|
||||
index 18bd950..275138d 100644
|
||||
--- a/lib/utils.c
|
||||
+++ b/lib/utils.c
|
||||
@@ -1143,6 +1143,15 @@ int nl_has_capability (int capability)
|
||||
_NL_SETV((i), 1, (v1)) | _NL_SETV((i), 5, (v5)) | \
|
||||
_NL_SETV((i), 2, (v2)) | _NL_SETV((i), 6, (v6)) | \
|
||||
_NL_SETV((i), 3, (v3)) | _NL_SETV((i), 7, (v7)) )
|
||||
+ _NL_SET(0,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 0),
|
||||
#undef _NL_SET
|
||||
#undef _NL_SETV
|
||||
#undef _NL_ASSERT
|
||||
diff --git a/libnl.sym.in b/libnl.sym.in
|
||||
index e8f6c53..df8888c 100644
|
||||
--- a/libnl.sym.in
|
||||
+++ b/libnl.sym.in
|
||||
@@ -1,4 +1,9 @@
|
||||
libnl_@MAJ_VERSION@ {
|
||||
global:
|
||||
*;
|
||||
+local:
|
||||
+ _nl_socket_generate_local_port_no_release;
|
||||
+ _nl_socket_is_local_port_unspecified;
|
||||
+ _nl_socket_used_ports_release_all;
|
||||
+ _nl_socket_used_ports_set;
|
||||
};
|
||||
--
|
||||
1.9.0
|
||||
|
||||
|
||||
From 04f64c10aea96c97dea0327c6a2ac80b1da63c7c Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Wed, 9 Apr 2014 12:08:53 +0200
|
||||
Subject: [PATCH 5/5] lib/socket: randomize the generated local port
|
||||
|
||||
Instead of always trying the same order of ports when
|
||||
looking for an unused port, randomize the order (naively).
|
||||
|
||||
As libnl-1 uses the same function, it is likely that two applications
|
||||
that are using both libraries generate the same ports. By chosing a
|
||||
different order how to select the local port, the chances are smaller
|
||||
for this to happen (however, it cannot avoid it entirely. The user
|
||||
and/or libnl3 still has to cope with the situation, that somebody
|
||||
else might already use the port).
|
||||
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit 1f734a8f892abcd3f81637df4a089155aca1b66a)
|
||||
---
|
||||
lib/socket.c | 29 ++++++++++++++++++++++++++---
|
||||
1 file changed, 26 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/socket.c b/lib/socket.c
|
||||
index c08f053..5f61b38 100644
|
||||
--- a/lib/socket.c
|
||||
+++ b/lib/socket.c
|
||||
@@ -62,16 +62,39 @@ static NL_RW_LOCK(port_map_lock);
|
||||
|
||||
static uint32_t generate_local_port(void)
|
||||
{
|
||||
- int i, n;
|
||||
+ int i, j, n, m;
|
||||
+ static uint16_t idx_state = 0;
|
||||
uint32_t pid = getpid() & 0x3FFFFF;
|
||||
|
||||
nl_write_lock(&port_map_lock);
|
||||
|
||||
- for (i = 0; i < 32; i++) {
|
||||
+ if (idx_state == 0) {
|
||||
+ uint32_t t = time(NULL);
|
||||
+
|
||||
+ /* from time to time (on average each 2^15 calls), the idx_state will
|
||||
+ * be zero again. No problem, just "seed" anew with time(). */
|
||||
+ idx_state = t ^ (t >> 16) ^ 0x3047;
|
||||
+ } else
|
||||
+ idx_state = idx_state + 20011; /* add prime number */
|
||||
+
|
||||
+ i = idx_state >> 5;
|
||||
+ n = idx_state;
|
||||
+ for (j = 0; j < 32; j++) {
|
||||
+ /* walk the index somewhat randomized, with always leaving the block
|
||||
+ * #0 as last. The reason is that libnl-1 will start at block #0,
|
||||
+ * so just leave the first 32 ports preferably for libnl-1 owned sockets
|
||||
+ * (this is relevant only if the applications ends up using both versions
|
||||
+ * of the library and doesn't hurt otherwise). */
|
||||
+ if (j == 31)
|
||||
+ i = 0;
|
||||
+ else
|
||||
+ i = (((i-1) + 7) % 31) + 1;
|
||||
+
|
||||
if (used_ports_map[i] == 0xFFFFFFFF)
|
||||
continue;
|
||||
|
||||
- for (n = 0; n < 32; n++) {
|
||||
+ for (m = 0; m < 32; m++) {
|
||||
+ n = (n + 13) % 32;
|
||||
if (1UL & (used_ports_map[i] >> n))
|
||||
continue;
|
||||
|
||||
--
|
||||
1.9.0
|
||||
|
157
0004-backport-diverse-fixes.patch
Normal file
157
0004-backport-diverse-fixes.patch
Normal file
@ -0,0 +1,157 @@
|
||||
From b982d2da8f3511f0d21984d70aa18cc6c43338d2 Mon Sep 17 00:00:00 2001
|
||||
From: Hiroaki KAWAI <kawai@stratosphere.co.jp>
|
||||
Date: Wed, 9 Apr 2014 10:09:16 +0900
|
||||
Subject: [PATCH 1/3] python: fix wrongly passing argument to function in
|
||||
ObjIterator.next()
|
||||
|
||||
self.__next__() bound method does not take an extra argument.
|
||||
|
||||
https://github.com/thom311/libnl/pull/57
|
||||
|
||||
Signed-off-by: Hiroaki KAWAI <kawai@stratosphere.co.jp>
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit cb319e22f5680b49fad62dc7f0eb35b7d737cb3b)
|
||||
---
|
||||
python/netlink/core.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/python/netlink/core.py b/python/netlink/core.py
|
||||
index fbd1c9e..e5864cf 100644
|
||||
--- a/python/netlink/core.py
|
||||
+++ b/python/netlink/core.py
|
||||
@@ -449,7 +449,7 @@ class ObjIterator(object):
|
||||
return capi.nl_cache_get_next(self._nl_object)
|
||||
|
||||
def next(self):
|
||||
- return self.__next__(self)
|
||||
+ return self.__next__()
|
||||
|
||||
def __next__(self):
|
||||
if self._end:
|
||||
--
|
||||
1.9.0
|
||||
|
||||
|
||||
From a6aab53a1ab360f50947db1b026286647ff94049 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Fri, 31 Jan 2014 14:15:13 +0100
|
||||
Subject: [PATCH 2/3] route: fix return value of nl_rtgen_request()
|
||||
|
||||
According to documentation, nl_rtgen_request() returns 0 on success,
|
||||
but before it returned the number of bytes sent.
|
||||
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit b70174668b9867de573cf51471bc98bfe7fd2bc3)
|
||||
---
|
||||
lib/route/rtnl.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/route/rtnl.c b/lib/route/rtnl.c
|
||||
index 82397e9..6a55ca1 100644
|
||||
--- a/lib/route/rtnl.c
|
||||
+++ b/lib/route/rtnl.c
|
||||
@@ -34,15 +34,20 @@
|
||||
* Fills out a routing netlink request message and sends it out
|
||||
* using nl_send_simple().
|
||||
*
|
||||
- * @return 0 on success or a negative error code.
|
||||
+ * @return 0 on success or a negative error code. Due to a bug in
|
||||
+ * older versions, this returned the number of bytes sent. So for
|
||||
+ * compatibility, treat positive return values as success too.
|
||||
*/
|
||||
int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags)
|
||||
{
|
||||
+ int err;
|
||||
struct rtgenmsg gmsg = {
|
||||
.rtgen_family = family,
|
||||
};
|
||||
|
||||
- return nl_send_simple(sk, type, flags, &gmsg, sizeof(gmsg));
|
||||
+ err = nl_send_simple(sk, type, flags, &gmsg, sizeof(gmsg));
|
||||
+
|
||||
+ return err >= 0 ? 0 : err;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
--
|
||||
1.9.0
|
||||
|
||||
|
||||
From 0e0e12bfc306b7f4ca945af6c8c31f1dc5549191 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Wed, 19 Feb 2014 19:22:13 +0100
|
||||
Subject: [PATCH 3/3] utils: fix nl_msec2str() which always returned '0msec'
|
||||
for whole second durations
|
||||
|
||||
If the duration was without subsecond part, the function always returned
|
||||
'0msec', instead of giving the time in days, hours, minutes or seconds.
|
||||
|
||||
Regression introduced by commit b3fb89f445108677d405c62865b25aeea209d10a.
|
||||
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
Acked-by: Thomas Graf <tgraf@suug.ch>
|
||||
(cherry picked from commit 3fb0aae0bc37eafe868d28f0f12ee8803d7ad266)
|
||||
---
|
||||
lib/utils.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/lib/utils.c b/lib/utils.c
|
||||
index 275138d..267368e 100644
|
||||
--- a/lib/utils.c
|
||||
+++ b/lib/utils.c
|
||||
@@ -551,6 +551,11 @@ char * nl_msec2str(uint64_t msec, char *buf, size_t len)
|
||||
static const char *units[5] = {"d", "h", "m", "s", "msec"};
|
||||
char * const buf_orig = buf;
|
||||
|
||||
+ if (msec == 0) {
|
||||
+ snprintf(buf, len, "0msec");
|
||||
+ return buf_orig;
|
||||
+ }
|
||||
+
|
||||
#define _SPLIT(idx, unit) if ((split[idx] = msec / unit)) msec %= unit
|
||||
_SPLIT(0, 86400000); /* days */
|
||||
_SPLIT(1, 3600000); /* hours */
|
||||
@@ -559,11 +564,6 @@ char * nl_msec2str(uint64_t msec, char *buf, size_t len)
|
||||
#undef _SPLIT
|
||||
split[4] = msec;
|
||||
|
||||
- if (msec == 0) {
|
||||
- snprintf(buf, len, "0msec");
|
||||
- return buf_orig;
|
||||
- }
|
||||
-
|
||||
for (i = 0; i < ARRAY_SIZE(split) && len; i++) {
|
||||
int l;
|
||||
if (split[i] == 0)
|
||||
--
|
||||
1.9.0
|
||||
|
||||
From a0688f9a6ef3f37cb6908251826d352a8f50d8e5 Mon Sep 17 00:00:00 2001
|
||||
From: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Date: Sun, 23 Mar 2014 12:02:10 -0700
|
||||
Subject: [PATCH 1/1] act: fix a pointer in rtnl_act_msg_parse()
|
||||
|
||||
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Acked-by: Thomas Graf <tgraf@suug.ch>
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit b8d90d9bb19b5d9e4e5f71c4f6bb0eaadd78d7a0)
|
||||
---
|
||||
lib/route/act.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/route/act.c b/lib/route/act.c
|
||||
index 2bb222b..d3391ec 100644
|
||||
--- a/lib/route/act.c
|
||||
+++ b/lib/route/act.c
|
||||
@@ -452,7 +452,7 @@ err_free:
|
||||
|
||||
static int rtnl_act_msg_parse(struct nlmsghdr *n, struct rtnl_act **act)
|
||||
{
|
||||
- struct rtnl_tc *tc = TC_CAST(act);
|
||||
+ struct rtnl_tc *tc = TC_CAST(*act);
|
||||
struct nl_cache *link_cache;
|
||||
struct nlattr *tb[TCAA_MAX + 1];
|
||||
struct tcamsg *tm;
|
||||
--
|
||||
1.9.0
|
||||
|
98
0005-route-scope-in-route-build-msg.patch
Normal file
98
0005-route-scope-in-route-build-msg.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From b95a9f0a7253f1d6d772bf0489bb0d55897411f9 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Thu, 13 Feb 2014 21:31:37 +0100
|
||||
Subject: [PATCH 1/2] route: rtnl_route_build_msg() should not overwrite the
|
||||
route scope
|
||||
|
||||
rtnl_route_build_msg() should allow the user to set the route scope
|
||||
explicitly to RT_SCOPE_NOWHERE.
|
||||
|
||||
This is useful for IPv4 routes, because when deleting a route,
|
||||
the kernel requires the scope to match, unless the scope is set to
|
||||
RT_SCOPE_NOWHERE. Thus by setting the scope to RT_SCOPE_NOWHERE,
|
||||
the user can delete a route, even without knowing its scope.
|
||||
|
||||
rtnl_route_build_msg() should only try to guess the scope, if it was
|
||||
not explicitly specified.
|
||||
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
Acked-by: Thomas Graf <tgraf@suug.ch>
|
||||
(cherry picked from commit 85ec9c7ad80c60f4f619472f2bb9d9595da93b26)
|
||||
---
|
||||
lib/route/route_obj.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c
|
||||
index f2de523..dd4bf49 100644
|
||||
--- a/lib/route/route_obj.c
|
||||
+++ b/lib/route/route_obj.c
|
||||
@@ -1198,7 +1198,7 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)
|
||||
if (route->rt_src)
|
||||
rtmsg.rtm_src_len = nl_addr_get_prefixlen(route->rt_src);
|
||||
|
||||
- if (rtmsg.rtm_scope == RT_SCOPE_NOWHERE)
|
||||
+ if (!(route->ce_mask & ROUTE_ATTR_SCOPE))
|
||||
rtmsg.rtm_scope = rtnl_route_guess_scope(route);
|
||||
|
||||
if (rtnl_route_get_nnexthops(route) == 1) {
|
||||
--
|
||||
1.9.0
|
||||
|
||||
|
||||
From 06633875c6ebbfae598edbc20a305f6c8fb55fc6 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Thu, 13 Mar 2014 13:16:51 +0100
|
||||
Subject: [PATCH 2/2] utils: indicate capability
|
||||
NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE
|
||||
|
||||
This capability indicates that libnl does no longer overwrites
|
||||
the route scope in rtnl_route_build_msg(), as fixed by commit
|
||||
85ec9c7ad80c60f4f619472f2bb9d9595da93b26.
|
||||
|
||||
Acked-by: Thomas Graf <tgraf@suug.ch>
|
||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||
(cherry picked from commit 015c4ee59b786fec35118c2a963532b3e05ba5a2)
|
||||
|
||||
Conflicts:
|
||||
include/netlink/utils.h
|
||||
lib/utils.c
|
||||
---
|
||||
include/netlink/utils.h | 8 ++++++++
|
||||
lib/utils.c | 2 +-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/netlink/utils.h b/include/netlink/utils.h
|
||||
index e929cfd..5b0d275 100644
|
||||
--- a/include/netlink/utils.h
|
||||
+++ b/include/netlink/utils.h
|
||||
@@ -83,6 +83,14 @@ enum {
|
||||
NL_CAPABILITY_NONE,
|
||||
|
||||
/**
|
||||
+ * rtnl_route_build_msg() no longer guesses the route scope
|
||||
+ * if explicitly set to RT_SCOPE_NOWHERE.
|
||||
+ * @ingroup utils
|
||||
+ */
|
||||
+ NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE = 1,
|
||||
+#define NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE
|
||||
+
|
||||
+ /**
|
||||
* Indicate that the local port is unspecified until the user accesses
|
||||
* it (via nl_socket_get_local_port()) or until nl_connect(). More importantly,
|
||||
* if the port is left unspecified, nl_connect() will retry generating another
|
||||
diff --git a/lib/utils.c b/lib/utils.c
|
||||
index 267368e..77d1ff0 100644
|
||||
--- a/lib/utils.c
|
||||
+++ b/lib/utils.c
|
||||
@@ -1144,7 +1144,7 @@ int nl_has_capability (int capability)
|
||||
_NL_SETV((i), 2, (v2)) | _NL_SETV((i), 6, (v6)) | \
|
||||
_NL_SETV((i), 3, (v3)) | _NL_SETV((i), 7, (v7)) )
|
||||
_NL_SET(0,
|
||||
- 0,
|
||||
+ NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE,
|
||||
0,
|
||||
0,
|
||||
NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE,
|
||||
--
|
||||
1.9.0
|
||||
|
19
libnl3.spec
19
libnl3.spec
@ -3,11 +3,15 @@ Group: Development/Libraries
|
||||
License: LGPLv2
|
||||
Name: libnl3
|
||||
Version: 3.2.24
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
URL: http://www.infradead.org/~tgr/libnl/
|
||||
Source: http://www.infradead.org/~tgr/libnl/files/libnl-%{version}.tar.gz
|
||||
Source1: http://www.infradead.org/~tgr/libnl/files/libnl-doc-%{version}.tar.gz
|
||||
Patch1: 0001.ifa_flags-workaround.patch
|
||||
Patch2: 0002-rh1097176-nl-has-capability.patch
|
||||
Patch3: 0003-rh1097176-retry-local-port.patch
|
||||
Patch4: 0004-backport-diverse-fixes.patch
|
||||
Patch5: 0005-route-scope-in-route-build-msg.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
BuildRequires: flex bison
|
||||
BuildRequires: python
|
||||
@ -47,6 +51,10 @@ This package contains libnl3 API documentation
|
||||
%prep
|
||||
%setup -q -n libnl-%{version}
|
||||
%patch1 -p1 -b .0001.ifa_flags-workaround.orig
|
||||
%patch2 -p1 -b .0002-rh1097175-nl-has-capability.orig
|
||||
%patch3 -p1 -b .0003-rh1097175-retry-local-port.orig
|
||||
%patch4 -p1 -b .0004-backport-diverse-fixes.orig
|
||||
%patch5 -p1 -b .0005-route-scope-in-route-build-msg.orig
|
||||
|
||||
tar -xzf %SOURCE1
|
||||
|
||||
@ -99,6 +107,15 @@ find $RPM_BUILD_ROOT -name \*.la -delete
|
||||
%doc libnl-doc-%{version}/api/*
|
||||
|
||||
%changelog
|
||||
* Thu May 22 2014 Thomas Haller <thaller@redhat.com> - 3.2.24-3
|
||||
- add nl_has_capability() function
|
||||
- retry local port on ADDRINUSE (rh #1097175)
|
||||
- python: fix passing wrong argument in netlink/core.py
|
||||
- fix return value of nl_rtgen_request()
|
||||
- fix nl_msec2str()
|
||||
- fix crash in rtnl_act_msg_parse()
|
||||
- fix rtnl_route_build_msg() not to guess the route scope if RT_SCOPE_NOWHERE
|
||||
|
||||
* Fri Apr 4 2014 Thomas Haller <thaller@redhat.com> - 3.2.24-2
|
||||
- fix breaking on older kernels due to IFA_FLAGS attribute (rh #1063885)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user