From e0146fa254496dc12187053cd0cd6e5d20eb6a43 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 8 Jul 2017 05:07:23 +0530 Subject: include: Pass nf_sock where needed as parameter This socket should not be global, it is also hidden in many layers of code. Expose it as function parameters to decouple the netlink socket handling logic from the command parsing, evaluation and bytecode generation. Joint work with Varsha Rao. Signed-off-by: Varsha Rao Signed-off-by: Pablo Neira Ayuso --- src/cli.c | 11 +++++++--- src/evaluate.c | 22 ++++++++++---------- src/main.c | 24 +++++++++++++--------- src/netlink.c | 60 ++++++++++++++++++++++++++++-------------------------- src/parser_bison.y | 4 +++- src/rule.c | 13 +++++++----- 6 files changed, 75 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/cli.c b/src/cli.c index 7cd2f45e..c1fdcf6c 100644 --- a/src/cli.c +++ b/src/cli.c @@ -31,6 +31,8 @@ #include #include +#include + #define CMDLINE_HISTFILE ".nft.history" static const struct input_descriptor indesc_cli = { @@ -40,6 +42,7 @@ static const struct input_descriptor indesc_cli = { static struct parser_state *state; static struct nft_ctx cli_nft; +static struct mnl_socket *cli_nf_sock; static void *scanner; static char histfile[PATH_MAX]; @@ -128,9 +131,9 @@ static void cli_complete(char *line) xfree(line); line = s; - parser_init(state, &msgs); + parser_init(cli_nf_sock, state, &msgs); scanner_push_buffer(scanner, &indesc_cli, line); - nft_run(&cli_nft, scanner, state, &msgs); + nft_run(&cli_nft, cli_nf_sock, scanner, state, &msgs); erec_print_list(stdout, &msgs); xfree(line); cache_release(); @@ -168,10 +171,12 @@ void __fmtstring(1, 0) cli_display(const char *fmt, va_list ap) rl_forced_update_display(); } -int cli_init(struct nft_ctx *nft, struct parser_state *_state) +int cli_init(struct nft_ctx *nft, struct mnl_socket *nf_sock, + struct parser_state *_state) { const char *home; + cli_nf_sock = nf_sock; cli_nft = *nft; rl_readline_name = "nft"; rl_instream = stdin; diff --git a/src/evaluate.c b/src/evaluate.c index ca8b63b7..74a40974 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -181,7 +181,7 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr) new = expr_clone(sym->expr); break; case SYMBOL_SET: - ret = cache_update(ctx->cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, ctx->cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -2950,13 +2950,13 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) switch (cmd->obj) { case CMD_OBJ_SETELEM: - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; return setelem_evaluate(ctx, &cmd->expr); case CMD_OBJ_SET: - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -2966,7 +2966,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) handle_merge(&cmd->rule->handle, &cmd->handle); return rule_evaluate(ctx, cmd->rule); case CMD_OBJ_CHAIN: - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -2988,7 +2988,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd) switch (cmd->obj) { case CMD_OBJ_SETELEM: - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -3030,7 +3030,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) struct set *set; int ret; - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -3113,7 +3113,7 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd) { int ret; - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -3139,7 +3139,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) struct set *set; int ret; - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -3197,7 +3197,7 @@ static int cmd_evaluate_rename(struct eval_ctx *ctx, struct cmd *cmd) switch (cmd->obj) { case CMD_OBJ_CHAIN: - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -3283,7 +3283,7 @@ static int cmd_evaluate_monitor(struct eval_ctx *ctx, struct cmd *cmd) uint32_t event; int ret; - ret = cache_update(cmd->op, ctx->msgs); + ret = cache_update(ctx->nf_sock, cmd->op, ctx->msgs); if (ret < 0) return ret; @@ -3306,7 +3306,7 @@ static int cmd_evaluate_monitor(struct eval_ctx *ctx, struct cmd *cmd) static int cmd_evaluate_export(struct eval_ctx *ctx, struct cmd *cmd) { - return cache_update(cmd->op, ctx->msgs); + return cache_update(ctx->nf_sock, cmd->op, ctx->msgs); } #ifdef DEBUG diff --git a/src/main.c b/src/main.c index 7fbf00a7..36b4bbc6 100644 --- a/src/main.c +++ b/src/main.c @@ -182,7 +182,7 @@ static const struct input_descriptor indesc_cmdline = { }; static int nft_netlink(struct nft_ctx *nft, struct parser_state *state, - struct list_head *msgs) + struct list_head *msgs, struct mnl_socket *nf_sock) { struct nftnl_batch *batch; struct netlink_ctx ctx; @@ -190,7 +190,7 @@ static int nft_netlink(struct nft_ctx *nft, struct parser_state *state, struct mnl_err *err, *tmp; LIST_HEAD(err_list); uint32_t batch_seqnum; - bool batch_supported = netlink_batch_supported(); + bool batch_supported = netlink_batch_supported(nf_sock); int ret = 0; batch = mnl_batch_init(); @@ -203,6 +203,7 @@ static int nft_netlink(struct nft_ctx *nft, struct parser_state *state, ctx.batch = batch; ctx.batch_supported = batch_supported; ctx.octx = &nft->output; + ctx.nf_sock = nf_sock; init_list_head(&ctx.list); ret = do_command(&ctx, cmd); if (ret < 0) @@ -237,8 +238,8 @@ out: return ret; } -int nft_run(struct nft_ctx *nft, void *scanner, struct parser_state *state, - struct list_head *msgs) +int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, void *scanner, + struct parser_state *state, struct list_head *msgs) { struct cmd *cmd, *next; int ret; @@ -252,7 +253,7 @@ int nft_run(struct nft_ctx *nft, void *scanner, struct parser_state *state, list_for_each_entry(cmd, &state->cmds, list) nft_cmd_expand(cmd); - ret = nft_netlink(nft, state, msgs); + ret = nft_netlink(nft, state, msgs, nf_sock); err1: list_for_each_entry_safe(cmd, next, &state->cmds, list) { list_del(&cmd->list); @@ -271,7 +272,9 @@ int main(int argc, char * const *argv) unsigned int len; bool interactive = false; int i, val, rc = NFT_EXIT_SUCCESS; + struct mnl_socket *nf_sock; + nf_sock = netlink_open_sock(); while (1) { val = getopt_long(argc, argv, OPTSTRING, options, NULL); if (val == -1) @@ -365,20 +368,20 @@ int main(int argc, char * const *argv) strcat(buf, " "); } strcat(buf, "\n"); - parser_init(&state, &msgs); + parser_init(nf_sock, &state, &msgs); scanner = scanner_init(&state); scanner_push_buffer(scanner, &indesc_cmdline, buf); } else if (filename != NULL) { - rc = cache_update(CMD_INVALID, &msgs); + rc = cache_update(nf_sock, CMD_INVALID, &msgs); if (rc < 0) return rc; - parser_init(&state, &msgs); + parser_init(nf_sock, &state, &msgs); scanner = scanner_init(&state); if (scanner_read_file(scanner, filename, &internal_location) < 0) goto out; } else if (interactive) { - if (cli_init(&nft, &state) < 0) { + if (cli_init(&nft, nf_sock, &state) < 0) { fprintf(stderr, "%s: interactive CLI not supported in this build\n", argv[0]); exit(NFT_EXIT_FAILURE); @@ -389,7 +392,7 @@ int main(int argc, char * const *argv) exit(NFT_EXIT_FAILURE); } - if (nft_run(&nft, scanner, &state, &msgs) != 0) + if (nft_run(&nft, nf_sock, scanner, &state, &msgs) != 0) rc = NFT_EXIT_FAILURE; out: scanner_destroy(scanner); @@ -397,6 +400,7 @@ out: xfree(buf); cache_release(); iface_cache_release(); + netlink_close_sock(nf_sock); return rc; } diff --git a/src/netlink.c b/src/netlink.c index b9731a91..8bf90b20 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -39,7 +39,6 @@ #include #include -static struct mnl_socket *nf_sock; static struct mnl_socket *nf_mon_sock; const struct input_descriptor indesc_netlink = { @@ -61,13 +60,16 @@ static struct mnl_socket *nfsock_open(void) return s; } -static void __init netlink_open_sock(void) +struct mnl_socket *netlink_open_sock(void) { + struct mnl_socket *nf_sock; + nf_sock = nfsock_open(); fcntl(mnl_socket_get_fd(nf_sock), F_SETFL, O_NONBLOCK); + return nf_sock; } -static void __exit netlink_close_sock(void) +void netlink_close_sock(struct mnl_socket *nf_sock) { if (nf_sock) mnl_socket_close(nf_sock); @@ -75,13 +77,13 @@ static void __exit netlink_close_sock(void) mnl_socket_close(nf_mon_sock); } -void netlink_restart(void) +void netlink_restart(struct mnl_socket *nf_sock) { - netlink_close_sock(); - netlink_open_sock(); + netlink_close_sock(nf_sock); + nf_sock = netlink_open_sock(); } -void netlink_genid_get(void) +void netlink_genid_get(struct mnl_socket *nf_sock) { mnl_genid_get(nf_sock); } @@ -559,7 +561,7 @@ static int netlink_list_rules(struct netlink_ctx *ctx, const struct handle *h, { struct nftnl_rule_list *rule_cache; - rule_cache = mnl_nft_rule_dump(nf_sock, h->family); + rule_cache = mnl_nft_rule_dump(ctx->nf_sock, h->family); if (rule_cache == NULL) { if (errno == EINTR) return -1; @@ -616,7 +618,7 @@ static int netlink_add_chain_compat(struct netlink_ctx *ctx, } netlink_dump_chain(nlc); - err = mnl_nft_chain_add(nf_sock, nlc, excl ? NLM_F_EXCL : 0); + err = mnl_nft_chain_add(ctx->nf_sock, nlc, excl ? NLM_F_EXCL : 0); nftnl_chain_free(nlc); if (err < 0) @@ -683,7 +685,7 @@ static int netlink_rename_chain_compat(struct netlink_ctx *ctx, nlc = alloc_nftnl_chain(h); nftnl_chain_set_str(nlc, NFTNL_CHAIN_NAME, name); netlink_dump_chain(nlc); - err = mnl_nft_chain_add(nf_sock, nlc, 0); + err = mnl_nft_chain_add(ctx->nf_sock, nlc, 0); nftnl_chain_free(nlc); if (err < 0) @@ -730,7 +732,7 @@ static int netlink_del_chain_compat(struct netlink_ctx *ctx, nlc = alloc_nftnl_chain(h); netlink_dump_chain(nlc); - err = mnl_nft_chain_delete(nf_sock, nlc, 0); + err = mnl_nft_chain_delete(ctx->nf_sock, nlc, 0); nftnl_chain_free(nlc); if (err < 0) @@ -833,7 +835,7 @@ int netlink_list_chains(struct netlink_ctx *ctx, const struct handle *h, struct nftnl_chain_list *chain_cache; struct chain *chain; - chain_cache = mnl_nft_chain_dump(nf_sock, h->family); + chain_cache = mnl_nft_chain_dump(ctx->nf_sock, h->family); if (chain_cache == NULL) { if (errno == EINTR) return -1; @@ -869,7 +871,7 @@ int netlink_get_chain(struct netlink_ctx *ctx, const struct handle *h, int err; nlc = alloc_nftnl_chain(h); - err = mnl_nft_chain_get(nf_sock, nlc, 0); + err = mnl_nft_chain_get(ctx->nf_sock, nlc, 0); if (err < 0) { netlink_io_error(ctx, loc, "Could not receive chain from kernel: %s", @@ -905,7 +907,7 @@ static int netlink_add_table_compat(struct netlink_ctx *ctx, int err; nlt = alloc_nftnl_table(h); - err = mnl_nft_table_add(nf_sock, nlt, excl ? NLM_F_EXCL : 0); + err = mnl_nft_table_add(ctx->nf_sock, nlt, excl ? NLM_F_EXCL : 0); nftnl_table_free(nlt); if (err < 0) @@ -956,7 +958,7 @@ static int netlink_del_table_compat(struct netlink_ctx *ctx, int err; nlt = alloc_nftnl_table(h); - err = mnl_nft_table_delete(nf_sock, nlt, 0); + err = mnl_nft_table_delete(ctx->nf_sock, nlt, 0); nftnl_table_free(nlt); if (err < 0) @@ -1033,7 +1035,7 @@ int netlink_list_tables(struct netlink_ctx *ctx, const struct handle *h, { struct nftnl_table_list *table_cache; - table_cache = mnl_nft_table_dump(nf_sock, h->family); + table_cache = mnl_nft_table_dump(ctx->nf_sock, h->family); if (table_cache == NULL) { if (errno == EINTR) return -1; @@ -1054,7 +1056,7 @@ int netlink_get_table(struct netlink_ctx *ctx, const struct handle *h, int err; nlt = alloc_nftnl_table(h); - err = mnl_nft_table_get(nf_sock, nlt, 0); + err = mnl_nft_table_get(ctx->nf_sock, nlt, 0); if (err < 0) { netlink_io_error(ctx, loc, "Could not receive table from kernel: %s", @@ -1246,7 +1248,7 @@ static int netlink_add_set_compat(struct netlink_ctx *ctx, } netlink_dump_set(nls); - err = mnl_nft_set_add(nf_sock, nls, NLM_F_ECHO | flags); + err = mnl_nft_set_add(ctx->nf_sock, nls, NLM_F_ECHO | flags); if (err < 0) netlink_io_error(ctx, &set->location, "Could not add set: %s", strerror(errno)); @@ -1343,7 +1345,7 @@ static int netlink_del_set_compat(struct netlink_ctx *ctx, int err; nls = alloc_nftnl_set(h); - err = mnl_nft_set_delete(nf_sock, nls, 0); + err = mnl_nft_set_delete(ctx->nf_sock, nls, 0); nftnl_set_free(nls); if (err < 0) @@ -1396,7 +1398,7 @@ int netlink_list_sets(struct netlink_ctx *ctx, const struct handle *h, struct nftnl_set_list *set_cache; int err; - set_cache = mnl_nft_set_dump(nf_sock, h->family, h->table); + set_cache = mnl_nft_set_dump(ctx->nf_sock, h->family, h->table); if (set_cache == NULL) { if (errno == EINTR) return -1; @@ -1417,7 +1419,7 @@ int netlink_get_set(struct netlink_ctx *ctx, const struct handle *h, int err; nls = alloc_nftnl_set(h); - err = mnl_nft_set_get(nf_sock, nls); + err = mnl_nft_set_get(ctx->nf_sock, nls); if (err < 0) { nftnl_set_free(nls); return netlink_io_error(ctx, loc, @@ -1477,7 +1479,7 @@ static int netlink_add_setelems_compat(struct netlink_ctx *ctx, alloc_setelem_cache(expr, nls); netlink_dump_set(nls); - err = mnl_nft_setelem_add(nf_sock, nls, excl ? NLM_F_EXCL : 0); + err = mnl_nft_setelem_add(ctx->nf_sock, nls, excl ? NLM_F_EXCL : 0); nftnl_set_free(nls); if (err < 0) netlink_io_error(ctx, &expr->location, @@ -1527,7 +1529,7 @@ static int netlink_del_setelems_compat(struct netlink_ctx *ctx, alloc_setelem_cache(expr, nls); netlink_dump_set(nls); - err = mnl_nft_setelem_delete(nf_sock, nls, 0); + err = mnl_nft_setelem_delete(ctx->nf_sock, nls, 0); nftnl_set_free(nls); if (err < 0) netlink_io_error(ctx, &expr->location, @@ -1722,7 +1724,7 @@ int netlink_get_setelems(struct netlink_ctx *ctx, const struct handle *h, nls = alloc_nftnl_set(h); - err = mnl_nft_setelem_get(nf_sock, nls); + err = mnl_nft_setelem_get(ctx->nf_sock, nls); if (err < 0) { nftnl_set_free(nls); if (errno == EINTR) @@ -1861,7 +1863,7 @@ int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h, struct nftnl_obj_list *obj_cache; int err; - obj_cache = mnl_nft_obj_dump(nf_sock, h->family, h->table, NULL, + obj_cache = mnl_nft_obj_dump(ctx->nf_sock, h->family, h->table, NULL, 0, true, false); if (obj_cache == NULL) { if (errno == EINTR) @@ -1881,7 +1883,7 @@ int netlink_reset_objs(struct netlink_ctx *ctx, const struct handle *h, struct nftnl_obj_list *obj_cache; int err; - obj_cache = mnl_nft_obj_dump(nf_sock, h->family, h->table, h->obj, + obj_cache = mnl_nft_obj_dump(ctx->nf_sock, h->family, h->table, h->obj, type, dump, true); if (obj_cache == NULL) { if (errno == EINTR) @@ -1899,7 +1901,7 @@ int netlink_reset_objs(struct netlink_ctx *ctx, const struct handle *h, int netlink_batch_send(struct netlink_ctx *ctx, struct list_head *err_list) { - return mnl_batch_talk(nf_sock, ctx->batch, err_list); + return mnl_batch_talk(ctx->nf_sock, ctx->batch, err_list); } int netlink_flush_ruleset(struct netlink_ctx *ctx, const struct handle *h, @@ -1927,7 +1929,7 @@ struct nftnl_ruleset *netlink_dump_ruleset(struct netlink_ctx *ctx, { struct nftnl_ruleset *rs; - rs = mnl_nft_ruleset_dump(nf_sock, h->family); + rs = mnl_nft_ruleset_dump(ctx->nf_sock, h->family); if (rs == NULL) { if (errno == EINTR) return NULL; @@ -2937,7 +2939,7 @@ int netlink_monitor(struct netlink_mon_handler *monhandler) monhandler); } -bool netlink_batch_supported(void) +bool netlink_batch_supported(struct mnl_socket *nf_sock) { return mnl_batch_supported(nf_sock); } diff --git a/src/parser_bison.y b/src/parser_bison.y index 74b2ac7b..87d898b8 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -35,7 +35,8 @@ #include "parser_bison.h" -void parser_init(struct parser_state *state, struct list_head *msgs) +void parser_init(struct mnl_socket *nf_sock, struct parser_state *state, + struct list_head *msgs) { memset(state, 0, sizeof(*state)); init_list_head(&state->cmds); @@ -43,6 +44,7 @@ void parser_init(struct parser_state *state, struct list_head *msgs) state->msgs = msgs; state->scopes[0] = scope_init(&state->top_scope, NULL); state->ectx.msgs = msgs; + state->ectx.nf_sock = nf_sock; } static void yyerror(struct location *loc, void *scanner, diff --git a/src/rule.c b/src/rule.c index ee510fe0..b0b64ffe 100644 --- a/src/rule.c +++ b/src/rule.c @@ -122,7 +122,8 @@ static int cache_init_objects(struct netlink_ctx *ctx, enum cmd_ops cmd) return 0; } -static int cache_init(enum cmd_ops cmd, struct list_head *msgs) +static int cache_init(struct mnl_socket *nf_sock, enum cmd_ops cmd, + struct list_head *msgs) { struct handle handle = { .family = NFPROTO_UNSPEC, @@ -132,6 +133,7 @@ static int cache_init(enum cmd_ops cmd, struct list_head *msgs) memset(&ctx, 0, sizeof(ctx)); init_list_head(&ctx.list); + ctx.nf_sock = nf_sock; ctx.msgs = msgs; ret = cache_init_tables(&ctx, &handle); @@ -146,19 +148,20 @@ static int cache_init(enum cmd_ops cmd, struct list_head *msgs) static bool cache_initialized; -int cache_update(enum cmd_ops cmd, struct list_head *msgs) +int cache_update(struct mnl_socket *nf_sock, enum cmd_ops cmd, + struct list_head *msgs) { int ret; if (cache_initialized) return 0; replay: - netlink_genid_get(); - ret = cache_init(cmd, msgs); + netlink_genid_get(nf_sock); + ret = cache_init(nf_sock, cmd, msgs); if (ret < 0) { cache_release(); if (errno == EINTR) { - netlink_restart(); + netlink_restart(nf_sock); goto replay; } return -1; -- cgit v1.2.3