Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * llc_input.c - Minimal input path for LLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 1997 by Procom Technology, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This program can be redistributed or modified under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * GNU General Public License as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * This program is distributed without any warranty or implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * of merchantability or fitness for a particular purpose.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * See the GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <net/llc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <net/llc_pdu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <net/llc_sap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define dprintk(args...) printk(KERN_DEBUG args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define dprintk(args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * Packet handler for the station, registerable because in the minimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * LLC core that is taking shape only the very minimal subset of LLC that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * is needed for things like IPX, Appletalk, etc will stay, with all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * rest in the llc1 and llc2 modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static void (*llc_station_handler)(struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * Packet handlers for LLC_DEST_SAP and LLC_DEST_CONN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static void (*llc_type_handlers[2])(struct llc_sap *sap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 				    struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 					    struct sk_buff *skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	smp_wmb(); /* ensure initialisation is complete before it's called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		llc_type_handlers[type - 1] = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) void llc_remove_pack(int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		llc_type_handlers[type - 1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	/* Ensure initialisation is complete before it's called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	llc_station_handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (!handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *	llc_pdu_type - returns which LLC component must handle for PDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *	@skb: input skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *	This function returns which LLC component must handle this PDU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static __inline__ int llc_pdu_type(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	int type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	switch (LLC_U_PDU_CMD(pdu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	case LLC_1_PDU_CMD_XID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	case LLC_1_PDU_CMD_UI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	case LLC_1_PDU_CMD_TEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		type = LLC_DEST_SAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	case LLC_2_PDU_CMD_SABME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	case LLC_2_PDU_CMD_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	case LLC_2_PDU_RSP_UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	case LLC_2_PDU_RSP_DM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	case LLC_2_PDU_RSP_FRMR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		type = LLC_DEST_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *	llc_fixup_skb - initializes skb pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  *	@skb: This argument points to incoming skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  *	Initializes internal skb pointer to start of network layer by deriving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  *	length of LLC header; finds length of LLC control field in LLC header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  *	by looking at the two lowest-order bits of the first control field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  *	byte; field is either 3 or 4 bytes long.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline int llc_fixup_skb(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	u8 llc_len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	struct llc_pdu_un *pdu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (unlikely(!pskb_may_pull(skb, sizeof(*pdu))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	pdu = (struct llc_pdu_un *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		llc_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	llc_len += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (unlikely(!pskb_may_pull(skb, llc_len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	skb->transport_header += llc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	skb_pull(skb, llc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (skb->protocol == htons(ETH_P_802_2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		__be16 pdulen = eth_hdr(skb)->h_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		s32 data_size = ntohs(pdulen) - llc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		if (data_size < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		    !pskb_may_pull(skb, data_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		if (unlikely(pskb_trim_rcsum(skb, data_size)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  *	llc_rcv - 802.2 entry point from net lower layers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *	@skb: received pdu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  *	@dev: device that receive pdu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *	@pt: packet type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  *	@orig_dev: the original receive net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *	When the system receives a 802.2 frame this function is called. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *	checks SAP and connection of received pdu and passes frame to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  *	llc_{station,sap,conn}_rcv for sending to proper state machine. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  *	the frame is related to a busy connection (a connection is sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  *	data now), it queues this frame in the connection's backlog.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int llc_rcv(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	    struct packet_type *pt, struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	struct llc_sap *sap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	struct llc_pdu_sn *pdu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	int dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	int (*rcv)(struct sk_buff *, struct net_device *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		   struct packet_type *, struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	void (*sta_handler)(struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 * When the interface is in promisc. mode, drop all the crap that it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	 * receives, do not try to analyse it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	if (unlikely(skb->pkt_type == PACKET_OTHERHOST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		dprintk("%s: PACKET_OTHERHOST\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	skb = skb_share_check(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if (unlikely(!skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (unlikely(!llc_fixup_skb(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	pdu = llc_pdu_sn_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (unlikely(!pdu->dsap)) /* NULL DSAP, refer to station */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	       goto handle_station;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	sap = llc_sap_find(pdu->dsap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (unlikely(!sap)) {/* unknown SAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		dprintk("%s: llc_sap_find(%02X) failed!\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			pdu->dsap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	 * First the upper layer protocols that don't need the full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	 * LLC functionality
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	rcv = rcu_dereference(sap->rcv_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	dest = llc_pdu_type(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	sap_handler = dest ? READ_ONCE(llc_type_handlers[dest - 1]) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (unlikely(!sap_handler)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		if (rcv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			rcv(skb, dev, pt, orig_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		if (rcv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			if (cskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				rcv(cskb, dev, pt, orig_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		sap_handler(sap, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	llc_sap_put(sap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) handle_station:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	sta_handler = READ_ONCE(llc_station_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (!sta_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	sta_handler(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) EXPORT_SYMBOL(llc_add_pack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) EXPORT_SYMBOL(llc_remove_pack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) EXPORT_SYMBOL(llc_set_station_handler);