diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/ppp_generic.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r-- | drivers/net/ppp_generic.c | 262 |
1 files changed, 144 insertions, 118 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 736b91703b3e..4609bc0e2f56 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/device.h> | 46 | #include <linux/device.h> |
47 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
48 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
49 | #include <asm/unaligned.h> | ||
49 | #include <net/slhc_vj.h> | 50 | #include <net/slhc_vj.h> |
50 | #include <asm/atomic.h> | 51 | #include <asm/atomic.h> |
51 | 52 | ||
@@ -210,7 +211,7 @@ struct ppp_net { | |||
210 | }; | 211 | }; |
211 | 212 | ||
212 | /* Get the PPP protocol number from a skb */ | 213 | /* Get the PPP protocol number from a skb */ |
213 | #define PPP_PROTO(skb) (((skb)->data[0] << 8) + (skb)->data[1]) | 214 | #define PPP_PROTO(skb) get_unaligned_be16((skb)->data) |
214 | 215 | ||
215 | /* We limit the length of ppp->file.rq to this (arbitrary) value */ | 216 | /* We limit the length of ppp->file.rq to this (arbitrary) value */ |
216 | #define PPP_MAX_RQLEN 32 | 217 | #define PPP_MAX_RQLEN 32 |
@@ -591,8 +592,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
591 | ppp_release(NULL, file); | 592 | ppp_release(NULL, file); |
592 | err = 0; | 593 | err = 0; |
593 | } else | 594 | } else |
594 | printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%ld\n", | 595 | pr_warn("PPPIOCDETACH file->f_count=%ld\n", |
595 | atomic_long_read(&file->f_count)); | 596 | atomic_long_read(&file->f_count)); |
596 | mutex_unlock(&ppp_mutex); | 597 | mutex_unlock(&ppp_mutex); |
597 | return err; | 598 | return err; |
598 | } | 599 | } |
@@ -629,7 +630,7 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
629 | 630 | ||
630 | if (pf->kind != INTERFACE) { | 631 | if (pf->kind != INTERFACE) { |
631 | /* can't happen */ | 632 | /* can't happen */ |
632 | printk(KERN_ERR "PPP: not interface or channel??\n"); | 633 | pr_err("PPP: not interface or channel??\n"); |
633 | return -EINVAL; | 634 | return -EINVAL; |
634 | } | 635 | } |
635 | 636 | ||
@@ -703,7 +704,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
703 | } | 704 | } |
704 | vj = slhc_init(val2+1, val+1); | 705 | vj = slhc_init(val2+1, val+1); |
705 | if (!vj) { | 706 | if (!vj) { |
706 | printk(KERN_ERR "PPP: no memory (VJ compressor)\n"); | 707 | netdev_err(ppp->dev, |
708 | "PPP: no memory (VJ compressor)\n"); | ||
707 | err = -ENOMEM; | 709 | err = -ENOMEM; |
708 | break; | 710 | break; |
709 | } | 711 | } |
@@ -856,7 +858,8 @@ static const struct file_operations ppp_device_fops = { | |||
856 | .poll = ppp_poll, | 858 | .poll = ppp_poll, |
857 | .unlocked_ioctl = ppp_ioctl, | 859 | .unlocked_ioctl = ppp_ioctl, |
858 | .open = ppp_open, | 860 | .open = ppp_open, |
859 | .release = ppp_release | 861 | .release = ppp_release, |
862 | .llseek = noop_llseek, | ||
860 | }; | 863 | }; |
861 | 864 | ||
862 | static __net_init int ppp_init_net(struct net *net) | 865 | static __net_init int ppp_init_net(struct net *net) |
@@ -896,17 +899,17 @@ static int __init ppp_init(void) | |||
896 | { | 899 | { |
897 | int err; | 900 | int err; |
898 | 901 | ||
899 | printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); | 902 | pr_info("PPP generic driver version " PPP_VERSION "\n"); |
900 | 903 | ||
901 | err = register_pernet_device(&ppp_net_ops); | 904 | err = register_pernet_device(&ppp_net_ops); |
902 | if (err) { | 905 | if (err) { |
903 | printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err); | 906 | pr_err("failed to register PPP pernet device (%d)\n", err); |
904 | goto out; | 907 | goto out; |
905 | } | 908 | } |
906 | 909 | ||
907 | err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops); | 910 | err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops); |
908 | if (err) { | 911 | if (err) { |
909 | printk(KERN_ERR "failed to register PPP device (%d)\n", err); | 912 | pr_err("failed to register PPP device (%d)\n", err); |
910 | goto out_net; | 913 | goto out_net; |
911 | } | 914 | } |
912 | 915 | ||
@@ -963,8 +966,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
963 | 966 | ||
964 | pp = skb_push(skb, 2); | 967 | pp = skb_push(skb, 2); |
965 | proto = npindex_to_proto[npi]; | 968 | proto = npindex_to_proto[npi]; |
966 | pp[0] = proto >> 8; | 969 | put_unaligned_be16(proto, pp); |
967 | pp[1] = proto; | ||
968 | 970 | ||
969 | netif_stop_queue(dev); | 971 | netif_stop_queue(dev); |
970 | skb_queue_tail(&ppp->file.xq, skb); | 972 | skb_queue_tail(&ppp->file.xq, skb); |
@@ -1077,7 +1079,7 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb) | |||
1077 | new_skb = alloc_skb(new_skb_size, GFP_ATOMIC); | 1079 | new_skb = alloc_skb(new_skb_size, GFP_ATOMIC); |
1078 | if (!new_skb) { | 1080 | if (!new_skb) { |
1079 | if (net_ratelimit()) | 1081 | if (net_ratelimit()) |
1080 | printk(KERN_ERR "PPP: no memory (comp pkt)\n"); | 1082 | netdev_err(ppp->dev, "PPP: no memory (comp pkt)\n"); |
1081 | return NULL; | 1083 | return NULL; |
1082 | } | 1084 | } |
1083 | if (ppp->dev->hard_header_len > PPP_HDRLEN) | 1085 | if (ppp->dev->hard_header_len > PPP_HDRLEN) |
@@ -1107,7 +1109,7 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb) | |||
1107 | * the same number. | 1109 | * the same number. |
1108 | */ | 1110 | */ |
1109 | if (net_ratelimit()) | 1111 | if (net_ratelimit()) |
1110 | printk(KERN_ERR "ppp: compressor dropped pkt\n"); | 1112 | netdev_err(ppp->dev, "ppp: compressor dropped pkt\n"); |
1111 | kfree_skb(skb); | 1113 | kfree_skb(skb); |
1112 | kfree_skb(new_skb); | 1114 | kfree_skb(new_skb); |
1113 | new_skb = NULL; | 1115 | new_skb = NULL; |
@@ -1135,17 +1137,17 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1135 | a four-byte PPP header on each packet */ | 1137 | a four-byte PPP header on each packet */ |
1136 | *skb_push(skb, 2) = 1; | 1138 | *skb_push(skb, 2) = 1; |
1137 | if (ppp->pass_filter && | 1139 | if (ppp->pass_filter && |
1138 | sk_run_filter(skb, ppp->pass_filter, | 1140 | sk_run_filter(skb, ppp->pass_filter) == 0) { |
1139 | ppp->pass_len) == 0) { | ||
1140 | if (ppp->debug & 1) | 1141 | if (ppp->debug & 1) |
1141 | printk(KERN_DEBUG "PPP: outbound frame not passed\n"); | 1142 | netdev_printk(KERN_DEBUG, ppp->dev, |
1143 | "PPP: outbound frame " | ||
1144 | "not passed\n"); | ||
1142 | kfree_skb(skb); | 1145 | kfree_skb(skb); |
1143 | return; | 1146 | return; |
1144 | } | 1147 | } |
1145 | /* if this packet passes the active filter, record the time */ | 1148 | /* if this packet passes the active filter, record the time */ |
1146 | if (!(ppp->active_filter && | 1149 | if (!(ppp->active_filter && |
1147 | sk_run_filter(skb, ppp->active_filter, | 1150 | sk_run_filter(skb, ppp->active_filter) == 0)) |
1148 | ppp->active_len) == 0)) | ||
1149 | ppp->last_xmit = jiffies; | 1151 | ppp->last_xmit = jiffies; |
1150 | skb_pull(skb, 2); | 1152 | skb_pull(skb, 2); |
1151 | #else | 1153 | #else |
@@ -1165,7 +1167,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1165 | new_skb = alloc_skb(skb->len + ppp->dev->hard_header_len - 2, | 1167 | new_skb = alloc_skb(skb->len + ppp->dev->hard_header_len - 2, |
1166 | GFP_ATOMIC); | 1168 | GFP_ATOMIC); |
1167 | if (!new_skb) { | 1169 | if (!new_skb) { |
1168 | printk(KERN_ERR "PPP: no memory (VJ comp pkt)\n"); | 1170 | netdev_err(ppp->dev, "PPP: no memory (VJ comp pkt)\n"); |
1169 | goto drop; | 1171 | goto drop; |
1170 | } | 1172 | } |
1171 | skb_reserve(new_skb, ppp->dev->hard_header_len - 2); | 1173 | skb_reserve(new_skb, ppp->dev->hard_header_len - 2); |
@@ -1203,7 +1205,9 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1203 | proto != PPP_LCP && proto != PPP_CCP) { | 1205 | proto != PPP_LCP && proto != PPP_CCP) { |
1204 | if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) { | 1206 | if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) { |
1205 | if (net_ratelimit()) | 1207 | if (net_ratelimit()) |
1206 | printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n"); | 1208 | netdev_err(ppp->dev, |
1209 | "ppp: compression required but " | ||
1210 | "down - pkt dropped.\n"); | ||
1207 | goto drop; | 1211 | goto drop; |
1208 | } | 1212 | } |
1209 | skb = pad_compress_skb(ppp, skb); | 1213 | skb = pad_compress_skb(ppp, skb); |
@@ -1284,6 +1288,11 @@ ppp_push(struct ppp *ppp) | |||
1284 | } | 1288 | } |
1285 | 1289 | ||
1286 | #ifdef CONFIG_PPP_MULTILINK | 1290 | #ifdef CONFIG_PPP_MULTILINK |
1291 | static bool mp_protocol_compress __read_mostly = true; | ||
1292 | module_param(mp_protocol_compress, bool, S_IRUGO | S_IWUSR); | ||
1293 | MODULE_PARM_DESC(mp_protocol_compress, | ||
1294 | "compress protocol id in multilink fragments"); | ||
1295 | |||
1287 | /* | 1296 | /* |
1288 | * Divide a packet to be transmitted into fragments and | 1297 | * Divide a packet to be transmitted into fragments and |
1289 | * send them out the individual links. | 1298 | * send them out the individual links. |
@@ -1346,10 +1355,10 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1346 | if (nfree == 0 || nfree < navail / 2) | 1355 | if (nfree == 0 || nfree < navail / 2) |
1347 | return 0; /* can't take now, leave it in xmit_pending */ | 1356 | return 0; /* can't take now, leave it in xmit_pending */ |
1348 | 1357 | ||
1349 | /* Do protocol field compression (XXX this should be optional) */ | 1358 | /* Do protocol field compression */ |
1350 | p = skb->data; | 1359 | p = skb->data; |
1351 | len = skb->len; | 1360 | len = skb->len; |
1352 | if (*p == 0) { | 1361 | if (*p == 0 && mp_protocol_compress) { |
1353 | ++p; | 1362 | ++p; |
1354 | --len; | 1363 | --len; |
1355 | } | 1364 | } |
@@ -1439,7 +1448,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1439 | 1448 | ||
1440 | /* | 1449 | /* |
1441 | *check if we are on the last channel or | 1450 | *check if we are on the last channel or |
1442 | *we exceded the lenght of the data to | 1451 | *we exceded the length of the data to |
1443 | *fragment | 1452 | *fragment |
1444 | */ | 1453 | */ |
1445 | if ((nfree <= 0) || (flen > len)) | 1454 | if ((nfree <= 0) || (flen > len)) |
@@ -1469,8 +1478,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1469 | q = skb_put(frag, flen + hdrlen); | 1478 | q = skb_put(frag, flen + hdrlen); |
1470 | 1479 | ||
1471 | /* make the MP header */ | 1480 | /* make the MP header */ |
1472 | q[0] = PPP_MP >> 8; | 1481 | put_unaligned_be16(PPP_MP, q); |
1473 | q[1] = PPP_MP; | ||
1474 | if (ppp->flags & SC_MP_XSHORTSEQ) { | 1482 | if (ppp->flags & SC_MP_XSHORTSEQ) { |
1475 | q[2] = bits + ((ppp->nxseq >> 8) & 0xf); | 1483 | q[2] = bits + ((ppp->nxseq >> 8) & 0xf); |
1476 | q[3] = ppp->nxseq; | 1484 | q[3] = ppp->nxseq; |
@@ -1502,7 +1510,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1502 | noskb: | 1510 | noskb: |
1503 | spin_unlock_bh(&pch->downl); | 1511 | spin_unlock_bh(&pch->downl); |
1504 | if (ppp->debug & 1) | 1512 | if (ppp->debug & 1) |
1505 | printk(KERN_ERR "PPP: no memory (fragment)\n"); | 1513 | netdev_err(ppp->dev, "PPP: no memory (fragment)\n"); |
1506 | ++ppp->dev->stats.tx_errors; | 1514 | ++ppp->dev->stats.tx_errors; |
1507 | ++ppp->nxseq; | 1515 | ++ppp->nxseq; |
1508 | return 1; /* abandon the frame */ | 1516 | return 1; /* abandon the frame */ |
@@ -1547,9 +1555,11 @@ ppp_channel_push(struct channel *pch) | |||
1547 | * Receive-side routines. | 1555 | * Receive-side routines. |
1548 | */ | 1556 | */ |
1549 | 1557 | ||
1550 | /* misuse a few fields of the skb for MP reconstruction */ | 1558 | struct ppp_mp_skb_parm { |
1551 | #define sequence priority | 1559 | u32 sequence; |
1552 | #define BEbits cb[0] | 1560 | u8 BEbits; |
1561 | }; | ||
1562 | #define PPP_MP_CB(skb) ((struct ppp_mp_skb_parm *)((skb)->cb)) | ||
1553 | 1563 | ||
1554 | static inline void | 1564 | static inline void |
1555 | ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | 1565 | ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) |
@@ -1681,7 +1691,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1681 | /* copy to a new sk_buff with more tailroom */ | 1691 | /* copy to a new sk_buff with more tailroom */ |
1682 | ns = dev_alloc_skb(skb->len + 128); | 1692 | ns = dev_alloc_skb(skb->len + 128); |
1683 | if (!ns) { | 1693 | if (!ns) { |
1684 | printk(KERN_ERR"PPP: no memory (VJ decomp)\n"); | 1694 | netdev_err(ppp->dev, "PPP: no memory " |
1695 | "(VJ decomp)\n"); | ||
1685 | goto err; | 1696 | goto err; |
1686 | } | 1697 | } |
1687 | skb_reserve(ns, 2); | 1698 | skb_reserve(ns, 2); |
@@ -1694,7 +1705,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1694 | 1705 | ||
1695 | len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); | 1706 | len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); |
1696 | if (len <= 0) { | 1707 | if (len <= 0) { |
1697 | printk(KERN_DEBUG "PPP: VJ decompression error\n"); | 1708 | netdev_printk(KERN_DEBUG, ppp->dev, |
1709 | "PPP: VJ decompression error\n"); | ||
1698 | goto err; | 1710 | goto err; |
1699 | } | 1711 | } |
1700 | len += 2; | 1712 | len += 2; |
@@ -1716,7 +1728,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1716 | goto err; | 1728 | goto err; |
1717 | 1729 | ||
1718 | if (slhc_remember(ppp->vj, skb->data + 2, skb->len - 2) <= 0) { | 1730 | if (slhc_remember(ppp->vj, skb->data + 2, skb->len - 2) <= 0) { |
1719 | printk(KERN_ERR "PPP: VJ uncompressed error\n"); | 1731 | netdev_err(ppp->dev, "PPP: VJ uncompressed error\n"); |
1720 | goto err; | 1732 | goto err; |
1721 | } | 1733 | } |
1722 | proto = PPP_IP; | 1734 | proto = PPP_IP; |
@@ -1755,17 +1767,16 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1755 | 1767 | ||
1756 | *skb_push(skb, 2) = 0; | 1768 | *skb_push(skb, 2) = 0; |
1757 | if (ppp->pass_filter && | 1769 | if (ppp->pass_filter && |
1758 | sk_run_filter(skb, ppp->pass_filter, | 1770 | sk_run_filter(skb, ppp->pass_filter) == 0) { |
1759 | ppp->pass_len) == 0) { | ||
1760 | if (ppp->debug & 1) | 1771 | if (ppp->debug & 1) |
1761 | printk(KERN_DEBUG "PPP: inbound frame " | 1772 | netdev_printk(KERN_DEBUG, ppp->dev, |
1762 | "not passed\n"); | 1773 | "PPP: inbound frame " |
1774 | "not passed\n"); | ||
1763 | kfree_skb(skb); | 1775 | kfree_skb(skb); |
1764 | return; | 1776 | return; |
1765 | } | 1777 | } |
1766 | if (!(ppp->active_filter && | 1778 | if (!(ppp->active_filter && |
1767 | sk_run_filter(skb, ppp->active_filter, | 1779 | sk_run_filter(skb, ppp->active_filter) == 0)) |
1768 | ppp->active_len) == 0)) | ||
1769 | ppp->last_recv = jiffies; | 1780 | ppp->last_recv = jiffies; |
1770 | __skb_pull(skb, 2); | 1781 | __skb_pull(skb, 2); |
1771 | } else | 1782 | } else |
@@ -1818,7 +1829,8 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1818 | 1829 | ||
1819 | ns = dev_alloc_skb(obuff_size); | 1830 | ns = dev_alloc_skb(obuff_size); |
1820 | if (!ns) { | 1831 | if (!ns) { |
1821 | printk(KERN_ERR "ppp_decompress_frame: no memory\n"); | 1832 | netdev_err(ppp->dev, "ppp_decompress_frame: " |
1833 | "no memory\n"); | ||
1822 | goto err; | 1834 | goto err; |
1823 | } | 1835 | } |
1824 | /* the decompressor still expects the A/C bytes in the hdr */ | 1836 | /* the decompressor still expects the A/C bytes in the hdr */ |
@@ -1878,13 +1890,13 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1878 | seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5]; | 1890 | seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5]; |
1879 | mask = 0xffffff; | 1891 | mask = 0xffffff; |
1880 | } | 1892 | } |
1881 | skb->BEbits = skb->data[2]; | 1893 | PPP_MP_CB(skb)->BEbits = skb->data[2]; |
1882 | skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */ | 1894 | skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */ |
1883 | 1895 | ||
1884 | /* | 1896 | /* |
1885 | * Do protocol ID decompression on the first fragment of each packet. | 1897 | * Do protocol ID decompression on the first fragment of each packet. |
1886 | */ | 1898 | */ |
1887 | if ((skb->BEbits & B) && (skb->data[0] & 1)) | 1899 | if ((PPP_MP_CB(skb)->BEbits & B) && (skb->data[0] & 1)) |
1888 | *skb_push(skb, 1) = 0; | 1900 | *skb_push(skb, 1) = 0; |
1889 | 1901 | ||
1890 | /* | 1902 | /* |
@@ -1896,7 +1908,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1896 | seq += mask + 1; | 1908 | seq += mask + 1; |
1897 | else if ((int)(seq - ppp->minseq) > (int)(mask >> 1)) | 1909 | else if ((int)(seq - ppp->minseq) > (int)(mask >> 1)) |
1898 | seq -= mask + 1; /* should never happen */ | 1910 | seq -= mask + 1; /* should never happen */ |
1899 | skb->sequence = seq; | 1911 | PPP_MP_CB(skb)->sequence = seq; |
1900 | pch->lastseq = seq; | 1912 | pch->lastseq = seq; |
1901 | 1913 | ||
1902 | /* | 1914 | /* |
@@ -1932,8 +1944,8 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1932 | before the start of the queue. */ | 1944 | before the start of the queue. */ |
1933 | if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { | 1945 | if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { |
1934 | struct sk_buff *mskb = skb_peek(&ppp->mrq); | 1946 | struct sk_buff *mskb = skb_peek(&ppp->mrq); |
1935 | if (seq_before(ppp->minseq, mskb->sequence)) | 1947 | if (seq_before(ppp->minseq, PPP_MP_CB(mskb)->sequence)) |
1936 | ppp->minseq = mskb->sequence; | 1948 | ppp->minseq = PPP_MP_CB(mskb)->sequence; |
1937 | } | 1949 | } |
1938 | 1950 | ||
1939 | /* Pull completed packets off the queue and receive them. */ | 1951 | /* Pull completed packets off the queue and receive them. */ |
@@ -1963,12 +1975,12 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb) | |||
1963 | { | 1975 | { |
1964 | struct sk_buff *p; | 1976 | struct sk_buff *p; |
1965 | struct sk_buff_head *list = &ppp->mrq; | 1977 | struct sk_buff_head *list = &ppp->mrq; |
1966 | u32 seq = skb->sequence; | 1978 | u32 seq = PPP_MP_CB(skb)->sequence; |
1967 | 1979 | ||
1968 | /* N.B. we don't need to lock the list lock because we have the | 1980 | /* N.B. we don't need to lock the list lock because we have the |
1969 | ppp unit receive-side lock. */ | 1981 | ppp unit receive-side lock. */ |
1970 | skb_queue_walk(list, p) { | 1982 | skb_queue_walk(list, p) { |
1971 | if (seq_before(seq, p->sequence)) | 1983 | if (seq_before(seq, PPP_MP_CB(p)->sequence)) |
1972 | break; | 1984 | break; |
1973 | } | 1985 | } |
1974 | __skb_queue_before(list, p, skb); | 1986 | __skb_queue_before(list, p, skb); |
@@ -1986,7 +1998,7 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
1986 | u32 seq = ppp->nextseq; | 1998 | u32 seq = ppp->nextseq; |
1987 | u32 minseq = ppp->minseq; | 1999 | u32 minseq = ppp->minseq; |
1988 | struct sk_buff_head *list = &ppp->mrq; | 2000 | struct sk_buff_head *list = &ppp->mrq; |
1989 | struct sk_buff *p, *next; | 2001 | struct sk_buff *p, *tmp; |
1990 | struct sk_buff *head, *tail; | 2002 | struct sk_buff *head, *tail; |
1991 | struct sk_buff *skb = NULL; | 2003 | struct sk_buff *skb = NULL; |
1992 | int lost = 0, len = 0; | 2004 | int lost = 0, len = 0; |
@@ -1995,26 +2007,27 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
1995 | return NULL; | 2007 | return NULL; |
1996 | head = list->next; | 2008 | head = list->next; |
1997 | tail = NULL; | 2009 | tail = NULL; |
1998 | for (p = head; p != (struct sk_buff *) list; p = next) { | 2010 | skb_queue_walk_safe(list, p, tmp) { |
1999 | next = p->next; | 2011 | again: |
2000 | if (seq_before(p->sequence, seq)) { | 2012 | if (seq_before(PPP_MP_CB(p)->sequence, seq)) { |
2001 | /* this can't happen, anyway ignore the skb */ | 2013 | /* this can't happen, anyway ignore the skb */ |
2002 | printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n", | 2014 | netdev_err(ppp->dev, "ppp_mp_reconstruct bad " |
2003 | p->sequence, seq); | 2015 | "seq %u < %u\n", |
2004 | head = next; | 2016 | PPP_MP_CB(p)->sequence, seq); |
2017 | __skb_unlink(p, list); | ||
2018 | kfree_skb(p); | ||
2005 | continue; | 2019 | continue; |
2006 | } | 2020 | } |
2007 | if (p->sequence != seq) { | 2021 | if (PPP_MP_CB(p)->sequence != seq) { |
2008 | /* Fragment `seq' is missing. If it is after | 2022 | /* Fragment `seq' is missing. If it is after |
2009 | minseq, it might arrive later, so stop here. */ | 2023 | minseq, it might arrive later, so stop here. */ |
2010 | if (seq_after(seq, minseq)) | 2024 | if (seq_after(seq, minseq)) |
2011 | break; | 2025 | break; |
2012 | /* Fragment `seq' is lost, keep going. */ | 2026 | /* Fragment `seq' is lost, keep going. */ |
2013 | lost = 1; | 2027 | lost = 1; |
2014 | seq = seq_before(minseq, p->sequence)? | 2028 | seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? |
2015 | minseq + 1: p->sequence; | 2029 | minseq + 1: PPP_MP_CB(p)->sequence; |
2016 | next = p; | 2030 | goto again; |
2017 | continue; | ||
2018 | } | 2031 | } |
2019 | 2032 | ||
2020 | /* | 2033 | /* |
@@ -2026,7 +2039,7 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2026 | */ | 2039 | */ |
2027 | 2040 | ||
2028 | /* B bit set indicates this fragment starts a packet */ | 2041 | /* B bit set indicates this fragment starts a packet */ |
2029 | if (p->BEbits & B) { | 2042 | if (PPP_MP_CB(p)->BEbits & B) { |
2030 | head = p; | 2043 | head = p; |
2031 | lost = 0; | 2044 | lost = 0; |
2032 | len = 0; | 2045 | len = 0; |
@@ -2035,20 +2048,13 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2035 | len += p->len; | 2048 | len += p->len; |
2036 | 2049 | ||
2037 | /* Got a complete packet yet? */ | 2050 | /* Got a complete packet yet? */ |
2038 | if (lost == 0 && (p->BEbits & E) && (head->BEbits & B)) { | 2051 | if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) && |
2052 | (PPP_MP_CB(head)->BEbits & B)) { | ||
2039 | if (len > ppp->mrru + 2) { | 2053 | if (len > ppp->mrru + 2) { |
2040 | ++ppp->dev->stats.rx_length_errors; | 2054 | ++ppp->dev->stats.rx_length_errors; |
2041 | printk(KERN_DEBUG "PPP: reconstructed packet" | 2055 | netdev_printk(KERN_DEBUG, ppp->dev, |
2042 | " is too long (%d)\n", len); | 2056 | "PPP: reconstructed packet" |
2043 | } else if (p == head) { | 2057 | " is too long (%d)\n", len); |
2044 | /* fragment is complete packet - reuse skb */ | ||
2045 | tail = p; | ||
2046 | skb = skb_get(p); | ||
2047 | break; | ||
2048 | } else if ((skb = dev_alloc_skb(len)) == NULL) { | ||
2049 | ++ppp->dev->stats.rx_missed_errors; | ||
2050 | printk(KERN_DEBUG "PPP: no memory for " | ||
2051 | "reconstructed packet"); | ||
2052 | } else { | 2058 | } else { |
2053 | tail = p; | 2059 | tail = p; |
2054 | break; | 2060 | break; |
@@ -2061,9 +2067,17 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2061 | * and we haven't found a complete valid packet yet, | 2067 | * and we haven't found a complete valid packet yet, |
2062 | * we can discard up to and including this fragment. | 2068 | * we can discard up to and including this fragment. |
2063 | */ | 2069 | */ |
2064 | if (p->BEbits & E) | 2070 | if (PPP_MP_CB(p)->BEbits & E) { |
2065 | head = next; | 2071 | struct sk_buff *tmp2; |
2066 | 2072 | ||
2073 | skb_queue_reverse_walk_from_safe(list, p, tmp2) { | ||
2074 | __skb_unlink(p, list); | ||
2075 | kfree_skb(p); | ||
2076 | } | ||
2077 | head = skb_peek(list); | ||
2078 | if (!head) | ||
2079 | break; | ||
2080 | } | ||
2067 | ++seq; | 2081 | ++seq; |
2068 | } | 2082 | } |
2069 | 2083 | ||
@@ -2071,27 +2085,39 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2071 | if (tail != NULL) { | 2085 | if (tail != NULL) { |
2072 | /* If we have discarded any fragments, | 2086 | /* If we have discarded any fragments, |
2073 | signal a receive error. */ | 2087 | signal a receive error. */ |
2074 | if (head->sequence != ppp->nextseq) { | 2088 | if (PPP_MP_CB(head)->sequence != ppp->nextseq) { |
2075 | if (ppp->debug & 1) | 2089 | if (ppp->debug & 1) |
2076 | printk(KERN_DEBUG " missed pkts %u..%u\n", | 2090 | netdev_printk(KERN_DEBUG, ppp->dev, |
2077 | ppp->nextseq, head->sequence-1); | 2091 | " missed pkts %u..%u\n", |
2092 | ppp->nextseq, | ||
2093 | PPP_MP_CB(head)->sequence-1); | ||
2078 | ++ppp->dev->stats.rx_dropped; | 2094 | ++ppp->dev->stats.rx_dropped; |
2079 | ppp_receive_error(ppp); | 2095 | ppp_receive_error(ppp); |
2080 | } | 2096 | } |
2081 | 2097 | ||
2082 | if (head != tail) | 2098 | skb = head; |
2083 | /* copy to a single skb */ | 2099 | if (head != tail) { |
2084 | for (p = head; p != tail->next; p = p->next) | 2100 | struct sk_buff **fragpp = &skb_shinfo(skb)->frag_list; |
2085 | skb_copy_bits(p, 0, skb_put(skb, p->len), p->len); | 2101 | p = skb_queue_next(list, head); |
2086 | ppp->nextseq = tail->sequence + 1; | 2102 | __skb_unlink(skb, list); |
2087 | head = tail->next; | 2103 | skb_queue_walk_from_safe(list, p, tmp) { |
2088 | } | 2104 | __skb_unlink(p, list); |
2105 | *fragpp = p; | ||
2106 | p->next = NULL; | ||
2107 | fragpp = &p->next; | ||
2108 | |||
2109 | skb->len += p->len; | ||
2110 | skb->data_len += p->len; | ||
2111 | skb->truesize += p->len; | ||
2112 | |||
2113 | if (p == tail) | ||
2114 | break; | ||
2115 | } | ||
2116 | } else { | ||
2117 | __skb_unlink(skb, list); | ||
2118 | } | ||
2089 | 2119 | ||
2090 | /* Discard all the skbuffs that we have copied the data out of | 2120 | ppp->nextseq = PPP_MP_CB(tail)->sequence + 1; |
2091 | or that we can't use. */ | ||
2092 | while ((p = list->next) != head) { | ||
2093 | __skb_unlink(p, list); | ||
2094 | kfree_skb(p); | ||
2095 | } | 2121 | } |
2096 | 2122 | ||
2097 | return skb; | 2123 | return skb; |
@@ -2579,16 +2605,16 @@ ppp_create_interface(struct net *net, int unit, int *retp) | |||
2579 | */ | 2605 | */ |
2580 | dev_net_set(dev, net); | 2606 | dev_net_set(dev, net); |
2581 | 2607 | ||
2582 | ret = -EEXIST; | ||
2583 | mutex_lock(&pn->all_ppp_mutex); | 2608 | mutex_lock(&pn->all_ppp_mutex); |
2584 | 2609 | ||
2585 | if (unit < 0) { | 2610 | if (unit < 0) { |
2586 | unit = unit_get(&pn->units_idr, ppp); | 2611 | unit = unit_get(&pn->units_idr, ppp); |
2587 | if (unit < 0) { | 2612 | if (unit < 0) { |
2588 | *retp = unit; | 2613 | ret = unit; |
2589 | goto out2; | 2614 | goto out2; |
2590 | } | 2615 | } |
2591 | } else { | 2616 | } else { |
2617 | ret = -EEXIST; | ||
2592 | if (unit_find(&pn->units_idr, unit)) | 2618 | if (unit_find(&pn->units_idr, unit)) |
2593 | goto out2; /* unit already exists */ | 2619 | goto out2; /* unit already exists */ |
2594 | /* | 2620 | /* |
@@ -2612,8 +2638,8 @@ ppp_create_interface(struct net *net, int unit, int *retp) | |||
2612 | ret = register_netdev(dev); | 2638 | ret = register_netdev(dev); |
2613 | if (ret != 0) { | 2639 | if (ret != 0) { |
2614 | unit_put(&pn->units_idr, unit); | 2640 | unit_put(&pn->units_idr, unit); |
2615 | printk(KERN_ERR "PPP: couldn't register device %s (%d)\n", | 2641 | netdev_err(ppp->dev, "PPP: couldn't register device %s (%d)\n", |
2616 | dev->name, ret); | 2642 | dev->name, ret); |
2617 | goto out2; | 2643 | goto out2; |
2618 | } | 2644 | } |
2619 | 2645 | ||
@@ -2663,10 +2689,10 @@ static void ppp_shutdown_interface(struct ppp *ppp) | |||
2663 | ppp->closing = 1; | 2689 | ppp->closing = 1; |
2664 | ppp_unlock(ppp); | 2690 | ppp_unlock(ppp); |
2665 | unregister_netdev(ppp->dev); | 2691 | unregister_netdev(ppp->dev); |
2692 | unit_put(&pn->units_idr, ppp->file.index); | ||
2666 | } else | 2693 | } else |
2667 | ppp_unlock(ppp); | 2694 | ppp_unlock(ppp); |
2668 | 2695 | ||
2669 | unit_put(&pn->units_idr, ppp->file.index); | ||
2670 | ppp->file.dead = 1; | 2696 | ppp->file.dead = 1; |
2671 | ppp->owner = NULL; | 2697 | ppp->owner = NULL; |
2672 | wake_up_interruptible(&ppp->file.rwait); | 2698 | wake_up_interruptible(&ppp->file.rwait); |
@@ -2685,9 +2711,9 @@ static void ppp_destroy_interface(struct ppp *ppp) | |||
2685 | 2711 | ||
2686 | if (!ppp->file.dead || ppp->n_channels) { | 2712 | if (!ppp->file.dead || ppp->n_channels) { |
2687 | /* "can't happen" */ | 2713 | /* "can't happen" */ |
2688 | printk(KERN_ERR "ppp: destroying ppp struct %p but dead=%d " | 2714 | netdev_err(ppp->dev, "ppp: destroying ppp struct %p " |
2689 | "n_channels=%d !\n", ppp, ppp->file.dead, | 2715 | "but dead=%d n_channels=%d !\n", |
2690 | ppp->n_channels); | 2716 | ppp, ppp->file.dead, ppp->n_channels); |
2691 | return; | 2717 | return; |
2692 | } | 2718 | } |
2693 | 2719 | ||
@@ -2829,8 +2855,7 @@ static void ppp_destroy_channel(struct channel *pch) | |||
2829 | 2855 | ||
2830 | if (!pch->file.dead) { | 2856 | if (!pch->file.dead) { |
2831 | /* "can't happen" */ | 2857 | /* "can't happen" */ |
2832 | printk(KERN_ERR "ppp: destroying undead channel %p !\n", | 2858 | pr_err("ppp: destroying undead channel %p !\n", pch); |
2833 | pch); | ||
2834 | return; | 2859 | return; |
2835 | } | 2860 | } |
2836 | skb_queue_purge(&pch->file.xq); | 2861 | skb_queue_purge(&pch->file.xq); |
@@ -2842,7 +2867,7 @@ static void __exit ppp_cleanup(void) | |||
2842 | { | 2867 | { |
2843 | /* should never happen */ | 2868 | /* should never happen */ |
2844 | if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count)) | 2869 | if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count)) |
2845 | printk(KERN_ERR "PPP: removing module but units remain!\n"); | 2870 | pr_err("PPP: removing module but units remain!\n"); |
2846 | unregister_chrdev(PPP_MAJOR, "ppp"); | 2871 | unregister_chrdev(PPP_MAJOR, "ppp"); |
2847 | device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); | 2872 | device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); |
2848 | class_destroy(ppp_class); | 2873 | class_destroy(ppp_class); |
@@ -2854,22 +2879,35 @@ static void __exit ppp_cleanup(void) | |||
2854 | * by holding all_ppp_mutex | 2879 | * by holding all_ppp_mutex |
2855 | */ | 2880 | */ |
2856 | 2881 | ||
2857 | /* associate pointer with specified number */ | 2882 | static int __unit_alloc(struct idr *p, void *ptr, int n) |
2858 | static int unit_set(struct idr *p, void *ptr, int n) | ||
2859 | { | 2883 | { |
2860 | int unit, err; | 2884 | int unit, err; |
2861 | 2885 | ||
2862 | again: | 2886 | again: |
2863 | if (!idr_pre_get(p, GFP_KERNEL)) { | 2887 | if (!idr_pre_get(p, GFP_KERNEL)) { |
2864 | printk(KERN_ERR "PPP: No free memory for idr\n"); | 2888 | pr_err("PPP: No free memory for idr\n"); |
2865 | return -ENOMEM; | 2889 | return -ENOMEM; |
2866 | } | 2890 | } |
2867 | 2891 | ||
2868 | err = idr_get_new_above(p, ptr, n, &unit); | 2892 | err = idr_get_new_above(p, ptr, n, &unit); |
2869 | if (err == -EAGAIN) | 2893 | if (err < 0) { |
2870 | goto again; | 2894 | if (err == -EAGAIN) |
2895 | goto again; | ||
2896 | return err; | ||
2897 | } | ||
2871 | 2898 | ||
2872 | if (unit != n) { | 2899 | return unit; |
2900 | } | ||
2901 | |||
2902 | /* associate pointer with specified number */ | ||
2903 | static int unit_set(struct idr *p, void *ptr, int n) | ||
2904 | { | ||
2905 | int unit; | ||
2906 | |||
2907 | unit = __unit_alloc(p, ptr, n); | ||
2908 | if (unit < 0) | ||
2909 | return unit; | ||
2910 | else if (unit != n) { | ||
2873 | idr_remove(p, unit); | 2911 | idr_remove(p, unit); |
2874 | return -EINVAL; | 2912 | return -EINVAL; |
2875 | } | 2913 | } |
@@ -2880,19 +2918,7 @@ again: | |||
2880 | /* get new free unit number and associate pointer with it */ | 2918 | /* get new free unit number and associate pointer with it */ |
2881 | static int unit_get(struct idr *p, void *ptr) | 2919 | static int unit_get(struct idr *p, void *ptr) |
2882 | { | 2920 | { |
2883 | int unit, err; | 2921 | return __unit_alloc(p, ptr, 0); |
2884 | |||
2885 | again: | ||
2886 | if (!idr_pre_get(p, GFP_KERNEL)) { | ||
2887 | printk(KERN_ERR "PPP: No free memory for idr\n"); | ||
2888 | return -ENOMEM; | ||
2889 | } | ||
2890 | |||
2891 | err = idr_get_new_above(p, ptr, 0, &unit); | ||
2892 | if (err == -EAGAIN) | ||
2893 | goto again; | ||
2894 | |||
2895 | return unit; | ||
2896 | } | 2922 | } |
2897 | 2923 | ||
2898 | /* put unit number back to a pool */ | 2924 | /* put unit number back to a pool */ |