From f8aec603aa7e9dad1316079d42c7efcc52b773fa Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 17 Feb 2020 22:38:13 +0100 Subject: src: initial extended netlink error reporting This patch correlates the in-kernel extended netlink error offset and the location information. Assuming 'foo' table does not exist, then error reporting shows: # nft delete table foo Error: Could not process rule: No such file or directory delete table foo ^^^ Similarly, if table uniquely identified by handle '1234' does not exist, then error reporting shows: # nft delete table handle 1234 Error: Could not process rule: No such file or directory delete table handle 1234 ^^^^ Assuming 'bar' chain does not exists in the kernel, while 'foo' does: # nft delete chain foo bar Error: Could not process rule: No such file or directory delete chain foo bar ^^^ This also gives us a hint when adding rules: # nft add rule ip foo bar counter Error: Could not process rule: No such file or directory add rule ip foo bar counter ^^^ This is based on ("src: basic support for extended netlink errors") from Florian Westphal, posted in 2018, with no netlink offset correlation support. Signed-off-by: Pablo Neira Ayuso --- include/cmd.h | 7 +++++++ include/mnl.h | 13 +++++++------ include/netlink.h | 20 ++++++++++++++++++++ include/rule.h | 9 +++++++++ 4 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 include/cmd.h (limited to 'include') diff --git a/include/cmd.h b/include/cmd.h new file mode 100644 index 00000000..27fa6087 --- /dev/null +++ b/include/cmd.h @@ -0,0 +1,7 @@ +#ifndef _NFT_CMD_H_ +#define _NFT_CMD_H_ + +void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd, + struct mnl_err *err); + +#endif diff --git a/include/mnl.h b/include/mnl.h index eeba7379..07669957 100644 --- a/include/mnl.h +++ b/include/mnl.h @@ -16,6 +16,7 @@ struct mnl_err { struct list_head head; int err; uint32_t seqnum; + uint32_t offset; }; void mnl_err_list_free(struct mnl_err *err); @@ -28,7 +29,7 @@ void mnl_batch_end(struct nftnl_batch *batch, uint32_t seqnum); int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list, uint32_t num_cmds); -int mnl_nft_rule_add(struct netlink_ctx *ctx, const struct cmd *cmd, +int mnl_nft_rule_add(struct netlink_ctx *ctx, struct cmd *cmd, unsigned int flags); int mnl_nft_rule_del(struct netlink_ctx *ctx, const struct cmd *cmd); int mnl_nft_rule_replace(struct netlink_ctx *ctx, const struct cmd *cmd); @@ -38,7 +39,7 @@ struct nftnl_rule_list *mnl_nft_rule_dump(struct netlink_ctx *ctx, int mnl_nft_chain_add(struct netlink_ctx *ctx, const struct cmd *cmd, unsigned int flags); -int mnl_nft_chain_del(struct netlink_ctx *ctx, const struct cmd *cmd); +int mnl_nft_chain_del(struct netlink_ctx *ctx, struct cmd *cmd); int mnl_nft_chain_rename(struct netlink_ctx *ctx, const struct cmd *cmd, const struct chain *chain); @@ -47,14 +48,14 @@ struct nftnl_chain_list *mnl_nft_chain_dump(struct netlink_ctx *ctx, int mnl_nft_table_add(struct netlink_ctx *ctx, const struct cmd *cmd, unsigned int flags); -int mnl_nft_table_del(struct netlink_ctx *ctx, const struct cmd *cmd); +int mnl_nft_table_del(struct netlink_ctx *ctx, struct cmd *cmd); struct nftnl_table_list *mnl_nft_table_dump(struct netlink_ctx *ctx, int family); int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd, unsigned int flags); -int mnl_nft_set_del(struct netlink_ctx *ctx, const struct cmd *cmd); +int mnl_nft_set_del(struct netlink_ctx *ctx, struct cmd *cmd); struct nftnl_set_list *mnl_nft_set_dump(struct netlink_ctx *ctx, int family, const char *table); @@ -73,14 +74,14 @@ struct nftnl_obj_list *mnl_nft_obj_dump(struct netlink_ctx *ctx, int family, bool dump, bool reset); int mnl_nft_obj_add(struct netlink_ctx *ctx, const struct cmd *cmd, unsigned int flags); -int mnl_nft_obj_del(struct netlink_ctx *ctx, const struct cmd *cmd, int type); +int mnl_nft_obj_del(struct netlink_ctx *ctx, struct cmd *cmd, int type); struct nftnl_flowtable_list * mnl_nft_flowtable_dump(struct netlink_ctx *ctx, int family, const char *table); int mnl_nft_flowtable_add(struct netlink_ctx *ctx, const struct cmd *cmd, unsigned int flags); -int mnl_nft_flowtable_del(struct netlink_ctx *ctx, const struct cmd *cmd); +int mnl_nft_flowtable_del(struct netlink_ctx *ctx, struct cmd *cmd); int mnl_nft_event_listener(struct mnl_socket *nf_sock, unsigned int debug_mask, struct output_ctx *octx, diff --git a/include/netlink.h b/include/netlink.h index d02533ec..c2eb8949 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -16,6 +16,22 @@ #define MAX_REGS (1 + NFT_REG32_15 - NFT_REG32_00) +#ifndef NETLINK_EXT_ACK +#define NETLINK_EXT_ACK 11 + +enum nlmsgerr_attrs { + NLMSGERR_ATTR_UNUSED, + NLMSGERR_ATTR_MSG, + NLMSGERR_ATTR_OFFS, + NLMSGERR_ATTR_COOKIE, + + __NLMSGERR_ATTR_MAX, + NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1 +}; +#define NLM_F_CAPPED 0x100 /* request was capped */ +#define NLM_F_ACK_TLVS 0x200 /* extended ACK TVLs were included */ +#endif + struct netlink_parse_ctx { struct list_head *msgs; struct table *table; @@ -176,6 +192,10 @@ struct netlink_mon_handler { extern int netlink_monitor(struct netlink_mon_handler *monhandler, struct mnl_socket *nf_sock); +struct netlink_cb_data { + struct netlink_ctx *nl_ctx; + struct list_head *err_list; +}; int netlink_echo_callback(const struct nlmsghdr *nlh, void *data); struct ruleset_parse { diff --git a/include/rule.h b/include/rule.h index c232221e..ced63f3e 100644 --- a/include/rule.h +++ b/include/rule.h @@ -635,6 +635,8 @@ struct monitor { struct monitor *monitor_alloc(uint32_t format, uint32_t type, const char *event); void monitor_free(struct monitor *m); +#define NFT_NLATTR_LOC_MAX 8 + /** * struct cmd - command statement * @@ -666,6 +668,11 @@ struct cmd { struct markup *markup; struct obj *object; }; + struct { + uint16_t offset; + struct location *location; + } attr[NFT_NLATTR_LOC_MAX]; + int num_attrs; const void *arg; }; @@ -678,6 +685,8 @@ extern struct cmd *cmd_alloc_obj_ct(enum cmd_ops op, int type, const struct location *loc, struct obj *obj); extern void cmd_free(struct cmd *cmd); +void cmd_add_loc(struct cmd *cmd, uint16_t offset, struct location *loc); + #include #include -- cgit v1.2.3