1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * llc_input.c - Minimal input path for LLC 4 * 5 * Copyright (c) 1997 by Procom Technology, Inc. 6 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> 7 */ 8 #include <linux/netdevice.h> 9 #include <net/llc.h> 10 #include <net/llc_pdu.h> 11 12 #if 0 13 #define dprintk(args...) printk(KERN_DEBUG args) 14 #else 15 #define dprintk(args...) 16 #endif 17 18 /** 19 * llc_fixup_skb - initializes skb pointers 20 * @skb: This argument points to incoming skb 21 * 22 * Initializes internal skb pointer to start of network layer by deriving 23 * length of LLC header; finds length of LLC control field in LLC header 24 * by looking at the two lowest-order bits of the first control field 25 * byte; field is either 3 or 4 bytes long. 26 */ 27 static inline int llc_fixup_skb(struct sk_buff *skb) 28 { 29 u8 llc_len = 2; 30 struct llc_pdu_un *pdu; 31 32 if (unlikely(!pskb_may_pull(skb, sizeof(*pdu)))) 33 return 0; 34 35 pdu = (struct llc_pdu_un *)skb->data; 36 if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U) 37 llc_len = 1; 38 llc_len += 2; 39 40 if (unlikely(!pskb_may_pull(skb, llc_len))) 41 return 0; 42 43 skb_pull(skb, llc_len); 44 skb_reset_transport_header(skb); 45 if (skb->protocol == htons(ETH_P_802_2)) { 46 __be16 pdulen; 47 s32 data_size; 48 49 if (skb->mac_len < ETH_HLEN) 50 return 0; 51 52 pdulen = eth_hdr(skb)->h_proto; 53 data_size = ntohs(pdulen) - llc_len; 54 55 if (data_size < 0 || 56 !pskb_may_pull(skb, data_size)) 57 return 0; 58 if (unlikely(pskb_trim_rcsum(skb, data_size))) 59 return 0; 60 } 61 return 1; 62 } 63 64 /** 65 * llc_rcv - 802.2 entry point from net lower layers 66 * @skb: received pdu 67 * @dev: device that receive pdu 68 * @pt: packet type 69 * @orig_dev: the original receive net device 70 * 71 * When the system receives a 802.2 frame this function is called. It 72 * looks up the SAP the pdu is addressed to and passes the frame to its 73 * handler, dropping it if the SAP is unknown or has no handler. 74 */ 75 int llc_rcv(struct sk_buff *skb, struct net_device *dev, 76 struct packet_type *pt, struct net_device *orig_dev) 77 { 78 int (*rcv)(struct sk_buff *, struct net_device *, 79 struct packet_type *, struct net_device *); 80 struct llc_pdu_un *pdu; 81 struct llc_sap *sap; 82 83 /* 84 * When the interface is in promisc. mode, drop all the crap that it 85 * receives, do not try to analyse it. 86 */ 87 if (unlikely(skb->pkt_type == PACKET_OTHERHOST)) { 88 dprintk("%s: PACKET_OTHERHOST\n", __func__); 89 goto drop; 90 } 91 skb = skb_share_check(skb, GFP_ATOMIC); 92 if (unlikely(!skb)) 93 goto out; 94 if (unlikely(!llc_fixup_skb(skb))) 95 goto drop; 96 pdu = llc_pdu_un_hdr(skb); 97 sap = llc_sap_find(pdu->dsap); 98 if (unlikely(!sap)) {/* unknown SAP */ 99 dprintk("%s: llc_sap_find(%02X) failed!\n", __func__, 100 pdu->dsap); 101 goto drop; 102 } 103 rcv = rcu_dereference(sap->rcv_func); 104 if (likely(rcv)) 105 rcv(skb, dev, pt, orig_dev); 106 else 107 kfree_skb(skb); 108 llc_sap_put(sap); 109 out: 110 return 0; 111 drop: 112 kfree_skb(skb); 113 goto out; 114 } 115