90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/*
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek SSSD - Service monitor - netlink support
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek Authors:
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek Parts of this code were borrowed from NetworkManager
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek Copyright (C) 2010 Red Hat
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek This program is free software; you can redistribute it and/or modify
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek it under the terms of the GNU General Public License as published by
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek (at your option) any later version.
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek This program is distributed in the hope that it will be useful,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek GNU General Public License for more details.
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek You should have received a copy of the GNU General Public License
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek*/
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
1384d0ce6ea741aefb56b0006b6268d76e6cc2c2Jakub Hrozek#include "config.h"
1384d0ce6ea741aefb56b0006b6268d76e6cc2c2Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <talloc.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <tevent.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <sys/types.h>
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek#include <sys/ioctl.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <sys/socket.h>
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek#include <netinet/in.h>
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek#include <arpa/inet.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <unistd.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <fcntl.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include "monitor/monitor.h"
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include "util/util.h"
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#ifdef HAVE_LIBNL
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <linux/if.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <linux/socket.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <linux/rtnetlink.h>
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek#include <linux/wireless.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <netlink/netlink.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <netlink/utils.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <netlink/route/addr.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <netlink/route/link.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <netlink/route/rtnl.h>
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek#include <netlink/route/route.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#include <netlink/handlers.h>
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#include <netlink/socket.h>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/* Linux header file confusion causes this to be undefined. */
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#ifndef SOL_NETLINK
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#define SOL_NETLINK 270
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek#define SYSFS_IFACE_TEMPLATE "/sys/class/net/%s"
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek#define SYSFS_IFACE_PATH_MAX (16+IFNAMSIZ)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek#define PHY_80211_SUBDIR "phy80211"
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz/* 9 = strlen(PHY_80211_SUBDIR)+1, 1 = path delimiter */
5d98dce1111f04475e0d14ace9a4bcb876206fa5Jakub Hrozek#define SYSFS_SUBDIR_PATH_MAX (SYSFS_IFACE_PATH_MAX+9+1)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek#define TYPE_FILE "type"
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz/* 5 = strlen(TYPE_FILE)+1, 1 = path delimiter */
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek#define SYSFS_TYPE_PATH_MAX (SYSFS_IFACE_PATH_MAX+5+1)
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek#define BUFSIZE 8
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#ifdef HAVE_LIBNL
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos/* Wrappers determining use of libnl version 1 or 3 */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#ifdef HAVE_LIBNL3
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_destroy_handle nl_socket_free
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_alloc nl_socket_alloc
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_disable_seq_check nl_socket_disable_seq_check
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_geterror(error) nl_geterror(error)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_handle nl_sock
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
fa0938a6e3cb928602633c3da0b909deb269369dLukas Slebodnik#elif defined(HAVE_LIBNL1)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_destroy_handle nl_handle_destroy
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_alloc nl_handle_alloc
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_disable_seq_check nl_disable_sequence_check
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_geterror(error) nl_geterror()
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_handle nl_handle
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#endif /* HAVE_LIBNL3 */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#endif /* HAVE_LIBNL */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekenum nlw_msg_type {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek NLW_LINK,
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek NLW_ROUTE,
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek NLW_ADDR,
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek NLW_OTHER
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek};
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstruct netlink_ctx {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#ifdef HAVE_LIBNL
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos struct nlw_handle *nlp;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct tevent_fd *tefd;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek network_change_cb change_cb;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek void *cb_data;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek};
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#ifdef HAVE_LIBNL
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic int netlink_ctx_destructor(void *ptr)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *nlctx;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx = talloc_get_type(ptr, struct netlink_ctx);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos nlw_destroy_handle(nlctx->nlp);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return 0;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek/*******************************************************************
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek * Utility functions
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek *******************************************************************/
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos/* rtnl_route_get_oif removed from libnl3 */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosint
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosrtnlw_route_get_oif(struct rtnl_route * route)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos{
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#ifndef HAVE_RTNL_ROUTE_GET_OIF
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos struct rtnl_nexthop * nh;
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos int hops;
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos hops = rtnl_route_get_nnexthops(route);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos if (hops <= 0) {
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return 0;
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos }
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos nh = rtnl_route_nexthop_n(route, 0);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return rtnl_route_nh_get_ifindex(nh);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#else
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return rtnl_route_get_oif(route);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#endif
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos}
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozekstatic bool has_wireless_extension(const char *ifname)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek{
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek int s;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek errno_t ret;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek struct iwreq iwr;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek s = socket(PF_INET, SOCK_DGRAM, 0);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (s == -1) {
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Could not open socket: [%d] %s\n", ret, strerror(ret));
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
39ed7bb0c0e1d4c431033b77cdeb176cfeae26e9Jakub Hrozek strncpy(iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ-1);
39ed7bb0c0e1d4c431033b77cdeb176cfeae26e9Jakub Hrozek iwr.ifr_ifrn.ifrn_name[IFNAMSIZ-1] = '\0';
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* Does the interface support a wireless extension? */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = ioctl(s, SIOCGIWNAME, &iwr);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek close(s);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return ret == 0;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek}
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozekstatic bool has_ethernet_encapsulation(const char *sysfs_path)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek{
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek char type_path[SYSFS_TYPE_PATH_MAX];
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek errno_t ret;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek int fd = -1;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek char buf[BUFSIZE];
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek ret = snprintf(type_path, SYSFS_TYPE_PATH_MAX,
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek "%s/%s", sysfs_path, TYPE_FILE);
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek if (ret < 0) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n");
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek return false;
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek } else if (ret >= SYSFS_TYPE_PATH_MAX) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n");
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek return false;
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek }
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek errno = 0;
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek fd = open(type_path, O_RDONLY);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (fd == -1) {
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Could not open sysfs file %s: [%d] %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov type_path, ret, strerror(ret));
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek memset(buf, 0, BUFSIZE);
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek errno = 0;
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek ret = sss_atomic_read_s(fd, buf, BUFSIZE);
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek if (ret == -1) {
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek ret = errno;
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "read failed [%d][%s].\n", ret, strerror(ret));
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek close(fd);
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek close(fd);
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek buf[BUFSIZE-1] = '\0';
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return strncmp(buf, "1\n", BUFSIZE) == 0;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek}
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozekstatic bool has_phy_80211_subdir(const char *sysfs_path)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek{
5d98dce1111f04475e0d14ace9a4bcb876206fa5Jakub Hrozek char phy80211_path[SYSFS_SUBDIR_PATH_MAX];
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek struct stat statbuf;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek errno_t ret;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = snprintf(phy80211_path, SYSFS_SUBDIR_PATH_MAX,
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek "%s/%s", sysfs_path, PHY_80211_SUBDIR);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (ret < 0) {
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek } else if (ret >= SYSFS_SUBDIR_PATH_MAX) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek errno = 0;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = stat(phy80211_path, &statbuf);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (ret == -1) {
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = errno;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (ret == ENOENT || ret == ENOTDIR) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "No %s directory in sysfs, probably "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "not a wireless interface\n", PHY_80211_SUBDIR);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek } else {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "stat failed: [%d] %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (statbuf.st_mode & S_IFDIR) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "Directory %s found in sysfs, looks like "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "a wireless iface\n", PHY_80211_SUBDIR);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek}
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozekstatic bool discard_iff_up(const char *ifname)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek{
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek char path[SYSFS_IFACE_PATH_MAX];
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek errno_t ret;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* This catches most of the new 80211 drivers */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (has_wireless_extension(ifname)) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%s has a wireless extension\n", ifname);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = snprintf(path, SYSFS_IFACE_PATH_MAX, SYSFS_IFACE_TEMPLATE, ifname);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (ret < 0) {
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek } else if (ret >= SYSFS_IFACE_PATH_MAX) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* This will filter PPP and such. Both wired and wireless
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek * interfaces have the encapsulation. */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (!has_ethernet_encapsulation(path)) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%s does not have ethernet encapsulation, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "filtering out\n", ifname);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* This captures old WEXT drivers, the new mac8011 would
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek * be caught by the ioctl check */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (has_phy_80211_subdir(path)) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%s has a 802_11 subdir, filtering out\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ifname);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek }
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek}
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void nladdr_to_string(struct nl_addr *nl, char *buf, size_t bufsize)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek int addr_family;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek void *addr;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek addr_family = nl_addr_get_family(nl);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (addr_family != AF_INET && addr_family != AF_INET6) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek strncpy(buf, "unknown", bufsize);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek addr = nl_addr_get_binary_addr(nl);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!addr) return;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (inet_ntop(addr_family, addr, buf, bufsize) == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop failed\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek snprintf(buf, bufsize, "unknown");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/*******************************************************************
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * Wrappers for different capabilities of different libnl versions
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek *******************************************************************/
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic bool nlw_accept_message(struct nlw_handle *nlp,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek const struct sockaddr_nl *snl,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct nlmsghdr *hdr)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek bool accept_msg = false;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek uint32_t local_port;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (snl == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Malformed message, skipping\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return false;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Accept any messages from the kernel */
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (hdr->nlmsg_pid == 0 || snl->nl_pid == 0) {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek accept_msg = true;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* And any multicast message directed to our netlink PID, since multicast
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * currently requires CAP_ADMIN to use.
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos local_port = nl_socket_get_local_port(nlp);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if ((hdr->nlmsg_pid == local_port) && snl->nl_groups) {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek accept_msg = true;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (accept_msg == false) {
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik DEBUG(SSSDBG_TRACE_ALL,
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik "ignoring netlink message from PID %d\n", hdr->nlmsg_pid);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return accept_msg;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic bool nlw_is_addr_object(struct nl_object *obj)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek bool is_addr_object = true;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct rtnl_addr *filter;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek filter = rtnl_addr_alloc();
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!filter) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error!\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek is_addr_object = false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* Ensure it's an addr object */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos if (!nl_object_match_filter(obj, OBJ_CAST(filter))) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Not an addr object\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek is_addr_object = false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek rtnl_addr_put(filter);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return is_addr_object;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic bool nlw_is_route_object(struct nl_object *obj)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek bool is_route_object = true;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct rtnl_route *filter;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek filter = rtnl_route_alloc();
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!filter) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error!\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek is_route_object = false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* Ensure it's a route object */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos if (!nl_object_match_filter(obj, OBJ_CAST(filter))) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Not a route object\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek is_route_object = false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek rtnl_route_put(filter);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return is_route_object;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic bool nlw_is_link_object(struct nl_object *obj)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek bool is_link_object = true;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct rtnl_link *filter;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek filter = rtnl_link_alloc();
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (!filter) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Allocation error!\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek is_link_object = false;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Ensure it's a link object */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos if (!nl_object_match_filter(obj, OBJ_CAST(filter))) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Not a link object\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek is_link_object = false;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek rtnl_link_put(filter);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return is_link_object;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_enable_passcred(struct nlw_handle *nlp)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#ifdef HAVE_NL_SET_PASSCRED
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return nl_set_passcred(nlp, 1); /* 1 = enabled */
fa0938a6e3cb928602633c3da0b909deb269369dLukas Slebodnik#elif defined(HAVE_NL_SOCKET_SET_PASSCRED)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return nl_socket_set_passcred(nlp, 1);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#else
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return EOK; /* not available in this version */
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_group_subscribe(struct nlw_handle *nlp, int group)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek int ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#ifdef HAVE_NL_SOCKET_ADD_MEMBERSHIP
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_socket_add_membership(nlp, group);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != 0) {
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to add membership: %s\n", nlw_geterror(ret));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#else
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos int nlfd = nl_socket_get_fd(nlp);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek errno = 0;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = setsockopt(nlfd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek &group, sizeof(group));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret < 0) {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "setsockopt failed (%d): %s\n", ret, strerror(ret));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return 0;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_groups_subscribe(struct nlw_handle *nlp, int *groups)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek int ret;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek int i;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek for (i=0; groups[i]; i++) {
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nlw_group_subscribe(nlp, groups[i]);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (ret != EOK) return ret;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return EOK;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/*******************************************************************
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * Callbacks for validating and receiving messages
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek *******************************************************************/
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic int event_msg_recv(struct nl_msg *msg, void *arg)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct nlmsghdr *hdr;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek const struct sockaddr_nl *snl;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct ucred *creds;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek creds = nlmsg_get_creds(msg);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (!creds || creds->uid != 0) {
f2c346eaa486431ffa2a3adc05356159de834e2eLukas Slebodnik DEBUG(SSSDBG_TRACE_ALL,
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik "Ignoring netlink message from UID %"SPRIuid"\n",
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik creds ? creds->uid : (uid_t)-1);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return NL_SKIP;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek hdr = nlmsg_hdr(msg);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek snl = nlmsg_get_src(msg);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos if (!nlw_accept_message(ctx->nlp, snl, hdr)) {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return NL_SKIP;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return NL_OK;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic void link_msg_handler(struct nl_object *obj, void *arg);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void route_msg_handler(struct nl_object *obj, void *arg);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void addr_msg_handler(struct nl_object *obj, void *arg);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic enum nlw_msg_type message_type(struct nlmsghdr *hdr)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_FUNC_DATA, "netlink Message type: %d\n", hdr->nlmsg_type);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek switch (hdr->nlmsg_type) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* network interface added */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case RTM_NEWLINK:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return NLW_LINK;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* routing table changed */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case RTM_NEWROUTE:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case RTM_DELROUTE:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return NLW_ROUTE;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* IP address added or deleted */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case RTM_NEWADDR:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case RTM_DELADDR:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return NLW_ADDR;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* Something else happened, but we don't care (typically RTM_GET* ) */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek default:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return NLW_OTHER;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return NLW_OTHER;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic int event_msg_ready(struct nl_msg *msg, void *arg)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct nlmsghdr *hdr = nlmsg_hdr(msg);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek switch (message_type(hdr)) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case NLW_LINK:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nl_msg_parse(msg, &link_msg_handler, arg);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek break;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case NLW_ROUTE:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nl_msg_parse(msg, &route_msg_handler, arg);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek break;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek case NLW_ADDR:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nl_msg_parse(msg, &addr_msg_handler, arg);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek break;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek default:
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return EOK; /* Don't care */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return NL_OK;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_set_callbacks(struct nlw_handle *nlp, void *data)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek int ret = EIO;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#ifdef HAVE_NL_SOCKET_MODIFY_CB
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_socket_modify_cb(nlp, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv,
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos data);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#else
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos struct nl_cb *cb = nl_handle_get_cb(nlp);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, data);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set validation callback\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#ifdef HAVE_NL_SOCKET_MODIFY_CB
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_socket_modify_cb(nlp, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready,
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos data);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#else
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready, data);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set receive callback\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void route_msg_debug_print(struct rtnl_route *route_obj)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek int prefixlen;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek char buf[INET6_ADDRSTRLEN];
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct nl_addr *nl;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nl = rtnl_route_get_dst(route_obj);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (nl) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nladdr_to_string(nl, buf, INET6_ADDRSTRLEN);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek prefixlen = nl_addr_get_prefixlen(nl);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek } else {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek strncpy(buf, "unknown", INET6_ADDRSTRLEN);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek prefixlen = 0;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "route idx %d flags %#X family %d addr %s/%d\n",
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos rtnlw_route_get_oif(route_obj), rtnl_route_get_flags(route_obj),
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov rtnl_route_get_family(route_obj), buf, prefixlen);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek/*
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek * If a bridge interface is configured it sets up a timer to requery for
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek * multicast group memberships periodically. We need to discard such
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek * messages.
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic bool route_is_multicast(struct rtnl_route *route_obj)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct nl_addr *nl;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct in6_addr *addr6 = NULL;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct in_addr *addr4 = NULL;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nl = rtnl_route_get_dst(route_obj);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!nl) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "A route with no destination?\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (nl_addr_get_family(nl) == AF_INET) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek addr4 = nl_addr_get_binary_addr(nl);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!addr4) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
6982b488e03b8e29e186f0c54cf5f80438cceaddJakub Hrozek return IN_MULTICAST(ntohl(addr4->s_addr));
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek } else if (nl_addr_get_family(nl) == AF_INET6) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek addr6 = nl_addr_get_binary_addr(nl);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!addr6) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return IN6_IS_ADDR_MULTICAST(addr6);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Unknown route address family\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void route_msg_handler(struct nl_object *obj, void *arg)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct rtnl_route *route_obj;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!nlw_is_route_object(obj)) return;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek route_obj = (struct rtnl_route *) obj;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (route_is_multicast(route_obj)) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Discarding multicast route message\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (debug_level & SSSDBG_TRACE_LIBS) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek route_msg_debug_print(route_obj);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek ctx->change_cb(ctx->cb_data);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void addr_msg_debug_print(struct rtnl_addr *addr_obj)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek unsigned int flags;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek char str_flags[512];
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek int ifidx;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct nl_addr *local_addr;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek char buf[INET6_ADDRSTRLEN];
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek flags = rtnl_addr_get_flags(addr_obj);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek ifidx = rtnl_addr_get_ifindex(addr_obj);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek local_addr = rtnl_addr_get_local(addr_obj);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek rtnl_addr_flags2str(flags, str_flags, 512);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nladdr_to_string(local_addr, buf, INET6_ADDRSTRLEN);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "netlink addr message: iface idx %u "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "addr %s flags 0x%X (%s)\n", ifidx, buf, flags, str_flags);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void addr_msg_handler(struct nl_object *obj, void *arg)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek{
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher int err;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct rtnl_addr *addr_obj;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher struct nl_addr *local_addr;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher struct sockaddr_in sa4;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher struct sockaddr_in6 sa6;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher socklen_t salen;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!nlw_is_addr_object(obj)) return;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek addr_obj = (struct rtnl_addr *) obj;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (debug_level & SSSDBG_TRACE_LIBS) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek addr_msg_debug_print(addr_obj);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek }
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher local_addr = rtnl_addr_get_local(addr_obj);
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher if (local_addr == NULL) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher "Received RTM_NEWADDR with no address\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher return;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher }
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher switch (nl_addr_get_family(local_addr)) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher case AF_INET6:
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher salen = sizeof(struct sockaddr_in6);
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher err = nl_addr_fill_sockaddr(local_addr,
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher (struct sockaddr *) &sa6,
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher &salen);
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher if (err < 0) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher "Unknown error in nl_addr_fill_sockaddr\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher return;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher }
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher if (!check_ipv6_addr(&sa6.sin6_addr, SSS_NO_SPECIAL)) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_TRACE_LIBS, "Ignoring special address.\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher return;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher }
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher break;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher case AF_INET:
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher salen = sizeof(struct sockaddr_in);
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher err = nl_addr_fill_sockaddr(local_addr,
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher (struct sockaddr *) &sa4,
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher &salen);
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher if (err < 0) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher "Unknown error in nl_addr_fill_sockaddr\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher return;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher }
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher if (check_ipv4_addr(&sa4.sin_addr, SSS_NO_SPECIAL)) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_TRACE_LIBS, "Ignoring special address.\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher return;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher }
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher break;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher default:
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher return;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher }
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek ctx->change_cb(ctx->cb_data);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek}
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic void link_msg_handler(struct nl_object *obj, void *arg)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct rtnl_link *link_obj;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek unsigned int flags;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek char str_flags[512];
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek int ifidx;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek const char *ifname;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (!nlw_is_link_object(obj)) return;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek link_obj = (struct rtnl_link *) obj;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek flags = rtnl_link_get_flags(link_obj);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ifidx = rtnl_link_get_ifindex(link_obj);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek rtnl_link_flags2str(flags, str_flags, 512);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ifname = rtnl_link_get_name(link_obj);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "netlink link message: iface idx %u (%s) "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "flags 0x%X (%s)\n", ifidx, ifname, flags, str_flags);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* IFF_LOWER_UP is the indicator of carrier status */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if ((flags & IFF_RUNNING) && (flags & IFF_LOWER_UP) &&
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek !discard_iff_up(ifname)) {
4745ac57b7fb4ab071ee8f9b3386c5f4941a1561Jakub Hrozek ctx->change_cb(ctx->cb_data);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic void netlink_fd_handler(struct tevent_context *ev, struct tevent_fd *fde,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek uint16_t flags, void *data)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *nlctx = talloc_get_type(data, struct netlink_ctx);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek int ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos if (!nlctx || !nlctx->nlp) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Invalid netlink handle, this is most likely a bug!\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_recvmsgs_default(nlctx->nlp);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error while reading from netlink fd\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/*******************************************************************
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * Set up the netlink library
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek *******************************************************************/
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekint setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek network_change_cb change_cb, void *cb_data,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx **_nlctx)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *nlctx;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek int ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek int nlfd;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek unsigned flags;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek int groups[] = { RTNLGRP_LINK, RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE,
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, 0 };
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx = talloc_zero(mem_ctx, struct netlink_ctx);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (!nlctx) return ENOMEM;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek talloc_set_destructor((TALLOC_CTX *) nlctx, netlink_ctx_destructor);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx->change_cb = change_cb;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx->cb_data = cb_data;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos /* allocate the libnl handle/socket and register the default filter set */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos nlctx->nlp = nlw_alloc();
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos if (!nlctx->nlp) {
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik DEBUG(SSSDBG_CRIT_FAILURE,
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik "unable to allocate netlink handle: %s\n", nlw_geterror(ENOMEM));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = ENOMEM;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek goto fail;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Register our custom message validation filter */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nlw_set_callbacks(nlctx->nlp, nlctx);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set callbacks\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = EIO;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek goto fail;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Try to start talking to netlink */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_connect(nlctx->nlp, NETLINK_ROUTE);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != 0) {
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to connect to netlink: %s\n", nlw_geterror(ret));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = EIO;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek goto fail;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nlw_enable_passcred(nlctx->nlp);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != 0) {
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Cannot enable credential passing: %s\n", nlw_geterror(ret));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = EIO;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek goto fail;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Subscribe to the LINK group for internal carrier signals */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nlw_groups_subscribe(nlctx->nlp, groups);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret != 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to subscribe to netlink monitor\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = EIO;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek goto fail;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos nlw_disable_seq_check(nlctx->nlp);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos nlfd = nl_socket_get_fd(nlctx->nlp);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek flags = fcntl(nlfd, F_GETFL, 0);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek errno = 0;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = fcntl(nlfd, F_SETFL, flags | O_NONBLOCK);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (ret < 0) {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Cannot set the netlink fd to nonblocking\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek goto fail;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx->tefd = tevent_add_fd(ev, nlctx, nlfd, TEVENT_FD_READ,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek netlink_fd_handler, nlctx);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (nlctx->tefd == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd() failed\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = EIO;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek goto fail;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek }
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek *_nlctx = nlctx;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return EOK;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekfail:
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek talloc_free(nlctx);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return ret;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#else /* HAVE_LIBNL not defined */
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekint setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek network_change_cb change_cb, void *cb_data,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx **_nlctx)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek{
fa6c70fabb8dc2fab580a014cdcf1b0dd3e99554Sumit Bose if (_nlctx) *_nlctx = NULL;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return EOK;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek}
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#endif