Skip to content

Commit 1c5fc27

Browse files
committed
Merge tag 'nf-next-24-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next into main
Pablo Neira Ayuso says: ==================== Netfilter/IPVS updates for net-next The following patchset contains Netfilter/IPVS updates for net-next: Patch amazonlinux#1 to gregkh#11 to shrink memory consumption for transaction objects: struct nft_trans_chain { /* size: 120 (-32), cachelines: 2, members: 10 */ struct nft_trans_elem { /* size: 72 (-40), cachelines: 2, members: 4 */ struct nft_trans_flowtable { /* size: 80 (-48), cachelines: 2, members: 5 */ struct nft_trans_obj { /* size: 72 (-40), cachelines: 2, members: 4 */ struct nft_trans_rule { /* size: 80 (-32), cachelines: 2, members: 6 */ struct nft_trans_set { /* size: 96 (-24), cachelines: 2, members: 8 */ struct nft_trans_table { /* size: 56 (-40), cachelines: 1, members: 2 */ struct nft_trans_elem can now be allocated from kmalloc-96 instead of kmalloc-128 slab. Series from Florian Westphal. For the record, I have mangled patch amazonlinux#1 to add nft_trans_container_*() and use if for every transaction object. I have also added BUILD_BUG_ON to ensure struct nft_trans always comes at the beginning of the container transaction object. And few minor cleanups, any new bugs are of my own. Patch gregkh#12 simplify check for SCTP GSO in IPVS, from Ismael Luceno. Patch gregkh#13 nf_conncount key length remains in the u32 bound, from Yunjian Wang. Patch gregkh#14 removes unnecessary check for CTA_TIMEOUT_L3PROTO when setting default conntrack timeouts via nfnetlink_cttimeout API, from Lin Ma. Patch gregkh#15 updates NFT_SECMARK_CTX_MAXLEN to 4096, SELinux could use larger secctx names than the existing 256 bytes length. Patch gregkh#16 adds a selftest to exercise nfnetlink_queue listeners leaving nfnetlink_queue, from Florian Westphal. Patch gregkh#17 increases hitcount from 255 to 65535 in xt_recent, from Phil Sutter. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents a051091 + f4ebd03 commit 1c5fc27

File tree

10 files changed

+459
-278
lines changed

10 files changed

+459
-278
lines changed

include/net/netfilter/nf_tables.h

+146-76
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,7 @@ static inline bool nft_chain_is_bound(struct nft_chain *chain)
11761176

11771177
int nft_chain_add(struct nft_table *table, struct nft_chain *chain);
11781178
void nft_chain_del(struct nft_chain *chain);
1179-
void nf_tables_chain_destroy(struct nft_ctx *ctx);
1179+
void nf_tables_chain_destroy(struct nft_chain *chain);
11801180

11811181
struct nft_stats {
11821182
u64 bytes;
@@ -1613,41 +1613,67 @@ static inline int nft_set_elem_is_dead(const struct nft_set_ext *ext)
16131613
}
16141614

16151615
/**
1616-
* struct nft_trans - nf_tables object update in transaction
1616+
* struct nft_trans - nf_tables object update in transaction
16171617
*
1618-
* @list: used internally
1619-
* @binding_list: list of objects with possible bindings
1620-
* @msg_type: message type
1621-
* @put_net: ctx->net needs to be put
1622-
* @ctx: transaction context
1623-
* @data: internal information related to the transaction
1618+
* @list: used internally
1619+
* @net: struct net
1620+
* @table: struct nft_table the object resides in
1621+
* @msg_type: message type
1622+
* @seq: netlink sequence number
1623+
* @flags: modifiers to new request
1624+
* @report: notify via unicast netlink message
1625+
* @put_net: net needs to be put
1626+
*
1627+
* This is the information common to all objects in the transaction,
1628+
* this must always be the first member of derived sub-types.
16241629
*/
16251630
struct nft_trans {
16261631
struct list_head list;
1627-
struct list_head binding_list;
1632+
struct net *net;
1633+
struct nft_table *table;
16281634
int msg_type;
1629-
bool put_net;
1630-
struct nft_ctx ctx;
1631-
char data[];
1635+
u32 seq;
1636+
u16 flags;
1637+
u8 report:1;
1638+
u8 put_net:1;
1639+
};
1640+
1641+
/**
1642+
* struct nft_trans_binding - nf_tables object with binding support in transaction
1643+
* @nft_trans: base structure, MUST be first member
1644+
* @binding_list: list of objects with possible bindings
1645+
*
1646+
* This is the base type used by objects that can be bound to a chain.
1647+
*/
1648+
struct nft_trans_binding {
1649+
struct nft_trans nft_trans;
1650+
struct list_head binding_list;
16321651
};
16331652

16341653
struct nft_trans_rule {
1654+
struct nft_trans nft_trans;
16351655
struct nft_rule *rule;
1656+
struct nft_chain *chain;
16361657
struct nft_flow_rule *flow;
16371658
u32 rule_id;
16381659
bool bound;
16391660
};
16401661

1641-
#define nft_trans_rule(trans) \
1642-
(((struct nft_trans_rule *)trans->data)->rule)
1643-
#define nft_trans_flow_rule(trans) \
1644-
(((struct nft_trans_rule *)trans->data)->flow)
1645-
#define nft_trans_rule_id(trans) \
1646-
(((struct nft_trans_rule *)trans->data)->rule_id)
1647-
#define nft_trans_rule_bound(trans) \
1648-
(((struct nft_trans_rule *)trans->data)->bound)
1662+
#define nft_trans_container_rule(trans) \
1663+
container_of(trans, struct nft_trans_rule, nft_trans)
1664+
#define nft_trans_rule(trans) \
1665+
nft_trans_container_rule(trans)->rule
1666+
#define nft_trans_flow_rule(trans) \
1667+
nft_trans_container_rule(trans)->flow
1668+
#define nft_trans_rule_id(trans) \
1669+
nft_trans_container_rule(trans)->rule_id
1670+
#define nft_trans_rule_bound(trans) \
1671+
nft_trans_container_rule(trans)->bound
1672+
#define nft_trans_rule_chain(trans) \
1673+
nft_trans_container_rule(trans)->chain
16491674

16501675
struct nft_trans_set {
1676+
struct nft_trans_binding nft_trans_binding;
16511677
struct nft_set *set;
16521678
u32 set_id;
16531679
u32 gc_int;
@@ -1657,100 +1683,117 @@ struct nft_trans_set {
16571683
u32 size;
16581684
};
16591685

1660-
#define nft_trans_set(trans) \
1661-
(((struct nft_trans_set *)trans->data)->set)
1662-
#define nft_trans_set_id(trans) \
1663-
(((struct nft_trans_set *)trans->data)->set_id)
1664-
#define nft_trans_set_bound(trans) \
1665-
(((struct nft_trans_set *)trans->data)->bound)
1666-
#define nft_trans_set_update(trans) \
1667-
(((struct nft_trans_set *)trans->data)->update)
1668-
#define nft_trans_set_timeout(trans) \
1669-
(((struct nft_trans_set *)trans->data)->timeout)
1670-
#define nft_trans_set_gc_int(trans) \
1671-
(((struct nft_trans_set *)trans->data)->gc_int)
1672-
#define nft_trans_set_size(trans) \
1673-
(((struct nft_trans_set *)trans->data)->size)
1686+
#define nft_trans_container_set(t) \
1687+
container_of(t, struct nft_trans_set, nft_trans_binding.nft_trans)
1688+
#define nft_trans_set(trans) \
1689+
nft_trans_container_set(trans)->set
1690+
#define nft_trans_set_id(trans) \
1691+
nft_trans_container_set(trans)->set_id
1692+
#define nft_trans_set_bound(trans) \
1693+
nft_trans_container_set(trans)->bound
1694+
#define nft_trans_set_update(trans) \
1695+
nft_trans_container_set(trans)->update
1696+
#define nft_trans_set_timeout(trans) \
1697+
nft_trans_container_set(trans)->timeout
1698+
#define nft_trans_set_gc_int(trans) \
1699+
nft_trans_container_set(trans)->gc_int
1700+
#define nft_trans_set_size(trans) \
1701+
nft_trans_container_set(trans)->size
16741702

16751703
struct nft_trans_chain {
1704+
struct nft_trans_binding nft_trans_binding;
16761705
struct nft_chain *chain;
1677-
bool update;
16781706
char *name;
16791707
struct nft_stats __percpu *stats;
16801708
u8 policy;
1709+
bool update;
16811710
bool bound;
16821711
u32 chain_id;
16831712
struct nft_base_chain *basechain;
16841713
struct list_head hook_list;
16851714
};
16861715

1687-
#define nft_trans_chain(trans) \
1688-
(((struct nft_trans_chain *)trans->data)->chain)
1689-
#define nft_trans_chain_update(trans) \
1690-
(((struct nft_trans_chain *)trans->data)->update)
1691-
#define nft_trans_chain_name(trans) \
1692-
(((struct nft_trans_chain *)trans->data)->name)
1693-
#define nft_trans_chain_stats(trans) \
1694-
(((struct nft_trans_chain *)trans->data)->stats)
1695-
#define nft_trans_chain_policy(trans) \
1696-
(((struct nft_trans_chain *)trans->data)->policy)
1697-
#define nft_trans_chain_bound(trans) \
1698-
(((struct nft_trans_chain *)trans->data)->bound)
1699-
#define nft_trans_chain_id(trans) \
1700-
(((struct nft_trans_chain *)trans->data)->chain_id)
1701-
#define nft_trans_basechain(trans) \
1702-
(((struct nft_trans_chain *)trans->data)->basechain)
1703-
#define nft_trans_chain_hooks(trans) \
1704-
(((struct nft_trans_chain *)trans->data)->hook_list)
1716+
#define nft_trans_container_chain(t) \
1717+
container_of(t, struct nft_trans_chain, nft_trans_binding.nft_trans)
1718+
#define nft_trans_chain(trans) \
1719+
nft_trans_container_chain(trans)->chain
1720+
#define nft_trans_chain_update(trans) \
1721+
nft_trans_container_chain(trans)->update
1722+
#define nft_trans_chain_name(trans) \
1723+
nft_trans_container_chain(trans)->name
1724+
#define nft_trans_chain_stats(trans) \
1725+
nft_trans_container_chain(trans)->stats
1726+
#define nft_trans_chain_policy(trans) \
1727+
nft_trans_container_chain(trans)->policy
1728+
#define nft_trans_chain_bound(trans) \
1729+
nft_trans_container_chain(trans)->bound
1730+
#define nft_trans_chain_id(trans) \
1731+
nft_trans_container_chain(trans)->chain_id
1732+
#define nft_trans_basechain(trans) \
1733+
nft_trans_container_chain(trans)->basechain
1734+
#define nft_trans_chain_hooks(trans) \
1735+
nft_trans_container_chain(trans)->hook_list
17051736

17061737
struct nft_trans_table {
1738+
struct nft_trans nft_trans;
17071739
bool update;
17081740
};
17091741

1710-
#define nft_trans_table_update(trans) \
1711-
(((struct nft_trans_table *)trans->data)->update)
1742+
#define nft_trans_container_table(trans) \
1743+
container_of(trans, struct nft_trans_table, nft_trans)
1744+
#define nft_trans_table_update(trans) \
1745+
nft_trans_container_table(trans)->update
17121746

17131747
struct nft_trans_elem {
1748+
struct nft_trans nft_trans;
17141749
struct nft_set *set;
17151750
struct nft_elem_priv *elem_priv;
17161751
bool bound;
17171752
};
17181753

1719-
#define nft_trans_elem_set(trans) \
1720-
(((struct nft_trans_elem *)trans->data)->set)
1721-
#define nft_trans_elem_priv(trans) \
1722-
(((struct nft_trans_elem *)trans->data)->elem_priv)
1723-
#define nft_trans_elem_set_bound(trans) \
1724-
(((struct nft_trans_elem *)trans->data)->bound)
1754+
#define nft_trans_container_elem(t) \
1755+
container_of(t, struct nft_trans_elem, nft_trans)
1756+
#define nft_trans_elem_set(trans) \
1757+
nft_trans_container_elem(trans)->set
1758+
#define nft_trans_elem_priv(trans) \
1759+
nft_trans_container_elem(trans)->elem_priv
1760+
#define nft_trans_elem_set_bound(trans) \
1761+
nft_trans_container_elem(trans)->bound
17251762

17261763
struct nft_trans_obj {
1764+
struct nft_trans nft_trans;
17271765
struct nft_object *obj;
17281766
struct nft_object *newobj;
17291767
bool update;
17301768
};
17311769

1732-
#define nft_trans_obj(trans) \
1733-
(((struct nft_trans_obj *)trans->data)->obj)
1734-
#define nft_trans_obj_newobj(trans) \
1735-
(((struct nft_trans_obj *)trans->data)->newobj)
1736-
#define nft_trans_obj_update(trans) \
1737-
(((struct nft_trans_obj *)trans->data)->update)
1770+
#define nft_trans_container_obj(t) \
1771+
container_of(t, struct nft_trans_obj, nft_trans)
1772+
#define nft_trans_obj(trans) \
1773+
nft_trans_container_obj(trans)->obj
1774+
#define nft_trans_obj_newobj(trans) \
1775+
nft_trans_container_obj(trans)->newobj
1776+
#define nft_trans_obj_update(trans) \
1777+
nft_trans_container_obj(trans)->update
17381778

17391779
struct nft_trans_flowtable {
1780+
struct nft_trans nft_trans;
17401781
struct nft_flowtable *flowtable;
1741-
bool update;
17421782
struct list_head hook_list;
17431783
u32 flags;
1784+
bool update;
17441785
};
17451786

1746-
#define nft_trans_flowtable(trans) \
1747-
(((struct nft_trans_flowtable *)trans->data)->flowtable)
1748-
#define nft_trans_flowtable_update(trans) \
1749-
(((struct nft_trans_flowtable *)trans->data)->update)
1750-
#define nft_trans_flowtable_hooks(trans) \
1751-
(((struct nft_trans_flowtable *)trans->data)->hook_list)
1752-
#define nft_trans_flowtable_flags(trans) \
1753-
(((struct nft_trans_flowtable *)trans->data)->flags)
1787+
#define nft_trans_container_flowtable(t) \
1788+
container_of(t, struct nft_trans_flowtable, nft_trans)
1789+
#define nft_trans_flowtable(trans) \
1790+
nft_trans_container_flowtable(trans)->flowtable
1791+
#define nft_trans_flowtable_update(trans) \
1792+
nft_trans_container_flowtable(trans)->update
1793+
#define nft_trans_flowtable_hooks(trans) \
1794+
nft_trans_container_flowtable(trans)->hook_list
1795+
#define nft_trans_flowtable_flags(trans) \
1796+
nft_trans_container_flowtable(trans)->flags
17541797

17551798
#define NFT_TRANS_GC_BATCHCOUNT 256
17561799

@@ -1764,6 +1807,33 @@ struct nft_trans_gc {
17641807
struct rcu_head rcu;
17651808
};
17661809

1810+
static inline void nft_ctx_update(struct nft_ctx *ctx,
1811+
const struct nft_trans *trans)
1812+
{
1813+
switch (trans->msg_type) {
1814+
case NFT_MSG_NEWRULE:
1815+
case NFT_MSG_DELRULE:
1816+
case NFT_MSG_DESTROYRULE:
1817+
ctx->chain = nft_trans_rule_chain(trans);
1818+
break;
1819+
case NFT_MSG_NEWCHAIN:
1820+
case NFT_MSG_DELCHAIN:
1821+
case NFT_MSG_DESTROYCHAIN:
1822+
ctx->chain = nft_trans_chain(trans);
1823+
break;
1824+
default:
1825+
ctx->chain = NULL;
1826+
break;
1827+
}
1828+
1829+
ctx->net = trans->net;
1830+
ctx->table = trans->table;
1831+
ctx->family = trans->table->family;
1832+
ctx->report = trans->report;
1833+
ctx->flags = trans->flags;
1834+
ctx->seq = trans->seq;
1835+
}
1836+
17671837
struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
17681838
unsigned int gc_seq, gfp_t gfp);
17691839
void nft_trans_gc_destroy(struct nft_trans_gc *trans);

include/uapi/linux/netfilter/nf_tables.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,7 @@ enum nft_secmark_attributes {
13761376
#define NFTA_SECMARK_MAX (__NFTA_SECMARK_MAX - 1)
13771377

13781378
/* Max security context length */
1379-
#define NFT_SECMARK_CTX_MAXLEN 256
1379+
#define NFT_SECMARK_CTX_MAXLEN 4096
13801380

13811381
/**
13821382
* enum nft_reject_types - nf_tables reject expression reject types

net/netfilter/ipvs/ip_vs_proto_sctp.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
126126
if (sctph->source != cp->vport || payload_csum ||
127127
skb->ip_summed == CHECKSUM_PARTIAL) {
128128
sctph->source = cp->vport;
129-
if (!skb_is_gso(skb) || !skb_is_gso_sctp(skb))
129+
if (!skb_is_gso(skb))
130130
sctp_nat_csum(skb, sctph, sctphoff);
131131
} else {
132132
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -175,7 +175,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
175175
(skb->ip_summed == CHECKSUM_PARTIAL &&
176176
!(skb_dst(skb)->dev->features & NETIF_F_SCTP_CRC))) {
177177
sctph->dest = cp->dport;
178-
if (!skb_is_gso(skb) || !skb_is_gso_sctp(skb))
178+
if (!skb_is_gso(skb))
179179
sctp_nat_csum(skb, sctph, sctphoff);
180180
} else if (skb->ip_summed != CHECKSUM_PARTIAL) {
181181
skb->ip_summed = CHECKSUM_UNNECESSARY;

net/netfilter/nf_conncount.c

+3-5
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,6 @@ insert_tree(struct net *net,
321321
struct nf_conncount_rb *rbconn;
322322
struct nf_conncount_tuple *conn;
323323
unsigned int count = 0, gc_count = 0;
324-
u8 keylen = data->keylen;
325324
bool do_gc = true;
326325

327326
spin_lock_bh(&nf_conncount_locks[hash]);
@@ -333,7 +332,7 @@ insert_tree(struct net *net,
333332
rbconn = rb_entry(*rbnode, struct nf_conncount_rb, node);
334333

335334
parent = *rbnode;
336-
diff = key_diff(key, rbconn->key, keylen);
335+
diff = key_diff(key, rbconn->key, data->keylen);
337336
if (diff < 0) {
338337
rbnode = &((*rbnode)->rb_left);
339338
} else if (diff > 0) {
@@ -378,7 +377,7 @@ insert_tree(struct net *net,
378377

379378
conn->tuple = *tuple;
380379
conn->zone = *zone;
381-
memcpy(rbconn->key, key, sizeof(u32) * keylen);
380+
memcpy(rbconn->key, key, sizeof(u32) * data->keylen);
382381

383382
nf_conncount_list_init(&rbconn->list);
384383
list_add(&conn->node, &rbconn->list.head);
@@ -403,7 +402,6 @@ count_tree(struct net *net,
403402
struct rb_node *parent;
404403
struct nf_conncount_rb *rbconn;
405404
unsigned int hash;
406-
u8 keylen = data->keylen;
407405

408406
hash = jhash2(key, data->keylen, conncount_rnd) % CONNCOUNT_SLOTS;
409407
root = &data->root[hash];
@@ -414,7 +412,7 @@ count_tree(struct net *net,
414412

415413
rbconn = rb_entry(parent, struct nf_conncount_rb, node);
416414

417-
diff = key_diff(key, rbconn->key, keylen);
415+
diff = key_diff(key, rbconn->key, data->keylen);
418416
if (diff < 0) {
419417
parent = rcu_dereference_raw(parent->rb_left);
420418
} else if (diff > 0) {

0 commit comments

Comments
 (0)