90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek SSSD - Service monitor - netlink support
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek Parts of this code were borrowed from NetworkManager
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek Copyright (C) 2010 Red Hat
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 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 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/* Linux header file confusion causes this to be undefined. */
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek#define SYSFS_IFACE_TEMPLATE "/sys/class/net/%s"
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz/* 9 = strlen(PHY_80211_SUBDIR)+1, 1 = path delimiter */
5d98dce1111f04475e0d14ace9a4bcb876206fa5Jakub Hrozek#define SYSFS_SUBDIR_PATH_MAX (SYSFS_IFACE_PATH_MAX+9+1)
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz/* 5 = strlen(TYPE_FILE)+1, 1 = path delimiter */
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek#define SYSFS_TYPE_PATH_MAX (SYSFS_IFACE_PATH_MAX+5+1)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos/* Wrappers determining use of libnl version 1 or 3 */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_disable_seq_check nl_socket_disable_seq_check
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#define nlw_disable_seq_check nl_disable_sequence_check
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#endif /* HAVE_LIBNL3 */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos#endif /* HAVE_LIBNL */
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx = talloc_get_type(ptr, struct netlink_ctx);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek/*******************************************************************
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek * Utility functions
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek *******************************************************************/
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos/* rtnl_route_get_oif removed from libnl3 */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozekstatic bool has_wireless_extension(const char *ifname)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if (s == -1) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Could not open socket: [%d] %s\n", ret, strerror(ret));
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
39ed7bb0c0e1d4c431033b77cdeb176cfeae26e9Jakub Hrozek strncpy(iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ-1);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* Does the interface support a wireless extension? */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return ret == 0;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozekstatic bool has_ethernet_encapsulation(const char *sysfs_path)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n");
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n");
a4421a4261f73718e6b4c18c7bb9f020255e15c7Jakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Could not open sysfs file %s: [%d] %s\n",
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "read failed [%d][%s].\n", ret, strerror(ret));
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozekstatic bool has_phy_80211_subdir(const char *sysfs_path)
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = snprintf(phy80211_path, SYSFS_SUBDIR_PATH_MAX,
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "No %s directory in sysfs, probably "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "not a wireless interface\n", PHY_80211_SUBDIR);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "stat failed: [%d] %s\n",
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "Directory %s found in sysfs, looks like "
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* This catches most of the new 80211 drivers */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%s has a wireless extension\n", ifname);
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek ret = snprintf(path, SYSFS_IFACE_PATH_MAX, SYSFS_IFACE_TEMPLATE, ifname);
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n");
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* This will filter PPP and such. Both wired and wireless
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek * interfaces have the encapsulation. */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%s does not have ethernet encapsulation, "
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek /* This captures old WEXT drivers, the new mac8011 would
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek * be caught by the ioctl check */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "%s has a 802_11 subdir, filtering out\n",
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return true;
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void nladdr_to_string(struct nl_addr *nl, char *buf, size_t bufsize)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (addr_family != AF_INET && addr_family != AF_INET6) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (!addr) return;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek if (inet_ntop(addr_family, addr, buf, bufsize) == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop failed\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/*******************************************************************
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * Wrappers for different capabilities of different libnl versions
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek *******************************************************************/
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic bool nlw_accept_message(struct nlw_handle *nlp,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Malformed message, skipping\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek return false;
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Accept any messages from the kernel */
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* And any multicast message directed to our netlink PID, since multicast
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * currently requires CAP_ADMIN to use.
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if ((hdr->nlmsg_pid == local_port) && snl->nl_groups) {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek if (accept_msg == false) {
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik "ignoring netlink message from PID %d\n", hdr->nlmsg_pid);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic bool nlw_is_addr_object(struct nl_object *obj)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error!\n");
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 Hrozekstatic bool nlw_is_route_object(struct nl_object *obj)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error!\n");
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");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic bool nlw_is_link_object(struct nl_object *obj)
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Allocation error!\n");
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");
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_enable_passcred(struct nlw_handle *nlp)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos return nl_set_passcred(nlp, 1); /* 1 = enabled */
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_group_subscribe(struct nlw_handle *nlp, int group)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to add membership: %s\n", nlw_geterror(ret));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = setsockopt(nlfd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "setsockopt failed (%d): %s\n", ret, strerror(ret));
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_groups_subscribe(struct nlw_handle *nlp, int *groups)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek for (i=0; groups[i]; i++) {
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/*******************************************************************
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * Callbacks for validating and receiving messages
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek *******************************************************************/
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic int event_msg_recv(struct nl_msg *msg, void *arg)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik "Ignoring netlink message from UID %"SPRIuid"\n",
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 Hrozekstatic enum nlw_msg_type message_type(struct nlmsghdr *hdr)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_FUNC_DATA, "netlink Message type: %d\n", hdr->nlmsg_type);
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* network interface added */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* routing table changed */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* IP address added or deleted */
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek /* Something else happened, but we don't care (typically RTM_GET* ) */
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic int event_msg_ready(struct nl_msg *msg, void *arg)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kosstatic int nlw_set_callbacks(struct nlw_handle *nlp, void *data)
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_socket_modify_cb(nlp, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv,
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, data);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set validation callback\n");
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_socket_modify_cb(nlp, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready,
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos ret = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready, data);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set receive callback\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void route_msg_debug_print(struct rtnl_route *route_obj)
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);
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 Hrozekstatic bool route_is_multicast(struct rtnl_route *route_obj)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "A route with no destination?\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek } else if (nl_addr_get_family(nl) == AF_INET6) {
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Unknown route address family\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek return false;
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void route_msg_handler(struct nl_object *obj, void *arg)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Discarding multicast route message\n");
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozekstatic void addr_msg_debug_print(struct rtnl_addr *addr_obj)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek nladdr_to_string(local_addr, buf, INET6_ADDRSTRLEN);
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 Hrozekstatic void addr_msg_handler(struct nl_object *obj, void *arg)
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher local_addr = rtnl_addr_get_local(addr_obj);
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher "Received RTM_NEWADDR with no address\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher "Unknown error in nl_addr_fill_sockaddr\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher if (!check_ipv6_addr(&sa6.sin6_addr, SSS_NO_SPECIAL)) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_TRACE_LIBS, "Ignoring special address.\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher "Unknown error in nl_addr_fill_sockaddr\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher if (check_ipv4_addr(&sa4.sin_addr, SSS_NO_SPECIAL)) {
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_TRACE_LIBS, "Ignoring special address.\n");
a9d1b4b61b614a954c784f224b8fe7a47b6dd206Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic void link_msg_handler(struct nl_object *obj, void *arg)
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *ctx = (struct netlink_ctx *) arg;
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 /* IFF_LOWER_UP is the indicator of carrier status */
172bf27813151351a1ff8284a3d524660eca2efeJakub Hrozek if ((flags & IFF_RUNNING) && (flags & IFF_LOWER_UP) &&
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekstatic void netlink_fd_handler(struct tevent_context *ev, struct tevent_fd *fde,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek struct netlink_ctx *nlctx = talloc_get_type(data, struct netlink_ctx);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Invalid netlink handle, this is most likely a bug!\n");
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Error while reading from netlink fd\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek/*******************************************************************
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek * Set up the netlink library
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek *******************************************************************/
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozekint setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
4e3495b3b8927a282adc48cc80f0611ecf79821bJakub Hrozek int groups[] = { RTNLGRP_LINK, RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE,
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx = talloc_zero(mem_ctx, struct netlink_ctx);
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek talloc_set_destructor((TALLOC_CTX *) nlctx, netlink_ctx_destructor);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos /* allocate the libnl handle/socket and register the default filter set */
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik "unable to allocate netlink handle: %s\n", nlw_geterror(ENOMEM));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Register our custom message validation filter */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set callbacks\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Try to start talking to netlink */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to connect to netlink: %s\n", nlw_geterror(ret));
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Cannot enable credential passing: %s\n", nlw_geterror(ret));
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek /* Subscribe to the LINK group for internal carrier signals */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to subscribe to netlink monitor\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek ret = fcntl(nlfd, F_SETFL, flags | O_NONBLOCK);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Cannot set the netlink fd to nonblocking\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek nlctx->tefd = tevent_add_fd(ev, nlctx, nlfd, TEVENT_FD_READ,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd() failed\n");
90acbcf20b5f896ca8f631923afe946c90d90de7Jakub Hrozek#else /* HAVE_LIBNL not defined */