summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-06-23 18:08:07 +0200
committerThomas Haller <thaller@redhat.com>2022-06-24 11:03:37 +0200
commitc09b37f3c7c35c8a50b19dbaad3e963de05da9bb (patch)
tree3693ff4f946600a67a45272ea1c8f112b7026c17
parent919a61bc533abf6b6fedf728eba2703b126efb46 (diff)
downloadNetworkManager-c09b37f3c7c35c8a50b19dbaad3e963de05da9bb.tar.gz
platform/netlink: add flags argument to nl_socket_new()
The real purpose is that we set the socket options before bind(). For that, we need to be able to specify the flag during nl_socket_new(). Another reason is that these are common questions to ponder while creating a netlink socket. There shouldn't be several setter functions, just specify the flag right away. These parameters are not going to change afterwards (at least, we don't need/use that and we don't have API for that either).
-rw-r--r--src/libnm-platform/nm-linux-platform.c19
-rw-r--r--src/libnm-platform/nm-netlink.c28
-rw-r--r--src/libnm-platform/nm-netlink.h17
3 files changed, 47 insertions, 17 deletions
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index 4b9280d696..a3d3b50c6e 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -9747,7 +9747,7 @@ constructed(GObject *_object)
/*************************************************************************/
- nle = nl_socket_new(&priv->sk_genl_sync, NETLINK_GENERIC, TRUE, 0, 0);
+ nle = nl_socket_new(&priv->sk_genl_sync, NETLINK_GENERIC, NL_SOCKET_FLAGS_NONE, 0, 0);
g_assert(!nle);
_LOGD("genl: generic netlink socket for sync operations created: port=%u, fd=%d",
@@ -9756,18 +9756,15 @@ constructed(GObject *_object)
/*************************************************************************/
- nle = nl_socket_new(&priv->sk_rtnl, NETLINK_ROUTE, FALSE, 8 * 1024 * 1024, 0);
+ /* disable MSG_PEEK, we will handle lost messages ourselves. */
+ nle = nl_socket_new(&priv->sk_rtnl,
+ NETLINK_ROUTE,
+ NL_SOCKET_FLAGS_NONBLOCK | NL_SOCKET_FLAGS_PASSCRED
+ | NL_SOCKET_FLAGS_DISABLE_MSG_PEEK,
+ 8 * 1024 * 1024,
+ 0);
g_assert(!nle);
- nle = nl_socket_set_passcred(priv->sk_rtnl, 1);
- g_assert(!nle);
-
- /* explicitly set the msg buffer size and disable MSG_PEEK.
- * We use our own receive buffer priv->netlink_recv_buf.
- * If we encounter NME_NL_MSG_TRUNC, we will increase the buffer
- * and resync (as we would have lost the message without NL_MSG_PEEK). */
- nl_socket_disable_msg_peek(priv->sk_rtnl);
-
nle = nl_socket_add_memberships(priv->sk_rtnl,
RTNLGRP_IPV4_IFADDR,
RTNLGRP_IPV4_ROUTE,
diff --git a/src/libnm-platform/nm-netlink.c b/src/libnm-platform/nm-netlink.c
index 9ee13eedb8..7761fc58b5 100644
--- a/src/libnm-platform/nm-netlink.c
+++ b/src/libnm-platform/nm-netlink.c
@@ -1061,7 +1061,11 @@ nl_socket_disable_msg_peek(struct nl_sock *sk)
/*****************************************************************************/
int
-nl_socket_new(struct nl_sock **out_sk, int protocol, bool blocking, int bufsize_rx, int bufsize_tx)
+nl_socket_new(struct nl_sock **out_sk,
+ int protocol,
+ NLSocketFlags flags,
+ int bufsize_rx,
+ int bufsize_tx)
{
nm_auto_nlsock struct nl_sock *sk = NULL;
nm_auto_close int fd = -1;
@@ -1073,7 +1077,10 @@ nl_socket_new(struct nl_sock **out_sk, int protocol, bool blocking, int bufsize_
nm_assert(out_sk && !*out_sk);
- fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC | (blocking ? 0 : SOCK_NONBLOCK), protocol);
+ fd = socket(AF_NETLINK,
+ SOCK_RAW | SOCK_CLOEXEC
+ | (NM_FLAGS_HAS(flags, NL_SOCKET_FLAGS_NONBLOCK) ? SOCK_NONBLOCK : 0),
+ protocol);
if (fd < 0)
return -nm_errno_from_native(errno);
@@ -1096,12 +1103,27 @@ nl_socket_new(struct nl_sock **out_sk, int protocol, bool blocking, int bufsize_
},
.s_seq_expect = t,
.s_seq_next = t,
+ .s_flags = NM_FLAGS_HAS(flags, NL_SOCKET_FLAGS_DISABLE_MSG_PEEK) ? 0 : NL_MSG_PEEK,
};
nmerr = nl_socket_set_buffer_size(sk, bufsize_rx, bufsize_tx);
if (nmerr < 0)
return nmerr;
+ (void) nl_socket_set_ext_ack(sk, TRUE);
+
+ if (NM_FLAGS_HAS(flags, NL_SOCKET_FLAGS_PASSCRED)) {
+ err = nl_socket_set_passcred(sk, 1);
+ if (err < 0)
+ return err;
+ }
+
+ if (NM_FLAGS_HAS(flags, NL_SOCKET_FLAGS_PKTINFO)) {
+ err = nl_socket_set_pktinfo(sk, 1);
+ if (err < 0)
+ return err;
+ }
+
err = bind(sk->s_fd, (struct sockaddr *) &sk->s_local, sizeof(sk->s_local));
if (err != 0)
return -nm_errno_from_native(errno);
@@ -1117,8 +1139,6 @@ nl_socket_new(struct nl_sock **out_sk, int protocol, bool blocking, int bufsize_
if (local.nl_family != AF_NETLINK)
return -NME_UNSPEC;
- (void) nl_socket_set_ext_ack(sk, TRUE);
-
sk->s_local = local;
sk->s_proto = protocol;
diff --git a/src/libnm-platform/nm-netlink.h b/src/libnm-platform/nm-netlink.h
index 013df74869..3b9f960fac 100644
--- a/src/libnm-platform/nm-netlink.h
+++ b/src/libnm-platform/nm-netlink.h
@@ -507,13 +507,26 @@ nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, i
/*****************************************************************************/
+typedef enum {
+ NL_SOCKET_FLAGS_NONE = 0,
+ NL_SOCKET_FLAGS_NONBLOCK = 0x1,
+ NL_SOCKET_FLAGS_PASSCRED = 0x2,
+ NL_SOCKET_FLAGS_PKTINFO = 0x4,
+ NL_SOCKET_FLAGS_DISABLE_MSG_PEEK = 0x8,
+
+ _NL_SOCKET_FLAGS_ALL = (NL_SOCKET_FLAGS_DISABLE_MSG_PEEK << 1) - 1,
+} NLSocketFlags;
+
#define NL_AUTO_PORT 0
#define NL_AUTO_SEQ 0
struct nl_sock;
-int
-nl_socket_new(struct nl_sock **out_sk, int protocol, bool blocking, int bufsize_rx, int bufsize_tx);
+int nl_socket_new(struct nl_sock **out_sk,
+ int protocol,
+ NLSocketFlags flags,
+ int bufsize_rx,
+ int bufsize_tx);
void nl_socket_free(struct nl_sock *sk);