From: Chema Gonzalez <chema@google.com>
To: David Miller <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Alexei Starovoitov <ast@plumgrid.com>,
dborkman@redhat.com
Cc: netdev@vger.kernel.org, Chema Gonzalez <chema@google.com>
Subject: [PATCH v3 net-next 1/3] net: flow_dissector: avoid multiple calls in BPF
Date: Wed, 14 May 2014 11:51:20 -0700 [thread overview]
Message-ID: <1400093480-498-1-git-send-email-chema@google.com> (raw)
In-Reply-To: <1398882591-30422-1-git-send-email-chema@google.com>
We want multiple calls to __skb_get_poff() in the same filter to only
cause one invocation to the flow dissector. In order to reuse the result
of the flow dissector invocation (skb_flow_dissect()), we add a flow_keys
variable in the eBPF runner stack (__sk_run_filter() function), and pass
it as an argument to __skb_get_poff(). __skb_get_poff() inits the variable
the very first time it is called, and reuses the result in any further
invocation.
We also add handy function to init/check for inited flow_keys.
Signed-off-by: Chema Gonzalez <chema@google.com>
---
include/linux/skbuff.h | 4 +++-
net/core/filter.c | 14 ++++++++++++--
net/core/flow_dissector.c | 28 ++++++++++++++++++++++------
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7a9beeb..858d7af 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3065,7 +3065,9 @@ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off);
int skb_checksum_setup(struct sk_buff *skb, bool recalculate);
-u32 __skb_get_poff(const struct sk_buff *skb);
+void __flow_keys_reset(struct flow_keys *flow);
+bool __flow_keys_inited(struct flow_keys *flow);
+u32 __skb_get_poff(const struct sk_buff *skb, struct flow_keys *flow);
/**
* skb_head_is_locked - Determine if the skb->head is locked down
diff --git a/net/core/filter.c b/net/core/filter.c
index c442a0d..b71948b 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -66,6 +66,11 @@
#define CTX regs[BPF_REG_CTX]
#define K insn->imm
+struct sk_run_filter_ctx {
+ struct sk_buff *skb;
+ struct flow_keys *flow;
+};
+
/* No hurry in this branch
*
* Exported for the bpf jit load helper.
@@ -252,12 +257,15 @@ unsigned int __sk_run_filter(void *ctx, const struct sock_filter_int *insn)
};
void *ptr;
int off;
+ struct flow_keys flow;
+ struct sk_run_filter_ctx context = { ctx, &flow };
#define CONT ({ insn++; goto select_insn; })
#define CONT_JMP ({ insn++; goto select_insn; })
+ memset(&flow, 0, sizeof(flow));
FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)];
- ARG1 = (u64) (unsigned long) ctx;
+ ARG1 = (u64) (unsigned long) &context;
/* Register for user BPF programs need to be reset first. */
regs[BPF_REG_A] = 0;
@@ -602,7 +610,9 @@ static unsigned int pkt_type_offset(void)
static u64 __skb_get_pay_offset(u64 ctx, u64 a, u64 x, u64 r4, u64 r5)
{
- return __skb_get_poff((struct sk_buff *)(unsigned long) ctx);
+ struct sk_run_filter_ctx *context = (struct sk_run_filter_ctx *)
+ (unsigned long) ctx;
+ return __skb_get_poff(context->skb, context->flow);
}
static u64 __skb_get_nlattr(u64 ctx, u64 a, u64 x, u64 r4, u64 r5)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 107ed12..4d431f0 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -270,21 +270,37 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
}
EXPORT_SYMBOL(__skb_tx_hash);
+/* __flow_keys_reset() zeroes a flow_keys struct */
+void __flow_keys_reset(struct flow_keys *flow)
+{
+ memset(flow, 0, sizeof(struct flow_keys));
+}
+
+/* __flow_keys_inited() checks whether a flow_keys struct is init */
+bool __flow_keys_inited(struct flow_keys *flow)
+{
+ struct flow_keys zero_flow;
+
+ __flow_keys_reset(&zero_flow);
+ return memcmp(flow, &zero_flow, sizeof(struct flow_keys));
+}
+
/* __skb_get_poff() returns the offset to the payload as far as it could
* be dissected. The main user is currently BPF, so that we can dynamically
* truncate packets without needing to push actual payload to the user
* space and can analyze headers only, instead.
*/
-u32 __skb_get_poff(const struct sk_buff *skb)
+u32 __skb_get_poff(const struct sk_buff *skb, struct flow_keys *flow)
{
- struct flow_keys keys;
u32 poff = 0;
- if (!skb_flow_dissect(skb, &keys))
- return 0;
+ /* check whether the flow dissector has already been run */
+ if (!__flow_keys_inited(flow))
+ if (!skb_flow_dissect(skb, flow))
+ return 0;
- poff += keys.thoff;
- switch (keys.ip_proto) {
+ poff += flow->thoff;
+ switch (flow->ip_proto) {
case IPPROTO_TCP: {
const struct tcphdr *tcph;
struct tcphdr _tcph;
--
1.9.1.423.g4596e3a
next prev parent reply other threads:[~2014-05-14 18:51 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-30 18:29 [PATCH] net: filter: add insn for loading internal transport header offset Chema Gonzalez
2014-04-30 22:21 ` Alexei Starovoitov
2014-05-01 10:53 ` Daniel Borkmann
2014-05-01 10:55 ` Daniel Borkmann
2014-05-01 18:44 ` Chema Gonzalez
2014-05-01 18:44 ` [PATCH net-next v2] " Chema Gonzalez
2014-05-02 16:21 ` Ben Hutchings
2014-05-02 21:49 ` David Miller
2014-05-03 0:53 ` Chema Gonzalez
2014-05-03 2:52 ` David Miller
2014-05-05 18:42 ` Chema Gonzalez
2014-05-05 19:12 ` David Miller
2014-05-14 18:42 ` Chema Gonzalez
2014-05-14 18:51 ` Chema Gonzalez
2014-05-14 18:42 ` [PATCH v2 net-next 1/3] net: flow_dissector: avoid multiple calls in BPF Chema Gonzalez
2014-05-14 18:42 ` [PATCH v2 net-next 2/3] net: filter: add insn for loading internal transport header offset Chema Gonzalez
2014-05-14 18:42 ` [PATCH v2 net-next 3/3] net: filter: add insn for loading internal transport header proto Chema Gonzalez
2014-05-14 18:51 ` Chema Gonzalez [this message]
2014-05-14 20:05 ` [PATCH v3 net-next 1/3] net: flow_dissector: avoid multiple calls in BPF Alexei Starovoitov
2014-05-14 21:51 ` Chema Gonzalez
2014-05-14 22:44 ` Alexei Starovoitov
2014-05-16 18:41 ` Chema Gonzalez
2014-05-14 18:51 ` [PATCH v3 net-next 2/3] net: filter: add insn for loading internal transport header offset Chema Gonzalez
2014-05-14 18:51 ` [PATCH v3 net-next 3/3] net: filter: add insn for loading internal transport header proto Chema Gonzalez
2014-05-16 18:41 ` [PATCH v5 net-next 1/3] net: flow_dissector: avoid multiple calls in BPF Chema Gonzalez
2014-05-16 22:00 ` Alexei Starovoitov
2014-05-19 22:23 ` Chema Gonzalez
2014-05-20 9:58 ` Daniel Borkmann
2014-05-16 18:41 ` [PATCH v5 net-next 2/3] net: filter: add insn for loading internal transport header offset Chema Gonzalez
2014-05-16 18:41 ` [PATCH v5 net-next 3/3] net: filter: add insn for loading internal transport header proto Chema Gonzalez
2014-05-29 18:55 ` [PATCH v6 net-next 1/4] net: flow_dissector: avoid multiple calls in eBPF Chema Gonzalez
2014-05-29 23:54 ` Daniel Borkmann
2014-05-30 17:12 ` Chema Gonzalez
2014-06-02 12:36 ` Daniel Borkmann
2014-06-02 16:48 ` Alexei Starovoitov
2014-06-03 8:33 ` Daniel Borkmann
2014-06-03 20:15 ` Alexei Starovoitov
2014-06-03 21:12 ` Chema Gonzalez
2014-06-04 8:51 ` Daniel Borkmann
2014-06-05 6:55 ` David Miller
2014-06-20 21:56 ` Chema Gonzalez
2014-06-24 8:14 ` Daniel Borkmann
2014-06-25 22:00 ` Chema Gonzalez
2014-06-27 10:19 ` Daniel Borkmann
2014-05-29 18:56 ` [PATCH v6 net-next 2/4] net: filter: add insn for loading internal transport header offset Chema Gonzalez
2014-05-29 18:56 ` [PATCH v6 net-next 3/4] net: filter: add insn for loading internal transport header proto Chema Gonzalez
2014-05-29 18:56 ` [PATCH v6 net-next 4/4] net: filter: minor BPF cleanups Chema Gonzalez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1400093480-498-1-git-send-email-chema@google.com \
--to=chema@google.com \
--cc=ast@plumgrid.com \
--cc=davem@davemloft.net \
--cc=dborkman@redhat.com \
--cc=edumazet@google.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).