Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+50 -81
+10 -4
include/net/netfilter/nf_conntrack.h
··· 160 160 return read_pnet(&ct->ct_net); 161 161 } 162 162 163 - /* Alter reply tuple (maybe alter helper). */ 164 - void nf_conntrack_alter_reply(struct nf_conn *ct, 165 - const struct nf_conntrack_tuple *newreply); 166 - 167 163 /* Is this tuple taken? (ignoring any belonging to the given 168 164 conntrack). */ 169 165 int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, ··· 278 282 static inline bool nf_is_loopback_packet(const struct sk_buff *skb) 279 283 { 280 284 return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK; 285 + } 286 + 287 + static inline void nf_conntrack_alter_reply(struct nf_conn *ct, 288 + const struct nf_conntrack_tuple *newreply) 289 + { 290 + /* Must be unconfirmed, so not in hash table yet */ 291 + if (WARN_ON(nf_ct_is_confirmed(ct))) 292 + return; 293 + 294 + ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; 281 295 } 282 296 283 297 #define nfct_time_stamp ((u32)(jiffies))
+4 -1
include/net/netfilter/nf_tables.h
··· 1198 1198 * @hgenerator: handle generator state 1199 1199 * @handle: table handle 1200 1200 * @use: number of chain references to this table 1201 + * @family:address family 1201 1202 * @flags: table flag (see enum nft_table_flags) 1202 1203 * @genmask: generation mask 1203 - * @afinfo: address family info 1204 + * @nlpid: netlink port ID 1204 1205 * @name: name of the table 1206 + * @udlen: length of the user data 1207 + * @udata: user data 1205 1208 * @validate_state: internal, set when transaction adds jumps 1206 1209 */ 1207 1210 struct nft_table {
-18
net/netfilter/nf_conntrack_core.c
··· 2042 2042 } 2043 2043 EXPORT_SYMBOL_GPL(nf_conntrack_in); 2044 2044 2045 - /* Alter reply tuple (maybe alter helper). This is for NAT, and is 2046 - implicitly racy: see __nf_conntrack_confirm */ 2047 - void nf_conntrack_alter_reply(struct nf_conn *ct, 2048 - const struct nf_conntrack_tuple *newreply) 2049 - { 2050 - struct nf_conn_help *help = nfct_help(ct); 2051 - 2052 - /* Should be unconfirmed, so not in hash table yet */ 2053 - WARN_ON(nf_ct_is_confirmed(ct)); 2054 - 2055 - nf_ct_dump_tuple(newreply); 2056 - 2057 - ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; 2058 - if (ct->master || (help && !hlist_empty(&help->expectations))) 2059 - return; 2060 - } 2061 - EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply); 2062 - 2063 2045 /* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */ 2064 2046 void __nf_ct_refresh_acct(struct nf_conn *ct, 2065 2047 enum ip_conntrack_info ctinfo,
+1 -6
net/netfilter/nf_conntrack_helper.c
··· 194 194 struct nf_conntrack_helper *helper = NULL; 195 195 struct nf_conn_help *help; 196 196 197 - /* We already got a helper explicitly attached. The function 198 - * nf_conntrack_alter_reply - in case NAT is in use - asks for looking 199 - * the helper up again. Since now the user is in full control of 200 - * making consistent helper configurations, skip this automatic 201 - * re-lookup, otherwise we'll lose the helper. 202 - */ 197 + /* We already got a helper explicitly attached (e.g. nft_ct) */ 203 198 if (test_bit(IPS_HELPER_BIT, &ct->status)) 204 199 return 0; 205 200
+4 -3
net/netfilter/nf_conntrack_proto_tcp.c
··· 835 835 836 836 static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb, 837 837 unsigned int dataoff, 838 - const struct tcphdr *th) 838 + const struct tcphdr *th, 839 + const struct nf_hook_state *state) 839 840 { 840 841 enum tcp_conntrack new_state; 841 842 struct net *net = nf_ct_net(ct); ··· 847 846 848 847 /* Invalid: delete conntrack */ 849 848 if (new_state >= TCP_CONNTRACK_MAX) { 850 - pr_debug("nf_ct_tcp: invalid new deleting.\n"); 849 + tcp_error_log(skb, state, "invalid new"); 851 850 return false; 852 851 } 853 852 ··· 981 980 if (tcp_error(th, skb, dataoff, state)) 982 981 return -NF_ACCEPT; 983 982 984 - if (!nf_ct_is_confirmed(ct) && !tcp_new(ct, skb, dataoff, th)) 983 + if (!nf_ct_is_confirmed(ct) && !tcp_new(ct, skb, dataoff, th, state)) 985 984 return -NF_ACCEPT; 986 985 987 986 spin_lock_bh(&ct->lock);
+31 -49
net/netfilter/nf_tables_api.c
··· 3441 3441 } 3442 3442 3443 3443 struct nft_rule_dump_ctx { 3444 + unsigned int s_idx; 3444 3445 char *table; 3445 3446 char *chain; 3447 + bool reset; 3446 3448 }; 3447 3449 3448 3450 static int __nf_tables_dump_rules(struct sk_buff *skb, 3449 3451 unsigned int *idx, 3450 3452 struct netlink_callback *cb, 3451 3453 const struct nft_table *table, 3452 - const struct nft_chain *chain, 3453 - bool reset) 3454 + const struct nft_chain *chain) 3454 3455 { 3456 + struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; 3455 3457 struct net *net = sock_net(skb->sk); 3456 3458 const struct nft_rule *rule, *prule; 3457 - unsigned int s_idx = cb->args[0]; 3458 3459 unsigned int entries = 0; 3459 3460 int ret = 0; 3460 3461 u64 handle; ··· 3464 3463 list_for_each_entry_rcu(rule, &chain->rules, list) { 3465 3464 if (!nft_is_active(net, rule)) 3466 3465 goto cont_skip; 3467 - if (*idx < s_idx) 3466 + if (*idx < ctx->s_idx) 3468 3467 goto cont; 3469 - if (*idx > s_idx) { 3470 - memset(&cb->args[1], 0, 3471 - sizeof(cb->args) - sizeof(cb->args[0])); 3472 - } 3473 3468 if (prule) 3474 3469 handle = prule->handle; 3475 3470 else ··· 3476 3479 NFT_MSG_NEWRULE, 3477 3480 NLM_F_MULTI | NLM_F_APPEND, 3478 3481 table->family, 3479 - table, chain, rule, handle, reset) < 0) { 3482 + table, chain, rule, handle, ctx->reset) < 0) { 3480 3483 ret = 1; 3481 3484 break; 3482 3485 } ··· 3488 3491 (*idx)++; 3489 3492 } 3490 3493 3491 - if (reset && entries) 3494 + if (ctx->reset && entries) 3492 3495 audit_log_rule_reset(table, cb->seq, entries); 3493 3496 3494 3497 return ret; ··· 3498 3501 struct netlink_callback *cb) 3499 3502 { 3500 3503 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); 3501 - const struct nft_rule_dump_ctx *ctx = cb->data; 3504 + struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; 3502 3505 struct nft_table *table; 3503 3506 const struct nft_chain *chain; 3504 3507 unsigned int idx = 0; 3505 3508 struct net *net = sock_net(skb->sk); 3506 3509 int family = nfmsg->nfgen_family; 3507 3510 struct nftables_pernet *nft_net; 3508 - bool reset = false; 3509 - 3510 - if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET) 3511 - reset = true; 3512 3511 3513 3512 rcu_read_lock(); 3514 3513 nft_net = nft_pernet(net); ··· 3514 3521 if (family != NFPROTO_UNSPEC && family != table->family) 3515 3522 continue; 3516 3523 3517 - if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0) 3524 + if (ctx->table && strcmp(ctx->table, table->name) != 0) 3518 3525 continue; 3519 3526 3520 - if (ctx && ctx->table && ctx->chain) { 3527 + if (ctx->table && ctx->chain) { 3521 3528 struct rhlist_head *list, *tmp; 3522 3529 3523 3530 list = rhltable_lookup(&table->chains_ht, ctx->chain, ··· 3529 3536 if (!nft_is_active(net, chain)) 3530 3537 continue; 3531 3538 __nf_tables_dump_rules(skb, &idx, 3532 - cb, table, chain, reset); 3539 + cb, table, chain); 3533 3540 break; 3534 3541 } 3535 3542 goto done; ··· 3537 3544 3538 3545 list_for_each_entry_rcu(chain, &table->chains, list) { 3539 3546 if (__nf_tables_dump_rules(skb, &idx, 3540 - cb, table, chain, reset)) 3547 + cb, table, chain)) 3541 3548 goto done; 3542 3549 } 3543 3550 3544 - if (ctx && ctx->table) 3551 + if (ctx->table) 3545 3552 break; 3546 3553 } 3547 3554 done: 3548 3555 rcu_read_unlock(); 3549 3556 3550 - cb->args[0] = idx; 3557 + ctx->s_idx = idx; 3551 3558 return skb->len; 3552 3559 } 3553 3560 3554 3561 static int nf_tables_dump_rules_start(struct netlink_callback *cb) 3555 3562 { 3563 + struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; 3556 3564 const struct nlattr * const *nla = cb->data; 3557 - struct nft_rule_dump_ctx *ctx = NULL; 3558 3565 3559 - if (nla[NFTA_RULE_TABLE] || nla[NFTA_RULE_CHAIN]) { 3560 - ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); 3561 - if (!ctx) 3566 + BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx)); 3567 + 3568 + if (nla[NFTA_RULE_TABLE]) { 3569 + ctx->table = nla_strdup(nla[NFTA_RULE_TABLE], GFP_ATOMIC); 3570 + if (!ctx->table) 3562 3571 return -ENOMEM; 3563 - 3564 - if (nla[NFTA_RULE_TABLE]) { 3565 - ctx->table = nla_strdup(nla[NFTA_RULE_TABLE], 3566 - GFP_ATOMIC); 3567 - if (!ctx->table) { 3568 - kfree(ctx); 3569 - return -ENOMEM; 3570 - } 3571 - } 3572 - if (nla[NFTA_RULE_CHAIN]) { 3573 - ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN], 3574 - GFP_ATOMIC); 3575 - if (!ctx->chain) { 3576 - kfree(ctx->table); 3577 - kfree(ctx); 3578 - return -ENOMEM; 3579 - } 3572 + } 3573 + if (nla[NFTA_RULE_CHAIN]) { 3574 + ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN], GFP_ATOMIC); 3575 + if (!ctx->chain) { 3576 + kfree(ctx->table); 3577 + return -ENOMEM; 3580 3578 } 3581 3579 } 3580 + if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET) 3581 + ctx->reset = true; 3582 3582 3583 - cb->data = ctx; 3584 3583 return 0; 3585 3584 } 3586 3585 3587 3586 static int nf_tables_dump_rules_done(struct netlink_callback *cb) 3588 3587 { 3589 - struct nft_rule_dump_ctx *ctx = cb->data; 3588 + struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; 3590 3589 3591 - if (ctx) { 3592 - kfree(ctx->table); 3593 - kfree(ctx->chain); 3594 - kfree(ctx); 3595 - } 3590 + kfree(ctx->table); 3591 + kfree(ctx->chain); 3596 3592 return 0; 3597 3593 } 3598 3594