18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Netlink helper functions for driver wrappers 3fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "priv_netlink.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "netlink.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct netlink_data { 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct netlink_config *cfg; 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int sock; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void netlink_receive_link(struct netlink_data *netlink, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*cb)(void *ctx, struct ifinfomsg *ifi, 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len), 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct nlmsghdr *h) 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cb == NULL || NLMSG_PAYLOAD(h, 0) < sizeof(struct ifinfomsg)) 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb(netlink->cfg->ctx, NLMSG_DATA(h), 311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) NLMSG_DATA(h) + NLMSG_ALIGN(sizeof(struct ifinfomsg)), 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NLMSG_PAYLOAD(h, sizeof(struct ifinfomsg))); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void netlink_receive(int sock, void *eloop_ctx, void *sock_ctx) 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct netlink_data *netlink = eloop_ctx; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[8192]; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int left; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_nl from; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct nlmsghdr *h; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int max_events = 10; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttry_again: 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen = sizeof(from); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) &from, &fromlen); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 0) { 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (errno != EINTR && errno != EAGAIN) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "netlink: recvfrom failed: %s", 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(errno)); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h = (struct nlmsghdr *) buf; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (NLMSG_OK(h, left)) { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (h->nlmsg_type) { 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RTM_NEWLINK: 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt netlink_receive_link(netlink, netlink->cfg->newlink_cb, 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RTM_DELLINK: 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt netlink_receive_link(netlink, netlink->cfg->dellink_cb, 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h = NLMSG_NEXT(h, left); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left > 0) { 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "netlink: %d extra bytes in the end of " 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "netlink message", left); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (--max_events > 0) { 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Try to receive all events in one eloop call in order to 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * limit race condition on cases where AssocInfo event, Assoc 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * event, and EAPOL frames are received more or less at the 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * same time. We want to process the event messages first 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * before starting EAPOL processing. 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto try_again; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct netlink_data * netlink_init(struct netlink_config *cfg) 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct netlink_data *netlink; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_nl local; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt netlink = os_zalloc(sizeof(*netlink)); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (netlink == NULL) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (netlink->sock < 0) { 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "netlink: Failed to open netlink " 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "socket: %s", strerror(errno)); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt netlink_deinit(netlink); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&local, 0, sizeof(local)); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt local.nl_family = AF_NETLINK; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt local.nl_groups = RTMGRP_LINK; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(netlink->sock, (struct sockaddr *) &local, sizeof(local)) < 0) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "netlink: Failed to bind netlink " 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "socket: %s", strerror(errno)); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt netlink_deinit(netlink); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(netlink->sock, netlink_receive, netlink, 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 122d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt netlink->cfg = cfg; 123d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return netlink; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid netlink_deinit(struct netlink_data *netlink) 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (netlink == NULL) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (netlink->sock >= 0) { 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(netlink->sock); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(netlink->sock); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(netlink->cfg); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(netlink); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 140fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 141fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic const char * linkmode_str(int mode) 142fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 143fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt switch (mode) { 144fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case -1: 145fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "no change"; 146fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case 0: 147fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "kernel-control"; 148fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case 1: 149fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "userspace-control"; 150fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 151fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "?"; 152fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 153fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 154fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 155fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic const char * operstate_str(int state) 156fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 157fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt switch (state) { 158fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case -1: 159fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "no change"; 160fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case IF_OPER_DORMANT: 161fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "IF_OPER_DORMANT"; 162fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case IF_OPER_UP: 163fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "IF_OPER_UP"; 164fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 165fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "?"; 166fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 167fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 168fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint netlink_send_oper_ifla(struct netlink_data *netlink, int ifindex, 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int linkmode, int operstate) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct nlmsghdr hdr; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ifinfomsg ifinfo; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char opts[16]; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } req; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rtattr *rta; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int nl_seq; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssize_t ret; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&req, 0, sizeof(req)); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hdr.nlmsg_type = RTM_SETLINK; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hdr.nlmsg_flags = NLM_F_REQUEST; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hdr.nlmsg_seq = ++nl_seq; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hdr.nlmsg_pid = 0; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.ifinfo.ifi_family = AF_UNSPEC; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.ifinfo.ifi_type = 0; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.ifinfo.ifi_index = ifindex; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.ifinfo.ifi_flags = 0; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.ifinfo.ifi_change = 0; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (linkmode != -1) { 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rta = aliasing_hide_typecast( 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rtattr); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rta->rta_type = IFLA_LINKMODE; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rta->rta_len = RTA_LENGTH(sizeof(char)); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *((char *) RTA_DATA(rta)) = linkmode; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RTA_LENGTH(sizeof(char)); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (operstate != -1) { 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rta = aliasing_hide_typecast( 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rtattr); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rta->rta_type = IFLA_OPERSTATE; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rta->rta_len = RTA_LENGTH(sizeof(char)); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *((char *) RTA_DATA(rta)) = operstate; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RTA_LENGTH(sizeof(char)); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 216fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "netlink: Operstate: ifindex=%d linkmode=%d (%s), operstate=%d (%s)", 217fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ifindex, linkmode, linkmode_str(linkmode), 218fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt operstate, operstate_str(operstate)); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = send(netlink->sock, &req, req.hdr.nlmsg_len, 0); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "netlink: Sending operstate IFLA " 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %s (assume operstate is not supported)", 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(errno)); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret < 0 ? -1 : 0; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 229