netlink: add support for formatted extack messages
Include an 80-byte buffer in struct netlink_ext_ack that can be used for scnprintf()ed messages. This does mean that the resulting string can't be enumerated, translated etc. in the way NL_SET_ERR_MSG() was designed to allow. Signed-off-by: Edward Cree <ecree.xilinx@gmail.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
a526a3cc9c
commit
51c352bdbc
1 changed files with 27 additions and 2 deletions
|
@ -64,6 +64,7 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
|
||||||
|
|
||||||
/* this can be increased when necessary - don't expose to userland */
|
/* this can be increased when necessary - don't expose to userland */
|
||||||
#define NETLINK_MAX_COOKIE_LEN 20
|
#define NETLINK_MAX_COOKIE_LEN 20
|
||||||
|
#define NETLINK_MAX_FMTMSG_LEN 80
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct netlink_ext_ack - netlink extended ACK report struct
|
* struct netlink_ext_ack - netlink extended ACK report struct
|
||||||
|
@ -75,6 +76,8 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
|
||||||
* @miss_nest: nest missing an attribute (%NULL if missing top level attr)
|
* @miss_nest: nest missing an attribute (%NULL if missing top level attr)
|
||||||
* @cookie: cookie data to return to userspace (for success)
|
* @cookie: cookie data to return to userspace (for success)
|
||||||
* @cookie_len: actual cookie data length
|
* @cookie_len: actual cookie data length
|
||||||
|
* @_msg_buf: output buffer for formatted message strings - don't access
|
||||||
|
* directly, use %NL_SET_ERR_MSG_FMT
|
||||||
*/
|
*/
|
||||||
struct netlink_ext_ack {
|
struct netlink_ext_ack {
|
||||||
const char *_msg;
|
const char *_msg;
|
||||||
|
@ -84,13 +87,13 @@ struct netlink_ext_ack {
|
||||||
u16 miss_type;
|
u16 miss_type;
|
||||||
u8 cookie[NETLINK_MAX_COOKIE_LEN];
|
u8 cookie[NETLINK_MAX_COOKIE_LEN];
|
||||||
u8 cookie_len;
|
u8 cookie_len;
|
||||||
|
char _msg_buf[NETLINK_MAX_FMTMSG_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Always use this macro, this allows later putting the
|
/* Always use this macro, this allows later putting the
|
||||||
* message into a separate section or such for things
|
* message into a separate section or such for things
|
||||||
* like translation or listing all possible messages.
|
* like translation or listing all possible messages.
|
||||||
* Currently string formatting is not supported (due
|
* If string formatting is needed use NL_SET_ERR_MSG_FMT.
|
||||||
* to the lack of an output buffer.)
|
|
||||||
*/
|
*/
|
||||||
#define NL_SET_ERR_MSG(extack, msg) do { \
|
#define NL_SET_ERR_MSG(extack, msg) do { \
|
||||||
static const char __msg[] = msg; \
|
static const char __msg[] = msg; \
|
||||||
|
@ -102,9 +105,31 @@ struct netlink_ext_ack {
|
||||||
__extack->_msg = __msg; \
|
__extack->_msg = __msg; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/* We splice fmt with %s at each end even in the snprintf so that both calls
|
||||||
|
* can use the same string constant, avoiding its duplication in .ro
|
||||||
|
*/
|
||||||
|
#define NL_SET_ERR_MSG_FMT(extack, fmt, args...) do { \
|
||||||
|
struct netlink_ext_ack *__extack = (extack); \
|
||||||
|
\
|
||||||
|
if (!__extack) \
|
||||||
|
break; \
|
||||||
|
if (snprintf(__extack->_msg_buf, NETLINK_MAX_FMTMSG_LEN, \
|
||||||
|
"%s" fmt "%s", "", ##args, "") >= \
|
||||||
|
NETLINK_MAX_FMTMSG_LEN) \
|
||||||
|
net_warn_ratelimited("%s" fmt "%s", "truncated extack: ", \
|
||||||
|
##args, "\n"); \
|
||||||
|
\
|
||||||
|
do_trace_netlink_extack(__extack->_msg_buf); \
|
||||||
|
\
|
||||||
|
__extack->_msg = __extack->_msg_buf; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define NL_SET_ERR_MSG_MOD(extack, msg) \
|
#define NL_SET_ERR_MSG_MOD(extack, msg) \
|
||||||
NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " msg)
|
NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " msg)
|
||||||
|
|
||||||
|
#define NL_SET_ERR_MSG_FMT_MOD(extack, fmt, args...) \
|
||||||
|
NL_SET_ERR_MSG_FMT((extack), KBUILD_MODNAME ": " fmt, ##args)
|
||||||
|
|
||||||
#define NL_SET_BAD_ATTR_POLICY(extack, attr, pol) do { \
|
#define NL_SET_BAD_ATTR_POLICY(extack, attr, pol) do { \
|
||||||
if ((extack)) { \
|
if ((extack)) { \
|
||||||
(extack)->bad_attr = (attr); \
|
(extack)->bad_attr = (attr); \
|
||||||
|
|
Loading…
Add table
Reference in a new issue