18
18
#include <net/netfilter/nf_flow_table.h>
19
19
#include <net/netfilter/nf_tables_core.h>
20
20
#include <net/netfilter/nf_tables.h>
21
+ #include <net/netfilter/nf_tables_offload.h>
21
22
#include <net/net_namespace.h>
22
23
#include <net/sock.h>
23
24
@@ -97,6 +98,7 @@ static void nft_ctx_init(struct nft_ctx *ctx,
97
98
ctx -> nla = nla ;
98
99
ctx -> portid = NETLINK_CB (skb ).portid ;
99
100
ctx -> report = nlmsg_report (nlh );
101
+ ctx -> flags = nlh -> nlmsg_flags ;
100
102
ctx -> seq = nlh -> nlmsg_seq ;
101
103
}
102
104
@@ -1169,6 +1171,7 @@ static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
1169
1171
[NFTA_CHAIN_POLICY ] = { .type = NLA_U32 },
1170
1172
[NFTA_CHAIN_TYPE ] = { .type = NLA_STRING },
1171
1173
[NFTA_CHAIN_COUNTERS ] = { .type = NLA_NESTED },
1174
+ [NFTA_CHAIN_FLAGS ] = { .type = NLA_U32 },
1172
1175
};
1173
1176
1174
1177
static const struct nla_policy nft_hook_policy [NFTA_HOOK_MAX + 1 ] = {
@@ -1603,7 +1606,7 @@ static struct nft_rule **nf_tables_chain_alloc_rules(const struct nft_chain *cha
1603
1606
}
1604
1607
1605
1608
static int nf_tables_addchain (struct nft_ctx * ctx , u8 family , u8 genmask ,
1606
- u8 policy )
1609
+ u8 policy , u32 flags )
1607
1610
{
1608
1611
const struct nlattr * const * nla = ctx -> nla ;
1609
1612
struct nft_table * table = ctx -> table ;
@@ -1657,8 +1660,9 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1657
1660
ops -> hook = hook .type -> hooks [ops -> hooknum ];
1658
1661
ops -> dev = hook .dev ;
1659
1662
1660
- chain -> flags |= NFT_BASE_CHAIN ;
1663
+ chain -> flags |= NFT_BASE_CHAIN | flags ;
1661
1664
basechain -> policy = NF_ACCEPT ;
1665
+ INIT_LIST_HEAD (& basechain -> cb_list );
1662
1666
} else {
1663
1667
chain = kzalloc (sizeof (* chain ), GFP_KERNEL );
1664
1668
if (chain == NULL )
@@ -1718,7 +1722,8 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1718
1722
return err ;
1719
1723
}
1720
1724
1721
- static int nf_tables_updchain (struct nft_ctx * ctx , u8 genmask , u8 policy )
1725
+ static int nf_tables_updchain (struct nft_ctx * ctx , u8 genmask , u8 policy ,
1726
+ u32 flags )
1722
1727
{
1723
1728
const struct nlattr * const * nla = ctx -> nla ;
1724
1729
struct nft_table * table = ctx -> table ;
@@ -1730,6 +1735,9 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy)
1730
1735
struct nft_trans * trans ;
1731
1736
int err ;
1732
1737
1738
+ if (chain -> flags ^ flags )
1739
+ return - EOPNOTSUPP ;
1740
+
1733
1741
if (nla [NFTA_CHAIN_HOOK ]) {
1734
1742
if (!nft_is_base_chain (chain ))
1735
1743
return - EBUSY ;
@@ -1835,6 +1843,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1835
1843
u8 policy = NF_ACCEPT ;
1836
1844
struct nft_ctx ctx ;
1837
1845
u64 handle = 0 ;
1846
+ u32 flags = 0 ;
1838
1847
1839
1848
lockdep_assert_held (& net -> nft .commit_mutex );
1840
1849
@@ -1889,6 +1898,9 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1889
1898
}
1890
1899
}
1891
1900
1901
+ if (nla [NFTA_CHAIN_FLAGS ])
1902
+ flags = ntohl (nla_get_be32 (nla [NFTA_CHAIN_FLAGS ]));
1903
+
1892
1904
nft_ctx_init (& ctx , net , skb , nlh , family , table , chain , nla );
1893
1905
1894
1906
if (chain != NULL ) {
@@ -1899,10 +1911,10 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1899
1911
if (nlh -> nlmsg_flags & NLM_F_REPLACE )
1900
1912
return - EOPNOTSUPP ;
1901
1913
1902
- return nf_tables_updchain (& ctx , genmask , policy );
1914
+ return nf_tables_updchain (& ctx , genmask , policy , flags );
1903
1915
}
1904
1916
1905
- return nf_tables_addchain (& ctx , family , genmask , policy );
1917
+ return nf_tables_addchain (& ctx , family , genmask , policy , flags );
1906
1918
}
1907
1919
1908
1920
static int nf_tables_delchain (struct net * net , struct sock * nlsk ,
@@ -2658,6 +2670,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2658
2670
u8 genmask = nft_genmask_next (net );
2659
2671
struct nft_expr_info * info = NULL ;
2660
2672
int family = nfmsg -> nfgen_family ;
2673
+ struct nft_flow_rule * flow ;
2661
2674
struct nft_table * table ;
2662
2675
struct nft_chain * chain ;
2663
2676
struct nft_rule * rule , * old_rule = NULL ;
@@ -2804,7 +2817,8 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2804
2817
2805
2818
list_add_tail_rcu (& rule -> list , & old_rule -> list );
2806
2819
} else {
2807
- if (nft_trans_rule_add (& ctx , NFT_MSG_NEWRULE , rule ) == NULL ) {
2820
+ trans = nft_trans_rule_add (& ctx , NFT_MSG_NEWRULE , rule );
2821
+ if (!trans ) {
2808
2822
err = - ENOMEM ;
2809
2823
goto err2 ;
2810
2824
}
@@ -2827,6 +2841,14 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2827
2841
if (net -> nft .validate_state == NFT_VALIDATE_DO )
2828
2842
return nft_table_validate (net , table );
2829
2843
2844
+ if (chain -> flags & NFT_CHAIN_HW_OFFLOAD ) {
2845
+ flow = nft_flow_rule_create (rule );
2846
+ if (IS_ERR (flow ))
2847
+ return PTR_ERR (flow );
2848
+
2849
+ nft_trans_flow_rule (trans ) = flow ;
2850
+ }
2851
+
2830
2852
return 0 ;
2831
2853
err2 :
2832
2854
nf_tables_rule_release (& ctx , rule );
@@ -6624,6 +6646,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
6624
6646
struct nft_trans_elem * te ;
6625
6647
struct nft_chain * chain ;
6626
6648
struct nft_table * table ;
6649
+ int err ;
6627
6650
6628
6651
if (list_empty (& net -> nft .commit_list )) {
6629
6652
mutex_unlock (& net -> nft .commit_mutex );
@@ -6634,6 +6657,10 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
6634
6657
if (nf_tables_validate (net ) < 0 )
6635
6658
return - EAGAIN ;
6636
6659
6660
+ err = nft_flow_rule_offload_commit (net );
6661
+ if (err < 0 )
6662
+ return err ;
6663
+
6637
6664
/* 1. Allocate space for next generation rules_gen_X[] */
6638
6665
list_for_each_entry_safe (trans , next , & net -> nft .commit_list , list ) {
6639
6666
int ret ;
0 commit comments