Blame view
net/ax25/ax25_iface.c
4.92 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 |
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) */ |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 |
#include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/kernel.h> |
70868eace [AX.25]: Move AX.... |
14 |
#include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 17 18 19 |
#include <linux/spinlock.h> #include <linux/timer.h> #include <linux/string.h> #include <linux/sockios.h> #include <linux/net.h> |
5a0e3ad6a include cleanup: ... |
20 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 24 25 26 |
#include <net/ax25.h> #include <linux/inet.h> #include <linux/netdevice.h> #include <linux/skbuff.h> #include <net/sock.h> #include <asm/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 |
#include <linux/fcntl.h> #include <linux/mm.h> #include <linux/interrupt.h> |
8d5cf596d [AX.25]: Fix unch... |
30 |
static struct ax25_protocol *protocol_list; |
1da177e4c Linux-2.6.12-rc2 |
31 |
static DEFINE_RWLOCK(protocol_list_lock); |
a4282717c [AX.25]: Fix unch... |
32 |
static HLIST_HEAD(ax25_linkfail_list); |
1da177e4c Linux-2.6.12-rc2 |
33 34 35 36 37 38 39 40 |
static DEFINE_SPINLOCK(linkfail_lock); static struct listen_struct { struct listen_struct *next; ax25_address callsign; struct net_device *dev; } *listen_list = NULL; static DEFINE_SPINLOCK(listen_lock); |
8d5cf596d [AX.25]: Fix unch... |
41 42 43 44 45 |
/* * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT, * AX25_P_IP or AX25_P_ARP ... */ void ax25_register_pid(struct ax25_protocol *ap) |
1da177e4c Linux-2.6.12-rc2 |
46 |
{ |
95ff9f4d3 [AX.25]: Fix lock... |
47 |
write_lock_bh(&protocol_list_lock); |
8d5cf596d [AX.25]: Fix unch... |
48 49 |
ap->next = protocol_list; protocol_list = ap; |
95ff9f4d3 [AX.25]: Fix lock... |
50 |
write_unlock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
51 |
} |
8d5cf596d [AX.25]: Fix unch... |
52 |
EXPORT_SYMBOL_GPL(ax25_register_pid); |
70868eace [AX.25]: Move AX.... |
53 |
|
1da177e4c Linux-2.6.12-rc2 |
54 55 |
void ax25_protocol_release(unsigned int pid) { |
d8f969e60 ax25: Fix set-but... |
56 |
struct ax25_protocol *protocol; |
1da177e4c Linux-2.6.12-rc2 |
57 |
|
95ff9f4d3 [AX.25]: Fix lock... |
58 |
write_lock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
59 |
protocol = protocol_list; |
910d30b70 ax25: more common... |
60 61 |
if (protocol == NULL) goto out; |
1da177e4c Linux-2.6.12-rc2 |
62 63 64 |
if (protocol->pid == pid) { protocol_list = protocol->next; |
910d30b70 ax25: more common... |
65 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
66 67 68 69 |
} while (protocol != NULL && protocol->next != NULL) { if (protocol->next->pid == pid) { |
1da177e4c Linux-2.6.12-rc2 |
70 |
protocol->next = protocol->next->next; |
910d30b70 ax25: more common... |
71 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
72 73 74 75 |
} protocol = protocol->next; } |
910d30b70 ax25: more common... |
76 |
out: |
95ff9f4d3 [AX.25]: Fix lock... |
77 |
write_unlock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
78 |
} |
70868eace [AX.25]: Move AX.... |
79 |
EXPORT_SYMBOL(ax25_protocol_release); |
a4282717c [AX.25]: Fix unch... |
80 |
void ax25_linkfail_register(struct ax25_linkfail *lf) |
1da177e4c Linux-2.6.12-rc2 |
81 |
{ |
1da177e4c Linux-2.6.12-rc2 |
82 |
spin_lock_bh(&linkfail_lock); |
a4282717c [AX.25]: Fix unch... |
83 |
hlist_add_head(&lf->lf_node, &ax25_linkfail_list); |
1da177e4c Linux-2.6.12-rc2 |
84 |
spin_unlock_bh(&linkfail_lock); |
1da177e4c Linux-2.6.12-rc2 |
85 |
} |
70868eace [AX.25]: Move AX.... |
86 |
EXPORT_SYMBOL(ax25_linkfail_register); |
a4282717c [AX.25]: Fix unch... |
87 |
void ax25_linkfail_release(struct ax25_linkfail *lf) |
1da177e4c Linux-2.6.12-rc2 |
88 |
{ |
1da177e4c Linux-2.6.12-rc2 |
89 |
spin_lock_bh(&linkfail_lock); |
a4282717c [AX.25]: Fix unch... |
90 |
hlist_del_init(&lf->lf_node); |
1da177e4c Linux-2.6.12-rc2 |
91 92 |
spin_unlock_bh(&linkfail_lock); } |
70868eace [AX.25]: Move AX.... |
93 |
EXPORT_SYMBOL(ax25_linkfail_release); |
1da177e4c Linux-2.6.12-rc2 |
94 95 96 97 98 99 100 101 |
int ax25_listen_register(ax25_address *callsign, struct net_device *dev) { struct listen_struct *listen; if (ax25_listen_mine(callsign, dev)) return 0; if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) |
81dcd1690 [AX.25]: Fix unch... |
102 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 106 107 108 109 110 |
listen->callsign = *callsign; listen->dev = dev; spin_lock_bh(&listen_lock); listen->next = listen_list; listen_list = listen; spin_unlock_bh(&listen_lock); |
81dcd1690 [AX.25]: Fix unch... |
111 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
112 |
} |
70868eace [AX.25]: Move AX.... |
113 |
EXPORT_SYMBOL(ax25_listen_register); |
1da177e4c Linux-2.6.12-rc2 |
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
void ax25_listen_release(ax25_address *callsign, struct net_device *dev) { struct listen_struct *s, *listen; spin_lock_bh(&listen_lock); listen = listen_list; if (listen == NULL) { spin_unlock_bh(&listen_lock); return; } if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) { listen_list = listen->next; spin_unlock_bh(&listen_lock); kfree(listen); return; } while (listen != NULL && listen->next != NULL) { if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) { s = listen->next; listen->next = listen->next->next; spin_unlock_bh(&listen_lock); kfree(s); return; } listen = listen->next; } spin_unlock_bh(&listen_lock); } |
70868eace [AX.25]: Move AX.... |
145 |
EXPORT_SYMBOL(ax25_listen_release); |
1da177e4c Linux-2.6.12-rc2 |
146 147 148 |
int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) { int (*res)(struct sk_buff *, ax25_cb *) = NULL; |
8d5cf596d [AX.25]: Fix unch... |
149 |
struct ax25_protocol *protocol; |
1da177e4c Linux-2.6.12-rc2 |
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
read_lock(&protocol_list_lock); for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) if (protocol->pid == pid) { res = protocol->func; break; } read_unlock(&protocol_list_lock); return res; } int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) { struct listen_struct *listen; spin_lock_bh(&listen_lock); for (listen = listen_list; listen != NULL; listen = listen->next) |
81dcd1690 [AX.25]: Fix unch... |
168 169 |
if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) { |
1da177e4c Linux-2.6.12-rc2 |
170 171 172 173 174 175 176 177 178 179 |
spin_unlock_bh(&listen_lock); return 1; } spin_unlock_bh(&listen_lock); return 0; } void ax25_link_failed(ax25_cb *ax25, int reason) { |
a4282717c [AX.25]: Fix unch... |
180 181 |
struct ax25_linkfail *lf; struct hlist_node *node; |
1da177e4c Linux-2.6.12-rc2 |
182 183 |
spin_lock_bh(&linkfail_lock); |
a4282717c [AX.25]: Fix unch... |
184 185 |
hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) lf->func(ax25, reason); |
1da177e4c Linux-2.6.12-rc2 |
186 187 188 189 190 |
spin_unlock_bh(&linkfail_lock); } int ax25_protocol_is_registered(unsigned int pid) { |
8d5cf596d [AX.25]: Fix unch... |
191 |
struct ax25_protocol *protocol; |
1da177e4c Linux-2.6.12-rc2 |
192 |
int res = 0; |
95ff9f4d3 [AX.25]: Fix lock... |
193 |
read_lock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
194 195 196 197 198 |
for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) if (protocol->pid == pid) { res = 1; break; } |
95ff9f4d3 [AX.25]: Fix lock... |
199 |
read_unlock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
200 201 202 |
return res; } |