mirror_iproute2/tipc/media.c
GhantaKrishnamurthy MohanKrishna 7d40bdbc8d tipc: Add support to set and get MTU for UDP bearer
In this commit we introduce the ability to set and get
MTU for UDP media and bearer.

For set and get properties such as tolerance, window and priority,
we already do:

    $ tipc media set PPROPERTY media MEDIA
    $ tipc media get PPROPERTY media MEDIA

    $ tipc bearer set OPTION media MEDIA ARGS
    $ tipc bearer get [OPTION] media MEDIA ARGS

The same has been extended for MTU, with an exception to support
only media type UDP.

Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: GhantaKrishnamurthy MohanKrishna <mohan.krishna.ghanta.krishnamurthy@ericsson.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
2018-05-09 20:53:32 -07:00

281 lines
7.1 KiB
C

/*
* media.c TIPC link functionality.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Richard Alpe <richard.alpe@ericsson.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <linux/tipc_netlink.h>
#include <linux/tipc.h>
#include <linux/genetlink.h>
#include <libmnl/libmnl.h>
#include "cmdl.h"
#include "msg.h"
#include "media.h"
static int media_list_cb(const struct nlmsghdr *nlh, void *data)
{
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *info[TIPC_NLA_MAX + 1] = {};
struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {};
mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
if (!info[TIPC_NLA_MEDIA])
return MNL_CB_ERROR;
mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs);
if (!attrs[TIPC_NLA_MEDIA_NAME])
return MNL_CB_ERROR;
printf("%s\n", mnl_attr_get_str(attrs[TIPC_NLA_MEDIA_NAME]));
return MNL_CB_OK;
}
static int cmd_media_list(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
if (help_flag) {
fprintf(stderr, "Usage: %s media list\n", cmdl->argv[0]);
return -EINVAL;
}
if (!(nlh = msg_init(buf, TIPC_NL_MEDIA_GET))) {
fprintf(stderr, "error, message initialisation failed\n");
return -1;
}
return msg_dumpit(nlh, media_list_cb, NULL);
}
static int media_get_cb(const struct nlmsghdr *nlh, void *data)
{
int *prop = data;
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *info[TIPC_NLA_MAX + 1] = {};
struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {};
struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {};
mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
if (!info[TIPC_NLA_MEDIA])
return MNL_CB_ERROR;
mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs);
if (!attrs[TIPC_NLA_MEDIA_PROP])
return MNL_CB_ERROR;
mnl_attr_parse_nested(attrs[TIPC_NLA_MEDIA_PROP], parse_attrs, props);
if (!props[*prop])
return MNL_CB_ERROR;
printf("%u\n", mnl_attr_get_u32(props[*prop]));
return MNL_CB_OK;
}
static int cmd_media_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
int prop;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlattr *nest;
struct opt *opt;
struct opt opts[] = {
{ "media", OPT_KEYVAL, NULL },
{ NULL }
};
if (strcmp(cmd->cmd, "priority") == 0)
prop = TIPC_NLA_PROP_PRIO;
else if ((strcmp(cmd->cmd, "tolerance") == 0))
prop = TIPC_NLA_PROP_TOL;
else if ((strcmp(cmd->cmd, "window") == 0))
prop = TIPC_NLA_PROP_WIN;
else if ((strcmp(cmd->cmd, "mtu") == 0))
prop = TIPC_NLA_PROP_MTU;
else
return -EINVAL;
if (help_flag) {
(cmd->help)(cmdl);
return -EINVAL;
}
if (parse_opts(opts, cmdl) < 0)
return -EINVAL;
if (!(nlh = msg_init(buf, TIPC_NL_MEDIA_GET))) {
fprintf(stderr, "error, message initialisation failed\n");
return -1;
}
if (!(opt = get_opt(opts, "media"))) {
fprintf(stderr, "error, missing media\n");
return -EINVAL;
}
if ((prop == TIPC_NLA_PROP_MTU) &&
(strcmp(opt->val, "udp"))) {
fprintf(stderr, "error, not supported for media\n");
return -EINVAL;
}
nest = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA);
mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val);
mnl_attr_nest_end(nlh, nest);
return msg_doit(nlh, media_get_cb, &prop);
}
static void cmd_media_get_help(struct cmdl *cmdl)
{
fprintf(stderr, "Usage: %s media get PPROPERTY media MEDIA\n\n"
"PROPERTIES\n"
" tolerance - Get media tolerance\n"
" priority - Get media priority\n"
" window - Get media window\n"
" mtu - Get media mtu\n",
cmdl->argv[0]);
}
static int cmd_media_get(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
const struct cmd cmds[] = {
{ "priority", cmd_media_get_prop, cmd_media_get_help },
{ "tolerance", cmd_media_get_prop, cmd_media_get_help },
{ "window", cmd_media_get_prop, cmd_media_get_help },
{ "mtu", cmd_media_get_prop, cmd_media_get_help },
{ NULL }
};
return run_cmd(nlh, cmd, cmds, cmdl, NULL);
}
static void cmd_media_set_help(struct cmdl *cmdl)
{
fprintf(stderr, "Usage: %s media set PPROPERTY media MEDIA\n\n"
"PROPERTIES\n"
" tolerance TOLERANCE - Set media tolerance\n"
" priority PRIORITY - Set media priority\n"
" window WINDOW - Set media window\n"
" mtu MTU - Set media mtu\n",
cmdl->argv[0]);
}
static int cmd_media_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
int val;
int prop;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlattr *props;
struct nlattr *attrs;
struct opt *opt;
struct opt opts[] = {
{ "media", OPT_KEYVAL, NULL },
{ NULL }
};
if (strcmp(cmd->cmd, "priority") == 0)
prop = TIPC_NLA_PROP_PRIO;
else if ((strcmp(cmd->cmd, "tolerance") == 0))
prop = TIPC_NLA_PROP_TOL;
else if ((strcmp(cmd->cmd, "window") == 0))
prop = TIPC_NLA_PROP_WIN;
else if ((strcmp(cmd->cmd, "mtu") == 0))
prop = TIPC_NLA_PROP_MTU;
else
return -EINVAL;
if (help_flag) {
(cmd->help)(cmdl);
return -EINVAL;
}
if (cmdl->optind >= cmdl->argc) {
fprintf(stderr, "error, missing value\n");
return -EINVAL;
}
val = atoi(shift_cmdl(cmdl));
if (parse_opts(opts, cmdl) < 0)
return -EINVAL;
if (!(nlh = msg_init(buf, TIPC_NL_MEDIA_SET))) {
fprintf(stderr, "error, message initialisation failed\n");
return -1;
}
attrs = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA);
if (!(opt = get_opt(opts, "media"))) {
fprintf(stderr, "error, missing media\n");
return -EINVAL;
}
if ((prop == TIPC_NLA_PROP_MTU) &&
(strcmp(opt->val, "udp"))) {
fprintf(stderr, "error, not supported for media\n");
return -EINVAL;
}
mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val);
props = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA_PROP);
mnl_attr_put_u32(nlh, prop, val);
mnl_attr_nest_end(nlh, props);
mnl_attr_nest_end(nlh, attrs);
return msg_doit(nlh, NULL, NULL);
}
static int cmd_media_set(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
const struct cmd cmds[] = {
{ "priority", cmd_media_set_prop, cmd_media_set_help },
{ "tolerance", cmd_media_set_prop, cmd_media_set_help },
{ "window", cmd_media_set_prop, cmd_media_set_help },
{ "mtu", cmd_media_set_prop, cmd_media_set_help },
{ NULL }
};
return run_cmd(nlh, cmd, cmds, cmdl, NULL);
}
void cmd_media_help(struct cmdl *cmdl)
{
fprintf(stderr,
"Usage: %s media COMMAND [ARGS] ...\n"
"\n"
"Commands:\n"
" list - List active media types\n"
" get - Get various media properties\n"
" set - Set various media properties\n",
cmdl->argv[0]);
}
int cmd_media(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
void *data)
{
const struct cmd cmds[] = {
{ "get", cmd_media_get, cmd_media_get_help },
{ "list", cmd_media_list, NULL },
{ "set", cmd_media_set, cmd_media_set_help },
{ NULL }
};
return run_cmd(nlh, cmd, cmds, cmdl, NULL);
}