Blame view

net/llc/llc_core.c 4.13 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  /*
   * llc_core.c - Minimum needed routines for sap handling and module init/exit
   *
   * Copyright (c) 1997 by Procom Technology, Inc.
   * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   *
   * This program can be redistributed or modified under the terms of the
   * GNU General Public License as published by the Free Software Foundation.
   * This program is distributed without any warranty or implied warranty
   * of merchantability or fitness for a particular purpose.
   *
   * See the GNU General Public License for more details.
   */
  
  #include <linux/module.h>
  #include <linux/interrupt.h>
  #include <linux/if_ether.h>
  #include <linux/netdevice.h>
  #include <linux/slab.h>
  #include <linux/string.h>
  #include <linux/init.h>
881d966b4   Eric W. Biederman   [NET]: Make the d...
22
  #include <net/net_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
  #include <net/llc.h>
  
  LIST_HEAD(llc_sap_list);
5e419e68a   stephen hemminger   llc: make lock st...
26
  static DEFINE_SPINLOCK(llc_sap_list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
30
31
32
33
34
  /**
   *	llc_sap_alloc - allocates and initializes sap.
   *
   *	Allocates and initializes sap.
   */
  static struct llc_sap *llc_sap_alloc(void)
  {
0da974f4f   Panagiotis Issaris   [NET]: Conversion...
35
  	struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC);
52d58aef5   Octavian Purdila   llc: replace the ...
36
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
  
  	if (sap) {
a5a04819c   Joonwoo Park   [LLC]: station so...
39
  		/* sap->laddr.mac - leave as a null, it's filled by bind */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
  		sap->state = LLC_SAP_STATE_ACTIVE;
b76f5a842   Octavian Purdila   llc: convert the ...
41
  		spin_lock_init(&sap->sk_lock);
52d58aef5   Octavian Purdila   llc: replace the ...
42
43
  		for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++)
  			INIT_HLIST_NULLS_HEAD(&sap->sk_laddr_hash[i], i);
6e2144b76   Arnaldo Carvalho de Melo   [LLC]: Use refcou...
44
  		atomic_set(&sap->refcnt, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
  	}
  	return sap;
  }
2928c19e1   Arnaldo Carvalho de Melo   [LLC]: Fix sparse...
48
  static struct llc_sap *__llc_sap_find(unsigned char sap_value)
6e2144b76   Arnaldo Carvalho de Melo   [LLC]: Use refcou...
49
  {
3cdba604d   Weilong Chen   llc: "foo* bar" s...
50
  	struct llc_sap *sap;
6e2144b76   Arnaldo Carvalho de Melo   [LLC]: Use refcou...
51
52
53
54
55
56
57
58
  
  	list_for_each_entry(sap, &llc_sap_list, node)
  		if (sap->laddr.lsap == sap_value)
  			goto out;
  	sap = NULL;
  out:
  	return sap;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
  /**
   *	llc_sap_find - searchs a SAP in station
   *	@sap_value: sap to be found
   *
   *	Searchs for a sap in the sap list of the LLC's station upon the sap ID.
6e2144b76   Arnaldo Carvalho de Melo   [LLC]: Use refcou...
64
65
   *	If the sap is found it will be refcounted and the user will have to do
   *	a llc_sap_put after use.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
   *	Returns the sap or %NULL if not found.
   */
  struct llc_sap *llc_sap_find(unsigned char sap_value)
  {
8beb9ab6c   Octavian Purdila   llc: convert llc_...
70
  	struct llc_sap *sap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

8beb9ab6c   Octavian Purdila   llc: convert llc_...
72
  	rcu_read_lock_bh();
6e2144b76   Arnaldo Carvalho de Melo   [LLC]: Use refcou...
73
74
75
  	sap = __llc_sap_find(sap_value);
  	if (sap)
  		llc_sap_hold(sap);
8beb9ab6c   Octavian Purdila   llc: convert llc_...
76
  	rcu_read_unlock_bh();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  	return sap;
  }
  
  /**
   *	llc_sap_open - open interface to the upper layers.
   *	@lsap: SAP number.
   *	@func: rcv func for datalink protos
   *
   *	Interface function to upper layer. Each one who wants to get a SAP
   *	(for example NetBEUI) should call this function. Returns the opened
   *	SAP for success, NULL for failure.
   */
  struct llc_sap *llc_sap_open(unsigned char lsap,
  			     int (*func)(struct sk_buff *skb,
  					 struct net_device *dev,
f2ccd8fa0   David S. Miller   [NET]: Kill skb->...
92
93
  					 struct packet_type *pt,
  					 struct net_device *orig_dev))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  {
6e2144b76   Arnaldo Carvalho de Melo   [LLC]: Use refcou...
95
  	struct llc_sap *sap = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96

8beb9ab6c   Octavian Purdila   llc: convert llc_...
97
  	spin_lock_bh(&llc_sap_list_lock);
6e2144b76   Arnaldo Carvalho de Melo   [LLC]: Use refcou...
98
  	if (__llc_sap_find(lsap)) /* SAP already exists */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
103
104
  	sap = llc_sap_alloc();
  	if (!sap)
  		goto out;
  	sap->laddr.lsap = lsap;
  	sap->rcv_func	= func;
8beb9ab6c   Octavian Purdila   llc: convert llc_...
105
  	list_add_tail_rcu(&sap->node, &llc_sap_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  out:
8beb9ab6c   Octavian Purdila   llc: convert llc_...
107
  	spin_unlock_bh(&llc_sap_list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  	return sap;
  }
  
  /**
   *	llc_sap_close - close interface for upper layers.
   *	@sap: SAP to be closed.
   *
   *	Close interface function to upper layer. Each one who wants to
   *	close an open SAP (for example NetBEUI) should call this function.
   * 	Removes this sap from the list of saps in the station and then
   * 	frees the memory for this sap.
   */
  void llc_sap_close(struct llc_sap *sap)
  {
52d58aef5   Octavian Purdila   llc: replace the ...
122
  	WARN_ON(sap->sk_count);
8beb9ab6c   Octavian Purdila   llc: convert llc_...
123
124
125
126
127
128
  
  	spin_lock_bh(&llc_sap_list_lock);
  	list_del_rcu(&sap->node);
  	spin_unlock_bh(&llc_sap_list_lock);
  
  	synchronize_rcu();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
  	kfree(sap);
  }
7546dd97d   Stephen Hemminger   net: convert usag...
131
  static struct packet_type llc_packet_type __read_mostly = {
09640e636   Harvey Harrison   net: replace uses...
132
  	.type = cpu_to_be16(ETH_P_802_2),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
  	.func = llc_rcv,
  };
7546dd97d   Stephen Hemminger   net: convert usag...
135
  static struct packet_type llc_tr_packet_type __read_mostly = {
09640e636   Harvey Harrison   net: replace uses...
136
  	.type = cpu_to_be16(ETH_P_TR_802_2),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
141
  	.func = llc_rcv,
  };
  
  static int __init llc_init(void)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
147
148
149
150
151
152
153
154
  	dev_add_pack(&llc_packet_type);
  	dev_add_pack(&llc_tr_packet_type);
  	return 0;
  }
  
  static void __exit llc_exit(void)
  {
  	dev_remove_pack(&llc_packet_type);
  	dev_remove_pack(&llc_tr_packet_type);
  }
  
  module_init(llc_init);
  module_exit(llc_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  EXPORT_SYMBOL(llc_sap_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
159
160
161
162
  EXPORT_SYMBOL(llc_sap_find);
  EXPORT_SYMBOL(llc_sap_open);
  EXPORT_SYMBOL(llc_sap_close);
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
  MODULE_DESCRIPTION("LLC IEEE 802.2 core support");