Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c737b7c4 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: bridge: add helpers for fetching physin/outdev



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: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent e70deecb
Loading
Loading
Loading
Loading
+22 −1
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
#define __LINUX_BRIDGE_NETFILTER_H
#define __LINUX_BRIDGE_NETFILTER_H


#include <uapi/linux/netfilter_bridge.h>
#include <uapi/linux/netfilter_bridge.h>

#include <linux/skbuff.h>


enum nf_br_hook_priorities {
enum nf_br_hook_priorities {
	NF_BR_PRI_FIRST = INT_MIN,
	NF_BR_PRI_FIRST = INT_MIN,
@@ -40,6 +40,27 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb)
		skb_dst_drop(skb);
		skb_dst_drop(skb);
}
}


static inline int nf_bridge_get_physinif(const struct sk_buff *skb)
{
	return skb->nf_bridge ? skb->nf_bridge->physindev->ifindex : 0;
}

static inline int nf_bridge_get_physoutif(const struct sk_buff *skb)
{
	return skb->nf_bridge ? skb->nf_bridge->physoutdev->ifindex : 0;
}

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;
}
#else
#else
#define br_drop_fake_rtable(skb)	        do { } while (0)
#define br_drop_fake_rtable(skb)	        do { } while (0)
#endif /* CONFIG_BRIDGE_NETFILTER */
#endif /* CONFIG_BRIDGE_NETFILTER */
+3 −1
Original line number Original line Diff line number Diff line
@@ -13,6 +13,7 @@
#include <net/dst.h>
#include <net/dst.h>
#include <net/netfilter/ipv4/nf_reject.h>
#include <net/netfilter/ipv4/nf_reject.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_bridge.h>
#include <net/netfilter/ipv4/nf_reject.h>
#include <net/netfilter/ipv4/nf_reject.h>


const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
@@ -146,7 +147,8 @@ void nf_send_reset(struct sk_buff *oldskb, int hook)
	 */
	 */
	if (oldskb->nf_bridge) {
	if (oldskb->nf_bridge) {
		struct ethhdr *oeth = eth_hdr(oldskb);
		struct ethhdr *oeth = eth_hdr(oldskb);
		nskb->dev = oldskb->nf_bridge->physindev;

		nskb->dev = nf_bridge_get_physindev(oldskb);
		niph->tot_len = htons(nskb->len);
		niph->tot_len = htons(nskb->len);
		ip_send_check(niph);
		ip_send_check(niph);
		if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
		if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
+3 −1
Original line number Original line Diff line number Diff line
@@ -13,6 +13,7 @@
#include <net/ip6_checksum.h>
#include <net/ip6_checksum.h>
#include <net/netfilter/ipv6/nf_reject.h>
#include <net/netfilter/ipv6/nf_reject.h>
#include <linux/netfilter_ipv6.h>
#include <linux/netfilter_ipv6.h>
#include <linux/netfilter_bridge.h>
#include <net/netfilter/ipv6/nf_reject.h>
#include <net/netfilter/ipv6/nf_reject.h>


const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
@@ -195,7 +196,8 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
	 */
	 */
	if (oldskb->nf_bridge) {
	if (oldskb->nf_bridge) {
		struct ethhdr *oeth = eth_hdr(oldskb);
		struct ethhdr *oeth = eth_hdr(oldskb);
		nskb->dev = oldskb->nf_bridge->physindev;

		nskb->dev = nf_bridge_get_physindev(oldskb);
		nskb->protocol = htons(ETH_P_IPV6);
		nskb->protocol = htons(ETH_P_IPV6);
		ip6h->payload_len = htons(sizeof(struct tcphdr));
		ip6h->payload_len = htons(sizeof(struct tcphdr));
		if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
		if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
+24 −8
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@
#include <net/netlink.h>
#include <net/netlink.h>


#include <linux/netfilter.h>
#include <linux/netfilter.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter/ipset/pfxlen.h>
#include <linux/netfilter/ipset/pfxlen.h>
#include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set_hash.h>
#include <linux/netfilter/ipset/ip_set_hash.h>
@@ -211,6 +212,22 @@ hash_netiface4_data_next(struct hash_netiface4_elem *next,
#define HKEY_DATALEN	sizeof(struct hash_netiface4_elem_hashed)
#define HKEY_DATALEN	sizeof(struct hash_netiface4_elem_hashed)
#include "ip_set_hash_gen.h"
#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_phyoutdev_name(const struct sk_buff *skb)
{
	struct net_device *dev = nf_bridge_get_physoutdev(skb);

	return dev ? dev->name : NULL;
}
#endif

static int
static int
hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
		    const struct xt_action_param *par,
		    const struct xt_action_param *par,
@@ -234,16 +251,15 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
	e.ip &= ip_set_netmask(e.cidr);
	e.ip &= ip_set_netmask(e.cidr);


#define IFACE(dir)	(par->dir ? par->dir->name : NULL)
#define IFACE(dir)	(par->dir ? par->dir->name : NULL)
#define PHYSDEV(dir)	(nf_bridge->dir ? nf_bridge->dir->name : NULL)
#define SRCDIR		(opt->flags & IPSET_DIM_TWO_SRC)
#define SRCDIR		(opt->flags & IPSET_DIM_TWO_SRC)


	if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
	if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
		const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
		e.iface = SRCDIR ? get_physindev_name(skb) :
				   get_phyoutdev_name(skb);


		if (!nf_bridge)
		if (!e.iface)
			return -EINVAL;
			return -EINVAL;
		e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
		e.physdev = 1;
		e.physdev = 1;
#else
#else
		e.iface = NULL;
		e.iface = NULL;
@@ -476,11 +492,11 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,


	if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
	if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
		const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
		e.iface = SRCDIR ? get_physindev_name(skb) :

				   get_phyoutdev_name(skb);
		if (!nf_bridge)
		if (!e.iface)
			return -EINVAL;
			return -EINVAL;
		e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);

		e.physdev = 1;
		e.physdev = 1;
#else
#else
		e.iface = NULL;
		e.iface = NULL;
+3 −2
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#include <net/route.h>
#include <net/route.h>


#include <linux/netfilter.h>
#include <linux/netfilter.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter/xt_LOG.h>
#include <linux/netfilter/xt_LOG.h>
#include <net/netfilter/nf_log.h>
#include <net/netfilter/nf_log.h>


@@ -163,10 +164,10 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
		const struct net_device *physindev;
		const struct net_device *physindev;
		const struct net_device *physoutdev;
		const struct net_device *physoutdev;


		physindev = skb->nf_bridge->physindev;
		physindev = nf_bridge_get_physindev(skb);
		if (physindev && in != physindev)
		if (physindev && in != physindev)
			nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
			nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
		physoutdev = skb->nf_bridge->physoutdev;
		physoutdev = nf_bridge_get_physoutdev(skb);
		if (physoutdev && out != physoutdev)
		if (physoutdev && out != physoutdev)
			nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
			nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
	}
	}
Loading