Commit 1db64e87 authored by Eran Ben Elisha's avatar Eran Ben Elisha Committed by David S. Miller

devlink: Add devlink formatted message (fmsg) API

Devlink fmsg is a mechanism to pass descriptors between drivers and
devlink, in json-like format. The API allows the driver to add nested
attributes such as object, object pair and value array, in addition to
attributes such as name and value.

Driver can use this API to fill the fmsg context in a format which will be
translated by the devlink to the netlink message later.
There is no memory allocation in advance (other than the initial list
head), and it dynamically allocates messages descriptors and add them to
the list on the fly.

When it needs to send the data using SKBs to the netlink layer, it
fragments the data between different SKBs. In order to do this
fragmentation, it uses virtual nests attributes, to avoid actual
nesting use which cannot be divided between different SKBs.
Signed-off-by: default avatarEran Ben Elisha <eranbe@mellanox.com>
Reviewed-by: default avatarMoshe Shemesh <moshe@mellanox.com>
Acked-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8f289805
......@@ -448,6 +448,8 @@ struct devlink_info_req;
typedef void devlink_snapshot_data_dest_t(const void *data);
struct devlink_fmsg;
struct devlink_ops {
int (*reload)(struct devlink *devlink, struct netlink_ext_ack *extack);
int (*port_type_set)(struct devlink_port *devlink_port,
......@@ -639,6 +641,37 @@ int devlink_info_version_running_put(struct devlink_info_req *req,
const char *version_name,
const char *version_value);
int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg);
int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg);
int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name);
int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg);
int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
const char *name);
int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg);
int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value);
int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value);
int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value);
int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value);
int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value);
int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
u16 value_len);
int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
bool value);
int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
u8 value);
int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
u32 value);
int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
u64 value);
int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
const char *value);
int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
const void *value, u16 value_len);
#else
static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
......@@ -971,6 +1004,122 @@ devlink_info_version_running_put(struct devlink_info_req *req,
{
return 0;
}
static inline int
devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
{
return 0;
}
static inline int
devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
{
return 0;
}
static inline int
devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
{
return 0;
}
static inline int
devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
{
return 0;
}
static inline int
devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
const char *name)
{
return 0;
}
static inline int
devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
{
return 0;
}
static inline int
devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
{
return 0;
}
static inline int
devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
{
return 0;
}
static inline int
devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
{
return 0;
}
static inline int
devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
{
return 0;
}
static inline int
devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
{
return 0;
}
static inline int
devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
u16 value_len)
{
return 0;
}
static inline int
devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
bool value)
{
return 0;
}
static inline int
devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
u8 value)
{
return 0;
}
static inline int
devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
u32 value)
{
return 0;
}
static inline int
devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
u64 value)
{
return 0;
}
static inline int
devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
const char *value)
{
return 0;
}
static inline int
devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
const void *value, u16 value_len)
{
return 0;
}
#endif
#if IS_REACHABLE(CONFIG_NET_DEVLINK)
......
......@@ -302,6 +302,14 @@ enum devlink_attr {
DEVLINK_ATTR_SB_POOL_CELL_SIZE, /* u32 */
DEVLINK_ATTR_FMSG, /* nested */
DEVLINK_ATTR_FMSG_OBJ_NEST_START, /* flag */
DEVLINK_ATTR_FMSG_PAIR_NEST_START, /* flag */
DEVLINK_ATTR_FMSG_ARR_NEST_START, /* flag */
DEVLINK_ATTR_FMSG_NEST_END, /* flag */
DEVLINK_ATTR_FMSG_OBJ_NAME, /* string */
DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, /* u8 */
DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA, /* dynamic */
/* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment