1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * llc_core.c - Minimum needed routines for sap handling and module init/exit 4 * 5 * Copyright (c) 1997 by Procom Technology, Inc. 6 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/if_ether.h> 11 #include <linux/netdevice.h> 12 #include <linux/slab.h> 13 #include <linux/init.h> 14 #include <net/llc.h> 15 16 static LIST_HEAD(llc_sap_list); 17 static DEFINE_SPINLOCK(llc_sap_list_lock); 18 19 /** 20 * llc_sap_alloc - allocates and initializes sap. 21 * 22 * Allocates and initializes sap. 23 */ 24 static struct llc_sap *llc_sap_alloc(void) 25 { 26 struct llc_sap *sap = kzalloc_obj(*sap, GFP_ATOMIC); 27 28 if (sap) 29 refcount_set(&sap->refcnt, 1); 30 return sap; 31 } 32 33 static struct llc_sap *__llc_sap_find(unsigned char sap_value) 34 { 35 struct llc_sap *sap; 36 37 list_for_each_entry(sap, &llc_sap_list, node) 38 if (sap->lsap == sap_value) 39 goto out; 40 sap = NULL; 41 out: 42 return sap; 43 } 44 45 /** 46 * llc_sap_find - searches for a SAP by its number 47 * @sap_value: sap to be found 48 * 49 * If the sap is found it will be refcounted and the user will have to do 50 * a llc_sap_put after use. 51 * Returns the sap or %NULL if not found. 52 */ 53 struct llc_sap *llc_sap_find(unsigned char sap_value) 54 { 55 struct llc_sap *sap; 56 57 rcu_read_lock_bh(); 58 sap = __llc_sap_find(sap_value); 59 if (!sap || !llc_sap_hold_safe(sap)) 60 sap = NULL; 61 rcu_read_unlock_bh(); 62 return sap; 63 } 64 65 /** 66 * llc_sap_open - open interface to the upper layers. 67 * @lsap: SAP number. 68 * @func: rcv func for datalink protos 69 * 70 * Interface function to upper layer. Each one who wants to get a SAP 71 * (for example NetBEUI) should call this function. Returns the opened 72 * SAP for success, NULL for failure. 73 */ 74 struct llc_sap *llc_sap_open(unsigned char lsap, 75 int (*func)(struct sk_buff *skb, 76 struct net_device *dev, 77 struct packet_type *pt, 78 struct net_device *orig_dev)) 79 { 80 struct llc_sap *sap = NULL; 81 82 spin_lock_bh(&llc_sap_list_lock); 83 if (__llc_sap_find(lsap)) /* SAP already exists */ 84 goto out; 85 sap = llc_sap_alloc(); 86 if (!sap) 87 goto out; 88 sap->lsap = lsap; 89 sap->rcv_func = func; 90 list_add_tail_rcu(&sap->node, &llc_sap_list); 91 out: 92 spin_unlock_bh(&llc_sap_list_lock); 93 return sap; 94 } 95 96 /** 97 * llc_sap_close - close interface for upper layers. 98 * @sap: SAP to be closed. 99 * 100 * Close interface function to upper layer. Each one who wants to 101 * close an open SAP (for example NetBEUI) should call this function. 102 * Removes this sap from the SAP list and then frees the memory for it. 103 */ 104 void llc_sap_close(struct llc_sap *sap) 105 { 106 spin_lock_bh(&llc_sap_list_lock); 107 list_del_rcu(&sap->node); 108 spin_unlock_bh(&llc_sap_list_lock); 109 110 kfree_rcu(sap, rcu); 111 } 112 113 static struct packet_type llc_packet_type __read_mostly = { 114 .type = cpu_to_be16(ETH_P_802_2), 115 .func = llc_rcv, 116 }; 117 118 static int __init llc_init(void) 119 { 120 dev_add_pack(&llc_packet_type); 121 return 0; 122 } 123 124 static void __exit llc_exit(void) 125 { 126 dev_remove_pack(&llc_packet_type); 127 } 128 129 module_init(llc_init); 130 module_exit(llc_exit); 131 132 EXPORT_SYMBOL(llc_sap_open); 133 EXPORT_SYMBOL(llc_sap_close); 134 135 MODULE_LICENSE("GPL"); 136 MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003"); 137 MODULE_DESCRIPTION("LLC IEEE 802.2 core support"); 138