diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 44a119ce05..68ed1966a5 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,15 @@ #define warning(...) nm_log_warn (LOGD_PLATFORM, __VA_ARGS__) #define error(...) nm_log_err (LOGD_PLATFORM, __VA_ARGS__) + +struct libnl_vtable +{ + void *handle; + + int (*f_nl_has_capability) (int capability); +}; + + typedef struct { struct nl_sock *nlh; struct nl_sock *nlh_event; @@ -89,6 +99,43 @@ nm_linux_platform_setup (void) /******************************************************************/ +static int +_nl_f_nl_has_capability (int capability) +{ + return FALSE; +} + +static struct libnl_vtable * +_nl_get_vtable () +{ + static struct libnl_vtable vtable; + + if (G_UNLIKELY (!vtable.f_nl_has_capability)) { + void *handle; + + handle = dlopen ("libnl-3.so", RTLD_LAZY | RTLD_NOLOAD); + if (handle) { + vtable.handle = handle; + vtable.f_nl_has_capability = dlsym (handle, "nl_has_capability"); + } + + if (!vtable.f_nl_has_capability) + vtable.f_nl_has_capability = &_nl_f_nl_has_capability; + + g_return_val_if_fail (vtable.handle, &vtable); + } + + return &vtable; +} + +static gboolean +_nl_has_capability (int capability) +{ + return (_nl_get_vtable ()->f_nl_has_capability) (capability); +} + +/******************************************************************/ + /* libnl library workarounds and additions */ /* Automatic deallocation of local variables */