Commit bd304a6c authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Protect ipc_head list

Make sure that the ipc_head list cannot change under us by
protecting it with a spin lock.
parent 6565c3f9
......@@ -557,6 +557,7 @@ ippp_ccp_send_ccp(struct ippp_ccp *ccp, struct sk_buff *skb)
}
static LIST_HEAD(ipc_head);
static spinlock_t ipc_head_lock;
int
ippp_ccp_set_compressor(struct ippp_ccp *ccp, int unit,
......@@ -571,43 +572,48 @@ ippp_ccp_set_compressor(struct ippp_ccp *ccp, int unit,
printk(KERN_DEBUG "[%d] Set %scompressor type %d\n", unit,
data->flags & IPPP_COMP_FLAG_XMIT ? "" : "de", num);
spin_lock(&ipc_head_lock);
list_for_each_entry(ipc, &ipc_head, list) {
if (ipc->num != num)
continue;
if (!try_module_get(ipc->owner))
continue;
stat = ipc->alloc(data);
if (!stat) {
printk(KERN_ERR "Can't alloc (de)compression!\n");
module_put(ipc->owner);
break;
}
ret = ipc->init(stat, data, unit, 0);
if(!ret) {
printk(KERN_ERR "Can't init (de)compression!\n");
ipc->free(stat);
module_put(ipc->owner);
break;
if (ipc->num == num &&
try_module_get(ipc->owner))
goto found;
}
spin_unlock(&ipc_head_lock);
return -EINVAL;
found:
spin_unlock(&ipc_head_lock);
stat = ipc->alloc(data);
if (!stat) {
printk(KERN_ERR "Can't alloc (de)compression!\n");
goto err;
}
ret = ipc->init(stat, data, unit, 0);
if(!ret) {
printk(KERN_ERR "Can't init (de)compression!\n");
ipc->free(stat);
goto err;
}
if (data->flags & IPPP_COMP_FLAG_XMIT) {
if (ccp->comp_stat) {
ccp->compressor->free(ccp->comp_stat);
module_put(ccp->compressor->owner);
}
if (data->flags & IPPP_COMP_FLAG_XMIT) {
if (ccp->comp_stat) {
ccp->compressor->free(ccp->comp_stat);
module_put(ccp->compressor->owner);
}
ccp->comp_stat = stat;
ccp->compressor = ipc;
} else {
if (ccp->decomp_stat) {
ccp->decompressor->free(ccp->decomp_stat);
module_put(ccp->decompressor->owner);
}
ccp->decomp_stat = stat;
ccp->decompressor = ipc;
} else {
if (ccp->decomp_stat) {
ccp->decompressor->free(ccp->decomp_stat);
module_put(ccp->decompressor->owner);
}
return 0;
ccp->decomp_stat = stat;
ccp->decompressor = ipc;
}
return 0;
err:
module_put(ipc->owner);
return -EINVAL;
}
......@@ -618,25 +624,34 @@ ippp_ccp_get_compressors(unsigned long protos[8])
int i, j;
memset(protos, 0, sizeof(unsigned long) * 8);
spin_lock(&ipc_head_lock);
list_for_each_entry(ipc, &ipc_head, list) {
j = ipc->num / (sizeof(long)*8);
i = ipc->num % (sizeof(long)*8);
if (j < 8)
protos[j] |= 1 << i;
}
spin_unlock(&ipc_head_lock);
}
int
isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
{
spin_lock(&ipc_head_lock);
list_add_tail(&ipc->list, &ipc_head);
spin_unlock(&ipc_head_lock);
return 0;
}
int
isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
{
spin_lock(&ipc_head_lock);
list_del(&ipc->list);
spin_unlock(&ipc_head_lock);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment