2 * link.c TIPC link 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 link_list_cb(const struct nlmsghdr
*nlh
, void *data
)
29 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
30 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
31 struct nlattr
*attrs
[TIPC_NLA_LINK_MAX
+ 1] = {};
33 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
34 if (!info
[TIPC_NLA_LINK
])
37 mnl_attr_parse_nested(info
[TIPC_NLA_LINK
], parse_attrs
, attrs
);
38 if (!attrs
[TIPC_NLA_LINK_NAME
])
41 printf("%s: ", mnl_attr_get_str(attrs
[TIPC_NLA_LINK_NAME
]));
43 if (attrs
[TIPC_NLA_LINK_UP
])
51 static int cmd_link_list(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
52 struct cmdl
*cmdl
, void *data
)
54 char buf
[MNL_SOCKET_BUFFER_SIZE
];
57 fprintf(stderr
, "Usage: %s link list\n", cmdl
->argv
[0]);
61 if (!(nlh
= msg_init(buf
, TIPC_NL_LINK_GET
))) {
62 fprintf(stderr
, "error, message initialisation failed\n");
66 return msg_dumpit(nlh
, link_list_cb
, NULL
);
69 static int link_get_cb(const struct nlmsghdr
*nlh
, void *data
)
72 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
73 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
74 struct nlattr
*attrs
[TIPC_NLA_LINK_MAX
+ 1] = {};
75 struct nlattr
*props
[TIPC_NLA_PROP_MAX
+ 1] = {};
77 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
78 if (!info
[TIPC_NLA_LINK
])
81 mnl_attr_parse_nested(info
[TIPC_NLA_LINK
], parse_attrs
, attrs
);
82 if (!attrs
[TIPC_NLA_LINK_PROP
])
85 mnl_attr_parse_nested(attrs
[TIPC_NLA_LINK_PROP
], parse_attrs
, props
);
89 printf("%u\n", mnl_attr_get_u32(props
[*prop
]));
94 static int cmd_link_get_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
95 struct cmdl
*cmdl
, void *data
)
98 char buf
[MNL_SOCKET_BUFFER_SIZE
];
100 struct opt opts
[] = {
101 { "link", OPT_KEYVAL
, NULL
},
105 if (strcmp(cmd
->cmd
, "priority") == 0)
106 prop
= TIPC_NLA_PROP_PRIO
;
107 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
108 prop
= TIPC_NLA_PROP_TOL
;
109 else if ((strcmp(cmd
->cmd
, "window") == 0))
110 prop
= TIPC_NLA_PROP_WIN
;
119 if (parse_opts(opts
, cmdl
) < 0)
122 if (!(nlh
= msg_init(buf
, TIPC_NL_LINK_GET
))) {
123 fprintf(stderr
, "error, message initialisation failed\n");
127 if (!(opt
= get_opt(opts
, "link"))) {
128 fprintf(stderr
, "error, missing link\n");
131 mnl_attr_put_strz(nlh
, TIPC_NLA_LINK_NAME
, opt
->val
);
133 return msg_doit(nlh
, link_get_cb
, &prop
);
136 static void cmd_link_get_help(struct cmdl
*cmdl
)
138 fprintf(stderr
, "Usage: %s link get PPROPERTY link LINK\n\n"
140 " tolerance - Get link tolerance\n"
141 " priority - Get link priority\n"
142 " window - Get link window\n",
146 static int cmd_link_get(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
147 struct cmdl
*cmdl
, void *data
)
149 const struct cmd cmds
[] = {
150 { "priority", cmd_link_get_prop
, cmd_link_get_help
},
151 { "tolerance", cmd_link_get_prop
, cmd_link_get_help
},
152 { "window", cmd_link_get_prop
, cmd_link_get_help
},
156 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
159 static void cmd_link_stat_reset_help(struct cmdl
*cmdl
)
161 fprintf(stderr
, "Usage: %s link stat reset link LINK\n\n", cmdl
->argv
[0]);
164 static int cmd_link_stat_reset(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
165 struct cmdl
*cmdl
, void *data
)
168 char buf
[MNL_SOCKET_BUFFER_SIZE
];
171 struct opt opts
[] = {
172 { "link", OPT_KEYVAL
, NULL
},
181 if (parse_opts(opts
, cmdl
) != 1) {
186 if (!(nlh
= msg_init(buf
, TIPC_NL_LINK_RESET_STATS
))) {
187 fprintf(stderr
, "error, message initialisation failed\n");
191 if (!(opt
= get_opt(opts
, "link"))) {
192 fprintf(stderr
, "error, missing link\n");
197 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_LINK
);
198 mnl_attr_put_strz(nlh
, TIPC_NLA_LINK_NAME
, link
);
199 mnl_attr_nest_end(nlh
, nest
);
201 return msg_doit(nlh
, NULL
, NULL
);
204 static uint32_t perc(uint32_t count
, uint32_t total
)
206 return (count
* 100 + (total
/ 2)) / total
;
209 static int _show_link_stat(struct nlattr
*attrs
[], struct nlattr
*prop
[],
210 struct nlattr
*stats
[])
214 if (attrs
[TIPC_NLA_LINK_ACTIVE
])
216 else if (attrs
[TIPC_NLA_LINK_UP
])
221 printf(" MTU:%u Priority:%u Tolerance:%u ms Window:%u packets\n",
222 mnl_attr_get_u32(attrs
[TIPC_NLA_LINK_MTU
]),
223 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_PRIO
]),
224 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_TOL
]),
225 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_WIN
]));
227 printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
228 mnl_attr_get_u32(attrs
[TIPC_NLA_LINK_RX
]) -
229 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_INFO
]),
230 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTS
]),
231 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTED
]),
232 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLES
]),
233 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLED
]));
235 printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
236 mnl_attr_get_u32(attrs
[TIPC_NLA_LINK_TX
]) -
237 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_INFO
]),
238 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTS
]),
239 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTED
]),
240 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLES
]),
241 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLED
]));
243 proft
= mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_PROF_TOT
]);
244 printf(" TX profile sample:%u packets average:%u octets\n",
245 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_CNT
]),
246 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_TOT
]) / proft
);
248 printf(" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% "
249 "-16384:%u%% -32768:%u%% -66000:%u%%\n",
250 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P0
]), proft
),
251 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P1
]), proft
),
252 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P2
]), proft
),
253 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P3
]), proft
),
254 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P4
]), proft
),
255 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P5
]), proft
),
256 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P6
]), proft
));
258 printf(" RX states:%u probes:%u naks:%u defs:%u dups:%u\n",
259 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_STATES
]),
260 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_PROBES
]),
261 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_NACKS
]),
262 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_DEFERRED
]),
263 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_DUPLICATES
]));
265 printf(" TX states:%u probes:%u naks:%u acks:%u dups:%u\n",
266 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_STATES
]),
267 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_PROBES
]),
268 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_NACKS
]),
269 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_ACKS
]),
270 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RETRANSMITTED
]));
272 printf(" Congestion link:%u Send queue max:%u avg:%u\n",
273 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_LINK_CONGS
]),
274 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MAX_QUEUE
]),
275 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_AVG_QUEUE
]));
280 static int _show_bc_link_stat(struct nlattr
*prop
[], struct nlattr
*stats
[])
282 printf(" Window:%u packets\n",
283 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_WIN
]));
285 printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
286 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_INFO
]),
287 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTS
]),
288 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTED
]),
289 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLES
]),
290 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLED
]));
292 printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
293 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_INFO
]),
294 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTS
]),
295 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTED
]),
296 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLES
]),
297 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLED
]));
299 printf(" RX naks:%u defs:%u dups:%u\n",
300 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_NACKS
]),
301 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_DEFERRED
]),
302 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_DUPLICATES
]));
304 printf(" TX naks:%u acks:%u dups:%u\n",
305 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_NACKS
]),
306 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_ACKS
]),
307 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RETRANSMITTED
]));
309 printf(" Congestion link:%u Send queue max:%u avg:%u\n",
310 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_LINK_CONGS
]),
311 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MAX_QUEUE
]),
312 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_AVG_QUEUE
]));
317 static int link_stat_show_cb(const struct nlmsghdr
*nlh
, void *data
)
320 const char *link
= data
;
321 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
322 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
323 struct nlattr
*attrs
[TIPC_NLA_LINK_MAX
+ 1] = {};
324 struct nlattr
*prop
[TIPC_NLA_PROP_MAX
+ 1] = {};
325 struct nlattr
*stats
[TIPC_NLA_STATS_MAX
+ 1] = {};
327 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
328 if (!info
[TIPC_NLA_LINK
])
331 mnl_attr_parse_nested(info
[TIPC_NLA_LINK
], parse_attrs
, attrs
);
332 if (!attrs
[TIPC_NLA_LINK_NAME
] || !attrs
[TIPC_NLA_LINK_PROP
] ||
333 !attrs
[TIPC_NLA_LINK_STATS
])
336 mnl_attr_parse_nested(attrs
[TIPC_NLA_LINK_PROP
], parse_attrs
, prop
);
337 mnl_attr_parse_nested(attrs
[TIPC_NLA_LINK_STATS
], parse_attrs
, stats
);
339 name
= mnl_attr_get_str(attrs
[TIPC_NLA_LINK_NAME
]);
341 /* If a link is passed, skip all but that link */
342 if (link
&& (strcmp(name
, link
) != 0))
345 if (attrs
[TIPC_NLA_LINK_BROADCAST
]) {
346 printf("Link <%s>\n", name
);
347 return _show_bc_link_stat(prop
, stats
);
350 printf("\nLink <%s>\n", name
);
352 return _show_link_stat(attrs
, prop
, stats
);
355 static void cmd_link_stat_show_help(struct cmdl
*cmdl
)
357 fprintf(stderr
, "Usage: %s link stat show [ link LINK ]\n",
361 static int cmd_link_stat_show(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
362 struct cmdl
*cmdl
, void *data
)
365 char buf
[MNL_SOCKET_BUFFER_SIZE
];
367 struct opt opts
[] = {
368 { "link", OPT_KEYVAL
, NULL
},
377 if (!(nlh
= msg_init(buf
, TIPC_NL_LINK_GET
))) {
378 fprintf(stderr
, "error, message initialisation failed\n");
382 if (parse_opts(opts
, cmdl
) < 0)
385 if ((opt
= get_opt(opts
, "link")))
388 return msg_dumpit(nlh
, link_stat_show_cb
, link
);
391 static void cmd_link_stat_help(struct cmdl
*cmdl
)
393 fprintf(stderr
, "Usage: %s link stat COMMAND [ARGS]\n\n"
395 " reset - Reset link statistics for link\n"
396 " show - Get link priority\n",
400 static int cmd_link_stat(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
401 struct cmdl
*cmdl
, void *data
)
403 const struct cmd cmds
[] = {
404 { "reset", cmd_link_stat_reset
, cmd_link_stat_reset_help
},
405 { "show", cmd_link_stat_show
, cmd_link_stat_show_help
},
409 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
412 static void cmd_link_set_help(struct cmdl
*cmdl
)
414 fprintf(stderr
, "Usage: %s link set PPROPERTY link LINK\n\n"
416 " tolerance TOLERANCE - Set link tolerance\n"
417 " priority PRIORITY - Set link priority\n"
418 " window WINDOW - Set link window\n",
422 static int cmd_link_set_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
423 struct cmdl
*cmdl
, void *data
)
427 char buf
[MNL_SOCKET_BUFFER_SIZE
];
428 struct nlattr
*props
;
429 struct nlattr
*attrs
;
431 struct opt opts
[] = {
432 { "link", OPT_KEYVAL
, NULL
},
436 if (strcmp(cmd
->cmd
, "priority") == 0)
437 prop
= TIPC_NLA_PROP_PRIO
;
438 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
439 prop
= TIPC_NLA_PROP_TOL
;
440 else if ((strcmp(cmd
->cmd
, "window") == 0))
441 prop
= TIPC_NLA_PROP_WIN
;
450 if (cmdl
->optind
>= cmdl
->argc
) {
451 fprintf(stderr
, "error, missing value\n");
454 val
= atoi(shift_cmdl(cmdl
));
456 if (parse_opts(opts
, cmdl
) < 0)
459 if (!(nlh
= msg_init(buf
, TIPC_NL_LINK_SET
))) {
460 fprintf(stderr
, "error, message initialisation failed\n");
463 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_LINK
);
465 if (!(opt
= get_opt(opts
, "link"))) {
466 fprintf(stderr
, "error, missing link\n");
469 mnl_attr_put_strz(nlh
, TIPC_NLA_LINK_NAME
, opt
->val
);
471 props
= mnl_attr_nest_start(nlh
, TIPC_NLA_LINK_PROP
);
472 mnl_attr_put_u32(nlh
, prop
, val
);
473 mnl_attr_nest_end(nlh
, props
);
475 mnl_attr_nest_end(nlh
, attrs
);
477 return msg_doit(nlh
, link_get_cb
, &prop
);
480 static int cmd_link_set(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
481 struct cmdl
*cmdl
, void *data
)
483 const struct cmd cmds
[] = {
484 { "priority", cmd_link_set_prop
, cmd_link_set_help
},
485 { "tolerance", cmd_link_set_prop
, cmd_link_set_help
},
486 { "window", cmd_link_set_prop
, cmd_link_set_help
},
490 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
493 static int cmd_link_mon_set_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
494 struct cmdl
*cmdl
, void *data
)
497 char buf
[MNL_SOCKET_BUFFER_SIZE
];
498 struct nlattr
*attrs
;
500 if (cmdl
->argc
!= cmdl
->optind
+ 1) {
501 fprintf(stderr
, "error, missing value\n");
504 size
= atoi(shift_cmdl(cmdl
));
506 if (!(nlh
= msg_init(buf
, TIPC_NL_MON_SET
))) {
507 fprintf(stderr
, "error, message initialisation failed\n");
510 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_MON
);
512 mnl_attr_put_u32(nlh
, TIPC_NLA_MON_ACTIVATION_THRESHOLD
, size
);
514 mnl_attr_nest_end(nlh
, attrs
);
516 return msg_doit(nlh
, NULL
, NULL
);
519 static int link_mon_summary_cb(const struct nlmsghdr
*nlh
, void *data
)
521 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
522 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
523 struct nlattr
*attrs
[TIPC_NLA_MON_MAX
+ 1] = {};
525 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
526 if (!info
[TIPC_NLA_MON
])
529 mnl_attr_parse_nested(info
[TIPC_NLA_MON
], parse_attrs
, attrs
);
531 printf("\nbearer %s\n",
532 mnl_attr_get_str(attrs
[TIPC_NLA_MON_BEARER_NAME
]));
534 printf(" table_generation %u\n",
535 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_LISTGEN
]));
536 printf(" cluster_size %u\n",
537 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEERCNT
]));
538 printf(" algorithm %s\n",
539 attrs
[TIPC_NLA_MON_ACTIVE
] ? "overlapping-ring" : "full-mesh");
544 static int cmd_link_mon_summary(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
545 struct cmdl
*cmdl
, void *data
)
547 char buf
[MNL_SOCKET_BUFFER_SIZE
];
550 fprintf(stderr
, "Usage: %s monitor summary\n", cmdl
->argv
[0]);
554 if (!(nlh
= msg_init(buf
, TIPC_NL_MON_GET
))) {
555 fprintf(stderr
, "error, message initialisation failed\n");
559 return msg_dumpit(nlh
, link_mon_summary_cb
, NULL
);
562 #define STATUS_WIDTH 7
563 #define MAX_NODE_WIDTH 14 /* 255.4095.4095 */
564 #define MAX_DOM_GEN_WIDTH 11 /* 65535 */
565 #define DIRECTLY_MON_WIDTH 10
567 #define APPL_NODE_STATUS_WIDTH 5
569 static int map_get(uint64_t up_map
, int i
)
571 return (up_map
& (1 << i
)) >> i
;
574 /* print the applied members, since we know the the members
575 * are listed in ascending order, we print only the state */
576 static void link_mon_print_applied(uint16_t applied
, uint64_t up_map
)
581 for (i
= 0; i
< applied
; i
++) {
582 /* print the delimiter for every -n- entry */
583 if (i
&& !(i
% APPL_NODE_STATUS_WIDTH
))
586 state
= map_get(up_map
, i
) ? 'U' : 'D';
591 /* print the non applied members, since we dont know
592 * the members, we print them along with the state */
593 static void link_mon_print_non_applied(uint16_t applied
, uint16_t member_cnt
,
594 uint64_t up_map
, uint32_t *members
)
600 for (i
= applied
; i
< member_cnt
; i
++) {
603 /* print the delimiter for every entry */
607 sprintf(addr_str
, "%u.%u.%u:", tipc_zone(members
[i
]),
608 tipc_cluster(members
[i
]), tipc_node(members
[i
]));
609 state
= map_get(up_map
, i
) ? 'U' : 'D';
610 printf("%s%c", addr_str
, state
);
615 static void link_mon_print_peer_state(const uint32_t addr
, const char *status
,
616 const char *monitored
,
617 const uint32_t dom_gen
)
621 sprintf(addr_str
, "%u.%u.%u", tipc_zone(addr
), tipc_cluster(addr
),
624 printf("%-*s", MAX_NODE_WIDTH
, addr_str
);
625 printf("%-*s", STATUS_WIDTH
, status
);
626 printf("%-*s", DIRECTLY_MON_WIDTH
, monitored
);
627 printf("%-*u", MAX_DOM_GEN_WIDTH
, dom_gen
);
630 static int link_mon_peer_list_cb(const struct nlmsghdr
*nlh
, void *data
)
632 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
633 struct nlattr
*attrs
[TIPC_NLA_MON_PEER_MAX
+ 1] = {};
634 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
642 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
643 if (!info
[TIPC_NLA_MON_PEER
])
646 mnl_attr_parse_nested(info
[TIPC_NLA_MON_PEER
], parse_attrs
, attrs
);
648 (attrs
[TIPC_NLA_MON_PEER_LOCAL
] || attrs
[TIPC_NLA_MON_PEER_HEAD
]) ?
649 strcpy(monitored
, "direct") :
650 strcpy(monitored
, "indirect");
652 attrs
[TIPC_NLA_MON_PEER_UP
] ?
653 strcpy(status
, "up") :
654 strcpy(status
, "down");
656 dom_gen
= attrs
[TIPC_NLA_MON_PEER_DOMGEN
] ?
657 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEER_DOMGEN
]) : 0;
659 link_mon_print_peer_state(mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEER_ADDR
]),
660 status
, monitored
, dom_gen
);
662 applied
= mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEER_APPLIED
]);
667 up_map
= mnl_attr_get_u64(attrs
[TIPC_NLA_MON_PEER_UPMAP
]);
669 member_cnt
= mnl_attr_get_payload_len(attrs
[TIPC_NLA_MON_PEER_MEMBERS
]);
671 /* each tipc address occupies 4 bytes of payload, hence compensate it */
672 member_cnt
/= sizeof(uint32_t);
674 link_mon_print_applied(applied
, up_map
);
676 link_mon_print_non_applied(applied
, member_cnt
, up_map
,
677 mnl_attr_get_payload(attrs
[TIPC_NLA_MON_PEER_MEMBERS
]));
685 static int link_mon_peer_list(uint32_t mon_ref
)
687 struct nlmsghdr
*nlh
;
688 char buf
[MNL_SOCKET_BUFFER_SIZE
];
691 if (!(nlh
= msg_init(buf
, TIPC_NL_MON_PEER_GET
))) {
692 fprintf(stderr
, "error, message initialisation failed\n");
696 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_MON
);
697 mnl_attr_put_u32(nlh
, TIPC_NLA_MON_REF
, mon_ref
);
698 mnl_attr_nest_end(nlh
, nest
);
700 return msg_dumpit(nlh
, link_mon_peer_list_cb
, NULL
);
703 static int link_mon_list_cb(const struct nlmsghdr
*nlh
, void *data
)
705 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
706 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
707 struct nlattr
*attrs
[TIPC_NLA_MON_MAX
+ 1] = {};
708 char *req_bearer
= data
;
710 const char *title
= "node status monitored generation "
711 "applied_node_status [non_applied_node:status]";
713 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
714 if (!info
[TIPC_NLA_MON
])
717 mnl_attr_parse_nested(info
[TIPC_NLA_MON
], parse_attrs
, attrs
);
719 bname
= mnl_attr_get_str(attrs
[TIPC_NLA_MON_BEARER_NAME
]);
721 if (*req_bearer
&& (strcmp(req_bearer
, bname
) != 0))
724 printf("\nbearer %s\n", bname
);
725 printf("%s\n", title
);
727 if (mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEERCNT
]))
728 link_mon_peer_list(mnl_attr_get_u32(attrs
[TIPC_NLA_MON_REF
]));
733 static void cmd_link_mon_list_help(struct cmdl
*cmdl
)
735 fprintf(stderr
, "Usage: %s monitor list [ media MEDIA ARGS...] \n\n",
737 print_bearer_media();
740 static void cmd_link_mon_list_l2_help(struct cmdl
*cmdl
, char *media
)
743 "Usage: %s monitor list media %s device DEVICE [OPTIONS]\n",
744 cmdl
->argv
[0], media
);
747 static void cmd_link_mon_list_udp_help(struct cmdl
*cmdl
, char *media
)
750 "Usage: %s monitor list media udp name NAME \n\n",
754 static int cmd_link_mon_list(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
755 struct cmdl
*cmdl
, void *data
)
757 char buf
[MNL_SOCKET_BUFFER_SIZE
];
758 char bname
[TIPC_MAX_BEARER_NAME
] = {0};
759 struct opt opts
[] = {
760 { "media", OPT_KEYVAL
, NULL
},
761 { "device", OPT_KEYVAL
, NULL
},
762 { "name", OPT_KEYVAL
, NULL
},
765 struct tipc_sup_media sup_media
[] = {
766 { "udp", "name", cmd_link_mon_list_udp_help
},
767 { "eth", "device", cmd_link_mon_list_l2_help
},
768 { "ib", "device", cmd_link_mon_list_l2_help
},
774 if (parse_opts(opts
, cmdl
) < 0)
777 if (get_opt(opts
, "media")) {
778 if ((err
= cmd_get_unique_bearer_name(cmd
, cmdl
, opts
, bname
,
788 if (!(nlh
= msg_init(buf
, TIPC_NL_MON_GET
))) {
789 fprintf(stderr
, "error, message initialisation failed\n");
793 return msg_dumpit(nlh
, link_mon_list_cb
, bname
);
796 static void cmd_link_mon_set_help(struct cmdl
*cmdl
)
798 fprintf(stderr
, "Usage: %s monitor set PPROPERTY\n\n"
800 " threshold SIZE - Set monitor activation threshold\n",
804 static int cmd_link_mon_set(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
805 struct cmdl
*cmdl
, void *data
)
807 const struct cmd cmds
[] = {
808 { "threshold", cmd_link_mon_set_prop
, NULL
},
812 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
815 static void cmd_link_mon_get_help(struct cmdl
*cmdl
)
817 fprintf(stderr
, "Usage: %s monitor get PPROPERTY \n\n"
819 " threshold - Get monitor activation threshold\n",
823 static int link_mon_get_cb(const struct nlmsghdr
*nlh
, void *data
)
825 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
826 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
827 struct nlattr
*attrs
[TIPC_NLA_MON_MAX
+ 1] = {};
829 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
830 if (!info
[TIPC_NLA_MON
])
833 mnl_attr_parse_nested(info
[TIPC_NLA_MON
], parse_attrs
, attrs
);
834 if (!attrs
[TIPC_NLA_MON_ACTIVATION_THRESHOLD
])
838 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_ACTIVATION_THRESHOLD
]));
843 static int cmd_link_mon_get_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
844 struct cmdl
*cmdl
, void *data
)
846 char buf
[MNL_SOCKET_BUFFER_SIZE
];
848 if (!(nlh
= msg_init(buf
, TIPC_NL_MON_GET
))) {
849 fprintf(stderr
, "error, message initialisation failed\n");
853 return msg_doit(nlh
, link_mon_get_cb
, NULL
);
856 static int cmd_link_mon_get(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
857 struct cmdl
*cmdl
, void *data
)
859 const struct cmd cmds
[] = {
860 { "threshold", cmd_link_mon_get_prop
, NULL
},
864 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
867 static void cmd_link_mon_help(struct cmdl
*cmdl
)
870 "Usage: %s montior COMMAND [ARGS] ...\n\n"
872 " set - Set monitor properties\n"
873 " get - Get monitor properties\n"
874 " list - List all cluster members\n"
875 " summary - Show local node monitor summary\n",
879 static int cmd_link_mon(struct nlmsghdr
*nlh
, const struct cmd
*cmd
, struct cmdl
*cmdl
,
882 const struct cmd cmds
[] = {
883 { "set", cmd_link_mon_set
, cmd_link_mon_set_help
},
884 { "get", cmd_link_mon_get
, cmd_link_mon_get_help
},
885 { "list", cmd_link_mon_list
, cmd_link_mon_list_help
},
886 { "summary", cmd_link_mon_summary
, NULL
},
890 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
893 void cmd_link_help(struct cmdl
*cmdl
)
896 "Usage: %s link COMMAND [ARGS] ...\n"
899 " list - List links\n"
900 " get - Get various link properties\n"
901 " set - Set various link properties\n"
902 " statistics - Show or reset statistics\n"
903 " monitor - Show or set link supervision\n",
907 int cmd_link(struct nlmsghdr
*nlh
, const struct cmd
*cmd
, struct cmdl
*cmdl
,
910 const struct cmd cmds
[] = {
911 { "get", cmd_link_get
, cmd_link_get_help
},
912 { "list", cmd_link_list
, NULL
},
913 { "set", cmd_link_set
, cmd_link_set_help
},
914 { "statistics", cmd_link_stat
, cmd_link_stat_help
},
915 { "monitor", cmd_link_mon
, cmd_link_mon_help
},
919 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);