mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
netfilter net-next pull request 2023-10-10
-----BEGIN PGP SIGNATURE----- iQJBBAABCAArFiEEgKkgxbID4Gn1hq6fcJGo2a1f9gAFAmUlYWENHGZ3QHN0cmxl bi5kZQAKCRBwkajZrV/2AC68D/0WnxpQHiCMl7rUWrDJjmhYenUY1uM9VZb1fpd7 hH543aVbJmWNQj9uzWmKceuLKtIV5jCgsgzqHcxq5e0oHLc3IjIOX1j6L6Dtv7Wf 8obzfCZOYvp0rfaB/2W8d+ehet69i8UQlWM6uKVD/vEedAynfu8AaCgaNy6WwgrK ElXa3lZzflfoeqvwZkndxIkeuoXQB4mYCcuIXuseB+pYv5pz2th2OsGNxeeae0Q0 XlOPY7LNrAWMbUFfJUiRMb7bEXINOcmZMGC/9OTpYTJe3j32ybi0pZY91AV8HEQY xuQY2k4dVs4bSfxPFkrXlansPh7fbtl/EF6LNoDbCobV6RAZrc0SEM7eSybRoigm FrsWdms4bp5RRaBWxi3MRj1ir8nBHjLJ3AHlec1h6EMcXOWsF91u8mk0+0i9eF8E htw7Rxc7ZR3xRUKFxA5+53oYwMYnst9PdZ54DKrAMJOfykU6pGx2hJbsmTfodeGl zAT1GXPjEDejbXdmD84CzIs+bCmuGNrQQZ6o9gAaYVm9DJJMEXUpp1yK+/ApEnsz pcZNi7NeZRlwJhayLCYdvTT3sUlcDYqGuJoDE/krKNH6Aq0iAb/zvHxbOAn7R550 UFTVpB78W+0G0eufpgCIsxGHIgAZOGYWTe/TcrQIghWPNxfrt6p5XZVh2N4g8n9C nPiOdg== =pmbB -----END PGP SIGNATURE----- Merge tag 'nf-next-23-10-10' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next Florian Westphal says: ==================== netfilter updates for next First 5 patches, from Phil Sutter, clean up nftables dumpers to use the context buffer in the netlink_callback structure rather than a kmalloc'd buffer. Patch 6, from myself, zaps dead code and replaces the helper function with a small inlined helper. Patch 7, also from myself, removes another pr_debug and replaces it with the existing nf_log-based debug helpers. Last patch, from George Guo, gets nft_table comments back in sync with the structure members. * tag 'nf-next-23-10-10' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: cleanup struct nft_table netfilter: conntrack: prefer tcp_error_log to pr_debug netfilter: conntrack: simplify nf_conntrack_alter_reply netfilter: nf_tables: Don't allocate nft_rule_dump_ctx netfilter: nf_tables: Carry s_idx in nft_rule_dump_ctx netfilter: nf_tables: Carry reset flag in nft_rule_dump_ctx netfilter: nf_tables: Drop pointless memset when dumping rules netfilter: nf_tables: Always allocate nft_rule_dump_ctx ==================== Link: https://lore.kernel.org/r/20231010145343.12551-1-fw@strlen.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
21b2e2624d
6 changed files with 50 additions and 81 deletions
|
@ -160,10 +160,6 @@ static inline struct net *nf_ct_net(const struct nf_conn *ct)
|
|||
return read_pnet(&ct->ct_net);
|
||||
}
|
||||
|
||||
/* Alter reply tuple (maybe alter helper). */
|
||||
void nf_conntrack_alter_reply(struct nf_conn *ct,
|
||||
const struct nf_conntrack_tuple *newreply);
|
||||
|
||||
/* Is this tuple taken? (ignoring any belonging to the given
|
||||
conntrack). */
|
||||
int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
|
||||
|
@ -284,6 +280,16 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
|
|||
return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK;
|
||||
}
|
||||
|
||||
static inline void nf_conntrack_alter_reply(struct nf_conn *ct,
|
||||
const struct nf_conntrack_tuple *newreply)
|
||||
{
|
||||
/* Must be unconfirmed, so not in hash table yet */
|
||||
if (WARN_ON(nf_ct_is_confirmed(ct)))
|
||||
return;
|
||||
|
||||
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
|
||||
}
|
||||
|
||||
#define nfct_time_stamp ((u32)(jiffies))
|
||||
|
||||
/* jiffies until ct expires, 0 if already expired */
|
||||
|
|
|
@ -1198,10 +1198,13 @@ static inline void nft_use_inc_restore(u32 *use)
|
|||
* @hgenerator: handle generator state
|
||||
* @handle: table handle
|
||||
* @use: number of chain references to this table
|
||||
* @family:address family
|
||||
* @flags: table flag (see enum nft_table_flags)
|
||||
* @genmask: generation mask
|
||||
* @afinfo: address family info
|
||||
* @nlpid: netlink port ID
|
||||
* @name: name of the table
|
||||
* @udlen: length of the user data
|
||||
* @udata: user data
|
||||
* @validate_state: internal, set when transaction adds jumps
|
||||
*/
|
||||
struct nft_table {
|
||||
|
|
|
@ -2042,24 +2042,6 @@ nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_in);
|
||||
|
||||
/* Alter reply tuple (maybe alter helper). This is for NAT, and is
|
||||
implicitly racy: see __nf_conntrack_confirm */
|
||||
void nf_conntrack_alter_reply(struct nf_conn *ct,
|
||||
const struct nf_conntrack_tuple *newreply)
|
||||
{
|
||||
struct nf_conn_help *help = nfct_help(ct);
|
||||
|
||||
/* Should be unconfirmed, so not in hash table yet */
|
||||
WARN_ON(nf_ct_is_confirmed(ct));
|
||||
|
||||
nf_ct_dump_tuple(newreply);
|
||||
|
||||
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
|
||||
if (ct->master || (help && !hlist_empty(&help->expectations)))
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
|
||||
|
||||
/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
|
||||
void __nf_ct_refresh_acct(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
|
|
|
@ -194,12 +194,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
|
|||
struct nf_conntrack_helper *helper = NULL;
|
||||
struct nf_conn_help *help;
|
||||
|
||||
/* We already got a helper explicitly attached. The function
|
||||
* nf_conntrack_alter_reply - in case NAT is in use - asks for looking
|
||||
* the helper up again. Since now the user is in full control of
|
||||
* making consistent helper configurations, skip this automatic
|
||||
* re-lookup, otherwise we'll lose the helper.
|
||||
*/
|
||||
/* We already got a helper explicitly attached (e.g. nft_ct) */
|
||||
if (test_bit(IPS_HELPER_BIT, &ct->status))
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -835,7 +835,8 @@ static bool tcp_error(const struct tcphdr *th,
|
|||
|
||||
static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
const struct tcphdr *th)
|
||||
const struct tcphdr *th,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
enum tcp_conntrack new_state;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
|
@ -846,7 +847,7 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
|||
|
||||
/* Invalid: delete conntrack */
|
||||
if (new_state >= TCP_CONNTRACK_MAX) {
|
||||
pr_debug("nf_ct_tcp: invalid new deleting.\n");
|
||||
tcp_error_log(skb, state, "invalid new");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -980,7 +981,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
|
|||
if (tcp_error(th, skb, dataoff, state))
|
||||
return -NF_ACCEPT;
|
||||
|
||||
if (!nf_ct_is_confirmed(ct) && !tcp_new(ct, skb, dataoff, th))
|
||||
if (!nf_ct_is_confirmed(ct) && !tcp_new(ct, skb, dataoff, th, state))
|
||||
return -NF_ACCEPT;
|
||||
|
||||
spin_lock_bh(&ct->lock);
|
||||
|
|
|
@ -3441,20 +3441,21 @@ static void audit_log_rule_reset(const struct nft_table *table,
|
|||
}
|
||||
|
||||
struct nft_rule_dump_ctx {
|
||||
unsigned int s_idx;
|
||||
char *table;
|
||||
char *chain;
|
||||
bool reset;
|
||||
};
|
||||
|
||||
static int __nf_tables_dump_rules(struct sk_buff *skb,
|
||||
unsigned int *idx,
|
||||
struct netlink_callback *cb,
|
||||
const struct nft_table *table,
|
||||
const struct nft_chain *chain,
|
||||
bool reset)
|
||||
const struct nft_chain *chain)
|
||||
{
|
||||
struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
const struct nft_rule *rule, *prule;
|
||||
unsigned int s_idx = cb->args[0];
|
||||
unsigned int entries = 0;
|
||||
int ret = 0;
|
||||
u64 handle;
|
||||
|
@ -3463,12 +3464,8 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
|
|||
list_for_each_entry_rcu(rule, &chain->rules, list) {
|
||||
if (!nft_is_active(net, rule))
|
||||
goto cont_skip;
|
||||
if (*idx < s_idx)
|
||||
if (*idx < ctx->s_idx)
|
||||
goto cont;
|
||||
if (*idx > s_idx) {
|
||||
memset(&cb->args[1], 0,
|
||||
sizeof(cb->args) - sizeof(cb->args[0]));
|
||||
}
|
||||
if (prule)
|
||||
handle = prule->handle;
|
||||
else
|
||||
|
@ -3479,7 +3476,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
|
|||
NFT_MSG_NEWRULE,
|
||||
NLM_F_MULTI | NLM_F_APPEND,
|
||||
table->family,
|
||||
table, chain, rule, handle, reset) < 0) {
|
||||
table, chain, rule, handle, ctx->reset) < 0) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -3491,7 +3488,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
|
|||
(*idx)++;
|
||||
}
|
||||
|
||||
if (reset && entries)
|
||||
if (ctx->reset && entries)
|
||||
audit_log_rule_reset(table, cb->seq, entries);
|
||||
|
||||
return ret;
|
||||
|
@ -3501,17 +3498,13 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
|
|||
struct netlink_callback *cb)
|
||||
{
|
||||
const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
|
||||
const struct nft_rule_dump_ctx *ctx = cb->data;
|
||||
struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
|
||||
struct nft_table *table;
|
||||
const struct nft_chain *chain;
|
||||
unsigned int idx = 0;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
int family = nfmsg->nfgen_family;
|
||||
struct nftables_pernet *nft_net;
|
||||
bool reset = false;
|
||||
|
||||
if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
|
||||
reset = true;
|
||||
|
||||
rcu_read_lock();
|
||||
nft_net = nft_pernet(net);
|
||||
|
@ -3521,10 +3514,10 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
|
|||
if (family != NFPROTO_UNSPEC && family != table->family)
|
||||
continue;
|
||||
|
||||
if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0)
|
||||
if (ctx->table && strcmp(ctx->table, table->name) != 0)
|
||||
continue;
|
||||
|
||||
if (ctx && ctx->table && ctx->chain) {
|
||||
if (ctx->table && ctx->chain) {
|
||||
struct rhlist_head *list, *tmp;
|
||||
|
||||
list = rhltable_lookup(&table->chains_ht, ctx->chain,
|
||||
|
@ -3536,7 +3529,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
|
|||
if (!nft_is_active(net, chain))
|
||||
continue;
|
||||
__nf_tables_dump_rules(skb, &idx,
|
||||
cb, table, chain, reset);
|
||||
cb, table, chain);
|
||||
break;
|
||||
}
|
||||
goto done;
|
||||
|
@ -3544,62 +3537,51 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
|
|||
|
||||
list_for_each_entry_rcu(chain, &table->chains, list) {
|
||||
if (__nf_tables_dump_rules(skb, &idx,
|
||||
cb, table, chain, reset))
|
||||
cb, table, chain))
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ctx && ctx->table)
|
||||
if (ctx->table)
|
||||
break;
|
||||
}
|
||||
done:
|
||||
rcu_read_unlock();
|
||||
|
||||
cb->args[0] = idx;
|
||||
ctx->s_idx = idx;
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
static int nf_tables_dump_rules_start(struct netlink_callback *cb)
|
||||
{
|
||||
struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
|
||||
const struct nlattr * const *nla = cb->data;
|
||||
struct nft_rule_dump_ctx *ctx = NULL;
|
||||
|
||||
if (nla[NFTA_RULE_TABLE] || nla[NFTA_RULE_CHAIN]) {
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
|
||||
if (!ctx)
|
||||
BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
|
||||
|
||||
if (nla[NFTA_RULE_TABLE]) {
|
||||
ctx->table = nla_strdup(nla[NFTA_RULE_TABLE], GFP_ATOMIC);
|
||||
if (!ctx->table)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (nla[NFTA_RULE_CHAIN]) {
|
||||
ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN], GFP_ATOMIC);
|
||||
if (!ctx->chain) {
|
||||
kfree(ctx->table);
|
||||
return -ENOMEM;
|
||||
|
||||
if (nla[NFTA_RULE_TABLE]) {
|
||||
ctx->table = nla_strdup(nla[NFTA_RULE_TABLE],
|
||||
GFP_ATOMIC);
|
||||
if (!ctx->table) {
|
||||
kfree(ctx);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if (nla[NFTA_RULE_CHAIN]) {
|
||||
ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN],
|
||||
GFP_ATOMIC);
|
||||
if (!ctx->chain) {
|
||||
kfree(ctx->table);
|
||||
kfree(ctx);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
|
||||
ctx->reset = true;
|
||||
|
||||
cb->data = ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nf_tables_dump_rules_done(struct netlink_callback *cb)
|
||||
{
|
||||
struct nft_rule_dump_ctx *ctx = cb->data;
|
||||
struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
|
||||
|
||||
if (ctx) {
|
||||
kfree(ctx->table);
|
||||
kfree(ctx->chain);
|
||||
kfree(ctx);
|
||||
}
|
||||
kfree(ctx->table);
|
||||
kfree(ctx->chain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue