@@ -2759,7 +2759,7 @@ static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
27592759};
27602760
27612761static int nf_tables_fill_expr_info (struct sk_buff * skb ,
2762- const struct nft_expr * expr )
2762+ const struct nft_expr * expr , bool reset )
27632763{
27642764 if (nla_put_string (skb , NFTA_EXPR_NAME , expr -> ops -> type -> name ))
27652765 goto nla_put_failure ;
@@ -2769,7 +2769,7 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
27692769 NFTA_EXPR_DATA );
27702770 if (data == NULL )
27712771 goto nla_put_failure ;
2772- if (expr -> ops -> dump (skb , expr , false ) < 0 )
2772+ if (expr -> ops -> dump (skb , expr , reset ) < 0 )
27732773 goto nla_put_failure ;
27742774 nla_nest_end (skb , data );
27752775 }
@@ -2781,14 +2781,14 @@ static int nf_tables_fill_expr_info(struct sk_buff *skb,
27812781};
27822782
27832783int nft_expr_dump (struct sk_buff * skb , unsigned int attr ,
2784- const struct nft_expr * expr )
2784+ const struct nft_expr * expr , bool reset )
27852785{
27862786 struct nlattr * nest ;
27872787
27882788 nest = nla_nest_start_noflag (skb , attr );
27892789 if (!nest )
27902790 goto nla_put_failure ;
2791- if (nf_tables_fill_expr_info (skb , expr ) < 0 )
2791+ if (nf_tables_fill_expr_info (skb , expr , reset ) < 0 )
27922792 goto nla_put_failure ;
27932793 nla_nest_end (skb , nest );
27942794 return 0 ;
@@ -3034,7 +3034,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
30343034 u32 flags , int family ,
30353035 const struct nft_table * table ,
30363036 const struct nft_chain * chain ,
3037- const struct nft_rule * rule , u64 handle )
3037+ const struct nft_rule * rule , u64 handle ,
3038+ bool reset )
30383039{
30393040 struct nlmsghdr * nlh ;
30403041 const struct nft_expr * expr , * next ;
@@ -3067,7 +3068,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
30673068 if (list == NULL )
30683069 goto nla_put_failure ;
30693070 nft_rule_for_each_expr (expr , next , rule ) {
3070- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr ) < 0 )
3071+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , reset ) < 0 )
30713072 goto nla_put_failure ;
30723073 }
30733074 nla_nest_end (skb , list );
@@ -3118,7 +3119,7 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
31183119
31193120 err = nf_tables_fill_rule_info (skb , ctx -> net , ctx -> portid , ctx -> seq ,
31203121 event , flags , ctx -> family , ctx -> table ,
3121- ctx -> chain , rule , handle );
3122+ ctx -> chain , rule , handle , false );
31223123 if (err < 0 ) {
31233124 kfree_skb (skb );
31243125 goto err ;
@@ -3139,7 +3140,8 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
31393140 unsigned int * idx ,
31403141 struct netlink_callback * cb ,
31413142 const struct nft_table * table ,
3142- const struct nft_chain * chain )
3143+ const struct nft_chain * chain ,
3144+ bool reset )
31433145{
31443146 struct net * net = sock_net (skb -> sk );
31453147 const struct nft_rule * rule , * prule ;
@@ -3166,7 +3168,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
31663168 NFT_MSG_NEWRULE ,
31673169 NLM_F_MULTI | NLM_F_APPEND ,
31683170 table -> family ,
3169- table , chain , rule , handle ) < 0 )
3171+ table , chain , rule , handle , reset ) < 0 )
31703172 return 1 ;
31713173
31723174 nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
@@ -3189,6 +3191,10 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
31893191 struct net * net = sock_net (skb -> sk );
31903192 int family = nfmsg -> nfgen_family ;
31913193 struct nftables_pernet * nft_net ;
3194+ bool reset = false;
3195+
3196+ if (NFNL_MSG_TYPE (cb -> nlh -> nlmsg_type ) == NFT_MSG_GETRULE_RESET )
3197+ reset = true;
31923198
31933199 rcu_read_lock ();
31943200 nft_net = nft_pernet (net );
@@ -3213,14 +3219,15 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
32133219 if (!nft_is_active (net , chain ))
32143220 continue ;
32153221 __nf_tables_dump_rules (skb , & idx ,
3216- cb , table , chain );
3222+ cb , table , chain , reset );
32173223 break ;
32183224 }
32193225 goto done ;
32203226 }
32213227
32223228 list_for_each_entry_rcu (chain , & table -> chains , list ) {
3223- if (__nf_tables_dump_rules (skb , & idx , cb , table , chain ))
3229+ if (__nf_tables_dump_rules (skb , & idx ,
3230+ cb , table , chain , reset ))
32243231 goto done ;
32253232 }
32263233
@@ -3291,6 +3298,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
32913298 struct net * net = info -> net ;
32923299 struct nft_table * table ;
32933300 struct sk_buff * skb2 ;
3301+ bool reset = false;
32943302 int err ;
32953303
32963304 if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
@@ -3327,9 +3335,12 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
33273335 if (!skb2 )
33283336 return - ENOMEM ;
33293337
3338+ if (NFNL_MSG_TYPE (info -> nlh -> nlmsg_type ) == NFT_MSG_GETRULE_RESET )
3339+ reset = true;
3340+
33303341 err = nf_tables_fill_rule_info (skb2 , net , NETLINK_CB (skb ).portid ,
33313342 info -> nlh -> nlmsg_seq , NFT_MSG_NEWRULE , 0 ,
3332- family , table , chain , rule , 0 );
3343+ family , table , chain , rule , 0 , reset );
33333344 if (err < 0 )
33343345 goto err_fill_rule_info ;
33353346
@@ -4104,7 +4115,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
41044115
41054116 if (set -> num_exprs == 1 ) {
41064117 nest = nla_nest_start_noflag (skb , NFTA_SET_EXPR );
4107- if (nf_tables_fill_expr_info (skb , set -> exprs [0 ]) < 0 )
4118+ if (nf_tables_fill_expr_info (skb , set -> exprs [0 ], false ) < 0 )
41084119 goto nla_put_failure ;
41094120
41104121 nla_nest_end (skb , nest );
@@ -4115,7 +4126,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
41154126
41164127 for (i = 0 ; i < set -> num_exprs ; i ++ ) {
41174128 if (nft_expr_dump (skb , NFTA_LIST_ELEM ,
4118- set -> exprs [i ]) < 0 )
4129+ set -> exprs [i ], false ) < 0 )
41194130 goto nla_put_failure ;
41204131 }
41214132 nla_nest_end (skb , nest );
@@ -4946,7 +4957,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
49464957
49474958 if (num_exprs == 1 ) {
49484959 expr = nft_setelem_expr_at (elem_expr , 0 );
4949- if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr ) < 0 )
4960+ if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr , false ) < 0 )
49504961 return -1 ;
49514962
49524963 return 0 ;
@@ -4957,7 +4968,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
49574968
49584969 nft_setelem_expr_foreach (expr , elem_expr , size ) {
49594970 expr = nft_setelem_expr_at (elem_expr , size );
4960- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr ) < 0 )
4971+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , false ) < 0 )
49614972 goto nla_put_failure ;
49624973 }
49634974 nla_nest_end (skb , nest );
@@ -8311,6 +8322,12 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
83118322 .attr_count = NFTA_RULE_MAX ,
83128323 .policy = nft_rule_policy ,
83138324 },
8325+ [NFT_MSG_GETRULE_RESET ] = {
8326+ .call = nf_tables_getrule ,
8327+ .type = NFNL_CB_RCU ,
8328+ .attr_count = NFTA_RULE_MAX ,
8329+ .policy = nft_rule_policy ,
8330+ },
83148331 [NFT_MSG_DELRULE ] = {
83158332 .call = nf_tables_delrule ,
83168333 .type = NFNL_CB_BATCH ,
0 commit comments