~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/llc/llc_core.c

Version: ~ [ linux-4.14 ] ~ [ linux-4.13.12 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.61 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.97 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.46 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.80 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.50 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.95 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.27.62 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * llc_core.c - Minimum needed routines for sap handling and module init/exit
  3  *
  4  * Copyright (c) 1997 by Procom Technology, Inc.
  5  *               2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  6  *
  7  * This program can be redistributed or modified under the terms of the
  8  * GNU General Public License as published by the Free Software Foundation.
  9  * This program is distributed without any warranty or implied warranty
 10  * of merchantability or fitness for a particular purpose.
 11  *
 12  * See the GNU General Public License for more details.
 13  */
 14 
 15 #include <linux/module.h>
 16 #include <linux/interrupt.h>
 17 #include <linux/if_ether.h>
 18 #include <linux/netdevice.h>
 19 #include <linux/slab.h>
 20 #include <linux/string.h>
 21 #include <linux/init.h>
 22 #include <net/net_namespace.h>
 23 #include <net/llc.h>
 24 
 25 LIST_HEAD(llc_sap_list);
 26 static DEFINE_SPINLOCK(llc_sap_list_lock);
 27 
 28 /**
 29  *      llc_sap_alloc - allocates and initializes sap.
 30  *
 31  *      Allocates and initializes sap.
 32  */
 33 static struct llc_sap *llc_sap_alloc(void)
 34 {
 35         struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC);
 36         int i;
 37 
 38         if (sap) {
 39                 /* sap->laddr.mac - leave as a null, it's filled by bind */
 40                 sap->state = LLC_SAP_STATE_ACTIVE;
 41                 spin_lock_init(&sap->sk_lock);
 42                 for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++)
 43                         INIT_HLIST_NULLS_HEAD(&sap->sk_laddr_hash[i], i);
 44                 refcount_set(&sap->refcnt, 1);
 45         }
 46         return sap;
 47 }
 48 
 49 static struct llc_sap *__llc_sap_find(unsigned char sap_value)
 50 {
 51         struct llc_sap *sap;
 52 
 53         list_for_each_entry(sap, &llc_sap_list, node)
 54                 if (sap->laddr.lsap == sap_value)
 55                         goto out;
 56         sap = NULL;
 57 out:
 58         return sap;
 59 }
 60 
 61 /**
 62  *      llc_sap_find - searchs a SAP in station
 63  *      @sap_value: sap to be found
 64  *
 65  *      Searchs for a sap in the sap list of the LLC's station upon the sap ID.
 66  *      If the sap is found it will be refcounted and the user will have to do
 67  *      a llc_sap_put after use.
 68  *      Returns the sap or %NULL if not found.
 69  */
 70 struct llc_sap *llc_sap_find(unsigned char sap_value)
 71 {
 72         struct llc_sap *sap;
 73 
 74         rcu_read_lock_bh();
 75         sap = __llc_sap_find(sap_value);
 76         if (sap)
 77                 llc_sap_hold(sap);
 78         rcu_read_unlock_bh();
 79         return sap;
 80 }
 81 
 82 /**
 83  *      llc_sap_open - open interface to the upper layers.
 84  *      @lsap: SAP number.
 85  *      @func: rcv func for datalink protos
 86  *
 87  *      Interface function to upper layer. Each one who wants to get a SAP
 88  *      (for example NetBEUI) should call this function. Returns the opened
 89  *      SAP for success, NULL for failure.
 90  */
 91 struct llc_sap *llc_sap_open(unsigned char lsap,
 92                              int (*func)(struct sk_buff *skb,
 93                                          struct net_device *dev,
 94                                          struct packet_type *pt,
 95                                          struct net_device *orig_dev))
 96 {
 97         struct llc_sap *sap = NULL;
 98 
 99         spin_lock_bh(&llc_sap_list_lock);
100         if (__llc_sap_find(lsap)) /* SAP already exists */
101                 goto out;
102         sap = llc_sap_alloc();
103         if (!sap)
104                 goto out;
105         sap->laddr.lsap = lsap;
106         sap->rcv_func   = func;
107         list_add_tail_rcu(&sap->node, &llc_sap_list);
108 out:
109         spin_unlock_bh(&llc_sap_list_lock);
110         return sap;
111 }
112 
113 /**
114  *      llc_sap_close - close interface for upper layers.
115  *      @sap: SAP to be closed.
116  *
117  *      Close interface function to upper layer. Each one who wants to
118  *      close an open SAP (for example NetBEUI) should call this function.
119  *      Removes this sap from the list of saps in the station and then
120  *      frees the memory for this sap.
121  */
122 void llc_sap_close(struct llc_sap *sap)
123 {
124         WARN_ON(sap->sk_count);
125 
126         spin_lock_bh(&llc_sap_list_lock);
127         list_del_rcu(&sap->node);
128         spin_unlock_bh(&llc_sap_list_lock);
129 
130         synchronize_rcu();
131 
132         kfree(sap);
133 }
134 
135 static struct packet_type llc_packet_type __read_mostly = {
136         .type = cpu_to_be16(ETH_P_802_2),
137         .func = llc_rcv,
138 };
139 
140 static struct packet_type llc_tr_packet_type __read_mostly = {
141         .type = cpu_to_be16(ETH_P_TR_802_2),
142         .func = llc_rcv,
143 };
144 
145 static int __init llc_init(void)
146 {
147         dev_add_pack(&llc_packet_type);
148         dev_add_pack(&llc_tr_packet_type);
149         return 0;
150 }
151 
152 static void __exit llc_exit(void)
153 {
154         dev_remove_pack(&llc_packet_type);
155         dev_remove_pack(&llc_tr_packet_type);
156 }
157 
158 module_init(llc_init);
159 module_exit(llc_exit);
160 
161 EXPORT_SYMBOL(llc_sap_list);
162 EXPORT_SYMBOL(llc_sap_find);
163 EXPORT_SYMBOL(llc_sap_open);
164 EXPORT_SYMBOL(llc_sap_close);
165 
166 MODULE_LICENSE("GPL");
167 MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
168 MODULE_DESCRIPTION("LLC IEEE 802.2 core support");
169 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp