Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp884049pxb; Tue, 3 Nov 2020 15:29:57 -0800 (PST) X-Google-Smtp-Source: ABdhPJyUprLj61/fehm9JadS/qRWYfCLBH1igIBkvUIEJH0A3yke0hc8rSNl8VNUp5vEQZlwz1Im X-Received: by 2002:a50:950e:: with SMTP id u14mr23916572eda.260.1604446197579; Tue, 03 Nov 2020 15:29:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604446197; cv=none; d=google.com; s=arc-20160816; b=cM/+HE/rShPLTIsRf6z1/rE9Jl6hE4ytDa+P9aPosEPksgyIZTo2bvsGCUkdWZZeLL NIngUIYEmvBxDij/b0/6c5jPcerc2w2oAv8jf+Xz9NhkgC8qDBm2ytSCZVvm5pdJnbHR Rz5o8cLJIxsJDrfke9V3gaciqeyMOzCRcpLIzbOz/akbinJJ+3TimnSNqv3gkmxfXyOw t+0KYY+fK+h7tm4F1RCzyew6mAQ95bn7MqN5YYF950Rq/Ri2tBd3pWugXkqyrMUeJWc5 K9EDnepkesfdMGQfZDsa55gY4PZJNYZSTrLOO5EEn9YsfRTID+dXNrXR2jaCxGa38Ror zpXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=TwbLzQl7Jvkur7Xcv+dkKCF4QxuacVPQmCtfpop1D7Y=; b=gWigBq4khXYAr18Tp2DKTtWjn2lbFl0kc/PsE+XiFxSPErNvz1vWXQaaGO77IFypmJ 5nFd9t1/M33NQhCTHHuagjxmDKFEz0coC7MiqftoXp1J1Ca3V/fhX7ezigg7pN+p4Cxe Y2M0ATrL1xl+HSte8kPrmcsCFjtNeGWkMAptJMDKjby1/Zg2KguBBqNRc7jCCkj9OpVO D5wevzMPgL3NTmjsJ5D50IHXBZ+BSJ8vK3BEuUOUw5Zw61IvbM50j4w3viFgcRquj5nA 9nPXkgfhzkBUWW+HXuIa5E9z3FKLEXnHLDBjHg3Xzp1KxtSdFEC1N4vPro/KzK1SIx3t 4CFw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="VDQr3Xp/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s20si217010eji.711.2020.11.03.15.29.34; Tue, 03 Nov 2020 15:29:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="VDQr3Xp/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732923AbgKCVmu (ORCPT + 99 others); Tue, 3 Nov 2020 16:42:50 -0500 Received: from mail.kernel.org ([198.145.29.99]:55692 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732278AbgKCUzV (ORCPT ); Tue, 3 Nov 2020 15:55:21 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 806DE223BD; Tue, 3 Nov 2020 20:55:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1604436920; bh=p8r48/0O0bFuRYbXSO15mbWvfUOyDkFCWdH+Jt+GNHI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VDQr3Xp/xIT6Fvm3Hn9BsQTSpWqVA/MFMLk5VeO/gZLRhLUEkkzQW8K8sFy1OlJsv nJ4wvXUwG6qwVk827oY9njboXiwZTpsf/dUs2VihOYfFGER9t6wpZxbwxxXz0E1kpS wX7LtjNQBeUL5kQECZjxZ6ywpUpY118h9onkt2q8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Krzysztof Halasa , Xie He , "David S. Miller" , Sasha Levin Subject: [PATCH 5.4 067/214] drivers/net/wan/hdlc_fr: Correctly handle special skb->protocol values Date: Tue, 3 Nov 2020 21:35:15 +0100 Message-Id: <20201103203256.667064609@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201103203249.448706377@linuxfoundation.org> References: <20201103203249.448706377@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xie He [ Upstream commit 8306266c1d51aac9aa7aa907fe99032a58c6382c ] The fr_hard_header function is used to prepend the header to skbs before transmission. It is used in 3 situations: 1) When a control packet is generated internally in this driver; 2) When a user sends an skb on an Ethernet-emulating PVC device; 3) When a user sends an skb on a normal PVC device. These 3 situations need to be handled differently by fr_hard_header. Different headers should be prepended to the skb in different situations. Currently fr_hard_header distinguishes these 3 situations using skb->protocol. For situation 1 and 2, a special skb->protocol value will be assigned before calling fr_hard_header, so that it can recognize these 2 situations. All skb->protocol values other than these special ones are treated by fr_hard_header as situation 3. However, it is possible that in situation 3, the user sends an skb with one of the special skb->protocol values. In this case, fr_hard_header would incorrectly treat it as situation 1 or 2. This patch tries to solve this issue by using skb->dev instead of skb->protocol to distinguish between these 3 situations. For situation 1, skb->dev would be NULL; for situation 2, skb->dev->type would be ARPHRD_ETHER; and for situation 3, skb->dev->type would be ARPHRD_DLCI. This way fr_hard_header would be able to distinguish these 3 situations correctly regardless what skb->protocol value the user tries to use in situation 3. Cc: Krzysztof Halasa Signed-off-by: Xie He Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/wan/hdlc_fr.c | 98 ++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index d6cfd51613ed8..3a44dad87602d 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -273,63 +273,69 @@ static inline struct net_device **get_dev_p(struct pvc_device *pvc, static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) { - u16 head_len; struct sk_buff *skb = *skb_p; - switch (skb->protocol) { - case cpu_to_be16(NLPID_CCITT_ANSI_LMI): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_CCITT_ANSI_LMI; - break; - - case cpu_to_be16(NLPID_CISCO_LMI): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_CISCO_LMI; - break; - - case cpu_to_be16(ETH_P_IP): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_IP; - break; - - case cpu_to_be16(ETH_P_IPV6): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_IPV6; - break; - - case cpu_to_be16(ETH_P_802_3): - head_len = 10; - if (skb_headroom(skb) < head_len) { - struct sk_buff *skb2 = skb_realloc_headroom(skb, - head_len); + if (!skb->dev) { /* Control packets */ + switch (dlci) { + case LMI_CCITT_ANSI_DLCI: + skb_push(skb, 4); + skb->data[3] = NLPID_CCITT_ANSI_LMI; + break; + + case LMI_CISCO_DLCI: + skb_push(skb, 4); + skb->data[3] = NLPID_CISCO_LMI; + break; + + default: + return -EINVAL; + } + + } else if (skb->dev->type == ARPHRD_DLCI) { + switch (skb->protocol) { + case htons(ETH_P_IP): + skb_push(skb, 4); + skb->data[3] = NLPID_IP; + break; + + case htons(ETH_P_IPV6): + skb_push(skb, 4); + skb->data[3] = NLPID_IPV6; + break; + + default: + skb_push(skb, 10); + skb->data[3] = FR_PAD; + skb->data[4] = NLPID_SNAP; + /* OUI 00-00-00 indicates an Ethertype follows */ + skb->data[5] = 0x00; + skb->data[6] = 0x00; + skb->data[7] = 0x00; + /* This should be an Ethertype: */ + *(__be16 *)(skb->data + 8) = skb->protocol; + } + + } else if (skb->dev->type == ARPHRD_ETHER) { + if (skb_headroom(skb) < 10) { + struct sk_buff *skb2 = skb_realloc_headroom(skb, 10); if (!skb2) return -ENOBUFS; dev_kfree_skb(skb); skb = *skb_p = skb2; } - skb_push(skb, head_len); + skb_push(skb, 10); skb->data[3] = FR_PAD; skb->data[4] = NLPID_SNAP; - skb->data[5] = FR_PAD; + /* OUI 00-80-C2 stands for the 802.1 organization */ + skb->data[5] = 0x00; skb->data[6] = 0x80; skb->data[7] = 0xC2; + /* PID 00-07 stands for Ethernet frames without FCS */ skb->data[8] = 0x00; - skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */ - break; + skb->data[9] = 0x07; - default: - head_len = 10; - skb_push(skb, head_len); - skb->data[3] = FR_PAD; - skb->data[4] = NLPID_SNAP; - skb->data[5] = FR_PAD; - skb->data[6] = FR_PAD; - skb->data[7] = FR_PAD; - *(__be16*)(skb->data + 8) = skb->protocol; + } else { + return -EINVAL; } dlci_to_q922(skb->data, dlci); @@ -425,8 +431,8 @@ static netdev_tx_t pvc_xmit(struct sk_buff *skb, struct net_device *dev) skb_put(skb, pad); memset(skb->data + len, 0, pad); } - skb->protocol = cpu_to_be16(ETH_P_802_3); } + skb->dev = dev; if (!fr_hard_header(&skb, pvc->dlci)) { dev->stats.tx_bytes += skb->len; dev->stats.tx_packets++; @@ -494,10 +500,8 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) memset(skb->data, 0, len); skb_reserve(skb, 4); if (lmi == LMI_CISCO) { - skb->protocol = cpu_to_be16(NLPID_CISCO_LMI); fr_hard_header(&skb, LMI_CISCO_DLCI); } else { - skb->protocol = cpu_to_be16(NLPID_CCITT_ANSI_LMI); fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI); } data = skb_tail_pointer(skb); -- 2.27.0