]> git.proxmox.com Git - mirror_iproute2.git/blob - tipc/node.c
Merge branch 'master' into net-next
[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 uint32_t addr;
30 struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
31 struct nlattr *info[TIPC_NLA_MAX + 1] = {};
32 struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1] = {};
33
34 mnl_attr_parse(nlh, sizeof(*genl), 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 printf("<%u.%u.%u>: ",
44 tipc_zone(addr),
45 tipc_cluster(addr),
46 tipc_node(addr));
47
48 if (attrs[TIPC_NLA_NODE_UP])
49 printf("up\n");
50 else
51 printf("down\n");
52
53 return MNL_CB_OK;
54 }
55
56 static int cmd_node_list(struct nlmsghdr *nlh, const struct cmd *cmd,
57 struct cmdl *cmdl, void *data)
58 {
59 char buf[MNL_SOCKET_BUFFER_SIZE];
60
61 if (help_flag) {
62 fprintf(stderr, "Usage: %s node list\n", cmdl->argv[0]);
63 return -EINVAL;
64 }
65
66 if (!(nlh = msg_init(buf, TIPC_NL_NODE_GET))) {
67 fprintf(stderr, "error, message initialisation failed\n");
68 return -1;
69 }
70
71 return msg_dumpit(nlh, node_list_cb, NULL);
72 }
73
74 static int cmd_node_set_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
75 struct cmdl *cmdl, void *data)
76 {
77 char *str;
78 uint32_t addr;
79 struct nlattr *nest;
80 char buf[MNL_SOCKET_BUFFER_SIZE];
81
82 if (cmdl->argc != cmdl->optind + 1) {
83 fprintf(stderr, "Usage: %s node set address ADDRESS\n",
84 cmdl->argv[0]);
85 return -EINVAL;
86 }
87
88 str = shift_cmdl(cmdl);
89 addr = str2addr(str);
90 if (!addr)
91 return -1;
92
93 if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) {
94 fprintf(stderr, "error, message initialisation failed\n");
95 return -1;
96 }
97
98 nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
99 mnl_attr_put_u32(nlh, TIPC_NLA_NET_ADDR, addr);
100 mnl_attr_nest_end(nlh, nest);
101
102 return msg_doit(nlh, NULL, NULL);
103 }
104
105 static int cmd_node_get_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
106 struct cmdl *cmdl, void *data)
107 {
108 int sk;
109 socklen_t sz = sizeof(struct sockaddr_tipc);
110 struct sockaddr_tipc addr;
111
112 sk = socket(AF_TIPC, SOCK_RDM, 0);
113 if (sk < 0) {
114 fprintf(stderr, "opening TIPC socket: %s\n", strerror(errno));
115 return -1;
116 }
117
118 if (getsockname(sk, (struct sockaddr *)&addr, &sz) < 0) {
119 fprintf(stderr, "getting TIPC socket address: %s\n",
120 strerror(errno));
121 close(sk);
122 return -1;
123 }
124 close(sk);
125
126 printf("<%u.%u.%u>\n",
127 tipc_zone(addr.addr.id.node),
128 tipc_cluster(addr.addr.id.node),
129 tipc_node(addr.addr.id.node));
130
131 return 0;
132 }
133
134 static int netid_get_cb(const struct nlmsghdr *nlh, void *data)
135 {
136 struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
137 struct nlattr *info[TIPC_NLA_MAX + 1] = {};
138 struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
139
140 mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
141 if (!info[TIPC_NLA_NET])
142 return MNL_CB_ERROR;
143
144 mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs);
145 if (!attrs[TIPC_NLA_NET_ID])
146 return MNL_CB_ERROR;
147
148 printf("%u\n", mnl_attr_get_u32(attrs[TIPC_NLA_NET_ID]));
149
150 return MNL_CB_OK;
151 }
152
153 static int cmd_node_get_netid(struct nlmsghdr *nlh, const struct cmd *cmd,
154 struct cmdl *cmdl, void *data)
155 {
156 char buf[MNL_SOCKET_BUFFER_SIZE];
157
158 if (help_flag) {
159 (cmd->help)(cmdl);
160 return -EINVAL;
161 }
162
163 if (!(nlh = msg_init(buf, TIPC_NL_NET_GET))) {
164 fprintf(stderr, "error, message initialisation failed\n");
165 return -1;
166 }
167
168 return msg_dumpit(nlh, netid_get_cb, NULL);
169 }
170
171 static int cmd_node_set_netid(struct nlmsghdr *nlh, const struct cmd *cmd,
172 struct cmdl *cmdl, void *data)
173 {
174 int netid;
175 char buf[MNL_SOCKET_BUFFER_SIZE];
176 struct nlattr *nest;
177
178 if (help_flag) {
179 (cmd->help)(cmdl);
180 return -EINVAL;
181 }
182
183 if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) {
184 fprintf(stderr, "error, message initialisation failed\n");
185 return -1;
186 }
187
188 if (cmdl->argc != cmdl->optind + 1) {
189 fprintf(stderr, "Usage: %s node set netid NETID\n",
190 cmdl->argv[0]);
191 return -EINVAL;
192 }
193 netid = atoi(shift_cmdl(cmdl));
194
195 nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
196 mnl_attr_put_u32(nlh, TIPC_NLA_NET_ID, netid);
197 mnl_attr_nest_end(nlh, nest);
198
199 return msg_doit(nlh, NULL, NULL);
200 }
201
202 static void cmd_node_set_help(struct cmdl *cmdl)
203 {
204 fprintf(stderr,
205 "Usage: %s node set PROPERTY\n\n"
206 "PROPERTIES\n"
207 " address ADDRESS - Set local address\n"
208 " netid NETID - Set local netid\n",
209 cmdl->argv[0]);
210 }
211
212 static int cmd_node_set(struct nlmsghdr *nlh, const struct cmd *cmd,
213 struct cmdl *cmdl, void *data)
214 {
215 const struct cmd cmds[] = {
216 { "address", cmd_node_set_addr, NULL },
217 { "netid", cmd_node_set_netid, NULL },
218 { NULL }
219 };
220
221 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
222 }
223
224 static void cmd_node_get_help(struct cmdl *cmdl)
225 {
226 fprintf(stderr,
227 "Usage: %s node get PROPERTY\n\n"
228 "PROPERTIES\n"
229 " address - Get local address\n"
230 " netid - Get local netid\n",
231 cmdl->argv[0]);
232 }
233
234 static int cmd_node_get(struct nlmsghdr *nlh, const struct cmd *cmd,
235 struct cmdl *cmdl, void *data)
236 {
237 const struct cmd cmds[] = {
238 { "address", cmd_node_get_addr, NULL },
239 { "netid", cmd_node_get_netid, NULL },
240 { NULL }
241 };
242
243 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
244 }
245
246 void cmd_node_help(struct cmdl *cmdl)
247 {
248 fprintf(stderr,
249 "Usage: %s node COMMAND [ARGS] ...\n\n"
250 "COMMANDS\n"
251 " list - List remote nodes\n"
252 " get - Get local node parameters\n"
253 " set - Set local node parameters\n",
254 cmdl->argv[0]);
255 }
256
257 int cmd_node(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
258 void *data)
259 {
260 const struct cmd cmds[] = {
261 { "list", cmd_node_list, NULL },
262 { "get", cmd_node_get, cmd_node_get_help },
263 { "set", cmd_node_set, cmd_node_set_help },
264 { NULL }
265 };
266
267 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
268 }