diff options
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-internal.h | 3 | ||||
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-socket.c | 47 | ||||
-rw-r--r-- | src/libsystemd/sd-netlink/sd-netlink.c | 44 |
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; |