mempolicy: ERR_PTR dereference in mpol_shared_policy_init()
[safe/jmp/linux-2.6] / drivers / net / ppp_generic.c
index fddc849..c5f8eb1 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/stddef.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/slhc_vj.h>
 #include <asm/atomic.h>
 
@@ -167,6 +168,7 @@ struct channel {
        u8              avail;          /* flag used in multilink stuff */
        u8              had_frag;       /* >= 1 fragments have been sent */
        u32             lastseq;        /* MP: last sequence # received */
+       int             speed;          /* speed of the corresponding ppp channel*/
 #endif /* CONFIG_PPP_MULTILINK */
 };
 
@@ -183,7 +185,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 unsigned int ppp_net_id;
+static int ppp_net_id __read_mostly;
 struct ppp_net {
        /* units to ppp mapping */
        struct idr units_idr;
@@ -403,6 +405,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
        DECLARE_WAITQUEUE(wait, current);
        ssize_t ret;
        struct sk_buff *skb = NULL;
+       struct iovec iov;
 
        ret = count;
 
@@ -424,8 +427,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;
@@ -446,7 +449,9 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
        if (skb->len > count)
                goto outf;
        ret = -EFAULT;
-       if (copy_to_user(buf, skb->data, skb->len))
+       iov.iov_base = buf;
+       iov.iov_len = count;
+       if (skb_copy_datagram_iovec(skb, 0, &iov, skb->len))
                goto outf;
        ret = skb->len;
 
@@ -510,8 +515,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;
        }
 
@@ -863,12 +868,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);
@@ -878,32 +878,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
@@ -916,7 +905,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;
@@ -942,7 +931,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;
 }
@@ -950,7 +939,7 @@ out:
 /*
  * Network interface unit routines.
  */
-static int
+static netdev_tx_t
 ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ppp *ppp = netdev_priv(dev);
@@ -987,12 +976,12 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
        netif_stop_queue(dev);
        skb_queue_tail(&ppp->file.xq, skb);
        ppp_xmit_process(ppp);
-       return 0;
+       return NETDEV_TX_OK;
 
  outf:
        kfree_skb(skb);
-       ++ppp->dev->stats.tx_dropped;
-       return 0;
+       ++dev->stats.tx_dropped;
+       return NETDEV_TX_OK;
 }
 
 static int
@@ -1053,6 +1042,7 @@ static void ppp_setup(struct net_device *dev)
        dev->type = ARPHRD_PPP;
        dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
        dev->features |= NETIF_F_NETNS_LOCAL;
+       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 }
 
 /*
@@ -1071,8 +1061,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. */
@@ -1151,18 +1141,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
@@ -1216,8 +1206,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");
@@ -1245,8 +1235,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
        return;
 
  drop:
-       if (skb)
-               kfree_skb(skb);
+       kfree_skb(skb);
        ++ppp->dev->stats.tx_errors;
 }
 
@@ -1308,42 +1297,56 @@ ppp_push(struct ppp *ppp)
  */
 static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 {
-       int len, fragsize;
+       int len, totlen;
        int i, bits, hdrlen, mtu;
        int flen;
-       int navail, nfree;
+       int navail, nfree, nzero;
        int nbigger;
+       int totspeed;
+       int totfree;
        unsigned char *p, *q;
        struct list_head *list;
        struct channel *pch;
        struct sk_buff *frag;
        struct ppp_channel *chan;
 
-       nfree = 0;      /* # channels which have no packet already queued */
-       navail = 0;     /* total # of usable channels (not deregistered) */
+       totspeed = 0; /*total bitrate of the bundle*/
+       nfree = 0; /* # channels which have no packet already queued */
+       navail = 0; /* total # of usable channels (not deregistered) */
+       nzero = 0; /* number of channels with zero speed associated*/
+       totfree = 0; /*total # of channels available and
+                                 *having no queued packets before
+                                 *starting the fragmentation*/
+
        hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
        i = 0;
        list_for_each_entry(pch, &ppp->channels, clist) {
                navail += pch->avail = (pch->chan != NULL);
+               pch->speed = pch->chan->speed;
                if (pch->avail) {
                        if (skb_queue_empty(&pch->file.xq) ||
-                           !pch->had_frag) {
-                               pch->avail = 2;
-                               ++nfree;
-                       }
+                               !pch->had_frag) {
+                                       if (pch->speed == 0)
+                                               nzero++;
+                                       else
+                                               totspeed += pch->speed;
+
+                                       pch->avail = 2;
+                                       ++nfree;
+                                       ++totfree;
+                               }
                        if (!pch->had_frag && i < ppp->nxchan)
                                ppp->nxchan = i;
                }
                ++i;
        }
-
        /*
         * Don't start sending this packet unless at least half of
         * the channels are free.  This gives much better TCP
         * performance if we have a lot of channels.
         */
        if (nfree == 0 || nfree < navail / 2)
-               return 0;       /* can't take now, leave it in xmit_pending */
+               return 0; /* can't take now, leave it in xmit_pending */
 
        /* Do protocol field compression (XXX this should be optional) */
        p = skb->data;
@@ -1353,18 +1356,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                --len;
        }
 
-       /*
-        * Decide on fragment size.
-        * We create a fragment for each free channel regardless of
-        * how small they are (i.e. even 0 length) in order to minimize
-        * the time that it will take to detect when a channel drops
-        * a fragment.
-        */
-       fragsize = len;
-       if (nfree > 1)
-               fragsize = DIV_ROUND_UP(fragsize, nfree);
-       /* nbigger channels get fragsize bytes, the rest get fragsize-1,
-          except if nbigger==0, then they all get fragsize. */
+       totlen = len;
        nbigger = len % nfree;
 
        /* skip to the channel after the one we last used
@@ -1380,7 +1372,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 
        /* create a fragment for each channel */
        bits = B;
-       while (nfree > 0 || len > 0) {
+       while (len > 0) {
                list = list->next;
                if (list == &ppp->channels) {
                        i = 0;
@@ -1399,7 +1391,6 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                        if (nfree > 0)
                                continue;
                } else {
-                       --nfree;
                        pch->avail = 1;
                }
 
@@ -1407,28 +1398,72 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                spin_lock_bh(&pch->downl);
                if (pch->chan == NULL) {
                        /* can't use this channel, it's being deregistered */
+                       if (pch->speed == 0)
+                               nzero--;
+                       else
+                               totspeed -= pch->speed;
+
                        spin_unlock_bh(&pch->downl);
                        pch->avail = 0;
+                       totlen = len;
+                       totfree--;
+                       nfree--;
                        if (--navail == 0)
                                break;
                        continue;
                }
 
                /*
-                * Create a fragment for this channel of
-                * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes.
-                * If mtu+2-hdrlen < 4, that is a ridiculously small
-                * MTU, so we use mtu = 2 + hdrlen.
+               *if the channel speed is not set divide
+               *the packet evenly among the free channels;
+               *otherwise divide it according to the speed
+               *of the channel we are going to transmit on
+               */
+               flen = len;
+               if (nfree > 0) {
+                       if (pch->speed == 0) {
+                               flen = totlen/nfree;
+                               if (nbigger > 0) {
+                                       flen++;
+                                       nbigger--;
+                               }
+                       } else {
+                               flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
+                                       ((totspeed*totfree)/pch->speed)) - hdrlen;
+                               if (nbigger > 0) {
+                                       flen += ((totfree - nzero)*pch->speed)/totspeed;
+                                       nbigger -= ((totfree - nzero)*pch->speed)/
+                                                       totspeed;
+                               }
+                       }
+                       nfree--;
+               }
+
+               /*
+                *check if we are on the last channel or
+                *we exceded the lenght of the data to
+                *fragment
                 */
-               if (fragsize > len)
-                       fragsize = len;
-               flen = fragsize;
-               mtu = pch->chan->mtu + 2 - hdrlen;
+               if ((nfree <= 0) || (flen > len))
+                       flen = len;
+               /*
+                *it is not worth to tx on slow channels:
+                *in that case from the resulting flen according to the
+                *above formula will be equal or less than zero.
+                *Skip the channel in this case
+                */
+               if (flen <= 0) {
+                       pch->avail = 2;
+                       spin_unlock_bh(&pch->downl);
+                       continue;
+               }
+
+               mtu = pch->chan->mtu - hdrlen;
                if (mtu < 4)
                        mtu = 4;
                if (flen > mtu)
                        flen = mtu;
-               if (flen == len && nfree == 0)
+               if (flen == len)
                        bits |= E;
                frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
                if (!frag)
@@ -1448,24 +1483,12 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                        q[5] = ppp->nxseq;
                }
 
-               /*
-                * Copy the data in.
-                * Unfortunately there is a bug in older versions of
-                * the Linux PPP multilink reconstruction code where it
-                * drops 0-length fragments.  Therefore we make sure the
-                * fragment has at least one byte of data.  Any bytes
-                * we add in this situation will end up as padding on the
-                * end of the reconstructed packet.
-                */
-               if (flen == 0)
-                       *skb_put(frag, 1) = 0;
-               else
-                       memcpy(q + hdrlen, p, flen);
+               memcpy(q + hdrlen, p, flen);
 
                /* try to send it down the channel */
                chan = pch->chan;
                if (!skb_queue_empty(&pch->file.xq) ||
-                   !chan->ops->start_xmit(chan, frag))
+                       !chan->ops->start_xmit(chan, frag))
                        skb_queue_tail(&pch->file.xq, frag);
                pch->had_frag = 1;
                p += flen;
@@ -1473,9 +1496,6 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                ++ppp->nxseq;
                bits = 0;
                spin_unlock_bh(&pch->downl);
-
-               if (--nbigger == 0 && fragsize > 0)
-                       --fragsize;
        }
        ppp->nxchan = i;
 
@@ -1550,24 +1570,35 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
        struct channel *pch = chan->ppp;
        int proto;
 
-       if (!pch || skb->len == 0) {
+       if (!pch) {
                kfree_skb(skb);
                return;
        }
 
-       proto = PPP_PROTO(skb);
        read_lock_bh(&pch->upl);
+       if (!pskb_may_pull(skb, 2)) {
+               kfree_skb(skb);
+               if (pch->ppp) {
+                       ++pch->ppp->dev->stats.rx_length_errors;
+                       ppp_receive_error(pch->ppp);
+               }
+               goto done;
+       }
+
+       proto = PPP_PROTO(skb);
        if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
                /* 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 {
                ppp_do_recv(pch->ppp, skb, pch);
        }
+
+done:
        read_unlock_bh(&pch->upl);
 }
 
@@ -1600,7 +1631,8 @@ ppp_input_error(struct ppp_channel *chan, int code)
 static void
 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
-       if (pskb_may_pull(skb, 2)) {
+       /* note: a 0-length skb is used as an error indication */
+       if (skb->len > 0) {
 #ifdef CONFIG_PPP_MULTILINK
                /* XXX do channel-level decompression here */
                if (PPP_PROTO(skb) == PPP_MP)
@@ -1608,15 +1640,10 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
                else
 #endif /* CONFIG_PPP_MULTILINK */
                        ppp_receive_nonmp_frame(ppp, skb);
-               return;
+       } else {
+               kfree_skb(skb);
+               ppp_receive_error(ppp);
        }
-
-       if (skb->len > 0)
-               /* note: a 0-length skb is used as an error indication */
-               ++ppp->dev->stats.rx_length_errors;
-
-       kfree_skb(skb);
-       ppp_receive_error(ppp);
 }
 
 static void
@@ -1638,8 +1665,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)
@@ -1710,8 +1737,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);
@@ -1729,26 +1756,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 */
@@ -1912,8 +1939,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;
 
@@ -2140,6 +2174,24 @@ int ppp_unit_number(struct ppp_channel *chan)
 }
 
 /*
+ * Return the PPP device interface name of a channel.
+ */
+char *ppp_dev_name(struct ppp_channel *chan)
+{
+       struct channel *pch = chan->ppp;
+       char *name = NULL;
+
+       if (pch) {
+               read_lock_bh(&pch->upl);
+               if (pch->ppp && pch->ppp->dev)
+                       name = pch->ppp->dev->name;
+               read_unlock_bh(&pch->upl);
+       }
+       return name;
+}
+
+
+/*
  * Disconnect a channel from the generic layer.
  * This must be called in process context.
  */
@@ -2205,13 +2257,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(
@@ -2658,8 +2710,7 @@ static void ppp_destroy_interface(struct ppp *ppp)
        ppp->active_filter = NULL;
 #endif /* CONFIG_PPP_FILTER */
 
-       if (ppp->xmit_pending)
-               kfree_skb(ppp->xmit_pending);
+       kfree_skb(ppp->xmit_pending);
 
        free_netdev(ppp->dev);
 }
@@ -2797,7 +2848,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);
 }
 
 /*
@@ -2868,11 +2919,12 @@ EXPORT_SYMBOL(ppp_register_channel);
 EXPORT_SYMBOL(ppp_unregister_channel);
 EXPORT_SYMBOL(ppp_channel_index);
 EXPORT_SYMBOL(ppp_unit_number);
+EXPORT_SYMBOL(ppp_dev_name);
 EXPORT_SYMBOL(ppp_input);
 EXPORT_SYMBOL(ppp_input_error);
 EXPORT_SYMBOL(ppp_output_wakeup);
 EXPORT_SYMBOL(ppp_register_compressor);
 EXPORT_SYMBOL(ppp_unregister_compressor);
 MODULE_LICENSE("GPL");
-MODULE_ALIAS_CHARDEV_MAJOR(PPP_MAJOR);
-MODULE_ALIAS("/dev/ppp");
+MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0);
+MODULE_ALIAS("devname:ppp");