@@ -405,9 +405,9 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
405
405
[NFTA_TABLE_FLAGS ] = { .type = NLA_U32 },
406
406
};
407
407
408
- static int nf_tables_fill_table_info (struct sk_buff * skb , u32 portid , u32 seq ,
409
- int event , u32 flags , int family ,
410
- const struct nft_table * table )
408
+ static int nf_tables_fill_table_info (struct sk_buff * skb , struct net * net ,
409
+ u32 portid , u32 seq , int event , u32 flags ,
410
+ int family , const struct nft_table * table )
411
411
{
412
412
struct nlmsghdr * nlh ;
413
413
struct nfgenmsg * nfmsg ;
@@ -420,7 +420,7 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, u32 portid, u32 seq,
420
420
nfmsg = nlmsg_data (nlh );
421
421
nfmsg -> nfgen_family = family ;
422
422
nfmsg -> version = NFNETLINK_V0 ;
423
- nfmsg -> res_id = 0 ;
423
+ nfmsg -> res_id = htons ( net -> nft . base_seq & 0xffff ) ;
424
424
425
425
if (nla_put_string (skb , NFTA_TABLE_NAME , table -> name ) ||
426
426
nla_put_be32 (skb , NFTA_TABLE_FLAGS , htonl (table -> flags )) ||
@@ -448,8 +448,8 @@ static int nf_tables_table_notify(const struct nft_ctx *ctx, int event)
448
448
if (skb == NULL )
449
449
goto err ;
450
450
451
- err = nf_tables_fill_table_info (skb , ctx -> portid , ctx -> seq , event , 0 ,
452
- ctx -> afi -> family , ctx -> table );
451
+ err = nf_tables_fill_table_info (skb , ctx -> net , ctx -> portid , ctx -> seq ,
452
+ event , 0 , ctx -> afi -> family , ctx -> table );
453
453
if (err < 0 ) {
454
454
kfree_skb (skb );
455
455
goto err ;
@@ -488,7 +488,7 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
488
488
if (idx > s_idx )
489
489
memset (& cb -> args [1 ], 0 ,
490
490
sizeof (cb -> args ) - sizeof (cb -> args [0 ]));
491
- if (nf_tables_fill_table_info (skb ,
491
+ if (nf_tables_fill_table_info (skb , net ,
492
492
NETLINK_CB (cb -> skb ).portid ,
493
493
cb -> nlh -> nlmsg_seq ,
494
494
NFT_MSG_NEWTABLE ,
@@ -540,7 +540,7 @@ static int nf_tables_gettable(struct sock *nlsk, struct sk_buff *skb,
540
540
if (!skb2 )
541
541
return - ENOMEM ;
542
542
543
- err = nf_tables_fill_table_info (skb2 , NETLINK_CB (skb ).portid ,
543
+ err = nf_tables_fill_table_info (skb2 , net , NETLINK_CB (skb ).portid ,
544
544
nlh -> nlmsg_seq , NFT_MSG_NEWTABLE , 0 ,
545
545
family , table );
546
546
if (err < 0 )
@@ -914,9 +914,9 @@ static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
914
914
return - ENOSPC ;
915
915
}
916
916
917
- static int nf_tables_fill_chain_info (struct sk_buff * skb , u32 portid , u32 seq ,
918
- int event , u32 flags , int family ,
919
- const struct nft_table * table ,
917
+ static int nf_tables_fill_chain_info (struct sk_buff * skb , struct net * net ,
918
+ u32 portid , u32 seq , int event , u32 flags ,
919
+ int family , const struct nft_table * table ,
920
920
const struct nft_chain * chain )
921
921
{
922
922
struct nlmsghdr * nlh ;
@@ -930,7 +930,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq,
930
930
nfmsg = nlmsg_data (nlh );
931
931
nfmsg -> nfgen_family = family ;
932
932
nfmsg -> version = NFNETLINK_V0 ;
933
- nfmsg -> res_id = 0 ;
933
+ nfmsg -> res_id = htons ( net -> nft . base_seq & 0xffff ) ;
934
934
935
935
if (nla_put_string (skb , NFTA_CHAIN_TABLE , table -> name ))
936
936
goto nla_put_failure ;
@@ -988,8 +988,8 @@ static int nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
988
988
if (skb == NULL )
989
989
goto err ;
990
990
991
- err = nf_tables_fill_chain_info (skb , ctx -> portid , ctx -> seq , event , 0 ,
992
- ctx -> afi -> family , ctx -> table ,
991
+ err = nf_tables_fill_chain_info (skb , ctx -> net , ctx -> portid , ctx -> seq ,
992
+ event , 0 , ctx -> afi -> family , ctx -> table ,
993
993
ctx -> chain );
994
994
if (err < 0 ) {
995
995
kfree_skb (skb );
@@ -1031,7 +1031,8 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
1031
1031
if (idx > s_idx )
1032
1032
memset (& cb -> args [1 ], 0 ,
1033
1033
sizeof (cb -> args ) - sizeof (cb -> args [0 ]));
1034
- if (nf_tables_fill_chain_info (skb , NETLINK_CB (cb -> skb ).portid ,
1034
+ if (nf_tables_fill_chain_info (skb , net ,
1035
+ NETLINK_CB (cb -> skb ).portid ,
1035
1036
cb -> nlh -> nlmsg_seq ,
1036
1037
NFT_MSG_NEWCHAIN ,
1037
1038
NLM_F_MULTI ,
@@ -1090,7 +1091,7 @@ static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb,
1090
1091
if (!skb2 )
1091
1092
return - ENOMEM ;
1092
1093
1093
- err = nf_tables_fill_chain_info (skb2 , NETLINK_CB (skb ).portid ,
1094
+ err = nf_tables_fill_chain_info (skb2 , net , NETLINK_CB (skb ).portid ,
1094
1095
nlh -> nlmsg_seq , NFT_MSG_NEWCHAIN , 0 ,
1095
1096
family , table , chain );
1096
1097
if (err < 0 )
@@ -1647,8 +1648,9 @@ static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
1647
1648
.len = NFT_USERDATA_MAXLEN },
1648
1649
};
1649
1650
1650
- static int nf_tables_fill_rule_info (struct sk_buff * skb , u32 portid , u32 seq ,
1651
- int event , u32 flags , int family ,
1651
+ static int nf_tables_fill_rule_info (struct sk_buff * skb , struct net * net ,
1652
+ u32 portid , u32 seq , int event ,
1653
+ u32 flags , int family ,
1652
1654
const struct nft_table * table ,
1653
1655
const struct nft_chain * chain ,
1654
1656
const struct nft_rule * rule )
@@ -1668,7 +1670,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, u32 portid, u32 seq,
1668
1670
nfmsg = nlmsg_data (nlh );
1669
1671
nfmsg -> nfgen_family = family ;
1670
1672
nfmsg -> version = NFNETLINK_V0 ;
1671
- nfmsg -> res_id = 0 ;
1673
+ nfmsg -> res_id = htons ( net -> nft . base_seq & 0xffff ) ;
1672
1674
1673
1675
if (nla_put_string (skb , NFTA_RULE_TABLE , table -> name ))
1674
1676
goto nla_put_failure ;
@@ -1724,8 +1726,8 @@ static int nf_tables_rule_notify(const struct nft_ctx *ctx,
1724
1726
if (skb == NULL )
1725
1727
goto err ;
1726
1728
1727
- err = nf_tables_fill_rule_info (skb , ctx -> portid , ctx -> seq , event , 0 ,
1728
- ctx -> afi -> family , ctx -> table ,
1729
+ err = nf_tables_fill_rule_info (skb , ctx -> net , ctx -> portid , ctx -> seq ,
1730
+ event , 0 , ctx -> afi -> family , ctx -> table ,
1729
1731
ctx -> chain , rule );
1730
1732
if (err < 0 ) {
1731
1733
kfree_skb (skb );
@@ -1771,7 +1773,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
1771
1773
if (idx > s_idx )
1772
1774
memset (& cb -> args [1 ], 0 ,
1773
1775
sizeof (cb -> args ) - sizeof (cb -> args [0 ]));
1774
- if (nf_tables_fill_rule_info (skb , NETLINK_CB (cb -> skb ).portid ,
1776
+ if (nf_tables_fill_rule_info (skb , net , NETLINK_CB (cb -> skb ).portid ,
1775
1777
cb -> nlh -> nlmsg_seq ,
1776
1778
NFT_MSG_NEWRULE ,
1777
1779
NLM_F_MULTI | NLM_F_APPEND ,
@@ -1837,7 +1839,7 @@ static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb,
1837
1839
if (!skb2 )
1838
1840
return - ENOMEM ;
1839
1841
1840
- err = nf_tables_fill_rule_info (skb2 , NETLINK_CB (skb ).portid ,
1842
+ err = nf_tables_fill_rule_info (skb2 , net , NETLINK_CB (skb ).portid ,
1841
1843
nlh -> nlmsg_seq , NFT_MSG_NEWRULE , 0 ,
1842
1844
family , table , chain , rule );
1843
1845
if (err < 0 )
@@ -2321,7 +2323,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
2321
2323
nfmsg = nlmsg_data (nlh );
2322
2324
nfmsg -> nfgen_family = ctx -> afi -> family ;
2323
2325
nfmsg -> version = NFNETLINK_V0 ;
2324
- nfmsg -> res_id = 0 ;
2326
+ nfmsg -> res_id = htons ( ctx -> net -> nft . base_seq & 0xffff ) ;
2325
2327
2326
2328
if (nla_put_string (skb , NFTA_SET_TABLE , ctx -> table -> name ))
2327
2329
goto nla_put_failure ;
@@ -2925,7 +2927,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
2925
2927
nfmsg = nlmsg_data (nlh );
2926
2928
nfmsg -> nfgen_family = ctx .afi -> family ;
2927
2929
nfmsg -> version = NFNETLINK_V0 ;
2928
- nfmsg -> res_id = 0 ;
2930
+ nfmsg -> res_id = htons ( ctx . net -> nft . base_seq & 0xffff ) ;
2929
2931
2930
2932
if (nla_put_string (skb , NFTA_SET_ELEM_LIST_TABLE , ctx .table -> name ))
2931
2933
goto nla_put_failure ;
@@ -3006,7 +3008,7 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
3006
3008
nfmsg = nlmsg_data (nlh );
3007
3009
nfmsg -> nfgen_family = ctx -> afi -> family ;
3008
3010
nfmsg -> version = NFNETLINK_V0 ;
3009
- nfmsg -> res_id = 0 ;
3011
+ nfmsg -> res_id = htons ( ctx -> net -> nft . base_seq & 0xffff ) ;
3010
3012
3011
3013
if (nla_put_string (skb , NFTA_SET_TABLE , ctx -> table -> name ))
3012
3014
goto nla_put_failure ;
@@ -3293,6 +3295,87 @@ static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
3293
3295
return err ;
3294
3296
}
3295
3297
3298
+ static int nf_tables_fill_gen_info (struct sk_buff * skb , struct net * net ,
3299
+ u32 portid , u32 seq )
3300
+ {
3301
+ struct nlmsghdr * nlh ;
3302
+ struct nfgenmsg * nfmsg ;
3303
+ int event = (NFNL_SUBSYS_NFTABLES << 8 ) | NFT_MSG_NEWGEN ;
3304
+
3305
+ nlh = nlmsg_put (skb , portid , seq , event , sizeof (struct nfgenmsg ), 0 );
3306
+ if (nlh == NULL )
3307
+ goto nla_put_failure ;
3308
+
3309
+ nfmsg = nlmsg_data (nlh );
3310
+ nfmsg -> nfgen_family = AF_UNSPEC ;
3311
+ nfmsg -> version = NFNETLINK_V0 ;
3312
+ nfmsg -> res_id = htons (net -> nft .base_seq & 0xffff );
3313
+
3314
+ if (nla_put_be32 (skb , NFTA_GEN_ID , htonl (net -> nft .base_seq )))
3315
+ goto nla_put_failure ;
3316
+
3317
+ return nlmsg_end (skb , nlh );
3318
+
3319
+ nla_put_failure :
3320
+ nlmsg_trim (skb , nlh );
3321
+ return - EMSGSIZE ;
3322
+ }
3323
+
3324
+ static int nf_tables_gen_notify (struct net * net , struct sk_buff * skb , int event )
3325
+ {
3326
+ struct nlmsghdr * nlh = nlmsg_hdr (skb );
3327
+ struct sk_buff * skb2 ;
3328
+ int err ;
3329
+
3330
+ if (nlmsg_report (nlh ) &&
3331
+ !nfnetlink_has_listeners (net , NFNLGRP_NFTABLES ))
3332
+ return 0 ;
3333
+
3334
+ err = - ENOBUFS ;
3335
+ skb2 = nlmsg_new (NLMSG_GOODSIZE , GFP_KERNEL );
3336
+ if (skb2 == NULL )
3337
+ goto err ;
3338
+
3339
+ err = nf_tables_fill_gen_info (skb2 , net , NETLINK_CB (skb ).portid ,
3340
+ nlh -> nlmsg_seq );
3341
+ if (err < 0 ) {
3342
+ kfree_skb (skb2 );
3343
+ goto err ;
3344
+ }
3345
+
3346
+ err = nfnetlink_send (skb2 , net , NETLINK_CB (skb ).portid ,
3347
+ NFNLGRP_NFTABLES , nlmsg_report (nlh ), GFP_KERNEL );
3348
+ err :
3349
+ if (err < 0 ) {
3350
+ nfnetlink_set_err (net , NETLINK_CB (skb ).portid , NFNLGRP_NFTABLES ,
3351
+ err );
3352
+ }
3353
+ return err ;
3354
+ }
3355
+
3356
+ static int nf_tables_getgen (struct sock * nlsk , struct sk_buff * skb ,
3357
+ const struct nlmsghdr * nlh ,
3358
+ const struct nlattr * const nla [])
3359
+ {
3360
+ struct net * net = sock_net (skb -> sk );
3361
+ struct sk_buff * skb2 ;
3362
+ int err ;
3363
+
3364
+ skb2 = alloc_skb (NLMSG_GOODSIZE , GFP_KERNEL );
3365
+ if (skb2 == NULL )
3366
+ return - ENOMEM ;
3367
+
3368
+ err = nf_tables_fill_gen_info (skb2 , net , NETLINK_CB (skb ).portid ,
3369
+ nlh -> nlmsg_seq );
3370
+ if (err < 0 )
3371
+ goto err ;
3372
+
3373
+ return nlmsg_unicast (nlsk , skb2 , NETLINK_CB (skb ).portid );
3374
+ err :
3375
+ kfree_skb (skb2 );
3376
+ return err ;
3377
+ }
3378
+
3296
3379
static const struct nfnl_callback nf_tables_cb [NFT_MSG_MAX ] = {
3297
3380
[NFT_MSG_NEWTABLE ] = {
3298
3381
.call_batch = nf_tables_newtable ,
@@ -3369,6 +3452,9 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
3369
3452
.attr_count = NFTA_SET_ELEM_LIST_MAX ,
3370
3453
.policy = nft_set_elem_list_policy ,
3371
3454
},
3455
+ [NFT_MSG_GETGEN ] = {
3456
+ .call = nf_tables_getgen ,
3457
+ },
3372
3458
};
3373
3459
3374
3460
static void nft_chain_commit_update (struct nft_trans * trans )
@@ -3526,6 +3612,8 @@ static int nf_tables_commit(struct sk_buff *skb)
3526
3612
call_rcu (& trans -> rcu_head , nf_tables_commit_release_rcu );
3527
3613
}
3528
3614
3615
+ nf_tables_gen_notify (net , skb , NFT_MSG_NEWGEN );
3616
+
3529
3617
return 0 ;
3530
3618
}
3531
3619
0 commit comments