summaryrefslogtreecommitdiffstats
path: root/drivers/net/ppp_generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r--drivers/net/ppp_generic.c109
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);
}
/*