]>
git.proxmox.com Git - mirror_iproute2.git/blob - tipc/node.c
2 * node.c TIPC node functionality.
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.
9 * Authors: Richard Alpe <richard.alpe@ericsson.com>
17 #include <linux/tipc_netlink.h>
18 #include <linux/tipc.h>
19 #include <linux/genetlink.h>
20 #include <libmnl/libmnl.h>
27 static int node_list_cb(const struct nlmsghdr
*nlh
, void *data
)
29 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
30 struct nlattr
*attrs
[TIPC_NLA_NODE_MAX
+ 1] = {};
34 mnl_attr_parse(nlh
, sizeof(struct genlmsghdr
), parse_attrs
, info
);
35 if (!info
[TIPC_NLA_NODE
])
38 mnl_attr_parse_nested(info
[TIPC_NLA_NODE
], parse_attrs
, attrs
);
39 if (!attrs
[TIPC_NLA_NODE_ADDR
])
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
])
52 static int cmd_node_list(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
53 struct cmdl
*cmdl
, void *data
)
55 char buf
[MNL_SOCKET_BUFFER_SIZE
];
58 fprintf(stderr
, "Usage: %s node list\n", cmdl
->argv
[0]);
62 if (!(nlh
= msg_init(buf
, TIPC_NL_NODE_GET
))) {
63 fprintf(stderr
, "error, message initialisation failed\n");
66 printf("Node Identity Hash State\n");
67 return msg_dumpit(nlh
, node_list_cb
, NULL
);
70 static int cmd_node_set_addr(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
71 struct cmdl
*cmdl
, void *data
)
76 char buf
[MNL_SOCKET_BUFFER_SIZE
];
78 if (cmdl
->argc
!= cmdl
->optind
+ 1) {
79 fprintf(stderr
, "Usage: %s node set address ADDRESS\n",
84 str
= shift_cmdl(cmdl
);
89 if (!(nlh
= msg_init(buf
, TIPC_NL_NET_SET
))) {
90 fprintf(stderr
, "error, message initialisation failed\n");
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
);
98 return msg_doit(nlh
, NULL
, NULL
);
101 static int cmd_node_get_addr(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
102 struct cmdl
*cmdl
, void *data
)
105 socklen_t sz
= sizeof(struct sockaddr_tipc
);
106 struct sockaddr_tipc addr
;
108 sk
= socket(AF_TIPC
, SOCK_RDM
, 0);
110 fprintf(stderr
, "opening TIPC socket: %s\n", strerror(errno
));
114 if (getsockname(sk
, (struct sockaddr
*)&addr
, &sz
) < 0) {
115 fprintf(stderr
, "getting TIPC socket address: %s\n",
122 printf("%08x\n", addr
.addr
.id
.node
);
126 static int cmd_node_set_nodeid(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
127 struct cmdl
*cmdl
, void *data
)
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];
136 if (cmdl
->argc
!= cmdl
->optind
+ 1) {
137 fprintf(stderr
, "Usage: %s node set nodeid NODE_ID\n",
142 str
= shift_cmdl(cmdl
);
143 if (str2nodeid(str
, id
)) {
144 fprintf(stderr
, "Invalid node identity\n");
148 nlh
= msg_init(buf
, TIPC_NL_NET_SET
);
150 fprintf(stderr
, "error, message initialisation failed\n");
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
);
160 static void cmd_node_set_key_help(struct cmdl
*cmdl
)
163 "Usage: %s node set key KEY [algname ALGNAME] [PROPERTIES]\n"
164 " %s node set key rekeying REKEYING\n\n"
166 " Symmetric KEY & SALT as a composite ASCII or hex string (0x...) in form:\n"
167 " [KEY: 16, 24 or 32 octets][SALT: 4 octets]\n\n"
169 " Cipher algorithm [default: \"gcm(aes)\"]\n\n"
171 " master - Set KEY as a cluster master key\n"
172 " <empty> - Set KEY as a cluster key\n"
173 " nodeid NODEID - Set KEY as a per-node key for own or peer\n\n"
175 " INTERVAL - Set rekeying interval (in minutes) [0: disable]\n"
176 " now - Trigger one (first) rekeying immediately\n\n"
178 " %s node set key this_is_a_master_key master\n"
179 " %s node set key 0x746869735F69735F615F6B657931365F73616C74\n"
180 " %s node set key this_is_a_key16_salt algname \"gcm(aes)\" nodeid 1001002\n"
181 " %s node set key rekeying 600\n\n",
182 cmdl
->argv
[0], cmdl
->argv
[0], cmdl
->argv
[0], cmdl
->argv
[0],
183 cmdl
->argv
[0], cmdl
->argv
[0]);
186 static int cmd_node_set_key(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
187 struct cmdl
*cmdl
, void *data
)
191 struct tipc_aead_key key
;
192 char mem
[TIPC_AEAD_KEY_SIZE_MAX
];
195 struct opt opts
[] = {
196 { "algname", OPT_KEYVAL
, NULL
},
197 { "nodeid", OPT_KEYVAL
, NULL
},
198 { "master", OPT_KEY
, NULL
},
199 { "rekeying", OPT_KEYVAL
, NULL
},
203 struct opt
*opt_algname
, *opt_nodeid
, *opt_master
, *opt_rekeying
;
204 char buf
[MNL_SOCKET_BUFFER_SIZE
];
205 uint8_t id
[TIPC_NODEID_LEN
] = {0,};
206 uint32_t rekeying
= 0;
207 bool has_key
= false;
211 if (help_flag
|| cmdl
->optind
>= cmdl
->argc
) {
216 /* Check if command starts with opts i.e. "rekeying" opt without key */
217 if (find_opt(opts
, cmdl
->argv
[cmdl
->optind
]))
222 str
= shift_cmdl(cmdl
);
223 if (str2key(str
, &input
.key
)) {
224 fprintf(stderr
, "error, invalid key input\n");
229 if (parse_opts(opts
, cmdl
) < 0)
232 /* Get rekeying time */
233 opt_rekeying
= get_opt(opts
, "rekeying");
235 if (!strcmp(opt_rekeying
->val
, "now"))
236 rekeying
= TIPC_REKEYING_NOW
;
238 rekeying
= atoi(opt_rekeying
->val
);
241 /* Get algorithm name, default: "gcm(aes)" */
242 opt_algname
= get_opt(opts
, "algname");
244 strcpy(input
.key
.alg_name
, "gcm(aes)");
246 strcpy(input
.key
.alg_name
, opt_algname
->val
);
248 /* Get node identity */
249 opt_nodeid
= get_opt(opts
, "nodeid");
250 if (opt_nodeid
&& str2nodeid(opt_nodeid
->val
, id
)) {
251 fprintf(stderr
, "error, invalid node identity\n");
255 /* Get master key indication */
256 opt_master
= get_opt(opts
, "master");
258 /* Sanity check if wrong option */
259 if (opt_nodeid
&& opt_master
) {
260 fprintf(stderr
, "error, per-node key cannot be master\n");
264 /* Init & do the command */
265 nlh
= msg_init(buf
, TIPC_NL_KEY_SET
);
267 fprintf(stderr
, "error, message initialisation failed\n");
271 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_NODE
);
273 keysize
= tipc_aead_key_size(&input
.key
);
274 mnl_attr_put(nlh
, TIPC_NLA_NODE_KEY
, keysize
, &input
.key
);
276 mnl_attr_put(nlh
, TIPC_NLA_NODE_ID
, TIPC_NODEID_LEN
, id
);
278 mnl_attr_put(nlh
, TIPC_NLA_NODE_KEY_MASTER
, 0, NULL
);
281 mnl_attr_put_u32(nlh
, TIPC_NLA_NODE_REKEYING
, rekeying
);
283 mnl_attr_nest_end(nlh
, nest
);
284 return msg_doit(nlh
, NULL
, NULL
);
287 static int cmd_node_flush_key(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
288 struct cmdl
*cmdl
, void *data
)
290 char buf
[MNL_SOCKET_BUFFER_SIZE
];
297 /* Init & do the command */
298 nlh
= msg_init(buf
, TIPC_NL_KEY_FLUSH
);
300 fprintf(stderr
, "error, message initialisation failed\n");
303 return msg_doit(nlh
, NULL
, NULL
);
306 static int nodeid_get_cb(const struct nlmsghdr
*nlh
, void *data
)
308 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
309 struct nlattr
*attrs
[TIPC_NLA_NET_MAX
+ 1] = {};
311 uint8_t id
[16] = {0,};
312 uint64_t *w0
= (uint64_t *) &id
[0];
313 uint64_t *w1
= (uint64_t *) &id
[8];
315 mnl_attr_parse(nlh
, sizeof(struct genlmsghdr
), parse_attrs
, info
);
316 if (!info
[TIPC_NLA_NET
])
319 mnl_attr_parse_nested(info
[TIPC_NLA_NET
], parse_attrs
, attrs
);
320 if (!attrs
[TIPC_NLA_NET_ID
])
323 *w0
= mnl_attr_get_u64(attrs
[TIPC_NLA_NET_NODEID
]);
324 *w1
= mnl_attr_get_u64(attrs
[TIPC_NLA_NET_NODEID_W1
]);
326 printf("Node Identity Hash\n");
327 printf("%-33s", str
);
328 cmd_node_get_addr(NULL
, NULL
, NULL
, NULL
);
332 static int cmd_node_get_nodeid(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
333 struct cmdl
*cmdl
, void *data
)
335 char buf
[MNL_SOCKET_BUFFER_SIZE
];
342 nlh
= msg_init(buf
, TIPC_NL_NET_GET
);
344 fprintf(stderr
, "error, message initialisation failed\n");
348 return msg_dumpit(nlh
, nodeid_get_cb
, NULL
);
352 static int netid_get_cb(const struct nlmsghdr
*nlh
, void *data
)
354 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
355 struct nlattr
*attrs
[TIPC_NLA_NET_MAX
+ 1] = {};
357 mnl_attr_parse(nlh
, sizeof(struct genlmsghdr
), parse_attrs
, info
);
358 if (!info
[TIPC_NLA_NET
])
361 mnl_attr_parse_nested(info
[TIPC_NLA_NET
], parse_attrs
, attrs
);
362 if (!attrs
[TIPC_NLA_NET_ID
])
365 printf("%u\n", mnl_attr_get_u32(attrs
[TIPC_NLA_NET_ID
]));
370 static int cmd_node_get_netid(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
371 struct cmdl
*cmdl
, void *data
)
373 char buf
[MNL_SOCKET_BUFFER_SIZE
];
380 if (!(nlh
= msg_init(buf
, TIPC_NL_NET_GET
))) {
381 fprintf(stderr
, "error, message initialisation failed\n");
385 return msg_dumpit(nlh
, netid_get_cb
, NULL
);
388 static int cmd_node_set_netid(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
389 struct cmdl
*cmdl
, void *data
)
392 char buf
[MNL_SOCKET_BUFFER_SIZE
];
400 if (!(nlh
= msg_init(buf
, TIPC_NL_NET_SET
))) {
401 fprintf(stderr
, "error, message initialisation failed\n");
405 if (cmdl
->argc
!= cmdl
->optind
+ 1) {
406 fprintf(stderr
, "Usage: %s node set netid NETID\n",
410 netid
= atoi(shift_cmdl(cmdl
));
412 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_NET
);
413 mnl_attr_put_u32(nlh
, TIPC_NLA_NET_ID
, netid
);
414 mnl_attr_nest_end(nlh
, nest
);
416 return msg_doit(nlh
, NULL
, NULL
);
419 static void cmd_node_flush_help(struct cmdl
*cmdl
)
422 "Usage: %s node flush PROPERTY\n\n"
424 " key - Flush all symmetric-keys\n",
428 static int cmd_node_flush(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
429 struct cmdl
*cmdl
, void *data
)
431 const struct cmd cmds
[] = {
432 { "key", cmd_node_flush_key
, NULL
},
436 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
439 static void cmd_node_set_help(struct cmdl
*cmdl
)
442 "Usage: %s node set PROPERTY\n\n"
444 " identity NODEID - Set node identity\n"
445 " clusterid CLUSTERID - Set local cluster id\n"
446 " key PROPERTY - Set symmetric-key\n",
450 static int cmd_node_set(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
451 struct cmdl
*cmdl
, void *data
)
453 const struct cmd cmds
[] = {
454 { "address", cmd_node_set_addr
, NULL
},
455 { "identity", cmd_node_set_nodeid
, NULL
},
456 { "netid", cmd_node_set_netid
, NULL
},
457 { "clusterid", cmd_node_set_netid
, NULL
},
458 { "key", cmd_node_set_key
, cmd_node_set_key_help
},
462 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
465 static void cmd_node_get_help(struct cmdl
*cmdl
)
468 "Usage: %s node get PROPERTY\n\n"
470 " identity - Get node identity\n"
471 " clusterid - Get local clusterid\n",
475 static int cmd_node_get(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
476 struct cmdl
*cmdl
, void *data
)
478 const struct cmd cmds
[] = {
479 { "address", cmd_node_get_addr
, NULL
},
480 { "identity", cmd_node_get_nodeid
, NULL
},
481 { "netid", cmd_node_get_netid
, NULL
},
482 { "clusterid", cmd_node_get_netid
, NULL
},
486 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
489 void cmd_node_help(struct cmdl
*cmdl
)
492 "Usage: %s node COMMAND [ARGS] ...\n\n"
494 " list - List remote nodes\n"
495 " get - Get local node parameters\n"
496 " set - Set local node parameters\n"
497 " flush - Flush local node parameters\n",
501 int cmd_node(struct nlmsghdr
*nlh
, const struct cmd
*cmd
, struct cmdl
*cmdl
,
504 const struct cmd cmds
[] = {
505 { "list", cmd_node_list
, NULL
},
506 { "get", cmd_node_get
, cmd_node_get_help
},
507 { "set", cmd_node_set
, cmd_node_set_help
},
508 { "flush", cmd_node_flush
, cmd_node_flush_help
},
512 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);