aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_bpf.c
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2015-03-17 15:25:57 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-17 22:15:06 -0400
commitced585c83b27deca427c606a34dd3eaa6b96d82b (patch)
treebb3708147935b1cafdc95c61657cfa764efd87ca /net/sched/act_bpf.c
parent8d7d9cca4390062ccd09ffd9fdb37d1c4eeea9ac (diff)
act_bpf: allow non-default TC_ACT opcodes as BPF exec outcome
Revisiting commit d23b8ad8ab23 ("tc: add BPF based action") with regards to eBPF support, I was thinking that it might be better to improve return semantics from a BPF program invoked through BPF_PROG_RUN(). Currently, in case filter_res is 0, we overwrite the default action opcode with TC_ACT_SHOT. A default action opcode configured through tc's m_bpf can be: TC_ACT_RECLASSIFY, TC_ACT_PIPE, TC_ACT_SHOT, TC_ACT_UNSPEC, TC_ACT_OK. In cls_bpf, we have the possibility to overwrite the default class associated with the classifier in case filter_res is _not_ 0xffffffff (-1). That allows us to fold multiple [e]BPF programs into a single one, where they would otherwise need to be defined as a separate classifier with its own classid, needlessly redoing parsing work, etc. Similarly, we could do better in act_bpf: Since above TC_ACT* opcodes are exported to UAPI anyway, we reuse them for return-code-to-tc-opcode mapping, where we would allow above possibilities. Thus, like in cls_bpf, a filter_res of 0xffffffff (-1) means that the configured _default_ action is used. Any unkown return code from the BPF program would fail in tcf_bpf() with TC_ACT_UNSPEC. Should we one day want to make use of TC_ACT_STOLEN or TC_ACT_QUEUED, which both have the same semantics, we have the option to either use that as a default action (filter_res of 0xffffffff) or non-default BPF return code. All that will allow us to transparently use tcf_bpf() for both BPF flavours. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Jiri Pirko <jiri@resnulli.us> Cc: Alexei Starovoitov <ast@plumgrid.com> Cc: Jamal Hadi Salim <jhs@mojatatu.com> Acked-by: Jiri Pirko <jiri@resnulli.us> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/act_bpf.c')
-rw-r--r--net/sched/act_bpf.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index 82c5d7fc1988..5f6288fa3f12 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -25,21 +25,41 @@ static int tcf_bpf(struct sk_buff *skb, const struct tc_action *a,
25 struct tcf_result *res) 25 struct tcf_result *res)
26{ 26{
27 struct tcf_bpf *b = a->priv; 27 struct tcf_bpf *b = a->priv;
28 int action; 28 int action, filter_res;
29 int filter_res;
30 29
31 spin_lock(&b->tcf_lock); 30 spin_lock(&b->tcf_lock);
31
32 b->tcf_tm.lastuse = jiffies; 32 b->tcf_tm.lastuse = jiffies;
33 bstats_update(&b->tcf_bstats, skb); 33 bstats_update(&b->tcf_bstats, skb);
34 action = b->tcf_action;
35 34
36 filter_res = BPF_PROG_RUN(b->filter, skb); 35 filter_res = BPF_PROG_RUN(b->filter, skb);
37 if (filter_res == 0) { 36
38 /* Return code 0 from the BPF program 37 /* A BPF program may overwrite the default action opcode.
39 * is being interpreted as a drop here. 38 * Similarly as in cls_bpf, if filter_res == -1 we use the
40 */ 39 * default action specified from tc.
41 action = TC_ACT_SHOT; 40 *
41 * In case a different well-known TC_ACT opcode has been
42 * returned, it will overwrite the default one.
43 *
44 * For everything else that is unkown, TC_ACT_UNSPEC is
45 * returned.
46 */
47 switch (filter_res) {
48 case TC_ACT_PIPE:
49 case TC_ACT_RECLASSIFY:
50 case TC_ACT_OK:
51 action = filter_res;
52 break;
53 case TC_ACT_SHOT:
54 action = filter_res;
42 b->tcf_qstats.drops++; 55 b->tcf_qstats.drops++;
56 break;
57 case TC_ACT_UNSPEC:
58 action = b->tcf_action;
59 break;
60 default:
61 action = TC_ACT_UNSPEC;
62 break;
43 } 63 }
44 64
45 spin_unlock(&b->tcf_lock); 65 spin_unlock(&b->tcf_lock);