unsigned int bpf_flags = 0;
struct bpf_cfg_in cfg = {};
bool seen_run = false;
+ bool skip_sw = false;
struct rtattr *tail;
int ret = 0;
while (argc > 0) {
if (matches(*argv, "run") == 0) {
NEXT_ARG();
+
+ if (seen_run)
+ duparg("run", *argv);
opt_bpf:
seen_run = true;
+ cfg.type = bpf_type;
cfg.argc = argc;
cfg.argv = argv;
- if (bpf_parse_common(bpf_type, &cfg, &bpf_cb_ops, n))
+ if (bpf_parse_common(&cfg, &bpf_cb_ops) < 0) {
+ fprintf(stderr,
+ "Unable to parse bpf command line\n");
return -1;
+ }
argc = cfg.argc;
argv = cfg.argv;
bpf_gen_flags |= TCA_CLS_FLAGS_SKIP_HW;
} else if (matches(*argv, "skip_sw") == 0) {
bpf_gen_flags |= TCA_CLS_FLAGS_SKIP_SW;
+ skip_sw = true;
} else if (matches(*argv, "action") == 0) {
NEXT_ARG();
if (parse_action(&argc, &argv, TCA_BPF_ACT, n)) {
NEXT_ARG_FWD();
}
+ if (skip_sw)
+ cfg.ifindex = t->tcm_ifindex;
+ if (bpf_load_common(&cfg, &bpf_cb_ops, n) < 0) {
+ fprintf(stderr, "Unable to load program\n");
+ return -1;
+ }
+
if (bpf_gen_flags)
addattr32(n, MAX_MSG, TCA_BPF_FLAGS_GEN, bpf_gen_flags);
if (bpf_flags)
struct rtattr *opt, __u32 handle)
{
struct rtattr *tb[TCA_BPF_MAX + 1];
+ int dump_ok = 0;
if (opt == NULL)
return 0;
}
if (tb[TCA_BPF_OPS] && tb[TCA_BPF_OPS_LEN])
- bpf_print_ops(f, tb[TCA_BPF_OPS],
+ bpf_print_ops(tb[TCA_BPF_OPS],
rta_getattr_u16(tb[TCA_BPF_OPS_LEN]));
- if (tb[TCA_BPF_TAG]) {
+ if (tb[TCA_BPF_ID])
+ dump_ok = bpf_dump_prog_info(f, rta_getattr_u32(tb[TCA_BPF_ID]));
+ if (!dump_ok && tb[TCA_BPF_TAG]) {
SPRINT_BUF(b);
fprintf(f, "tag %s ",
b, sizeof(b)));
}
- if (tb[TCA_BPF_ID])
- bpf_dump_prog_info(f, rta_getattr_u32(tb[TCA_BPF_ID]));
-
if (tb[TCA_BPF_POLICE]) {
fprintf(f, "\n");
tc_print_police(f, tb[TCA_BPF_POLICE]);