Merge ssh://gitolite.kernel.org/pub/scm/network/iproute2/iproute2-next
This commit is contained in:
20
.editorconfig
Normal file
20
.editorconfig
Normal file
@@ -0,0 +1,20 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
max_line_length = 100
|
||||
tab_width = 8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[{COMMIT_EDITMSG,*.patch}]
|
||||
max_line_length = 75
|
||||
2
etc/iproute2/rt_addrprotos.d/README
Normal file
2
etc/iproute2/rt_addrprotos.d/README
Normal file
@@ -0,0 +1,2 @@
|
||||
Each file in this directory is an rt_addrprotos configuration file. iproute2
|
||||
commands scan this directory processing all files that end in '.conf'.
|
||||
@@ -24,6 +24,7 @@ int mnlu_gen_socket_sndrcv(struct mnlu_gen_socket *nlg, const struct nlmsghdr *n
|
||||
mnl_cb_t data_cb, void *data);
|
||||
|
||||
struct mnl_socket *mnlu_socket_open(int bus);
|
||||
int mnl_add_nl_group(struct mnl_socket *nl, unsigned int group);
|
||||
struct nlmsghdr *mnlu_msg_prepare(void *buf, uint32_t nlmsg_type, uint16_t flags,
|
||||
void *extra_header, size_t extra_header_size);
|
||||
int mnlu_socket_recv_run(struct mnl_socket *nl, unsigned int seq, void *buf, size_t buf_size,
|
||||
|
||||
@@ -11,6 +11,7 @@ const char *rtnl_rttable_n2a(__u32 id, char *buf, int len);
|
||||
const char *rtnl_rtrealm_n2a(int id, char *buf, int len);
|
||||
const char *rtnl_dsfield_n2a(int id, char *buf, int len);
|
||||
const char *rtnl_dsfield_get_name(int id);
|
||||
const char *rtnl_dscp_n2a(int id, char *buf, int len);
|
||||
const char *rtnl_group_n2a(int id, char *buf, int len);
|
||||
|
||||
int rtnl_rtprot_a2n(__u32 *id, const char *arg);
|
||||
@@ -19,6 +20,7 @@ int rtnl_rtscope_a2n(__u32 *id, const char *arg);
|
||||
int rtnl_rttable_a2n(__u32 *id, const char *arg);
|
||||
int rtnl_rtrealm_a2n(__u32 *id, const char *arg);
|
||||
int rtnl_dsfield_a2n(__u32 *id, const char *arg);
|
||||
int rtnl_dscp_a2n(__u32 *id, const char *arg);
|
||||
int rtnl_group_a2n(int *id, const char *arg);
|
||||
|
||||
const char *inet_proto_n2a(int proto, char *buf, int len);
|
||||
|
||||
@@ -37,6 +37,7 @@ extern int batch_mode;
|
||||
extern int numeric;
|
||||
extern bool do_all;
|
||||
extern int echo_request;
|
||||
extern int use_iec;
|
||||
|
||||
#ifndef CONF_USR_DIR
|
||||
#define CONF_USR_DIR "/usr/lib/iproute2"
|
||||
@@ -336,6 +337,7 @@ int get_time(unsigned int *time, const char *str);
|
||||
int get_time64(__s64 *time, const char *str);
|
||||
char *sprint_time(__u32 time, char *buf);
|
||||
char *sprint_time64(__s64 time, char *buf);
|
||||
void print_num(FILE *fp, unsigned int width, uint64_t count);
|
||||
|
||||
int do_batch(const char *name, bool force,
|
||||
int (*cmd)(int argc, char *argv[], void *user), void *user);
|
||||
|
||||
2
ip/ip.c
2
ip/ip.c
@@ -27,8 +27,6 @@
|
||||
#endif
|
||||
|
||||
int preferred_family = AF_UNSPEC;
|
||||
int human_readable;
|
||||
int use_iec;
|
||||
int show_stats;
|
||||
int show_details;
|
||||
int oneline;
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include "json_print.h"
|
||||
|
||||
extern int use_iec;
|
||||
|
||||
struct link_filter {
|
||||
int ifindex;
|
||||
int family;
|
||||
@@ -18,6 +16,7 @@ struct link_filter {
|
||||
int scope, scopemask;
|
||||
int flags, flagmask;
|
||||
int up;
|
||||
int down;
|
||||
char *label;
|
||||
int flushed;
|
||||
char *flushb;
|
||||
@@ -221,7 +220,6 @@ int ipstats_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs,
|
||||
#define LABEL_MAX_MASK 0xFFFFFU
|
||||
#endif
|
||||
|
||||
void print_num(FILE *fp, unsigned int width, uint64_t count);
|
||||
void print_rt_flags(FILE *fp, unsigned int flags);
|
||||
void print_rta_ifidx(FILE *fp, __u32 ifidx, const char *prefix);
|
||||
void __print_rta_gateway(FILE *fp, unsigned char family, const char *gateway);
|
||||
|
||||
@@ -52,12 +52,12 @@ static void usage(void)
|
||||
"Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n"
|
||||
" [ CONFFLAG-LIST ]\n"
|
||||
" ip address del IFADDR dev IFNAME [mngtmpaddr]\n"
|
||||
" ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n"
|
||||
" [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n"
|
||||
" ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ] [ to PREFIX ]\n"
|
||||
" [ FLAG-LIST ] [ label LABEL ] [ { up | down } ]\n"
|
||||
" ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n"
|
||||
" [ nomaster ]\n"
|
||||
" [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n"
|
||||
" [ label LABEL ] [up] [ vrf NAME ]\n"
|
||||
" [ label LABEL ] [ { up | down } ] [ vrf NAME ]\n"
|
||||
" [ proto ADDRPROTO ] ]\n"
|
||||
" ip address {showdump|restore}\n"
|
||||
"IFADDR := PREFIX | ADDR peer PREFIX\n"
|
||||
@@ -568,46 +568,6 @@ void size_columns(unsigned int cols[], unsigned int n, ...)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void print_num(FILE *fp, unsigned int width, uint64_t count)
|
||||
{
|
||||
const char *prefix = "kMGTPE";
|
||||
const unsigned int base = use_iec ? 1024 : 1000;
|
||||
uint64_t powi = 1;
|
||||
uint16_t powj = 1;
|
||||
uint8_t precision = 2;
|
||||
char buf[64];
|
||||
|
||||
if (!human_readable || count < base) {
|
||||
fprintf(fp, "%*"PRIu64" ", width, count);
|
||||
return;
|
||||
}
|
||||
|
||||
/* increase value by a factor of 1000/1024 and print
|
||||
* if result is something a human can read
|
||||
*/
|
||||
for (;;) {
|
||||
powi *= base;
|
||||
if (count / base < powi)
|
||||
break;
|
||||
|
||||
if (!prefix[1])
|
||||
break;
|
||||
++prefix;
|
||||
}
|
||||
|
||||
/* try to guess a good number of digits for precision */
|
||||
for (; precision > 0; precision--) {
|
||||
powj *= 10;
|
||||
if (count / powi < powj)
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.*f%c%s", precision,
|
||||
(double) count / powi, *prefix, use_iec ? "i" : "");
|
||||
|
||||
fprintf(fp, "%*s ", width, buf);
|
||||
}
|
||||
|
||||
static void print_vf_stats64(FILE *fp, struct rtattr *vfstats)
|
||||
{
|
||||
struct rtattr *vf[IFLA_VF_STATS_MAX + 1];
|
||||
@@ -1021,6 +981,8 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
|
||||
return -1;
|
||||
if (filter.up && !(ifi->ifi_flags&IFF_UP))
|
||||
return -1;
|
||||
if (filter.down && ifi->ifi_flags&IFF_UP)
|
||||
return -1;
|
||||
|
||||
parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);
|
||||
|
||||
@@ -1760,6 +1722,9 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi,
|
||||
if (filter.up && !(ifi->ifi_flags&IFF_UP))
|
||||
continue;
|
||||
|
||||
if (filter.down && ifi->ifi_flags&IFF_UP)
|
||||
continue;
|
||||
|
||||
open_json_object(NULL);
|
||||
print_addrinfo(n, fp);
|
||||
close_json_object();
|
||||
@@ -2180,6 +2145,8 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
||||
filter.scope = scope;
|
||||
} else if (strcmp(*argv, "up") == 0) {
|
||||
filter.up = 1;
|
||||
} else if (strcmp(*argv, "down") == 0) {
|
||||
filter.down = 1;
|
||||
} else if (get_filter(*argv) == 0) {
|
||||
|
||||
} else if (strcmp(*argv, "label") == 0) {
|
||||
|
||||
@@ -110,8 +110,8 @@ void iplink_usage(void)
|
||||
" [ gso_max_size BYTES ] [ gso_ipv4_max_size BYTES ] [ gso_max_segs PACKETS ]\n"
|
||||
" [ gro_max_size BYTES ] [ gro_ipv4_max_size BYTES ]\n"
|
||||
"\n"
|
||||
" ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
|
||||
" [nomaster] [ novf ]\n"
|
||||
" ip link show [ DEVICE | group GROUP ] [ { up | down } ] [master DEV] [vrf NAME]\n"
|
||||
" [type TYPE] [nomaster] [ novf ]\n"
|
||||
"\n"
|
||||
" ip link xstats type TYPE [ ARGS ]\n"
|
||||
"\n"
|
||||
|
||||
107
ip/iplink_can.c
107
ip/iplink_can.c
@@ -15,6 +15,12 @@
|
||||
#include "utils.h"
|
||||
#include "ip_common.h"
|
||||
|
||||
struct can_tdc {
|
||||
__u32 tdcv;
|
||||
__u32 tdco;
|
||||
__u32 tdcf;
|
||||
};
|
||||
|
||||
static void print_usage(FILE *f)
|
||||
{
|
||||
fprintf(f,
|
||||
@@ -126,87 +132,86 @@ static void print_ctrlmode(enum output_type t, __u32 flags, const char* key)
|
||||
static int can_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||
struct nlmsghdr *n)
|
||||
{
|
||||
struct can_bittiming bt = {}, dbt = {};
|
||||
struct can_bittiming bt = {}, fd_dbt = {};
|
||||
struct can_ctrlmode cm = { 0 };
|
||||
struct rtattr *tdc;
|
||||
__u32 tdcv = -1, tdco = -1, tdcf = -1;
|
||||
struct can_tdc fd = { .tdcv = -1, .tdco = -1, .tdcf = -1 };
|
||||
|
||||
while (argc > 0) {
|
||||
if (matches(*argv, "bitrate") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&bt.bitrate, *argv, 0))
|
||||
invarg("invalid \"bitrate\" value\n", *argv);
|
||||
invarg("invalid \"bitrate\" value", *argv);
|
||||
} else if (matches(*argv, "sample-point") == 0) {
|
||||
float sp;
|
||||
|
||||
NEXT_ARG();
|
||||
if (get_float(&sp, *argv))
|
||||
invarg("invalid \"sample-point\" value\n",
|
||||
invarg("invalid \"sample-point\" value",
|
||||
*argv);
|
||||
bt.sample_point = (__u32)(sp * 1000);
|
||||
} else if (matches(*argv, "tq") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&bt.tq, *argv, 0))
|
||||
invarg("invalid \"tq\" value\n", *argv);
|
||||
invarg("invalid \"tq\" value", *argv);
|
||||
} else if (matches(*argv, "prop-seg") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&bt.prop_seg, *argv, 0))
|
||||
invarg("invalid \"prop-seg\" value\n", *argv);
|
||||
invarg("invalid \"prop-seg\" value", *argv);
|
||||
} else if (matches(*argv, "phase-seg1") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&bt.phase_seg1, *argv, 0))
|
||||
invarg("invalid \"phase-seg1\" value\n", *argv);
|
||||
invarg("invalid \"phase-seg1\" value", *argv);
|
||||
} else if (matches(*argv, "phase-seg2") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&bt.phase_seg2, *argv, 0))
|
||||
invarg("invalid \"phase-seg2\" value\n", *argv);
|
||||
invarg("invalid \"phase-seg2\" value", *argv);
|
||||
} else if (matches(*argv, "sjw") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&bt.sjw, *argv, 0))
|
||||
invarg("invalid \"sjw\" value\n", *argv);
|
||||
invarg("invalid \"sjw\" value", *argv);
|
||||
} else if (matches(*argv, "dbitrate") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&dbt.bitrate, *argv, 0))
|
||||
invarg("invalid \"dbitrate\" value\n", *argv);
|
||||
if (get_u32(&fd_dbt.bitrate, *argv, 0))
|
||||
invarg("invalid \"dbitrate\" value", *argv);
|
||||
} else if (matches(*argv, "dsample-point") == 0) {
|
||||
float sp;
|
||||
|
||||
NEXT_ARG();
|
||||
if (get_float(&sp, *argv))
|
||||
invarg("invalid \"dsample-point\" value\n", *argv);
|
||||
dbt.sample_point = (__u32)(sp * 1000);
|
||||
invarg("invalid \"dsample-point\" value", *argv);
|
||||
fd_dbt.sample_point = (__u32)(sp * 1000);
|
||||
} else if (matches(*argv, "dtq") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&dbt.tq, *argv, 0))
|
||||
invarg("invalid \"dtq\" value\n", *argv);
|
||||
if (get_u32(&fd_dbt.tq, *argv, 0))
|
||||
invarg("invalid \"dtq\" value", *argv);
|
||||
} else if (matches(*argv, "dprop-seg") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&dbt.prop_seg, *argv, 0))
|
||||
invarg("invalid \"dprop-seg\" value\n", *argv);
|
||||
if (get_u32(&fd_dbt.prop_seg, *argv, 0))
|
||||
invarg("invalid \"dprop-seg\" value", *argv);
|
||||
} else if (matches(*argv, "dphase-seg1") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&dbt.phase_seg1, *argv, 0))
|
||||
invarg("invalid \"dphase-seg1\" value\n", *argv);
|
||||
if (get_u32(&fd_dbt.phase_seg1, *argv, 0))
|
||||
invarg("invalid \"dphase-seg1\" value", *argv);
|
||||
} else if (matches(*argv, "dphase-seg2") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&dbt.phase_seg2, *argv, 0))
|
||||
invarg("invalid \"dphase-seg2\" value\n", *argv);
|
||||
if (get_u32(&fd_dbt.phase_seg2, *argv, 0))
|
||||
invarg("invalid \"dphase-seg2\" value", *argv);
|
||||
} else if (matches(*argv, "dsjw") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&dbt.sjw, *argv, 0))
|
||||
invarg("invalid \"dsjw\" value\n", *argv);
|
||||
if (get_u32(&fd_dbt.sjw, *argv, 0))
|
||||
invarg("invalid \"dsjw\" value", *argv);
|
||||
} else if (matches(*argv, "tdcv") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&tdcv, *argv, 0))
|
||||
invarg("invalid \"tdcv\" value\n", *argv);
|
||||
if (get_u32(&fd.tdcv, *argv, 0))
|
||||
invarg("invalid \"tdcv\" value", *argv);
|
||||
} else if (matches(*argv, "tdco") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&tdco, *argv, 0))
|
||||
invarg("invalid \"tdco\" value\n", *argv);
|
||||
if (get_u32(&fd.tdco, *argv, 0))
|
||||
invarg("invalid \"tdco\" value", *argv);
|
||||
} else if (matches(*argv, "tdcf") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&tdcf, *argv, 0))
|
||||
invarg("invalid \"tdcf\" value\n", *argv);
|
||||
if (get_u32(&fd.tdcf, *argv, 0))
|
||||
invarg("invalid \"tdcf\" value", *argv);
|
||||
} else if (matches(*argv, "loopback") == 0) {
|
||||
NEXT_ARG();
|
||||
set_ctrlmode("loopback", *argv, &cm,
|
||||
@@ -255,10 +260,8 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||
cm.mask |= CAN_CTRLMODE_TDC_AUTO |
|
||||
CAN_CTRLMODE_TDC_MANUAL;
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Error: argument of \"tdc-mode\" must be \"auto\", \"manual\" or \"off\", not \"%s\"\n",
|
||||
invarg("\"tdc-mode\" must be either of \"auto\", \"manual\" or \"off\"",
|
||||
*argv);
|
||||
exit (-1);
|
||||
}
|
||||
} else if (matches(*argv, "restart") == 0) {
|
||||
__u32 val = 1;
|
||||
@@ -269,14 +272,14 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||
|
||||
NEXT_ARG();
|
||||
if (get_u32(&val, *argv, 0))
|
||||
invarg("invalid \"restart-ms\" value\n", *argv);
|
||||
invarg("invalid \"restart-ms\" value", *argv);
|
||||
addattr32(n, 1024, IFLA_CAN_RESTART_MS, val);
|
||||
} else if (matches(*argv, "termination") == 0) {
|
||||
__u16 val;
|
||||
|
||||
NEXT_ARG();
|
||||
if (get_u16(&val, *argv, 0))
|
||||
invarg("invalid \"termination\" value\n",
|
||||
invarg("invalid \"termination\" value",
|
||||
*argv);
|
||||
addattr16(n, 1024, IFLA_CAN_TERMINATION, val);
|
||||
} else if (matches(*argv, "help") == 0) {
|
||||
@@ -292,19 +295,21 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||
|
||||
if (bt.bitrate || bt.tq)
|
||||
addattr_l(n, 1024, IFLA_CAN_BITTIMING, &bt, sizeof(bt));
|
||||
if (dbt.bitrate || dbt.tq)
|
||||
addattr_l(n, 1024, IFLA_CAN_DATA_BITTIMING, &dbt, sizeof(dbt));
|
||||
if (fd_dbt.bitrate || fd_dbt.tq)
|
||||
addattr_l(n, 1024, IFLA_CAN_DATA_BITTIMING, &fd_dbt, sizeof(fd_dbt));
|
||||
if (cm.mask)
|
||||
addattr_l(n, 1024, IFLA_CAN_CTRLMODE, &cm, sizeof(cm));
|
||||
|
||||
if (tdcv != -1 || tdco != -1 || tdcf != -1) {
|
||||
tdc = addattr_nest(n, 1024, IFLA_CAN_TDC | NLA_F_NESTED);
|
||||
if (tdcv != -1)
|
||||
addattr32(n, 1024, IFLA_CAN_TDC_TDCV, tdcv);
|
||||
if (tdco != -1)
|
||||
addattr32(n, 1024, IFLA_CAN_TDC_TDCO, tdco);
|
||||
if (tdcf != -1)
|
||||
addattr32(n, 1024, IFLA_CAN_TDC_TDCF, tdcf);
|
||||
if (fd.tdcv != -1 || fd.tdco != -1 || fd.tdcf != -1) {
|
||||
struct rtattr *tdc = addattr_nest(n, 1024,
|
||||
IFLA_CAN_TDC | NLA_F_NESTED);
|
||||
|
||||
if (fd.tdcv != -1)
|
||||
addattr32(n, 1024, IFLA_CAN_TDC_TDCV, fd.tdcv);
|
||||
if (fd.tdco != -1)
|
||||
addattr32(n, 1024, IFLA_CAN_TDC_TDCO, fd.tdco);
|
||||
if (fd.tdcf != -1)
|
||||
addattr32(n, 1024, IFLA_CAN_TDC_TDCF, fd.tdcf);
|
||||
addattr_nest_end(n, tdc);
|
||||
}
|
||||
|
||||
@@ -337,7 +342,7 @@ can_print_timing_min_max(const char *json_attr, const char *fp_attr,
|
||||
close_json_object();
|
||||
}
|
||||
|
||||
static void can_print_tdc_opt(FILE *f, struct rtattr *tdc_attr)
|
||||
static void can_print_tdc_opt(struct rtattr *tdc_attr)
|
||||
{
|
||||
struct rtattr *tb[IFLA_CAN_TDC_MAX + 1];
|
||||
|
||||
@@ -365,7 +370,7 @@ static void can_print_tdc_opt(FILE *f, struct rtattr *tdc_attr)
|
||||
}
|
||||
}
|
||||
|
||||
static void can_print_tdc_const_opt(FILE *f, struct rtattr *tdc_attr)
|
||||
static void can_print_tdc_const_opt(struct rtattr *tdc_attr)
|
||||
{
|
||||
struct rtattr *tb[IFLA_CAN_TDC_MAX + 1];
|
||||
|
||||
@@ -393,7 +398,7 @@ static void can_print_tdc_const_opt(FILE *f, struct rtattr *tdc_attr)
|
||||
close_json_object();
|
||||
}
|
||||
|
||||
static void can_print_ctrlmode_ext(FILE *f, struct rtattr *ctrlmode_ext_attr,
|
||||
static void can_print_ctrlmode_ext(struct rtattr *ctrlmode_ext_attr,
|
||||
__u32 cm_flags)
|
||||
{
|
||||
struct rtattr *tb[IFLA_CAN_CTRLMODE_MAX + 1];
|
||||
@@ -417,7 +422,7 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
|
||||
print_ctrlmode(PRINT_ANY, cm->flags, "ctrlmode");
|
||||
if (tb[IFLA_CAN_CTRLMODE_EXT])
|
||||
can_print_ctrlmode_ext(f, tb[IFLA_CAN_CTRLMODE_EXT],
|
||||
can_print_ctrlmode_ext(tb[IFLA_CAN_CTRLMODE_EXT],
|
||||
cm->flags);
|
||||
}
|
||||
|
||||
@@ -542,7 +547,7 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
print_uint(PRINT_ANY, "brp", " dbrp %u", dbt->brp);
|
||||
|
||||
if (tb[IFLA_CAN_TDC])
|
||||
can_print_tdc_opt(f, tb[IFLA_CAN_TDC]);
|
||||
can_print_tdc_opt(tb[IFLA_CAN_TDC]);
|
||||
|
||||
close_json_object();
|
||||
}
|
||||
@@ -566,7 +571,7 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
print_uint(PRINT_ANY, "brp_inc", " dbrp_inc %u", dbtc->brp_inc);
|
||||
|
||||
if (tb[IFLA_CAN_TDC])
|
||||
can_print_tdc_const_opt(f, tb[IFLA_CAN_TDC]);
|
||||
can_print_tdc_const_opt(tb[IFLA_CAN_TDC]);
|
||||
|
||||
close_json_object();
|
||||
}
|
||||
|
||||
36
ip/iprule.c
36
ip/iprule.c
@@ -46,6 +46,7 @@ static void usage(void)
|
||||
" [ ipproto PROTOCOL ]\n"
|
||||
" [ sport [ NUMBER | NUMBER-NUMBER ]\n"
|
||||
" [ dport [ NUMBER | NUMBER-NUMBER ] ]\n"
|
||||
" [ dscp DSCP ]\n"
|
||||
"ACTION := [ table TABLE_ID ]\n"
|
||||
" [ protocol PROTO ]\n"
|
||||
" [ nat ADDRESS ]\n"
|
||||
@@ -67,6 +68,7 @@ static struct
|
||||
unsigned int tos, tosmask;
|
||||
unsigned int pref, prefmask;
|
||||
unsigned int fwmark, fwmask;
|
||||
unsigned int dscp, dscpmask;
|
||||
uint64_t tun_id;
|
||||
char iif[IFNAMSIZ];
|
||||
char oif[IFNAMSIZ];
|
||||
@@ -219,6 +221,17 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.dscpmask) {
|
||||
if (tb[FRA_DSCP]) {
|
||||
__u8 dscp = rta_getattr_u8(tb[FRA_DSCP]);
|
||||
|
||||
if (filter.dscp != dscp)
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
table = frh_get_table(frh, tb);
|
||||
if (filter.tb > 0 && filter.tb ^ table)
|
||||
return false;
|
||||
@@ -468,6 +481,14 @@ int print_rule(struct nlmsghdr *n, void *arg)
|
||||
rtnl_rtprot_n2a(protocol, b1, sizeof(b1)));
|
||||
}
|
||||
}
|
||||
|
||||
if (tb[FRA_DSCP]) {
|
||||
__u8 dscp = rta_getattr_u8(tb[FRA_DSCP]);
|
||||
|
||||
print_string(PRINT_ANY, "dscp", " dscp %s",
|
||||
rtnl_dscp_n2a(dscp, b1, sizeof(b1)));
|
||||
}
|
||||
|
||||
print_string(PRINT_FP, NULL, "\n", "");
|
||||
close_json_object();
|
||||
fflush(fp);
|
||||
@@ -697,6 +718,14 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
|
||||
else if (ret != 2)
|
||||
invarg("invalid dport range\n", *argv);
|
||||
filter.dport = r;
|
||||
} else if (strcmp(*argv, "dscp") == 0) {
|
||||
__u32 dscp;
|
||||
|
||||
NEXT_ARG();
|
||||
if (rtnl_dscp_a2n(&dscp, *argv))
|
||||
invarg("invalid dscp\n", *argv);
|
||||
filter.dscp = dscp;
|
||||
filter.dscpmask = 1;
|
||||
} else {
|
||||
if (matches(*argv, "dst") == 0 ||
|
||||
matches(*argv, "to") == 0) {
|
||||
@@ -975,6 +1004,13 @@ static int iprule_modify(int cmd, int argc, char **argv)
|
||||
invarg("invalid dport range\n", *argv);
|
||||
addattr_l(&req.n, sizeof(req), FRA_DPORT_RANGE, &r,
|
||||
sizeof(r));
|
||||
} else if (strcmp(*argv, "dscp") == 0) {
|
||||
__u32 dscp;
|
||||
|
||||
NEXT_ARG();
|
||||
if (rtnl_dscp_a2n(&dscp, *argv))
|
||||
invarg("invalid dscp\n", *argv);
|
||||
addattr8(&req.n, sizeof(req), FRA_DSCP, dscp);
|
||||
} else {
|
||||
int type;
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@ err_bind:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int mnl_add_nl_group(struct mnl_socket *nl, unsigned int group)
|
||||
{
|
||||
return mnl_socket_bind(nl, group, MNL_SOCKET_AUTOPID);
|
||||
}
|
||||
|
||||
struct nlmsghdr *mnlu_msg_prepare(void *buf, uint32_t nlmsg_type, uint16_t flags,
|
||||
void *extra_header, size_t extra_header_size)
|
||||
{
|
||||
|
||||
@@ -315,6 +315,9 @@ static void rtnl_addrprot_initialize(void)
|
||||
ret = rtnl_tab_initialize(CONF_USR_DIR "/rt_addrprotos",
|
||||
rtnl_addrprot_tab,
|
||||
ARRAY_SIZE(rtnl_addrprot_tab));
|
||||
|
||||
rtnl_tab_initialize_dir("rt_addrprotos.d", rtnl_addrprot_tab,
|
||||
ARRAY_SIZE(rtnl_addrprot_tab));
|
||||
}
|
||||
|
||||
const char *rtnl_addrprot_n2a(__u8 id, char *buf, int len)
|
||||
@@ -625,6 +628,17 @@ const char *rtnl_dsfield_get_name(int id)
|
||||
return rtnl_rtdsfield_tab[id];
|
||||
}
|
||||
|
||||
const char *rtnl_dscp_n2a(int id, char *buf, int len)
|
||||
{
|
||||
if (!numeric) {
|
||||
const char *name = rtnl_dsfield_get_name(id << 2);
|
||||
|
||||
if (name != NULL)
|
||||
return name;
|
||||
}
|
||||
snprintf(buf, len, "%u", id);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int rtnl_dsfield_a2n(__u32 *id, const char *arg)
|
||||
{
|
||||
@@ -658,6 +672,18 @@ int rtnl_dsfield_a2n(__u32 *id, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_dscp_a2n(__u32 *id, const char *arg)
|
||||
{
|
||||
if (get_u32(id, arg, 0) == 0)
|
||||
return 0;
|
||||
|
||||
if (rtnl_dsfield_a2n(id, arg) != 0)
|
||||
return -1;
|
||||
/* Convert from DS field to DSCP */
|
||||
*id >>= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rtnl_hash_entry dflt_group_entry = {
|
||||
.id = 0, .name = "default"
|
||||
|
||||
44
lib/utils.c
44
lib/utils.c
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
@@ -38,6 +39,8 @@
|
||||
int resolve_hosts;
|
||||
int timestamp_short;
|
||||
int pretty;
|
||||
int use_iec;
|
||||
int human_readable;
|
||||
const char *_SL_ = "\n";
|
||||
|
||||
static int open_fds[5];
|
||||
@@ -2021,6 +2024,46 @@ FILE *generic_proc_open(const char *env, const char *name)
|
||||
return fopen(p, "r");
|
||||
}
|
||||
|
||||
void print_num(FILE *fp, unsigned int width, uint64_t count)
|
||||
{
|
||||
const char *prefix = "kMGTPE";
|
||||
const unsigned int base = use_iec ? 1024 : 1000;
|
||||
uint64_t powi = 1;
|
||||
uint16_t powj = 1;
|
||||
uint8_t precision = 2;
|
||||
char buf[64];
|
||||
|
||||
if (!human_readable || count < base) {
|
||||
fprintf(fp, "%*"PRIu64" ", width, count);
|
||||
return;
|
||||
}
|
||||
|
||||
/* increase value by a factor of 1000/1024 and print
|
||||
* if result is something a human can read
|
||||
*/
|
||||
for (;;) {
|
||||
powi *= base;
|
||||
if (count / base < powi)
|
||||
break;
|
||||
|
||||
if (!prefix[1])
|
||||
break;
|
||||
++prefix;
|
||||
}
|
||||
|
||||
/* try to guess a good number of digits for precision */
|
||||
for (; precision > 0; precision--) {
|
||||
powj *= 10;
|
||||
if (count / powi < powj)
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.*f%c%s", precision,
|
||||
(double) count / powi, *prefix, use_iec ? "i" : "");
|
||||
|
||||
fprintf(fp, "%*s ", width, buf);
|
||||
}
|
||||
|
||||
int open_fds_add(int fd)
|
||||
{
|
||||
if (open_fds_cnt >= ARRAY_SIZE(open_fds))
|
||||
@@ -2030,7 +2073,6 @@ int open_fds_add(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void open_fds_close(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
1
man/man8/.gitignore
vendored
1
man/man8/.gitignore
vendored
@@ -3,3 +3,4 @@ ip-address.8
|
||||
ip-link.8
|
||||
ip-netns.8
|
||||
ip-route.8
|
||||
ip-rule.8
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
TARGETS = ip-address.8 ip-link.8 ip-netns.8 ip-route.8
|
||||
TARGETS = ip-address.8 ip-link.8 ip-netns.8 ip-route.8 ip-rule.8
|
||||
|
||||
MAN8PAGES = $(TARGETS) $(filter-out $(TARGETS),$(wildcard *.8))
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ ip-address \- protocol address management
|
||||
.B to
|
||||
.IR PREFIX " ] [ " FLAG-LIST " ] [ "
|
||||
.B label
|
||||
.IR PATTERN " ] [ " up " ]"
|
||||
.IR PATTERN " ] [ { " up " | " down " } ]"
|
||||
|
||||
.ti -8
|
||||
.BR "ip address" " [ " show " [ " dev
|
||||
@@ -48,8 +48,8 @@ ip-address \- protocol address management
|
||||
.B type
|
||||
.IR TYPE " ] [ "
|
||||
.B vrf
|
||||
.IR NAME " ] [ "
|
||||
.BR up " ] ["
|
||||
.IR NAME " ] [ { "
|
||||
.BR up " | " down " } ] ["
|
||||
.BR nomaster " ]"
|
||||
.B proto
|
||||
.IR ADDRPROTO " ] ]"
|
||||
@@ -303,7 +303,10 @@ receive multicast traffic.
|
||||
the protocol identifier of this route.
|
||||
.I ADDRPROTO
|
||||
may be a number or a string from the file
|
||||
.BR "/etc/iproute2/rt_addrprotos" .
|
||||
.BR @SYSCONF_USR_DIR@/rt_addrprotos " or " @SYSCONF_ETC_DIR@/rt_addrprotos
|
||||
(has precedence if exists). A directory named
|
||||
.BR rt_addrprotos.d
|
||||
is also scanned in either location.
|
||||
If the protocol ID is not given,
|
||||
|
||||
.B ip assumes protocol 0. Several protocol
|
||||
@@ -378,6 +381,10 @@ output.
|
||||
.B up
|
||||
only list running interfaces.
|
||||
|
||||
.TP
|
||||
.B down
|
||||
only list not running interfaces.
|
||||
|
||||
.TP
|
||||
.B nomaster
|
||||
only list interfaces with no master.
|
||||
|
||||
@@ -194,8 +194,8 @@ ip-link \- network device configuration
|
||||
.B ip link show
|
||||
.RI "[ " DEVICE " | "
|
||||
.B group
|
||||
.IR GROUP " ] ["
|
||||
.BR up " ] ["
|
||||
.IR GROUP " ] [ { "
|
||||
.BR up " | " down " } ] ["
|
||||
.B master
|
||||
.IR DEVICE " ] ["
|
||||
.B type
|
||||
@@ -2903,6 +2903,10 @@ specifies what group of devices to show.
|
||||
.B up
|
||||
only display running interfaces.
|
||||
|
||||
.TP
|
||||
.B down
|
||||
only display not running interfaces.
|
||||
|
||||
.TP
|
||||
.BI master " DEVICE "
|
||||
.I DEVICE
|
||||
|
||||
@@ -36,6 +36,8 @@ ip-rule \- routing policy database management
|
||||
.IR PREFIX " ] [ "
|
||||
.B tos
|
||||
.IR TOS " ] [ "
|
||||
.B dscp
|
||||
.IR DSCP " ] [ "
|
||||
.B fwmark
|
||||
.IR FWMARK\fR[\fB/\fIMASK "] ] [ "
|
||||
.B iif
|
||||
@@ -234,6 +236,21 @@ a device.
|
||||
.BI dsfield " TOS"
|
||||
select the TOS value to match.
|
||||
|
||||
.TP
|
||||
.BI dscp " DSCP"
|
||||
select the DSCP value to match. DSCP values can be written either directly as
|
||||
numeric values (valid values are 0-63), or using symbolic names specified in
|
||||
.BR @SYSCONF_USR_DIR@/rt_dsfield " or " @SYSCONF_ETC_DIR@/rt_dsfield
|
||||
(has precedence if exists).
|
||||
However, note that the file specifies full 8-bit dsfield values, whereas
|
||||
.B ip rule
|
||||
will only use the higher six bits.
|
||||
.B ip rule show
|
||||
will similarly format DSCP values as symbolic names if possible. The
|
||||
command line option
|
||||
.B -N
|
||||
turns the show translation off.
|
||||
|
||||
.TP
|
||||
.BI fwmark " MARK"
|
||||
select the
|
||||
@@ -6,7 +6,7 @@ rdma-link \- rdma link configuration
|
||||
.ad l
|
||||
.in +8
|
||||
.ti -8
|
||||
.B devlink
|
||||
.B rdma
|
||||
.RI "[ " OPTIONS " ]"
|
||||
.B link
|
||||
.RI " { " COMMAND " | "
|
||||
|
||||
51
man/man8/rdma-monitor.8
Normal file
51
man/man8/rdma-monitor.8
Normal file
@@ -0,0 +1,51 @@
|
||||
.TH RDMA\-MONITOR 8 "22 Jul 2024" "iproute2" "Linux"
|
||||
.SH NAME
|
||||
rdma-monitor \- RDMA events monitoring
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
.ad l
|
||||
.in +8
|
||||
.ti -8
|
||||
.B rdma
|
||||
.RI "[ " OPTIONS " ]"
|
||||
.B monitor
|
||||
.RI " { " help " }"
|
||||
.sp
|
||||
|
||||
.ti -8
|
||||
.IR OPTIONS " := { "
|
||||
\fB\-V\fR[\fIersion\fR] }
|
||||
|
||||
.ti -8
|
||||
.B rdma monitor
|
||||
|
||||
.ti -8
|
||||
.B rdma monitor help
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
.SS rdma monitor - utility can monitor RDMA device events on all RDMA devices.
|
||||
.PP
|
||||
.B rdma
|
||||
opens an RDMA Netlink socket, listens on it and dumps the event info.
|
||||
|
||||
The event types supported are RDMA device registration/unregistration
|
||||
and net device attachment/detachment.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
rdma monitor
|
||||
.RS 4
|
||||
Listen for events of all RDMA devices
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR rdma (8),
|
||||
.BR rdma-link (8),
|
||||
.BR rdma-resource (8),
|
||||
.BR rdma-system (8),
|
||||
.BR rdma-statistic (8),
|
||||
.br
|
||||
|
||||
.SH AUTHOR
|
||||
Chiara Meiohas <cmeiohas@nvidia.com>
|
||||
@@ -38,8 +38,8 @@ rdma-system \- RDMA subsystem configuration
|
||||
.SS rdma system set - set RDMA subsystem network namespace mode or
|
||||
privileged qkey mode
|
||||
|
||||
.SS rdma system show - display RDMA subsystem network namespace mode and
|
||||
privileged qkey state
|
||||
.SS rdma system show - display RDMA subsystem network namespace mode,
|
||||
privileged qkey state and whether RDMA monitoring is supported.
|
||||
|
||||
.PP
|
||||
.I "NEWMODE"
|
||||
@@ -66,8 +66,8 @@ controlled QKEY or not.
|
||||
.PP
|
||||
rdma system show
|
||||
.RS 4
|
||||
Shows the state of RDMA subsystem network namespace mode on the system and
|
||||
the state of privileged qkey parameter.
|
||||
Shows the state of RDMA subsystem network namespace mode on the system,
|
||||
the state of privileged qkey parameter and whether RDMA monitor is supported.
|
||||
.RE
|
||||
.PP
|
||||
rdma system set netns exclusive
|
||||
@@ -100,6 +100,7 @@ is *not* allowed to specify a controlled QKEY.
|
||||
.BR rdma (8),
|
||||
.BR rdma-link (8),
|
||||
.BR rdma-resource (8),
|
||||
.BR rdma-monitor (8),
|
||||
.BR network_namespaces (7),
|
||||
.BR namespaces (7),
|
||||
.br
|
||||
|
||||
@@ -19,7 +19,7 @@ rdma \- RDMA tool
|
||||
|
||||
.ti -8
|
||||
.IR OBJECT " := { "
|
||||
.BR dev " | " link " | " resource " | " system " | " statistic " }"
|
||||
.BR dev " | " link " | " resource " | " system " | " statistic " | " monitor " }"
|
||||
.sp
|
||||
|
||||
.ti -8
|
||||
@@ -94,6 +94,10 @@ character.
|
||||
.B statistic
|
||||
- RDMA counter statistic related.
|
||||
|
||||
.TP
|
||||
.B monitor
|
||||
- RDMA events monitor
|
||||
|
||||
.PP
|
||||
The names of all objects may be written in full or
|
||||
abbreviated form, for example
|
||||
@@ -133,6 +137,7 @@ Exit status is 0 if command was successful or a positive integer upon failure.
|
||||
.BR rdma-resource (8),
|
||||
.BR rdma-system (8),
|
||||
.BR rdma-statistic (8),
|
||||
.BR rdma-monitor (8),
|
||||
.br
|
||||
|
||||
.SH REPORTING BUGS
|
||||
|
||||
@@ -115,14 +115,28 @@ parameters in a single schedule. Each one has the
|
||||
|
||||
sched-entry <command> <gatemask> <interval>
|
||||
|
||||
format. The only supported <command> is "S", which
|
||||
means "SetGateStates", following the IEEE 802.1Q-2018 definition
|
||||
(Table 8-7). <gate mask> is a bitmask where each bit is a associated
|
||||
with a traffic class, so bit 0 (the least significant bit) being "on"
|
||||
means that traffic class 0 is "active" for that schedule entry.
|
||||
<interval> is a time duration, in nanoseconds, that specifies for how
|
||||
long that state defined by <command> and <gate mask> should be held
|
||||
before moving to the next entry.
|
||||
format.
|
||||
|
||||
<command> support the following values:
|
||||
.br
|
||||
.I "S"
|
||||
for SetGateStates
|
||||
.br
|
||||
.I "H"
|
||||
for Set-And-Hold-MAC
|
||||
.br
|
||||
.I "R"
|
||||
for Set-And-Release-MAC
|
||||
.br
|
||||
These commands follow the IEEE 802.1Q-2018 definition (Table 8-7).
|
||||
|
||||
<gate mask> is a bitmask where each bit is associated with a traffic class, so
|
||||
bit 0 (the least significant bit) being "on" means that traffic class 0 is
|
||||
"active" for that schedule entry.
|
||||
|
||||
<interval> is a time duration, in nanoseconds, that specifies for how long that
|
||||
state defined by <command> and <gate mask> should be held before moving to
|
||||
the next entry.
|
||||
|
||||
.TP
|
||||
flags
|
||||
|
||||
@@ -50,6 +50,12 @@ vdpa-dev \- vdpa device configuration
|
||||
.B qidx
|
||||
.I QUEUE_INDEX
|
||||
|
||||
.ti -8
|
||||
.B vdpa dev set
|
||||
.B name
|
||||
.I NAME
|
||||
.B mac
|
||||
.RI "[ " MACADDR " ]"
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
.SS vdpa dev show - display vdpa device attributes
|
||||
@@ -120,6 +126,15 @@ VDPA_DEVICE_NAME
|
||||
.BI qidx " QUEUE_INDEX"
|
||||
- specifies the virtqueue index to query
|
||||
|
||||
.SS vdpa dev set - set the configuration to the vdpa device.
|
||||
|
||||
.BI name " NAME"
|
||||
-Name of the vdpa device to configure.
|
||||
|
||||
.BI mac " MACADDR"
|
||||
- specifies the mac address for the vdpa device.
|
||||
This is applicable only for the network type of vdpa device.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
vdpa dev show
|
||||
@@ -171,6 +186,11 @@ vdpa dev vstats show vdpa0 qidx 1
|
||||
.RS 4
|
||||
Shows vendor specific statistics information for vdpa device vdpa0 and virtqueue index 1
|
||||
.RE
|
||||
.PP
|
||||
vdpa dev set name vdpa0 mac 00:11:22:33:44:55
|
||||
.RS 4
|
||||
Set a specific MAC address to vdpa device vdpa0
|
||||
.RE
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR vdpa (8),
|
||||
|
||||
@@ -4,7 +4,8 @@ include ../config.mk
|
||||
CFLAGS += -I./include/uapi/
|
||||
|
||||
RDMA_OBJ = rdma.o utils.o dev.o link.o res.o res-pd.o res-mr.o res-cq.o \
|
||||
res-cmid.o res-qp.o sys.o stat.o stat-mr.o res-ctx.o res-srq.o
|
||||
res-cmid.o res-qp.o sys.o stat.o stat-mr.o res-ctx.o res-srq.o \
|
||||
monitor.o
|
||||
|
||||
TARGETS += rdma
|
||||
|
||||
|
||||
@@ -638,6 +638,8 @@ enum rdma_nl_notify_event_type {
|
||||
RDMA_UNREGISTER_EVENT,
|
||||
RDMA_NETDEV_ATTACH_EVENT,
|
||||
RDMA_NETDEV_DETACH_EVENT,
|
||||
RDMA_RENAME_EVENT,
|
||||
RDMA_NETDEV_RENAME_EVENT,
|
||||
};
|
||||
|
||||
#endif /* _RDMA_NETLINK_H */
|
||||
|
||||
209
rdma/monitor.c
Normal file
209
rdma/monitor.c
Normal file
@@ -0,0 +1,209 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
/*
|
||||
* monitor.c RDMA tool
|
||||
* Authors: Chiara Meiohas <cmeiohas@nvidia.com>
|
||||
*/
|
||||
|
||||
#include "rdma.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int mon_is_supported_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
|
||||
uint8_t *is_sup = data;
|
||||
|
||||
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
|
||||
if (tb[RDMA_NLDEV_SYS_ATTR_MONITOR_MODE])
|
||||
*is_sup = mnl_attr_get_u8(tb[RDMA_NLDEV_SYS_ATTR_MONITOR_MODE]);
|
||||
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
static int mon_is_supported(struct rd *rd, uint8_t *is_sup)
|
||||
{
|
||||
uint32_t seq;
|
||||
int ret;
|
||||
|
||||
*is_sup = 0;
|
||||
rd_prepare_msg(rd, RDMA_NLDEV_CMD_SYS_GET,
|
||||
&seq, (NLM_F_REQUEST | NLM_F_ACK));
|
||||
ret = rd_send_msg(rd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return rd_recv_msg(rd, mon_is_supported_cb, is_sup, seq);
|
||||
}
|
||||
|
||||
static void mon_print_event_type(struct nlattr **tb)
|
||||
{
|
||||
const char *const event_types_str[] = {
|
||||
[RDMA_REGISTER_EVENT] = "[REGISTER]",
|
||||
[RDMA_UNREGISTER_EVENT] = "[UNREGISTER]",
|
||||
[RDMA_NETDEV_ATTACH_EVENT] = "[NETDEV_ATTACH]",
|
||||
[RDMA_NETDEV_DETACH_EVENT] = "[NETDEV_DETACH]",
|
||||
[RDMA_RENAME_EVENT] = "[RENAME]",
|
||||
[RDMA_NETDEV_RENAME_EVENT] = "[NETDEV_RENAME]",
|
||||
};
|
||||
enum rdma_nl_notify_event_type etype;
|
||||
char unknown_type[32];
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_EVENT_TYPE])
|
||||
return;
|
||||
|
||||
etype = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_EVENT_TYPE]);
|
||||
if (etype < ARRAY_SIZE(event_types_str) && event_types_str[etype]) {
|
||||
print_string(PRINT_ANY, "event_type", "%s\t",
|
||||
event_types_str[etype]);
|
||||
} else {
|
||||
snprintf(unknown_type, sizeof(unknown_type), "[UNKNOWN 0x%02x]",
|
||||
etype);
|
||||
print_string(PRINT_ANY, "event_type", "%s\t", unknown_type);
|
||||
}
|
||||
}
|
||||
|
||||
static int mon_print_dev(struct nlattr **tb)
|
||||
{
|
||||
const char *name;
|
||||
uint32_t idx;
|
||||
|
||||
if (tb[RDMA_NLDEV_ATTR_DEV_INDEX]) {
|
||||
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
|
||||
print_uint(PRINT_ANY, "rdma_index", "dev %u", idx);
|
||||
}
|
||||
|
||||
if(tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
|
||||
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
|
||||
print_string(PRINT_ANY, "rdma_dev", " %s", name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mon_print_port_idx(struct nlattr **tb)
|
||||
{
|
||||
uint32_t port;
|
||||
|
||||
if (tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
|
||||
port = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
|
||||
print_uint(PRINT_ANY, "port", " port %u", port);
|
||||
}
|
||||
}
|
||||
|
||||
static void mon_print_netdev(struct nlattr **tb)
|
||||
{
|
||||
uint32_t netdev_idx;
|
||||
const char *name;
|
||||
|
||||
if (tb[RDMA_NLDEV_ATTR_NDEV_INDEX]) {
|
||||
netdev_idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_NDEV_INDEX]);
|
||||
print_uint(PRINT_ANY, "netdev_idx", " netdev %u", netdev_idx);
|
||||
}
|
||||
|
||||
if(tb[RDMA_NLDEV_ATTR_NDEV_NAME]) {
|
||||
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_NDEV_NAME]);
|
||||
print_string(PRINT_ANY, "netdev_name", " %s", name);
|
||||
}
|
||||
}
|
||||
|
||||
static int mon_show_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX + 1] = {};
|
||||
|
||||
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
|
||||
if (!tb[RDMA_NLDEV_ATTR_EVENT_TYPE])
|
||||
return MNL_CB_ERROR;
|
||||
|
||||
open_json_object(NULL);
|
||||
|
||||
mon_print_event_type(tb);
|
||||
mon_print_dev(tb);
|
||||
mon_print_port_idx(tb);
|
||||
mon_print_netdev(tb);
|
||||
|
||||
close_json_object();
|
||||
newline();
|
||||
fflush(stdout);
|
||||
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
static int mon_show(struct rd* rd)
|
||||
{
|
||||
unsigned int groups = 0;
|
||||
uint8_t is_sup = 0;
|
||||
int one = 1;
|
||||
char *buf;
|
||||
int err;
|
||||
|
||||
err = mon_is_supported(rd, &is_sup);
|
||||
if (err) {
|
||||
pr_err("Failed to check if RDMA monitoring is supported\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!is_sup) {
|
||||
pr_err("RDMA monitoring is not supported by the kernel\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
buf = malloc(MNL_SOCKET_BUFFER_SIZE);
|
||||
if (!buf) {
|
||||
pr_err("Buffer allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rd->nl = mnl_socket_open(NETLINK_RDMA);
|
||||
if (!rd->nl) {
|
||||
pr_err("Failed to open NETLINK_RDMA socket. Error: %s\n",
|
||||
strerror(errno));
|
||||
err = -ENODEV;
|
||||
goto err_free;
|
||||
}
|
||||
mnl_socket_setsockopt(rd->nl, NETLINK_CAP_ACK, &one, sizeof(one));
|
||||
mnl_socket_setsockopt(rd->nl, NETLINK_EXT_ACK, &one, sizeof(one));
|
||||
|
||||
groups |= nl_mgrp(RDMA_NL_GROUP_NOTIFY);
|
||||
|
||||
err = mnl_add_nl_group(rd->nl, groups);
|
||||
if (err < 0) {
|
||||
pr_err("Failed to add NETLINK_RDMA multicast group. Error: %s\n",
|
||||
strerror(errno));
|
||||
goto err_close;
|
||||
}
|
||||
new_json_obj(json);
|
||||
|
||||
err = mnlu_socket_recv_run(rd->nl, 0, buf, MNL_SOCKET_BUFFER_SIZE,
|
||||
mon_show_cb, rd);
|
||||
if (err) {
|
||||
pr_err("Failed to listen to rdma socket\n");
|
||||
goto err_free_json;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_json:
|
||||
delete_json_obj();
|
||||
err_close:
|
||||
mnl_socket_close(rd->nl);
|
||||
err_free:
|
||||
free(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mon_help(struct rd *rd)
|
||||
{
|
||||
pr_out("Usage: rdma monitor [ -j ]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_mon(struct rd *rd)
|
||||
{
|
||||
const struct rd_cmd cmds[] = {
|
||||
{ NULL, mon_show },
|
||||
{ "help", mon_help },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
return rd_exec_cmd(rd, cmds, "mon command");
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ static void help(char *name)
|
||||
{
|
||||
pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n"
|
||||
" %s [ -f[orce] ] -b[atch] filename\n"
|
||||
"where OBJECT := { dev | link | resource | system | statistic | help }\n"
|
||||
"where OBJECT := { dev | link | resource | monitor | system | statistic | help }\n"
|
||||
" OPTIONS := { -V[ersion] | -d[etails] | -j[son] | -p[retty] | -r[aw]}\n", name, name);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ static int rd_cmd(struct rd *rd, int argc, char **argv)
|
||||
{ "resource", cmd_res },
|
||||
{ "system", cmd_sys },
|
||||
{ "statistic", cmd_stat },
|
||||
{ "monitor", cmd_mon },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ int cmd_link(struct rd *rd);
|
||||
int cmd_res(struct rd *rd);
|
||||
int cmd_sys(struct rd *rd);
|
||||
int cmd_stat(struct rd *rd);
|
||||
int cmd_mon(struct rd* rd);
|
||||
int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str);
|
||||
int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd));
|
||||
int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd));
|
||||
|
||||
@@ -20,6 +20,7 @@ static const char *netns_modes_str[] = {
|
||||
static int sys_show_parse_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
|
||||
uint8_t mon_mode = 0;
|
||||
bool cof = false;
|
||||
|
||||
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
|
||||
@@ -48,6 +49,10 @@ static int sys_show_parse_cb(const struct nlmsghdr *nlh, void *data)
|
||||
|
||||
}
|
||||
|
||||
if (tb[RDMA_NLDEV_SYS_ATTR_MONITOR_MODE])
|
||||
mon_mode = mnl_attr_get_u8(tb[RDMA_NLDEV_SYS_ATTR_MONITOR_MODE]);
|
||||
print_on_off(PRINT_ANY, "monitor", "monitor %s ", mon_mode);
|
||||
|
||||
if (tb[RDMA_NLDEV_SYS_ATTR_COPY_ON_FORK])
|
||||
cof = mnl_attr_get_u8(tb[RDMA_NLDEV_SYS_ATTR_COPY_ON_FORK]);
|
||||
|
||||
@@ -77,6 +82,7 @@ static int sys_show(struct rd *rd)
|
||||
{ NULL, sys_show_no_args},
|
||||
{ "netns", sys_show_no_args},
|
||||
{ "privileged-qkey", sys_show_no_args},
|
||||
{ "monitor", sys_show_no_args},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -477,6 +477,8 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
|
||||
[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE] = MNL_TYPE_U8,
|
||||
[RDMA_NLDEV_ATTR_DEV_TYPE] = MNL_TYPE_U8,
|
||||
[RDMA_NLDEV_ATTR_PARENT_NAME] = MNL_TYPE_STRING,
|
||||
[RDMA_NLDEV_ATTR_EVENT_TYPE] = MNL_TYPE_U8,
|
||||
[RDMA_NLDEV_SYS_ATTR_MONITOR_MODE] = MNL_TYPE_U8,
|
||||
};
|
||||
|
||||
static int rd_attr_check(const struct nlattr *attr, int *typep)
|
||||
|
||||
@@ -53,6 +53,10 @@ static const char *entry_cmd_to_str(__u8 cmd)
|
||||
switch (cmd) {
|
||||
case TC_TAPRIO_CMD_SET_GATES:
|
||||
return "S";
|
||||
case TC_TAPRIO_CMD_SET_AND_HOLD:
|
||||
return "H";
|
||||
case TC_TAPRIO_CMD_SET_AND_RELEASE:
|
||||
return "R";
|
||||
default:
|
||||
return "Invalid";
|
||||
}
|
||||
@@ -62,6 +66,10 @@ static int str_to_entry_cmd(const char *str)
|
||||
{
|
||||
if (strcmp(str, "S") == 0)
|
||||
return TC_TAPRIO_CMD_SET_GATES;
|
||||
else if (strcmp(str, "H") == 0)
|
||||
return TC_TAPRIO_CMD_SET_AND_HOLD;
|
||||
else if (strcmp(str, "R") == 0)
|
||||
return TC_TAPRIO_CMD_SET_AND_RELEASE;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
1
tc/tc.c
1
tc/tc.c
@@ -31,7 +31,6 @@ int show_graph;
|
||||
int timestamp;
|
||||
|
||||
int batch_mode;
|
||||
int use_iec;
|
||||
int force;
|
||||
bool use_names;
|
||||
int json;
|
||||
|
||||
@@ -27,4 +27,3 @@ int check_size_table_opts(struct tc_sizespec *s);
|
||||
|
||||
extern int show_graph;
|
||||
extern bool use_names;
|
||||
extern int use_iec;
|
||||
|
||||
18
vdpa/vdpa.c
18
vdpa/vdpa.c
@@ -759,6 +759,22 @@ static int cmd_dev_del(struct vdpa *vdpa, int argc, char **argv)
|
||||
return mnlu_gen_socket_sndrcv(&vdpa->nlg, nlh, NULL, NULL);
|
||||
}
|
||||
|
||||
static int cmd_dev_set(struct vdpa *vdpa, int argc, char **argv)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
int err;
|
||||
|
||||
nlh = mnlu_gen_socket_cmd_prepare(&vdpa->nlg, VDPA_CMD_DEV_ATTR_SET,
|
||||
NLM_F_REQUEST | NLM_F_ACK);
|
||||
err = vdpa_argv_parse_put(nlh, vdpa, argc, argv,
|
||||
VDPA_OPT_VDEV_NAME,
|
||||
VDPA_OPT_VDEV_MAC);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return mnlu_gen_socket_sndrcv(&vdpa->nlg, nlh, NULL, NULL);
|
||||
}
|
||||
|
||||
static void pr_out_dev_net_config(struct vdpa *vdpa, struct nlattr **tb)
|
||||
{
|
||||
SPRINT_BUF(macaddr);
|
||||
@@ -1028,6 +1044,8 @@ static int cmd_dev(struct vdpa *vdpa, int argc, char **argv)
|
||||
return cmd_dev_config(vdpa, argc - 1, argv + 1);
|
||||
} else if (!strcmp(*argv, "vstats")) {
|
||||
return cmd_dev_vstats(vdpa, argc - 1, argv + 1);
|
||||
} else if (!strcmp(*argv, "set")) {
|
||||
return cmd_dev_set(vdpa, argc - 1, argv + 1);
|
||||
}
|
||||
fprintf(stderr, "Command \"%s\" not found\n", *argv);
|
||||
return -ENOENT;
|
||||
|
||||
Reference in New Issue
Block a user