@@ -2772,7 +2772,7 @@ static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
27722772};
27732773
27742774static int nf_tables_fill_expr_info (struct sk_buff * skb ,
2775- const struct nft_expr * expr )
2775+ const struct nft_expr * expr , bool reset )
27762776{
27772777 if (nla_put_string (skb , NFTA_EXPR_NAME , expr -> ops -> type -> name ))
27782778 goto nla_put_failure ;
@@ -2782,7 +2782,7 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
27822782 NFTA_EXPR_DATA );
27832783 if (data == NULL )
27842784 goto nla_put_failure ;
2785- if (expr -> ops -> dump (skb , expr , false ) < 0 )
2785+ if (expr -> ops -> dump (skb , expr , reset ) < 0 )
27862786 goto nla_put_failure ;
27872787 nla_nest_end (skb , data );
27882788 }
@@ -2794,14 +2794,14 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
27942794};
27952795
27962796int nft_expr_dump (struct sk_buff * skb , unsigned int attr ,
2797- const struct nft_expr * expr )
2797+ const struct nft_expr * expr , bool reset )
27982798{
27992799 struct nlattr * nest ;
28002800
28012801 nest = nla_nest_start_noflag (skb , attr );
28022802 if (!nest )
28032803 goto nla_put_failure ;
2804- if (nf_tables_fill_expr_info (skb , expr ) < 0 )
2804+ if (nf_tables_fill_expr_info (skb , expr , reset ) < 0 )
28052805 goto nla_put_failure ;
28062806 nla_nest_end (skb , nest );
28072807 return 0 ;
@@ -3010,7 +3010,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
30103010 u32 flags , int family ,
30113011 const struct nft_table * table ,
30123012 const struct nft_chain * chain ,
3013- const struct nft_rule * rule , u64 handle )
3013+ const struct nft_rule * rule , u64 handle ,
3014+ bool reset )
30143015{
30153016 struct nlmsghdr * nlh ;
30163017 const struct nft_expr * expr , * next ;
@@ -3043,7 +3044,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
30433044 if (list == NULL )
30443045 goto nla_put_failure ;
30453046 nft_rule_for_each_expr (expr , next , rule ) {
3046- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr ) < 0 )
3047+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , reset ) < 0 )
30473048 goto nla_put_failure ;
30483049 }
30493050 nla_nest_end (skb , list );
@@ -3094,7 +3095,7 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
30943095
30953096 err = nf_tables_fill_rule_info (skb , ctx -> net , ctx -> portid , ctx -> seq ,
30963097 event , flags , ctx -> family , ctx -> table ,
3097- ctx -> chain , rule , handle );
3098+ ctx -> chain , rule , handle , false );
30983099 if (err < 0 ) {
30993100 kfree_skb (skb );
31003101 goto err ;
@@ -3115,7 +3116,8 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
31153116 unsigned int * idx ,
31163117 struct netlink_callback * cb ,
31173118 const struct nft_table * table ,
3118- const struct nft_chain * chain )
3119+ const struct nft_chain * chain ,
3120+ bool reset )
31193121{
31203122 struct net * net = sock_net (skb -> sk );
31213123 const struct nft_rule * rule , * prule ;
@@ -3142,7 +3144,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
31423144 NFT_MSG_NEWRULE ,
31433145 NLM_F_MULTI | NLM_F_APPEND ,
31443146 table -> family ,
3145- table , chain , rule , handle ) < 0 )
3147+ table , chain , rule , handle , reset ) < 0 )
31463148 return 1 ;
31473149
31483150 nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
@@ -3165,6 +3167,10 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
31653167 struct net * net = sock_net (skb -> sk );
31663168 int family = nfmsg -> nfgen_family ;
31673169 struct nftables_pernet * nft_net ;
3170+ bool reset = false;
3171+
3172+ if (NFNL_MSG_TYPE (cb -> nlh -> nlmsg_type ) == NFT_MSG_GETRULE_RESET )
3173+ reset = true;
31683174
31693175 rcu_read_lock ();
31703176 nft_net = nft_pernet (net );
@@ -3189,14 +3195,15 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
31893195 if (!nft_is_active (net , chain ))
31903196 continue ;
31913197 __nf_tables_dump_rules (skb , & idx ,
3192- cb , table , chain );
3198+ cb , table , chain , reset );
31933199 break ;
31943200 }
31953201 goto done ;
31963202 }
31973203
31983204 list_for_each_entry_rcu (chain , & table -> chains , list ) {
3199- if (__nf_tables_dump_rules (skb , & idx , cb , table , chain ))
3205+ if (__nf_tables_dump_rules (skb , & idx ,
3206+ cb , table , chain , reset ))
32003207 goto done ;
32013208 }
32023209
@@ -3267,6 +3274,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
32673274 struct net * net = info -> net ;
32683275 struct nft_table * table ;
32693276 struct sk_buff * skb2 ;
3277+ bool reset = false;
32703278 int err ;
32713279
32723280 if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
@@ -3303,9 +3311,12 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
33033311 if (!skb2 )
33043312 return - ENOMEM ;
33053313
3314+ if (NFNL_MSG_TYPE (info -> nlh -> nlmsg_type ) == NFT_MSG_GETRULE_RESET )
3315+ reset = true;
3316+
33063317 err = nf_tables_fill_rule_info (skb2 , net , NETLINK_CB (skb ).portid ,
33073318 info -> nlh -> nlmsg_seq , NFT_MSG_NEWRULE , 0 ,
3308- family , table , chain , rule , 0 );
3319+ family , table , chain , rule , 0 , reset );
33093320 if (err < 0 )
33103321 goto err_fill_rule_info ;
33113322
@@ -4139,7 +4150,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
41394150
41404151 if (set -> num_exprs == 1 ) {
41414152 nest = nla_nest_start_noflag (skb , NFTA_SET_EXPR );
4142- if (nf_tables_fill_expr_info (skb , set -> exprs [0 ]) < 0 )
4153+ if (nf_tables_fill_expr_info (skb , set -> exprs [0 ], false ) < 0 )
41434154 goto nla_put_failure ;
41444155
41454156 nla_nest_end (skb , nest );
@@ -4150,7 +4161,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
41504161
41514162 for (i = 0 ; i < set -> num_exprs ; i ++ ) {
41524163 if (nft_expr_dump (skb , NFTA_LIST_ELEM ,
4153- set -> exprs [i ]) < 0 )
4164+ set -> exprs [i ], false ) < 0 )
41544165 goto nla_put_failure ;
41554166 }
41564167 nla_nest_end (skb , nest );
@@ -5062,7 +5073,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
50625073
50635074 if (num_exprs == 1 ) {
50645075 expr = nft_setelem_expr_at (elem_expr , 0 );
5065- if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr ) < 0 )
5076+ if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr , false ) < 0 )
50665077 return -1 ;
50675078
50685079 return 0 ;
@@ -5073,7 +5084,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
50735084
50745085 nft_setelem_expr_foreach (expr , elem_expr , size ) {
50755086 expr = nft_setelem_expr_at (elem_expr , size );
5076- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr ) < 0 )
5087+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , false ) < 0 )
50775088 goto nla_put_failure ;
50785089 }
50795090 nla_nest_end (skb , nest );
@@ -8375,6 +8386,12 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
83758386 .attr_count = NFTA_RULE_MAX ,
83768387 .policy = nft_rule_policy ,
83778388 },
8389+ [NFT_MSG_GETRULE_RESET ] = {
8390+ .call = nf_tables_getrule ,
8391+ .type = NFNL_CB_RCU ,
8392+ .attr_count = NFTA_RULE_MAX ,
8393+ .policy = nft_rule_policy ,
8394+ },
83788395 [NFT_MSG_DELRULE ] = {
83798396 .call = nf_tables_delrule ,
83808397 .type = NFNL_CB_BATCH ,
0 commit comments