aboutsummaryrefslogtreecommitdiffstats
path: root/net/ax25
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-01-17 18:34:51 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2007-01-17 18:34:51 -0500
commit9cdf083f981b8d37b3212400a359368661385099 (patch)
treeaa15a6a08ad87e650dea40fb59b3180bef0d345b /net/ax25
parente499e01d234a31d59679b7b1e1cf628d917ba49a (diff)
parenta8b3485287731978899ced11f24628c927890e78 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/ax25')
-rw-r--r--net/ax25/af_ax25.c10
-rw-r--r--net/ax25/ax25_addr.c36
-rw-r--r--net/ax25/ax25_iface.c103
-rw-r--r--net/ax25/ax25_out.c4
-rw-r--r--net/ax25/ax25_route.c7
-rw-r--r--net/ax25/sysctl_net_ax25.c5
6 files changed, 63 insertions, 102 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 000695c485..42233df2b0 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -906,13 +906,13 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
906 ax25->source_addr = oax25->source_addr; 906 ax25->source_addr = oax25->source_addr;
907 907
908 if (oax25->digipeat != NULL) { 908 if (oax25->digipeat != NULL) {
909 if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { 909 ax25->digipeat = kmemdup(oax25->digipeat, sizeof(ax25_digi),
910 GFP_ATOMIC);
911 if (ax25->digipeat == NULL) {
910 sk_free(sk); 912 sk_free(sk);
911 ax25_cb_put(ax25); 913 ax25_cb_put(ax25);
912 return NULL; 914 return NULL;
913 } 915 }
914
915 memcpy(ax25->digipeat, oax25->digipeat, sizeof(ax25_digi));
916 } 916 }
917 917
918 sk->sk_protinfo = ax25; 918 sk->sk_protinfo = ax25;
@@ -1088,8 +1088,8 @@ out:
1088/* 1088/*
1089 * FIXME: nonblock behaviour looks like it may have a bug. 1089 * FIXME: nonblock behaviour looks like it may have a bug.
1090 */ 1090 */
1091static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, 1091static int __must_check ax25_connect(struct socket *sock,
1092 int addr_len, int flags) 1092 struct sockaddr *uaddr, int addr_len, int flags)
1093{ 1093{
1094 struct sock *sk = sock->sk; 1094 struct sock *sk = sock->sk;
1095 ax25_cb *ax25 = ax25_sk(sk), *ax25t; 1095 ax25_cb *ax25 = ax25_sk(sk), *ax25t;
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index 5f0896ad00..97a49c79c6 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -29,17 +29,26 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30 30
31/* 31/*
32 * The null address is defined as a callsign of all spaces with an 32 * The default broadcast address of an interface is QST-0; the default address
33 * SSID of zero. 33 * is LINUX-1. The null address is defined as a callsign of all spaces with
34 * an SSID of zero.
34 */ 35 */
35ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}};
36 36
37const ax25_address ax25_bcast =
38 {{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}};
39const ax25_address ax25_defaddr =
40 {{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, 1 << 1}};
41const ax25_address null_ax25_address =
42 {{' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}};
43
44EXPORT_SYMBOL_GPL(ax25_bcast);
45EXPORT_SYMBOL_GPL(ax25_defaddr);
37EXPORT_SYMBOL(null_ax25_address); 46EXPORT_SYMBOL(null_ax25_address);
38 47
39/* 48/*
40 * ax25 -> ascii conversion 49 * ax25 -> ascii conversion
41 */ 50 */
42char *ax2asc(char *buf, ax25_address *a) 51char *ax2asc(char *buf, const ax25_address *a)
43{ 52{
44 char c, *s; 53 char c, *s;
45 int n; 54 int n;
@@ -72,9 +81,9 @@ EXPORT_SYMBOL(ax2asc);
72/* 81/*
73 * ascii -> ax25 conversion 82 * ascii -> ax25 conversion
74 */ 83 */
75void asc2ax(ax25_address *addr, char *callsign) 84void asc2ax(ax25_address *addr, const char *callsign)
76{ 85{
77 char *s; 86 const char *s;
78 int n; 87 int n;
79 88
80 for (s = callsign, n = 0; n < 6; n++) { 89 for (s = callsign, n = 0; n < 6; n++) {
@@ -107,7 +116,7 @@ EXPORT_SYMBOL(asc2ax);
107/* 116/*
108 * Compare two ax.25 addresses 117 * Compare two ax.25 addresses
109 */ 118 */
110int ax25cmp(ax25_address *a, ax25_address *b) 119int ax25cmp(const ax25_address *a, const ax25_address *b)
111{ 120{
112 int ct = 0; 121 int ct = 0;
113 122
@@ -128,7 +137,7 @@ EXPORT_SYMBOL(ax25cmp);
128/* 137/*
129 * Compare two AX.25 digipeater paths. 138 * Compare two AX.25 digipeater paths.
130 */ 139 */
131int ax25digicmp(ax25_digi *digi1, ax25_digi *digi2) 140int ax25digicmp(const ax25_digi *digi1, const ax25_digi *digi2)
132{ 141{
133 int i; 142 int i;
134 143
@@ -149,7 +158,9 @@ int ax25digicmp(ax25_digi *digi1, ax25_digi *digi2)
149 * Given an AX.25 address pull of to, from, digi list, command/response and the start of data 158 * Given an AX.25 address pull of to, from, digi list, command/response and the start of data
150 * 159 *
151 */ 160 */
152unsigned char *ax25_addr_parse(unsigned char *buf, int len, ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags, int *dama) 161const unsigned char *ax25_addr_parse(const unsigned char *buf, int len,
162 ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags,
163 int *dama)
153{ 164{
154 int d = 0; 165 int d = 0;
155 166
@@ -204,7 +215,8 @@ unsigned char *ax25_addr_parse(unsigned char *buf, int len, ax25_address *src, a
204/* 215/*
205 * Assemble an AX.25 header from the bits 216 * Assemble an AX.25 header from the bits
206 */ 217 */
207int ax25_addr_build(unsigned char *buf, ax25_address *src, ax25_address *dest, ax25_digi *d, int flag, int modulus) 218int ax25_addr_build(unsigned char *buf, const ax25_address *src,
219 const ax25_address *dest, const ax25_digi *d, int flag, int modulus)
208{ 220{
209 int len = 0; 221 int len = 0;
210 int ct = 0; 222 int ct = 0;
@@ -261,7 +273,7 @@ int ax25_addr_build(unsigned char *buf, ax25_address *src, ax25_address *dest, a
261 return len; 273 return len;
262} 274}
263 275
264int ax25_addr_size(ax25_digi *dp) 276int ax25_addr_size(const ax25_digi *dp)
265{ 277{
266 if (dp == NULL) 278 if (dp == NULL)
267 return 2 * AX25_ADDR_LEN; 279 return 2 * AX25_ADDR_LEN;
@@ -272,7 +284,7 @@ int ax25_addr_size(ax25_digi *dp)
272/* 284/*
273 * Reverse Digipeat List. May not pass both parameters as same struct 285 * Reverse Digipeat List. May not pass both parameters as same struct
274 */ 286 */
275void ax25_digi_invert(ax25_digi *in, ax25_digi *out) 287void ax25_digi_invert(const ax25_digi *in, ax25_digi *out)
276{ 288{
277 int ct; 289 int ct;
278 290
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 07ac0207eb..aff3e652c2 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
32static struct protocol_struct { 32static 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;
37static DEFINE_RWLOCK(protocol_list_lock); 33static DEFINE_RWLOCK(protocol_list_lock);
38 34
39static struct linkfail_struct { 35static HLIST_HEAD(ax25_linkfail_list);
40 struct linkfail_struct *next;
41 void (*func)(ax25_cb *, int);
42} *linkfail_list = NULL;
43static DEFINE_SPINLOCK(linkfail_lock); 36static DEFINE_SPINLOCK(linkfail_lock);
44 37
45static struct listen_struct { 38static struct listen_struct {
@@ -49,36 +42,23 @@ static struct listen_struct {
49} *listen_list = NULL; 42} *listen_list = NULL;
50static DEFINE_SPINLOCK(listen_lock); 43static DEFINE_SPINLOCK(listen_lock);
51 44
52int 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 */
49void 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
77EXPORT_SYMBOL(ax25_protocol_register); 57EXPORT_SYMBOL_GPL(ax25_register_pid);
78 58
79void ax25_protocol_release(unsigned int pid) 59void 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
111EXPORT_SYMBOL(ax25_protocol_release); 91EXPORT_SYMBOL(ax25_protocol_release);
112 92
113int ax25_linkfail_register(void (*func)(ax25_cb *, int)) 93void 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
130EXPORT_SYMBOL(ax25_linkfail_register); 100EXPORT_SYMBOL(ax25_linkfail_register);
131 101
132void ax25_linkfail_release(void (*func)(ax25_cb *, int)) 102void 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
187EXPORT_SYMBOL(ax25_listen_register); 132EXPORT_SYMBOL(ax25_listen_register);
@@ -223,7 +168,7 @@ EXPORT_SYMBOL(ax25_listen_release);
223int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) 168int (*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
254void ax25_link_failed(ax25_cb *ax25, int reason) 200void 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
264int ax25_protocol_is_registered(unsigned int pid) 211int 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);
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index d7736e5853..f84047d1e8 100644
--- a/net/ax25/ax25_out.c
+++ b/net/ax25/ax25_out.c
@@ -70,11 +70,11 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax2
70 ax25->dest_addr = *dest; 70 ax25->dest_addr = *dest;
71 71
72 if (digi != NULL) { 72 if (digi != NULL) {
73 if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { 73 ax25->digipeat = kmemdup(digi, sizeof(*digi), GFP_ATOMIC);
74 if (ax25->digipeat == NULL) {
74 ax25_cb_put(ax25); 75 ax25_cb_put(ax25);
75 return NULL; 76 return NULL;
76 } 77 }
77 memcpy(ax25->digipeat, digi, sizeof(ax25_digi));
78 } 78 }
79 79
80 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) { 80 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 51b7bdaf27..0a0381622b 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -71,7 +71,7 @@ void ax25_rt_device_down(struct net_device *dev)
71 write_unlock(&ax25_route_lock); 71 write_unlock(&ax25_route_lock);
72} 72}
73 73
74static int ax25_rt_add(struct ax25_routes_struct *route) 74static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
75{ 75{
76 ax25_route *ax25_rt; 76 ax25_route *ax25_rt;
77 ax25_dev *ax25_dev; 77 ax25_dev *ax25_dev;
@@ -432,11 +432,12 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
432 } 432 }
433 433
434 if (ax25_rt->digipeat != NULL) { 434 if (ax25_rt->digipeat != NULL) {
435 if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { 435 ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
436 GFP_ATOMIC);
437 if (ax25->digipeat == NULL) {
436 err = -ENOMEM; 438 err = -ENOMEM;
437 goto put; 439 goto put;
438 } 440 }
439 memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
440 ax25_adjust_path(addr, ax25->digipeat); 441 ax25_adjust_path(addr, ax25->digipeat);
441 } 442 }
442 443
diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c
index 867d425379..d23a27f25d 100644
--- a/net/ax25/sysctl_net_ax25.c
+++ b/net/ax25/sysctl_net_ax25.c
@@ -209,7 +209,9 @@ void ax25_register_sysctl(void)
209 } 209 }
210 210
211 for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) { 211 for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) {
212 ctl_table *child = kmalloc(sizeof(ax25_param_table), GFP_ATOMIC); 212 struct ctl_table *child = kmemdup(ax25_param_table,
213 sizeof(ax25_param_table),
214 GFP_ATOMIC);
213 if (!child) { 215 if (!child) {
214 while (n--) 216 while (n--)
215 kfree(ax25_table[n].child); 217 kfree(ax25_table[n].child);
@@ -217,7 +219,6 @@ void ax25_register_sysctl(void)
217 spin_unlock_bh(&ax25_dev_lock); 219 spin_unlock_bh(&ax25_dev_lock);
218 return; 220 return;
219 } 221 }
220 memcpy(child, ax25_param_table, sizeof(ax25_param_table));
221 ax25_table[n].child = ax25_dev->systable = child; 222 ax25_table[n].child = ax25_dev->systable = child;
222 ax25_table[n].ctl_name = n + 1; 223 ax25_table[n].ctl_name = n + 1;
223 ax25_table[n].procname = ax25_dev->dev->name; 224 ax25_table[n].procname = ax25_dev->dev->name;