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).
This commit is contained in:
Thomas Haller
2022-06-23 18:08:07 +02:00
parent 919a61bc53
commit c09b37f3c7
3 changed files with 47 additions and 17 deletions

View File

@@ -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,

View File

@@ -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;

View File

@@ -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);