Re: [PATCH v6 5/6] net: ipv4, ipv6: run cgroup eBPF egress programs

5 messages, 4 authors, 2016-09-20 · open the first message on its own page

Re: [PATCH v6 5/6] net: ipv4, ipv6: run cgroup eBPF egress programs

From: Pablo Neira Ayuso <hidden>
Date: 2016-09-19 20:35:33

On Mon, Sep 19, 2016 at 09:30:02PM +0200, Daniel Mack wrote:
On 09/19/2016 09:19 PM, Pablo Neira Ayuso wrote:
quoted
On Mon, Sep 19, 2016 at 06:44:00PM +0200, Daniel Mack wrote:
quoted
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6001e78..5dc90aa 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -39,6 +39,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
+#include <linux/bpf-cgroup.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
 
@@ -143,6 +144,7 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct net_device *dev = skb_dst(skb)->dev;
 	struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
+	int ret;
 
 	if (unlikely(idev->cnf.disable_ipv6)) {
 		IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
@@ -150,6 +152,12 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 		return 0;
 	}
 
+	ret = cgroup_bpf_run_filter(sk, skb, BPF_CGROUP_INET_EGRESS);
+	if (ret) {
+		kfree_skb(skb);
+		return ret;
+	}
1) If your goal is to filter packets, why so late? The sooner you
   enforce your policy, the less cycles you waste.

Actually, did you look at Google's approach to this problem?  They
want to control this at socket level, so you restrict what the process
can actually bind. That is enforcing the policy way before you even
send packets. On top of that, what they submitted is infrastructured
so any process with CAP_NET_ADMIN can access that policy that is being
applied and fetch a readable policy through kernel interface.
Yes, I've seen what they propose, but I want this approach to support
accounting, and so the code has to look at each and every packet in
order to count bytes and packets. Do you know of any better place to put
the hook then?
Accounting is part of the usecase that fits into the "network
introspection" idea that has been mentioned here, so you can achieve
this by adding a hook that returns no verdict, so this becomes similar
to the tracing infrastructure.
That said, I can well imagine more hooks types that also operate at port
bind time. That would be easy to add on top.
Filtering packets with cgroups is braindead.

You have the means to ensure that processes send no packets via
restricting port binding, there is no reason to do this any later for
locally generated traffic.

Re: [PATCH v6 5/6] net: ipv4, ipv6: run cgroup eBPF egress programs

From: Daniel Mack <hidden>
Date: 2016-09-19 20:56:14

On 09/19/2016 10:35 PM, Pablo Neira Ayuso wrote:
On Mon, Sep 19, 2016 at 09:30:02PM +0200, Daniel Mack wrote:
quoted
On 09/19/2016 09:19 PM, Pablo Neira Ayuso wrote:
quoted
quoted
Actually, did you look at Google's approach to this problem?  They
want to control this at socket level, so you restrict what the process
can actually bind. That is enforcing the policy way before you even
send packets. On top of that, what they submitted is infrastructured
so any process with CAP_NET_ADMIN can access that policy that is being
applied and fetch a readable policy through kernel interface.
Yes, I've seen what they propose, but I want this approach to support
accounting, and so the code has to look at each and every packet in
order to count bytes and packets. Do you know of any better place to put
the hook then?
Accounting is part of the usecase that fits into the "network
introspection" idea that has been mentioned here, so you can achieve
this by adding a hook that returns no verdict, so this becomes similar
to the tracing infrastructure.
Why would we artificially limit the use-cases of this implementation if
the way it stands, both filtering and introspection are possible?
Filtering packets with cgroups is braindead.
Filtering is done via eBPF, and cgroups are just the containers. I don't
see what's brain-dead in that approach. After all, accessing the cgroup
once we have a local socket is really fast, so the idea is kinda obvious.
You have the means to ensure that processes send no packets via
restricting port binding, there is no reason to do this any later for
locally generated traffic.
Yes, restricting port binding can be done on top, if people are worried
about the performance overhead of a per-packet program.



Thanks,
Daniel

Re: [PATCH v6 5/6] net: ipv4, ipv6: run cgroup eBPF egress programs

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: 2016-09-20 14:29:47

On Mon, Sep 19, 2016 at 10:56:14PM +0200, Daniel Mack wrote:
[...]
Why would we artificially limit the use-cases of this implementation if
the way it stands, both filtering and introspection are possible?
Why should we place infrastructure in the kernel to filter packets so
late, and why at postrouting btw, when we can do this way earlier
before any packet is actually sent? No performance impact, no need for
skbuff allocation and *no cycles wasted to evaluate if every packet is
wanted or not*.

Re: [PATCH v6 5/6] net: ipv4, ipv6: run cgroup eBPF egress programs

From: Daniel Mack <hidden>
Date: 2016-09-20 16:43:35

Hi Pablo,

On 09/20/2016 04:29 PM, Pablo Neira Ayuso wrote:
On Mon, Sep 19, 2016 at 10:56:14PM +0200, Daniel Mack wrote:
[...]
quoted
Why would we artificially limit the use-cases of this implementation if
the way it stands, both filtering and introspection are possible?
Why should we place infrastructure in the kernel to filter packets so
late, and why at postrouting btw, when we can do this way earlier
before any packet is actually sent?
The point is that from an application's perspective, restricting the
ability to bind a port and dropping packets that are being sent is a
very different thing. Applications will start to behave differently if
they can't bind to a port, and that's something we do not want to happen.

Looking at packets and making a verdict on them is the only way to
implement what we have in mind. Given that's in line with what netfilter
does, it can't be all that wrong, can it?
No performance impact, no need for
skbuff allocation and *no cycles wasted to evaluate if every packet is
wanted or not*.
Hmm, not sure why this keeps coming up. As I said - for accounting,
there is no other option than to look at every packet and its size.

Regarding the performance concerns, are you saying a netfilter based
implementation that uses counters for that purpose would be more
efficient? Because in my tests, just loading the netfilter modules with
no rules in place at all has more impact than running the code from 6/6
on every packet.

As stated before, I see no reason why we shouldn't have a netfilter
based implementation that can achieve the same, function-wise. And I
would also like to compare their throughput.


Thanks,
Daniel

Re: [PATCH v6 5/6] net: ipv4, ipv6: run cgroup eBPF egress programs

From: Thomas Graf <hidden>
Date: 2016-09-20 16:53:29

On 09/20/16 at 04:29pm, Pablo Neira Ayuso wrote:
On Mon, Sep 19, 2016 at 10:56:14PM +0200, Daniel Mack wrote:
[...]
quoted
Why would we artificially limit the use-cases of this implementation if
the way it stands, both filtering and introspection are possible?
Why should we place infrastructure in the kernel to filter packets so
late, and why at postrouting btw, when we can do this way earlier
before any packet is actually sent? No performance impact, no need for
skbuff allocation and *no cycles wasted to evaluate if every packet is
wanted or not*.
I won't argue against filtering at socket level, it is very valuable.
A difference is transparency of enforcement. Dropping at networking
level is accounted for in the usual counters and well understood by
admins. "Dropping" at bind socket level would either involve returning
an error to the application (which may change behaviour of the application)
or require a new form of accounting.

I also want to see packet size, selected source address, outgoing device,
and attach tunnel key metadata to the skb based on the cgroup. All of
which are not available at socket level.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help