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

Commit 5a99e7f2 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'nf-ingress'

Pablo Neira Ayuso says:

====================
Netfilter ingress support (v4)

This is the v4 round of patches to add the Netfilter ingress hook, it basically
comes in two steps:

1) Add the CONFIG_NET_INGRESS switch to wrap the ingress static key around it.
   The idea is to use the same global static key to avoid adding more code to
   the hot path.

2) Add the Netfilter ingress hook after the tc ingress hook, under the global
   ingress_needed static key. As I said, the netfilter ingress hook also has
   its own static key, that is nested under the global static key. Please, see
   patch 5/5 for performance numbers and more information.

I originally started this next round, as it was suggested, exploring the
independent static key for netfilter ingress just after tc ingress, but the
results that I gathered from that patch are not good for non-users:

Result: OK: 6425927(c6425843+d83) usec, 100000000 (60byte,0frags)
  15561955pps 7469Mb/sec (7469738400bps) errors: 100000000

this roughly means 500Kpps less performance wrt. the base numbers, so that's
the reason why I discarded that approach and I focused on this.

The idea of this patchset is to open the window to nf_tables, which comes with
features that will work out-of-the-box (once the boiler plate code to support
the 'netdev' table family is in place), to avoid repeating myself [1], the most
relevant features are:

1) Multi-dimensional key dictionary lookups.
2) Arbitrary stateful flow tables.
3) Transactions and good support for dynamic updates.

But there are also interest aspects to consider from userspace, such as the
ability to support new layer 2 protocols without kernel updates, a well-defined
netlink interface, userspace libraries and utilities for third party
applications, among others.

I hope we can be happy with this approach.

Please, apply. Thanks.

[1] http://marc.info/?l=netfilter-devel&m=143033337020328&w=2


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a104a6b3 e687ad60
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1656,6 +1656,9 @@ struct net_device {
	struct tcf_proto __rcu  *ingress_cl_list;
#endif
	struct netdev_queue __rcu *ingress_queue;
#ifdef CONFIG_NETFILTER_INGRESS
	struct list_head	nf_hooks_ingress;
#endif

	unsigned char		broadcast[MAX_ADDR_LEN];
#ifdef CONFIG_RFS_ACCEL
+25 −14
Original line number Diff line number Diff line
@@ -54,10 +54,12 @@ struct nf_hook_state {
	struct net_device *in;
	struct net_device *out;
	struct sock *sk;
	struct list_head *hook_list;
	int (*okfn)(struct sock *, struct sk_buff *);
};

static inline void nf_hook_state_init(struct nf_hook_state *p,
				      struct list_head *hook_list,
				      unsigned int hook,
				      int thresh, u_int8_t pf,
				      struct net_device *indev,
@@ -71,6 +73,7 @@ static inline void nf_hook_state_init(struct nf_hook_state *p,
	p->in = indev;
	p->out = outdev;
	p->sk = sk;
	p->hook_list = hook_list;
	p->okfn = okfn;
}

@@ -83,6 +86,7 @@ struct nf_hook_ops {

	/* User fills in from here down. */
	nf_hookfn		*hook;
	struct net_device	*dev;
	struct module		*owner;
	void			*priv;
	u_int8_t		pf;
@@ -131,21 +135,28 @@ extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
#ifdef HAVE_JUMP_LABEL
extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];

static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook)
static inline bool nf_hook_list_active(struct list_head *nf_hook_list,
				       u_int8_t pf, unsigned int hook)
{
	if (__builtin_constant_p(pf) &&
	    __builtin_constant_p(hook))
		return static_key_false(&nf_hooks_needed[pf][hook]);

	return !list_empty(&nf_hooks[pf][hook]);
	return !list_empty(nf_hook_list);
}
#else
static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook)
static inline bool nf_hook_list_active(struct list_head *nf_hook_list,
				       u_int8_t pf, unsigned int hook)
{
	return !list_empty(&nf_hooks[pf][hook]);
	return !list_empty(nf_hook_list);
}
#endif

static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook)
{
	return nf_hook_list_active(&nf_hooks[pf][hook], pf, hook);
}

int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state);

/**
@@ -166,8 +177,8 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
	if (nf_hooks_active(pf, hook)) {
		struct nf_hook_state state;

		nf_hook_state_init(&state, hook, thresh, pf,
				   indev, outdev, sk, okfn);
		nf_hook_state_init(&state, &nf_hooks[pf][hook], hook, thresh,
				   pf, indev, outdev, sk, okfn);
		return nf_hook_slow(skb, &state);
	}
	return 1;
+41 −0
Original line number Diff line number Diff line
#ifndef _NETFILTER_INGRESS_H_
#define _NETFILTER_INGRESS_H_

#include <linux/netfilter.h>
#include <linux/netdevice.h>

#ifdef CONFIG_NETFILTER_INGRESS
static inline int nf_hook_ingress_active(struct sk_buff *skb)
{
	return nf_hook_list_active(&skb->dev->nf_hooks_ingress,
				   NFPROTO_NETDEV, NF_NETDEV_INGRESS);
}

static inline int nf_hook_ingress(struct sk_buff *skb)
{
	struct nf_hook_state state;

	nf_hook_state_init(&state, &skb->dev->nf_hooks_ingress,
			   NF_NETDEV_INGRESS, INT_MIN, NFPROTO_NETDEV, NULL,
			   skb->dev, NULL, NULL);
	return nf_hook_slow(skb, &state);
}

static inline void nf_hook_ingress_init(struct net_device *dev)
{
	INIT_LIST_HEAD(&dev->nf_hooks_ingress);
}
#else /* CONFIG_NETFILTER_INGRESS */
static inline int nf_hook_ingress_active(struct sk_buff *skb)
{
	return 0;
}

static inline int nf_hook_ingress(struct sk_buff *skb)
{
	return 0;
}

static inline void nf_hook_ingress_init(struct net_device *dev) {}
#endif /* CONFIG_NETFILTER_INGRESS */
#endif /* _NETFILTER_INGRESS_H_ */
+1 −1
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev)

struct netdev_queue *dev_ingress_queue_create(struct net_device *dev);

#ifdef CONFIG_NET_CLS_ACT
#ifdef CONFIG_NET_INGRESS
void net_inc_ingress_queue(void);
void net_dec_ingress_queue(void);
#endif
+6 −0
Original line number Diff line number Diff line
@@ -51,11 +51,17 @@ enum nf_inet_hooks {
	NF_INET_NUMHOOKS
};

enum nf_dev_hooks {
	NF_NETDEV_INGRESS,
	NF_NETDEV_NUMHOOKS
};

enum {
	NFPROTO_UNSPEC =  0,
	NFPROTO_INET   =  1,
	NFPROTO_IPV4   =  2,
	NFPROTO_ARP    =  3,
	NFPROTO_NETDEV =  5,
	NFPROTO_BRIDGE =  7,
	NFPROTO_IPV6   = 10,
	NFPROTO_DECNET = 12,
Loading