diff options
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r-- | drivers/net/ppp_generic.c | 109 |
1 files changed, 50 insertions, 59 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 9bf2a6be903..2282e729edb 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -184,7 +184,7 @@ static atomic_t ppp_unit_count = ATOMIC_INIT(0); static atomic_t channel_count = ATOMIC_INIT(0); /* per-net private data for this module */ -static int ppp_net_id; +static int ppp_net_id __read_mostly; struct ppp_net { /* units to ppp mapping */ struct idr units_idr; @@ -425,8 +425,8 @@ static ssize_t ppp_read(struct file *file, char __user *buf, * network traffic (demand mode). */ struct ppp *ppp = PF_TO_PPP(pf); - if (ppp->n_channels == 0 - && (ppp->flags & SC_LOOP_TRAFFIC) == 0) + if (ppp->n_channels == 0 && + (ppp->flags & SC_LOOP_TRAFFIC) == 0) break; } ret = -EAGAIN; @@ -511,8 +511,8 @@ static unsigned int ppp_poll(struct file *file, poll_table *wait) else if (pf->kind == INTERFACE) { /* see comment in ppp_read */ struct ppp *ppp = PF_TO_PPP(pf); - if (ppp->n_channels == 0 - && (ppp->flags & SC_LOOP_TRAFFIC) == 0) + if (ppp->n_channels == 0 && + (ppp->flags & SC_LOOP_TRAFFIC) == 0) mask |= POLLIN | POLLRDNORM; } @@ -864,12 +864,7 @@ static const struct file_operations ppp_device_fops = { static __net_init int ppp_init_net(struct net *net) { - struct ppp_net *pn; - int err; - - pn = kzalloc(sizeof(*pn), GFP_KERNEL); - if (!pn) - return -ENOMEM; + struct ppp_net *pn = net_generic(net, ppp_net_id); idr_init(&pn->units_idr); mutex_init(&pn->all_ppp_mutex); @@ -879,32 +874,21 @@ static __net_init int ppp_init_net(struct net *net) spin_lock_init(&pn->all_channels_lock); - err = net_assign_generic(net, ppp_net_id, pn); - if (err) { - kfree(pn); - return err; - } - return 0; } static __net_exit void ppp_exit_net(struct net *net) { - struct ppp_net *pn; + struct ppp_net *pn = net_generic(net, ppp_net_id); - pn = net_generic(net, ppp_net_id); idr_destroy(&pn->units_idr); - /* - * if someone has cached our net then - * further net_generic call will return NULL - */ - net_assign_generic(net, ppp_net_id, NULL); - kfree(pn); } static struct pernet_operations ppp_net_ops = { .init = ppp_init_net, .exit = ppp_exit_net, + .id = &ppp_net_id, + .size = sizeof(struct ppp_net), }; #define PPP_MAJOR 108 @@ -917,7 +901,7 @@ static int __init ppp_init(void) printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); - err = register_pernet_gen_device(&ppp_net_id, &ppp_net_ops); + err = register_pernet_device(&ppp_net_ops); if (err) { printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err); goto out; @@ -943,7 +927,7 @@ static int __init ppp_init(void) out_chrdev: unregister_chrdev(PPP_MAJOR, "ppp"); out_net: - unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops); + unregister_pernet_device(&ppp_net_ops); out: return err; } @@ -1073,8 +1057,8 @@ ppp_xmit_process(struct ppp *ppp) ppp_xmit_lock(ppp); if (!ppp->closing) { ppp_push(ppp); - while (!ppp->xmit_pending - && (skb = skb_dequeue(&ppp->file.xq))) + while (!ppp->xmit_pending && + (skb = skb_dequeue(&ppp->file.xq))) ppp_send_frame(ppp, skb); /* If there's no work left to do, tell the core net code that we can accept some more. */ @@ -1153,18 +1137,18 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) /* the filter instructions are constructed assuming a four-byte PPP header on each packet */ *skb_push(skb, 2) = 1; - if (ppp->pass_filter - && sk_run_filter(skb, ppp->pass_filter, - ppp->pass_len) == 0) { + if (ppp->pass_filter && + sk_run_filter(skb, ppp->pass_filter, + ppp->pass_len) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: outbound frame not passed\n"); kfree_skb(skb); return; } /* if this packet passes the active filter, record the time */ - if (!(ppp->active_filter - && sk_run_filter(skb, ppp->active_filter, - ppp->active_len) == 0)) + if (!(ppp->active_filter && + sk_run_filter(skb, ppp->active_filter, + ppp->active_len) == 0)) ppp->last_xmit = jiffies; skb_pull(skb, 2); #else @@ -1218,8 +1202,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) } /* try to do packet compression */ - if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state - && proto != PPP_LCP && proto != PPP_CCP) { + if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state && + proto != PPP_LCP && proto != PPP_CCP) { if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) { if (net_ratelimit()) printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n"); @@ -1593,8 +1577,8 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb) /* put it on the channel queue */ skb_queue_tail(&pch->file.rq, skb); /* drop old frames if queue too long */ - while (pch->file.rq.qlen > PPP_MAX_RQLEN - && (skb = skb_dequeue(&pch->file.rq))) + while (pch->file.rq.qlen > PPP_MAX_RQLEN && + (skb = skb_dequeue(&pch->file.rq))) kfree_skb(skb); wake_up_interruptible(&pch->file.rwait); } else { @@ -1670,8 +1654,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) * Note that some decompressors need to see uncompressed frames * that come in as well as compressed frames. */ - if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN) - && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0) + if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN) && + (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0) skb = ppp_decompress_frame(ppp, skb); if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR) @@ -1742,8 +1726,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) /* control or unknown frame - pass it to pppd */ skb_queue_tail(&ppp->file.rq, skb); /* limit queue length by dropping old frames */ - while (ppp->file.rq.qlen > PPP_MAX_RQLEN - && (skb = skb_dequeue(&ppp->file.rq))) + while (ppp->file.rq.qlen > PPP_MAX_RQLEN && + (skb = skb_dequeue(&ppp->file.rq))) kfree_skb(skb); /* wake up any process polling or blocking on read */ wake_up_interruptible(&ppp->file.rwait); @@ -1761,26 +1745,26 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) goto err; *skb_push(skb, 2) = 0; - if (ppp->pass_filter - && sk_run_filter(skb, ppp->pass_filter, - ppp->pass_len) == 0) { + if (ppp->pass_filter && + sk_run_filter(skb, ppp->pass_filter, + ppp->pass_len) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: inbound frame " "not passed\n"); kfree_skb(skb); return; } - if (!(ppp->active_filter - && sk_run_filter(skb, ppp->active_filter, - ppp->active_len) == 0)) + if (!(ppp->active_filter && + sk_run_filter(skb, ppp->active_filter, + ppp->active_len) == 0)) ppp->last_recv = jiffies; __skb_pull(skb, 2); } else #endif /* CONFIG_PPP_FILTER */ ppp->last_recv = jiffies; - if ((ppp->dev->flags & IFF_UP) == 0 - || ppp->npmode[npi] != NPMODE_PASS) { + if ((ppp->dev->flags & IFF_UP) == 0 || + ppp->npmode[npi] != NPMODE_PASS) { kfree_skb(skb); } else { /* chop off protocol */ @@ -1944,8 +1928,15 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) } /* Pull completed packets off the queue and receive them. */ - while ((skb = ppp_mp_reconstruct(ppp))) - ppp_receive_nonmp_frame(ppp, skb); + while ((skb = ppp_mp_reconstruct(ppp))) { + if (pskb_may_pull(skb, 2)) + ppp_receive_nonmp_frame(ppp, skb); + else { + ++ppp->dev->stats.rx_length_errors; + kfree_skb(skb); + ppp_receive_error(ppp); + } + } return; @@ -2237,13 +2228,13 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg) unsigned char ccp_option[CCP_MAX_OPTION_LENGTH]; err = -EFAULT; - if (copy_from_user(&data, (void __user *) arg, sizeof(data)) - || (data.length <= CCP_MAX_OPTION_LENGTH - && copy_from_user(ccp_option, (void __user *) data.ptr, data.length))) + if (copy_from_user(&data, (void __user *) arg, sizeof(data)) || + (data.length <= CCP_MAX_OPTION_LENGTH && + copy_from_user(ccp_option, (void __user *) data.ptr, data.length))) goto out; err = -EINVAL; - if (data.length > CCP_MAX_OPTION_LENGTH - || ccp_option[1] < 2 || ccp_option[1] > data.length) + if (data.length > CCP_MAX_OPTION_LENGTH || + ccp_option[1] < 2 || ccp_option[1] > data.length) goto out; cp = try_then_request_module( @@ -2828,7 +2819,7 @@ static void __exit ppp_cleanup(void) unregister_chrdev(PPP_MAJOR, "ppp"); device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); class_destroy(ppp_class); - unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops); + unregister_pernet_device(&ppp_net_ops); } /* |