2 * m_bpf.c BPF based action module
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Jiri Pirko <jiri@resnulli.us>
10 * Daniel Borkmann <daniel@iogearbox.net>
16 #include <linux/bpf.h>
17 #include <linux/tc_act/tc_bpf.h>
23 static const enum bpf_prog_type bpf_type
= BPF_PROG_TYPE_SCHED_ACT
;
25 static const int nla_tbl
[BPF_NLA_MAX
] = {
26 [BPF_NLA_OPS_LEN
] = TCA_ACT_BPF_OPS_LEN
,
27 [BPF_NLA_OPS
] = TCA_ACT_BPF_OPS
,
28 [BPF_NLA_FD
] = TCA_ACT_BPF_FD
,
29 [BPF_NLA_NAME
] = TCA_ACT_BPF_NAME
,
32 static void explain(void)
34 fprintf(stderr
, "Usage: ... bpf ... [ index INDEX ]\n");
35 fprintf(stderr
, "\n");
36 fprintf(stderr
, "BPF use case:\n");
37 fprintf(stderr
, " bytecode BPF_BYTECODE\n");
38 fprintf(stderr
, " bytecode-file FILE\n");
39 fprintf(stderr
, "\n");
40 fprintf(stderr
, "eBPF use case:\n");
41 fprintf(stderr
, " object-file FILE [ section ACT_NAME ] [ export UDS_FILE ]");
42 fprintf(stderr
, " [ verbose ]\n");
43 fprintf(stderr
, " object-pinned FILE\n");
44 fprintf(stderr
, "\n");
45 fprintf(stderr
, "Where BPF_BYTECODE := \'s,c t f k,c t f k,c t f k,...\'\n");
46 fprintf(stderr
, "c,t,f,k and s are decimals; s denotes number of 4-tuples\n");
47 fprintf(stderr
, "\n");
48 fprintf(stderr
, "Where FILE points to a file containing the BPF_BYTECODE string,\n");
49 fprintf(stderr
, "an ELF file containing eBPF map definitions and bytecode, or a\n");
50 fprintf(stderr
, "pinned eBPF program.\n");
51 fprintf(stderr
, "\n");
52 fprintf(stderr
, "Where ACT_NAME refers to the section name containing the\n");
53 fprintf(stderr
, "action (default \'%s\').\n", bpf_default_section(bpf_type
));
54 fprintf(stderr
, "\n");
55 fprintf(stderr
, "Where UDS_FILE points to a unix domain socket file in order\n");
56 fprintf(stderr
, "to hand off control of all created eBPF maps to an agent.\n");
57 fprintf(stderr
, "\n");
58 fprintf(stderr
, "Where optionally INDEX points to an existing action, or\n");
59 fprintf(stderr
, "explicitly specifies an action index upon creation.\n");
62 static int bpf_parse_opt(struct action_util
*a
, int *ptr_argc
, char ***ptr_argv
,
63 int tca_id
, struct nlmsghdr
*n
)
65 const char *bpf_obj
= NULL
, *bpf_uds_name
= NULL
;
66 struct tc_act_bpf parm
= { .action
= TC_ACT_PIPE
};
67 bool seen_run
= false;
75 if (matches(*argv
, "bpf") != 0)
81 addattr_l(n
, MAX_MSG
, tca_id
, NULL
, 0);
84 if (matches(*argv
, "run") == 0) {
88 if (bpf_parse_common(&argc
, &argv
, nla_tbl
, bpf_type
,
89 &bpf_obj
, &bpf_uds_name
, n
)) {
90 fprintf(stderr
, "Failed to retrieve (e)BPF data!\n");
93 } else if (matches(*argv
, "help") == 0) {
96 } else if (matches(*argv
, "index") == 0) {
107 if (argc
&& !action_a2n(*argv
, &parm
.action
, false))
111 if (matches(*argv
, "index") == 0) {
113 if (get_u32(&parm
.index
, *argv
, 10)) {
114 fprintf(stderr
, "bpf: Illegal \"index\"\n");
122 addattr_l(n
, MAX_MSG
, TCA_ACT_BPF_PARMS
, &parm
, sizeof(parm
));
123 tail
->rta_len
= (char *)NLMSG_TAIL(n
) - (char *)tail
;
126 ret
= bpf_send_map_fds(bpf_uds_name
, bpf_obj
);
134 static int bpf_print_opt(struct action_util
*au
, FILE *f
, struct rtattr
*arg
)
136 struct rtattr
*tb
[TCA_ACT_BPF_MAX
+ 1];
137 struct tc_act_bpf
*parm
;
142 parse_rtattr_nested(tb
, TCA_ACT_BPF_MAX
, arg
);
144 if (!tb
[TCA_ACT_BPF_PARMS
]) {
145 fprintf(f
, "[NULL bpf parameters]");
149 parm
= RTA_DATA(tb
[TCA_ACT_BPF_PARMS
]);
152 if (tb
[TCA_ACT_BPF_NAME
])
153 fprintf(f
, "%s ", rta_getattr_str(tb
[TCA_ACT_BPF_NAME
]));
154 else if (tb
[TCA_ACT_BPF_FD
])
155 fprintf(f
, "pfd %u ", rta_getattr_u32(tb
[TCA_ACT_BPF_FD
]));
157 if (tb
[TCA_ACT_BPF_OPS
] && tb
[TCA_ACT_BPF_OPS_LEN
]) {
158 bpf_print_ops(f
, tb
[TCA_ACT_BPF_OPS
],
159 rta_getattr_u16(tb
[TCA_ACT_BPF_OPS_LEN
]));
163 fprintf(f
, "default-action %s\n", action_n2a(parm
->action
));
164 fprintf(f
, "\tindex %d ref %d bind %d", parm
->index
, parm
->refcnt
,
168 if (tb
[TCA_ACT_BPF_TM
]) {
169 struct tcf_t
*tm
= RTA_DATA(tb
[TCA_ACT_BPF_TM
]);
179 struct action_util bpf_action_util
= {
181 .parse_aopt
= bpf_parse_opt
,
182 .print_aopt
= bpf_print_opt
,