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 nlh
= msg_init(buf
, TIPC_NL_LINK_GET
);
63 fprintf(stderr
, "error, message initialisation failed\n");
67 return msg_dumpit(nlh
, link_list_cb
, NULL
);
70 static int link_get_cb(const struct nlmsghdr
*nlh
, void *data
)
73 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
74 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
75 struct nlattr
*attrs
[TIPC_NLA_LINK_MAX
+ 1] = {};
76 struct nlattr
*props
[TIPC_NLA_PROP_MAX
+ 1] = {};
78 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
79 if (!info
[TIPC_NLA_LINK
])
82 mnl_attr_parse_nested(info
[TIPC_NLA_LINK
], parse_attrs
, attrs
);
83 if (!attrs
[TIPC_NLA_LINK_PROP
])
86 mnl_attr_parse_nested(attrs
[TIPC_NLA_LINK_PROP
], parse_attrs
, props
);
90 printf("%u\n", mnl_attr_get_u32(props
[*prop
]));
95 static int cmd_link_get_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
96 struct cmdl
*cmdl
, void *data
)
99 char buf
[MNL_SOCKET_BUFFER_SIZE
];
101 struct opt opts
[] = {
102 { "link", OPT_KEYVAL
, NULL
},
106 if (strcmp(cmd
->cmd
, "priority") == 0)
107 prop
= TIPC_NLA_PROP_PRIO
;
108 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
109 prop
= TIPC_NLA_PROP_TOL
;
110 else if ((strcmp(cmd
->cmd
, "window") == 0))
111 prop
= TIPC_NLA_PROP_WIN
;
120 if (parse_opts(opts
, cmdl
) < 0)
123 nlh
= msg_init(buf
, TIPC_NL_LINK_GET
);
125 fprintf(stderr
, "error, message initialisation failed\n");
129 opt
= get_opt(opts
, "link");
131 fprintf(stderr
, "error, missing link\n");
134 mnl_attr_put_strz(nlh
, TIPC_NLA_LINK_NAME
, opt
->val
);
136 return msg_doit(nlh
, link_get_cb
, &prop
);
139 static void cmd_link_get_help(struct cmdl
*cmdl
)
141 fprintf(stderr
, "Usage: %s link get PPROPERTY link LINK\n\n"
143 " tolerance - Get link tolerance\n"
144 " priority - Get link priority\n"
145 " window - Get link window\n",
149 static int cmd_link_get(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
150 struct cmdl
*cmdl
, void *data
)
152 const struct cmd cmds
[] = {
153 { "priority", cmd_link_get_prop
, cmd_link_get_help
},
154 { "tolerance", cmd_link_get_prop
, cmd_link_get_help
},
155 { "window", cmd_link_get_prop
, cmd_link_get_help
},
159 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
162 static void cmd_link_stat_reset_help(struct cmdl
*cmdl
)
164 fprintf(stderr
, "Usage: %s link stat reset link LINK\n\n", cmdl
->argv
[0]);
167 static int cmd_link_stat_reset(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
168 struct cmdl
*cmdl
, void *data
)
171 char buf
[MNL_SOCKET_BUFFER_SIZE
];
174 struct opt opts
[] = {
175 { "link", OPT_KEYVAL
, NULL
},
184 if (parse_opts(opts
, cmdl
) != 1) {
189 nlh
= msg_init(buf
, TIPC_NL_LINK_RESET_STATS
);
191 fprintf(stderr
, "error, message initialisation failed\n");
195 opt
= get_opt(opts
, "link");
197 fprintf(stderr
, "error, missing link\n");
202 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_LINK
);
203 mnl_attr_put_strz(nlh
, TIPC_NLA_LINK_NAME
, link
);
204 mnl_attr_nest_end(nlh
, nest
);
206 return msg_doit(nlh
, NULL
, NULL
);
209 static uint32_t perc(uint32_t count
, uint32_t total
)
211 return (count
* 100 + (total
/ 2)) / total
;
214 static int _show_link_stat(struct nlattr
*attrs
[], struct nlattr
*prop
[],
215 struct nlattr
*stats
[])
219 if (attrs
[TIPC_NLA_LINK_ACTIVE
])
221 else if (attrs
[TIPC_NLA_LINK_UP
])
226 printf(" MTU:%u Priority:%u Tolerance:%u ms Window:%u packets\n",
227 mnl_attr_get_u32(attrs
[TIPC_NLA_LINK_MTU
]),
228 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_PRIO
]),
229 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_TOL
]),
230 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_WIN
]));
232 printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
233 mnl_attr_get_u32(attrs
[TIPC_NLA_LINK_RX
]) -
234 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_INFO
]),
235 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTS
]),
236 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTED
]),
237 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLES
]),
238 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLED
]));
240 printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
241 mnl_attr_get_u32(attrs
[TIPC_NLA_LINK_TX
]) -
242 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_INFO
]),
243 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTS
]),
244 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTED
]),
245 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLES
]),
246 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLED
]));
248 proft
= mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_PROF_TOT
]);
249 printf(" TX profile sample:%u packets average:%u octets\n",
250 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_CNT
]),
251 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_TOT
]) / proft
);
253 printf(" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% -16384:%u%% -32768:%u%% -66000:%u%%\n",
254 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P0
]), proft
),
255 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P1
]), proft
),
256 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P2
]), proft
),
257 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P3
]), proft
),
258 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P4
]), proft
),
259 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P5
]), proft
),
260 perc(mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MSG_LEN_P6
]), proft
));
262 printf(" RX states:%u probes:%u naks:%u defs:%u dups:%u\n",
263 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_STATES
]),
264 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_PROBES
]),
265 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_NACKS
]),
266 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_DEFERRED
]),
267 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_DUPLICATES
]));
269 printf(" TX states:%u probes:%u naks:%u acks:%u dups:%u\n",
270 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_STATES
]),
271 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_PROBES
]),
272 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_NACKS
]),
273 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_ACKS
]),
274 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RETRANSMITTED
]));
276 printf(" Congestion link:%u Send queue max:%u avg:%u\n",
277 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_LINK_CONGS
]),
278 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MAX_QUEUE
]),
279 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_AVG_QUEUE
]));
284 static int _show_bc_link_stat(struct nlattr
*prop
[], struct nlattr
*stats
[])
286 printf(" Window:%u packets\n",
287 mnl_attr_get_u32(prop
[TIPC_NLA_PROP_WIN
]));
289 printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
290 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_INFO
]),
291 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTS
]),
292 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_FRAGMENTED
]),
293 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLES
]),
294 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_BUNDLED
]));
296 printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
297 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_INFO
]),
298 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTS
]),
299 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_FRAGMENTED
]),
300 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLES
]),
301 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_BUNDLED
]));
303 printf(" RX naks:%u defs:%u dups:%u\n",
304 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_NACKS
]),
305 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RX_DEFERRED
]),
306 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_DUPLICATES
]));
308 printf(" TX naks:%u acks:%u dups:%u\n",
309 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_NACKS
]),
310 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_TX_ACKS
]),
311 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_RETRANSMITTED
]));
313 printf(" Congestion link:%u Send queue max:%u avg:%u\n",
314 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_LINK_CONGS
]),
315 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_MAX_QUEUE
]),
316 mnl_attr_get_u32(stats
[TIPC_NLA_STATS_AVG_QUEUE
]));
321 static int link_stat_show_cb(const struct nlmsghdr
*nlh
, void *data
)
324 const char *link
= data
;
325 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
326 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
327 struct nlattr
*attrs
[TIPC_NLA_LINK_MAX
+ 1] = {};
328 struct nlattr
*prop
[TIPC_NLA_PROP_MAX
+ 1] = {};
329 struct nlattr
*stats
[TIPC_NLA_STATS_MAX
+ 1] = {};
331 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
332 if (!info
[TIPC_NLA_LINK
])
335 mnl_attr_parse_nested(info
[TIPC_NLA_LINK
], parse_attrs
, attrs
);
336 if (!attrs
[TIPC_NLA_LINK_NAME
] || !attrs
[TIPC_NLA_LINK_PROP
] ||
337 !attrs
[TIPC_NLA_LINK_STATS
])
340 mnl_attr_parse_nested(attrs
[TIPC_NLA_LINK_PROP
], parse_attrs
, prop
);
341 mnl_attr_parse_nested(attrs
[TIPC_NLA_LINK_STATS
], parse_attrs
, stats
);
343 name
= mnl_attr_get_str(attrs
[TIPC_NLA_LINK_NAME
]);
345 /* If a link is passed, skip all but that link */
346 if (link
&& (strcmp(name
, link
) != 0))
349 if (attrs
[TIPC_NLA_LINK_BROADCAST
]) {
350 printf("Link <%s>\n", name
);
351 return _show_bc_link_stat(prop
, stats
);
354 printf("\nLink <%s>\n", name
);
356 return _show_link_stat(attrs
, prop
, stats
);
359 static void cmd_link_stat_show_help(struct cmdl
*cmdl
)
361 fprintf(stderr
, "Usage: %s link stat show [ link LINK ]\n",
365 static int cmd_link_stat_show(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
366 struct cmdl
*cmdl
, void *data
)
369 char buf
[MNL_SOCKET_BUFFER_SIZE
];
371 struct opt opts
[] = {
372 { "link", OPT_KEYVAL
, NULL
},
381 nlh
= msg_init(buf
, TIPC_NL_LINK_GET
);
383 fprintf(stderr
, "error, message initialisation failed\n");
387 if (parse_opts(opts
, cmdl
) < 0)
390 opt
= get_opt(opts
, "link");
394 return msg_dumpit(nlh
, link_stat_show_cb
, link
);
397 static void cmd_link_stat_help(struct cmdl
*cmdl
)
399 fprintf(stderr
, "Usage: %s link stat COMMAND [ARGS]\n\n"
401 " reset - Reset link statistics for link\n"
402 " show - Get link priority\n",
406 static int cmd_link_stat(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
407 struct cmdl
*cmdl
, void *data
)
409 const struct cmd cmds
[] = {
410 { "reset", cmd_link_stat_reset
, cmd_link_stat_reset_help
},
411 { "show", cmd_link_stat_show
, cmd_link_stat_show_help
},
415 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
418 static void cmd_link_set_help(struct cmdl
*cmdl
)
420 fprintf(stderr
, "Usage: %s link set PPROPERTY link LINK\n\n"
422 " tolerance TOLERANCE - Set link tolerance\n"
423 " priority PRIORITY - Set link priority\n"
424 " window WINDOW - Set link window\n",
428 static int cmd_link_set_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
429 struct cmdl
*cmdl
, void *data
)
433 char buf
[MNL_SOCKET_BUFFER_SIZE
];
434 struct nlattr
*props
;
435 struct nlattr
*attrs
;
437 struct opt opts
[] = {
438 { "link", OPT_KEYVAL
, NULL
},
442 if (strcmp(cmd
->cmd
, "priority") == 0)
443 prop
= TIPC_NLA_PROP_PRIO
;
444 else if ((strcmp(cmd
->cmd
, "tolerance") == 0))
445 prop
= TIPC_NLA_PROP_TOL
;
446 else if ((strcmp(cmd
->cmd
, "window") == 0))
447 prop
= TIPC_NLA_PROP_WIN
;
456 if (cmdl
->optind
>= cmdl
->argc
) {
457 fprintf(stderr
, "error, missing value\n");
460 val
= atoi(shift_cmdl(cmdl
));
462 if (parse_opts(opts
, cmdl
) < 0)
465 nlh
= msg_init(buf
, TIPC_NL_LINK_SET
);
467 fprintf(stderr
, "error, message initialisation failed\n");
470 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_LINK
);
472 opt
= get_opt(opts
, "link");
474 fprintf(stderr
, "error, missing link\n");
477 mnl_attr_put_strz(nlh
, TIPC_NLA_LINK_NAME
, opt
->val
);
479 props
= mnl_attr_nest_start(nlh
, TIPC_NLA_LINK_PROP
);
480 mnl_attr_put_u32(nlh
, prop
, val
);
481 mnl_attr_nest_end(nlh
, props
);
483 mnl_attr_nest_end(nlh
, attrs
);
485 return msg_doit(nlh
, link_get_cb
, &prop
);
488 static int cmd_link_set(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
489 struct cmdl
*cmdl
, void *data
)
491 const struct cmd cmds
[] = {
492 { "priority", cmd_link_set_prop
, cmd_link_set_help
},
493 { "tolerance", cmd_link_set_prop
, cmd_link_set_help
},
494 { "window", cmd_link_set_prop
, cmd_link_set_help
},
498 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
501 static int cmd_link_mon_set_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
502 struct cmdl
*cmdl
, void *data
)
505 char buf
[MNL_SOCKET_BUFFER_SIZE
];
506 struct nlattr
*attrs
;
508 if (cmdl
->argc
!= cmdl
->optind
+ 1) {
509 fprintf(stderr
, "error, missing value\n");
512 size
= atoi(shift_cmdl(cmdl
));
514 nlh
= msg_init(buf
, TIPC_NL_MON_SET
);
516 fprintf(stderr
, "error, message initialisation failed\n");
519 attrs
= mnl_attr_nest_start(nlh
, TIPC_NLA_MON
);
521 mnl_attr_put_u32(nlh
, TIPC_NLA_MON_ACTIVATION_THRESHOLD
, size
);
523 mnl_attr_nest_end(nlh
, attrs
);
525 return msg_doit(nlh
, NULL
, NULL
);
528 static int link_mon_summary_cb(const struct nlmsghdr
*nlh
, void *data
)
530 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
531 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
532 struct nlattr
*attrs
[TIPC_NLA_MON_MAX
+ 1] = {};
534 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
535 if (!info
[TIPC_NLA_MON
])
538 mnl_attr_parse_nested(info
[TIPC_NLA_MON
], parse_attrs
, attrs
);
540 printf("\nbearer %s\n",
541 mnl_attr_get_str(attrs
[TIPC_NLA_MON_BEARER_NAME
]));
543 printf(" table_generation %u\n",
544 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_LISTGEN
]));
545 printf(" cluster_size %u\n",
546 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEERCNT
]));
547 printf(" algorithm %s\n",
548 attrs
[TIPC_NLA_MON_ACTIVE
] ? "overlapping-ring" : "full-mesh");
553 static int cmd_link_mon_summary(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
554 struct cmdl
*cmdl
, void *data
)
556 char buf
[MNL_SOCKET_BUFFER_SIZE
];
559 fprintf(stderr
, "Usage: %s monitor summary\n", cmdl
->argv
[0]);
563 nlh
= msg_init(buf
, TIPC_NL_MON_GET
);
565 fprintf(stderr
, "error, message initialisation failed\n");
569 return msg_dumpit(nlh
, link_mon_summary_cb
, NULL
);
572 #define STATUS_WIDTH 7
573 #define MAX_NODE_WIDTH 14 /* 255.4095.4095 */
574 #define MAX_DOM_GEN_WIDTH 11 /* 65535 */
575 #define DIRECTLY_MON_WIDTH 10
577 #define APPL_NODE_STATUS_WIDTH 5
579 static int map_get(uint64_t up_map
, int i
)
581 return (up_map
& (1 << i
)) >> i
;
584 /* print the applied members, since we know the the members
585 * are listed in ascending order, we print only the state
587 static void link_mon_print_applied(uint16_t applied
, uint64_t up_map
)
592 for (i
= 0; i
< applied
; i
++) {
593 /* print the delimiter for every -n- entry */
594 if (i
&& !(i
% APPL_NODE_STATUS_WIDTH
))
597 state
= map_get(up_map
, i
) ? 'U' : 'D';
602 /* print the non applied members, since we dont know
603 * the members, we print them along with the state
605 static void link_mon_print_non_applied(uint16_t applied
, uint16_t member_cnt
,
606 uint64_t up_map
, uint32_t *members
)
612 for (i
= applied
; i
< member_cnt
; i
++) {
615 /* print the delimiter for every entry */
619 sprintf(addr_str
, "%u.%u.%u:", tipc_zone(members
[i
]),
620 tipc_cluster(members
[i
]), tipc_node(members
[i
]));
621 state
= map_get(up_map
, i
) ? 'U' : 'D';
622 printf("%s%c", addr_str
, state
);
627 static void link_mon_print_peer_state(const uint32_t addr
, const char *status
,
628 const char *monitored
,
629 const uint32_t dom_gen
)
633 sprintf(addr_str
, "%u.%u.%u", tipc_zone(addr
), tipc_cluster(addr
),
636 printf("%-*s", MAX_NODE_WIDTH
, addr_str
);
637 printf("%-*s", STATUS_WIDTH
, status
);
638 printf("%-*s", DIRECTLY_MON_WIDTH
, monitored
);
639 printf("%-*u", MAX_DOM_GEN_WIDTH
, dom_gen
);
642 static int link_mon_peer_list_cb(const struct nlmsghdr
*nlh
, void *data
)
644 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
645 struct nlattr
*attrs
[TIPC_NLA_MON_PEER_MAX
+ 1] = {};
646 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
654 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
655 if (!info
[TIPC_NLA_MON_PEER
])
658 mnl_attr_parse_nested(info
[TIPC_NLA_MON_PEER
], parse_attrs
, attrs
);
660 (attrs
[TIPC_NLA_MON_PEER_LOCAL
] || attrs
[TIPC_NLA_MON_PEER_HEAD
]) ?
661 strcpy(monitored
, "direct") :
662 strcpy(monitored
, "indirect");
664 attrs
[TIPC_NLA_MON_PEER_UP
] ?
665 strcpy(status
, "up") :
666 strcpy(status
, "down");
668 dom_gen
= attrs
[TIPC_NLA_MON_PEER_DOMGEN
] ?
669 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEER_DOMGEN
]) : 0;
671 link_mon_print_peer_state(mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEER_ADDR
]),
672 status
, monitored
, dom_gen
);
674 applied
= mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEER_APPLIED
]);
679 up_map
= mnl_attr_get_u64(attrs
[TIPC_NLA_MON_PEER_UPMAP
]);
681 member_cnt
= mnl_attr_get_payload_len(attrs
[TIPC_NLA_MON_PEER_MEMBERS
]);
683 /* each tipc address occupies 4 bytes of payload, hence compensate it */
684 member_cnt
/= sizeof(uint32_t);
686 link_mon_print_applied(applied
, up_map
);
688 link_mon_print_non_applied(applied
, member_cnt
, up_map
,
689 mnl_attr_get_payload(attrs
[TIPC_NLA_MON_PEER_MEMBERS
]));
697 static int link_mon_peer_list(uint32_t mon_ref
)
699 struct nlmsghdr
*nlh
;
700 char buf
[MNL_SOCKET_BUFFER_SIZE
];
703 nlh
= msg_init(buf
, TIPC_NL_MON_PEER_GET
);
705 fprintf(stderr
, "error, message initialisation failed\n");
709 nest
= mnl_attr_nest_start(nlh
, TIPC_NLA_MON
);
710 mnl_attr_put_u32(nlh
, TIPC_NLA_MON_REF
, mon_ref
);
711 mnl_attr_nest_end(nlh
, nest
);
713 return msg_dumpit(nlh
, link_mon_peer_list_cb
, NULL
);
716 static int link_mon_list_cb(const struct nlmsghdr
*nlh
, void *data
)
718 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
719 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
720 struct nlattr
*attrs
[TIPC_NLA_MON_MAX
+ 1] = {};
721 char *req_bearer
= data
;
724 "node status monitored generation applied_node_status [non_applied_node:status]";
726 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
727 if (!info
[TIPC_NLA_MON
])
730 mnl_attr_parse_nested(info
[TIPC_NLA_MON
], parse_attrs
, attrs
);
732 bname
= mnl_attr_get_str(attrs
[TIPC_NLA_MON_BEARER_NAME
]);
734 if (*req_bearer
&& (strcmp(req_bearer
, bname
) != 0))
737 printf("\nbearer %s\n", bname
);
738 printf("%s\n", title
);
740 if (mnl_attr_get_u32(attrs
[TIPC_NLA_MON_PEERCNT
]))
741 link_mon_peer_list(mnl_attr_get_u32(attrs
[TIPC_NLA_MON_REF
]));
746 static void cmd_link_mon_list_help(struct cmdl
*cmdl
)
748 fprintf(stderr
, "Usage: %s monitor list [ media MEDIA ARGS...]\n\n",
750 print_bearer_media();
753 static void cmd_link_mon_list_l2_help(struct cmdl
*cmdl
, char *media
)
756 "Usage: %s monitor list media %s device DEVICE [OPTIONS]\n",
757 cmdl
->argv
[0], media
);
760 static void cmd_link_mon_list_udp_help(struct cmdl
*cmdl
, char *media
)
763 "Usage: %s monitor list media udp name NAME\n\n",
767 static int cmd_link_mon_list(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
768 struct cmdl
*cmdl
, void *data
)
770 char buf
[MNL_SOCKET_BUFFER_SIZE
];
771 char bname
[TIPC_MAX_BEARER_NAME
] = {0};
772 struct opt opts
[] = {
773 { "media", OPT_KEYVAL
, NULL
},
774 { "device", OPT_KEYVAL
, NULL
},
775 { "name", OPT_KEYVAL
, NULL
},
778 struct tipc_sup_media sup_media
[] = {
779 { "udp", "name", cmd_link_mon_list_udp_help
},
780 { "eth", "device", cmd_link_mon_list_l2_help
},
781 { "ib", "device", cmd_link_mon_list_l2_help
},
787 if (parse_opts(opts
, cmdl
) < 0)
790 if (get_opt(opts
, "media")) {
791 err
= cmd_get_unique_bearer_name(cmd
, cmdl
, opts
, bname
,
802 nlh
= msg_init(buf
, TIPC_NL_MON_GET
);
804 fprintf(stderr
, "error, message initialisation failed\n");
808 return msg_dumpit(nlh
, link_mon_list_cb
, bname
);
811 static void cmd_link_mon_set_help(struct cmdl
*cmdl
)
813 fprintf(stderr
, "Usage: %s monitor set PPROPERTY\n\n"
815 " threshold SIZE - Set monitor activation threshold\n",
819 static int cmd_link_mon_set(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
820 struct cmdl
*cmdl
, void *data
)
822 const struct cmd cmds
[] = {
823 { "threshold", cmd_link_mon_set_prop
, NULL
},
827 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
830 static void cmd_link_mon_get_help(struct cmdl
*cmdl
)
832 fprintf(stderr
, "Usage: %s monitor get PPROPERTY\n\n"
834 " threshold - Get monitor activation threshold\n",
838 static int link_mon_get_cb(const struct nlmsghdr
*nlh
, void *data
)
840 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
841 struct nlattr
*info
[TIPC_NLA_MAX
+ 1] = {};
842 struct nlattr
*attrs
[TIPC_NLA_MON_MAX
+ 1] = {};
844 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, info
);
845 if (!info
[TIPC_NLA_MON
])
848 mnl_attr_parse_nested(info
[TIPC_NLA_MON
], parse_attrs
, attrs
);
849 if (!attrs
[TIPC_NLA_MON_ACTIVATION_THRESHOLD
])
853 mnl_attr_get_u32(attrs
[TIPC_NLA_MON_ACTIVATION_THRESHOLD
]));
858 static int cmd_link_mon_get_prop(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
859 struct cmdl
*cmdl
, void *data
)
861 char buf
[MNL_SOCKET_BUFFER_SIZE
];
863 nlh
= msg_init(buf
, TIPC_NL_MON_GET
);
865 fprintf(stderr
, "error, message initialisation failed\n");
869 return msg_doit(nlh
, link_mon_get_cb
, NULL
);
872 static int cmd_link_mon_get(struct nlmsghdr
*nlh
, const struct cmd
*cmd
,
873 struct cmdl
*cmdl
, void *data
)
875 const struct cmd cmds
[] = {
876 { "threshold", cmd_link_mon_get_prop
, NULL
},
880 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
883 static void cmd_link_mon_help(struct cmdl
*cmdl
)
886 "Usage: %s montior COMMAND [ARGS] ...\n\n"
888 " set - Set monitor properties\n"
889 " get - Get monitor properties\n"
890 " list - List all cluster members\n"
891 " summary - Show local node monitor summary\n",
895 static int cmd_link_mon(struct nlmsghdr
*nlh
, const struct cmd
*cmd
, struct cmdl
*cmdl
,
898 const struct cmd cmds
[] = {
899 { "set", cmd_link_mon_set
, cmd_link_mon_set_help
},
900 { "get", cmd_link_mon_get
, cmd_link_mon_get_help
},
901 { "list", cmd_link_mon_list
, cmd_link_mon_list_help
},
902 { "summary", cmd_link_mon_summary
, NULL
},
906 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);
909 void cmd_link_help(struct cmdl
*cmdl
)
912 "Usage: %s link COMMAND [ARGS] ...\n"
915 " list - List links\n"
916 " get - Get various link properties\n"
917 " set - Set various link properties\n"
918 " statistics - Show or reset statistics\n"
919 " monitor - Show or set link supervision\n",
923 int cmd_link(struct nlmsghdr
*nlh
, const struct cmd
*cmd
, struct cmdl
*cmdl
,
926 const struct cmd cmds
[] = {
927 { "get", cmd_link_get
, cmd_link_get_help
},
928 { "list", cmd_link_list
, NULL
},
929 { "set", cmd_link_set
, cmd_link_set_help
},
930 { "statistics", cmd_link_stat
, cmd_link_stat_help
},
931 { "monitor", cmd_link_mon
, cmd_link_mon_help
},
935 return run_cmd(nlh
, cmd
, cmds
, cmdl
, NULL
);