summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.txt2
-rw-r--r--configure.ac7
-rw-r--r--contrib/sssd.spec.in4
-rw-r--r--src/conf_macros.m431
-rw-r--r--src/external/libnl.m498
-rw-r--r--src/monitor/monitor_netlink.c150
6 files changed, 207 insertions, 85 deletions
diff --git a/BUILD.txt b/BUILD.txt
index 0eb3f468..26312921 100644
--- a/BUILD.txt
+++ b/BUILD.txt
@@ -26,7 +26,7 @@ yum install openldap-devel gettext libtool pcre-devel c-ares-devel \
libxml2 pam-devel nss-devel libtevent python-devel \
libtevent-devel libtdb libtdb-devel libtalloc libtalloc-devel \
libldb libldb-devel popt-devel c-ares-devel check-devel \
- doxygen libselinux-devel libsemanage-devel bind-utils libnl-devel \
+ doxygen libselinux-devel libsemanage-devel bind-utils libnl3-devel \
gettext-devel glib2-devel
ding-libs are available in Fedora 14 and later version:
diff --git a/configure.ac b/configure.ac
index 0d810840..5d47c4e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,7 +114,6 @@ WITH_PYTHON_BINDINGS
WITH_SELINUX
WITH_NSCD
WITH_SEMANAGE
-WITH_LIBNL
WITH_NOLOGIN_SHELL
WITH_APP_LIBS
WITH_SUDO
@@ -164,6 +163,8 @@ else
AC_SUBST(UNICODE_LIBS)
fi
+WITH_LIBNL
+
WITH_INITSCRIPT
if test x$initscript = xsystemd; then
WITH_SYSTEMD_UNIT_DIR
@@ -231,10 +232,6 @@ if test x$HAVE_SEMANAGE != x -a x$HAVE_SELINUX != x; then
AM_CHECK_SEMANAGE
fi
-if test x$BUILD_LIBNL != x; then
- AM_CHECK_LIBNL
-fi
-
if test x$HAVE_SYSTEMD_UNIT != x; then
AM_CHECK_SYSTEMD
fi
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index de3059bd..478247f3 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -122,7 +122,6 @@ BuildRequires: libselinux-devel
BuildRequires: libsemanage-devel
BuildRequires: bind-utils
BuildRequires: keyutils-libs-devel
-BuildRequires: libnl-devel
BuildRequires: gettext-devel
BuildRequires: pkgconfig
BuildRequires: findutils
@@ -130,6 +129,9 @@ BuildRequires: glib2-devel
BuildRequires: selinux-policy-targeted
%if (0%{?fedora} >= 18)
BuildRequires: libcmocka-devel
+BuildRequires: libnl3-devel
+%else
+BuildRequires: libnl-devel
%endif
# RHEL 5 is too old to support samba4 and the PAC responder
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
index 65f4d6ce..4ea4e936 100644
--- a/src/conf_macros.m4
+++ b/src/conf_macros.m4
@@ -371,15 +371,40 @@ AC_DEFUN([WITH_SEMANAGE],
AC_DEFUN([WITH_LIBNL],
[ AC_ARG_WITH([libnl],
[AC_HELP_STRING([--with-libnl],
- [Whether to build with libnetlink support [AUTO]]
+ [Whether to build with libnetlink support (libnl3, libnl1, no) [auto]]
)
],
[],
with_libnl=yes
)
+
if test x"$with_libnl" = xyes; then
- BUILD_LIBNL=1
- AC_SUBST(BUILD_LIBNL)
+
+ AM_CHECK_LIBNL3
+
+ if test x"$HAVE_LIBNL" != x1; then
+ AM_CHECK_LIBNL1
+ fi
+
+ if test x"$HAVE_LIBNL" != x1; then
+ AC_MSG_WARN([Building without netlink])
+ fi
+
+ elif test x"$with_libnl" = xlibnl3; then
+
+ AM_CHECK_LIBNL3
+
+ if test x"$HAVE_LIBNL" != x1; then
+ AC_MSG_ERROR([Libnl3 required, but not available])
+ fi
+
+ elif test x"$with_libnl" = xlibnl1; then
+
+ AM_CHECK_LIBNL1
+
+ if test x"$HAVE_LIBNL" != x1; then
+ AC_MSG_ERROR([Libnl required, but not available])
+ fi
fi
])
diff --git a/src/external/libnl.m4 b/src/external/libnl.m4
index 36619ff8..d468a490 100644
--- a/src/external/libnl.m4
+++ b/src/external/libnl.m4
@@ -1,34 +1,82 @@
+dnl A macro to check if this particular version of libnl supports particular common libnl functions
+AC_DEFUN([AM_CHECK_LIBNL_FCS],
+[
+ AC_CHECK_LIB($1,
+ [nl_socket_add_membership],
+ [AC_DEFINE([HAVE_NL_SOCKET_ADD_MEMBERSHIP], 1, [Does libnl have nl_socket_add_membership?])
+ ],
+ )
+
+ AC_CHECK_LIB($1,
+ [nl_socket_modify_cb],
+ [AC_DEFINE([HAVE_NL_SOCKET_MODIFY_CB], 1, [Does libnl have nl_socket_modify_cb?])
+ ],
+ )
+
+ AC_CHECK_LIB($1,
+ [rtnl_route_get_oif],
+ [AC_DEFINE([HAVE_RTNL_ROUTE_GET_OIF], 1, [Does libnl have rtnl_route_get_oif?])
+ ],
+ )
+
+ AC_CHECK_LIB($1,
+ [nl_set_passcred],
+ [AC_DEFINE([HAVE_NL_SET_PASSCRED], 1, [Does libnl have nl_set_passcred?])
+ ],
+ )
+
+ AC_CHECK_LIB($1,
+ [nl_socket_set_passcred],
+ [AC_DEFINE([HAVE_NL_SOCKET_SET_PASSCRED], 1, [Does libnl have nl_socket_set_passcred?])
+ ],
+ )
+])
+
dnl A macro to check the availability and version of libnetlink
+AC_DEFUN([AM_CHECK_LIBNL1],
+[
+ PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.1,[
+
+ HAVE_LIBNL=1
+ HAVE_LIBNL1=1
+
+ AC_DEFINE_UNQUOTED(HAVE_LIBNL, 1, [Build with libnetlink support])
+ AC_DEFINE_UNQUOTED(HAVE_LIBNL1, 1, [Libnetlink version = 1])
+
+ AC_MSG_NOTICE([Building with libnl])
+
+ AC_CHECK_HEADERS(netlink.h)
+ AC_CHECK_LIB(nl, nl_connect, [ LIBNL_LIBS="-lnl" ], [AC_MSG_ERROR([libnl is required])])
-AC_DEFUN([AM_CHECK_LIBNL],
+ AM_CHECK_LIBNL_FCS(nl)
+
+
+ ],[AC_MSG_WARN([Netlink v1 support unavailable or too old])])
+
+ AC_SUBST(LIBNL_CFLAGS)
+ AC_SUBST(LIBNL_LIBS)
+])
+
+dnl A macro to check the availability of libnetlink version 3
+
+AC_DEFUN([AM_CHECK_LIBNL3],
[
- PKG_CHECK_MODULES(libnl, libnl-1 >= 1.1,[
+ PKG_CHECK_MODULES(LIBNL, [
+ libnl-3.0 >= 3.0
+ libnl-route-3.0 >= 3.0], [
+
HAVE_LIBNL=1
- AC_SUBST(HAVE_LIBNL)
+ HAVE_LIBNL3=1
+
+
AC_DEFINE_UNQUOTED(HAVE_LIBNL, 1, [Build with libnetlink support])
+ AC_DEFINE_UNQUOTED(HAVE_LIBNL3, 1, [Libnetlink version = 3])
+
+ AC_MSG_NOTICE([Building with libnl3])
+
+ AM_CHECK_LIBNL_FCS(nl-3)
- AC_CHECK_HEADERS(netlink.h)
- AC_CHECK_LIB(nl, nl_connect, [ LIBNL_LIBS="-lnl" ], [AC_MSG_ERROR([libnl is required])])
-
- dnl Check if this particular version of libnl supports particular functions
- AC_CHECK_LIB([nl],
- [nl_socket_add_membership],
- [AC_DEFINE([HAVE_NL_SOCKET_ADD_MEMBERSHIP], 1, [Does libnl have nl_socket_add_membership?])
- ],
- )
-
- AC_CHECK_LIB([nl],
- [nl_socket_modify_cb],
- [AC_DEFINE([HAVE_NL_SOCKET_MODIFY_CB], 1, [Does libnl have nl_socket_modify_cb?])
- ],
- )
-
- AC_CHECK_LIB([nl],
- [nl_set_passcred],
- [AC_DEFINE([HAVE_NL_SET_PASSCRED], 1, [Does libnl have nl_set_passcred?])
- ],
- )
- ],[AC_MSG_WARN([Netlink support unavailable or too old])])
+ ],[AC_MSG_WARN([Netlink v3 support unavailable or too old])])
AC_SUBST(LIBNL_CFLAGS)
AC_SUBST(LIBNL_LIBS)
diff --git a/src/monitor/monitor_netlink.c b/src/monitor/monitor_netlink.c
index 3842c4f1..932a6bf3 100644
--- a/src/monitor/monitor_netlink.c
+++ b/src/monitor/monitor_netlink.c
@@ -47,6 +47,7 @@
#include <netlink/route/rtnl.h>
#include <netlink/route/route.h>
#include <netlink/handlers.h>
+#include <netlink/socket.h>
#endif
/* Linux header file confusion causes this to be undefined. */
@@ -54,12 +55,6 @@
#define SOL_NETLINK 270
#endif
-#define nlw_get_fd nl_socket_get_fd
-#define nlw_recvmsgs_default nl_recvmsgs_default
-#define nlw_get_pid nl_socket_get_local_port
-#define nlw_object_match nl_object_match_filter
-#define NLW_OK NL_OK
-
#define SYSFS_IFACE_TEMPLATE "/sys/class/net/%s"
#define SYSFS_IFACE_PATH_MAX (16+IFNAMSIZ)
@@ -73,6 +68,32 @@
#define BUFSIZE 8
+#ifdef HAVE_LIBNL
+/* Wrappers determining use of libnl version 1 or 3 */
+#ifdef HAVE_LIBNL3
+
+#define nlw_destroy_handle nl_socket_free
+#define nlw_alloc nl_socket_alloc
+#define nlw_disable_seq_check nl_socket_disable_seq_check
+
+#define nlw_geterror(error) nl_geterror(error)
+
+#define nlw_handle nl_sock
+
+#elif HAVE_LIBNL1
+
+#define nlw_destroy_handle nl_handle_destroy
+#define nlw_alloc nl_handle_alloc
+#define nlw_disable_seq_check nl_disable_sequence_check
+
+#define nlw_geterror(error) nl_geterror()
+
+#define nlw_handle nl_handle
+
+#endif /* HAVE_LIBNL3 */
+
+#endif /* HAVE_LIBNL */
+
enum nlw_msg_type {
NLW_LINK,
NLW_ROUTE,
@@ -82,7 +103,7 @@ enum nlw_msg_type {
struct netlink_ctx {
#ifdef HAVE_LIBNL
- struct nl_handle *nlh;
+ struct nlw_handle *nlp;
#endif
struct tevent_fd *tefd;
@@ -96,7 +117,7 @@ static int netlink_ctx_destructor(void *ptr)
struct netlink_ctx *nlctx;
nlctx = talloc_get_type(ptr, struct netlink_ctx);
- nl_handle_destroy(nlctx->nlh);
+ nlw_destroy_handle(nlctx->nlp);
return 0;
}
@@ -104,6 +125,27 @@ static int netlink_ctx_destructor(void *ptr)
* Utility functions
*******************************************************************/
+/* rtnl_route_get_oif removed from libnl3 */
+int
+rtnlw_route_get_oif(struct rtnl_route * route)
+{
+#ifndef HAVE_RTNL_ROUTE_GET_OIF
+ struct rtnl_nexthop * nh;
+ int hops;
+
+ hops = rtnl_route_get_nnexthops(route);
+ if (hops <= 0) {
+ return 0;
+ }
+
+ nh = rtnl_route_nexthop_n(route, 0);
+
+ return rtnl_route_nh_get_ifindex(nh);
+#else
+ return rtnl_route_get_oif(route);
+#endif
+}
+
static bool has_wireless_extension(const char *ifname)
{
int s;
@@ -270,7 +312,7 @@ static void nladdr_to_string(struct nl_addr *nl, char *buf, size_t bufsize)
* Wrappers for different capabilities of different libnl versions
*******************************************************************/
-static bool nlw_accept_message(struct nl_handle *nlh,
+static bool nlw_accept_message(struct nlw_handle *nlp,
const struct sockaddr_nl *snl,
struct nlmsghdr *hdr)
{
@@ -290,7 +332,7 @@ static bool nlw_accept_message(struct nl_handle *nlh,
/* And any multicast message directed to our netlink PID, since multicast
* currently requires CAP_ADMIN to use.
*/
- local_port = nlw_get_pid(nlh);
+ local_port = nl_socket_get_local_port(nlp);
if ((hdr->nlmsg_pid == local_port) && snl->nl_groups) {
accept_msg = true;
}
@@ -315,7 +357,7 @@ static bool nlw_is_addr_object(struct nl_object *obj)
}
/* Ensure it's an addr object */
- if (!nlw_object_match(obj, OBJ_CAST(filter))) {
+ if (!nl_object_match_filter(obj, OBJ_CAST(filter))) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Not an addr object\n"));
is_addr_object = false;
}
@@ -336,7 +378,7 @@ static bool nlw_is_route_object(struct nl_object *obj)
}
/* Ensure it's a route object */
- if (!nlw_object_match(obj, OBJ_CAST(filter))) {
+ if (!nl_object_match_filter(obj, OBJ_CAST(filter))) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Not a route object\n"));
is_route_object = false;
}
@@ -357,7 +399,7 @@ static bool nlw_is_link_object(struct nl_object *obj)
}
/* Ensure it's a link object */
- if (!nlw_object_match(obj, OBJ_CAST(filter))) {
+ if (!nl_object_match_filter(obj, OBJ_CAST(filter))) {
DEBUG(2, ("Not a link object\n"));
is_link_object = false;
}
@@ -366,27 +408,30 @@ static bool nlw_is_link_object(struct nl_object *obj)
return is_link_object;
}
-static int nlw_enable_passcred(struct nl_handle *nlh)
+static int nlw_enable_passcred(struct nlw_handle *nlp)
{
-#ifndef HAVE_NL_SET_PASSCRED
- return EOK; /* not available in this version */
+#ifdef HAVE_NL_SET_PASSCRED
+ return nl_set_passcred(nlp, 1); /* 1 = enabled */
+#elif HAVE_NL_SOCKET_SET_PASSCRED
+ return nl_socket_set_passcred(nlp, 1);
#else
- return nl_set_passcred(nlh, 1); /* 1 = enabled */
+ return EOK; /* not available in this version */
#endif
}
-static int nlw_group_subscribe(struct nl_handle *nlh, int group)
+static int nlw_group_subscribe(struct nlw_handle *nlp, int group)
{
int ret;
#ifdef HAVE_NL_SOCKET_ADD_MEMBERSHIP
- ret = nl_socket_add_membership(nlh, group);
+ ret = nl_socket_add_membership(nlp, group);
if (ret != 0) {
- DEBUG(1, ("Unable to add membership: %s\n", nl_geterror()));
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Unable to add membership: %s\n", nlw_geterror(ret)));
return ret;
}
#else
- int nlfd = nlw_get_fd(nlh);
+ int nlfd = nl_socket_get_fd(nlp);
errno = 0;
ret = setsockopt(nlfd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
@@ -401,13 +446,13 @@ static int nlw_group_subscribe(struct nl_handle *nlh, int group)
return 0;
}
-static int nlw_groups_subscribe(struct nl_handle *nlh, int *groups)
+static int nlw_groups_subscribe(struct nlw_handle *nlp, int *groups)
{
int ret;
int i;
for (i=0; groups[i]; i++) {
- ret = nlw_group_subscribe(nlh, groups[i]);
+ ret = nlw_group_subscribe(nlp, groups[i]);
if (ret != EOK) return ret;
}
@@ -435,11 +480,11 @@ static int event_msg_recv(struct nl_msg *msg, void *arg)
hdr = nlmsg_hdr(msg);
snl = nlmsg_get_src(msg);
- if (!nlw_accept_message(ctx->nlh, snl, hdr)) {
+ if (!nlw_accept_message(ctx->nlp, snl, hdr)) {
return NL_SKIP;
}
- return NLW_OK;
+ return NL_OK;
}
static void link_msg_handler(struct nl_object *obj, void *arg);
@@ -487,28 +532,30 @@ static int event_msg_ready(struct nl_msg *msg, void *arg)
return EOK; /* Don't care */
}
- return NLW_OK;
+ return NL_OK;
}
-static int nlw_set_callbacks(struct nl_handle *nlh, void *data)
+static int nlw_set_callbacks(struct nlw_handle *nlp, void *data)
{
int ret = EIO;
-#ifndef HAVE_NL_SOCKET_MODIFY_CB
- struct nl_cb *cb = nl_handle_get_cb(nlh);
- ret = nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, data);
+#ifdef HAVE_NL_SOCKET_MODIFY_CB
+ ret = nl_socket_modify_cb(nlp, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv,
+ data);
#else
- ret = nl_socket_modify_cb(nlh, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, data);
+ struct nl_cb *cb = nl_handle_get_cb(nlp);
+ ret = nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, data);
#endif
if (ret != 0) {
DEBUG(1, ("Unable to set validation callback\n"));
return ret;
}
-#ifndef HAVE_NL_SOCKET_MODIFY_CB
- ret = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready, data);
+#ifdef HAVE_NL_SOCKET_MODIFY_CB
+ ret = nl_socket_modify_cb(nlp, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready,
+ data);
#else
- ret = nl_socket_modify_cb(nlh, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready, data);
+ ret = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready, data);
#endif
if (ret != 0) {
DEBUG(1, ("Unable to set receive callback\n"));
@@ -534,8 +581,9 @@ static void route_msg_debug_print(struct rtnl_route *route_obj)
}
DEBUG(SSSDBG_TRACE_LIBS, ("route idx %d flags %#X family %d addr %s/%d\n",
- rtnl_route_get_oif(route_obj), rtnl_route_get_flags(route_obj),
+ rtnlw_route_get_oif(route_obj), rtnl_route_get_flags(route_obj),
rtnl_route_get_family(route_obj), buf, prefixlen));
+
}
/*
@@ -665,12 +713,12 @@ static void netlink_fd_handler(struct tevent_context *ev, struct tevent_fd *fde,
struct netlink_ctx *nlctx = talloc_get_type(data, struct netlink_ctx);
int ret;
- if (!nlctx || !nlctx->nlh) {
+ if (!nlctx || !nlctx->nlp) {
DEBUG(1, ("Invalid netlink handle, this is most likely a bug!\n"));
return;
}
- ret = nlw_recvmsgs_default(nlctx->nlh);
+ ret = nl_recvmsgs_default(nlctx->nlp);
if (ret != EOK) {
DEBUG(1, ("Error while reading from netlink fd\n"));
return;
@@ -699,17 +747,17 @@ int setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
nlctx->change_cb = change_cb;
nlctx->cb_data = cb_data;
- /* allocate the libnl handle and register the default filter set */
- nlctx->nlh = nl_handle_alloc();
- if (!nlctx->nlh) {
- DEBUG(1, (("unable to allocate netlink handle: %s"),
- nl_geterror()));
+ /* allocate the libnl handle/socket and register the default filter set */
+ nlctx->nlp = nlw_alloc();
+ if (!nlctx->nlp) {
+ DEBUG(SSSDBG_CRIT_FAILURE, (("unable to allocate netlink handle: %s"),
+ nlw_geterror(ENOMEM)));
ret = ENOMEM;
goto fail;
}
/* Register our custom message validation filter */
- ret = nlw_set_callbacks(nlctx->nlh, nlctx);
+ ret = nlw_set_callbacks(nlctx->nlp, nlctx);
if (ret != 0) {
DEBUG(1, ("Unable to set callbacks\n"));
ret = EIO;
@@ -717,31 +765,33 @@ int setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
}
/* Try to start talking to netlink */
- ret = nl_connect(nlctx->nlh, NETLINK_ROUTE);
+ ret = nl_connect(nlctx->nlp, NETLINK_ROUTE);
if (ret != 0) {
- DEBUG(1, ("Unable to connect to netlink: %s\n", nl_geterror()));
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Unable to connect to netlink: %s\n", nlw_geterror(ret)));
ret = EIO;
goto fail;
}
- ret = nlw_enable_passcred(nlctx->nlh);
+ ret = nlw_enable_passcred(nlctx->nlp);
if (ret != 0) {
- DEBUG(1, ("Cannot enable credential passing: %s\n", nl_geterror()));
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Cannot enable credential passing: %s\n", nlw_geterror(ret)));
ret = EIO;
goto fail;
}
/* Subscribe to the LINK group for internal carrier signals */
- ret = nlw_groups_subscribe(nlctx->nlh, groups);
+ ret = nlw_groups_subscribe(nlctx->nlp, groups);
if (ret != 0) {
DEBUG(1, ("Unable to subscribe to netlink monitor\n"));
ret = EIO;
goto fail;
}
- nl_disable_sequence_check(nlctx->nlh);
+ nlw_disable_seq_check(nlctx->nlp);
- nlfd = nlw_get_fd(nlctx->nlh);
+ nlfd = nl_socket_get_fd(nlctx->nlp);
flags = fcntl(nlfd, F_GETFL, 0);
errno = 0;