diff options
Diffstat (limited to 'net/ax25/ax25_iface.c')
-rw-r--r-- | net/ax25/ax25_iface.c | 103 |
1 files changed, 25 insertions, 78 deletions
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c index 07ac0207eb69..aff3e652c2d1 100644 --- a/net/ax25/ax25_iface.c +++ b/net/ax25/ax25_iface.c | |||
@@ -29,17 +29,10 @@ | |||
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | 31 | ||
32 | static struct protocol_struct { | 32 | static struct ax25_protocol *protocol_list; |
33 | struct protocol_struct *next; | ||
34 | unsigned int pid; | ||
35 | int (*func)(struct sk_buff *, ax25_cb *); | ||
36 | } *protocol_list = NULL; | ||
37 | static DEFINE_RWLOCK(protocol_list_lock); | 33 | static DEFINE_RWLOCK(protocol_list_lock); |
38 | 34 | ||
39 | static struct linkfail_struct { | 35 | static HLIST_HEAD(ax25_linkfail_list); |
40 | struct linkfail_struct *next; | ||
41 | void (*func)(ax25_cb *, int); | ||
42 | } *linkfail_list = NULL; | ||
43 | static DEFINE_SPINLOCK(linkfail_lock); | 36 | static DEFINE_SPINLOCK(linkfail_lock); |
44 | 37 | ||
45 | static struct listen_struct { | 38 | static struct listen_struct { |
@@ -49,36 +42,23 @@ static struct listen_struct { | |||
49 | } *listen_list = NULL; | 42 | } *listen_list = NULL; |
50 | static DEFINE_SPINLOCK(listen_lock); | 43 | static DEFINE_SPINLOCK(listen_lock); |
51 | 44 | ||
52 | int ax25_protocol_register(unsigned int pid, | 45 | /* |
53 | int (*func)(struct sk_buff *, ax25_cb *)) | 46 | * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT, |
47 | * AX25_P_IP or AX25_P_ARP ... | ||
48 | */ | ||
49 | void ax25_register_pid(struct ax25_protocol *ap) | ||
54 | { | 50 | { |
55 | struct protocol_struct *protocol; | ||
56 | |||
57 | if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT) | ||
58 | return 0; | ||
59 | #ifdef CONFIG_INET | ||
60 | if (pid == AX25_P_IP || pid == AX25_P_ARP) | ||
61 | return 0; | ||
62 | #endif | ||
63 | if ((protocol = kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL) | ||
64 | return 0; | ||
65 | |||
66 | protocol->pid = pid; | ||
67 | protocol->func = func; | ||
68 | |||
69 | write_lock_bh(&protocol_list_lock); | 51 | write_lock_bh(&protocol_list_lock); |
70 | protocol->next = protocol_list; | 52 | ap->next = protocol_list; |
71 | protocol_list = protocol; | 53 | protocol_list = ap; |
72 | write_unlock_bh(&protocol_list_lock); | 54 | write_unlock_bh(&protocol_list_lock); |
73 | |||
74 | return 1; | ||
75 | } | 55 | } |
76 | 56 | ||
77 | EXPORT_SYMBOL(ax25_protocol_register); | 57 | EXPORT_SYMBOL_GPL(ax25_register_pid); |
78 | 58 | ||
79 | void ax25_protocol_release(unsigned int pid) | 59 | void ax25_protocol_release(unsigned int pid) |
80 | { | 60 | { |
81 | struct protocol_struct *s, *protocol; | 61 | struct ax25_protocol *s, *protocol; |
82 | 62 | ||
83 | write_lock_bh(&protocol_list_lock); | 63 | write_lock_bh(&protocol_list_lock); |
84 | protocol = protocol_list; | 64 | protocol = protocol_list; |
@@ -110,54 +90,19 @@ void ax25_protocol_release(unsigned int pid) | |||
110 | 90 | ||
111 | EXPORT_SYMBOL(ax25_protocol_release); | 91 | EXPORT_SYMBOL(ax25_protocol_release); |
112 | 92 | ||
113 | int ax25_linkfail_register(void (*func)(ax25_cb *, int)) | 93 | void ax25_linkfail_register(struct ax25_linkfail *lf) |
114 | { | 94 | { |
115 | struct linkfail_struct *linkfail; | ||
116 | |||
117 | if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL) | ||
118 | return 0; | ||
119 | |||
120 | linkfail->func = func; | ||
121 | |||
122 | spin_lock_bh(&linkfail_lock); | 95 | spin_lock_bh(&linkfail_lock); |
123 | linkfail->next = linkfail_list; | 96 | hlist_add_head(&lf->lf_node, &ax25_linkfail_list); |
124 | linkfail_list = linkfail; | ||
125 | spin_unlock_bh(&linkfail_lock); | 97 | spin_unlock_bh(&linkfail_lock); |
126 | |||
127 | return 1; | ||
128 | } | 98 | } |
129 | 99 | ||
130 | EXPORT_SYMBOL(ax25_linkfail_register); | 100 | EXPORT_SYMBOL(ax25_linkfail_register); |
131 | 101 | ||
132 | void ax25_linkfail_release(void (*func)(ax25_cb *, int)) | 102 | void ax25_linkfail_release(struct ax25_linkfail *lf) |
133 | { | 103 | { |
134 | struct linkfail_struct *s, *linkfail; | ||
135 | |||
136 | spin_lock_bh(&linkfail_lock); | 104 | spin_lock_bh(&linkfail_lock); |
137 | linkfail = linkfail_list; | 105 | hlist_del_init(&lf->lf_node); |
138 | if (linkfail == NULL) { | ||
139 | spin_unlock_bh(&linkfail_lock); | ||
140 | return; | ||
141 | } | ||
142 | |||
143 | if (linkfail->func == func) { | ||
144 | linkfail_list = linkfail->next; | ||
145 | spin_unlock_bh(&linkfail_lock); | ||
146 | kfree(linkfail); | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | while (linkfail != NULL && linkfail->next != NULL) { | ||
151 | if (linkfail->next->func == func) { | ||
152 | s = linkfail->next; | ||
153 | linkfail->next = linkfail->next->next; | ||
154 | spin_unlock_bh(&linkfail_lock); | ||
155 | kfree(s); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | linkfail = linkfail->next; | ||
160 | } | ||
161 | spin_unlock_bh(&linkfail_lock); | 106 | spin_unlock_bh(&linkfail_lock); |
162 | } | 107 | } |
163 | 108 | ||
@@ -171,7 +116,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev) | |||
171 | return 0; | 116 | return 0; |
172 | 117 | ||
173 | if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) | 118 | if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) |
174 | return 0; | 119 | return -ENOMEM; |
175 | 120 | ||
176 | listen->callsign = *callsign; | 121 | listen->callsign = *callsign; |
177 | listen->dev = dev; | 122 | listen->dev = dev; |
@@ -181,7 +126,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev) | |||
181 | listen_list = listen; | 126 | listen_list = listen; |
182 | spin_unlock_bh(&listen_lock); | 127 | spin_unlock_bh(&listen_lock); |
183 | 128 | ||
184 | return 1; | 129 | return 0; |
185 | } | 130 | } |
186 | 131 | ||
187 | EXPORT_SYMBOL(ax25_listen_register); | 132 | EXPORT_SYMBOL(ax25_listen_register); |
@@ -223,7 +168,7 @@ EXPORT_SYMBOL(ax25_listen_release); | |||
223 | int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) | 168 | int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) |
224 | { | 169 | { |
225 | int (*res)(struct sk_buff *, ax25_cb *) = NULL; | 170 | int (*res)(struct sk_buff *, ax25_cb *) = NULL; |
226 | struct protocol_struct *protocol; | 171 | struct ax25_protocol *protocol; |
227 | 172 | ||
228 | read_lock(&protocol_list_lock); | 173 | read_lock(&protocol_list_lock); |
229 | for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) | 174 | for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) |
@@ -242,7 +187,8 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) | |||
242 | 187 | ||
243 | spin_lock_bh(&listen_lock); | 188 | spin_lock_bh(&listen_lock); |
244 | for (listen = listen_list; listen != NULL; listen = listen->next) | 189 | for (listen = listen_list; listen != NULL; listen = listen->next) |
245 | if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) { | 190 | if (ax25cmp(&listen->callsign, callsign) == 0 && |
191 | (listen->dev == dev || listen->dev == NULL)) { | ||
246 | spin_unlock_bh(&listen_lock); | 192 | spin_unlock_bh(&listen_lock); |
247 | return 1; | 193 | return 1; |
248 | } | 194 | } |
@@ -253,17 +199,18 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) | |||
253 | 199 | ||
254 | void ax25_link_failed(ax25_cb *ax25, int reason) | 200 | void ax25_link_failed(ax25_cb *ax25, int reason) |
255 | { | 201 | { |
256 | struct linkfail_struct *linkfail; | 202 | struct ax25_linkfail *lf; |
203 | struct hlist_node *node; | ||
257 | 204 | ||
258 | spin_lock_bh(&linkfail_lock); | 205 | spin_lock_bh(&linkfail_lock); |
259 | for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) | 206 | hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) |
260 | (linkfail->func)(ax25, reason); | 207 | lf->func(ax25, reason); |
261 | spin_unlock_bh(&linkfail_lock); | 208 | spin_unlock_bh(&linkfail_lock); |
262 | } | 209 | } |
263 | 210 | ||
264 | int ax25_protocol_is_registered(unsigned int pid) | 211 | int ax25_protocol_is_registered(unsigned int pid) |
265 | { | 212 | { |
266 | struct protocol_struct *protocol; | 213 | struct ax25_protocol *protocol; |
267 | int res = 0; | 214 | int res = 0; |
268 | 215 | ||
269 | read_lock_bh(&protocol_list_lock); | 216 | read_lock_bh(&protocol_list_lock); |