summaryrefslogtreecommitdiff
path: root/include/linux/netlink.h
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2022-10-19 13:00:09 -0700
committerJakub Kicinski <kuba@kernel.org>2022-10-19 13:00:10 -0700
commit5c624a1d77d3eb2e314b59282b1213fa760d192c (patch)
treea063036b4c78b6cde4e1819b602d5137767c0728 /include/linux/netlink.h
parenta526a3cc9c8d426713f8bebc18ebbe39a8495d82 (diff)
parentb799f052a987c3fdd315cbac665b9202dd96382b (diff)
Merge branch 'netlink-formatted-extacks'
Edward Cree says: ==================== netlink: formatted extacks Currently, netlink extacks can only carry fixed string messages, which is limiting when reporting failures in complex systems. This series adds the ability to return printf-formatted messages, and uses it in the sfc driver's TC offload code. Formatted extack messages are limited in length to a fixed buffer size, currently 80 characters. If the message exceeds this, the full message will be logged (ratelimited) to the console and a truncated version returned over netlink. There is no change to the netlink uAPI; only internal kernel changes are needed. ==================== Link: https://lore.kernel.org/r/cover.1666102698.git.ecree.xilinx@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/linux/netlink.h')
-rw-r--r--include/linux/netlink.h29
1 files changed, 27 insertions, 2 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index d51e041d2242..d81bde5a5844 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -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 */
#define NETLINK_MAX_COOKIE_LEN 20
+#define NETLINK_MAX_FMTMSG_LEN 80
/**
* 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)
* @cookie: cookie data to return to userspace (for success)
* @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 {
const char *_msg;
@@ -84,13 +87,13 @@ struct netlink_ext_ack {
u16 miss_type;
u8 cookie[NETLINK_MAX_COOKIE_LEN];
u8 cookie_len;
+ char _msg_buf[NETLINK_MAX_FMTMSG_LEN];
};
/* Always use this macro, this allows later putting the
* message into a separate section or such for things
* like translation or listing all possible messages.
- * Currently string formatting is not supported (due
- * to the lack of an output buffer.)
+ * If string formatting is needed use NL_SET_ERR_MSG_FMT.
*/
#define NL_SET_ERR_MSG(extack, msg) do { \
static const char __msg[] = msg; \
@@ -102,9 +105,31 @@ struct netlink_ext_ack {
__extack->_msg = __msg; \
} 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) \
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 { \
if ((extack)) { \
(extack)->bad_attr = (attr); \