This source file includes following definitions.
- llc_sap_alloc
- __llc_sap_find
- llc_sap_find
- llc_sap_open
- llc_sap_close
- llc_init
- llc_exit
1
2
3
4
5
6
7
8
9
10
11
12
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
30
31
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
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
63
64
65
66
67
68
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 || !llc_sap_hold_safe(sap))
77 sap = NULL;
78 rcu_read_unlock_bh();
79 return sap;
80 }
81
82
83
84
85
86
87
88
89
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))
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
115
116
117
118
119
120
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 kfree_rcu(sap, rcu);
131 }
132
133 static struct packet_type llc_packet_type __read_mostly = {
134 .type = cpu_to_be16(ETH_P_802_2),
135 .func = llc_rcv,
136 };
137
138 static struct packet_type llc_tr_packet_type __read_mostly = {
139 .type = cpu_to_be16(ETH_P_TR_802_2),
140 .func = llc_rcv,
141 };
142
143 static int __init llc_init(void)
144 {
145 dev_add_pack(&llc_packet_type);
146 dev_add_pack(&llc_tr_packet_type);
147 return 0;
148 }
149
150 static void __exit llc_exit(void)
151 {
152 dev_remove_pack(&llc_packet_type);
153 dev_remove_pack(&llc_tr_packet_type);
154 }
155
156 module_init(llc_init);
157 module_exit(llc_exit);
158
159 EXPORT_SYMBOL(llc_sap_list);
160 EXPORT_SYMBOL(llc_sap_find);
161 EXPORT_SYMBOL(llc_sap_open);
162 EXPORT_SYMBOL(llc_sap_close);
163
164 MODULE_LICENSE("GPL");
165 MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
166 MODULE_DESCRIPTION("LLC IEEE 802.2 core support");