From patchwork Thu Jul 26 14:25:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toshiaki Makita X-Patchwork-Id: 949736 X-Patchwork-Delegate: bpf@iogearbox.net 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="Ff47TPI5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41bvY33Gr5z9s0w for ; Fri, 27 Jul 2018 00:26:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730764AbeGZPnf (ORCPT ); Thu, 26 Jul 2018 11:43:35 -0400 Received: from mail-pl0-f67.google.com ([209.85.160.67]:41346 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730059AbeGZPnf (ORCPT ); Thu, 26 Jul 2018 11:43:35 -0400 Received: by mail-pl0-f67.google.com with SMTP id w8-v6so901584ply.8 for ; Thu, 26 Jul 2018 07:26:29 -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; bh=wTcGWO8IQ8A6LK5/t3qJMB5bOXxQvw/zyQOdyj0X7Js=; b=Ff47TPI5Dwvs0UdaTb/e2GiP5LX2sXC4EsMSeKfQmG50ze8FkyHPhVv/Ojt2FztgUG F5WsdKefBwUV8MkZaGFd2FEmsAqdwS81nCKxDJcrJ3xRcW+uMJrTOIIw6UQfvDt/bGOJ 7Jj7cupHq4wOWbTyMYxVLq7aZKwHo04NW/bWdpFUgzWBm2Yq9sMLp2F1RSGnkdDV7Rtl a4CcjDNpTLRgNf7GQpqaU4YHwtwzMAzCyr2ZdfjTGCmoFz9ShgdFy2yOT7+9i+/XDSfH vEuI2BdJN+YQTMA6WsID6WF8ktxlsLqTOHc9w+UsVN+5+SQ4MASS60HE5wXBBc+8Zwnw MKLg== 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; bh=wTcGWO8IQ8A6LK5/t3qJMB5bOXxQvw/zyQOdyj0X7Js=; b=mX4Mixh89qDjIU1rWMYRQ1ZUBG310o/2BP8A6bIzKGKh6NQJH7qZP8il4+Eu2VXX7m iaD5LEuMSCHl4Uh5VpWreW7hSvEPJJrNBKLlmpB8GKKuzf5Uog6q2+zs6lTnGQlTZOaP u7QOZ0MdYqnztox2JLC1OXrctpK6eXWq41IreutS8EX8mPPoInpJ6A+VuBh8yUmlMaFX 9W54vXdk/M/ITnWI6E2JI0Hkh2V4S6K7oFe0vdN5E5szQT9SghtkCLRPBJFevP0jcI/w Ya6mRT0zlPwAS922jAYkZG89tXC+VAHMfF24XAkPIxk3MD+DZvRmGE7lBfbX3ciP60Wp Jssg== X-Gm-Message-State: AOUpUlGnuaXCtRWxkdipYY83/yO2Jz6poJGlEq7W71ZSAHUXQMKJjqDO jpJziZpsYl4tKNvTPmmwWZFqhuD4 X-Google-Smtp-Source: AAOMgpeSshIfgRTBKfCZyVY6VUhca3l3yWbF3WKIFtkEyJC844JDPIIv0WOo1DaWhh2czFX+24+g/w== X-Received: by 2002:a17:902:8645:: with SMTP id y5-v6mr2191444plt.334.1532615188363; Thu, 26 Jul 2018 07:26:28 -0700 (PDT) Received: from localhost.localdomain (i153-145-22-9.s42.a013.ap.plala.or.jp. [153.145.22.9]) by smtp.gmail.com with ESMTPSA id q26-v6sm2484150pff.9.2018.07.26.07.26.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 26 Jul 2018 07:26:27 -0700 (PDT) From: Toshiaki Makita To: netdev@vger.kernel.org, Alexei Starovoitov , Daniel Borkmann Cc: Toshiaki Makita , Jesper Dangaard Brouer , Jakub Kicinski , Toshiaki Makita Subject: [PATCH v4 bpf-next 5/9] veth: Add ndo_xdp_xmit Date: Thu, 26 Jul 2018 23:25:53 +0900 Message-Id: <20180726142557.1765-6-toshiaki.makita1@gmail.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180726142557.1765-1-toshiaki.makita1@gmail.com> References: <20180726142557.1765-1-toshiaki.makita1@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Toshiaki Makita This allows NIC's XDP to redirect packets to veth. The destination veth device enqueues redirected packets to the napi ring of its peer, then they are processed by XDP on its peer veth device. This can be thought as calling another XDP program by XDP program using REDIRECT, when the peer enables driver XDP. Note that when the peer veth device does not set driver xdp, redirected packets will be dropped because the peer is not ready for NAPI. v4: - Don't use xdp_ok_fwd_dev() because checking IFF_UP is not necessary. Add comments about it and check only MTU. v2: - Drop the part converting xdp_frame into skb when XDP is not enabled. - Implement bulk interface of ndo_xdp_xmit. - Implement XDP_XMIT_FLUSH bit and drop ndo_xdp_flush. Signed-off-by: Toshiaki Makita Signed-off-by: Toshiaki Makita --- drivers/net/veth.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index ef22d991f678..acdb1c543f4b 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -125,6 +126,11 @@ static void *veth_ptr_to_xdp(void *ptr) return (void *)((unsigned long)ptr & ~VETH_XDP_FLAG); } +static void *veth_xdp_to_ptr(void *ptr) +{ + return (void *)((unsigned long)ptr | VETH_XDP_FLAG); +} + static void veth_ptr_free(void *ptr) { if (veth_is_xdp_frame(ptr)) @@ -267,6 +273,50 @@ static struct sk_buff *veth_build_skb(void *head, int headroom, int len, return skb; } +static int veth_xdp_xmit(struct net_device *dev, int n, + struct xdp_frame **frames, u32 flags) +{ + struct veth_priv *rcv_priv, *priv = netdev_priv(dev); + struct net_device *rcv; + unsigned int max_len; + int i, drops = 0; + + if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) + return -EINVAL; + + rcv = rcu_dereference(priv->peer); + if (unlikely(!rcv)) + return -ENXIO; + + rcv_priv = netdev_priv(rcv); + /* Non-NULL xdp_prog ensures that xdp_ring is initialized on receive + * side. This means an XDP program is loaded on the peer and the peer + * device is up. + */ + if (!rcu_access_pointer(rcv_priv->xdp_prog)) + return -ENXIO; + + max_len = rcv->mtu + rcv->hard_header_len + VLAN_HLEN; + + spin_lock(&rcv_priv->xdp_ring.producer_lock); + for (i = 0; i < n; i++) { + struct xdp_frame *frame = frames[i]; + void *ptr = veth_xdp_to_ptr(frame); + + if (unlikely(frame->len > max_len || + __ptr_ring_produce(&rcv_priv->xdp_ring, ptr))) { + xdp_return_frame_rx_napi(frame); + drops++; + } + } + spin_unlock(&rcv_priv->xdp_ring.producer_lock); + + if (flags & XDP_XMIT_FLUSH) + __veth_xdp_flush(rcv_priv); + + return n - drops; +} + static struct sk_buff *veth_xdp_rcv_one(struct veth_priv *priv, struct xdp_frame *frame) { @@ -766,6 +816,7 @@ static const struct net_device_ops veth_netdev_ops = { .ndo_features_check = passthru_features_check, .ndo_set_rx_headroom = veth_set_rx_headroom, .ndo_bpf = veth_xdp, + .ndo_xdp_xmit = veth_xdp_xmit, }; #define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \