@@ -2681,7 +2681,7 @@ static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
26812681};
26822682
26832683static int nf_tables_fill_expr_info (struct sk_buff * skb ,
2684- const struct nft_expr * expr )
2684+ const struct nft_expr * expr , bool reset )
26852685{
26862686 if (nla_put_string (skb , NFTA_EXPR_NAME , expr -> ops -> type -> name ))
26872687 goto nla_put_failure ;
@@ -2691,7 +2691,7 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
26912691 NFTA_EXPR_DATA );
26922692 if (data == NULL )
26932693 goto nla_put_failure ;
2694- if (expr -> ops -> dump (skb , expr , false ) < 0 )
2694+ if (expr -> ops -> dump (skb , expr , reset ) < 0 )
26952695 goto nla_put_failure ;
26962696 nla_nest_end (skb , data );
26972697 }
@@ -2703,14 +2703,14 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
27032703};
27042704
27052705int nft_expr_dump (struct sk_buff * skb , unsigned int attr ,
2706- const struct nft_expr * expr )
2706+ const struct nft_expr * expr , bool reset )
27072707{
27082708 struct nlattr * nest ;
27092709
27102710 nest = nla_nest_start_noflag (skb , attr );
27112711 if (!nest )
27122712 goto nla_put_failure ;
2713- if (nf_tables_fill_expr_info (skb , expr ) < 0 )
2713+ if (nf_tables_fill_expr_info (skb , expr , reset ) < 0 )
27142714 goto nla_put_failure ;
27152715 nla_nest_end (skb , nest );
27162716 return 0 ;
@@ -2919,7 +2919,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
29192919 u32 flags , int family ,
29202920 const struct nft_table * table ,
29212921 const struct nft_chain * chain ,
2922- const struct nft_rule * rule , u64 handle )
2922+ const struct nft_rule * rule , u64 handle ,
2923+ bool reset )
29232924{
29242925 struct nlmsghdr * nlh ;
29252926 const struct nft_expr * expr , * next ;
@@ -2952,7 +2953,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
29522953 if (list == NULL )
29532954 goto nla_put_failure ;
29542955 nft_rule_for_each_expr (expr , next , rule ) {
2955- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr ) < 0 )
2956+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , reset ) < 0 )
29562957 goto nla_put_failure ;
29572958 }
29582959 nla_nest_end (skb , list );
@@ -3003,7 +3004,7 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
30033004
30043005 err = nf_tables_fill_rule_info (skb , ctx -> net , ctx -> portid , ctx -> seq ,
30053006 event , flags , ctx -> family , ctx -> table ,
3006- ctx -> chain , rule , handle );
3007+ ctx -> chain , rule , handle , false );
30073008 if (err < 0 ) {
30083009 kfree_skb (skb );
30093010 goto err ;
@@ -3024,7 +3025,8 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
30243025 unsigned int * idx ,
30253026 struct netlink_callback * cb ,
30263027 const struct nft_table * table ,
3027- const struct nft_chain * chain )
3028+ const struct nft_chain * chain ,
3029+ bool reset )
30283030{
30293031 struct net * net = sock_net (skb -> sk );
30303032 const struct nft_rule * rule , * prule ;
@@ -3051,7 +3053,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
30513053 NFT_MSG_NEWRULE ,
30523054 NLM_F_MULTI | NLM_F_APPEND ,
30533055 table -> family ,
3054- table , chain , rule , handle ) < 0 )
3056+ table , chain , rule , handle , reset ) < 0 )
30553057 return 1 ;
30563058
30573059 nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
@@ -3074,6 +3076,10 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
30743076 struct net * net = sock_net (skb -> sk );
30753077 int family = nfmsg -> nfgen_family ;
30763078 struct nftables_pernet * nft_net ;
3079+ bool reset = false;
3080+
3081+ if (NFNL_MSG_TYPE (cb -> nlh -> nlmsg_type ) == NFT_MSG_GETRULE_RESET )
3082+ reset = true;
30773083
30783084 rcu_read_lock ();
30793085 nft_net = nft_pernet (net );
@@ -3098,14 +3104,15 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
30983104 if (!nft_is_active (net , chain ))
30993105 continue ;
31003106 __nf_tables_dump_rules (skb , & idx ,
3101- cb , table , chain );
3107+ cb , table , chain , reset );
31023108 break ;
31033109 }
31043110 goto done ;
31053111 }
31063112
31073113 list_for_each_entry_rcu (chain , & table -> chains , list ) {
3108- if (__nf_tables_dump_rules (skb , & idx , cb , table , chain ))
3114+ if (__nf_tables_dump_rules (skb , & idx ,
3115+ cb , table , chain , reset ))
31093116 goto done ;
31103117 }
31113118
@@ -3176,6 +3183,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
31763183 struct net * net = info -> net ;
31773184 struct nft_table * table ;
31783185 struct sk_buff * skb2 ;
3186+ bool reset = false;
31793187 int err ;
31803188
31813189 if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
@@ -3212,9 +3220,12 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
32123220 if (!skb2 )
32133221 return - ENOMEM ;
32143222
3223+ if (NFNL_MSG_TYPE (info -> nlh -> nlmsg_type ) == NFT_MSG_GETRULE_RESET )
3224+ reset = true;
3225+
32153226 err = nf_tables_fill_rule_info (skb2 , net , NETLINK_CB (skb ).portid ,
32163227 info -> nlh -> nlmsg_seq , NFT_MSG_NEWRULE , 0 ,
3217- family , table , chain , rule , 0 );
3228+ family , table , chain , rule , 0 , reset );
32183229 if (err < 0 )
32193230 goto err_fill_rule_info ;
32203231
@@ -4045,7 +4056,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
40454056
40464057 if (set -> num_exprs == 1 ) {
40474058 nest = nla_nest_start_noflag (skb , NFTA_SET_EXPR );
4048- if (nf_tables_fill_expr_info (skb , set -> exprs [0 ]) < 0 )
4059+ if (nf_tables_fill_expr_info (skb , set -> exprs [0 ], false ) < 0 )
40494060 goto nla_put_failure ;
40504061
40514062 nla_nest_end (skb , nest );
@@ -4056,7 +4067,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
40564067
40574068 for (i = 0 ; i < set -> num_exprs ; i ++ ) {
40584069 if (nft_expr_dump (skb , NFTA_LIST_ELEM ,
4059- set -> exprs [i ]) < 0 )
4070+ set -> exprs [i ], false ) < 0 )
40604071 goto nla_put_failure ;
40614072 }
40624073 nla_nest_end (skb , nest );
@@ -4959,7 +4970,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
49594970
49604971 if (num_exprs == 1 ) {
49614972 expr = nft_setelem_expr_at (elem_expr , 0 );
4962- if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr ) < 0 )
4973+ if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr , false ) < 0 )
49634974 return -1 ;
49644975
49654976 return 0 ;
@@ -4970,7 +4981,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
49704981
49714982 nft_setelem_expr_foreach (expr , elem_expr , size ) {
49724983 expr = nft_setelem_expr_at (elem_expr , size );
4973- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr ) < 0 )
4984+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , false ) < 0 )
49744985 goto nla_put_failure ;
49754986 }
49764987 nla_nest_end (skb , nest );
@@ -8281,6 +8292,12 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
82818292 .attr_count = NFTA_RULE_MAX ,
82828293 .policy = nft_rule_policy ,
82838294 },
8295+ [NFT_MSG_GETRULE_RESET ] = {
8296+ .call = nf_tables_getrule ,
8297+ .type = NFNL_CB_RCU ,
8298+ .attr_count = NFTA_RULE_MAX ,
8299+ .policy = nft_rule_policy ,
8300+ },
82848301 [NFT_MSG_DELRULE ] = {
82858302 .call = nf_tables_delrule ,
82868303 .type = NFNL_CB_BATCH ,
0 commit comments