mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:19:34 +02:00
netfilter: x_tables: add .check_hooks to matches and targets
Add a new .check_hooks interface for checking if the match/target is used from the validate hook according to its configuration. Move existing conditional hook check based on the match/target configuration from .checkentry to .check_hooks for the following matches/targets: - addrtype - devgroup - physdev - policy - set - TCPMSS - SET This is a preparation patch to fix nft_compat, not functional changes are intended. Based on patch from Florian Westphal. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
@@ -146,6 +146,9 @@ struct xt_match {
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
int (*checkentry)(const struct xt_mtchk_param *);
|
||||
|
||||
/* Called to validate hooks based on the match configuration. */
|
||||
int (*check_hooks)(const struct xt_mtchk_param *);
|
||||
|
||||
/* Called when entry of this type deleted. */
|
||||
void (*destroy)(const struct xt_mtdtor_param *);
|
||||
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||
@@ -187,6 +190,9 @@ struct xt_target {
|
||||
/* Should return 0 on success or an error code otherwise (-Exxxx). */
|
||||
int (*checkentry)(const struct xt_tgchk_param *);
|
||||
|
||||
/* Called to validate hooks based on the target configuration. */
|
||||
int (*check_hooks)(const struct xt_tgchk_param *);
|
||||
|
||||
/* Called when entry of this type deleted. */
|
||||
void (*destroy)(const struct xt_tgdtor_param *);
|
||||
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||
@@ -279,8 +285,10 @@ bool xt_find_jump_offset(const unsigned int *offsets,
|
||||
|
||||
int xt_check_proc_name(const char *name, unsigned int size);
|
||||
|
||||
int xt_check_hooks_match(struct xt_mtchk_param *par);
|
||||
int xt_check_match(struct xt_mtchk_param *, unsigned int size, u16 proto,
|
||||
bool inv_proto);
|
||||
int xt_check_hooks_target(struct xt_tgchk_param *par);
|
||||
int xt_check_target(struct xt_tgchk_param *, unsigned int size, u16 proto,
|
||||
bool inv_proto);
|
||||
|
||||
|
||||
@@ -477,11 +477,9 @@ int xt_check_proc_name(const char *name, unsigned int size)
|
||||
}
|
||||
EXPORT_SYMBOL(xt_check_proc_name);
|
||||
|
||||
int xt_check_match(struct xt_mtchk_param *par,
|
||||
unsigned int size, u16 proto, bool inv_proto)
|
||||
static int xt_check_match_common(struct xt_mtchk_param *par,
|
||||
unsigned int size, u16 proto, bool inv_proto)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (XT_ALIGN(par->match->matchsize) != size &&
|
||||
par->match->matchsize != -1) {
|
||||
/*
|
||||
@@ -530,6 +528,14 @@ int xt_check_match(struct xt_mtchk_param *par,
|
||||
par->match->proto);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xt_checkentry_match(struct xt_mtchk_param *par)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (par->match->checkentry != NULL) {
|
||||
ret = par->match->checkentry(par);
|
||||
if (ret < 0)
|
||||
@@ -538,8 +544,34 @@ int xt_check_match(struct xt_mtchk_param *par,
|
||||
/* Flag up potential errors. */
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xt_check_hooks_match(struct xt_mtchk_param *par)
|
||||
{
|
||||
if (par->match->check_hooks != NULL)
|
||||
return par->match->check_hooks(par);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_check_hooks_match);
|
||||
|
||||
int xt_check_match(struct xt_mtchk_param *par,
|
||||
unsigned int size, u16 proto, bool inv_proto)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xt_check_match_common(par, size, proto, inv_proto);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = xt_check_hooks_match(par);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return xt_checkentry_match(par);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_check_match);
|
||||
|
||||
/** xt_check_entry_match - check that matches end before start of target
|
||||
@@ -1012,11 +1044,9 @@ bool xt_find_jump_offset(const unsigned int *offsets,
|
||||
}
|
||||
EXPORT_SYMBOL(xt_find_jump_offset);
|
||||
|
||||
int xt_check_target(struct xt_tgchk_param *par,
|
||||
unsigned int size, u16 proto, bool inv_proto)
|
||||
static int xt_check_target_common(struct xt_tgchk_param *par,
|
||||
unsigned int size, u16 proto, bool inv_proto)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (XT_ALIGN(par->target->targetsize) != size) {
|
||||
pr_err_ratelimited("%s_tables: %s.%u target: invalid size %u (kernel) != (user) %u\n",
|
||||
xt_prefix[par->family], par->target->name,
|
||||
@@ -1061,6 +1091,23 @@ int xt_check_target(struct xt_tgchk_param *par,
|
||||
par->target->proto);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xt_check_hooks_target(struct xt_tgchk_param *par)
|
||||
{
|
||||
if (par->target->check_hooks != NULL)
|
||||
return par->target->check_hooks(par);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_check_hooks_target);
|
||||
|
||||
static int xt_checkentry_target(struct xt_tgchk_param *par)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (par->target->checkentry != NULL) {
|
||||
ret = par->target->checkentry(par);
|
||||
if (ret < 0)
|
||||
@@ -1071,6 +1118,22 @@ int xt_check_target(struct xt_tgchk_param *par,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xt_check_target(struct xt_tgchk_param *par,
|
||||
unsigned int size, u16 proto, bool inv_proto)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xt_check_target_common(par, size, proto, inv_proto);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = xt_check_hooks_target(par);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return xt_checkentry_target(par);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_check_target);
|
||||
|
||||
/**
|
||||
|
||||
+17
-16
@@ -247,6 +247,21 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tcpmss_tg4_check_hooks(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct xt_tcpmss_info *info = par->targinfo;
|
||||
|
||||
if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
|
||||
(par->hook_mask & ~((1 << NF_INET_FORWARD) |
|
||||
(1 << NF_INET_LOCAL_OUT) |
|
||||
(1 << NF_INET_POST_ROUTING))) != 0) {
|
||||
pr_info_ratelimited("path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Must specify -p tcp --syn */
|
||||
static inline bool find_syn_match(const struct xt_entry_match *m)
|
||||
{
|
||||
@@ -262,17 +277,9 @@ static inline bool find_syn_match(const struct xt_entry_match *m)
|
||||
|
||||
static int tcpmss_tg4_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct xt_tcpmss_info *info = par->targinfo;
|
||||
const struct ipt_entry *e = par->entryinfo;
|
||||
const struct xt_entry_match *ematch;
|
||||
|
||||
if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
|
||||
(par->hook_mask & ~((1 << NF_INET_FORWARD) |
|
||||
(1 << NF_INET_LOCAL_OUT) |
|
||||
(1 << NF_INET_POST_ROUTING))) != 0) {
|
||||
pr_info_ratelimited("path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (par->nft_compat)
|
||||
return 0;
|
||||
|
||||
@@ -286,17 +293,9 @@ static int tcpmss_tg4_check(const struct xt_tgchk_param *par)
|
||||
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
|
||||
static int tcpmss_tg6_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct xt_tcpmss_info *info = par->targinfo;
|
||||
const struct ip6t_entry *e = par->entryinfo;
|
||||
const struct xt_entry_match *ematch;
|
||||
|
||||
if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
|
||||
(par->hook_mask & ~((1 << NF_INET_FORWARD) |
|
||||
(1 << NF_INET_LOCAL_OUT) |
|
||||
(1 << NF_INET_POST_ROUTING))) != 0) {
|
||||
pr_info_ratelimited("path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (par->nft_compat)
|
||||
return 0;
|
||||
|
||||
@@ -312,6 +311,7 @@ static struct xt_target tcpmss_tg_reg[] __read_mostly = {
|
||||
{
|
||||
.family = NFPROTO_IPV4,
|
||||
.name = "TCPMSS",
|
||||
.check_hooks = tcpmss_tg4_check_hooks,
|
||||
.checkentry = tcpmss_tg4_check,
|
||||
.target = tcpmss_tg4,
|
||||
.targetsize = sizeof(struct xt_tcpmss_info),
|
||||
@@ -322,6 +322,7 @@ static struct xt_target tcpmss_tg_reg[] __read_mostly = {
|
||||
{
|
||||
.family = NFPROTO_IPV6,
|
||||
.name = "TCPMSS",
|
||||
.check_hooks = tcpmss_tg4_check_hooks,
|
||||
.checkentry = tcpmss_tg6_check,
|
||||
.target = tcpmss_tg6,
|
||||
.targetsize = sizeof(struct xt_tcpmss_info),
|
||||
|
||||
@@ -153,14 +153,10 @@ addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
|
||||
static int addrtype_mt_check_hooks(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const char *errmsg = "both incoming and outgoing interface limitation cannot be selected";
|
||||
struct xt_addrtype_info_v1 *info = par->matchinfo;
|
||||
|
||||
if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN &&
|
||||
info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)
|
||||
goto err;
|
||||
const char *errmsg;
|
||||
|
||||
if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
|
||||
(1 << NF_INET_LOCAL_IN)) &&
|
||||
@@ -176,6 +172,21 @@ static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
pr_info_ratelimited("%s\n", errmsg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const char *errmsg = "both incoming and outgoing interface limitation cannot be selected";
|
||||
struct xt_addrtype_info_v1 *info = par->matchinfo;
|
||||
|
||||
if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN &&
|
||||
info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)
|
||||
goto err;
|
||||
|
||||
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
|
||||
if (par->family == NFPROTO_IPV6) {
|
||||
if ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) {
|
||||
@@ -211,6 +222,7 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = {
|
||||
.family = NFPROTO_IPV4,
|
||||
.revision = 1,
|
||||
.match = addrtype_mt_v1,
|
||||
.check_hooks = addrtype_mt_check_hooks,
|
||||
.checkentry = addrtype_mt_checkentry_v1,
|
||||
.matchsize = sizeof(struct xt_addrtype_info_v1),
|
||||
.me = THIS_MODULE
|
||||
@@ -221,6 +233,7 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = {
|
||||
.family = NFPROTO_IPV6,
|
||||
.revision = 1,
|
||||
.match = addrtype_mt_v1,
|
||||
.check_hooks = addrtype_mt_check_hooks,
|
||||
.checkentry = addrtype_mt_checkentry_v1,
|
||||
.matchsize = sizeof(struct xt_addrtype_info_v1),
|
||||
.me = THIS_MODULE
|
||||
|
||||
@@ -33,14 +33,10 @@ static bool devgroup_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int devgroup_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
static int devgroup_mt_check_hooks(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_devgroup_info *info = par->matchinfo;
|
||||
|
||||
if (info->flags & ~(XT_DEVGROUP_MATCH_SRC | XT_DEVGROUP_INVERT_SRC |
|
||||
XT_DEVGROUP_MATCH_DST | XT_DEVGROUP_INVERT_DST))
|
||||
return -EINVAL;
|
||||
|
||||
if (info->flags & XT_DEVGROUP_MATCH_SRC &&
|
||||
par->hook_mask & ~((1 << NF_INET_PRE_ROUTING) |
|
||||
(1 << NF_INET_LOCAL_IN) |
|
||||
@@ -56,9 +52,21 @@ static int devgroup_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int devgroup_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_devgroup_info *info = par->matchinfo;
|
||||
|
||||
if (info->flags & ~(XT_DEVGROUP_MATCH_SRC | XT_DEVGROUP_INVERT_SRC |
|
||||
XT_DEVGROUP_MATCH_DST | XT_DEVGROUP_INVERT_DST))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_match devgroup_mt_reg __read_mostly = {
|
||||
.name = "devgroup",
|
||||
.match = devgroup_mt,
|
||||
.check_hooks = devgroup_mt_check_hooks,
|
||||
.checkentry = devgroup_mt_checkentry,
|
||||
.matchsize = sizeof(struct xt_devgroup_info),
|
||||
.family = NFPROTO_UNSPEC,
|
||||
|
||||
@@ -91,6 +91,21 @@ match_outdev:
|
||||
return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT));
|
||||
}
|
||||
|
||||
static int physdev_mt_check_hooks(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_physdev_info *info = par->matchinfo;
|
||||
|
||||
if (info->bitmask & (XT_PHYSDEV_OP_OUT | XT_PHYSDEV_OP_ISOUT) &&
|
||||
(!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
|
||||
info->invert & XT_PHYSDEV_OP_BRIDGED) &&
|
||||
par->hook_mask & (1 << NF_INET_LOCAL_OUT)) {
|
||||
pr_info_ratelimited("--physdev-out and --physdev-is-out only supported in the FORWARD and POSTROUTING chains with bridged traffic\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int physdev_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_physdev_info *info = par->matchinfo;
|
||||
@@ -99,13 +114,6 @@ static int physdev_mt_check(const struct xt_mtchk_param *par)
|
||||
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
|
||||
info->bitmask & ~XT_PHYSDEV_OP_MASK)
|
||||
return -EINVAL;
|
||||
if (info->bitmask & (XT_PHYSDEV_OP_OUT | XT_PHYSDEV_OP_ISOUT) &&
|
||||
(!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
|
||||
info->invert & XT_PHYSDEV_OP_BRIDGED) &&
|
||||
par->hook_mask & (1 << NF_INET_LOCAL_OUT)) {
|
||||
pr_info_ratelimited("--physdev-out and --physdev-is-out only supported in the FORWARD and POSTROUTING chains with bridged traffic\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#define X(memb) strnlen(info->memb, sizeof(info->memb)) >= sizeof(info->memb)
|
||||
if (info->bitmask & XT_PHYSDEV_OP_IN) {
|
||||
@@ -141,6 +149,7 @@ static struct xt_match physdev_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "physdev",
|
||||
.family = NFPROTO_IPV4,
|
||||
.check_hooks = physdev_mt_check_hooks,
|
||||
.checkentry = physdev_mt_check,
|
||||
.match = physdev_mt,
|
||||
.matchsize = sizeof(struct xt_physdev_info),
|
||||
@@ -149,6 +158,7 @@ static struct xt_match physdev_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "physdev",
|
||||
.family = NFPROTO_IPV6,
|
||||
.check_hooks = physdev_mt_check_hooks,
|
||||
.checkentry = physdev_mt_check,
|
||||
.match = physdev_mt,
|
||||
.matchsize = sizeof(struct xt_physdev_info),
|
||||
|
||||
@@ -126,13 +126,10 @@ policy_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int policy_mt_check(const struct xt_mtchk_param *par)
|
||||
static int policy_mt_check_hooks(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_policy_info *info = par->matchinfo;
|
||||
const char *errmsg = "neither incoming nor outgoing policy selected";
|
||||
|
||||
if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT)))
|
||||
goto err;
|
||||
const char *errmsg;
|
||||
|
||||
if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
|
||||
(1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) {
|
||||
@@ -144,6 +141,21 @@ static int policy_mt_check(const struct xt_mtchk_param *par)
|
||||
errmsg = "input policy not valid in POSTROUTING and OUTPUT";
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
pr_info_ratelimited("%s\n", errmsg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int policy_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_policy_info *info = par->matchinfo;
|
||||
const char *errmsg = "neither incoming nor outgoing policy selected";
|
||||
|
||||
if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT)))
|
||||
goto err;
|
||||
|
||||
if (info->len > XT_POLICY_MAX_ELEM) {
|
||||
errmsg = "too many policy elements";
|
||||
goto err;
|
||||
@@ -158,6 +170,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "policy",
|
||||
.family = NFPROTO_IPV4,
|
||||
.check_hooks = policy_mt_check_hooks,
|
||||
.checkentry = policy_mt_check,
|
||||
.match = policy_mt,
|
||||
.matchsize = sizeof(struct xt_policy_info),
|
||||
@@ -166,6 +179,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "policy",
|
||||
.family = NFPROTO_IPV6,
|
||||
.check_hooks = policy_mt_check_hooks,
|
||||
.checkentry = policy_mt_check,
|
||||
.match = policy_mt,
|
||||
.matchsize = sizeof(struct xt_policy_info),
|
||||
|
||||
+25
-14
@@ -430,6 +430,29 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
set_target_v3_check_hooks(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct xt_set_info_target_v3 *info = par->targinfo;
|
||||
|
||||
if (info->map_set.index != IPSET_INVALID_ID) {
|
||||
if (strncmp(par->table, "mangle", 7)) {
|
||||
pr_info_ratelimited("--map-set only usable from mangle table\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) |
|
||||
(info->flags & IPSET_FLAG_MAP_SKBQUEUE)) &&
|
||||
(par->hook_mask & ~(1 << NF_INET_FORWARD |
|
||||
1 << NF_INET_LOCAL_OUT |
|
||||
1 << NF_INET_POST_ROUTING))) {
|
||||
pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_target_v3_checkentry(const struct xt_tgchk_param *par)
|
||||
{
|
||||
@@ -459,20 +482,6 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par)
|
||||
}
|
||||
|
||||
if (info->map_set.index != IPSET_INVALID_ID) {
|
||||
if (strncmp(par->table, "mangle", 7)) {
|
||||
pr_info_ratelimited("--map-set only usable from mangle table\n");
|
||||
ret = -EINVAL;
|
||||
goto cleanup_del;
|
||||
}
|
||||
if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) |
|
||||
(info->flags & IPSET_FLAG_MAP_SKBQUEUE)) &&
|
||||
(par->hook_mask & ~(1 << NF_INET_FORWARD |
|
||||
1 << NF_INET_LOCAL_OUT |
|
||||
1 << NF_INET_POST_ROUTING))) {
|
||||
pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n");
|
||||
ret = -EINVAL;
|
||||
goto cleanup_del;
|
||||
}
|
||||
index = ip_set_nfnl_get_byindex(par->net,
|
||||
info->map_set.index);
|
||||
if (index == IPSET_INVALID_ID) {
|
||||
@@ -672,6 +681,7 @@ static struct xt_target set_targets[] __read_mostly = {
|
||||
.family = NFPROTO_IPV4,
|
||||
.target = set_target_v3,
|
||||
.targetsize = sizeof(struct xt_set_info_target_v3),
|
||||
.check_hooks = set_target_v3_check_hooks,
|
||||
.checkentry = set_target_v3_checkentry,
|
||||
.destroy = set_target_v3_destroy,
|
||||
.me = THIS_MODULE
|
||||
@@ -682,6 +692,7 @@ static struct xt_target set_targets[] __read_mostly = {
|
||||
.family = NFPROTO_IPV6,
|
||||
.target = set_target_v3,
|
||||
.targetsize = sizeof(struct xt_set_info_target_v3),
|
||||
.check_hooks = set_target_v3_check_hooks,
|
||||
.checkentry = set_target_v3_checkentry,
|
||||
.destroy = set_target_v3_destroy,
|
||||
.me = THIS_MODULE
|
||||
|
||||
Reference in New Issue
Block a user