From patchwork Mon Oct 19 16:04:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 11844671 X-Patchwork-Delegate: bpf@iogearbox.net 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=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=unavailable 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 AE05FC43457 for ; Mon, 19 Oct 2020 16:05:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 586AF222B9 for ; Mon, 19 Oct 2020 16:05:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="DfkobQGU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730286AbgJSQFL (ORCPT ); Mon, 19 Oct 2020 12:05:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:22656 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730568AbgJSQFF (ORCPT ); Mon, 19 Oct 2020 12:05:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1603123503; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oNPjravVaxcCo6ufyTkom4COG7g6erShkorV8bvLIFg=; b=DfkobQGU0oGvvTIc48LhPpReL04evHrGCvrafExeShrEydIEQ+I6CK8BqJZgzSI3d+Ww+c Z4TxIc9Kpn1JJU08dW5Lg2ws85sjdbj7ZZxcThHBFRTFynZVPkR5gF3zTcViBneJ2OL4pY B/fAQeiSSFXcPW9lBrLELYoVQVrQmB0= Received: from mail-vs1-f71.google.com (mail-vs1-f71.google.com [209.85.217.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-90-DDgWXZ6jNrufsIB-PwkW1w-1; Mon, 19 Oct 2020 12:05:00 -0400 X-MC-Unique: DDgWXZ6jNrufsIB-PwkW1w-1 Received: by mail-vs1-f71.google.com with SMTP id d9so2070657vsl.12 for ; Mon, 19 Oct 2020 09:05:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=oNPjravVaxcCo6ufyTkom4COG7g6erShkorV8bvLIFg=; b=SM7FhadpmA5py15o92QP+e5qJuMwBU0c0bBUUIoMVmWDqlFJ3zuIu7jlSJ6SkPYHnq s6F/O8MRY1Y3l1cRzpCnEat3lX+HKAd62Wati25W/jU3+16QvySH5CSsNQJCKP6V9RwB m5R1tKW+NFWrWQvYsfZrQwbWlIuI8xgltSS/5aIR0dj0xP9BNoCgeaNf2cBoU4TsUFet 9dbb/lUJP1Rs8UqaMHZK89gO/5qCRjo4+p5W152l3LmNR6TKbGomaVf31Zfr+xMPTTBV ZtK1zKe764TGuTHRIW0LGI1n0qNr2yHT6ld4yuwj5wO4VU974aqxPQeIUaSVGCYmpRXI ojKg== X-Gm-Message-State: AOAM532TBNtmiOJq4UDFR5cc1zlxnM4p5N/kYwazMxSopag+DuzKoxeL ksiUsnLBGH3q+RGeCFeAdrvCyOpz5wH1jtoWxkgi0AvWIf8A4ffv8z+JA80Lxp4Re88O78eYpp5 TYiD86L7Wu+HZ X-Received: by 2002:a67:fd59:: with SMTP id g25mr644186vsr.29.1603123499499; Mon, 19 Oct 2020 09:04:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJykanLKQDu6ikfoanjSVL64s34Jz+KxL3muYO7CNjH7kGwaVwMqrW7AMXxfl0mIFz7FSmDSkw== X-Received: by 2002:a67:fd59:: with SMTP id g25mr644143vsr.29.1603123499187; Mon, 19 Oct 2020 09:04:59 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([45.145.92.2]) by smtp.gmail.com with ESMTPSA id j15sm30858vke.49.2020.10.19.09.04.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Oct 2020 09:04:57 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 357D21838FF; Mon, 19 Oct 2020 18:04:56 +0200 (CEST) Subject: [PATCH bpf 2/2] selftests: Update test_tc_redirect.sh to use the modified bpf_redirect_neigh() From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Daniel Borkmann Cc: David Ahern , netdev@vger.kernel.org, bpf@vger.kernel.org Date: Mon, 19 Oct 2020 18:04:56 +0200 Message-ID: <160312349612.7917.2292641333686513322.stgit@toke.dk> In-Reply-To: <160312349392.7917.6673239142315191801.stgit@toke.dk> References: <160312349392.7917.6673239142315191801.stgit@toke.dk> User-Agent: StGit/0.23 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net From: Toke Høiland-Jørgensen This updates the test_tc_neigh prog in selftests to use the new syntax of bpf_redirect_neigh(). To exercise the helper both with and without the optional parameter, add an additional test_tc_neigh_fib test program, which does a bpf_fib_lookup() followed by a call to bpf_redirect_neigh() instead of looking up the ifindex in a map. Update the test_tc_redirect.sh script to run both versions of the test, and while we're add it, fix it to work on systems that have a consolidated dual-stack 'ping' binary instead of separate ping/ping6 versions. Signed-off-by: Toke Høiland-Jørgensen --- tools/testing/selftests/bpf/progs/test_tc_neigh.c | 5 - .../selftests/bpf/progs/test_tc_neigh_fib.c | 142 ++++++++++++++++++++ tools/testing/selftests/bpf/test_tc_redirect.sh | 27 +++- 3 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/test_tc_neigh_fib.c diff --git a/tools/testing/selftests/bpf/progs/test_tc_neigh.c b/tools/testing/selftests/bpf/progs/test_tc_neigh.c index fe182616b112..b985ac4e7a81 100644 --- a/tools/testing/selftests/bpf/progs/test_tc_neigh.c +++ b/tools/testing/selftests/bpf/progs/test_tc_neigh.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include @@ -118,7 +119,7 @@ SEC("dst_ingress") int tc_dst(struct __sk_buff *skb) if (bpf_skb_store_bytes(skb, 0, &zero, sizeof(zero), 0) < 0) return TC_ACT_SHOT; - return bpf_redirect_neigh(get_dev_ifindex(dev_src), 0); + return bpf_redirect_neigh(get_dev_ifindex(dev_src), NULL, 0, 0); } SEC("src_ingress") int tc_src(struct __sk_buff *skb) @@ -142,7 +143,7 @@ SEC("src_ingress") int tc_src(struct __sk_buff *skb) if (bpf_skb_store_bytes(skb, 0, &zero, sizeof(zero), 0) < 0) return TC_ACT_SHOT; - return bpf_redirect_neigh(get_dev_ifindex(dev_dst), 0); + return bpf_redirect_neigh(get_dev_ifindex(dev_dst), NULL, 0, 0); } char __license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_tc_neigh_fib.c b/tools/testing/selftests/bpf/progs/test_tc_neigh_fib.c new file mode 100644 index 000000000000..055c7582c86c --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_tc_neigh_fib.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef ctx_ptr +# define ctx_ptr(field) (void *)(long)(field) +#endif + +#define AF_INET 2 +#define AF_INET6 10 + +static __always_inline int fill_fib_params_v4(struct __sk_buff *skb, + struct bpf_fib_lookup *fib_params) +{ + void *data_end = ctx_ptr(skb->data_end); + void *data = ctx_ptr(skb->data); + struct iphdr *ip4h; + + if (data + sizeof(struct ethhdr) > data_end) + return -1; + + ip4h = (struct iphdr *)(data + sizeof(struct ethhdr)); + if ((void *)(ip4h + 1) > data_end) + return -1; + + fib_params->family = AF_INET; + fib_params->tos = ip4h->tos; + fib_params->l4_protocol = ip4h->protocol; + fib_params->sport = 0; + fib_params->dport = 0; + fib_params->tot_len = bpf_ntohs(ip4h->tot_len); + fib_params->ipv4_src = ip4h->saddr; + fib_params->ipv4_dst = ip4h->daddr; + + return 0; +} + +static __always_inline int fill_fib_params_v6(struct __sk_buff *skb, + struct bpf_fib_lookup *fib_params) +{ + struct in6_addr *src = (struct in6_addr *)fib_params->ipv6_src; + struct in6_addr *dst = (struct in6_addr *)fib_params->ipv6_dst; + void *data_end = ctx_ptr(skb->data_end); + void *data = ctx_ptr(skb->data); + struct ipv6hdr *ip6h; + + if (data + sizeof(struct ethhdr) > data_end) + return -1; + + ip6h = (struct ipv6hdr *)(data + sizeof(struct ethhdr)); + if ((void *)(ip6h + 1) > data_end) + return -1; + + fib_params->family = AF_INET6; + fib_params->flowinfo = 0; + fib_params->l4_protocol = ip6h->nexthdr; + fib_params->sport = 0; + fib_params->dport = 0; + fib_params->tot_len = bpf_ntohs(ip6h->payload_len); + *src = ip6h->saddr; + *dst = ip6h->daddr; + + return 0; +} + +SEC("chk_egress") int tc_chk(struct __sk_buff *skb) +{ + void *data_end = ctx_ptr(skb->data_end); + void *data = ctx_ptr(skb->data); + __u32 *raw = data; + + if (data + sizeof(struct ethhdr) > data_end) + return TC_ACT_SHOT; + + return !raw[0] && !raw[1] && !raw[2] ? TC_ACT_SHOT : TC_ACT_OK; +} + +SEC("redir_ingress") int tc_dst(struct __sk_buff *skb) +{ + struct bpf_fib_lookup fib_params = { .ifindex = skb->ingress_ifindex }; + __u8 zero[ETH_ALEN * 2]; + int ret = -1; + + switch (skb->protocol) { + case __bpf_constant_htons(ETH_P_IP): + ret = fill_fib_params_v4(skb, &fib_params); + break; + case __bpf_constant_htons(ETH_P_IPV6): + ret = fill_fib_params_v6(skb, &fib_params); + break; + } + + if (ret) + return TC_ACT_OK; + + ret = bpf_fib_lookup(skb, &fib_params, sizeof(fib_params), 0); + if (ret == BPF_FIB_LKUP_RET_NOT_FWDED || ret < 0) + return TC_ACT_OK; + + __builtin_memset(&zero, 0, sizeof(zero)); + if (bpf_skb_store_bytes(skb, 0, &zero, sizeof(zero), 0) < 0) + return TC_ACT_SHOT; + + if (ret == BPF_FIB_LKUP_RET_SUCCESS) { + void *data_end = ctx_ptr(skb->data_end); + struct ethhdr *eth = ctx_ptr(skb->data); + + if (eth + 1 > data_end) + return TC_ACT_SHOT; + + __builtin_memcpy(eth->h_dest, fib_params.dmac, ETH_ALEN); + __builtin_memcpy(eth->h_source, fib_params.smac, ETH_ALEN); + + return bpf_redirect(fib_params.ifindex, 0); + + } else if (ret == BPF_FIB_LKUP_RET_NO_NEIGH) { + struct bpf_redir_neigh nh_params = {}; + + nh_params.nh_family = fib_params.family; + __builtin_memcpy(&nh_params.ipv6_nh, &fib_params.ipv6_dst, + sizeof(nh_params.ipv6_nh)); + + return bpf_redirect_neigh(fib_params.ifindex, &nh_params, + sizeof(nh_params), 0); + } + + return TC_ACT_SHOT; +} + +char __license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/test_tc_redirect.sh b/tools/testing/selftests/bpf/test_tc_redirect.sh index 6d7482562140..a4903739846d 100755 --- a/tools/testing/selftests/bpf/test_tc_redirect.sh +++ b/tools/testing/selftests/bpf/test_tc_redirect.sh @@ -24,8 +24,7 @@ command -v timeout >/dev/null 2>&1 || \ { echo >&2 "timeout is not available"; exit 1; } command -v ping >/dev/null 2>&1 || \ { echo >&2 "ping is not available"; exit 1; } -command -v ping6 >/dev/null 2>&1 || \ - { echo >&2 "ping6 is not available"; exit 1; } +if command -v ping6 >/dev/null 2>&1; then PING6=ping6; else PING6=ping; fi command -v perl >/dev/null 2>&1 || \ { echo >&2 "perl is not available"; exit 1; } command -v jq >/dev/null 2>&1 || \ @@ -152,7 +151,7 @@ netns_test_connectivity() echo -e "${TEST}: ${GREEN}PASS${NC}" TEST="ICMPv6 connectivity test" - ip netns exec ${NS_SRC} ping6 $PING_ARG ${IP6_DST} + ip netns exec ${NS_SRC} $PING6 $PING_ARG ${IP6_DST} if [ $? -ne 0 ]; then echo -e "${TEST}: ${RED}FAIL${NC}" exit 1 @@ -192,6 +191,24 @@ netns_setup_bpf() done } +netns_setup_bpf_fib() +{ + local obj=$1 + + ip netns exec ${NS_FWD} tc qdisc add dev veth_src_fwd clsact + ip netns exec ${NS_FWD} tc filter add dev veth_src_fwd ingress bpf da obj $obj sec redir_ingress + ip netns exec ${NS_FWD} tc filter add dev veth_src_fwd egress bpf da obj $obj sec chk_egress + + ip netns exec ${NS_FWD} tc qdisc add dev veth_dst_fwd clsact + ip netns exec ${NS_FWD} tc filter add dev veth_dst_fwd ingress bpf da obj $obj sec redir_ingress + ip netns exec ${NS_FWD} tc filter add dev veth_dst_fwd egress bpf da obj $obj sec chk_egress + + # bpf_fib_lookup() checks if forwarding is enabled + ip netns exec ${NS_FWD} sysctl -w net.ipv4.ip_forward=1 + ip netns exec ${NS_FWD} sysctl -w net.ipv6.conf.veth_dst_fwd.forwarding=1 + ip netns exec ${NS_FWD} sysctl -w net.ipv6.conf.veth_src_fwd.forwarding=1 +} + trap netns_cleanup EXIT set -e @@ -200,5 +217,9 @@ netns_setup_bpf test_tc_neigh.o netns_test_connectivity netns_cleanup netns_setup +netns_setup_bpf_fib test_tc_neigh_fib.o +netns_test_connectivity +netns_cleanup +netns_setup netns_setup_bpf test_tc_peer.o netns_test_connectivity