diff --git a/include/net/ax25.h b/include/net/ax25.h index 51060ef745901d204e97fbbdf005967001e9d4cc..5ae10dd2e32ebaa1a08ae06392ea7ffc42b37eb7 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -342,8 +342,14 @@ struct ax25_protocol { extern void ax25_register_pid(struct ax25_protocol *ap); extern void ax25_protocol_release(unsigned int); -extern int __must_check ax25_linkfail_register(void (*)(ax25_cb *, int)); -extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); + +struct ax25_linkfail { + struct hlist_node lf_node; + void (*func)(ax25_cb *, int); +}; + +extern void ax25_linkfail_register(struct ax25_linkfail *lf); +extern void ax25_linkfail_release(struct ax25_linkfail *lf); extern int __must_check ax25_listen_register(ax25_address *, struct net_device *); extern void ax25_listen_release(ax25_address *, struct net_device *); diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c index 51e293420b7f90fc8c9dbf5df0cee13ee64383be..aff3e652c2d110ad55448ae2e41dd15fcac5affc 100644 --- a/net/ax25/ax25_iface.c +++ b/net/ax25/ax25_iface.c @@ -32,10 +32,7 @@ static struct ax25_protocol *protocol_list; static DEFINE_RWLOCK(protocol_list_lock); -static struct linkfail_struct { - struct linkfail_struct *next; - void (*func)(ax25_cb *, int); -} *linkfail_list = NULL; +static HLIST_HEAD(ax25_linkfail_list); static DEFINE_SPINLOCK(linkfail_lock); static struct listen_struct { @@ -93,54 +90,19 @@ void ax25_protocol_release(unsigned int pid) EXPORT_SYMBOL(ax25_protocol_release); -int ax25_linkfail_register(void (*func)(ax25_cb *, int)) +void ax25_linkfail_register(struct ax25_linkfail *lf) { - struct linkfail_struct *linkfail; - - if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL) - return 0; - - linkfail->func = func; - spin_lock_bh(&linkfail_lock); - linkfail->next = linkfail_list; - linkfail_list = linkfail; + hlist_add_head(&lf->lf_node, &ax25_linkfail_list); spin_unlock_bh(&linkfail_lock); - - return 1; } EXPORT_SYMBOL(ax25_linkfail_register); -void ax25_linkfail_release(void (*func)(ax25_cb *, int)) +void ax25_linkfail_release(struct ax25_linkfail *lf) { - struct linkfail_struct *s, *linkfail; - spin_lock_bh(&linkfail_lock); - linkfail = linkfail_list; - if (linkfail == NULL) { - spin_unlock_bh(&linkfail_lock); - return; - } - - if (linkfail->func == func) { - linkfail_list = linkfail->next; - spin_unlock_bh(&linkfail_lock); - kfree(linkfail); - return; - } - - while (linkfail != NULL && linkfail->next != NULL) { - if (linkfail->next->func == func) { - s = linkfail->next; - linkfail->next = linkfail->next->next; - spin_unlock_bh(&linkfail_lock); - kfree(s); - return; - } - - linkfail = linkfail->next; - } + hlist_del_init(&lf->lf_node); spin_unlock_bh(&linkfail_lock); } @@ -237,11 +199,12 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) void ax25_link_failed(ax25_cb *ax25, int reason) { - struct linkfail_struct *linkfail; + struct ax25_linkfail *lf; + struct hlist_node *node; spin_lock_bh(&linkfail_lock); - for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) - (linkfail->func)(ax25, reason); + hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) + lf->func(ax25, reason); spin_unlock_bh(&linkfail_lock); } diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index f4675bf3976c96c6e90c7dd4cbef1d7a63fe2a13..43bbe2c9e49aa48f8b8995e857945f440dc98acd 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1382,6 +1382,10 @@ static struct ax25_protocol nr_pid = { .func = nr_route_frame }; +static struct ax25_linkfail nr_linkfail_notifier = { + .func = nr_link_failed, +}; + static int __init nr_proto_init(void) { int i; @@ -1430,7 +1434,7 @@ static int __init nr_proto_init(void) register_netdevice_notifier(&nr_dev_notifier); ax25_register_pid(&nr_pid); - ax25_linkfail_register(nr_link_failed); + ax25_linkfail_register(&nr_linkfail_notifier); #ifdef CONFIG_SYSCTL nr_register_sysctl(); @@ -1479,7 +1483,7 @@ static void __exit nr_exit(void) nr_unregister_sysctl(); #endif - ax25_linkfail_release(nr_link_failed); + ax25_linkfail_release(&nr_linkfail_notifier); ax25_protocol_release(AX25_P_NETROM); unregister_netdevice_notifier(&nr_dev_notifier); diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 09f8a06bf806ec1869ea5dd1ed011e762cdb7558..9e279464c9d1ed59e7b558e2fa1e0e8e6a37737a 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1487,6 +1487,10 @@ static struct ax25_protocol rose_pid = { .func = rose_route_frame }; +static struct ax25_linkfail rose_linkfail_notifier = { + .func = rose_link_failed +}; + static int __init rose_proto_init(void) { int i; @@ -1537,7 +1541,7 @@ static int __init rose_proto_init(void) register_netdevice_notifier(&rose_dev_notifier); ax25_register_pid(&rose_pid); - ax25_linkfail_register(rose_link_failed); + ax25_linkfail_register(&rose_linkfail_notifier); #ifdef CONFIG_SYSCTL rose_register_sysctl(); @@ -1585,7 +1589,7 @@ static void __exit rose_exit(void) rose_rt_free(); ax25_protocol_release(AX25_P_ROSE); - ax25_linkfail_release(rose_link_failed); + ax25_linkfail_release(&rose_linkfail_notifier); if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) ax25_listen_release(&rose_callsign, NULL);