From patchwork Fri Mar 22 15:14:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 1061302 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Vk8qqGb/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44QnK54zkrz9sRk for ; Sat, 23 Mar 2019 02:15:21 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727050AbfCVPPU (ORCPT ); Fri, 22 Mar 2019 11:15:20 -0400 Received: from mail-qt1-f195.google.com ([209.85.160.195]:46600 "EHLO mail-qt1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726041AbfCVPPS (ORCPT ); Fri, 22 Mar 2019 11:15:18 -0400 Received: by mail-qt1-f195.google.com with SMTP id z17so2834188qts.13 for ; Fri, 22 Mar 2019 08:15:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZST5GqxUBIvT8T0S0DznoG5C1ARfm8EFpNqt1tBLxew=; b=Vk8qqGb/ATdX9UPGiKgJuINrCcrYOJ8MTuS/wJ0btkt0KEuRMMEOmY/AAuVAYkqzTp t56MXOg5/C51/PpPOsEucZ/rt4JuDMsOM//dpsJgJbbrQYDvmgOtDR+lcLioBQsJAx5+ Z4BZuzeOohq35nGNUSQkbBuMn2hjIO/8upsEZ7bKNXmbiW3KMGVY0c1eek1xf27iTDUz vNA6eVlk7yQll2KNghNmpTWuNDWTMxZJRziwoKMZy/uCOr25a/9yZKa+pdNtlV82OTYI cNPn3mxrKOgbU4PCb3T+L4xBTCQSJU0ISZlyKQCQc9vQaK26FmdHD5Y4kWIl7gn5CwH5 DWoA== 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=ZST5GqxUBIvT8T0S0DznoG5C1ARfm8EFpNqt1tBLxew=; b=JSAG61bLO4W7RyVP4lTrikF1nk0p0CbvdS40QJiHiKVaHtEFX+agi75Gz8Y0TEsK4V dHTp7Lj2lxujqyYO+R1g2IrbujQ4dRXDL7Y17shgZmzVOFpey7YH+khp49cD/Iz82Fud a+IbDI4le2GLEE027Nvi7k+qEQeWauPkqKUstfGpkUSoFVcMBgZfga/SPkDooeF6Kvdv jvNrEW4306NvSorLoUXKOmPlRr7AqmIqKJepsY9nsunN/z0GFXD/AO9C+TYG4eGZ/J/y dILlFdfi1myeSVPRSb4w0MtIlYJ8d3TddJdNQKUiKfwZ0bb6tu19adIqnBgCsC1phKTn 5Bfg== X-Gm-Message-State: APjAAAVDNmdv+R1uUvTgzu6CztiWIlk0TSBIxaa0gGfmSSvqq8vKxkYe 5zMpyqKgCtL1YAAi6ZDWptIYXRJP X-Google-Smtp-Source: APXvYqzsjsh+k2j33dqtCbEXRb5+HzMp9D2Vn8LAmgwuJodB0FUKUmJoN4fu5RQX/8dsEs5F9UbXoQ== X-Received: by 2002:ac8:2acc:: with SMTP id c12mr8631023qta.108.1553267716635; Fri, 22 Mar 2019 08:15:16 -0700 (PDT) Received: from willemb1.nyc.corp.google.com ([2620:0:1003:315:3fa1:a34c:1128:1d39]) by smtp.gmail.com with ESMTPSA id v4sm4631317qtq.94.2019.03.22.08.15.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Mar 2019 08:15:15 -0700 (PDT) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, alan.maguire@oracle.com, Willem de Bruijn Subject: [PATCH bpf-next v2 07/13] bpf: add bpf_skb_adjust_room mode BPF_ADJ_ROOM_MAC Date: Fri, 22 Mar 2019 11:14:58 -0400 Message-Id: <20190322151504.89983-8-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190322151504.89983-1-willemdebruijn.kernel@gmail.com> References: <20190322151504.89983-1-willemdebruijn.kernel@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Willem de Bruijn bpf_skb_adjust_room net allows inserting room in an skb. Existing mode BPF_ADJ_ROOM_NET inserts room after the network header by pulling the skb, moving the network header forward and zeroing the new space. Add new mode BPF_ADJUST_ROOM_MAC that inserts room after the mac header. This allows inserting tunnel headers in front of the network header without having to recreate the network header in the original space, avoiding two copies. Signed-off-by: Willem de Bruijn --- include/uapi/linux/bpf.h | 6 +++++- net/core/filter.c | 38 ++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 3c04410137d9..7c8fd0647070 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1478,7 +1478,10 @@ union bpf_attr { * Grow or shrink the room for data in the packet associated to * *skb* by *len_diff*, and according to the selected *mode*. * - * There is a single supported mode at this time: + * There are two supported modes at this time: + * + * * **BPF_ADJ_ROOM_MAC**: Adjust room at the mac layer + * (room space is added or removed below the layer 2 header). * * * **BPF_ADJ_ROOM_NET**: Adjust room at the network layer * (room space is added or removed below the layer 3 header). @@ -2627,6 +2630,7 @@ enum bpf_func_id { /* Mode for BPF_FUNC_skb_adjust_room helper. */ enum bpf_adj_room_mode { BPF_ADJ_ROOM_NET, + BPF_ADJ_ROOM_MAC, }; /* Mode for BPF_FUNC_skb_load_bytes_relative helper. */ diff --git a/net/core/filter.c b/net/core/filter.c index d21e1acdde29..e7b7720b18e9 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -2963,9 +2963,8 @@ static u32 bpf_skb_net_base_len(const struct sk_buff *skb) } } -static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff) +static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff) { - u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); int ret; if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) @@ -2992,9 +2991,8 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff) return 0; } -static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff) +static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff) { - u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); int ret; if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) @@ -3027,7 +3025,8 @@ static u32 __bpf_skb_max_len(const struct sk_buff *skb) SKB_MAX_ALLOC; } -static int bpf_skb_adjust_net(struct sk_buff *skb, s32 len_diff) +BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, + u32, mode, u64, flags) { bool trans_same = skb->transport_header == skb->network_header; u32 len_cur, len_diff_abs = abs(len_diff); @@ -3035,14 +3034,28 @@ static int bpf_skb_adjust_net(struct sk_buff *skb, s32 len_diff) u32 len_max = __bpf_skb_max_len(skb); __be16 proto = skb->protocol; bool shrink = len_diff < 0; + u32 off; int ret; + if (unlikely(flags)) + return -EINVAL; if (unlikely(len_diff_abs > 0xfffU)) return -EFAULT; if (unlikely(proto != htons(ETH_P_IP) && proto != htons(ETH_P_IPV6))) return -ENOTSUPP; + off = skb_mac_header_len(skb); + switch (mode) { + case BPF_ADJ_ROOM_NET: + off += bpf_skb_net_base_len(skb); + break; + case BPF_ADJ_ROOM_MAC: + break; + default: + return -ENOTSUPP; + } + len_cur = skb->len - skb_network_offset(skb); if (skb_transport_header_was_set(skb) && !trans_same) len_cur = skb_network_header_len(skb); @@ -3052,24 +3065,13 @@ static int bpf_skb_adjust_net(struct sk_buff *skb, s32 len_diff) !skb_is_gso(skb)))) return -ENOTSUPP; - ret = shrink ? bpf_skb_net_shrink(skb, len_diff_abs) : - bpf_skb_net_grow(skb, len_diff_abs); + ret = shrink ? bpf_skb_net_shrink(skb, off, len_diff_abs) : + bpf_skb_net_grow(skb, off, len_diff_abs); bpf_compute_data_pointers(skb); return ret; } -BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, - u32, mode, u64, flags) -{ - if (unlikely(flags)) - return -EINVAL; - if (likely(mode == BPF_ADJ_ROOM_NET)) - return bpf_skb_adjust_net(skb, len_diff); - - return -ENOTSUPP; -} - static const struct bpf_func_proto bpf_skb_adjust_room_proto = { .func = bpf_skb_adjust_room, .gpl_only = false,