summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2015-04-27 21:48:33 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2015-04-27 21:49:25 +0200
commit3fdc27aaad9cd644ddaae6f2dba6f13b5e78f27f (patch)
tree7b8605a5026efd6e09e04210a0883abb469811c9
parent00a3c3dd11e54c3d98c11f081e8d05d2d27aa11d (diff)
netfilter: bridge: add helpers for fetching physin/outdevpablo
right now we store this in the nf_bridge_info struct, accessible via skb->nf_bridge. This patch prepares removal of this pointer from skb: Instead of using skb->nf_bridge->x, we use helpers to obtain the in/out device (or ifindexes). Followup patches to netfilter will then allow nf_bridge_info to be obtained by a call into the br_netfilter core, rather than keeping a pointer to it in sk_buff. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-rw-r--r--configure.ac10
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set_compat.h.in17
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_netiface.c34
3 files changed, 52 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac
index a6b86a9..c032bf6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -406,6 +406,16 @@ else
AC_SUBST(HAVE_ETHER_ADDR_COPY, undef)
fi
+AC_MSG_CHECKING([kernel source for nf_bridge_get_physindev])
+if test -f $ksourcedir/include/linux/netfilter_bridge.h && \
+ $GREP -q 'nf_bridge_get_physindev' $ksourcedir/include/linux/netfilter_bridge.h; then
+ AC_MSG_RESULT(yes)
+ AC_SUBST(HAVE_NF_BRIDGE_GET_PHYSDEV, define)
+else
+ AC_MSG_RESULT(no)
+ AC_SUBST(HAVE_NF_BRIDGE_GET_PHYSDEV, 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 5938d8f..02c2a37 100644
--- a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in
+++ b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in
@@ -43,6 +43,7 @@
#@HAVE_LIST_LAST_ENTRY@ HAVE_LIST_LAST_ENTRY
#@HAVE_LIST_NEXT_ENTRY@ HAVE_LIST_NEXT_ENTRY
#@HAVE_ETHER_ADDR_COPY@ HAVE_ETHER_ADDR_COPY
+#@HAVE_NF_BRIDGE_GET_PHYSDEV@ HAVE_NF_BRIDGE_GET_PHYSDEV
/* Not everything could be moved here. Compatibility stuffs can be found in
* xt_set.c, ip_set_core.c, ip_set_getport.c, pfxlen.c too.
@@ -209,6 +210,22 @@ static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
#define ether_addr_copy(dst, src) memcpy(dst, src, ETH_ALEN)
#endif
+#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+#ifndef HAVE_NF_BRIDGE_GET_PHYSDEV
+static inline struct net_device *
+nf_bridge_get_physindev(const struct sk_buff *skb)
+{
+ return skb->nf_bridge ? skb->nf_bridge->physindev : NULL;
+}
+
+static inline struct net_device *
+nf_bridge_get_physoutdev(const struct sk_buff *skb)
+{
+ return skb->nf_bridge ? skb->nf_bridge->physoutdev : NULL;
+}
+#endif
+#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 646c9f5..136af7c 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -18,6 +18,7 @@
#include <net/netlink.h>
#include <linux/netfilter.h>
+#include <linux/netfilter_bridge.h>
#include <linux/netfilter/ipset/pfxlen.h>
#include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set_hash.h>
@@ -134,6 +135,22 @@ hash_netiface4_data_next(struct hash_netiface4_elem *next,
#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed)
#include "ip_set_hash_gen.h"
+#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+static const char *get_physindev_name(const struct sk_buff *skb)
+{
+ struct net_device *dev = nf_bridge_get_physindev(skb);
+
+ return dev ? dev->name : NULL;
+}
+
+static const char *get_physoutdev_name(const struct sk_buff *skb)
+{
+ struct net_device *dev = nf_bridge_get_physoutdev(skb);
+
+ return dev ? dev->name : NULL;
+}
+#endif
+
static int
hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par,
@@ -156,17 +173,16 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
e.ip &= ip_set_netmask(e.cidr);
#define IFACE(dir) (par->dir ? par->dir->name : "")
-#define PHYSDEV(dir) (nf_bridge->dir ? nf_bridge->dir->name : "")
#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC)
if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
- const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+ const char *eiface = SRCDIR ? get_physindev_name(skb) :
+ get_phyoutdev_name(skb);
- if (!nf_bridge)
+ if (!eiface)
return -EINVAL;
- STRLCPY(e.iface,
- SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev));
+ STRLCPY(e.iface, eiface);
e.physdev = 1;
#endif
} else {
@@ -371,12 +387,12 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
- const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+ const char *eiface = SRCDIR ? get_physindev_name(skb) :
+ get_phyoutdev_name(skb);
- if (!nf_bridge)
+ if (!eiface)
return -EINVAL;
- STRLCPY(e.iface,
- SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev));
+ STRLCPY(e.iface, eiface);
e.physdev = 1;
#endif
} else {