Received: by 2002:ab2:6309:0:b0:1fb:d597:ff75 with SMTP id s9csp1424286lqt; Fri, 7 Jun 2024 19:54:29 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXZjMUDjzEWLpxRTS24V6rIcaQCBI8Pigmcof+ChNUFXE4j9fTPWJoP1nSf3ZiTPnavlJuIiFXvJSMqL+jxqXXIlnOPaUkiZ9P8nwbE2A== X-Google-Smtp-Source: AGHT+IE6U6KXIpsMct7oqzfVk0dDyeI9PTxpTvG+A3gL6FHhLubi86jvayKdghEdcn5U7i+QGLeL X-Received: by 2002:ac8:7dca:0:b0:43a:a8ad:7954 with SMTP id d75a77b69052e-44041c65b22mr59617561cf.28.1717815269285; Fri, 07 Jun 2024 19:54:29 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717815269; cv=pass; d=google.com; s=arc-20160816; b=wIWS/YfGKl9A9H/iZR7SpZQgxNEpQ4x0GDstAAHeEJqGT1dNFGTfEnh3PBHrUBVTT1 zEnwQNi915F8ft98vEgi/bgtem08tKqtxkbkbbLfxViiHSwwzHHPnTNcRkMoFJYBYOrn 5U7SJhwBaMMYrKEASRixcCawYsfzXlwZ8/BTqbj5IpIDHEtRnAnsX0/OBbPfk4zoETnE RN4pElSvFqk52U9VVDmBpUiWdpg0SpaoV0IKGn8begh+8i/BToLW6rsmgMo8IwBQJmPs ueJKFS/5PQjjb51DKgaH49PlGT+W1eL+Lz+ca0OlGBtuAzasHohq/9D1c0jfep9Nbbc8 Wn2g== 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=eG9eAD1eUsRWubPosFB8FQEEdV1lJ1Ey5T3UFqQEt+8=; fh=8LKQuwT2myc/x4H/b/Z3t8UccHqqsWtR0iwWAuKBzLM=; b=boZGvhPYEEpAMKgpv+12emXzf2sQGqiZoydc7qhsHH7yDWC0Kx+24wQtzR4C6gGqJW Iy3/mu8r/vcBAPkD0/KVLJdt3BSgOc7zW5Eck3TcOhe88KC1oQUCyF9h7rKE8oTWW4WV 0BaqWDsouSIhPOc1eBtS8fvaYSNpEJEEQIyAHVUQlaWTbI+xKkuWskcWL/+g7kb4k1GD QTwraWh5lqVSdMswVLKyKeOW/H2UtKbVW5+CPwx3nmSsDYCbTi1UXcbYtZ8Mdtqs+DJt c2T5DdrybsaojOfCTAvoKCmy7sZzFnvU3yHTTXCqt/JekzMdblFEqNrlo8mla0BTmty0 6J0A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=kpQ0bjyf; 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-206885-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-206885-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. [147.75.199.223]) by mx.google.com with ESMTPS id d75a77b69052e-44038a6fc0esi54911491cf.109.2024.06.07.19.54.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jun 2024 19:54:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-206885-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=kpQ0bjyf; 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-206885-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-206885-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 AE6C41C21157 for ; Sat, 8 Jun 2024 02:54:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 58062E56C; Sat, 8 Jun 2024 02:54:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="kpQ0bjyf" Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (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 07F488BF8 for ; Sat, 8 Jun 2024 02:54:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.123 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717815259; cv=none; b=B1Yet+I2UvRN9Dal9Gt8+Tklq0wfrNi2vcTbsLsrlT0A/IIpAuSOPzIEuz+7dL/fRT5GcHj5dILVF02ba2lsMbjyZshC9eDGvMekP33lN9uTDpE+bXcu1ASSD26RCY0W2IptgtncGU3QMSB78cxhfq9kwEu2JwhhY5pd+daCSBw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717815259; c=relaxed/simple; bh=XCq98BdW69m3pSWZHjycAMDpvLfIsaMbXaCFIS2C+3k=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=oPNk7q5q1gZMbV7NY+uOms21eISDrlPLM6Xo/pRFbhF17s8plfQTtvC9uL/8F+SPeVddrhWknXeOKdzcMVoL39U/gSxp0mU+at5iG/fM0fD7OeEXjn/surn4BUl3U70OJVKpxX0Yl46PR3/0opXeHQ1N+S9R0Hhg4ealxPzU3jY= 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=kpQ0bjyf; arc=none smtp.client-ip=185.125.188.123 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-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (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-1.canonical.com (Postfix) with ESMTPS id 677A13F2D0 for ; Sat, 8 Jun 2024 02:54:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1717815248; bh=eG9eAD1eUsRWubPosFB8FQEEdV1lJ1Ey5T3UFqQEt+8=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=kpQ0bjyfJ+ZtznV5ozbDDA4WkHYP/w8qNkrfcnE9NsVWM7OtYHFriL4hkRbh2m5tk uCF8yhQhCKaSvQ0TR0/ohkLMUEidTe3hQ4yK8Cir+T6Lfxc0muObCAu9TsW9BOVnRe uKxw50LMydJCX9UHKKU5QWTZPFgJHAqtK2B9MuVs5nSNtinZveVs+UXp0nf68SabBA MSOJWe/K2i2kTXruDl/tfqO8Qv/5QqgYtwZIMoyOiMHx5zn6sG2hvGu0N0OgFSbIGN If2VwwCFrFh1rStfB0NCLcvD3qWJnWJZrdp+dK1E7OUogxI70ScqJJ9lvvxvWRwQep lwqIXrrMpRovQ== Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-1f656692564so28499575ad.2 for ; Fri, 07 Jun 2024 19:54:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717815247; x=1718420047; 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=eG9eAD1eUsRWubPosFB8FQEEdV1lJ1Ey5T3UFqQEt+8=; b=Q2LEJpB0TpHbJ9z0GGPc6qpIHaXAe5Owx/WngvQviRkkJn7jzaVwMWagDjy7zOLeOs 8aFrAfPLo1RUuff0vWv+Hoaprx7Zjfa3Fe0p+G4GNxFX15ZkLTobzDW8ROEjJnqmtEQG 014F58xbgPewUZQlogLc/ecE33YztzfOHUMNSKNWoqqssE7PHmli7TcPLYmA1evPR0Cx O46xiWRicnOPaC1xiRGvpJP9rR/qH2i54fDBkgImxdoexoHpSkDdooq6+yikhNQdu9ii dm7m34t7DSpiDC1zMrTW6S3lP4Dpemqp3ndLN0iIs6ksasVjClLCxEV94qNB+qI4uQO2 4Slw== X-Forwarded-Encrypted: i=1; AJvYcCWgbCfViH3JpWU3AIoiOnCnu287KxB4tPYp186TtdPPPaIUac05YV2FIySkoEqBfFAu31bOsihN7LHXc9sFk8i9D7O45zFA8dAU3Glc X-Gm-Message-State: AOJu0YxdmytNDucdv37ko0vR0DnhOVqnfgDCN1PA4eLG8qu6c2oi+BnM 8FBLe2Usa74Bp9TV+0TcmQWzuIataXg+zUFG8CGtkwOzpwMlv25lZXYVrRV/OU6rXFvVcwvmpxg vq3mCbgDkuuVBetaLKKU/PvfMqDrxH3P82YIaR3YFd7F1Dnv7DwV0peEO5DN9C7fw+oVhaLmnwG m6Dg== X-Received: by 2002:a17:902:a3cf:b0:1f6:dfbc:7f1c with SMTP id d9443c01a7336-1f6dfbc819amr23641455ad.35.1717815246673; Fri, 07 Jun 2024 19:54:06 -0700 (PDT) X-Received: by 2002:a17:902:a3cf:b0:1f6:dfbc:7f1c with SMTP id d9443c01a7336-1f6dfbc819amr23641255ad.35.1717815245929; Fri, 07 Jun 2024 19:54:05 -0700 (PDT) Received: from chengendu.. (2001-b011-381c-b87f-87a2-26e8-842b-6eef.dynamic-ip6.hinet.net. [2001:b011:381c:b87f:87a2:26e8:842b:6eef]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f6bd7e07edsm41614665ad.214.2024.06.07.19.54.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jun 2024 19:54:05 -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 v6] af_packet: Handle outgoing VLAN packets without hardware offloading Date: Sat, 8 Jun 2024 10:53:47 +0800 Message-ID: <20240608025347.90680-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 | 57 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ea3ebc160e25..8cffbe1f912d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -538,6 +538,43 @@ 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) +{ + struct vlan_hdr vhdr, *vh; + u8 *skb_orig_data = skb->data; + int skb_orig_len = skb->len; + + skb_push(skb, skb->data - skb_mac_header(skb)); + vh = skb_header_pointer(skb, ETH_HLEN, sizeof(vhdr), &vhdr); + if (skb_orig_data != skb->data) { + skb->data = skb_orig_data; + skb->len = skb_orig_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_orig_data = skb->data; + int skb_orig_len = skb->len; + + skb_push(skb, skb->data - skb_mac_header(skb)); + proto = __vlan_get_protocol(skb, proto, NULL); + if (skb_orig_data != skb->data) { + skb->data = skb_orig_data; + skb->len = skb_orig_len; + } + } + + return proto; +} + static void prb_del_retire_blk_timer(struct tpacket_kbdq_core *pkc) { del_timer_sync(&pkc->retire_blk_timer); @@ -1007,10 +1044,16 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *pkc, static void prb_fill_vlan_info(struct tpacket_kbdq_core *pkc, struct tpacket3_hdr *ppd) { + struct packet_sock *po = container_of(pkc, struct packet_sock, rx_ring.prb_bdqc); + if (skb_vlan_tag_present(pkc->skb)) { 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(po->sk.sk_type == SOCK_DGRAM && 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 +2471,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(sk->sk_type == SOCK_DGRAM && 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 +2504,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 +3530,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 +3588,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(sock->type == SOCK_DGRAM && 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