summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac31
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set_compat.h.in19
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_netiface.c2
-rw-r--r--kernel/net/netfilter/xt_set.c26
-rw-r--r--kernel/net/sched/em_ipset.c24
5 files changed, 85 insertions, 17 deletions
diff --git a/configure.ac b/configure.ac
index cdb24d2..c7a030c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -508,6 +508,37 @@ else
AC_SUBST(HAVE_NET_IN_XT_ACTION_PARAM, undef)
fi
+AC_MSG_CHECKING([kernel source for struct nf_hook_state in struct xt_action_param])
+if test -f $ksourcedir/include/linux/netfilter/x_tables.h && \
+ $AWK '/^struct xt_action_param / {for(i=1; i<=10; i++) {getline; print}}' $ksourcedir/include/linux/netfilter/x_tables.h | \
+ $GREP -q 'struct nf_hook_state '; then
+ AC_MSG_RESULT(yes)
+ AC_SUBST(HAVE_STATE_IN_XT_ACTION_PARAM, define)
+else
+ AC_MSG_RESULT(no)
+ AC_SUBST(HAVE_STATE_IN_XT_ACTION_PARAM, undef)
+fi
+
+AC_MSG_CHECKING([kernel source for xt_family() in x_tables.h])
+if test -f $ksourcedir/include/linux/netfilter/x_tables.h && \
+ $GREP -q 'xt_family' $ksourcedir/include/linux/netfilter/x_tables.h; then
+ AC_MSG_RESULT(yes)
+ AC_SUBST(HAVE_XT_FAMILY, define)
+else
+ AC_MSG_RESULT(no)
+ AC_SUBST(HAVE_XT_FAMILY, undef)
+fi
+
+AC_MSG_CHECKING([kernel source for xt_net() in x_tables.h])
+if test -f $ksourcedir/include/linux/netfilter/x_tables.h && \
+ $GREP -q 'xt_net' $ksourcedir/include/linux/netfilter/x_tables.h; then
+ AC_MSG_RESULT(yes)
+ AC_SUBST(HAVE_XT_NET, define)
+else
+ AC_MSG_RESULT(no)
+ AC_SUBST(HAVE_XT_NET, undef)
+fi
+
AC_MSG_CHECKING([kernel source for struct net_generic])
if test -f $ksourcedir/include/net/netns/generic.h && \
$GREP -q 'struct net_generic' $ksourcedir/include/net/netns/generic.h; then
diff --git a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in
index 6bd24e5..a6f9093 100644
--- a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in
+++ b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in
@@ -35,6 +35,9 @@
#@HAVE_EXPORT_SYMBOL_GPL_IN_MODULE_H@ HAVE_EXPORT_SYMBOL_GPL_IN_MODULE_H
#@HAVE_TC_SKB_PROTOCOL@ HAVE_TC_SKB_PROTOCOL
#@HAVE_NET_IN_XT_ACTION_PARAM@ HAVE_NET_IN_XT_ACTION_PARAM
+#@HAVE_STATE_IN_XT_ACTION_PARAM@ HAVE_STATE_IN_XT_ACTION_PARAM
+#@HAVE_XT_FAMILY@ HAVE_XT_FAMILY
+#@HAVE_XT_NET@ HAVE_XT_NET
#ifdef HAVE_EXPORT_SYMBOL_GPL_IN_MODULE_H
#include <linux/module.h>
@@ -285,12 +288,26 @@ static inline __be16 tc_skb_protocol(const struct sk_buff *skb)
}
#endif
-#ifdef HAVE_NET_IN_XT_ACTION_PARAM
+#ifdef HAVE_XT_NET
+#define IPSET_DEV_NET(par) xt_net(par)
+#elif defined(HAVE_NET_IN_XT_ACTION_PARAM)
#define IPSET_DEV_NET(par) (par)->net
#else
#define IPSET_DEV_NET(par) dev_net((par)->in ? (par)->in : (par)->out)
#endif
+#ifdef HAVE_STATE_IN_XT_ACTION_PARAM
+#define XAP_STATE(par) (par->state)
+#else
+#define XAP_STATE(par) par
+#endif
+
+#ifdef HAVE_XT_FAMILY
+#define XT_FAMILY(par) xt_family(par)
+#else
+#define XT_FAMILY(par) (par)->family
+#endif
+
#ifndef smp_mb__before_atomic
#define smp_mb__before_atomic() smp_mb()
#define smp_mb__after_atomic() smp_mb()
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netiface.c b/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
index 5de22cb..079bbe1 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -170,7 +170,7 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
e.ip &= ip_set_netmask(e.cidr);
-#define IFACE(dir) (par->dir ? par->dir->name : "")
+#define IFACE(dir) (XAP_STATE(par)->dir ? XAP_STATE(par)->dir->name : "")
#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC)
if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
diff --git a/kernel/net/netfilter/xt_set.c b/kernel/net/netfilter/xt_set.c
index a0780b3..01868aa 100644
--- a/kernel/net/netfilter/xt_set.c
+++ b/kernel/net/netfilter/xt_set.c
@@ -72,7 +72,7 @@ set_match_v0(const struct sk_buff *skb, CONST struct xt_action_param *par)
{
const struct xt_set_info_match_v0 *info = par->matchinfo;
- ADT_OPT(opt, par->family, info->match_set.u.compat.dim,
+ ADT_OPT(opt, XT_FAMILY(par), info->match_set.u.compat.dim,
info->match_set.u.compat.flags, 0, UINT_MAX);
return match_set(info->match_set.index, skb, par, &opt,
@@ -135,7 +135,7 @@ set_match_v1(const struct sk_buff *skb, CONST struct xt_action_param *par)
{
const struct xt_set_info_match_v1 *info = par->matchinfo;
- ADT_OPT(opt, par->family, info->match_set.dim,
+ ADT_OPT(opt, XT_FAMILY(par), info->match_set.dim,
info->match_set.flags, 0, UINT_MAX);
if (opt.flags & IPSET_RETURN_NOMATCH)
@@ -201,7 +201,7 @@ set_match_v3(const struct sk_buff *skb, CONST struct xt_action_param *par)
const struct xt_set_info_match_v3 *info = par->matchinfo;
int ret;
- ADT_OPT(opt, par->family, info->match_set.dim,
+ ADT_OPT(opt, XT_FAMILY(par), info->match_set.dim,
info->match_set.flags, info->flags, UINT_MAX);
if (info->packets.op != IPSET_COUNTER_NONE ||
@@ -248,7 +248,7 @@ set_match_v4(const struct sk_buff *skb, CONST struct xt_action_param *par)
const struct xt_set_info_match_v4 *info = par->matchinfo;
int ret;
- ADT_OPT(opt, par->family, info->match_set.dim,
+ ADT_OPT(opt, XT_FAMILY(par), info->match_set.dim,
info->match_set.flags, info->flags, UINT_MAX);
if (info->packets.op != IPSET_COUNTER_NONE ||
@@ -284,9 +284,9 @@ set_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_set_info_target_v0 *info = par->targinfo;
- ADT_OPT(add_opt, par->family, info->add_set.u.compat.dim,
+ ADT_OPT(add_opt, XT_FAMILY(par), info->add_set.u.compat.dim,
info->add_set.u.compat.flags, 0, UINT_MAX);
- ADT_OPT(del_opt, par->family, info->del_set.u.compat.dim,
+ ADT_OPT(del_opt, XT_FAMILY(par), info->del_set.u.compat.dim,
info->del_set.u.compat.flags, 0, UINT_MAX);
if (info->add_set.index != IPSET_INVALID_ID)
@@ -362,9 +362,9 @@ set_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_set_info_target_v1 *info = par->targinfo;
- ADT_OPT(add_opt, par->family, info->add_set.dim,
+ ADT_OPT(add_opt, XT_FAMILY(par), info->add_set.dim,
info->add_set.flags, 0, UINT_MAX);
- ADT_OPT(del_opt, par->family, info->del_set.dim,
+ ADT_OPT(del_opt, XT_FAMILY(par), info->del_set.dim,
info->del_set.flags, 0, UINT_MAX);
if (info->add_set.index != IPSET_INVALID_ID)
@@ -436,9 +436,9 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_set_info_target_v2 *info = par->targinfo;
- ADT_OPT(add_opt, par->family, info->add_set.dim,
+ ADT_OPT(add_opt, XT_FAMILY(par), info->add_set.dim,
info->add_set.flags, info->flags, info->timeout);
- ADT_OPT(del_opt, par->family, info->del_set.dim,
+ ADT_OPT(del_opt, XT_FAMILY(par), info->del_set.dim,
info->del_set.flags, 0, UINT_MAX);
/* Normalize to fit into jiffies */
@@ -468,11 +468,11 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
const struct xt_set_info_target_v3 *info = par->targinfo;
int ret;
- ADT_OPT(add_opt, par->family, info->add_set.dim,
+ ADT_OPT(add_opt, XT_FAMILY(par), info->add_set.dim,
info->add_set.flags, info->flags, info->timeout);
- ADT_OPT(del_opt, par->family, info->del_set.dim,
+ ADT_OPT(del_opt, XT_FAMILY(par), info->del_set.dim,
info->del_set.flags, 0, UINT_MAX);
- ADT_OPT(map_opt, par->family, info->map_set.dim,
+ ADT_OPT(map_opt, XT_FAMILY(par), info->map_set.dim,
info->map_set.flags, 0, UINT_MAX);
/* Normalize to fit into jiffies */
diff --git a/kernel/net/sched/em_ipset.c b/kernel/net/sched/em_ipset.c
index a4ab08d..bd9566f 100644
--- a/kernel/net/sched/em_ipset.c
+++ b/kernel/net/sched/em_ipset.c
@@ -75,17 +75,27 @@ static int em_ipset_match(struct sk_buff *skb, struct tcf_ematch *em,
struct xt_action_param acpar;
const struct xt_set_info *set = (const void *) em->data;
struct net_device *dev, *indev = NULL;
+#ifdef HAVE_STATE_IN_XT_ACTION_PARAM
+ struct nf_hook_state state = {
+ .net = em->net,
+ };
+#endif
int ret, network_offset;
+#ifdef HAVE_STATE_IN_XT_ACTION_PARAM
+#define ACPAR_FAMILY(f) state.pf = f
+#else
+#define ACPAR_FAMILY(f) acpar.family = f
+#endif
switch (tc_skb_protocol(skb)) {
case htons(ETH_P_IP):
- acpar.family = NFPROTO_IPV4;
+ ACPAR_FAMILY(NFPROTO_IPV4);
if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
return 0;
acpar.thoff = ip_hdrlen(skb);
break;
case htons(ETH_P_IPV6):
- acpar.family = NFPROTO_IPV6;
+ ACPAR_FAMILY(NFPROTO_IPV6);
if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
return 0;
/* doesn't call ipv6_find_hdr() because ipset doesn't use
@@ -97,9 +107,13 @@ static int em_ipset_match(struct sk_buff *skb, struct tcf_ematch *em,
return 0;
}
+#ifdef HAVE_STATE_IN_XT_ACTION_PARAM
+ opt.family = state.pf;
+#else
acpar.hooknum = 0;
opt.family = acpar.family;
+#endif
opt.dim = set->dim;
opt.flags = set->flags;
opt.cmdflags = 0;
@@ -119,11 +133,17 @@ static int em_ipset_match(struct sk_buff *skb, struct tcf_ematch *em,
indev = dev_get_by_index_rcu(dev_net(dev), skb->skb_iif);
#endif
+#ifdef HAVE_STATE_IN_XT_ACTION_PARAM
+ state.in = indev ? indev : dev;
+ state.out = dev;
+ acpar.state = &state;
+#else
#ifdef HAVE_NET_IN_XT_ACTION_PARAM
acpar.net = em->net;
#endif
acpar.in = indev ? indev : dev;
acpar.out = dev;
+#endif /* HAVE_STATE_IN_XT_ACTION_PARAM */
ret = ip_set_test(set->index, skb, &acpar, &opt);