From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCB16C3A59D for ; Tue, 20 Aug 2019 11:48:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9BFA822D6D for ; Tue, 20 Aug 2019 11:48:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729818AbfHTLsA (ORCPT ); Tue, 20 Aug 2019 07:48:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57936 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729842AbfHTLr7 (ORCPT ); Tue, 20 Aug 2019 07:47:59 -0400 Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AD76E65F4A for ; Tue, 20 Aug 2019 11:47:58 +0000 (UTC) Received: by mail-ed1-f72.google.com with SMTP id h25so3988400edb.12 for ; Tue, 20 Aug 2019 04:47:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Tns3X20kzIxYMTEjCT9/3JYq9mPQM7ixlDT6OHIk8Ac=; b=pAr+tFIqvNs3DojivHhTgFFU6GcR8UvnqjqOrPjp7m7nNqx1USgci76+8bTOOJdQf7 70BQAcwFPWz4yGbMRiN5GyZnPsH421T/z9/2Yar1WAT4KHrxv0dYdQwjZe42LScbcsNZ YBn2WEpJLYx9qrMZGm4vdBGcKzlDL49A9cj9s6eow41p/qQfmXc1yAG1qMvUlf2JiLch ayeO86V4++j6NZF3mFXcl73Z71/3KLUbVW0xzePhorq9EoE4XHgJegK71Z+hLVroUb1e rBDm0c4t0WVA9j/hqK8EEbpPwja7x8F0Qdx3n8dWHAKFyIwjZJGUteBztM7I5xiayw8Z twug== X-Gm-Message-State: APjAAAVGuZ7Do18vUT+OuHxUKz8TbqHmx+2sZvXH4ZjWAKs8AJldieXA Y2VcYavCRxHOPoVEj5TeNDOB7J9RojG/kO7spyZ5uRSg4cNTg+4Jsgx+18FxgwY1P/E5x8tIEHs yTD4DkqJAQF23 X-Received: by 2002:aa7:dd04:: with SMTP id i4mr15429680edv.235.1566301677439; Tue, 20 Aug 2019 04:47:57 -0700 (PDT) X-Google-Smtp-Source: APXvYqxTWRWkO8YxsKXoauqAjnJheJ39tiXDk3ZoJ3sI2LJTZhlpt/LrwJiSC8myAhKAE6dihJg42A== X-Received: by 2002:aa7:dd04:: with SMTP id i4mr15429654edv.235.1566301677236; Tue, 20 Aug 2019 04:47:57 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id d9sm3386687edz.85.2019.08.20.04.47.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Aug 2019 04:47:56 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 3B18D181CE4; Tue, 20 Aug 2019 13:47:56 +0200 (CEST) From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= To: Stephen Hemminger , Daniel Borkmann , Alexei Starovoitov Cc: Martin KaFai Lau , Song Liu , Yonghong Song , David Miller , Jesper Dangaard Brouer , netdev@vger.kernel.org, bpf@vger.kernel.org, =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Subject: [RFC bpf-next 5/5] iproute2: Support loading XDP programs with libbpf Date: Tue, 20 Aug 2019 13:47:06 +0200 Message-Id: <20190820114706.18546-6-toke@redhat.com> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190820114706.18546-1-toke@redhat.com> References: <20190820114706.18546-1-toke@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org This switches over loading of XDP programs to the using libbpf, if it is available. It uses the automatic pinning features added to libbpf to construct the same pinning paths as the libelf-based loader. Since map-in-map support has not yet been added to libbpf, this means that map-in-map definitions will not work with this patch. Signed-off-by: Toke Høiland-Jørgensen --- lib/bpf.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 13 deletions(-) diff --git a/lib/bpf.c b/lib/bpf.c index c6e3bd0d..de1a655a 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -938,9 +938,17 @@ static int bpf_do_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl) return ret; } +#ifdef HAVE_LIBBPF +static int bpf_do_load_libbpf(struct bpf_cfg_in *cfg); +#endif + static int bpf_do_load(struct bpf_cfg_in *cfg) { if (cfg->mode == EBPF_OBJECT) { +#ifdef HAVE_LIBBPF + if(cfg->type == BPF_PROG_TYPE_XDP) + return bpf_do_load_libbpf(cfg); +#endif cfg->prog_fd = bpf_obj_open(cfg->object, cfg->type, cfg->section, cfg->ifindex, cfg->verbose); @@ -1407,25 +1415,22 @@ static bool bpf_no_pinning(const struct bpf_elf_ctx *ctx, } } -static void bpf_make_pathname(char *pathname, size_t len, const char *name, +static int bpf_make_pathname(char *pathname, size_t len, const char *name, const struct bpf_elf_ctx *ctx, uint32_t pinning) { switch (pinning) { case PIN_OBJECT_NS: - snprintf(pathname, len, "%s/%s/%s", - bpf_get_work_dir(ctx->type), - ctx->obj_uid, name); - break; + return snprintf(pathname, len, "%s/%s/%s", + bpf_get_work_dir(ctx->type), + ctx->obj_uid, name); case PIN_GLOBAL_NS: - snprintf(pathname, len, "%s/%s/%s", - bpf_get_work_dir(ctx->type), - BPF_DIR_GLOBALS, name); - break; + return snprintf(pathname, len, "%s/%s/%s", + bpf_get_work_dir(ctx->type), + BPF_DIR_GLOBALS, name); default: - snprintf(pathname, len, "%s/../%s/%s", - bpf_get_work_dir(ctx->type), - bpf_custom_pinning(ctx, pinning), name); - break; + return snprintf(pathname, len, "%s/../%s/%s", + bpf_get_work_dir(ctx->type), + bpf_custom_pinning(ctx, pinning), name); } } @@ -3160,3 +3165,87 @@ int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux, return ret; } #endif /* HAVE_ELF */ + +#ifdef HAVE_LIBBPF +static int bpf_gen_pin_name(void *priv, char *buf, int buf_len, + const char *name, unsigned int pinning) +{ + struct bpf_elf_ctx *ctx = priv; + const char *tmp; + int ret = 0; + + if (bpf_no_pinning(ctx, pinning) || !bpf_get_work_dir(ctx->type)) + return 0; + + if (pinning == PIN_OBJECT_NS) + ret = bpf_make_obj_path(ctx); + else if ((tmp = bpf_custom_pinning(ctx, pinning))) + ret = bpf_make_custom_path(ctx, tmp); + if (ret < 0) + return ret; + + return bpf_make_pathname(buf, buf_len, name, ctx, pinning); +} + +static int bpf_elf_ctx_init_stub(struct bpf_elf_ctx *ctx, const char *pathname, + enum bpf_prog_type type, int verbose) +{ + uint8_t tmp[20]; + int ret; + + memset(ctx, 0, sizeof(*ctx)); + ret = bpf_obj_hash(pathname, tmp, sizeof(tmp)); + if (ret) + ctx->noafalg = true; + else + hexstring_n2a(tmp, sizeof(tmp), ctx->obj_uid, + sizeof(ctx->obj_uid)); + + ctx->verbose = verbose; + ctx->type = type; + bpf_hash_init(ctx, CONFDIR "/bpf_pinning"); + + return 0; +} + +static int verbose_print(enum libbpf_print_level level, const char *format, + va_list args) +{ + return vfprintf(stderr, format, args); +} + +static int bpf_do_load_libbpf(struct bpf_cfg_in *cfg) +{ + struct bpf_elf_ctx *ctx = &__ctx; + struct bpf_program *prog; + struct bpf_object *obj; + int err, prog_fd = -1; + + struct bpf_prog_load_attr attr = { + .file = cfg->object, + .prog_type = cfg->type, + .ifindex = cfg->ifindex, + .log_level = cfg->verbose, + .auto_pin_cb = bpf_gen_pin_name, + .auto_pin_ctx = ctx, + }; + + if (cfg->verbose) + libbpf_set_print(verbose_print); + + bpf_elf_ctx_init_stub(ctx, cfg->object, cfg->type, cfg->verbose); + + err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); + if (err) + return err; + + if (cfg->section) { + prog = bpf_object__find_program_by_title(obj, + cfg->section); + prog_fd = bpf_program__fd(prog); + } + + cfg->prog_fd = prog_fd; + return cfg->prog_fd; +} +#endif -- 2.22.1