Merge branch 'master' into net-next
This commit is contained in:
commit
a4b8e88d87
2
Makefile
2
Makefile
|
|
@ -49,7 +49,7 @@ WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2
|
|||
CFLAGS := $(WFLAGS) $(CCOPTS) -I../include $(DEFINES) $(CFLAGS)
|
||||
YACCFLAGS = -d -t -v
|
||||
|
||||
SUBDIRS=lib ip tc bridge misc netem genl tipc devlink man
|
||||
SUBDIRS=lib ip tc bridge misc netem genl tipc devlink rdma man
|
||||
|
||||
LIBNETLINK=../lib/libnetlink.a ../lib/libutil.a
|
||||
LDLIBS += $(LIBNETLINK)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "list.h"
|
||||
#include "mnlg.h"
|
||||
#include "json_writer.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define ESWITCH_MODE_LEGACY "legacy"
|
||||
#define ESWITCH_MODE_SWITCHDEV "switchdev"
|
||||
|
|
@ -160,7 +161,6 @@ static void ifname_map_free(struct ifname_map *ifname_map)
|
|||
free(ifname_map);
|
||||
}
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
#define DL_OPT_HANDLE BIT(0)
|
||||
#define DL_OPT_HANDLEP BIT(1)
|
||||
#define DL_OPT_PORT_TYPE BIT(2)
|
||||
|
|
@ -779,7 +779,7 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
|
|||
int err;
|
||||
|
||||
if (o_required & DL_OPT_HANDLE && o_required & DL_OPT_HANDLEP) {
|
||||
uint32_t handle_bit = handle_bit;
|
||||
uint32_t handle_bit;
|
||||
|
||||
err = dl_argv_handle_both(dl, &opts->bus_name, &opts->dev_name,
|
||||
&opts->port_index, &handle_bit);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,307 @@
|
|||
#ifndef _UAPI_RDMA_NETLINK_H
|
||||
#define _UAPI_RDMA_NETLINK_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
enum {
|
||||
RDMA_NL_RDMA_CM = 1,
|
||||
RDMA_NL_IWCM,
|
||||
RDMA_NL_RSVD,
|
||||
RDMA_NL_LS, /* RDMA Local Services */
|
||||
RDMA_NL_NLDEV, /* RDMA device interface */
|
||||
RDMA_NL_NUM_CLIENTS
|
||||
};
|
||||
|
||||
enum {
|
||||
RDMA_NL_GROUP_CM = 1,
|
||||
RDMA_NL_GROUP_IWPM,
|
||||
RDMA_NL_GROUP_LS,
|
||||
RDMA_NL_NUM_GROUPS
|
||||
};
|
||||
|
||||
#define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10)
|
||||
#define RDMA_NL_GET_OP(type) (type & ((1 << 10) - 1))
|
||||
#define RDMA_NL_GET_TYPE(client, op) ((client << 10) + op)
|
||||
|
||||
enum {
|
||||
RDMA_NL_RDMA_CM_ID_STATS = 0,
|
||||
RDMA_NL_RDMA_CM_NUM_OPS
|
||||
};
|
||||
|
||||
enum {
|
||||
RDMA_NL_RDMA_CM_ATTR_SRC_ADDR = 1,
|
||||
RDMA_NL_RDMA_CM_ATTR_DST_ADDR,
|
||||
RDMA_NL_RDMA_CM_NUM_ATTR,
|
||||
};
|
||||
|
||||
/* iwarp port mapper op-codes */
|
||||
enum {
|
||||
RDMA_NL_IWPM_REG_PID = 0,
|
||||
RDMA_NL_IWPM_ADD_MAPPING,
|
||||
RDMA_NL_IWPM_QUERY_MAPPING,
|
||||
RDMA_NL_IWPM_REMOVE_MAPPING,
|
||||
RDMA_NL_IWPM_REMOTE_INFO,
|
||||
RDMA_NL_IWPM_HANDLE_ERR,
|
||||
RDMA_NL_IWPM_MAPINFO,
|
||||
RDMA_NL_IWPM_MAPINFO_NUM,
|
||||
RDMA_NL_IWPM_NUM_OPS
|
||||
};
|
||||
|
||||
struct rdma_cm_id_stats {
|
||||
__u32 qp_num;
|
||||
__u32 bound_dev_if;
|
||||
__u32 port_space;
|
||||
__s32 pid;
|
||||
__u8 cm_state;
|
||||
__u8 node_type;
|
||||
__u8 port_num;
|
||||
__u8 qp_type;
|
||||
};
|
||||
|
||||
enum {
|
||||
IWPM_NLA_REG_PID_UNSPEC = 0,
|
||||
IWPM_NLA_REG_PID_SEQ,
|
||||
IWPM_NLA_REG_IF_NAME,
|
||||
IWPM_NLA_REG_IBDEV_NAME,
|
||||
IWPM_NLA_REG_ULIB_NAME,
|
||||
IWPM_NLA_REG_PID_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
IWPM_NLA_RREG_PID_UNSPEC = 0,
|
||||
IWPM_NLA_RREG_PID_SEQ,
|
||||
IWPM_NLA_RREG_IBDEV_NAME,
|
||||
IWPM_NLA_RREG_ULIB_NAME,
|
||||
IWPM_NLA_RREG_ULIB_VER,
|
||||
IWPM_NLA_RREG_PID_ERR,
|
||||
IWPM_NLA_RREG_PID_MAX
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
IWPM_NLA_MANAGE_MAPPING_UNSPEC = 0,
|
||||
IWPM_NLA_MANAGE_MAPPING_SEQ,
|
||||
IWPM_NLA_MANAGE_ADDR,
|
||||
IWPM_NLA_MANAGE_MAPPED_LOC_ADDR,
|
||||
IWPM_NLA_RMANAGE_MAPPING_ERR,
|
||||
IWPM_NLA_RMANAGE_MAPPING_MAX
|
||||
};
|
||||
|
||||
#define IWPM_NLA_MANAGE_MAPPING_MAX 3
|
||||
#define IWPM_NLA_QUERY_MAPPING_MAX 4
|
||||
#define IWPM_NLA_MAPINFO_SEND_MAX 3
|
||||
|
||||
enum {
|
||||
IWPM_NLA_QUERY_MAPPING_UNSPEC = 0,
|
||||
IWPM_NLA_QUERY_MAPPING_SEQ,
|
||||
IWPM_NLA_QUERY_LOCAL_ADDR,
|
||||
IWPM_NLA_QUERY_REMOTE_ADDR,
|
||||
IWPM_NLA_RQUERY_MAPPED_LOC_ADDR,
|
||||
IWPM_NLA_RQUERY_MAPPED_REM_ADDR,
|
||||
IWPM_NLA_RQUERY_MAPPING_ERR,
|
||||
IWPM_NLA_RQUERY_MAPPING_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
IWPM_NLA_MAPINFO_REQ_UNSPEC = 0,
|
||||
IWPM_NLA_MAPINFO_ULIB_NAME,
|
||||
IWPM_NLA_MAPINFO_ULIB_VER,
|
||||
IWPM_NLA_MAPINFO_REQ_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
IWPM_NLA_MAPINFO_UNSPEC = 0,
|
||||
IWPM_NLA_MAPINFO_LOCAL_ADDR,
|
||||
IWPM_NLA_MAPINFO_MAPPED_ADDR,
|
||||
IWPM_NLA_MAPINFO_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
IWPM_NLA_MAPINFO_NUM_UNSPEC = 0,
|
||||
IWPM_NLA_MAPINFO_SEQ,
|
||||
IWPM_NLA_MAPINFO_SEND_NUM,
|
||||
IWPM_NLA_MAPINFO_ACK_NUM,
|
||||
IWPM_NLA_MAPINFO_NUM_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
IWPM_NLA_ERR_UNSPEC = 0,
|
||||
IWPM_NLA_ERR_SEQ,
|
||||
IWPM_NLA_ERR_CODE,
|
||||
IWPM_NLA_ERR_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Local service operations:
|
||||
* RESOLVE - The client requests the local service to resolve a path.
|
||||
* SET_TIMEOUT - The local service requests the client to set the timeout.
|
||||
* IP_RESOLVE - The client requests the local service to resolve an IP to GID.
|
||||
*/
|
||||
enum {
|
||||
RDMA_NL_LS_OP_RESOLVE = 0,
|
||||
RDMA_NL_LS_OP_SET_TIMEOUT,
|
||||
RDMA_NL_LS_OP_IP_RESOLVE,
|
||||
RDMA_NL_LS_NUM_OPS
|
||||
};
|
||||
|
||||
/* Local service netlink message flags */
|
||||
#define RDMA_NL_LS_F_ERR 0x0100 /* Failed response */
|
||||
|
||||
/*
|
||||
* Local service resolve operation family header.
|
||||
* The layout for the resolve operation:
|
||||
* nlmsg header
|
||||
* family header
|
||||
* attributes
|
||||
*/
|
||||
|
||||
/*
|
||||
* Local service path use:
|
||||
* Specify how the path(s) will be used.
|
||||
* ALL - For connected CM operation (6 pathrecords)
|
||||
* UNIDIRECTIONAL - For unidirectional UD (1 pathrecord)
|
||||
* GMP - For miscellaneous GMP like operation (at least 1 reversible
|
||||
* pathrecord)
|
||||
*/
|
||||
enum {
|
||||
LS_RESOLVE_PATH_USE_ALL = 0,
|
||||
LS_RESOLVE_PATH_USE_UNIDIRECTIONAL,
|
||||
LS_RESOLVE_PATH_USE_GMP,
|
||||
LS_RESOLVE_PATH_USE_MAX
|
||||
};
|
||||
|
||||
#define LS_DEVICE_NAME_MAX 64
|
||||
|
||||
struct rdma_ls_resolve_header {
|
||||
__u8 device_name[LS_DEVICE_NAME_MAX];
|
||||
__u8 port_num;
|
||||
__u8 path_use;
|
||||
};
|
||||
|
||||
struct rdma_ls_ip_resolve_header {
|
||||
__u32 ifindex;
|
||||
};
|
||||
|
||||
/* Local service attribute type */
|
||||
#define RDMA_NLA_F_MANDATORY (1 << 13)
|
||||
#define RDMA_NLA_TYPE_MASK (~(NLA_F_NESTED | NLA_F_NET_BYTEORDER | \
|
||||
RDMA_NLA_F_MANDATORY))
|
||||
|
||||
/*
|
||||
* Local service attributes:
|
||||
* Attr Name Size Byte order
|
||||
* -----------------------------------------------------
|
||||
* PATH_RECORD struct ib_path_rec_data
|
||||
* TIMEOUT u32 cpu
|
||||
* SERVICE_ID u64 cpu
|
||||
* DGID u8[16] BE
|
||||
* SGID u8[16] BE
|
||||
* TCLASS u8
|
||||
* PKEY u16 cpu
|
||||
* QOS_CLASS u16 cpu
|
||||
* IPV4 u32 BE
|
||||
* IPV6 u8[16] BE
|
||||
*/
|
||||
enum {
|
||||
LS_NLA_TYPE_UNSPEC = 0,
|
||||
LS_NLA_TYPE_PATH_RECORD,
|
||||
LS_NLA_TYPE_TIMEOUT,
|
||||
LS_NLA_TYPE_SERVICE_ID,
|
||||
LS_NLA_TYPE_DGID,
|
||||
LS_NLA_TYPE_SGID,
|
||||
LS_NLA_TYPE_TCLASS,
|
||||
LS_NLA_TYPE_PKEY,
|
||||
LS_NLA_TYPE_QOS_CLASS,
|
||||
LS_NLA_TYPE_IPV4,
|
||||
LS_NLA_TYPE_IPV6,
|
||||
LS_NLA_TYPE_MAX
|
||||
};
|
||||
|
||||
/* Local service DGID/SGID attribute: big endian */
|
||||
struct rdma_nla_ls_gid {
|
||||
__u8 gid[16];
|
||||
};
|
||||
|
||||
enum rdma_nldev_command {
|
||||
RDMA_NLDEV_CMD_UNSPEC,
|
||||
|
||||
RDMA_NLDEV_CMD_GET, /* can dump */
|
||||
RDMA_NLDEV_CMD_SET,
|
||||
RDMA_NLDEV_CMD_NEW,
|
||||
RDMA_NLDEV_CMD_DEL,
|
||||
|
||||
RDMA_NLDEV_CMD_PORT_GET, /* can dump */
|
||||
RDMA_NLDEV_CMD_PORT_SET,
|
||||
RDMA_NLDEV_CMD_PORT_NEW,
|
||||
RDMA_NLDEV_CMD_PORT_DEL,
|
||||
|
||||
RDMA_NLDEV_NUM_OPS
|
||||
};
|
||||
|
||||
enum rdma_nldev_attr {
|
||||
/* don't change the order or add anything between, this is ABI! */
|
||||
RDMA_NLDEV_ATTR_UNSPEC,
|
||||
|
||||
/* Identifier for ib_device */
|
||||
RDMA_NLDEV_ATTR_DEV_INDEX, /* u32 */
|
||||
|
||||
RDMA_NLDEV_ATTR_DEV_NAME, /* string */
|
||||
/*
|
||||
* Device index together with port index are identifiers
|
||||
* for port/link properties.
|
||||
*
|
||||
* For RDMA_NLDEV_CMD_GET commamnd, port index will return number
|
||||
* of available ports in ib_device, while for port specific operations,
|
||||
* it will be real port index as it appears in sysfs. Port index follows
|
||||
* sysfs notation and starts from 1 for the first port.
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_PORT_INDEX, /* u32 */
|
||||
|
||||
/*
|
||||
* Device and port capabilities
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_CAP_FLAGS, /* u64 */
|
||||
|
||||
/*
|
||||
* FW version
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_FW_VERSION, /* string */
|
||||
|
||||
/*
|
||||
* Node GUID (in host byte order) associated with the RDMA device.
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_NODE_GUID, /* u64 */
|
||||
|
||||
/*
|
||||
* System image GUID (in host byte order) associated with
|
||||
* this RDMA device and other devices which are part of a
|
||||
* single system.
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_SYS_IMAGE_GUID, /* u64 */
|
||||
|
||||
/*
|
||||
* Subnet prefix (in host byte order)
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_SUBNET_PREFIX, /* u64 */
|
||||
|
||||
/*
|
||||
* Local Identifier (LID),
|
||||
* According to IB specification, It is 16-bit address assigned
|
||||
* by the Subnet Manager. Extended to be 32-bit for OmniPath users.
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_LID, /* u32 */
|
||||
RDMA_NLDEV_ATTR_SM_LID, /* u32 */
|
||||
|
||||
/*
|
||||
* LID mask control (LMC)
|
||||
*/
|
||||
RDMA_NLDEV_ATTR_LMC, /* u8 */
|
||||
|
||||
RDMA_NLDEV_ATTR_PORT_STATE, /* u8 */
|
||||
RDMA_NLDEV_ATTR_PORT_PHYS_STATE, /* u8 */
|
||||
|
||||
RDMA_NLDEV_ATTR_DEV_NODE_TYPE, /* u8 */
|
||||
|
||||
RDMA_NLDEV_ATTR_MAX
|
||||
};
|
||||
#endif /* _UAPI_RDMA_NETLINK_H */
|
||||
|
|
@ -196,6 +196,8 @@ static inline void __jiffies_to_tv(struct timeval *tv, unsigned long jiffies)
|
|||
int print_timestamp(FILE *fp);
|
||||
void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n);
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#define BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)]))
|
||||
|
|
|
|||
|
|
@ -202,8 +202,6 @@ static int ipntable_modify(int cmd, int flags, int argc, char **argv)
|
|||
if (get_u32(&queue, *argv, 0))
|
||||
invarg("\"queue\" value is invalid", *argv);
|
||||
|
||||
if (!parms_rta)
|
||||
parms_rta = (struct rtattr *)&parms_buf;
|
||||
rta_addattr32(parms_rta, sizeof(parms_buf),
|
||||
NDTPA_QUEUE_LEN, queue);
|
||||
parms_change = 1;
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|||
}
|
||||
if (tb[RTA_MULTIPATH]) {
|
||||
struct rtnexthop *nh = RTA_DATA(tb[RTA_MULTIPATH]);
|
||||
int first = 0;
|
||||
int first = 1;
|
||||
|
||||
len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
|
||||
|
||||
|
|
@ -634,10 +634,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|||
if (nh->rtnh_len > len)
|
||||
break;
|
||||
if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) {
|
||||
if (first)
|
||||
if (first) {
|
||||
fprintf(fp, "Oifs: ");
|
||||
else
|
||||
first = 0;
|
||||
} else {
|
||||
fprintf(fp, " ");
|
||||
}
|
||||
} else
|
||||
fprintf(fp, "%s\tnexthop ", _SL_);
|
||||
if (nh->rtnh_len > sizeof(*nh)) {
|
||||
|
|
|
|||
|
|
@ -410,10 +410,6 @@ const char *rtnl_rttable_n2a(__u32 id, char *buf, int len)
|
|||
{
|
||||
struct rtnl_hash_entry *entry;
|
||||
|
||||
if (id > RT_TABLE_MAX) {
|
||||
snprintf(buf, len, "%u", id);
|
||||
return buf;
|
||||
}
|
||||
if (!rtnl_rttable_init)
|
||||
rtnl_rttable_initialize();
|
||||
entry = rtnl_rttable_hash[id & 255];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
.TH RDMA\-DEV 8 "06 Jul 2017" "iproute2" "Linux"
|
||||
.SH NAME
|
||||
rdmak-dev \- RDMA device configuration
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
.ad l
|
||||
.in +8
|
||||
.ti -8
|
||||
.B rdma
|
||||
.RI "[ " OPTIONS " ]"
|
||||
.B dev
|
||||
.RI " { " COMMAND " | "
|
||||
.BR help " }"
|
||||
.sp
|
||||
|
||||
.ti -8
|
||||
.IR OPTIONS " := { "
|
||||
\fB\-V\fR[\fIersion\fR] |
|
||||
\fB\-d\fR[\fIetails\fR] }
|
||||
|
||||
.ti -8
|
||||
.B rdma dev show
|
||||
.RI "[ " DEV " ]"
|
||||
|
||||
.ti -8
|
||||
.B rdma dev help
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
.SS rdma dev show - display rdma device attributes
|
||||
|
||||
.PP
|
||||
.I "DEV"
|
||||
- specifies the RDMA device to show.
|
||||
If this argument is omitted all devices are listed.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
rdma dev
|
||||
.RS 4
|
||||
Shows the state of all RDMA devices on the system.
|
||||
.RE
|
||||
.PP
|
||||
rdma dev show mlx5_3
|
||||
.RS 4
|
||||
Shows the state of specified RDMA device.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR rdma (8),
|
||||
.BR rdma-link (8),
|
||||
.br
|
||||
|
||||
.SH AUTHOR
|
||||
Leon Romanovsky <leonro@mellanox.com>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
.TH RDMA\-LINK 8 "06 Jul 2017" "iproute2" "Linux"
|
||||
.SH NAME
|
||||
rdma-link \- rdma link configuration
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
.ad l
|
||||
.in +8
|
||||
.ti -8
|
||||
.B devlink
|
||||
.RI "[ " OPTIONS " ]"
|
||||
.B link
|
||||
.RI " { " COMMAND " | "
|
||||
.BR help " }"
|
||||
.sp
|
||||
|
||||
.ti -8
|
||||
.IR OPTIONS " := { "
|
||||
\fB\-V\fR[\fIersion\fR] |
|
||||
\fB\-d\fR[\fIetails\fR] }
|
||||
|
||||
.ti -8
|
||||
.B rdma link show
|
||||
.RI "[ " DEV/PORT_INDEX " ]"
|
||||
|
||||
.ti -8
|
||||
.B rdma link help
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
.SS rdma link show - display rdma link attributes
|
||||
|
||||
.PP
|
||||
.I "DEV/PORT_INDEX"
|
||||
- specifies the RDMa link to show.
|
||||
If this argument is omitted all links are listed.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
rdma link show
|
||||
.RS 4
|
||||
Shows the state of all rdma links on the system.
|
||||
.RE
|
||||
.PP
|
||||
rdma link show mlx5_2/1
|
||||
.RS 4
|
||||
Shows the state of specified rdma link.
|
||||
.RE
|
||||
.PP
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR rdma (8),
|
||||
.BR rdma-dev (8),
|
||||
.br
|
||||
|
||||
.SH AUTHOR
|
||||
Leon Romanovsky <leonro@mellanox.com>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
.TH RDMA 8 "28 Mar 2017" "iproute2" "Linux"
|
||||
.SH NAME
|
||||
rdma \- RDMA tool
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
.ad l
|
||||
.in +8
|
||||
.ti -8
|
||||
.B rdma
|
||||
.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | "
|
||||
.BR help " }"
|
||||
.sp
|
||||
|
||||
.ti -8
|
||||
.IR OBJECT " := { "
|
||||
.BR dev " | " link " }"
|
||||
.sp
|
||||
|
||||
.ti -8
|
||||
.IR OPTIONS " := { "
|
||||
\fB\-V\fR[\fIersion\fR] |
|
||||
\fB\-d\fR[\fIetails\fR] }
|
||||
\fB\-j\fR[\fIson\fR] }
|
||||
\fB\-p\fR[\fIretty\fR] }
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
.BR "\-V" , " -Version"
|
||||
Print the version of the
|
||||
.B rdma
|
||||
tool and exit.
|
||||
|
||||
.TP
|
||||
.BR "\-d" , " --details"
|
||||
Otuput detailed information.
|
||||
|
||||
.TP
|
||||
.BR "\-p" , " --pretty"
|
||||
When combined with -j generate a pretty JSON output.
|
||||
|
||||
.TP
|
||||
.BR "\-j" , " --json"
|
||||
Generate JSON output.
|
||||
|
||||
.SS
|
||||
.I OBJECT
|
||||
|
||||
.TP
|
||||
.B dev
|
||||
- RDMA device.
|
||||
|
||||
.TP
|
||||
.B link
|
||||
- RDMA port related.
|
||||
|
||||
.PP
|
||||
The names of all objects may be written in full or
|
||||
abbreviated form, for example
|
||||
.B stats
|
||||
can be abbreviated as
|
||||
.B stat
|
||||
or just
|
||||
.B s.
|
||||
|
||||
.SS
|
||||
.I COMMAND
|
||||
|
||||
Specifies the action to perform on the object.
|
||||
The set of possible actions depends on the object type.
|
||||
As a rule, it is possible to
|
||||
.B show
|
||||
(or
|
||||
.B list
|
||||
) objects, but some objects do not allow all of these operations
|
||||
or have some additional commands. The
|
||||
.B help
|
||||
command is available for all objects. It prints
|
||||
out a list of available commands and argument syntax conventions.
|
||||
.sp
|
||||
If no command is given, some default command is assumed.
|
||||
Usually it is
|
||||
.B list
|
||||
or, if the objects of this class cannot be listed,
|
||||
.BR "help" .
|
||||
|
||||
.SH EXIT STATUS
|
||||
Exit status is 0 if command was successful or a positive integer upon failure.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR rdma-dev (8),
|
||||
.BR rdma-link (8),
|
||||
.br
|
||||
|
||||
.SH REPORTING BUGS
|
||||
Report any bugs to the Linux RDMA mailing list
|
||||
.B <linux-rdma@vger.kernel.org>
|
||||
where the development and maintenance is primarily done.
|
||||
You do not have to be subscribed to the list to send a message there.
|
||||
|
||||
.SH AUTHOR
|
||||
Leon Romanovsky <leonro@mellanox.com>
|
||||
|
|
@ -1440,7 +1440,6 @@ static int remember_he(struct aafilter *a, struct hostent *he)
|
|||
if ((b = malloc(sizeof(*b))) == NULL)
|
||||
return cnt;
|
||||
*b = *a;
|
||||
b->next = a->next;
|
||||
a->next = b;
|
||||
}
|
||||
memcpy(b->addr.data, *ptr, len);
|
||||
|
|
@ -1671,7 +1670,7 @@ void *parse_hostcond(char *addr, bool is_port)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!is_port && addr && *addr && *addr != '*') {
|
||||
if (!is_port && *addr && *addr != '*') {
|
||||
if (get_prefix_1(&a.addr, addr, fam)) {
|
||||
if (get_dns_host(&a, addr, fam)) {
|
||||
fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", addr);
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
rdma
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
include ../Config
|
||||
|
||||
ifeq ($(HAVE_MNL),y)
|
||||
|
||||
RDMA_OBJ = rdma.o utils.o dev.o link.o
|
||||
|
||||
TARGETS=rdma
|
||||
CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
|
||||
LDLIBS += $(shell $(PKG_CONFIG) libmnl --libs)
|
||||
|
||||
endif
|
||||
|
||||
all: $(TARGETS) $(LIBS)
|
||||
|
||||
rdma: $(RDMA_OBJ) $(LIBS)
|
||||
$(QUIET_LINK)$(CC) $^ $(LDFLAGS) $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
install -m 0755 $(TARGETS) $(DESTDIR)$(SBINDIR)
|
||||
|
||||
clean:
|
||||
rm -f $(RDMA_OBJ) $(TARGETS)
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* dev.c RDMA tool
|
||||
*
|
||||
* 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: Leon Romanovsky <leonro@mellanox.com>
|
||||
*/
|
||||
|
||||
#include "rdma.h"
|
||||
|
||||
static int dev_help(struct rd *rd)
|
||||
{
|
||||
pr_out("Usage: %s dev show [DEV]\n", rd->filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *dev_caps_to_str(uint32_t idx)
|
||||
{
|
||||
#define RDMA_DEV_FLAGS(x) \
|
||||
x(RESIZE_MAX_WR, 0) \
|
||||
x(BAD_PKEY_CNTR, 1) \
|
||||
x(BAD_QKEY_CNTR, 2) \
|
||||
x(RAW_MULTI, 3) \
|
||||
x(AUTO_PATH_MIG, 4) \
|
||||
x(CHANGE_PHY_PORT, 5) \
|
||||
x(UD_AV_PORT_ENFORCE_PORT_ENFORCE, 6) \
|
||||
x(CURR_QP_STATE_MOD, 7) \
|
||||
x(SHUTDOWN_PORT, 8) \
|
||||
x(INIT_TYPE, 9) \
|
||||
x(PORT_ACTIVE_EVENT, 10) \
|
||||
x(SYS_IMAGE_GUID, 11) \
|
||||
x(RC_RNR_NAK_GEN, 12) \
|
||||
x(SRQ_RESIZE, 13) \
|
||||
x(N_NOTIFY_CQ, 14) \
|
||||
x(LOCAL_DMA_LKEY, 15) \
|
||||
x(MEM_WINDOW, 17) \
|
||||
x(UD_IP_CSUM, 18) \
|
||||
x(UD_TSO, 19) \
|
||||
x(XRC, 20) \
|
||||
x(MEM_MGT_EXTENSIONS, 21) \
|
||||
x(BLOCK_MULTICAST_LOOPBACK, 22) \
|
||||
x(MEM_WINDOW_TYPE_2A, 23) \
|
||||
x(MEM_WINDOW_TYPE_2B, 24) \
|
||||
x(RC_IP_CSUM, 25) \
|
||||
x(RAW_IP_CSUM, 26) \
|
||||
x(CROSS_CHANNEL, 27) \
|
||||
x(MANAGED_FLOW_STEERING, 29) \
|
||||
x(SIGNATURE_HANDOVER, 30) \
|
||||
x(ON_DEMAND_PAGING, 31) \
|
||||
x(SG_GAPS_REG, 32) \
|
||||
x(VIRTUAL_FUNCTION, 33) \
|
||||
x(RAW_SCATTER_FCS, 34) \
|
||||
x(RDMA_NETDEV_OPA_VNIC, 35)
|
||||
|
||||
enum { RDMA_DEV_FLAGS(RDMA_BITMAP_ENUM) };
|
||||
|
||||
static const char * const
|
||||
rdma_dev_names[] = { RDMA_DEV_FLAGS(RDMA_BITMAP_NAMES) };
|
||||
#undef RDMA_DEV_FLAGS
|
||||
|
||||
if (idx < ARRAY_SIZE(rdma_dev_names) && rdma_dev_names[idx])
|
||||
return rdma_dev_names[idx];
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
static void dev_print_caps(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint64_t caps;
|
||||
uint32_t idx;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
|
||||
return;
|
||||
|
||||
caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
|
||||
|
||||
if (rd->json_output) {
|
||||
jsonw_name(rd->jw, "caps");
|
||||
jsonw_start_array(rd->jw);
|
||||
} else {
|
||||
pr_out("\n caps: <");
|
||||
}
|
||||
for (idx = 0; caps; idx++) {
|
||||
if (caps & 0x1) {
|
||||
if (rd->json_output) {
|
||||
jsonw_string(rd->jw, dev_caps_to_str(idx));
|
||||
} else {
|
||||
pr_out("%s", dev_caps_to_str(idx));
|
||||
if (caps >> 0x1)
|
||||
pr_out(", ");
|
||||
}
|
||||
}
|
||||
caps >>= 0x1;
|
||||
}
|
||||
|
||||
if (rd->json_output)
|
||||
jsonw_end_array(rd->jw);
|
||||
else
|
||||
pr_out(">");
|
||||
}
|
||||
|
||||
static void dev_print_fw(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
const char *str;
|
||||
if (!tb[RDMA_NLDEV_ATTR_FW_VERSION])
|
||||
return;
|
||||
|
||||
str = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_FW_VERSION]);
|
||||
if (rd->json_output)
|
||||
jsonw_string_field(rd->jw, "fw", str);
|
||||
else
|
||||
pr_out("fw %s ", str);
|
||||
}
|
||||
|
||||
static void dev_print_node_guid(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint64_t node_guid;
|
||||
uint16_t vp[4];
|
||||
char str[32];
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_NODE_GUID])
|
||||
return;
|
||||
|
||||
node_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_NODE_GUID]);
|
||||
memcpy(vp, &node_guid, sizeof(uint64_t));
|
||||
snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
|
||||
if (rd->json_output)
|
||||
jsonw_string_field(rd->jw, "node_guid", str);
|
||||
else
|
||||
pr_out("node_guid %s ", str);
|
||||
}
|
||||
|
||||
static void dev_print_sys_image_guid(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint64_t sys_image_guid;
|
||||
uint16_t vp[4];
|
||||
char str[32];
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID])
|
||||
return;
|
||||
|
||||
sys_image_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID]);
|
||||
memcpy(vp, &sys_image_guid, sizeof(uint64_t));
|
||||
snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
|
||||
if (rd->json_output)
|
||||
jsonw_string_field(rd->jw, "sys_image_guid", str);
|
||||
else
|
||||
pr_out("sys_image_guid %s ", str);
|
||||
}
|
||||
|
||||
static const char *node_type_to_str(uint8_t node_type)
|
||||
{
|
||||
static const char * const node_type_str[] = { "unknown", "ca",
|
||||
"switch", "router",
|
||||
"rnic", "usnic",
|
||||
"usnic_dp" };
|
||||
if (node_type < ARRAY_SIZE(node_type_str))
|
||||
return node_type_str[node_type];
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void dev_print_node_type(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
const char *node_str;
|
||||
uint8_t node_type;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE])
|
||||
return;
|
||||
|
||||
node_type = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE]);
|
||||
node_str = node_type_to_str(node_type);
|
||||
if (rd->json_output)
|
||||
jsonw_string_field(rd->jw, "node_type", node_str);
|
||||
else
|
||||
pr_out("node_type %s ", node_str);
|
||||
}
|
||||
|
||||
static int dev_parse_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
|
||||
struct rd *rd = data;
|
||||
const char *name;
|
||||
uint32_t idx;
|
||||
|
||||
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
|
||||
if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
|
||||
return MNL_CB_ERROR;
|
||||
|
||||
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
|
||||
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
|
||||
if (rd->json_output) {
|
||||
jsonw_uint_field(rd->jw, "ifindex", idx);
|
||||
jsonw_string_field(rd->jw, "ifname", name);
|
||||
} else {
|
||||
pr_out("%u: %s: ", idx, name);
|
||||
}
|
||||
|
||||
dev_print_node_type(rd, tb);
|
||||
dev_print_fw(rd, tb);
|
||||
dev_print_node_guid(rd, tb);
|
||||
dev_print_sys_image_guid(rd, tb);
|
||||
if (rd->show_details)
|
||||
dev_print_caps(rd, tb);
|
||||
|
||||
if (!rd->json_output)
|
||||
pr_out("\n");
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
static int dev_no_args(struct rd *rd)
|
||||
{
|
||||
uint32_t seq;
|
||||
int ret;
|
||||
|
||||
rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET,
|
||||
&seq, (NLM_F_REQUEST | NLM_F_ACK));
|
||||
mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
|
||||
ret = rd_send_msg(rd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rd->json_output)
|
||||
jsonw_start_object(rd->jw);
|
||||
ret = rd_recv_msg(rd, dev_parse_cb, rd, seq);
|
||||
if (rd->json_output)
|
||||
jsonw_end_object(rd->jw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dev_one_show(struct rd *rd)
|
||||
{
|
||||
const struct rd_cmd cmds[] = {
|
||||
{ NULL, dev_no_args},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
return rd_exec_cmd(rd, cmds, "parameter");
|
||||
}
|
||||
|
||||
static int dev_show(struct rd *rd)
|
||||
{
|
||||
struct dev_map *dev_map;
|
||||
int ret = 0;
|
||||
|
||||
if (rd->json_output)
|
||||
jsonw_start_array(rd->jw);
|
||||
if (rd_no_arg(rd)) {
|
||||
list_for_each_entry(dev_map, &rd->dev_map_list, list) {
|
||||
rd->dev_idx = dev_map->idx;
|
||||
ret = dev_one_show(rd);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
dev_map = dev_map_lookup(rd, false);
|
||||
if (!dev_map) {
|
||||
pr_err("Wrong device name\n");
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
rd_arg_inc(rd);
|
||||
rd->dev_idx = dev_map->idx;
|
||||
ret = dev_one_show(rd);
|
||||
}
|
||||
out:
|
||||
if (rd->json_output)
|
||||
jsonw_end_array(rd->jw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cmd_dev(struct rd *rd)
|
||||
{
|
||||
const struct rd_cmd cmds[] = {
|
||||
{ NULL, dev_show },
|
||||
{ "show", dev_show },
|
||||
{ "list", dev_show },
|
||||
{ "help", dev_help },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
return rd_exec_cmd(rd, cmds, "dev command");
|
||||
}
|
||||
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* link.c RDMA tool
|
||||
*
|
||||
* 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: Leon Romanovsky <leonro@mellanox.com>
|
||||
*/
|
||||
|
||||
#include "rdma.h"
|
||||
|
||||
static int link_help(struct rd *rd)
|
||||
{
|
||||
pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *caps_to_str(uint32_t idx)
|
||||
{
|
||||
#define RDMA_PORT_FLAGS(x) \
|
||||
x(SM, 1) \
|
||||
x(NOTICE, 2) \
|
||||
x(TRAP, 3) \
|
||||
x(OPT_IPD, 4) \
|
||||
x(AUTO_MIGR, 5) \
|
||||
x(SL_MAP, 6) \
|
||||
x(MKEY_NVRAM, 7) \
|
||||
x(PKEY_NVRAM, 8) \
|
||||
x(LED_INFO, 9) \
|
||||
x(SM_DISABLED, 10) \
|
||||
x(SYS_IMAGE_GUIG, 11) \
|
||||
x(PKEY_SW_EXT_PORT_TRAP, 12) \
|
||||
x(EXTENDED_SPEEDS, 14) \
|
||||
x(CM, 16) \
|
||||
x(SNMP_TUNNEL, 17) \
|
||||
x(REINIT, 18) \
|
||||
x(DEVICE_MGMT, 19) \
|
||||
x(VENDOR_CLASS, 20) \
|
||||
x(DR_NOTICE, 21) \
|
||||
x(CAP_MASK_NOTICE, 22) \
|
||||
x(BOOT_MGMT, 23) \
|
||||
x(LINK_LATENCY, 24) \
|
||||
x(CLIENT_REG, 23) \
|
||||
x(IP_BASED_GIDS, 26)
|
||||
|
||||
enum { RDMA_PORT_FLAGS(RDMA_BITMAP_ENUM) };
|
||||
|
||||
static const char * const
|
||||
rdma_port_names[] = { RDMA_PORT_FLAGS(RDMA_BITMAP_NAMES) };
|
||||
#undef RDMA_PORT_FLAGS
|
||||
|
||||
if (idx < ARRAY_SIZE(rdma_port_names) && rdma_port_names[idx])
|
||||
return rdma_port_names[idx];
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
static void link_print_caps(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint64_t caps;
|
||||
uint32_t idx;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
|
||||
return;
|
||||
|
||||
caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
|
||||
|
||||
if (rd->json_output) {
|
||||
jsonw_name(rd->jw, "caps");
|
||||
jsonw_start_array(rd->jw);
|
||||
} else {
|
||||
pr_out("\n caps: <");
|
||||
}
|
||||
for (idx = 0; caps; idx++) {
|
||||
if (caps & 0x1) {
|
||||
if (rd->json_output) {
|
||||
jsonw_string(rd->jw, caps_to_str(idx));
|
||||
} else {
|
||||
pr_out("%s", caps_to_str(idx));
|
||||
if (caps >> 0x1)
|
||||
pr_out(", ");
|
||||
}
|
||||
}
|
||||
caps >>= 0x1;
|
||||
}
|
||||
|
||||
if (rd->json_output)
|
||||
jsonw_end_array(rd->jw);
|
||||
else
|
||||
pr_out(">");
|
||||
}
|
||||
|
||||
static void link_print_subnet_prefix(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint64_t subnet_prefix;
|
||||
uint16_t vp[4];
|
||||
char str[32];
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX])
|
||||
return;
|
||||
|
||||
subnet_prefix = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX]);
|
||||
memcpy(vp, &subnet_prefix, sizeof(uint64_t));
|
||||
snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
|
||||
if (rd->json_output)
|
||||
jsonw_string_field(rd->jw, "subnet_prefix", str);
|
||||
else
|
||||
pr_out("subnet_prefix %s ", str);
|
||||
}
|
||||
|
||||
static void link_print_lid(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint32_t lid;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_LID])
|
||||
return;
|
||||
|
||||
lid = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_LID]);
|
||||
if (rd->json_output)
|
||||
jsonw_uint_field(rd->jw, "lid", lid);
|
||||
else
|
||||
pr_out("lid %u ", lid);
|
||||
}
|
||||
|
||||
static void link_print_sm_lid(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint32_t sm_lid;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_SM_LID])
|
||||
return;
|
||||
|
||||
sm_lid = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_SM_LID]);
|
||||
if (rd->json_output)
|
||||
jsonw_uint_field(rd->jw, "sm_lid", sm_lid);
|
||||
else
|
||||
pr_out("sm_lid %u ", sm_lid);
|
||||
}
|
||||
|
||||
static void link_print_lmc(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint8_t lmc;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_LMC])
|
||||
return;
|
||||
|
||||
lmc = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_LMC]);
|
||||
if (rd->json_output)
|
||||
jsonw_uint_field(rd->jw, "lmc", lmc);
|
||||
else
|
||||
pr_out("lmc %u ", lmc);
|
||||
}
|
||||
|
||||
static const char *link_state_to_str(uint8_t link_state)
|
||||
{
|
||||
static const char * const link_state_str[] = { "NOP", "DOWN",
|
||||
"INIT", "ARMED",
|
||||
"ACTIVE",
|
||||
"ACTIVE_DEFER" };
|
||||
if (link_state < ARRAY_SIZE(link_state_str))
|
||||
return link_state_str[link_state];
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
static void link_print_state(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint8_t state;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_PORT_STATE])
|
||||
return;
|
||||
|
||||
state = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_PORT_STATE]);
|
||||
if (rd->json_output)
|
||||
jsonw_string_field(rd->jw, "state", link_state_to_str(state));
|
||||
else
|
||||
pr_out("state %s ", link_state_to_str(state));
|
||||
}
|
||||
|
||||
static const char *phys_state_to_str(uint8_t phys_state)
|
||||
{
|
||||
static const char * const phys_state_str[] = { "NOP", "SLEEP",
|
||||
"POLLING", "DISABLED",
|
||||
"ARMED", "LINK_UP",
|
||||
"LINK_ERROR_RECOVER",
|
||||
"PHY_TEST", "UNKNOWN",
|
||||
"OPA_OFFLINE",
|
||||
"UNKNOWN", "OPA_TEST" };
|
||||
if (phys_state < ARRAY_SIZE(phys_state_str))
|
||||
return phys_state_str[phys_state];
|
||||
return "UNKNOWN";
|
||||
};
|
||||
|
||||
static void link_print_phys_state(struct rd *rd, struct nlattr **tb)
|
||||
{
|
||||
uint8_t phys_state;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_PORT_PHYS_STATE])
|
||||
return;
|
||||
|
||||
phys_state = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_PORT_PHYS_STATE]);
|
||||
if (rd->json_output)
|
||||
jsonw_string_field(rd->jw, "physical_state",
|
||||
phys_state_to_str(phys_state));
|
||||
else
|
||||
pr_out("physical_state %s ", phys_state_to_str(phys_state));
|
||||
}
|
||||
|
||||
static int link_parse_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
|
||||
struct rd *rd = data;
|
||||
uint32_t port, idx;
|
||||
char name[32];
|
||||
|
||||
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
|
||||
if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
|
||||
return MNL_CB_ERROR;
|
||||
|
||||
if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
|
||||
pr_err("This tool doesn't support switches yet\n");
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
|
||||
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
|
||||
port = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
|
||||
snprintf(name, 32, "%s/%u",
|
||||
mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]), port);
|
||||
|
||||
if (rd->json_output) {
|
||||
jsonw_uint_field(rd->jw, "ifindex", idx);
|
||||
jsonw_uint_field(rd->jw, "port", port);
|
||||
jsonw_string_field(rd->jw, "ifname", name);
|
||||
|
||||
} else {
|
||||
pr_out("%u/%u: %s: ", idx, port, name);
|
||||
}
|
||||
|
||||
link_print_subnet_prefix(rd, tb);
|
||||
link_print_lid(rd, tb);
|
||||
link_print_sm_lid(rd, tb);
|
||||
link_print_lmc(rd, tb);
|
||||
link_print_state(rd, tb);
|
||||
link_print_phys_state(rd, tb);
|
||||
if (rd->show_details)
|
||||
link_print_caps(rd, tb);
|
||||
|
||||
if (!rd->json_output)
|
||||
pr_out("\n");
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
static int link_no_args(struct rd *rd)
|
||||
{
|
||||
uint32_t seq;
|
||||
int ret;
|
||||
|
||||
rd_prepare_msg(rd, RDMA_NLDEV_CMD_PORT_GET, &seq,
|
||||
(NLM_F_REQUEST | NLM_F_ACK));
|
||||
mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
|
||||
mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx);
|
||||
ret = rd_send_msg(rd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rd->json_output)
|
||||
jsonw_start_object(rd->jw);
|
||||
ret = rd_recv_msg(rd, link_parse_cb, rd, seq);
|
||||
if (rd->json_output)
|
||||
jsonw_end_object(rd->jw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int link_one_show(struct rd *rd)
|
||||
{
|
||||
const struct rd_cmd cmds[] = {
|
||||
{ NULL, link_no_args},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
return rd_exec_cmd(rd, cmds, "parameter");
|
||||
}
|
||||
|
||||
static int link_show(struct rd *rd)
|
||||
{
|
||||
struct dev_map *dev_map;
|
||||
uint32_t port;
|
||||
int ret = 0;
|
||||
|
||||
if (rd->json_output)
|
||||
jsonw_start_array(rd->jw);
|
||||
if (rd_no_arg(rd)) {
|
||||
list_for_each_entry(dev_map, &rd->dev_map_list, list) {
|
||||
rd->dev_idx = dev_map->idx;
|
||||
for (port = 1; port < dev_map->num_ports + 1; port++) {
|
||||
rd->port_idx = port;
|
||||
ret = link_one_show(rd);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
dev_map = dev_map_lookup(rd, true);
|
||||
port = get_port_from_argv(rd);
|
||||
if (!dev_map || port > dev_map->num_ports) {
|
||||
pr_err("Wrong device name\n");
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
rd_arg_inc(rd);
|
||||
rd->dev_idx = dev_map->idx;
|
||||
rd->port_idx = port ? : 1;
|
||||
for (; rd->port_idx < dev_map->num_ports + 1; rd->port_idx++) {
|
||||
ret = link_one_show(rd);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (port)
|
||||
/*
|
||||
* We got request to show link for devname
|
||||
* with port index.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (rd->json_output)
|
||||
jsonw_end_array(rd->jw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cmd_link(struct rd *rd)
|
||||
{
|
||||
const struct rd_cmd cmds[] = {
|
||||
{ NULL, link_show },
|
||||
{ "show", link_show },
|
||||
{ "list", link_show },
|
||||
{ "help", link_help },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
return rd_exec_cmd(rd, cmds, "link command");
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* rdma.c RDMA tool
|
||||
*
|
||||
* 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: Leon Romanovsky <leonro@mellanox.com>
|
||||
*/
|
||||
|
||||
#include "rdma.h"
|
||||
#include "SNAPSHOT.h"
|
||||
|
||||
static void help(char *name)
|
||||
{
|
||||
pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n"
|
||||
"where OBJECT := { dev | link | help }\n"
|
||||
" OPTIONS := { -V[ersion] | -d[etails] | -j[son] | -p[retty]}\n", name);
|
||||
}
|
||||
|
||||
static int cmd_help(struct rd *rd)
|
||||
{
|
||||
help(rd->filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rd_cmd(struct rd *rd)
|
||||
{
|
||||
const struct rd_cmd cmds[] = {
|
||||
{ NULL, cmd_help },
|
||||
{ "help", cmd_help },
|
||||
{ "dev", cmd_dev },
|
||||
{ "link", cmd_link },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
return rd_exec_cmd(rd, cmds, "object");
|
||||
}
|
||||
|
||||
static int rd_init(struct rd *rd, int argc, char **argv, char *filename)
|
||||
{
|
||||
uint32_t seq;
|
||||
int ret;
|
||||
|
||||
rd->filename = filename;
|
||||
rd->argc = argc;
|
||||
rd->argv = argv;
|
||||
INIT_LIST_HEAD(&rd->dev_map_list);
|
||||
|
||||
if (rd->json_output) {
|
||||
rd->jw = jsonw_new(stdout);
|
||||
if (!rd->jw) {
|
||||
pr_err("Failed to create JSON writer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
jsonw_pretty(rd->jw, rd->pretty_output);
|
||||
}
|
||||
|
||||
rd->buff = malloc(MNL_SOCKET_BUFFER_SIZE);
|
||||
if (!rd->buff)
|
||||
return -ENOMEM;
|
||||
|
||||
rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET,
|
||||
&seq, (NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP));
|
||||
ret = rd_send_msg(rd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return rd_recv_msg(rd, rd_dev_init_cb, rd, seq);
|
||||
}
|
||||
|
||||
static void rd_free(struct rd *rd)
|
||||
{
|
||||
if (rd->json_output)
|
||||
jsonw_destroy(&rd->jw);
|
||||
free(rd->buff);
|
||||
rd_free_devmap(rd);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static const struct option long_options[] = {
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "json", no_argument, NULL, 'j' },
|
||||
{ "pretty", no_argument, NULL, 'p' },
|
||||
{ "details", no_argument, NULL, 'd' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
bool pretty_output = false;
|
||||
bool show_details = false;
|
||||
bool json_output = false;
|
||||
char *filename;
|
||||
struct rd rd;
|
||||
int opt;
|
||||
int err;
|
||||
|
||||
filename = basename(argv[0]);
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "Vhdpj",
|
||||
long_options, NULL)) >= 0) {
|
||||
switch (opt) {
|
||||
case 'V':
|
||||
printf("%s utility, iproute2-ss%s\n",
|
||||
filename, SNAPSHOT);
|
||||
return EXIT_SUCCESS;
|
||||
case 'p':
|
||||
pretty_output = true;
|
||||
break;
|
||||
case 'd':
|
||||
show_details = true;
|
||||
break;
|
||||
case 'j':
|
||||
json_output = true;
|
||||
break;
|
||||
case 'h':
|
||||
help(filename);
|
||||
return EXIT_SUCCESS;
|
||||
default:
|
||||
pr_err("Unknown option.\n");
|
||||
help(filename);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
rd.show_details = show_details;
|
||||
rd.json_output = json_output;
|
||||
rd.pretty_output = pretty_output;
|
||||
|
||||
err = rd_init(&rd, argc, argv, filename);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = rd_cmd(&rd);
|
||||
out:
|
||||
/* Always cleanup */
|
||||
rd_free(&rd);
|
||||
return err ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* rdma.c RDMA tool
|
||||
*
|
||||
* 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: Leon Romanovsky <leonro@mellanox.com>
|
||||
*/
|
||||
#ifndef _RDMA_TOOL_H_
|
||||
#define _RDMA_TOOL_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <rdma/rdma_netlink.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "utils.h"
|
||||
#include "json_writer.h"
|
||||
|
||||
#define pr_err(args...) fprintf(stderr, ##args)
|
||||
#define pr_out(args...) fprintf(stdout, ##args)
|
||||
|
||||
#define RDMA_BITMAP_ENUM(name, bit_no) RDMA_BITMAP_##name = BIT(bit_no),
|
||||
#define RDMA_BITMAP_NAMES(name, bit_no) [bit_no] = #name,
|
||||
|
||||
struct dev_map {
|
||||
struct list_head list;
|
||||
char *dev_name;
|
||||
uint32_t num_ports;
|
||||
uint32_t idx;
|
||||
};
|
||||
|
||||
struct rd {
|
||||
int argc;
|
||||
char **argv;
|
||||
char *filename;
|
||||
bool show_details;
|
||||
struct list_head dev_map_list;
|
||||
uint32_t dev_idx;
|
||||
uint32_t port_idx;
|
||||
struct mnl_socket *nl;
|
||||
struct nlmsghdr *nlh;
|
||||
char *buff;
|
||||
json_writer_t *jw;
|
||||
bool json_output;
|
||||
bool pretty_output;
|
||||
};
|
||||
|
||||
struct rd_cmd {
|
||||
const char *cmd;
|
||||
int (*func)(struct rd *rd);
|
||||
};
|
||||
|
||||
/*
|
||||
* Parser interface
|
||||
*/
|
||||
bool rd_no_arg(struct rd *rd);
|
||||
void rd_arg_inc(struct rd *rd);
|
||||
|
||||
char *rd_argv(struct rd *rd);
|
||||
uint32_t get_port_from_argv(struct rd *rd);
|
||||
|
||||
/*
|
||||
* Commands interface
|
||||
*/
|
||||
int cmd_dev(struct rd *rd);
|
||||
int cmd_link(struct rd *rd);
|
||||
int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str);
|
||||
|
||||
/*
|
||||
* Device manipulation
|
||||
*/
|
||||
void rd_free_devmap(struct rd *rd);
|
||||
struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index);
|
||||
struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name);
|
||||
|
||||
/*
|
||||
* Netlink
|
||||
*/
|
||||
int rd_send_msg(struct rd *rd);
|
||||
int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, uint32_t seq);
|
||||
void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags);
|
||||
int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data);
|
||||
int rd_attr_cb(const struct nlattr *attr, void *data);
|
||||
#endif /* _RDMA_TOOL_H_ */
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* utils.c RDMA tool
|
||||
*
|
||||
* 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: Leon Romanovsky <leonro@mellanox.com>
|
||||
*/
|
||||
|
||||
#include "rdma.h"
|
||||
|
||||
static int rd_argc(struct rd *rd)
|
||||
{
|
||||
return rd->argc;
|
||||
}
|
||||
|
||||
char *rd_argv(struct rd *rd)
|
||||
{
|
||||
if (!rd_argc(rd))
|
||||
return NULL;
|
||||
return *rd->argv;
|
||||
}
|
||||
|
||||
static int strcmpx(const char *str1, const char *str2)
|
||||
{
|
||||
if (strlen(str1) > strlen(str2))
|
||||
return -1;
|
||||
return strncmp(str1, str2, strlen(str1));
|
||||
}
|
||||
|
||||
static bool rd_argv_match(struct rd *rd, const char *pattern)
|
||||
{
|
||||
if (!rd_argc(rd))
|
||||
return false;
|
||||
return strcmpx(rd_argv(rd), pattern) == 0;
|
||||
}
|
||||
|
||||
void rd_arg_inc(struct rd *rd)
|
||||
{
|
||||
if (!rd_argc(rd))
|
||||
return;
|
||||
rd->argc--;
|
||||
rd->argv++;
|
||||
}
|
||||
|
||||
bool rd_no_arg(struct rd *rd)
|
||||
{
|
||||
return rd_argc(rd) == 0;
|
||||
}
|
||||
|
||||
uint32_t get_port_from_argv(struct rd *rd)
|
||||
{
|
||||
char *slash;
|
||||
|
||||
slash = strchr(rd_argv(rd), '/');
|
||||
/* if no port found, return 0 */
|
||||
return slash ? atoi(slash + 1) : 0;
|
||||
}
|
||||
|
||||
static struct dev_map *dev_map_alloc(const char *dev_name)
|
||||
{
|
||||
struct dev_map *dev_map;
|
||||
|
||||
dev_map = calloc(1, sizeof(*dev_map));
|
||||
if (!dev_map)
|
||||
return NULL;
|
||||
dev_map->dev_name = strdup(dev_name);
|
||||
|
||||
return dev_map;
|
||||
}
|
||||
|
||||
static void dev_map_free(struct dev_map *dev_map)
|
||||
{
|
||||
if (!dev_map)
|
||||
return;
|
||||
|
||||
free(dev_map->dev_name);
|
||||
free(dev_map);
|
||||
}
|
||||
|
||||
static void dev_map_cleanup(struct rd *rd)
|
||||
{
|
||||
struct dev_map *dev_map, *tmp;
|
||||
|
||||
list_for_each_entry_safe(dev_map, tmp,
|
||||
&rd->dev_map_list, list) {
|
||||
list_del(&dev_map->list);
|
||||
dev_map_free(dev_map);
|
||||
}
|
||||
}
|
||||
|
||||
static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
|
||||
[RDMA_NLDEV_ATTR_DEV_INDEX] = MNL_TYPE_U32,
|
||||
[RDMA_NLDEV_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING,
|
||||
[RDMA_NLDEV_ATTR_PORT_INDEX] = MNL_TYPE_U32,
|
||||
[RDMA_NLDEV_ATTR_CAP_FLAGS] = MNL_TYPE_U64,
|
||||
[RDMA_NLDEV_ATTR_FW_VERSION] = MNL_TYPE_NUL_STRING,
|
||||
[RDMA_NLDEV_ATTR_NODE_GUID] = MNL_TYPE_U64,
|
||||
[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID] = MNL_TYPE_U64,
|
||||
[RDMA_NLDEV_ATTR_LID] = MNL_TYPE_U32,
|
||||
[RDMA_NLDEV_ATTR_SM_LID] = MNL_TYPE_U32,
|
||||
[RDMA_NLDEV_ATTR_LMC] = MNL_TYPE_U8,
|
||||
[RDMA_NLDEV_ATTR_PORT_STATE] = MNL_TYPE_U8,
|
||||
[RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = MNL_TYPE_U8,
|
||||
[RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = MNL_TYPE_U8,
|
||||
};
|
||||
|
||||
int rd_attr_cb(const struct nlattr *attr, void *data)
|
||||
{
|
||||
const struct nlattr **tb = data;
|
||||
int type;
|
||||
|
||||
if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX) < 0)
|
||||
return MNL_CB_ERROR;
|
||||
|
||||
type = mnl_attr_get_type(attr);
|
||||
|
||||
if (mnl_attr_validate(attr, nldev_policy[type]) < 0)
|
||||
return MNL_CB_ERROR;
|
||||
|
||||
tb[type] = attr;
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
|
||||
struct dev_map *dev_map;
|
||||
struct rd *rd = data;
|
||||
const char *dev_name;
|
||||
|
||||
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
|
||||
if (!tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
|
||||
return MNL_CB_ERROR;
|
||||
if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
|
||||
pr_err("This tool doesn't support switches yet\n");
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
|
||||
dev_name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
|
||||
|
||||
dev_map = dev_map_alloc(dev_name);
|
||||
if (!dev_map)
|
||||
/* The main function will cleanup the allocations */
|
||||
return MNL_CB_ERROR;
|
||||
list_add_tail(&dev_map->list, &rd->dev_map_list);
|
||||
|
||||
dev_map->num_ports = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
|
||||
dev_map->idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
void rd_free_devmap(struct rd *rd)
|
||||
{
|
||||
if (!rd)
|
||||
return;
|
||||
dev_map_cleanup(rd);
|
||||
}
|
||||
|
||||
int rd_exec_cmd(struct rd *rd, const struct rd_cmd *cmds, const char *str)
|
||||
{
|
||||
const struct rd_cmd *c;
|
||||
|
||||
/* First argument in objs table is default variant */
|
||||
if (rd_no_arg(rd))
|
||||
return cmds->func(rd);
|
||||
|
||||
for (c = cmds + 1; c->cmd; ++c) {
|
||||
if (rd_argv_match(rd, c->cmd)) {
|
||||
/* Move to next argument */
|
||||
rd_arg_inc(rd);
|
||||
return c->func(rd);
|
||||
}
|
||||
}
|
||||
|
||||
pr_err("Unknown %s '%s'.\n", str, rd_argv(rd));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags)
|
||||
{
|
||||
*seq = time(NULL);
|
||||
|
||||
rd->nlh = mnl_nlmsg_put_header(rd->buff);
|
||||
rd->nlh->nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, cmd);
|
||||
rd->nlh->nlmsg_seq = *seq;
|
||||
rd->nlh->nlmsg_flags = flags;
|
||||
}
|
||||
|
||||
int rd_send_msg(struct rd *rd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rd->nl = mnl_socket_open(NETLINK_RDMA);
|
||||
if (!rd->nl) {
|
||||
pr_err("Failed to open NETLINK_RDMA socket\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = mnl_socket_bind(rd->nl, 0, MNL_SOCKET_AUTOPID);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to bind socket with err %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = mnl_socket_sendto(rd->nl, rd->nlh, rd->nlh->nlmsg_len);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to send to socket with err %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mnl_socket_close(rd->nl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, unsigned int seq)
|
||||
{
|
||||
int ret;
|
||||
unsigned int portid;
|
||||
char buf[MNL_SOCKET_BUFFER_SIZE];
|
||||
|
||||
portid = mnl_socket_get_portid(rd->nl);
|
||||
do {
|
||||
ret = mnl_socket_recvfrom(rd->nl, buf, sizeof(buf));
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
ret = mnl_cb_run(buf, ret, seq, portid, callback, data);
|
||||
} while (ret > 0);
|
||||
|
||||
mnl_socket_close(rd->nl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name)
|
||||
{
|
||||
struct dev_map *dev_map;
|
||||
|
||||
list_for_each_entry(dev_map, &rd->dev_map_list, list)
|
||||
if (strcmp(dev_name, dev_map->dev_name) == 0)
|
||||
return dev_map;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index)
|
||||
{
|
||||
struct dev_map *dev_map;
|
||||
char *dev_name;
|
||||
char *slash;
|
||||
|
||||
dev_name = strdup(rd_argv(rd));
|
||||
if (allow_port_index) {
|
||||
slash = strrchr(dev_name, '/');
|
||||
if (slash)
|
||||
*slash = '\0';
|
||||
}
|
||||
|
||||
dev_map = _dev_map_lookup(rd, dev_name);
|
||||
free(dev_name);
|
||||
return dev_map;
|
||||
}
|
||||
14
tc/m_gact.c
14
tc/m_gact.c
|
|
@ -76,7 +76,6 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
|||
{
|
||||
int argc = *argc_p;
|
||||
char **argv = *argv_p;
|
||||
int ok = 0;
|
||||
struct tc_gact p = { 0 };
|
||||
#ifdef CONFIG_GACT_PROB
|
||||
int rd = 0;
|
||||
|
|
@ -89,17 +88,14 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
|||
|
||||
|
||||
if (matches(*argv, "gact") == 0) {
|
||||
ok++;
|
||||
argc--;
|
||||
argv++;
|
||||
} else {
|
||||
if (parse_action_control(&argc, &argv, &p.action, false) == -1)
|
||||
usage();
|
||||
ok++;
|
||||
} else if (parse_action_control(&argc, &argv, &p.action, false) == -1) {
|
||||
usage(); /* does not return */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GACT_PROB
|
||||
if (ok && argc > 0) {
|
||||
if (argc > 0) {
|
||||
if (matches(*argv, "random") == 0) {
|
||||
rd = 1;
|
||||
NEXT_ARG();
|
||||
|
|
@ -142,15 +138,11 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
|||
}
|
||||
argc--;
|
||||
argv++;
|
||||
ok++;
|
||||
} else if (matches(*argv, "help") == 0) {
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
return -1;
|
||||
|
||||
tail = NLMSG_TAIL(n);
|
||||
addattr_l(n, MAX_MSG, tca_id, NULL, 0);
|
||||
addattr_l(n, MAX_MSG, TCA_GACT_PARMS, &p, sizeof(p));
|
||||
|
|
|
|||
Loading…
Reference in New Issue