mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
net/sched: act_ct: Fill offloading tuple iifidx
Driver offloading ct tuples can use the information of which devices received the packets that created the offloaded connections, to more efficiently offload them only to the relevant device. Add new act_ct nf conntrack extension, which is used to store the skb devices before offloading the connection, and then fill in the tuple iifindex so drivers can get the device via metadata dissector match. Signed-off-by: Oz Shlomo <ozsh@nvidia.com> Signed-off-by: Paul Blakey <paulb@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9d2c27aad0
commit
9795ded7f9
50
include/net/netfilter/nf_conntrack_act_ct.h
Normal file
50
include/net/netfilter/nf_conntrack_act_ct.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _NF_CONNTRACK_ACT_CT_H
|
||||
#define _NF_CONNTRACK_ACT_CT_H
|
||||
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
#include <net/netfilter/nf_conntrack_extend.h>
|
||||
|
||||
struct nf_conn_act_ct_ext {
|
||||
int ifindex[IP_CT_DIR_MAX];
|
||||
};
|
||||
|
||||
static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_find(const struct nf_conn *ct)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_NET_ACT_CT)
|
||||
return nf_ct_ext_find(ct, NF_CT_EXT_ACT_CT);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_add(struct nf_conn *ct)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_NET_ACT_CT)
|
||||
struct nf_conn_act_ct_ext *act_ct = nf_ct_ext_find(ct, NF_CT_EXT_ACT_CT);
|
||||
|
||||
if (act_ct)
|
||||
return act_ct;
|
||||
|
||||
act_ct = nf_ct_ext_add(ct, NF_CT_EXT_ACT_CT, GFP_ATOMIC);
|
||||
return act_ct;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void nf_conn_act_ct_ext_fill(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_NET_ACT_CT)
|
||||
struct nf_conn_act_ct_ext *act_ct_ext;
|
||||
|
||||
act_ct_ext = nf_conn_act_ct_ext_find(ct);
|
||||
if (dev_net(skb->dev) == &init_net && act_ct_ext)
|
||||
act_ct_ext->ifindex[CTINFO2DIR(ctinfo)] = skb->dev->ifindex;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _NF_CONNTRACK_ACT_CT_H */
|
@ -27,6 +27,9 @@ enum nf_ct_ext_id {
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY)
|
||||
NF_CT_EXT_SYNPROXY,
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_NET_ACT_CT)
|
||||
NF_CT_EXT_ACT_CT,
|
||||
#endif
|
||||
NF_CT_EXT_NUM,
|
||||
};
|
||||
@ -40,6 +43,7 @@ enum nf_ct_ext_id {
|
||||
#define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout
|
||||
#define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels
|
||||
#define NF_CT_EXT_SYNPROXY_TYPE struct nf_conn_synproxy
|
||||
#define NF_CT_EXT_ACT_CT_TYPE struct nf_conn_act_ct_ext
|
||||
|
||||
/* Extensions: optional stuff which isn't permanently in struct. */
|
||||
struct nf_ct_ext {
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <net/netfilter/nf_conntrack_timeout.h>
|
||||
#include <net/netfilter/nf_conntrack_labels.h>
|
||||
#include <net/netfilter/nf_conntrack_synproxy.h>
|
||||
#include <net/netfilter/nf_conntrack_act_ct.h>
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
#include <net/netfilter/nf_nat_helper.h>
|
||||
#include <net/netns/hash.h>
|
||||
@ -2626,7 +2627,7 @@ int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp)
|
||||
static __always_inline unsigned int total_extension_size(void)
|
||||
{
|
||||
/* remember to add new extensions below */
|
||||
BUILD_BUG_ON(NF_CT_EXT_NUM > 9);
|
||||
BUILD_BUG_ON(NF_CT_EXT_NUM > 10);
|
||||
|
||||
return sizeof(struct nf_ct_ext) +
|
||||
sizeof(struct nf_conn_help)
|
||||
@ -2649,6 +2650,9 @@ static __always_inline unsigned int total_extension_size(void)
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY)
|
||||
+ sizeof(struct nf_conn_synproxy)
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_NET_ACT_CT)
|
||||
+ sizeof(struct nf_conn_act_ct_ext)
|
||||
#endif
|
||||
;
|
||||
};
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <net/netfilter/nf_conntrack_helper.h>
|
||||
#include <net/netfilter/nf_conntrack_acct.h>
|
||||
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
|
||||
#include <net/netfilter/nf_conntrack_act_ct.h>
|
||||
#include <uapi/linux/netfilter/nf_nat.h>
|
||||
|
||||
static struct workqueue_struct *act_ct_wq;
|
||||
@ -56,6 +57,12 @@ static const struct rhashtable_params zones_params = {
|
||||
.automatic_shrinking = true,
|
||||
};
|
||||
|
||||
static struct nf_ct_ext_type act_ct_extend __read_mostly = {
|
||||
.len = sizeof(struct nf_conn_act_ct_ext),
|
||||
.align = __alignof__(struct nf_conn_act_ct_ext),
|
||||
.id = NF_CT_EXT_ACT_CT,
|
||||
};
|
||||
|
||||
static struct flow_action_entry *
|
||||
tcf_ct_flow_table_flow_action_get_next(struct flow_action *flow_action)
|
||||
{
|
||||
@ -358,6 +365,7 @@ static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
|
||||
struct nf_conn *ct,
|
||||
bool tcp)
|
||||
{
|
||||
struct nf_conn_act_ct_ext *act_ct_ext;
|
||||
struct flow_offload *entry;
|
||||
int err;
|
||||
|
||||
@ -375,6 +383,14 @@ static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
|
||||
ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
||||
}
|
||||
|
||||
act_ct_ext = nf_conn_act_ct_ext_find(ct);
|
||||
if (act_ct_ext) {
|
||||
entry->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx =
|
||||
act_ct_ext->ifindex[IP_CT_DIR_ORIGINAL];
|
||||
entry->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.iifidx =
|
||||
act_ct_ext->ifindex[IP_CT_DIR_REPLY];
|
||||
}
|
||||
|
||||
err = flow_offload_add(&ct_ft->nf_ft, entry);
|
||||
if (err)
|
||||
goto err_add;
|
||||
@ -1027,6 +1043,7 @@ do_nat:
|
||||
if (!ct)
|
||||
goto out_push;
|
||||
nf_ct_deliver_cached_events(ct);
|
||||
nf_conn_act_ct_ext_fill(skb, ct, ctinfo);
|
||||
|
||||
err = tcf_ct_act_nat(skb, ct, ctinfo, p->ct_action, &p->range, commit);
|
||||
if (err != NF_ACCEPT)
|
||||
@ -1036,6 +1053,9 @@ do_nat:
|
||||
tcf_ct_act_set_mark(ct, p->mark, p->mark_mask);
|
||||
tcf_ct_act_set_labels(ct, p->labels, p->labels_mask);
|
||||
|
||||
if (!nf_ct_is_confirmed(ct))
|
||||
nf_conn_act_ct_ext_add(ct);
|
||||
|
||||
/* This will take care of sending queued events
|
||||
* even if the connection is already confirmed.
|
||||
*/
|
||||
@ -1583,10 +1603,16 @@ static int __init ct_init_module(void)
|
||||
if (err)
|
||||
goto err_register;
|
||||
|
||||
err = nf_ct_extend_register(&act_ct_extend);
|
||||
if (err)
|
||||
goto err_register_extend;
|
||||
|
||||
static_branch_inc(&tcf_frag_xmit_count);
|
||||
|
||||
return 0;
|
||||
|
||||
err_register_extend:
|
||||
tcf_unregister_action(&act_ct_ops, &ct_net_ops);
|
||||
err_register:
|
||||
tcf_ct_flow_tables_uninit();
|
||||
err_tbl_init:
|
||||
@ -1597,6 +1623,7 @@ err_tbl_init:
|
||||
static void __exit ct_cleanup_module(void)
|
||||
{
|
||||
static_branch_dec(&tcf_frag_xmit_count);
|
||||
nf_ct_extend_unregister(&act_ct_extend);
|
||||
tcf_unregister_action(&act_ct_ops, &ct_net_ops);
|
||||
tcf_ct_flow_tables_uninit();
|
||||
destroy_workqueue(act_ct_wq);
|
||||
|
Loading…
Reference in New Issue
Block a user