Received: by 2002:ab2:7903:0:b0:1fb:b500:807b with SMTP id a3csp1388454lqj; Mon, 3 Jun 2024 22:51:26 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVIQdPPIBJwlrySKlSj+JuWL/k2fX8R6Usd90GAsRmR0a+EbrLQ3h5Ia9fFrImJ2J15k7qw6zObuJr29lvkk213E5N+0O4s2kmzQd0OKQ== X-Google-Smtp-Source: AGHT+IEMz3txQaNSiVgBCJGAP/fIGvoZe+8B+PI7l7zBsLAzpYy8vXbK8vDhCBOxJLz+69ZV/ge+ X-Received: by 2002:a05:620a:2913:b0:795:823:509b with SMTP id af79cd13be357-79508235de8mr694710485a.4.1717480286290; Mon, 03 Jun 2024 22:51:26 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717480286; cv=pass; d=google.com; s=arc-20160816; b=HkNx2rKAnkpJ3ajGV8xIAU4g+XXyB6/3DW24P6vOVUYzWVgAQrWopGjgE4BWHIv5ea LXjT4asw4IaZN3dZGyOOSfT8SLEot0axtFL7lM6Izr+q4gHRmNlCvHickYyJyrSFWYpJ pGBQE94jvhBQVJQxHgLDoaqHJzE+ov4xBW2zDbATcG8fMDSAJ31snYMAMrBOsU4GWVRw R14k4ZQ4wtejyJwCMKDfv+9kahI3KlbkNBJJU6A9lgA0r37g5de6pkKFImbbe9pendK4 mQkSAymNJIfS65oI+SpL4wceRdDN6Fl30JX3vMiGnt/7yLHsIN0g89SMc9xv6gZag1Ol PTGg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=bakozUuCaN+IM6untUm+580ISMXPQFrIaEMbe9vcbuo=; fh=UB1RoGmktVIOw6Mglb7iLvvgMTzljSf5SNi7BVh5rLk=; b=RRS5qJApU4cDqqoWZOpyO99To1ASthBPj5JsU1chKkBnoV36Vx/TvQZIg6nz8GHRcM HdHgJ8pMrtraOq7OJCX5Prqc6btW+0OZX2yQAJhQ6voxgCsPiL8Lr8066sOBauTV394B detr6TkCM4o+2Q0GsoPY89Szdk/kLOt19crtFOH0EHbgWCGLnOsYZgbYzSY9tvkupAuX /24YUn03YlFQLb1FufhVpoZj+cjIYPqz01IiDwwusHqhsMBPpRV5us2HE3RFghcmlDBm 0Gn8+zy4oLyKh+9Di7lhnEQW6vfOI7zi2k20VmxNocoA4IcN5ojt/aJj+26rZmdgilc8 1mxQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=GFnLf3Tx; arc=pass (i=1 spf=pass spfdomain=canonical.com dkim=pass dkdomain=canonical.com dmarc=pass fromdomain=canonical.com); spf=pass (google.com: domain of linux-kernel+bounces-200073-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-200073-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id af79cd13be357-794f32a5622si905157285a.570.2024.06.03.22.51.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Jun 2024 22:51:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-200073-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=GFnLf3Tx; arc=pass (i=1 spf=pass spfdomain=canonical.com dkim=pass dkdomain=canonical.com dmarc=pass fromdomain=canonical.com); spf=pass (google.com: domain of linux-kernel+bounces-200073-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-200073-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 9FC151C23393 for ; Tue, 4 Jun 2024 05:51:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7517213DDD1; Tue, 4 Jun 2024 05:51:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="GFnLf3Tx" Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D6F6130A79 for ; Tue, 4 Jun 2024 05:51:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717480274; cv=none; b=ncIaCUiLRYni2tZEthwmG7Wc3YFybwk4GUCf3KWjkEMdfu0S2Xe/80mxhi9Y1WwT7AI4V9Y40oSkoY7xRiyh0VBM6w9vstupqILG9/5Plxw+PJznbkuM1q3QvzGKvpXPUw9RnQRWoj9GVrEJLfPyDbQ6CVmEaU8Y6BwWyfGn/wY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717480274; c=relaxed/simple; bh=uss0X1VN88HbrrQxklnUMnnojK0g+Phe6pPxPPeCyyA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=TW1fgd0hiBAyWMXcI07CACrXlpjZw9OR3MLKwfsNFMmeqAMwPIAqrOsWyNJVCw75oVmmqtnkhXgmiweCKXvW3GeGFDxoaG0JNktdABQhg+hgdNU/d31WhvJtvlNhYzsz0+RpY3NclJdo9dHd6HAtFe2D/5Y3bDe2qeJXr6IVDW0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=GFnLf3Tx; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 704763F2A1 for ; Tue, 4 Jun 2024 05:51:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1717480263; bh=bakozUuCaN+IM6untUm+580ISMXPQFrIaEMbe9vcbuo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=GFnLf3TxfuFyYvOzLXrGqDTZo4fyImCC02nFoHrEn/9TeanV6+w5FI7sQRMh+nbCR oy/9ZOe1cQp875wmfUg4ayEPypT5ZwVVCNYQBPNo/tZdxFkfKUvwvKzAb3I90SgJf+ h9qrx5adaVL4bHgODSSzh7/yhBfrkg1K0SUQ3illXGiK4IVZvf9v3XtZIyU7Pw8awO WPyHkxbZJPZJCBJFb5bgBRUAN9s4YOgo0HyCuOIXsZHZA3qrPbP/10uB38sHhsHLIH bFU9ljU19svJXoSuvzdm2lrQq3MbiSreGe3UGEyhUSnGpA32T979co0m1ai0L/Lc+d Mk8L8G6wlOAuw== Received: by mail-qt1-f200.google.com with SMTP id d75a77b69052e-43fa039d2dbso50282121cf.2 for ; Mon, 03 Jun 2024 22:51:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717480260; x=1718085060; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=bakozUuCaN+IM6untUm+580ISMXPQFrIaEMbe9vcbuo=; b=DtmnDQPiT5N5OGuC+WdtYCf03VqemTfGtASrrux/Myyz5sArHKlz13YXzDkgncmgJs KLr0g+4kTeaBoO2KX7nQM/iJJ8CcPAHn36vaPcyFBT1Ipb2NluQIuPHTm1zhLaleujzx 9EMCJshHh9J0c9DEaDUvSuhyKQFiKSuA0eQqpAZDztwB8WpET0qxfJpanz3kInLo3Ctn yI1lrjl1OqWWBfDUBwyA3ELY0TbGNnANurT9wHPl+7GhmOBvv8+i7SxoIclK185ANwQ5 DpPLYHtARWiDYGl5O3W2/LsP2sF7O2g4KSJrdsLBg3T2UUGI3qqZmsOqvkxJe7wh2sRE Qu9Q== X-Forwarded-Encrypted: i=1; AJvYcCVpuUhM/zZl7RmxET+jr6/kH8vXQ1zsgl3YK1gteMTYzXAOmbvoF7XVWhnz4v87VA7Gaqo/s42Ib98bVmsHNAHC3MDd1Hx4VLBrTUSU X-Gm-Message-State: AOJu0YzSoyk3CHr/6X0hSJfi0tqBjVDQwoL0u5bPzvThS+/s35yYClyy XlVNi/lV5pE/hQ6ozSb9y2wU1DMv80Xa4sgfhcqsN4cBoPVzyPSovkqmnjW1rugD09iy2ZyYnOT UvwA4dF45MKLVB5PCyIpEq54FbhSGqesKfNkHNO/vSAHBnhS5NGpv3Vk9sf2rjatYVjemnxqsrD 3jqw== X-Received: by 2002:ac8:7d42:0:b0:43e:3b8e:670f with SMTP id d75a77b69052e-43ff549f297mr105320041cf.43.1717480260394; Mon, 03 Jun 2024 22:51:00 -0700 (PDT) X-Received: by 2002:ac8:7d42:0:b0:43e:3b8e:670f with SMTP id d75a77b69052e-43ff549f297mr105319801cf.43.1717480259672; Mon, 03 Jun 2024 22:50:59 -0700 (PDT) Received: from localhost.localdomain ([2001:67c:1560:8007::aac:c40b]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-43ff23a1aacsm46472871cf.12.2024.06.03.22.50.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Jun 2024 22:50:59 -0700 (PDT) From: Chengen Du To: willemdebruijn.kernel@gmail.com Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, kaber@trash.net, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Chengen Du , stable@vger.kernel.org Subject: [PATCH v5] af_packet: Handle outgoing VLAN packets without hardware offloading Date: Tue, 4 Jun 2024 13:48:23 +0800 Message-ID: <20240604054823.20649-1-chengen.du@canonical.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The issue initially stems from libpcap. The ethertype will be overwritten as the VLAN TPID if the network interface lacks hardware VLAN offloading. In the outbound packet path, if hardware VLAN offloading is unavailable, the VLAN tag is inserted into the payload but then cleared from the sk_buff struct. Consequently, this can lead to a false negative when checking for the presence of a VLAN tag, causing the packet sniffing outcome to lack VLAN tag information (i.e., TCI-TPID). As a result, the packet capturing tool may be unable to parse packets as expected. The TCI-TPID is missing because the prb_fill_vlan_info() function does not modify the tp_vlan_tci/tp_vlan_tpid values, as the information is in the payload and not in the sk_buff struct. The skb_vlan_tag_present() function only checks vlan_all in the sk_buff struct. In cooked mode, the L2 header is stripped, preventing the packet capturing tool from determining the correct TCI-TPID value. Additionally, the protocol in SLL is incorrect, which means the packet capturing tool cannot parse the L3 header correctly. Link: https://github.com/the-tcpdump-group/libpcap/issues/1105 Link: https://lore.kernel.org/netdev/20240520070348.26725-1-chengen.du@canonical.com/T/#u Fixes: 393e52e33c6c ("packet: deliver VLAN TCI to userspace") Cc: stable@vger.kernel.org Signed-off-by: Chengen Du --- net/packet/af_packet.c | 64 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ea3ebc160e25..53d51ac87ac6 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -538,6 +538,52 @@ static void *packet_current_frame(struct packet_sock *po, return packet_lookup_frame(po, rb, rb->head, status); } +static u16 vlan_get_tci(struct sk_buff *skb) +{ + unsigned int vlan_depth = skb->mac_len; + struct vlan_hdr vhdr, *vh; + u8 *skb_head = skb->data; + int skb_len = skb->len; + + if (vlan_depth) { + if (WARN_ON(vlan_depth < VLAN_HLEN)) + return 0; + vlan_depth -= VLAN_HLEN; + } else { + vlan_depth = ETH_HLEN; + } + + skb_push(skb, skb->data - skb_mac_header(skb)); + vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr); + if (skb_head != skb->data) { + skb->data = skb_head; + skb->len = skb_len; + } + if (unlikely(!vh)) + return 0; + + return ntohs(vh->h_vlan_TCI); +} + +static __be16 vlan_get_protocol_dgram(struct sk_buff *skb) +{ + __be16 proto = skb->protocol; + + if (unlikely(eth_type_vlan(proto))) { + u8 *skb_head = skb->data; + int skb_len = skb->len; + + skb_push(skb, skb->data - skb_mac_header(skb)); + proto = __vlan_get_protocol(skb, proto, NULL); + if (skb_head != skb->data) { + skb->data = skb_head; + skb->len = skb_len; + } + } + + return proto; +} + static void prb_del_retire_blk_timer(struct tpacket_kbdq_core *pkc) { del_timer_sync(&pkc->retire_blk_timer); @@ -1011,6 +1057,10 @@ static void prb_fill_vlan_info(struct tpacket_kbdq_core *pkc, ppd->hv1.tp_vlan_tci = skb_vlan_tag_get(pkc->skb); ppd->hv1.tp_vlan_tpid = ntohs(pkc->skb->vlan_proto); ppd->tp_status = TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; + } else if (unlikely(eth_type_vlan(pkc->skb->protocol))) { + ppd->hv1.tp_vlan_tci = vlan_get_tci(pkc->skb); + ppd->hv1.tp_vlan_tpid = ntohs(pkc->skb->protocol); + ppd->tp_status = TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; } else { ppd->hv1.tp_vlan_tci = 0; ppd->hv1.tp_vlan_tpid = 0; @@ -2428,6 +2478,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, h.h2->tp_vlan_tci = skb_vlan_tag_get(skb); h.h2->tp_vlan_tpid = ntohs(skb->vlan_proto); status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; + } else if (unlikely(eth_type_vlan(skb->protocol))) { + h.h2->tp_vlan_tci = vlan_get_tci(skb); + h.h2->tp_vlan_tpid = ntohs(skb->protocol); + status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; } else { h.h2->tp_vlan_tci = 0; h.h2->tp_vlan_tpid = 0; @@ -2457,7 +2511,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, sll->sll_halen = dev_parse_header(skb, sll->sll_addr); sll->sll_family = AF_PACKET; sll->sll_hatype = dev->type; - sll->sll_protocol = skb->protocol; + sll->sll_protocol = (sk->sk_type == SOCK_DGRAM) ? + vlan_get_protocol_dgram(skb) : skb->protocol; sll->sll_pkttype = skb->pkt_type; if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV))) sll->sll_ifindex = orig_dev->ifindex; @@ -3482,7 +3537,8 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, /* Original length was stored in sockaddr_ll fields */ origlen = PACKET_SKB_CB(skb)->sa.origlen; sll->sll_family = AF_PACKET; - sll->sll_protocol = skb->protocol; + sll->sll_protocol = (sock->type == SOCK_DGRAM) ? + vlan_get_protocol_dgram(skb) : skb->protocol; } sock_recv_cmsgs(msg, sk, skb); @@ -3539,6 +3595,10 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, aux.tp_vlan_tci = skb_vlan_tag_get(skb); aux.tp_vlan_tpid = ntohs(skb->vlan_proto); aux.tp_status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; + } else if (unlikely(eth_type_vlan(skb->protocol))) { + aux.tp_vlan_tci = vlan_get_tci(skb); + aux.tp_vlan_tpid = ntohs(skb->protocol); + aux.tp_status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; } else { aux.tp_vlan_tci = 0; aux.tp_vlan_tpid = 0; -- 2.43.0