aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ax25.h10
-rw-r--r--net/ax25/ax25_iface.c55
-rw-r--r--net/netrom/af_netrom.c8
-rw-r--r--net/rose/af_rose.c8
4 files changed, 29 insertions, 52 deletions
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 51060ef74590..5ae10dd2e32e 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -342,8 +342,14 @@ struct ax25_protocol {
342 342
343extern void ax25_register_pid(struct ax25_protocol *ap); 343extern void ax25_register_pid(struct ax25_protocol *ap);
344extern void ax25_protocol_release(unsigned int); 344extern void ax25_protocol_release(unsigned int);
345extern int __must_check ax25_linkfail_register(void (*)(ax25_cb *, int)); 345
346extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); 346struct ax25_linkfail {
347 struct hlist_node lf_node;
348 void (*func)(ax25_cb *, int);
349};
350
351extern void ax25_linkfail_register(struct ax25_linkfail *lf);
352extern void ax25_linkfail_release(struct ax25_linkfail *lf);
347extern int __must_check ax25_listen_register(ax25_address *, 353extern int __must_check ax25_listen_register(ax25_address *,
348 struct net_device *); 354 struct net_device *);
349extern void ax25_listen_release(ax25_address *, struct net_device *); 355extern void ax25_listen_release(ax25_address *, struct net_device *);
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 51e293420b7f..aff3e652c2d1 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -32,10 +32,7 @@
32static struct ax25_protocol *protocol_list; 32static struct ax25_protocol *protocol_list;
33static DEFINE_RWLOCK(protocol_list_lock); 33static DEFINE_RWLOCK(protocol_list_lock);
34 34
35static struct linkfail_struct { 35static HLIST_HEAD(ax25_linkfail_list);
36 struct linkfail_struct *next;
37 void (*func)(ax25_cb *, int);
38} *linkfail_list = NULL;
39static DEFINE_SPINLOCK(linkfail_lock); 36static DEFINE_SPINLOCK(linkfail_lock);
40 37
41static struct listen_struct { 38static struct listen_struct {
@@ -93,54 +90,19 @@ void ax25_protocol_release(unsigned int pid)
93 90
94EXPORT_SYMBOL(ax25_protocol_release); 91EXPORT_SYMBOL(ax25_protocol_release);
95 92
96int ax25_linkfail_register(void (*func)(ax25_cb *, int)) 93void ax25_linkfail_register(struct ax25_linkfail *lf)
97{ 94{
98 struct linkfail_struct *linkfail;
99
100 if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
101 return 0;
102
103 linkfail->func = func;
104
105 spin_lock_bh(&linkfail_lock); 95 spin_lock_bh(&linkfail_lock);
106 linkfail->next = linkfail_list; 96 hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
107 linkfail_list = linkfail;
108 spin_unlock_bh(&linkfail_lock); 97 spin_unlock_bh(&linkfail_lock);
109
110 return 1;
111} 98}
112 99
113EXPORT_SYMBOL(ax25_linkfail_register); 100EXPORT_SYMBOL(ax25_linkfail_register);
114 101
115void ax25_linkfail_release(void (*func)(ax25_cb *, int)) 102void ax25_linkfail_release(struct ax25_linkfail *lf)
116{ 103{
117 struct linkfail_struct *s, *linkfail;
118
119 spin_lock_bh(&linkfail_lock); 104 spin_lock_bh(&linkfail_lock);
120 linkfail = linkfail_list; 105 hlist_del_init(&lf->lf_node);
121 if (linkfail == NULL) {
122 spin_unlock_bh(&linkfail_lock);
123 return;
124 }
125
126 if (linkfail->func == func) {
127 linkfail_list = linkfail->next;
128 spin_unlock_bh(&linkfail_lock);
129 kfree(linkfail);
130 return;
131 }
132
133 while (linkfail != NULL && linkfail->next != NULL) {
134 if (linkfail->next->func == func) {
135 s = linkfail->next;
136 linkfail->next = linkfail->next->next;
137 spin_unlock_bh(&linkfail_lock);
138 kfree(s);
139 return;
140 }
141
142 linkfail = linkfail->next;
143 }
144 spin_unlock_bh(&linkfail_lock); 106 spin_unlock_bh(&linkfail_lock);
145} 107}
146 108
@@ -237,11 +199,12 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
237 199
238void ax25_link_failed(ax25_cb *ax25, int reason) 200void ax25_link_failed(ax25_cb *ax25, int reason)
239{ 201{
240 struct linkfail_struct *linkfail; 202 struct ax25_linkfail *lf;
203 struct hlist_node *node;
241 204
242 spin_lock_bh(&linkfail_lock); 205 spin_lock_bh(&linkfail_lock);
243 for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) 206 hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node)
244 (linkfail->func)(ax25, reason); 207 lf->func(ax25, reason);
245 spin_unlock_bh(&linkfail_lock); 208 spin_unlock_bh(&linkfail_lock);
246} 209}
247 210
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index f4675bf3976c..43bbe2c9e49a 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1382,6 +1382,10 @@ static struct ax25_protocol nr_pid = {
1382 .func = nr_route_frame 1382 .func = nr_route_frame
1383}; 1383};
1384 1384
1385static struct ax25_linkfail nr_linkfail_notifier = {
1386 .func = nr_link_failed,
1387};
1388
1385static int __init nr_proto_init(void) 1389static int __init nr_proto_init(void)
1386{ 1390{
1387 int i; 1391 int i;
@@ -1430,7 +1434,7 @@ static int __init nr_proto_init(void)
1430 register_netdevice_notifier(&nr_dev_notifier); 1434 register_netdevice_notifier(&nr_dev_notifier);
1431 1435
1432 ax25_register_pid(&nr_pid); 1436 ax25_register_pid(&nr_pid);
1433 ax25_linkfail_register(nr_link_failed); 1437 ax25_linkfail_register(&nr_linkfail_notifier);
1434 1438
1435#ifdef CONFIG_SYSCTL 1439#ifdef CONFIG_SYSCTL
1436 nr_register_sysctl(); 1440 nr_register_sysctl();
@@ -1479,7 +1483,7 @@ static void __exit nr_exit(void)
1479 nr_unregister_sysctl(); 1483 nr_unregister_sysctl();
1480#endif 1484#endif
1481 1485
1482 ax25_linkfail_release(nr_link_failed); 1486 ax25_linkfail_release(&nr_linkfail_notifier);
1483 ax25_protocol_release(AX25_P_NETROM); 1487 ax25_protocol_release(AX25_P_NETROM);
1484 1488
1485 unregister_netdevice_notifier(&nr_dev_notifier); 1489 unregister_netdevice_notifier(&nr_dev_notifier);
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 09f8a06bf806..9e279464c9d1 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1487,6 +1487,10 @@ static struct ax25_protocol rose_pid = {
1487 .func = rose_route_frame 1487 .func = rose_route_frame
1488}; 1488};
1489 1489
1490static struct ax25_linkfail rose_linkfail_notifier = {
1491 .func = rose_link_failed
1492};
1493
1490static int __init rose_proto_init(void) 1494static int __init rose_proto_init(void)
1491{ 1495{
1492 int i; 1496 int i;
@@ -1537,7 +1541,7 @@ static int __init rose_proto_init(void)
1537 register_netdevice_notifier(&rose_dev_notifier); 1541 register_netdevice_notifier(&rose_dev_notifier);
1538 1542
1539 ax25_register_pid(&rose_pid); 1543 ax25_register_pid(&rose_pid);
1540 ax25_linkfail_register(rose_link_failed); 1544 ax25_linkfail_register(&rose_linkfail_notifier);
1541 1545
1542#ifdef CONFIG_SYSCTL 1546#ifdef CONFIG_SYSCTL
1543 rose_register_sysctl(); 1547 rose_register_sysctl();
@@ -1585,7 +1589,7 @@ static void __exit rose_exit(void)
1585 rose_rt_free(); 1589 rose_rt_free();
1586 1590
1587 ax25_protocol_release(AX25_P_ROSE); 1591 ax25_protocol_release(AX25_P_ROSE);
1588 ax25_linkfail_release(rose_link_failed); 1592 ax25_linkfail_release(&rose_linkfail_notifier);
1589 1593
1590 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) 1594 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
1591 ax25_listen_release(&rose_callsign, NULL); 1595 ax25_listen_release(&rose_callsign, NULL);