From: Chema Gonzalez <chema@google.com>
To: David Miller <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Daniel Borkmann <dborkman@redhat.com>,
Alexei Starovoitov <ast@plumgrid.com>
Cc: netdev@vger.kernel.org, Chema Gonzalez <chema@google.com>
Subject: [PATCH v6 net-next 2/4] net: filter: add insn for loading internal transport header offset
Date: Thu, 29 May 2014 11:56:03 -0700 [thread overview]
Message-ID: <1401389763-13320-1-git-send-email-chema@google.com> (raw)
In-Reply-To: <1398882591-30422-1-git-send-email-chema@google.com>
Patch adds an ANC_TRA_OFFSET insn that loads the internal transport
header of a packet ("internal" meaning after decapsulation by the
flow dissector). Goal is to be able to easily write filters based
on the inner-most header.
For example, the following filter will capture all packets whose
inner-most L4 dst port is 80:
ld #toff
tax
ldh [X+2]
jneq #80, drop
ret #-1
drop: ret #0
Signed-off-by: Chema Gonzalez <chema@google.com>
---
include/linux/filter.h | 1 +
include/uapi/linux/filter.h | 3 ++-
net/core/filter.c | 23 ++++++++++++++++++++++-
tools/net/bpf_exp.l | 1 +
tools/net/bpf_exp.y | 11 ++++++++++-
5 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 625f4de..9bc7771 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -304,6 +304,7 @@ enum {
BPF_S_ANC_VLAN_TAG_PRESENT,
BPF_S_ANC_PAY_OFFSET,
BPF_S_ANC_RANDOM,
+ BPF_S_ANC_TRA_OFFSET,
};
#endif /* __LINUX_FILTER_H__ */
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 253b4d4..9f1b8f1 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -131,7 +131,8 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
#define SKF_AD_VLAN_TAG_PRESENT 48
#define SKF_AD_PAY_OFFSET 52
#define SKF_AD_RANDOM 56
-#define SKF_AD_MAX 60
+#define SKF_AD_TRA_OFFSET 60
+#define SKF_AD_MAX 64
#define SKF_NET_OFF (-0x100000)
#define SKF_LL_OFF (-0x200000)
diff --git a/net/core/filter.c b/net/core/filter.c
index 0c55252..0d67498 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -623,6 +623,20 @@ static u64 __skb_get_pay_offset(u64 ctx, u64 a, u64 x, u64 fp, u64 r5)
&stack_layout->flow_inited);
}
+static u64 __skb_get_tra_offset(u64 ctx, u64 a, u64 x, u64 fp, u64 r5)
+{
+ struct classic_bpf_stack_layout *stack_layout =
+ (void *) fp - sizeof(struct classic_bpf_stack_layout);
+ /* check whether the flow dissector has already been run */
+ if (!stack_layout->flow_inited) {
+ if (!skb_flow_dissect((struct sk_buff *)(unsigned long) ctx,
+ &stack_layout->flow))
+ return 0;
+ stack_layout->flow_inited = 1;
+ }
+ return stack_layout->flow.thoff;
+}
+
static u64 __skb_get_nlattr(u64 ctx, u64 a, u64 x, u64 r4, u64 r5)
{
struct sk_buff *skb = (struct sk_buff *)(unsigned long) ctx;
@@ -789,6 +803,7 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
case SKF_AD_OFF + SKF_AD_NLATTR_NEST:
case SKF_AD_OFF + SKF_AD_CPU:
case SKF_AD_OFF + SKF_AD_RANDOM:
+ case SKF_AD_OFF + SKF_AD_TRA_OFFSET:
/* arg1 = ctx */
*insn = BPF_ALU64_REG(BPF_MOV, BPF_REG_ARG1, BPF_REG_CTX);
insn++;
@@ -823,6 +838,9 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
case SKF_AD_OFF + SKF_AD_RANDOM:
insn->imm = __get_random_u32 - __bpf_call_base;
break;
+ case SKF_AD_OFF + SKF_AD_TRA_OFFSET:
+ insn->imm = __skb_get_tra_offset - __bpf_call_base;
+ break;
}
break;
@@ -855,7 +873,8 @@ void __sk_convert_filter_prologue(struct sock_filter *fp, int len,
for (i = 0; i < len; fp++, i++) {
if (BPF_CLASS(fp->code) == BPF_LD &&
BPF_MODE(fp->code) == BPF_ABS &&
- fp->k == SKF_AD_OFF + SKF_AD_PAY_OFFSET) {
+ (fp->k == SKF_AD_OFF + SKF_AD_PAY_OFFSET ||
+ fp->k == SKF_AD_OFF + SKF_AD_TRA_OFFSET)) {
use_flow_dissector = true;
break;
}
@@ -1402,6 +1421,7 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
ANCILLARY(VLAN_TAG_PRESENT);
ANCILLARY(PAY_OFFSET);
ANCILLARY(RANDOM);
+ ANCILLARY(TRA_OFFSET);
}
/* ancillary operation unknown or unsupported */
@@ -1815,6 +1835,7 @@ void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
[BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_RANDOM] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_TRA_OFFSET] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_LD_W_LEN] = BPF_LD|BPF_W|BPF_LEN,
[BPF_S_LD_W_IND] = BPF_LD|BPF_W|BPF_IND,
[BPF_S_LD_H_IND] = BPF_LD|BPF_H|BPF_IND,
diff --git a/tools/net/bpf_exp.l b/tools/net/bpf_exp.l
index 833a966..4e72934 100644
--- a/tools/net/bpf_exp.l
+++ b/tools/net/bpf_exp.l
@@ -93,6 +93,7 @@ extern void yyerror(const char *str);
"#"?("vlan_tci") { return K_VLANT; }
"#"?("vlan_pr") { return K_VLANP; }
"#"?("rand") { return K_RAND; }
+"#"?("toff") { return K_TOFF; }
":" { return ':'; }
"," { return ','; }
diff --git a/tools/net/bpf_exp.y b/tools/net/bpf_exp.y
index e6306c5..ced6949 100644
--- a/tools/net/bpf_exp.y
+++ b/tools/net/bpf_exp.y
@@ -56,7 +56,7 @@ static void bpf_set_jmp_label(char *label, enum jmp_type type);
%token OP_LDXI
%token K_PKT_LEN K_PROTO K_TYPE K_NLATTR K_NLATTR_NEST K_MARK K_QUEUE K_HATYPE
-%token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP K_POFF K_RAND
+%token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP K_POFF K_RAND K_TOFF
%token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#' '%'
@@ -167,6 +167,9 @@ ldb
| OP_LDB K_RAND {
bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
SKF_AD_OFF + SKF_AD_RANDOM); }
+ | OP_LDB K_TOFF {
+ bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
+ SKF_AD_OFF + SKF_AD_TRA_OFFSET); }
;
ldh
@@ -218,6 +221,9 @@ ldh
| OP_LDH K_RAND {
bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
SKF_AD_OFF + SKF_AD_RANDOM); }
+ | OP_LDH K_TOFF {
+ bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
+ SKF_AD_OFF + SKF_AD_TRA_OFFSET); }
;
ldi
@@ -274,6 +280,9 @@ ld
| OP_LD K_RAND {
bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
SKF_AD_OFF + SKF_AD_RANDOM); }
+ | OP_LD K_TOFF {
+ bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
+ SKF_AD_OFF + SKF_AD_TRA_OFFSET); }
| OP_LD 'M' '[' number ']' {
bpf_set_curr_instr(BPF_LD | BPF_MEM, 0, 0, $4); }
| OP_LD '[' 'x' '+' number ']' {
--
1.9.1.423.g4596e3a
next prev parent reply other threads:[~2014-05-29 19:04 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 ` [PATCH v3 net-next 1/3] net: flow_dissector: avoid multiple calls in BPF Chema Gonzalez
2014-05-14 20:05 ` 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 ` Chema Gonzalez [this message]
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=1401389763-13320-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).