1f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe/* 2f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * link.c TIPC link functionality. 3f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * 4f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * This program is free software; you can redistribute it and/or 5f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * modify it under the terms of the GNU General Public License 6f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * as published by the Free Software Foundation; either version 7f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * 2 of the License, or (at your option) any later version. 8f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * 9f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe * Authors: Richard Alpe <richard.alpe@ericsson.com> 10f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe */ 11f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 12f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <stdio.h> 13f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <stdlib.h> 14f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <string.h> 15f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <errno.h> 16f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 17f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <linux/tipc_netlink.h> 18f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <linux/tipc.h> 19f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <linux/genetlink.h> 20f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include <libmnl/libmnl.h> 21f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 22f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include "cmdl.h" 23f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include "msg.h" 24f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe#include "link.h" 25f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 26f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int link_list_cb(const struct nlmsghdr *nlh, void *data) 27f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 28f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); 29f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *info[TIPC_NLA_MAX + 1] = {}; 30f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {}; 31f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 32f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); 33f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!info[TIPC_NLA_LINK]) 34f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_ERROR; 35f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 36f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs); 37f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!attrs[TIPC_NLA_LINK_NAME]) 38f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_ERROR; 39f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 40f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf("%s: ", mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME])); 41f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 42f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (attrs[TIPC_NLA_LINK_UP]) 43f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf("up\n"); 44f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else 45f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf("down\n"); 46f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 47f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_OK; 48f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 49f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 50f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_list(struct nlmsghdr *nlh, const struct cmd *cmd, 51f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 52f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 53f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe char buf[MNL_SOCKET_BUFFER_SIZE]; 54f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 55f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (help_flag) { 56f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "Usage: %s link list\n", cmdl->argv[0]); 57f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 58f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 59f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 60f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(nlh = msg_init(buf, TIPC_NL_LINK_GET))) { 61f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, message initialisation failed\n"); 62f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -1; 63f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 64f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 65f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return msg_dumpit(nlh, link_list_cb, NULL); 66f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 67f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 68f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int link_get_cb(const struct nlmsghdr *nlh, void *data) 69f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 70f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe int *prop = data; 71f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); 72f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *info[TIPC_NLA_MAX + 1] = {}; 73f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {}; 74f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {}; 75f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 76f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); 77f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!info[TIPC_NLA_LINK]) 78f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_ERROR; 79f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 80f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs); 81f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!attrs[TIPC_NLA_LINK_PROP]) 82f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_ERROR; 83f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 84f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, props); 85f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!props[*prop]) 86f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_ERROR; 87f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 88f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf("%u\n", mnl_attr_get_u32(props[*prop])); 89f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 90f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_OK; 91f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 92f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 93f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 94f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd, 95f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 96f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 97f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe int prop; 98f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe char buf[MNL_SOCKET_BUFFER_SIZE]; 99f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt *opt; 100f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt opts[] = { 101f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "link", NULL }, 102f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 103f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 104f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 105f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (strcmp(cmd->cmd, "priority") == 0) 106f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe prop = TIPC_NLA_PROP_PRIO; 107f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else if ((strcmp(cmd->cmd, "tolerance") == 0)) 108f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe prop = TIPC_NLA_PROP_TOL; 109f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else if ((strcmp(cmd->cmd, "window") == 0)) 110f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe prop = TIPC_NLA_PROP_WIN; 111f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else 112f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 113f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 114f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (help_flag) { 115f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe (cmd->help)(cmdl); 116f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 117f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 118f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 119f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (parse_opts(opts, cmdl) < 0) 120f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 121f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 122f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(nlh = msg_init(buf, TIPC_NL_LINK_GET))) { 123f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, message initialisation failed\n"); 124f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -1; 125f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 126f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 127f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(opt = get_opt(opts, "link"))) { 128f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, missing link\n"); 129f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 130f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 131f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, opt->val); 132f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 133f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return msg_doit(nlh, link_get_cb, &prop); 134f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 135f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 136f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic void cmd_link_get_help(struct cmdl *cmdl) 137f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 138f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "Usage: %s link get PPROPERTY link LINK\n\n" 139f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe "PROPERTIES\n" 140f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " tolerance - Get link tolerance\n" 141f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " priority - Get link priority\n" 142f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " window - Get link window\n", 143f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe cmdl->argv[0]); 144f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 145f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 146f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd, 147f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 148f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 149f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe const struct cmd cmds[] = { 150f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "priority", cmd_link_get_prop, cmd_link_get_help }, 151f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "tolerance", cmd_link_get_prop, cmd_link_get_help }, 152f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "window", cmd_link_get_prop, cmd_link_get_help }, 153f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 154f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 155f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 156f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return run_cmd(nlh, cmd, cmds, cmdl, NULL); 157f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 158f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 159f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic void cmd_link_stat_reset_help(struct cmdl *cmdl) 160f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 161f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "Usage: %s link stat reset link LINK\n\n", cmdl->argv[0]); 162f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 163f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 164f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_stat_reset(struct nlmsghdr *nlh, const struct cmd *cmd, 165f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 166f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 167f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe char *link; 168f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe char buf[MNL_SOCKET_BUFFER_SIZE]; 169f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt *opt; 170f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *nest; 171f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt opts[] = { 172f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "link", NULL }, 173f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 174f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 175f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 176f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (help_flag) { 177f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe (cmd->help)(cmdl); 178f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 179f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 180f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 181f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (parse_opts(opts, cmdl) != 1) { 182f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe (cmd->help)(cmdl); 183f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 184f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 185f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 186f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(nlh = msg_init(buf, TIPC_NL_LINK_RESET_STATS))) { 187f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, message initialisation failed\n"); 188f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -1; 189f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 190f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 191f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(opt = get_opt(opts, "link"))) { 192f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, missing link\n"); 193f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 194f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 195f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe link = opt->val; 196f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 197f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe nest = mnl_attr_nest_start(nlh, TIPC_NLA_LINK); 198f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, link); 199f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_nest_end(nlh, nest); 200f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 201f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return msg_doit(nlh, NULL, NULL); 202f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 203f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 204f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic uint32_t perc(uint32_t count, uint32_t total) 205f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 206f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return (count * 100 + (total / 2)) / total; 207f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 208f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 209f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int _show_link_stat(struct nlattr *attrs[], struct nlattr *prop[], 210f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *stats[]) 211f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 212f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe uint32_t proft; 213f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 214f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (attrs[TIPC_NLA_LINK_ACTIVE]) 215f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" ACTIVE"); 216f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else if (attrs[TIPC_NLA_LINK_UP]) 217f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" STANDBY"); 218f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else 219f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" DEFUNCT"); 220f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 221f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" MTU:%u Priority:%u Tolerance:%u ms Window:%u packets\n", 222f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU]), 223f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO]), 224f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL]), 225f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); 226f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 227f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n", 228f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) - 229f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), 230f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), 231f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), 232f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), 233f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); 234f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 235f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n", 236f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) - 237f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), 238f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), 239f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), 240f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), 241f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); 242f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 243f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe proft = mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]); 244f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" TX profile sample:%u packets average:%u octets\n", 245f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]), 246f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft); 247f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 248f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " 249f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe "-16384:%u%% -32768:%u%% -66000:%u%%\n", 250f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft), 251f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft), 252f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft), 253f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft), 254f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft), 255f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft), 256f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft)); 257f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 258f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" RX states:%u probes:%u naks:%u defs:%u dups:%u\n", 259f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES]), 260f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]), 261f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), 262f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), 263f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); 264f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 265f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" TX states:%u probes:%u naks:%u acks:%u dups:%u\n", 266f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES]), 267f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]), 268f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), 269f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), 270f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); 271f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 272f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" Congestion link:%u Send queue max:%u avg:%u\n", 273f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), 274f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), 275f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); 276f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 277f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_OK; 278f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 279f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 280f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int _show_bc_link_stat(struct nlattr *prop[], struct nlattr *stats[]) 281f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 282f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" Window:%u packets\n", 283f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); 284f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 285f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n", 286f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), 287f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), 288f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), 289f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), 290f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); 291f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 292f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n", 293f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), 294f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), 295f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), 296f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), 297f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); 298f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 299f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" RX naks:%u defs:%u dups:%u\n", 300f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), 301f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), 302f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); 303f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 304f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" TX naks:%u acks:%u dups:%u\n", 305f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), 306f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), 307f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); 308f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 309f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf(" Congestion link:%u Send queue max:%u avg:%u\n", 310f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), 311f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), 312f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); 313f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 314f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_OK; 315f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 316f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 317f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int link_stat_show_cb(const struct nlmsghdr *nlh, void *data) 318f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 319f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe const char *name; 320f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe const char *link = data; 321f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); 322f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *info[TIPC_NLA_MAX + 1] = {}; 323f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {}; 324f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *prop[TIPC_NLA_PROP_MAX + 1] = {}; 325f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *stats[TIPC_NLA_STATS_MAX + 1] = {}; 326f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 327f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); 328f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!info[TIPC_NLA_LINK]) 329f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_ERROR; 330f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 331f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs); 332f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!attrs[TIPC_NLA_LINK_NAME] || !attrs[TIPC_NLA_LINK_PROP] || 333f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe !attrs[TIPC_NLA_LINK_STATS]) 334f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_ERROR; 335f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 336f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, prop); 337f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_STATS], parse_attrs, stats); 338f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 339f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe name = mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]); 340f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 341f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe /* If a link is passed, skip all but that link */ 342f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (link && (strcmp(name, link) != 0)) 343f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return MNL_CB_OK; 344f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 345f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (attrs[TIPC_NLA_LINK_BROADCAST]) { 346f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf("Link <%s>\n", name); 347f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return _show_bc_link_stat(prop, stats); 348f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 349f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 350f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe printf("\nLink <%s>\n", name); 351f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 352f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return _show_link_stat(attrs, prop, stats); 353f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 354f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 355f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic void cmd_link_stat_show_help(struct cmdl *cmdl) 356f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 357f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "Usage: %s link stat show [ link LINK ]\n", 358f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe cmdl->argv[0]); 359f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 360f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 361f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_stat_show(struct nlmsghdr *nlh, const struct cmd *cmd, 362f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 363f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 364f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe char *link = NULL; 365f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe char buf[MNL_SOCKET_BUFFER_SIZE]; 366f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt *opt; 367f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt opts[] = { 368f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "link", NULL }, 369f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 370f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 371f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 372f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (help_flag) { 373f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe (cmd->help)(cmdl); 374f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 375f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 376f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 377f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(nlh = msg_init(buf, TIPC_NL_LINK_GET))) { 378f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, message initialisation failed\n"); 379f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -1; 380f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 381f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 382f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (parse_opts(opts, cmdl) < 0) 383f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 384f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 385f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if ((opt = get_opt(opts, "link"))) 386f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe link = opt->val; 387f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 388f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return msg_dumpit(nlh, link_stat_show_cb, link); 389f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 390f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 391f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic void cmd_link_stat_help(struct cmdl *cmdl) 392f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 393f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "Usage: %s link stat COMMAND [ARGS]\n\n" 394f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe "COMMANDS:\n" 395f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " reset - Reset link statistics for link\n" 396f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " show - Get link priority\n", 397f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe cmdl->argv[0]); 398f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 399f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 400f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_stat(struct nlmsghdr *nlh, const struct cmd *cmd, 401f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 402f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 403f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe const struct cmd cmds[] = { 404f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "reset", cmd_link_stat_reset, cmd_link_stat_reset_help }, 405f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "show", cmd_link_stat_show, cmd_link_stat_show_help }, 406f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 407f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 408f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 409f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return run_cmd(nlh, cmd, cmds, cmdl, NULL); 410f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 411f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 412f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic void cmd_link_set_help(struct cmdl *cmdl) 413f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 414f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "Usage: %s link set PPROPERTY link LINK\n\n" 415f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe "PROPERTIES\n" 416f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " tolerance TOLERANCE - Set link tolerance\n" 417f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " priority PRIORITY - Set link priority\n" 418f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " window WINDOW - Set link window\n", 419f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe cmdl->argv[0]); 420f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 421f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 422f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd, 423f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 424f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 425f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe int val; 426f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe int prop; 427f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe char buf[MNL_SOCKET_BUFFER_SIZE]; 428f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *props; 429f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct nlattr *attrs; 430f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt *opt; 431f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct opt opts[] = { 432f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "link", NULL }, 433f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 434f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 435f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 436f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (strcmp(cmd->cmd, "priority") == 0) 437f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe prop = TIPC_NLA_PROP_PRIO; 438f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else if ((strcmp(cmd->cmd, "tolerance") == 0)) 439f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe prop = TIPC_NLA_PROP_TOL; 440f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else if ((strcmp(cmd->cmd, "window") == 0)) 441f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe prop = TIPC_NLA_PROP_WIN; 442f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe else 443f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 444f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 445f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (help_flag) { 446f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe (cmd->help)(cmdl); 447f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 448f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 449f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 450f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (cmdl->optind >= cmdl->argc) { 451f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, missing value\n"); 452f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 453f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 454f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe val = atoi(shift_cmdl(cmdl)); 455f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 456f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (parse_opts(opts, cmdl) < 0) 457f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 458f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 459f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(nlh = msg_init(buf, TIPC_NL_LINK_SET))) { 460f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, message initialisation failed\n"); 461f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -1; 462f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 463f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe attrs = mnl_attr_nest_start(nlh, TIPC_NLA_LINK); 464f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 465f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe if (!(opt = get_opt(opts, "link"))) { 466f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, "error, missing link\n"); 467f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return -EINVAL; 468f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe } 469f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, opt->val); 470f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 471f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe props = mnl_attr_nest_start(nlh, TIPC_NLA_LINK_PROP); 472f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_put_u32(nlh, prop, val); 473f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_nest_end(nlh, props); 474f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 475f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe mnl_attr_nest_end(nlh, attrs); 476f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 477f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return msg_doit(nlh, link_get_cb, &prop); 478f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 479f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return 0; 480f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 481f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 482f043759dd492897513d5aa057427bcdab8592d4bRichard Alpestatic int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd, 483f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe struct cmdl *cmdl, void *data) 484f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 485f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe const struct cmd cmds[] = { 486f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "priority", cmd_link_set_prop, cmd_link_set_help }, 487f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "tolerance", cmd_link_set_prop, cmd_link_set_help }, 488f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "window", cmd_link_set_prop, cmd_link_set_help }, 489f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 490f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 491f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 492f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return run_cmd(nlh, cmd, cmds, cmdl, NULL); 493f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 494f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 495f043759dd492897513d5aa057427bcdab8592d4bRichard Alpevoid cmd_link_help(struct cmdl *cmdl) 496f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 497f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe fprintf(stderr, 498f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe "Usage: %s link COMMAND [ARGS] ...\n" 499f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe "\n" 500f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe "COMMANDS\n" 501f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " list - List links\n" 502f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " get - Get various link properties\n" 503f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " set - Set various link properties\n" 504f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe " statistics - Show or reset statistics\n", 505f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe cmdl->argv[0]); 506f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 507f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 508f043759dd492897513d5aa057427bcdab8592d4bRichard Alpeint cmd_link(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, 509f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe void *data) 510f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe{ 511f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe const struct cmd cmds[] = { 512f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "get", cmd_link_get, cmd_link_get_help }, 513f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "list", cmd_link_list, NULL }, 514f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "set", cmd_link_set, cmd_link_set_help }, 515f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { "statistics", cmd_link_stat, cmd_link_stat_help }, 516f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe { NULL } 517f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe }; 518f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe 519f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe return run_cmd(nlh, cmd, cmds, cmdl, NULL); 520f043759dd492897513d5aa057427bcdab8592d4bRichard Alpe} 521