@@ -455,8 +455,40 @@ __nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family)
455455 return NULL ;
456456}
457457
458+ /*
459+ * Loading a module requires dropping mutex that guards the
460+ * transaction.
461+ * We first need to abort any pending transactions as once
462+ * mutex is unlocked a different client could start a new
463+ * transaction. It must not see any 'future generation'
464+ * changes * as these changes will never happen.
465+ */
466+ #ifdef CONFIG_MODULES
467+ static int __nf_tables_abort (struct net * net );
468+
469+ static void nft_request_module (struct net * net , const char * fmt , ...)
470+ {
471+ char module_name [MODULE_NAME_LEN ];
472+ va_list args ;
473+ int ret ;
474+
475+ __nf_tables_abort (net );
476+
477+ va_start (args , fmt );
478+ ret = vsnprintf (module_name , MODULE_NAME_LEN , fmt , args );
479+ va_end (args );
480+ if (WARN (ret >= MODULE_NAME_LEN , "truncated: '%s' (len %d)" , module_name , ret ))
481+ return ;
482+
483+ nfnl_unlock (NFNL_SUBSYS_NFTABLES );
484+ request_module ("%s" , module_name );
485+ nfnl_lock (NFNL_SUBSYS_NFTABLES );
486+ }
487+ #endif
488+
458489static const struct nft_chain_type *
459- nf_tables_chain_type_lookup (const struct nlattr * nla , u8 family , bool autoload )
490+ nf_tables_chain_type_lookup (struct net * net , const struct nlattr * nla ,
491+ u8 family , bool autoload )
460492{
461493 const struct nft_chain_type * type ;
462494
@@ -465,10 +497,8 @@ nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family, bool autoload)
465497 return type ;
466498#ifdef CONFIG_MODULES
467499 if (autoload ) {
468- nfnl_unlock (NFNL_SUBSYS_NFTABLES );
469- request_module ("nft-chain-%u-%.*s" , family ,
470- nla_len (nla ), (const char * )nla_data (nla ));
471- nfnl_lock (NFNL_SUBSYS_NFTABLES );
500+ nft_request_module (net , "nft-chain-%u-%.*s" , family ,
501+ nla_len (nla ), (const char * )nla_data (nla ));
472502 type = __nf_tables_chain_type_lookup (nla , family );
473503 if (type != NULL )
474504 return ERR_PTR (- EAGAIN );
@@ -1412,7 +1442,7 @@ static int nft_chain_parse_hook(struct net *net,
14121442
14131443 type = chain_type [family ][NFT_CHAIN_T_DEFAULT ];
14141444 if (nla [NFTA_CHAIN_TYPE ]) {
1415- type = nf_tables_chain_type_lookup (nla [NFTA_CHAIN_TYPE ],
1445+ type = nf_tables_chain_type_lookup (net , nla [NFTA_CHAIN_TYPE ],
14161446 family , create );
14171447 if (IS_ERR (type ))
14181448 return PTR_ERR (type );
@@ -1875,7 +1905,8 @@ static const struct nft_expr_type *__nft_expr_type_get(u8 family,
18751905 return NULL ;
18761906}
18771907
1878- static const struct nft_expr_type * nft_expr_type_get (u8 family ,
1908+ static const struct nft_expr_type * nft_expr_type_get (struct net * net ,
1909+ u8 family ,
18791910 struct nlattr * nla )
18801911{
18811912 const struct nft_expr_type * type ;
@@ -1889,17 +1920,13 @@ static const struct nft_expr_type *nft_expr_type_get(u8 family,
18891920
18901921#ifdef CONFIG_MODULES
18911922 if (type == NULL ) {
1892- nfnl_unlock (NFNL_SUBSYS_NFTABLES );
1893- request_module ("nft-expr-%u-%.*s" , family ,
1894- nla_len (nla ), (char * )nla_data (nla ));
1895- nfnl_lock (NFNL_SUBSYS_NFTABLES );
1923+ nft_request_module (net , "nft-expr-%u-%.*s" , family ,
1924+ nla_len (nla ), (char * )nla_data (nla ));
18961925 if (__nft_expr_type_get (family , nla ))
18971926 return ERR_PTR (- EAGAIN );
18981927
1899- nfnl_unlock (NFNL_SUBSYS_NFTABLES );
1900- request_module ("nft-expr-%.*s" ,
1901- nla_len (nla ), (char * )nla_data (nla ));
1902- nfnl_lock (NFNL_SUBSYS_NFTABLES );
1928+ nft_request_module (net , "nft-expr-%.*s" ,
1929+ nla_len (nla ), (char * )nla_data (nla ));
19031930 if (__nft_expr_type_get (family , nla ))
19041931 return ERR_PTR (- EAGAIN );
19051932 }
@@ -1968,7 +1995,7 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx,
19681995 if (err < 0 )
19691996 return err ;
19701997
1971- type = nft_expr_type_get (ctx -> family , tb [NFTA_EXPR_NAME ]);
1998+ type = nft_expr_type_get (ctx -> net , ctx -> family , tb [NFTA_EXPR_NAME ]);
19721999 if (IS_ERR (type ))
19732000 return PTR_ERR (type );
19742001
@@ -2744,9 +2771,7 @@ nft_select_set_ops(const struct nft_ctx *ctx,
27442771
27452772#ifdef CONFIG_MODULES
27462773 if (list_empty (& nf_tables_set_types )) {
2747- nfnl_unlock (NFNL_SUBSYS_NFTABLES );
2748- request_module ("nft-set" );
2749- nfnl_lock (NFNL_SUBSYS_NFTABLES );
2774+ nft_request_module (ctx -> net , "nft-set" );
27502775 if (!list_empty (& nf_tables_set_types ))
27512776 return ERR_PTR (- EAGAIN );
27522777 }
@@ -4779,7 +4804,8 @@ static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
47794804 return NULL ;
47804805}
47814806
4782- static const struct nft_object_type * nft_obj_type_get (u32 objtype )
4807+ static const struct nft_object_type *
4808+ nft_obj_type_get (struct net * net , u32 objtype )
47834809{
47844810 const struct nft_object_type * type ;
47854811
@@ -4789,9 +4815,7 @@ static const struct nft_object_type *nft_obj_type_get(u32 objtype)
47894815
47904816#ifdef CONFIG_MODULES
47914817 if (type == NULL ) {
4792- nfnl_unlock (NFNL_SUBSYS_NFTABLES );
4793- request_module ("nft-obj-%u" , objtype );
4794- nfnl_lock (NFNL_SUBSYS_NFTABLES );
4818+ nft_request_module (net , "nft-obj-%u" , objtype );
47954819 if (__nft_obj_type_get (objtype ))
47964820 return ERR_PTR (- EAGAIN );
47974821 }
@@ -4843,7 +4867,7 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
48434867
48444868 nft_ctx_init (& ctx , net , skb , nlh , family , table , NULL , nla );
48454869
4846- type = nft_obj_type_get (objtype );
4870+ type = nft_obj_type_get (net , objtype );
48474871 if (IS_ERR (type ))
48484872 return PTR_ERR (type );
48494873
@@ -5339,7 +5363,8 @@ static const struct nf_flowtable_type *__nft_flowtable_type_get(u8 family)
53395363 return NULL ;
53405364}
53415365
5342- static const struct nf_flowtable_type * nft_flowtable_type_get (u8 family )
5366+ static const struct nf_flowtable_type *
5367+ nft_flowtable_type_get (struct net * net , u8 family )
53435368{
53445369 const struct nf_flowtable_type * type ;
53455370
@@ -5349,9 +5374,7 @@ static const struct nf_flowtable_type *nft_flowtable_type_get(u8 family)
53495374
53505375#ifdef CONFIG_MODULES
53515376 if (type == NULL ) {
5352- nfnl_unlock (NFNL_SUBSYS_NFTABLES );
5353- request_module ("nf-flowtable-%u" , family );
5354- nfnl_lock (NFNL_SUBSYS_NFTABLES );
5377+ nft_request_module (net , "nf-flowtable-%u" , family );
53555378 if (__nft_flowtable_type_get (family ))
53565379 return ERR_PTR (- EAGAIN );
53575380 }
@@ -5431,7 +5454,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
54315454 goto err1 ;
54325455 }
54335456
5434- type = nft_flowtable_type_get (family );
5457+ type = nft_flowtable_type_get (net , family );
54355458 if (IS_ERR (type )) {
54365459 err = PTR_ERR (type );
54375460 goto err2 ;
0 commit comments