aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/skbuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r--net/core/skbuff.c178
1 files changed, 161 insertions, 17 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index bb7210f4005e..8e5044ba3ab6 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -172,9 +172,9 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
172 shinfo = skb_shinfo(skb); 172 shinfo = skb_shinfo(skb);
173 atomic_set(&shinfo->dataref, 1); 173 atomic_set(&shinfo->dataref, 1);
174 shinfo->nr_frags = 0; 174 shinfo->nr_frags = 0;
175 shinfo->tso_size = 0; 175 shinfo->gso_size = 0;
176 shinfo->tso_segs = 0; 176 shinfo->gso_segs = 0;
177 shinfo->ufo_size = 0; 177 shinfo->gso_type = 0;
178 shinfo->ip6_frag_id = 0; 178 shinfo->ip6_frag_id = 0;
179 shinfo->frag_list = NULL; 179 shinfo->frag_list = NULL;
180 180
@@ -238,8 +238,9 @@ struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
238 238
239 atomic_set(&(skb_shinfo(skb)->dataref), 1); 239 atomic_set(&(skb_shinfo(skb)->dataref), 1);
240 skb_shinfo(skb)->nr_frags = 0; 240 skb_shinfo(skb)->nr_frags = 0;
241 skb_shinfo(skb)->tso_size = 0; 241 skb_shinfo(skb)->gso_size = 0;
242 skb_shinfo(skb)->tso_segs = 0; 242 skb_shinfo(skb)->gso_segs = 0;
243 skb_shinfo(skb)->gso_type = 0;
243 skb_shinfo(skb)->frag_list = NULL; 244 skb_shinfo(skb)->frag_list = NULL;
244out: 245out:
245 return skb; 246 return skb;
@@ -528,8 +529,9 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
528#endif 529#endif
529 skb_copy_secmark(new, old); 530 skb_copy_secmark(new, old);
530 atomic_set(&new->users, 1); 531 atomic_set(&new->users, 1);
531 skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size; 532 skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
532 skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs; 533 skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
534 skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
533} 535}
534 536
535/** 537/**
@@ -781,24 +783,40 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
781 * filled. Used by network drivers which may DMA or transfer data 783 * filled. Used by network drivers which may DMA or transfer data
782 * beyond the buffer end onto the wire. 784 * beyond the buffer end onto the wire.
783 * 785 *
784 * May return NULL in out of memory cases. 786 * May return error in out of memory cases. The skb is freed on error.
785 */ 787 */
786 788
787struct sk_buff *skb_pad(struct sk_buff *skb, int pad) 789int skb_pad(struct sk_buff *skb, int pad)
788{ 790{
789 struct sk_buff *nskb; 791 int err;
792 int ntail;
790 793
791 /* If the skbuff is non linear tailroom is always zero.. */ 794 /* If the skbuff is non linear tailroom is always zero.. */
792 if (skb_tailroom(skb) >= pad) { 795 if (!skb_cloned(skb) && skb_tailroom(skb) >= pad) {
793 memset(skb->data+skb->len, 0, pad); 796 memset(skb->data+skb->len, 0, pad);
794 return skb; 797 return 0;
795 } 798 }
796 799
797 nskb = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb) + pad, GFP_ATOMIC); 800 ntail = skb->data_len + pad - (skb->end - skb->tail);
801 if (likely(skb_cloned(skb) || ntail > 0)) {
802 err = pskb_expand_head(skb, 0, ntail, GFP_ATOMIC);
803 if (unlikely(err))
804 goto free_skb;
805 }
806
807 /* FIXME: The use of this function with non-linear skb's really needs
808 * to be audited.
809 */
810 err = skb_linearize(skb);
811 if (unlikely(err))
812 goto free_skb;
813
814 memset(skb->data + skb->len, 0, pad);
815 return 0;
816
817free_skb:
798 kfree_skb(skb); 818 kfree_skb(skb);
799 if (nskb) 819 return err;
800 memset(nskb->data+nskb->len, 0, pad);
801 return nskb;
802} 820}
803 821
804/* Trims skb to length len. It can change skb pointers. 822/* Trims skb to length len. It can change skb pointers.
@@ -1824,6 +1842,132 @@ unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
1824 1842
1825EXPORT_SYMBOL_GPL(skb_pull_rcsum); 1843EXPORT_SYMBOL_GPL(skb_pull_rcsum);
1826 1844
1845/**
1846 * skb_segment - Perform protocol segmentation on skb.
1847 * @skb: buffer to segment
1848 * @sg: whether scatter-gather can be used for generated segments
1849 *
1850 * This function performs segmentation on the given skb. It returns
1851 * the segment at the given position. It returns NULL if there are
1852 * no more segments to generate, or when an error is encountered.
1853 */
1854struct sk_buff *skb_segment(struct sk_buff *skb, int sg)
1855{
1856 struct sk_buff *segs = NULL;
1857 struct sk_buff *tail = NULL;
1858 unsigned int mss = skb_shinfo(skb)->gso_size;
1859 unsigned int doffset = skb->data - skb->mac.raw;
1860 unsigned int offset = doffset;
1861 unsigned int headroom;
1862 unsigned int len;
1863 int nfrags = skb_shinfo(skb)->nr_frags;
1864 int err = -ENOMEM;
1865 int i = 0;
1866 int pos;
1867
1868 __skb_push(skb, doffset);
1869 headroom = skb_headroom(skb);
1870 pos = skb_headlen(skb);
1871
1872 do {
1873 struct sk_buff *nskb;
1874 skb_frag_t *frag;
1875 int hsize, nsize;
1876 int k;
1877 int size;
1878
1879 len = skb->len - offset;
1880 if (len > mss)
1881 len = mss;
1882
1883 hsize = skb_headlen(skb) - offset;
1884 if (hsize < 0)
1885 hsize = 0;
1886 nsize = hsize + doffset;
1887 if (nsize > len + doffset || !sg)
1888 nsize = len + doffset;
1889
1890 nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
1891 if (unlikely(!nskb))
1892 goto err;
1893
1894 if (segs)
1895 tail->next = nskb;
1896 else
1897 segs = nskb;
1898 tail = nskb;
1899
1900 nskb->dev = skb->dev;
1901 nskb->priority = skb->priority;
1902 nskb->protocol = skb->protocol;
1903 nskb->dst = dst_clone(skb->dst);
1904 memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
1905 nskb->pkt_type = skb->pkt_type;
1906 nskb->mac_len = skb->mac_len;
1907
1908 skb_reserve(nskb, headroom);
1909 nskb->mac.raw = nskb->data;
1910 nskb->nh.raw = nskb->data + skb->mac_len;
1911 nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
1912 memcpy(skb_put(nskb, doffset), skb->data, doffset);
1913
1914 if (!sg) {
1915 nskb->csum = skb_copy_and_csum_bits(skb, offset,
1916 skb_put(nskb, len),
1917 len, 0);
1918 continue;
1919 }
1920
1921 frag = skb_shinfo(nskb)->frags;
1922 k = 0;
1923
1924 nskb->ip_summed = CHECKSUM_HW;
1925 nskb->csum = skb->csum;
1926 memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
1927
1928 while (pos < offset + len) {
1929 BUG_ON(i >= nfrags);
1930
1931 *frag = skb_shinfo(skb)->frags[i];
1932 get_page(frag->page);
1933 size = frag->size;
1934
1935 if (pos < offset) {
1936 frag->page_offset += offset - pos;
1937 frag->size -= offset - pos;
1938 }
1939
1940 k++;
1941
1942 if (pos + size <= offset + len) {
1943 i++;
1944 pos += size;
1945 } else {
1946 frag->size -= pos + size - (offset + len);
1947 break;
1948 }
1949
1950 frag++;
1951 }
1952
1953 skb_shinfo(nskb)->nr_frags = k;
1954 nskb->data_len = len - hsize;
1955 nskb->len += nskb->data_len;
1956 nskb->truesize += nskb->data_len;
1957 } while ((offset += len) < skb->len);
1958
1959 return segs;
1960
1961err:
1962 while ((skb = segs)) {
1963 segs = skb->next;
1964 kfree(skb);
1965 }
1966 return ERR_PTR(err);
1967}
1968
1969EXPORT_SYMBOL_GPL(skb_segment);
1970
1827void __init skb_init(void) 1971void __init skb_init(void)
1828{ 1972{
1829 skbuff_head_cache = kmem_cache_create("skbuff_head_cache", 1973 skbuff_head_cache = kmem_cache_create("skbuff_head_cache",