6 * Copyright (C) 2017 Samsung Electronics Co., Ltd.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 #include <connman/mesh-netlink.h>
29 #include <netlink/genl/genl.h>
30 #include <netlink/genl/family.h>
31 #include <netlink/genl/ctrl.h>
32 #include <netlink/msg.h>
33 #include <netlink/attr.h>
34 #include <netlink/netlink.h>
36 static int seq_check_cb(struct nl_msg *msg, void *arg)
43 static int finish_cb(struct nl_msg *msg, void *arg)
54 static int ack_cb(struct nl_msg *msg, void *arg)
65 static int valid_cb(struct nl_msg *msg, void *arg)
72 static int error_cb(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
78 DBG("error %d", *ret);
83 int __connman_mesh_netlink_set_gate_announce(mesh_nl80211_global *global,
84 int mesh_if_index, bool gate_announce, int hwmp_rootmode)
87 struct nlattr *container;
95 cb = nl_cb_clone(global->cb);
99 genlmsg_put(msg, 0, 0, global->id, 0, 0, NL80211_CMD_SET_MESH_CONFIG, 0);
100 nla_put_u32(msg, NL80211_ATTR_IFINDEX, mesh_if_index);
102 container = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
104 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, hwmp_rootmode);
106 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, gate_announce);
108 nla_nest_end(msg, container);
110 err = nl_send_auto_complete(global->nl_socket, msg);
112 DBG("Failed to send msg");
118 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_cb, &err);
119 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_cb, &err);
120 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_cb, &err);
121 nl_cb_err(cb, NL_CB_CUSTOM, error_cb, &err);
124 int res = nl_recvmsgs(global->nl_socket, cb);
126 DBG("nl_recvmsgs failed: %d", res);
135 mesh_nl80211_global *__connman_mesh_nl80211_global_init(void)
137 mesh_nl80211_global *global;
141 global = g_malloc0(sizeof(mesh_nl80211_global));
143 global->nl_socket = nl_socket_alloc();
144 if (!global->nl_socket) {
145 DBG("Failed to allocate netlink socket");
150 if (genl_connect(global->nl_socket)) {
151 DBG("Failed to connect to generic netlink");
152 nl_socket_free(global->nl_socket);
157 nl_socket_set_buffer_size(global->nl_socket, 8192, 8192);
159 global->id = genl_ctrl_resolve(global->nl_socket, "nl80211");
160 if (global->id < 0) {
161 DBG("nl80211 generic netlink not found");
162 nl_socket_free(global->nl_socket);
167 global->cb = nl_cb_alloc(NL_CB_DEFAULT);
169 DBG("Failed to allocate netwlink callbacks");
170 nl_socket_free(global->nl_socket);
175 nl_cb_set(global->cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, seq_check_cb, NULL);
180 void __connman_mesh_nl80211_global_deinit(mesh_nl80211_global *global)
184 nl_cb_put(global->cb);
185 nl_socket_free(global->nl_socket);