This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / net / ppp_generic.c
index 6516011..ffd5ac3 100644 (file)
@@ -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;
 }
 
 /*