80 lines
2.1 KiB
C
80 lines
2.1 KiB
C
|
/*
|
||
|
* Netlink helper functions for driver wrappers
|
||
|
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License version 2 as
|
||
|
* published by the Free Software Foundation.
|
||
|
*
|
||
|
* Alternatively, this software may be distributed under the terms of BSD
|
||
|
* license.
|
||
|
*
|
||
|
* See README and COPYING for more details.
|
||
|
*/
|
||
|
|
||
|
#include "includes.h"
|
||
|
|
||
|
#include "common.h"
|
||
|
#include "priv_netlink.h"
|
||
|
#include "netlink.h"
|
||
|
|
||
|
|
||
|
int netlink_send_oper_ifla(int sock, int ifindex, int linkmode, int operstate)
|
||
|
{
|
||
|
struct {
|
||
|
struct nlmsghdr hdr;
|
||
|
struct ifinfomsg ifinfo;
|
||
|
char opts[16];
|
||
|
} req;
|
||
|
struct rtattr *rta;
|
||
|
static int nl_seq;
|
||
|
ssize_t ret;
|
||
|
|
||
|
os_memset(&req, 0, sizeof(req));
|
||
|
|
||
|
req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||
|
req.hdr.nlmsg_type = RTM_SETLINK;
|
||
|
req.hdr.nlmsg_flags = NLM_F_REQUEST;
|
||
|
req.hdr.nlmsg_seq = ++nl_seq;
|
||
|
req.hdr.nlmsg_pid = 0;
|
||
|
|
||
|
req.ifinfo.ifi_family = AF_UNSPEC;
|
||
|
req.ifinfo.ifi_type = 0;
|
||
|
req.ifinfo.ifi_index = ifindex;
|
||
|
req.ifinfo.ifi_flags = 0;
|
||
|
req.ifinfo.ifi_change = 0;
|
||
|
|
||
|
if (linkmode != -1) {
|
||
|
rta = aliasing_hide_typecast(
|
||
|
((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
|
||
|
struct rtattr);
|
||
|
rta->rta_type = IFLA_LINKMODE;
|
||
|
rta->rta_len = RTA_LENGTH(sizeof(char));
|
||
|
*((char *) RTA_DATA(rta)) = linkmode;
|
||
|
req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
|
||
|
RTA_LENGTH(sizeof(char));
|
||
|
}
|
||
|
if (operstate != -1) {
|
||
|
rta = aliasing_hide_typecast(
|
||
|
((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
|
||
|
struct rtattr);
|
||
|
rta->rta_type = IFLA_OPERSTATE;
|
||
|
rta->rta_len = RTA_LENGTH(sizeof(char));
|
||
|
*((char *) RTA_DATA(rta)) = operstate;
|
||
|
req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
|
||
|
RTA_LENGTH(sizeof(char));
|
||
|
}
|
||
|
|
||
|
wpa_printf(MSG_DEBUG, "netlink: Operstate: linkmode=%d, operstate=%d",
|
||
|
linkmode, operstate);
|
||
|
|
||
|
ret = send(sock, &req, req.hdr.nlmsg_len, 0);
|
||
|
if (ret < 0) {
|
||
|
wpa_printf(MSG_DEBUG, "netlink: Sending operstate IFLA "
|
||
|
"failed: %s (assume operstate is not supported)",
|
||
|
strerror(errno));
|
||
|
}
|
||
|
|
||
|
return ret < 0 ? -1 : 0;
|
||
|
}
|