• 套接字缓存之skb_put、skb_push、skb_pull、skb_reserve


    skb操作中的预留和对齐操作主要由skb_put、skb_push、skb_pull、skb_reserve完成;这几个函数的区别通过下面图(图片来自:深入理解linux网络技术内幕)可以清晰的区分;另外,需要注意的是skb_reserve只能操作空skb,即在分配了空间,尚未填充数据时调用;

     

    以下为四个函数的源码分析;

     1 /**
     2  *    skb_put - add data to a buffer
     3  *    @skb: buffer to use
     4  *    @len: amount of data to add
     5  *
     6  *    This function extends the used data area of the buffer. If this would
     7  *    exceed the total buffer size the kernel will panic. A pointer to the
     8  *    first byte of the extra data is returned.
     9  */
    10 /*
    11     向skb尾部添加数据
    12 */
    13 unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
    14 {
    15     /* 获取当前skb->tail */
    16     unsigned char *tmp = skb_tail_pointer(skb);
    17 
    18     /* 要求skb数据区必须为线性 */
    19     SKB_LINEAR_ASSERT(skb);
    20     
    21     /* skb尾部增加len字节 */
    22     skb->tail += len;
    23     /* skb数据总长度增加len字节 */
    24     skb->len  += len;
    25 
    26     /* 如果增加之后的tail > end ,则panic */
    27     if (unlikely(skb->tail > skb->end))
    28         skb_over_panic(skb, len, __builtin_return_address(0));
    29     
    30     //返回添加数据的第一个字节位置
    31     return tmp;
    32 }
     1 /**
     2  *    skb_push - add data to the start of a buffer
     3  *    @skb: buffer to use
     4  *    @len: amount of data to add
     5  *
     6  *    This function extends the used data area of the buffer at the buffer
     7  *    start. If this would exceed the total buffer headroom the kernel will
     8  *    panic. A pointer to the first byte of the extra data is returned.
     9  */
    10 /*
    11     向skb数据区头部添加数据
    12 */
    13 unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
    14 {
    15     /* 数据区data指针前移len字节 */
    16     skb->data -= len;
    17     /* 数据总长度增加len字节 */
    18     skb->len  += len;
    19 
    20     /* 添加数据长度溢出过header ,panic*/
    21     if (unlikely(skb->data<skb->head))
    22         skb_under_panic(skb, len, __builtin_return_address(0));
    23 
    24     /* 返回新的data指针 */
    25     return skb->data;
    26 }
     1 /**
     2  *    skb_pull - remove data from the start of a buffer
     3  *    @skb: buffer to use
     4  *    @len: amount of data to remove
     5  *
     6  *    This function removes data from the start of a buffer, returning
     7  *    the memory to the headroom. A pointer to the next data in the buffer
     8  *    is returned. Once the data has been pulled future pushes will overwrite
     9  *    the old data.
    10  */
    11 /*
    12     从数据区头部移除数据
    13 */
    14 unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
    15 {
    16     return skb_pull_inline(skb, len);
    17 }
    1 /* 根据移除数据长度判断函数调用 */
    2 static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
    3 {
    4     /* 
    5         移除长度> skb数据总长度,返回NULL
    6         否则,继续调用_skb_pull函数
    7     */
    8     return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
    9 }
     1 /* 从skb数据区头部移除数据 */
     2 static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
     3 {
     4     /* 数据总长度减去len字节 */
     5     skb->len -= len;
     6     /* 数据总长度是否有异常 */
     7     BUG_ON(skb->len < skb->data_len);
     8 
     9     /* 
    10         data指针移动len字节
    11         返回移除之后新的data指针
    12     */
    13     return skb->data += len;
    14 }
     1 /*
     2     保留头部空间,只能对空的skb使用
     3 */
     4 static inline void skb_reserve(struct sk_buff *skb, int len)
     5 {
     6     /* 数据区data指针增加len字节*/
     7     skb->data += len;
     8     /* 数据区tail指针增加len字节 */
     9     skb->tail += len;
    10 }
  • 相关阅读:
    Windows Service 2016 DatacenterStandEmbedded激活方法
    批处理文件设置IP以及DNS
    C#类的一些基础知识(静态方法可以不用实例化调用)
    Dynamics Crm Plugin插件注册的问题及解决方案(持续更新。。。。。。)
    【转载】C# get 与set的一些说明
    C#补位函数PadLeft和PadRight
    Kubernetes集群调度之Scheduler
    Kubernetes集群控制之ControllerManager
    Kubernetes集群大脑之apiserver
    Kubernetes集群存储之etcd
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/7529512.html
Copyright © 2020-2023  润新知