免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3391 | 回复: 2
打印 上一主题 下一主题

[内核入门] skb_copy_datagram_iovec疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-07-29 17:05 |只看该作者 |倒序浏览
int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
                            struct iovec *to, int len)
{
        int start = skb_headlen(skb);
        int i, copy = start - offset;

        /* Copy header. */
        if (copy > 0) {
                if (copy > len)
                        copy = len;
                if (memcpy_toiovec(to, skb->data + offset, copy))
                        goto fault;
                if ((len -= copy) == 0)
                        return 0;
                offset += copy;
        }

        /* Copy paged appendix. Hmm... why does this look so complicated? */
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                int end;

                BUG_TRAP(start <= offset + len);

                end = start + skb_shinfo(skb)->frags[i].size;
                if ((copy = end - offset) > 0) {
                        int err;
                        u8  *vaddr;
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
                        struct page *page = frag->page;

                        if (copy > len)
                                copy = len;
                        vaddr = kmap(page);
                        err = memcpy_toiovec(to, vaddr + frag->page_offset +
                                             offset - start, copy);
                        kunmap(page);
                        if (err)
                                goto fault;
                        if (!(len -= copy))
                                return 0;
                        offset += copy;
                }
                start = end;
        }

        if (skb_shinfo(skb)->frag_list) {
                struct sk_buff *list = skb_shinfo(skb)->frag_list;

                for (; list; list = list->next) {
                        int end;

                        BUG_TRAP(start <= offset + len);

                        end = start + list->len;
                        if ((copy = end - offset) > 0) {
                                if (copy > len)
                                        copy = len;
                                if (skb_copy_datagram_iovec(list,
                                                            offset - start,
                                                            to, copy))
                                        goto fault;
                                if ((len -= copy) == 0)
                                        return 0;
                                offset += copy;
                        }
                        start = end;
                }
        }
        if (!len)
                return 0;

fault:
        return -EFAULT;
}

memcpy_toiovec(to, vaddr + frag->page_offset +offset - start, copy);想不明白offset - start是什么意思?求问

论坛徽章:
0
2 [报告]
发表于 2014-07-29 21:13 |只看该作者
快来大大啊。。

论坛徽章:
1
丑牛
日期:2013-10-23 14:49:51
3 [报告]
发表于 2015-09-07 20:03 |只看该作者
如果分片了,拷贝后续分片包。
因为第一个包拷贝的时候,包头已经拷过了,后续的包头就不需要拷贝了。
offset - start 是跳过后续分片包的包头。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP