netfilter: nf_tables: add AF specific expression support
For the reject module, we need to add AF-specific implementations to get rid of incorrect module dependencies. Try to load an AF-specific module first and fall back to generic modules. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
51292c0735
commit
64d46806b6
|
@ -252,6 +252,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||||
* @owner: module reference
|
* @owner: module reference
|
||||||
* @policy: netlink attribute policy
|
* @policy: netlink attribute policy
|
||||||
* @maxattr: highest netlink attribute number
|
* @maxattr: highest netlink attribute number
|
||||||
|
* @family: address family for AF-specific types
|
||||||
*/
|
*/
|
||||||
struct nft_expr_type {
|
struct nft_expr_type {
|
||||||
const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
|
const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
|
||||||
|
@ -262,6 +263,7 @@ struct nft_expr_type {
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
const struct nla_policy *policy;
|
const struct nla_policy *policy;
|
||||||
unsigned int maxattr;
|
unsigned int maxattr;
|
||||||
|
u8 family;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -529,6 +531,9 @@ void nft_unregister_expr(struct nft_expr_type *);
|
||||||
#define MODULE_ALIAS_NFT_CHAIN(family, name) \
|
#define MODULE_ALIAS_NFT_CHAIN(family, name) \
|
||||||
MODULE_ALIAS("nft-chain-" __stringify(family) "-" name)
|
MODULE_ALIAS("nft-chain-" __stringify(family) "-" name)
|
||||||
|
|
||||||
|
#define MODULE_ALIAS_NFT_AF_EXPR(family, name) \
|
||||||
|
MODULE_ALIAS("nft-expr-" __stringify(family) "-" name)
|
||||||
|
|
||||||
#define MODULE_ALIAS_NFT_EXPR(name) \
|
#define MODULE_ALIAS_NFT_EXPR(name) \
|
||||||
MODULE_ALIAS("nft-expr-" name)
|
MODULE_ALIAS("nft-expr-" name)
|
||||||
|
|
||||||
|
|
|
@ -1114,35 +1114,45 @@ void nft_unregister_expr(struct nft_expr_type *type)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nft_unregister_expr);
|
EXPORT_SYMBOL_GPL(nft_unregister_expr);
|
||||||
|
|
||||||
static const struct nft_expr_type *__nft_expr_type_get(struct nlattr *nla)
|
static const struct nft_expr_type *__nft_expr_type_get(u8 family,
|
||||||
|
struct nlattr *nla)
|
||||||
{
|
{
|
||||||
const struct nft_expr_type *type;
|
const struct nft_expr_type *type;
|
||||||
|
|
||||||
list_for_each_entry(type, &nf_tables_expressions, list) {
|
list_for_each_entry(type, &nf_tables_expressions, list) {
|
||||||
if (!nla_strcmp(nla, type->name))
|
if (!nla_strcmp(nla, type->name) &&
|
||||||
|
(!type->family || type->family == family))
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct nft_expr_type *nft_expr_type_get(struct nlattr *nla)
|
static const struct nft_expr_type *nft_expr_type_get(u8 family,
|
||||||
|
struct nlattr *nla)
|
||||||
{
|
{
|
||||||
const struct nft_expr_type *type;
|
const struct nft_expr_type *type;
|
||||||
|
|
||||||
if (nla == NULL)
|
if (nla == NULL)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
type = __nft_expr_type_get(nla);
|
type = __nft_expr_type_get(family, nla);
|
||||||
if (type != NULL && try_module_get(type->owner))
|
if (type != NULL && try_module_get(type->owner))
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
#ifdef CONFIG_MODULES
|
#ifdef CONFIG_MODULES
|
||||||
if (type == NULL) {
|
if (type == NULL) {
|
||||||
|
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
|
||||||
|
request_module("nft-expr-%u-%.*s", family,
|
||||||
|
nla_len(nla), (char *)nla_data(nla));
|
||||||
|
nfnl_lock(NFNL_SUBSYS_NFTABLES);
|
||||||
|
if (__nft_expr_type_get(family, nla))
|
||||||
|
return ERR_PTR(-EAGAIN);
|
||||||
|
|
||||||
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
|
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
|
||||||
request_module("nft-expr-%.*s",
|
request_module("nft-expr-%.*s",
|
||||||
nla_len(nla), (char *)nla_data(nla));
|
nla_len(nla), (char *)nla_data(nla));
|
||||||
nfnl_lock(NFNL_SUBSYS_NFTABLES);
|
nfnl_lock(NFNL_SUBSYS_NFTABLES);
|
||||||
if (__nft_expr_type_get(nla))
|
if (__nft_expr_type_get(family, nla))
|
||||||
return ERR_PTR(-EAGAIN);
|
return ERR_PTR(-EAGAIN);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1193,7 +1203,7 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
type = nft_expr_type_get(tb[NFTA_EXPR_NAME]);
|
type = nft_expr_type_get(ctx->afi->family, tb[NFTA_EXPR_NAME]);
|
||||||
if (IS_ERR(type))
|
if (IS_ERR(type))
|
||||||
return PTR_ERR(type);
|
return PTR_ERR(type);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue