summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libsystemd/sd-netlink/netlink-internal.h3
-rw-r--r--src/libsystemd/sd-netlink/netlink-socket.c47
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c44
3 files changed, 59 insertions, 35 deletions
diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h
index 763acbbb09..7290f4e875 100644
--- a/src/libsystemd/sd-netlink/netlink-internal.h
+++ b/src/libsystemd/sd-netlink/netlink-internal.h
@@ -113,6 +113,9 @@ struct sd_netlink_message {
int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type);
int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret);
+int socket_open(int family);
+int socket_bind(sd_netlink *nl);
+int socket_join_broadcast_group(sd_netlink *nl, unsigned group);
int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
int socket_read_message(sd_netlink *nl);
diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c
index 2e2826ac63..8136cf36ae 100644
--- a/src/libsystemd/sd-netlink/netlink-socket.c
+++ b/src/libsystemd/sd-netlink/netlink-socket.c
@@ -34,6 +34,53 @@
#include "netlink-internal.h"
#include "netlink-types.h"
+int socket_open(int family) {
+ int fd;
+
+ fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, family);
+ if (fd < 0)
+ return -errno;
+
+ return fd;
+}
+
+int socket_bind(sd_netlink *nl) {
+ socklen_t addrlen;
+ int r, one = 1;
+
+ r = setsockopt(nl->fd, SOL_NETLINK, NETLINK_PKTINFO, &one, sizeof(one));
+ if (r < 0)
+ return -errno;
+
+ addrlen = sizeof(nl->sockaddr);
+
+ r = bind(nl->fd, &nl->sockaddr.sa, addrlen);
+ /* ignore EINVAL to allow opening an already bound socket */
+ if (r < 0 && errno != EINVAL)
+ return -errno;
+
+ r = getsockname(nl->fd, &nl->sockaddr.sa, &addrlen);
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
+
+
+int socket_join_broadcast_group(sd_netlink *nl, unsigned group) {
+ int r;
+
+ assert(nl);
+ assert(nl->fd >= 0);
+ assert(group > 0);
+
+ r = setsockopt(nl->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group));
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
+
/* returns the number of bytes sent, or a negative error code */
int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
union {
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 572de90417..c413b1c266 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -103,8 +103,7 @@ static bool rtnl_pid_changed(sd_netlink *rtnl) {
int sd_netlink_open_fd(sd_netlink **ret, int fd) {
_cleanup_netlink_unref_ sd_netlink *rtnl = NULL;
- socklen_t addrlen;
- int r, one = 1;
+ int r;
assert_return(ret, -EINVAL);
assert_return(fd >= 0, -EINVAL);
@@ -113,22 +112,11 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) {
if (r < 0)
return r;
- r = setsockopt(fd, SOL_NETLINK, NETLINK_PKTINFO, &one, sizeof(one));
- if (r < 0)
- return -errno;
-
- addrlen = sizeof(rtnl->sockaddr);
-
- r = bind(fd, &rtnl->sockaddr.sa, addrlen);
- /* ignore EINVAL to allow opening an already bound socket */
- if (r < 0 && errno != EINVAL)
- return -errno;
+ rtnl->fd = fd;
- r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen);
+ r = socket_bind(rtnl);
if (r < 0)
- return -errno;
-
- rtnl->fd = fd;
+ return r;
*ret = rtnl;
rtnl = NULL;
@@ -140,9 +128,9 @@ int sd_netlink_open(sd_netlink **ret) {
_cleanup_close_ int fd = -1;
int r;
- fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_ROUTE);
+ fd = socket_open(NETLINK_ROUTE);
if (fd < 0)
- return -errno;
+ return fd;
r = sd_netlink_open_fd(ret, fd);
if (r < 0)
@@ -153,20 +141,6 @@ int sd_netlink_open(sd_netlink **ret) {
return 0;
}
-static int rtnl_join_broadcast_group(sd_netlink *rtnl, unsigned group) {
- int r;
-
- assert(rtnl);
- assert(rtnl->fd >= 0);
- assert(group > 0);
-
- r = setsockopt(rtnl->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group));
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
int sd_netlink_inc_rcvbuf(const sd_netlink *const rtnl, const int size) {
return fd_inc_rcvbuf(rtnl->fd, size);
}
@@ -885,7 +859,7 @@ int sd_netlink_add_match(sd_netlink *rtnl,
case RTM_SETLINK:
case RTM_GETLINK:
case RTM_DELLINK:
- r = rtnl_join_broadcast_group(rtnl, RTNLGRP_LINK);
+ r = socket_join_broadcast_group(rtnl, RTNLGRP_LINK);
if (r < 0)
return r;
@@ -893,11 +867,11 @@ int sd_netlink_add_match(sd_netlink *rtnl,
case RTM_NEWADDR:
case RTM_GETADDR:
case RTM_DELADDR:
- r = rtnl_join_broadcast_group(rtnl, RTNLGRP_IPV4_IFADDR);
+ r = socket_join_broadcast_group(rtnl, RTNLGRP_IPV4_IFADDR);
if (r < 0)
return r;
- r = rtnl_join_broadcast_group(rtnl, RTNLGRP_IPV6_IFADDR);
+ r = socket_join_broadcast_group(rtnl, RTNLGRP_IPV6_IFADDR);
if (r < 0)
return r;