X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fppp_generic.c;h=ffd5ac3a848ee1f617e98eed2743fca8bf3ab656;hb=f9296eb00ed30209424102d3c920e69617eea853;hp=6516011055677d7cc39e207446da23f96f5cedeb;hpb=a91482bdcc2e0f6035702e46f1b99043a0893346;p=linux-2.6.git diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 651601105..ffd5ac3a8 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -129,9 +129,8 @@ struct ppp { #endif /* CONFIG_PPP_MULTILINK */ struct net_device_stats stats; /* statistics */ #ifdef CONFIG_PPP_FILTER - struct sock_filter *pass_filter; /* filter for packets to pass */ - struct sock_filter *active_filter;/* filter for pkts to reset idle */ - unsigned pass_len, active_len; + struct sock_fprog pass_filter; /* filter for packets to pass */ + struct sock_fprog active_filter;/* filter for pkts to reset idle */ #endif /* CONFIG_PPP_FILTER */ }; @@ -371,7 +370,7 @@ static int ppp_release(struct inode *inode, struct file *file) struct ppp *ppp; if (pf != 0) { - file->private_data = NULL; + file->private_data = 0; if (pf->kind == INTERFACE) { ppp = PF_TO_PPP(pf); if (file == ppp->owner) @@ -397,7 +396,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf, struct ppp_file *pf = file->private_data; DECLARE_WAITQUEUE(wait, current); ssize_t ret; - struct sk_buff *skb = NULL; + struct sk_buff *skb = 0; ret = count; @@ -494,45 +493,6 @@ static unsigned int ppp_poll(struct file *file, poll_table *wait) return mask; } -#ifdef CONFIG_PPP_FILTER -static int get_filter(void __user *arg, struct sock_filter **p) -{ - struct sock_fprog uprog; - struct sock_filter *code = NULL; - int len, err; - - if (copy_from_user(&uprog, arg, sizeof(uprog))) - return -EFAULT; - - if (uprog.len > BPF_MAXINSNS) - return -EINVAL; - - if (!uprog.len) { - *p = NULL; - return 0; - } - - len = uprog.len * sizeof(struct sock_filter); - code = kmalloc(len, GFP_KERNEL); - if (code == NULL) - return -ENOMEM; - - if (copy_from_user(code, uprog.filter, len)) { - kfree(code); - return -EFAULT; - } - - err = sk_chk_filter(code, uprog.len); - if (err) { - kfree(code); - return err; - } - - *p = code; - return uprog.len; -} -#endif /* CONFIG_PPP_FILTER */ - static int ppp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -543,8 +503,6 @@ static int ppp_ioctl(struct inode *inode, struct file *file, struct npioctl npi; int unit, cflags; struct slcompress *vj; - void __user *argp = (void __user *)arg; - int __user *p = argp; if (pf == 0) return ppp_unattached_ioctl(pf, file, cmd, arg); @@ -582,7 +540,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file, switch (cmd) { case PPPIOCCONNECT: - if (get_user(unit, p)) + if (get_user(unit, (int *) arg)) break; err = ppp_connect_channel(pch, unit); break; @@ -611,14 +569,14 @@ static int ppp_ioctl(struct inode *inode, struct file *file, ppp = PF_TO_PPP(pf); switch (cmd) { case PPPIOCSMRU: - if (get_user(val, p)) + if (get_user(val, (int *) arg)) break; ppp->mru = val; err = 0; break; case PPPIOCSFLAGS: - if (get_user(val, p)) + if (get_user(val, (int *) arg)) break; ppp_lock(ppp); cflags = ppp->flags & ~val; @@ -631,7 +589,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file, case PPPIOCGFLAGS: val = ppp->flags | ppp->xstate | ppp->rstate; - if (put_user(val, p)) + if (put_user(val, (int *) arg)) break; err = 0; break; @@ -641,20 +599,20 @@ static int ppp_ioctl(struct inode *inode, struct file *file, break; case PPPIOCGUNIT: - if (put_user(ppp->file.index, p)) + if (put_user(ppp->file.index, (int *) arg)) break; err = 0; break; case PPPIOCSDEBUG: - if (get_user(val, p)) + if (get_user(val, (int *) arg)) break; ppp->debug = val; err = 0; break; case PPPIOCGDEBUG: - if (put_user(ppp->debug, p)) + if (put_user(ppp->debug, (int *) arg)) break; err = 0; break; @@ -662,13 +620,13 @@ static int ppp_ioctl(struct inode *inode, struct file *file, case PPPIOCGIDLE: idle.xmit_idle = (jiffies - ppp->last_xmit) / HZ; idle.recv_idle = (jiffies - ppp->last_recv) / HZ; - if (copy_to_user(argp, &idle, sizeof(idle))) + if (copy_to_user((void __user *) arg, &idle, sizeof(idle))) break; err = 0; break; case PPPIOCSMAXCID: - if (get_user(val, p)) + if (get_user(val, (int *) arg)) break; val2 = 15; if ((val >> 16) != 0) { @@ -691,7 +649,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file, case PPPIOCGNPMODE: case PPPIOCSNPMODE: - if (copy_from_user(&npi, argp, sizeof(npi))) + if (copy_from_user(&npi, (void __user *) arg, sizeof(npi))) break; err = proto_to_npindex(npi.protocol); if (err < 0) @@ -700,7 +658,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file, if (cmd == PPPIOCGNPMODE) { err = -EFAULT; npi.mode = ppp->npmode[i]; - if (copy_to_user(argp, &npi, sizeof(npi))) + if (copy_to_user((void __user *) arg, &npi, sizeof(npi))) break; } else { ppp->npmode[i] = npi.mode; @@ -712,38 +670,49 @@ static int ppp_ioctl(struct inode *inode, struct file *file, #ifdef CONFIG_PPP_FILTER case PPPIOCSPASS: - { - struct sock_filter *code; - err = get_filter(argp, &code); - if (err >= 0) { - ppp_lock(ppp); - kfree(ppp->pass_filter); - ppp->pass_filter = code; - ppp->pass_len = err; - ppp_unlock(ppp); - err = 0; - } - break; - } case PPPIOCSACTIVE: { - struct sock_filter *code; - err = get_filter(argp, &code); - if (err >= 0) { - ppp_lock(ppp); - kfree(ppp->active_filter); - ppp->active_filter = code; - ppp->active_len = err; - ppp_unlock(ppp); - err = 0; + struct sock_fprog uprog, *filtp; + struct sock_filter *code = NULL; + int len; + + if (copy_from_user(&uprog, (void __user *) arg, sizeof(uprog))) + break; + err = -EINVAL; + if (uprog.len > BPF_MAXINSNS) + break; + err = -ENOMEM; + if (uprog.len > 0) { + len = uprog.len * sizeof(struct sock_filter); + code = kmalloc(len, GFP_KERNEL); + if (code == NULL) + break; + err = -EFAULT; + if (copy_from_user(code, (void __user *) uprog.filter, len)) { + kfree(code); + break; + } + err = sk_chk_filter(code, uprog.len); + if (err) { + kfree(code); + break; + } } + filtp = (cmd == PPPIOCSPASS)? &ppp->pass_filter: &ppp->active_filter; + ppp_lock(ppp); + if (filtp->filter) + kfree(filtp->filter); + filtp->filter = code; + filtp->len = uprog.len; + ppp_unlock(ppp); + err = 0; break; } #endif /* CONFIG_PPP_FILTER */ #ifdef CONFIG_PPP_MULTILINK case PPPIOCSMRRU: - if (get_user(val, p)) + if (get_user(val, (int *) arg)) break; ppp_recv_lock(ppp); ppp->mrru = val; @@ -765,12 +734,11 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, int unit, err = -EFAULT; struct ppp *ppp; struct channel *chan; - int __user *p = (int __user *)arg; switch (cmd) { case PPPIOCNEWUNIT: /* Create a new ppp unit */ - if (get_user(unit, p)) + if (get_user(unit, (int *) arg)) break; ppp = ppp_create_interface(unit, &err); if (ppp == 0) @@ -778,14 +746,14 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, file->private_data = &ppp->file; ppp->owner = file; err = -EFAULT; - if (put_user(ppp->file.index, p)) + if (put_user(ppp->file.index, (int *) arg)) break; err = 0; break; case PPPIOCATTACH: /* Attach to an existing ppp unit */ - if (get_user(unit, p)) + if (get_user(unit, (int *) arg)) break; down(&all_ppp_sem); err = -ENXIO; @@ -799,7 +767,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, break; case PPPIOCATTCHAN: - if (get_user(unit, p)) + if (get_user(unit, (int *) arg)) break; spin_lock_bh(&all_channels_lock); err = -ENXIO; @@ -1026,19 +994,23 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) /* check if we should pass this packet */ /* 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) { + { + u_int16_t *p = (u_int16_t *) skb_push(skb, 2); + + *p = htons(4); /* indicate outbound in DLT_LINUX_SLL */; + } + if (ppp->pass_filter.filter + && sk_run_filter(skb, ppp->pass_filter.filter, + ppp->pass_filter.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.filter + && sk_run_filter(skb, ppp->active_filter.filter, + ppp->active_filter.len) == 0)) ppp->last_xmit = jiffies; skb_pull(skb, 2); #else @@ -1157,7 +1129,7 @@ ppp_push(struct ppp *ppp) list = &ppp->channels; if (list_empty(list)) { /* nowhere to send the packet, just drop it */ - ppp->xmit_pending = NULL; + ppp->xmit_pending = 0; kfree_skb(skb); return; } @@ -1170,11 +1142,11 @@ ppp_push(struct ppp *ppp) spin_lock_bh(&pch->downl); if (pch->chan) { if (pch->chan->ops->start_xmit(pch->chan, skb)) - ppp->xmit_pending = NULL; + ppp->xmit_pending = 0; } else { /* channel got unregistered */ kfree_skb(skb); - ppp->xmit_pending = NULL; + ppp->xmit_pending = 0; } spin_unlock_bh(&pch->downl); return; @@ -1187,7 +1159,7 @@ ppp_push(struct ppp *ppp) return; #endif /* CONFIG_PPP_MULTILINK */ - ppp->xmit_pending = NULL; + ppp->xmit_pending = 0; kfree_skb(skb); } @@ -1569,18 +1541,22 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) /* check if the packet passes the pass and active filters */ /* the filter instructions are constructed assuming a four-byte PPP header on each packet */ - *skb_push(skb, 2) = 0; - if (ppp->pass_filter - && sk_run_filter(skb, ppp->pass_filter, - ppp->pass_len) == 0) { + { + u_int16_t *p = (u_int16_t *) skb_push(skb, 2); + + *p = 0; /* indicate inbound in DLT_LINUX_SLL */ + } + if (ppp->pass_filter.filter + && sk_run_filter(skb, ppp->pass_filter.filter, + ppp->pass_filter.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.filter + && sk_run_filter(skb, ppp->active_filter.filter, + ppp->active_filter.len) == 0)) ppp->last_recv = jiffies; skb_pull(skb, 2); #else @@ -1968,7 +1944,7 @@ ppp_unregister_channel(struct ppp_channel *chan) if (pch == 0) return; /* should never happen */ - chan->ppp = NULL; + chan->ppp = 0; /* * This ensures that we have returned from any calls into the @@ -1976,7 +1952,7 @@ ppp_unregister_channel(struct ppp_channel *chan) */ down_write(&pch->chan_sem); spin_lock_bh(&pch->downl); - pch->chan = NULL; + pch->chan = 0; spin_unlock_bh(&pch->downl); up_write(&pch->chan_sem); ppp_disconnect_channel(pch); @@ -2179,11 +2155,11 @@ ppp_ccp_closed(struct ppp *ppp) ppp->xstate = 0; xcomp = ppp->xcomp; xstate = ppp->xc_state; - ppp->xc_state = NULL; + ppp->xc_state = 0; ppp->rstate = 0; rcomp = ppp->rcomp; rstate = ppp->rc_state; - ppp->rc_state = NULL; + ppp->rc_state = 0; ppp_unlock(ppp); if (xstate) { @@ -2216,7 +2192,7 @@ find_comp_entry(int proto) if (ce->comp->compress_proto == proto) return ce; } - return NULL; + return 0; } /* Register a compressor */ @@ -2261,7 +2237,7 @@ static struct compressor * find_compressor(int type) { struct compressor_entry *ce; - struct compressor *cp = NULL; + struct compressor *cp = 0; spin_lock(&compressor_list_lock); ce = find_comp_entry(type); @@ -2405,7 +2381,7 @@ static void ppp_shutdown_interface(struct ppp *ppp) down(&all_ppp_sem); ppp_lock(ppp); dev = ppp->dev; - ppp->dev = NULL; + ppp->dev = 0; ppp_unlock(ppp); /* This will call dev_close() for us. */ if (dev) { @@ -2439,7 +2415,7 @@ static void ppp_destroy_interface(struct ppp *ppp) ppp_ccp_closed(ppp); if (ppp->vj) { slhc_free(ppp->vj); - ppp->vj = NULL; + ppp->vj = 0; } skb_queue_purge(&ppp->file.xq); skb_queue_purge(&ppp->file.rq); @@ -2447,13 +2423,13 @@ static void ppp_destroy_interface(struct ppp *ppp) skb_queue_purge(&ppp->mrq); #endif /* CONFIG_PPP_MULTILINK */ #ifdef CONFIG_PPP_FILTER - if (ppp->pass_filter) { - kfree(ppp->pass_filter); - ppp->pass_filter = NULL; + if (ppp->pass_filter.filter) { + kfree(ppp->pass_filter.filter); + ppp->pass_filter.filter = NULL; } - if (ppp->active_filter) { - kfree(ppp->active_filter); - ppp->active_filter = NULL; + if (ppp->active_filter.filter) { + kfree(ppp->active_filter.filter); + ppp->active_filter.filter = 0; } #endif /* CONFIG_PPP_FILTER */ @@ -2499,7 +2475,7 @@ ppp_find_channel(int unit) if (pch->file.index == unit) return pch; } - return NULL; + return 0; } /*