diff options
author | Thomas Haller <thaller@redhat.com> | 2022-06-23 18:08:07 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-06-24 11:03:37 +0200 |
commit | c09b37f3c7c35c8a50b19dbaad3e963de05da9bb (patch) | |
tree | 3693ff4f946600a67a45272ea1c8f112b7026c17 | |
parent | 919a61bc533abf6b6fedf728eba2703b126efb46 (diff) | |
download | NetworkManager-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.c | 19 | ||||
-rw-r--r-- | src/libnm-platform/nm-netlink.c | 28 | ||||
-rw-r--r-- | src/libnm-platform/nm-netlink.h | 17 |
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); |