diff options
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r-- | net/core/skbuff.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index ef9d46b91eb..95501e40100 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -176,6 +176,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
176 | skb_shinfo(skb)->tso_size = 0; | 176 | skb_shinfo(skb)->tso_size = 0; |
177 | skb_shinfo(skb)->tso_segs = 0; | 177 | skb_shinfo(skb)->tso_segs = 0; |
178 | skb_shinfo(skb)->frag_list = NULL; | 178 | skb_shinfo(skb)->frag_list = NULL; |
179 | skb_shinfo(skb)->ufo_size = 0; | ||
180 | skb_shinfo(skb)->ip6_frag_id = 0; | ||
179 | out: | 181 | out: |
180 | return skb; | 182 | return skb; |
181 | nodata: | 183 | nodata: |
@@ -1696,6 +1698,78 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, | |||
1696 | return textsearch_find(config, state); | 1698 | return textsearch_find(config, state); |
1697 | } | 1699 | } |
1698 | 1700 | ||
1701 | /** | ||
1702 | * skb_append_datato_frags: - append the user data to a skb | ||
1703 | * @sk: sock structure | ||
1704 | * @skb: skb structure to be appened with user data. | ||
1705 | * @getfrag: call back function to be used for getting the user data | ||
1706 | * @from: pointer to user message iov | ||
1707 | * @length: length of the iov message | ||
1708 | * | ||
1709 | * Description: This procedure append the user data in the fragment part | ||
1710 | * of the skb if any page alloc fails user this procedure returns -ENOMEM | ||
1711 | */ | ||
1712 | int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, | ||
1713 | int getfrag(void *from, char *to, int offset, | ||
1714 | int len, int odd, struct sk_buff *skb), | ||
1715 | void *from, int length) | ||
1716 | { | ||
1717 | int frg_cnt = 0; | ||
1718 | skb_frag_t *frag = NULL; | ||
1719 | struct page *page = NULL; | ||
1720 | int copy, left; | ||
1721 | int offset = 0; | ||
1722 | int ret; | ||
1723 | |||
1724 | do { | ||
1725 | /* Return error if we don't have space for new frag */ | ||
1726 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
1727 | if (frg_cnt >= MAX_SKB_FRAGS) | ||
1728 | return -EFAULT; | ||
1729 | |||
1730 | /* allocate a new page for next frag */ | ||
1731 | page = alloc_pages(sk->sk_allocation, 0); | ||
1732 | |||
1733 | /* If alloc_page fails just return failure and caller will | ||
1734 | * free previous allocated pages by doing kfree_skb() | ||
1735 | */ | ||
1736 | if (page == NULL) | ||
1737 | return -ENOMEM; | ||
1738 | |||
1739 | /* initialize the next frag */ | ||
1740 | sk->sk_sndmsg_page = page; | ||
1741 | sk->sk_sndmsg_off = 0; | ||
1742 | skb_fill_page_desc(skb, frg_cnt, page, 0, 0); | ||
1743 | skb->truesize += PAGE_SIZE; | ||
1744 | atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc); | ||
1745 | |||
1746 | /* get the new initialized frag */ | ||
1747 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
1748 | frag = &skb_shinfo(skb)->frags[frg_cnt - 1]; | ||
1749 | |||
1750 | /* copy the user data to page */ | ||
1751 | left = PAGE_SIZE - frag->page_offset; | ||
1752 | copy = (length > left)? left : length; | ||
1753 | |||
1754 | ret = getfrag(from, (page_address(frag->page) + | ||
1755 | frag->page_offset + frag->size), | ||
1756 | offset, copy, 0, skb); | ||
1757 | if (ret < 0) | ||
1758 | return -EFAULT; | ||
1759 | |||
1760 | /* copy was successful so update the size parameters */ | ||
1761 | sk->sk_sndmsg_off += copy; | ||
1762 | frag->size += copy; | ||
1763 | skb->len += copy; | ||
1764 | skb->data_len += copy; | ||
1765 | offset += copy; | ||
1766 | length -= copy; | ||
1767 | |||
1768 | } while (length > 0); | ||
1769 | |||
1770 | return 0; | ||
1771 | } | ||
1772 | |||
1699 | void __init skb_init(void) | 1773 | void __init skb_init(void) |
1700 | { | 1774 | { |
1701 | skbuff_head_cache = kmem_cache_create("skbuff_head_cache", | 1775 | skbuff_head_cache = kmem_cache_create("skbuff_head_cache", |
@@ -1747,3 +1821,4 @@ EXPORT_SYMBOL(skb_prepare_seq_read); | |||
1747 | EXPORT_SYMBOL(skb_seq_read); | 1821 | EXPORT_SYMBOL(skb_seq_read); |
1748 | EXPORT_SYMBOL(skb_abort_seq_read); | 1822 | EXPORT_SYMBOL(skb_abort_seq_read); |
1749 | EXPORT_SYMBOL(skb_find_text); | 1823 | EXPORT_SYMBOL(skb_find_text); |
1824 | EXPORT_SYMBOL(skb_append_datato_frags); | ||