Blame view
net/ax25/ax25_iface.c
4.95 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 27 28 29 30 |
#include <net/ax25.h> #include <linux/inet.h> #include <linux/netdevice.h> #include <linux/skbuff.h> #include <net/sock.h> #include <asm/uaccess.h> #include <asm/system.h> #include <linux/fcntl.h> #include <linux/mm.h> #include <linux/interrupt.h> |
8d5cf596d [AX.25]: Fix unch... |
31 |
static struct ax25_protocol *protocol_list; |
1da177e4c Linux-2.6.12-rc2 |
32 |
static DEFINE_RWLOCK(protocol_list_lock); |
a4282717c [AX.25]: Fix unch... |
33 |
static HLIST_HEAD(ax25_linkfail_list); |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 38 39 40 41 |
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... |
42 43 44 45 46 |
/* * 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 |
47 |
{ |
95ff9f4d3 [AX.25]: Fix lock... |
48 |
write_lock_bh(&protocol_list_lock); |
8d5cf596d [AX.25]: Fix unch... |
49 50 |
ap->next = protocol_list; protocol_list = ap; |
95ff9f4d3 [AX.25]: Fix lock... |
51 |
write_unlock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
52 |
} |
8d5cf596d [AX.25]: Fix unch... |
53 |
EXPORT_SYMBOL_GPL(ax25_register_pid); |
70868eace [AX.25]: Move AX.... |
54 |
|
1da177e4c Linux-2.6.12-rc2 |
55 56 |
void ax25_protocol_release(unsigned int pid) { |
d8f969e60 ax25: Fix set-but... |
57 |
struct ax25_protocol *protocol; |
1da177e4c Linux-2.6.12-rc2 |
58 |
|
95ff9f4d3 [AX.25]: Fix lock... |
59 |
write_lock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
60 |
protocol = protocol_list; |
910d30b70 ax25: more common... |
61 62 |
if (protocol == NULL) goto out; |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 |
if (protocol->pid == pid) { protocol_list = protocol->next; |
910d30b70 ax25: more common... |
66 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
67 68 69 70 |
} while (protocol != NULL && protocol->next != NULL) { if (protocol->next->pid == pid) { |
1da177e4c Linux-2.6.12-rc2 |
71 |
protocol->next = protocol->next->next; |
910d30b70 ax25: more common... |
72 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
73 74 75 76 |
} protocol = protocol->next; } |
910d30b70 ax25: more common... |
77 |
out: |
95ff9f4d3 [AX.25]: Fix lock... |
78 |
write_unlock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
79 |
} |
70868eace [AX.25]: Move AX.... |
80 |
EXPORT_SYMBOL(ax25_protocol_release); |
a4282717c [AX.25]: Fix unch... |
81 |
void ax25_linkfail_register(struct ax25_linkfail *lf) |
1da177e4c Linux-2.6.12-rc2 |
82 |
{ |
1da177e4c Linux-2.6.12-rc2 |
83 |
spin_lock_bh(&linkfail_lock); |
a4282717c [AX.25]: Fix unch... |
84 |
hlist_add_head(&lf->lf_node, &ax25_linkfail_list); |
1da177e4c Linux-2.6.12-rc2 |
85 |
spin_unlock_bh(&linkfail_lock); |
1da177e4c Linux-2.6.12-rc2 |
86 |
} |
70868eace [AX.25]: Move AX.... |
87 |
EXPORT_SYMBOL(ax25_linkfail_register); |
a4282717c [AX.25]: Fix unch... |
88 |
void ax25_linkfail_release(struct ax25_linkfail *lf) |
1da177e4c Linux-2.6.12-rc2 |
89 |
{ |
1da177e4c Linux-2.6.12-rc2 |
90 |
spin_lock_bh(&linkfail_lock); |
a4282717c [AX.25]: Fix unch... |
91 |
hlist_del_init(&lf->lf_node); |
1da177e4c Linux-2.6.12-rc2 |
92 93 |
spin_unlock_bh(&linkfail_lock); } |
70868eace [AX.25]: Move AX.... |
94 |
EXPORT_SYMBOL(ax25_linkfail_release); |
1da177e4c Linux-2.6.12-rc2 |
95 96 97 98 99 100 101 102 |
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... |
103 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
104 105 106 107 108 109 110 111 |
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... |
112 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
113 |
} |
70868eace [AX.25]: Move AX.... |
114 |
EXPORT_SYMBOL(ax25_listen_register); |
1da177e4c Linux-2.6.12-rc2 |
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 145 |
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.... |
146 |
EXPORT_SYMBOL(ax25_listen_release); |
1da177e4c Linux-2.6.12-rc2 |
147 148 149 |
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... |
150 |
struct ax25_protocol *protocol; |
1da177e4c Linux-2.6.12-rc2 |
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
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... |
169 170 |
if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) { |
1da177e4c Linux-2.6.12-rc2 |
171 172 173 174 175 176 177 178 179 180 |
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... |
181 182 |
struct ax25_linkfail *lf; struct hlist_node *node; |
1da177e4c Linux-2.6.12-rc2 |
183 184 |
spin_lock_bh(&linkfail_lock); |
a4282717c [AX.25]: Fix unch... |
185 186 |
hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) lf->func(ax25, reason); |
1da177e4c Linux-2.6.12-rc2 |
187 188 189 190 191 |
spin_unlock_bh(&linkfail_lock); } int ax25_protocol_is_registered(unsigned int pid) { |
8d5cf596d [AX.25]: Fix unch... |
192 |
struct ax25_protocol *protocol; |
1da177e4c Linux-2.6.12-rc2 |
193 |
int res = 0; |
95ff9f4d3 [AX.25]: Fix lock... |
194 |
read_lock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
195 196 197 198 199 |
for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) if (protocol->pid == pid) { res = 1; break; } |
95ff9f4d3 [AX.25]: Fix lock... |
200 |
read_unlock_bh(&protocol_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
201 202 203 |
return res; } |