]> git.proxmox.com Git - mirror_iproute2.git/blob - tipc/node.c
ll_map: Add function to remove link cache entry by index
[mirror_iproute2.git] / tipc / node.c
1 /*
2 * node.c TIPC node functionality.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Richard Alpe <richard.alpe@ericsson.com>
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
16
17 #include <linux/tipc_netlink.h>
18 #include <linux/tipc.h>
19 #include <linux/genetlink.h>
20 #include <libmnl/libmnl.h>
21
22 #include "cmdl.h"
23 #include "msg.h"
24 #include "misc.h"
25 #include "node.h"
26
27 static int node_list_cb(const struct nlmsghdr *nlh, void *data)
28 {
29 struct nlattr *info[TIPC_NLA_MAX + 1] = {};
30 struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1] = {};
31 char str[33] = {};
32 uint32_t addr;
33
34 mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_attrs, info);
35 if (!info[TIPC_NLA_NODE])
36 return MNL_CB_ERROR;
37
38 mnl_attr_parse_nested(info[TIPC_NLA_NODE], parse_attrs, attrs);
39 if (!attrs[TIPC_NLA_NODE_ADDR])
40 return MNL_CB_ERROR;
41
42 addr = mnl_attr_get_u32(attrs[TIPC_NLA_NODE_ADDR]);
43 hash2nodestr(addr, str);
44 printf("%-32s %08x ", str, addr);
45 if (attrs[TIPC_NLA_NODE_UP])
46 printf("up\n");
47 else
48 printf("down\n");
49 return MNL_CB_OK;
50 }
51
52 static int cmd_node_list(struct nlmsghdr *nlh, const struct cmd *cmd,
53 struct cmdl *cmdl, void *data)
54 {
55 char buf[MNL_SOCKET_BUFFER_SIZE];
56
57 if (help_flag) {
58 fprintf(stderr, "Usage: %s node list\n", cmdl->argv[0]);
59 return -EINVAL;
60 }
61
62 if (!(nlh = msg_init(buf, TIPC_NL_NODE_GET))) {
63 fprintf(stderr, "error, message initialisation failed\n");
64 return -1;
65 }
66 printf("Node Identity Hash State\n");
67 return msg_dumpit(nlh, node_list_cb, NULL);
68 }
69
70 static int cmd_node_set_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
71 struct cmdl *cmdl, void *data)
72 {
73 char *str;
74 uint32_t addr;
75 struct nlattr *nest;
76 char buf[MNL_SOCKET_BUFFER_SIZE];
77
78 if (cmdl->argc != cmdl->optind + 1) {
79 fprintf(stderr, "Usage: %s node set address ADDRESS\n",
80 cmdl->argv[0]);
81 return -EINVAL;
82 }
83
84 str = shift_cmdl(cmdl);
85 addr = str2addr(str);
86 if (!addr)
87 return -1;
88
89 if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) {
90 fprintf(stderr, "error, message initialisation failed\n");
91 return -1;
92 }
93
94 nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
95 mnl_attr_put_u32(nlh, TIPC_NLA_NET_ADDR, addr);
96 mnl_attr_nest_end(nlh, nest);
97
98 return msg_doit(nlh, NULL, NULL);
99 }
100
101 static int cmd_node_get_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
102 struct cmdl *cmdl, void *data)
103 {
104 int sk;
105 socklen_t sz = sizeof(struct sockaddr_tipc);
106 struct sockaddr_tipc addr;
107
108 sk = socket(AF_TIPC, SOCK_RDM, 0);
109 if (sk < 0) {
110 fprintf(stderr, "opening TIPC socket: %s\n", strerror(errno));
111 return -1;
112 }
113
114 if (getsockname(sk, (struct sockaddr *)&addr, &sz) < 0) {
115 fprintf(stderr, "getting TIPC socket address: %s\n",
116 strerror(errno));
117 close(sk);
118 return -1;
119 }
120 close(sk);
121
122 printf("%08x\n", addr.addr.id.node);
123 return 0;
124 }
125
126 static int cmd_node_set_nodeid(struct nlmsghdr *nlh, const struct cmd *cmd,
127 struct cmdl *cmdl, void *data)
128 {
129 char buf[MNL_SOCKET_BUFFER_SIZE];
130 uint8_t id[16] = {0,};
131 uint64_t *w0 = (uint64_t *) &id[0];
132 uint64_t *w1 = (uint64_t *) &id[8];
133 struct nlattr *nest;
134 char *str;
135
136 if (cmdl->argc != cmdl->optind + 1) {
137 fprintf(stderr, "Usage: %s node set nodeid NODE_ID\n",
138 cmdl->argv[0]);
139 return -EINVAL;
140 }
141
142 str = shift_cmdl(cmdl);
143 if (str2nodeid(str, id)) {
144 fprintf(stderr, "Invalid node identity\n");
145 return -EINVAL;
146 }
147
148 nlh = msg_init(buf, TIPC_NL_NET_SET);
149 if (!nlh) {
150 fprintf(stderr, "error, message initialisation failed\n");
151 return -1;
152 }
153 nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
154 mnl_attr_put_u64(nlh, TIPC_NLA_NET_NODEID, *w0);
155 mnl_attr_put_u64(nlh, TIPC_NLA_NET_NODEID_W1, *w1);
156 mnl_attr_nest_end(nlh, nest);
157 return msg_doit(nlh, NULL, NULL);
158 }
159
160 static int nodeid_get_cb(const struct nlmsghdr *nlh, void *data)
161 {
162 struct nlattr *info[TIPC_NLA_MAX + 1] = {};
163 struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
164 char str[33] = {0,};
165 uint8_t id[16] = {0,};
166 uint64_t *w0 = (uint64_t *) &id[0];
167 uint64_t *w1 = (uint64_t *) &id[8];
168
169 mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_attrs, info);
170 if (!info[TIPC_NLA_NET])
171 return MNL_CB_ERROR;
172
173 mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs);
174 if (!attrs[TIPC_NLA_NET_ID])
175 return MNL_CB_ERROR;
176
177 *w0 = mnl_attr_get_u64(attrs[TIPC_NLA_NET_NODEID]);
178 *w1 = mnl_attr_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]);
179 nodeid2str(id, str);
180 printf("Node Identity Hash\n");
181 printf("%-33s", str);
182 cmd_node_get_addr(NULL, NULL, NULL, NULL);
183 return MNL_CB_OK;
184 }
185
186 static int cmd_node_get_nodeid(struct nlmsghdr *nlh, const struct cmd *cmd,
187 struct cmdl *cmdl, void *data)
188 {
189 char buf[MNL_SOCKET_BUFFER_SIZE];
190
191 if (help_flag) {
192 (cmd->help)(cmdl);
193 return -EINVAL;
194 }
195
196 nlh = msg_init(buf, TIPC_NL_NET_GET);
197 if (!nlh) {
198 fprintf(stderr, "error, message initialisation failed\n");
199 return -1;
200 }
201
202 return msg_dumpit(nlh, nodeid_get_cb, NULL);
203 }
204
205
206 static int netid_get_cb(const struct nlmsghdr *nlh, void *data)
207 {
208 struct nlattr *info[TIPC_NLA_MAX + 1] = {};
209 struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
210
211 mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_attrs, info);
212 if (!info[TIPC_NLA_NET])
213 return MNL_CB_ERROR;
214
215 mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs);
216 if (!attrs[TIPC_NLA_NET_ID])
217 return MNL_CB_ERROR;
218
219 printf("%u\n", mnl_attr_get_u32(attrs[TIPC_NLA_NET_ID]));
220
221 return MNL_CB_OK;
222 }
223
224 static int cmd_node_get_netid(struct nlmsghdr *nlh, const struct cmd *cmd,
225 struct cmdl *cmdl, void *data)
226 {
227 char buf[MNL_SOCKET_BUFFER_SIZE];
228
229 if (help_flag) {
230 (cmd->help)(cmdl);
231 return -EINVAL;
232 }
233
234 if (!(nlh = msg_init(buf, TIPC_NL_NET_GET))) {
235 fprintf(stderr, "error, message initialisation failed\n");
236 return -1;
237 }
238
239 return msg_dumpit(nlh, netid_get_cb, NULL);
240 }
241
242 static int cmd_node_set_netid(struct nlmsghdr *nlh, const struct cmd *cmd,
243 struct cmdl *cmdl, void *data)
244 {
245 int netid;
246 char buf[MNL_SOCKET_BUFFER_SIZE];
247 struct nlattr *nest;
248
249 if (help_flag) {
250 (cmd->help)(cmdl);
251 return -EINVAL;
252 }
253
254 if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) {
255 fprintf(stderr, "error, message initialisation failed\n");
256 return -1;
257 }
258
259 if (cmdl->argc != cmdl->optind + 1) {
260 fprintf(stderr, "Usage: %s node set netid NETID\n",
261 cmdl->argv[0]);
262 return -EINVAL;
263 }
264 netid = atoi(shift_cmdl(cmdl));
265
266 nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
267 mnl_attr_put_u32(nlh, TIPC_NLA_NET_ID, netid);
268 mnl_attr_nest_end(nlh, nest);
269
270 return msg_doit(nlh, NULL, NULL);
271 }
272
273 static void cmd_node_set_help(struct cmdl *cmdl)
274 {
275 fprintf(stderr,
276 "Usage: %s node set PROPERTY\n\n"
277 "PROPERTIES\n"
278 " identity NODEID - Set node identity\n"
279 " clusterid CLUSTERID - Set local cluster id\n",
280 cmdl->argv[0]);
281 }
282
283 static int cmd_node_set(struct nlmsghdr *nlh, const struct cmd *cmd,
284 struct cmdl *cmdl, void *data)
285 {
286 const struct cmd cmds[] = {
287 { "address", cmd_node_set_addr, NULL },
288 { "identity", cmd_node_set_nodeid, NULL },
289 { "netid", cmd_node_set_netid, NULL },
290 { "clusterid", cmd_node_set_netid, NULL },
291 { NULL }
292 };
293
294 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
295 }
296
297 static void cmd_node_get_help(struct cmdl *cmdl)
298 {
299 fprintf(stderr,
300 "Usage: %s node get PROPERTY\n\n"
301 "PROPERTIES\n"
302 " identity - Get node identity\n"
303 " clusterid - Get local clusterid\n",
304 cmdl->argv[0]);
305 }
306
307 static int cmd_node_get(struct nlmsghdr *nlh, const struct cmd *cmd,
308 struct cmdl *cmdl, void *data)
309 {
310 const struct cmd cmds[] = {
311 { "address", cmd_node_get_addr, NULL },
312 { "identity", cmd_node_get_nodeid, NULL },
313 { "netid", cmd_node_get_netid, NULL },
314 { "clusterid", cmd_node_get_netid, NULL },
315 { NULL }
316 };
317
318 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
319 }
320
321 void cmd_node_help(struct cmdl *cmdl)
322 {
323 fprintf(stderr,
324 "Usage: %s node COMMAND [ARGS] ...\n\n"
325 "COMMANDS\n"
326 " list - List remote nodes\n"
327 " get - Get local node parameters\n"
328 " set - Set local node parameters\n",
329 cmdl->argv[0]);
330 }
331
332 int cmd_node(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
333 void *data)
334 {
335 const struct cmd cmds[] = {
336 { "list", cmd_node_list, NULL },
337 { "get", cmd_node_get, cmd_node_get_help },
338 { "set", cmd_node_set, cmd_node_set_help },
339 { NULL }
340 };
341
342 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
343 }