aboutsummaryrefslogtreecommitdiffstats
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.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 09cf56d0416a..89294b43c4a9 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1285,6 +1285,11 @@ ppp_push(struct ppp *ppp)
1285} 1285}
1286 1286
1287#ifdef CONFIG_PPP_MULTILINK 1287#ifdef CONFIG_PPP_MULTILINK
1288static bool mp_protocol_compress __read_mostly = true;
1289module_param(mp_protocol_compress, bool, S_IRUGO | S_IWUSR);
1290MODULE_PARM_DESC(mp_protocol_compress,
1291 "compress protocol id in multilink fragments");
1292
1288/* 1293/*
1289 * Divide a packet to be transmitted into fragments and 1294 * Divide a packet to be transmitted into fragments and
1290 * send them out the individual links. 1295 * send them out the individual links.
@@ -1347,10 +1352,10 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1347 if (nfree == 0 || nfree < navail / 2) 1352 if (nfree == 0 || nfree < navail / 2)
1348 return 0; /* can't take now, leave it in xmit_pending */ 1353 return 0; /* can't take now, leave it in xmit_pending */
1349 1354
1350 /* Do protocol field compression (XXX this should be optional) */ 1355 /* Do protocol field compression */
1351 p = skb->data; 1356 p = skb->data;
1352 len = skb->len; 1357 len = skb->len;
1353 if (*p == 0) { 1358 if (*p == 0 && mp_protocol_compress) {
1354 ++p; 1359 ++p;
1355 --len; 1360 --len;
1356 } 1361 }
@@ -2584,16 +2589,16 @@ ppp_create_interface(struct net *net, int unit, int *retp)
2584 */ 2589 */
2585 dev_net_set(dev, net); 2590 dev_net_set(dev, net);
2586 2591
2587 ret = -EEXIST;
2588 mutex_lock(&pn->all_ppp_mutex); 2592 mutex_lock(&pn->all_ppp_mutex);
2589 2593
2590 if (unit < 0) { 2594 if (unit < 0) {
2591 unit = unit_get(&pn->units_idr, ppp); 2595 unit = unit_get(&pn->units_idr, ppp);
2592 if (unit < 0) { 2596 if (unit < 0) {
2593 *retp = unit; 2597 ret = unit;
2594 goto out2; 2598 goto out2;
2595 } 2599 }
2596 } else { 2600 } else {
2601 ret = -EEXIST;
2597 if (unit_find(&pn->units_idr, unit)) 2602 if (unit_find(&pn->units_idr, unit))
2598 goto out2; /* unit already exists */ 2603 goto out2; /* unit already exists */
2599 /* 2604 /*
@@ -2668,10 +2673,10 @@ static void ppp_shutdown_interface(struct ppp *ppp)
2668 ppp->closing = 1; 2673 ppp->closing = 1;
2669 ppp_unlock(ppp); 2674 ppp_unlock(ppp);
2670 unregister_netdev(ppp->dev); 2675 unregister_netdev(ppp->dev);
2676 unit_put(&pn->units_idr, ppp->file.index);
2671 } else 2677 } else
2672 ppp_unlock(ppp); 2678 ppp_unlock(ppp);
2673 2679
2674 unit_put(&pn->units_idr, ppp->file.index);
2675 ppp->file.dead = 1; 2680 ppp->file.dead = 1;
2676 ppp->owner = NULL; 2681 ppp->owner = NULL;
2677 wake_up_interruptible(&ppp->file.rwait); 2682 wake_up_interruptible(&ppp->file.rwait);
@@ -2859,8 +2864,7 @@ static void __exit ppp_cleanup(void)
2859 * by holding all_ppp_mutex 2864 * by holding all_ppp_mutex
2860 */ 2865 */
2861 2866
2862/* associate pointer with specified number */ 2867static int __unit_alloc(struct idr *p, void *ptr, int n)
2863static int unit_set(struct idr *p, void *ptr, int n)
2864{ 2868{
2865 int unit, err; 2869 int unit, err;
2866 2870
@@ -2871,10 +2875,24 @@ again:
2871 } 2875 }
2872 2876
2873 err = idr_get_new_above(p, ptr, n, &unit); 2877 err = idr_get_new_above(p, ptr, n, &unit);
2874 if (err == -EAGAIN) 2878 if (err < 0) {
2875 goto again; 2879 if (err == -EAGAIN)
2880 goto again;
2881 return err;
2882 }
2876 2883
2877 if (unit != n) { 2884 return unit;
2885}
2886
2887/* associate pointer with specified number */
2888static int unit_set(struct idr *p, void *ptr, int n)
2889{
2890 int unit;
2891
2892 unit = __unit_alloc(p, ptr, n);
2893 if (unit < 0)
2894 return unit;
2895 else if (unit != n) {
2878 idr_remove(p, unit); 2896 idr_remove(p, unit);
2879 return -EINVAL; 2897 return -EINVAL;
2880 } 2898 }
@@ -2885,19 +2903,7 @@ again:
2885/* get new free unit number and associate pointer with it */ 2903/* get new free unit number and associate pointer with it */
2886static int unit_get(struct idr *p, void *ptr) 2904static int unit_get(struct idr *p, void *ptr)
2887{ 2905{
2888 int unit, err; 2906 return __unit_alloc(p, ptr, 0);
2889
2890again:
2891 if (!idr_pre_get(p, GFP_KERNEL)) {
2892 printk(KERN_ERR "PPP: No free memory for idr\n");
2893 return -ENOMEM;
2894 }
2895
2896 err = idr_get_new_above(p, ptr, 0, &unit);
2897 if (err == -EAGAIN)
2898 goto again;
2899
2900 return unit;
2901} 2907}
2902 2908
2903/* put unit number back to a pool */ 2909/* put unit number back to a pool */