eBPF --- 对 eBPF sk_skb, sk_msg 的一些看法

===============================================================================================================

@@ 简单背景介绍


 eBPF 中有2个 prog_type:


    prog_type = BPF_PROG_TYPE_SK_SKB        # 之后,简称为 prog_sk_skb


    prog_type = BPF_PROG_TYPE_SK_MSG        # 之后,简称为 prog_sk_msg


 
 可以用来实现在内核态中的 packet 在不同的 socket 之间的 redirect。


 在这之前,如果需要实现 packet 在不同的 socket 之间的 redirect,可能是需要在用户态执行这样的逻辑:

        recvmsg( socket_0, buffer )            # 包含一次 kernel-user-level memcpy,将包内容,从内核态的 socket RXQ 拷贝到 用户态 buffer 中。

        sendmsg( socket_1, buffer )            # 包含另一次 kernel-user-level memcpy,将包内容,从 用户态 buffer 拷贝到 内核态 socket TXQ 中。


 对一个包,涉及到 2次 memcpy。

#
# --- 这就,好像很浪费呀。
#


 而 eBPF 的这两个 prog_type,可以实现在内核态下的,包 从一个 socket 的 RXQ,直接进入 另外一个 socket 的 TXQ。        

#
# --- 于是,节省了 2次 memcpy。
#

 大致的逻辑,简单介绍一下:        # 并不是很精确,大致如此。 详细可见:  https://mp.weixin.qq.com/s/VL6oKW1m0PXmuuE1v8h0iw


        创建一个 eBPF socketmap,实际上是一个 array,向里面填充是 socket 的 FD (__从用户态的角度看是如此,但在内核态逻辑中,FD 会转换为 socket instance )。

        将 prog_sk_skb 和 prog_skb_msg “安装”到 socketmap 上。        # 两个 prog 里面,是自己写的代码逻辑。 也可只安装一个。

        prog_sk_skb 是对 socket 的 ingress traffic 进行处理:


                从底层网卡和协议栈接收到一个ingress packet,在放进 socket RXQ 之前,执行 prog_sk_skb。

                如果 prog_sk_skb 对该 packet 进行 redirect 操作(__重定向到 socketmap 中另外一个 socket),则将该 packet 放进 另一个 socket 的 TXQ(__也可以放进它RXQ)。

                否则,不进行redirect操作的话,则正常进入原来socket的 RXQ。

        prog_sk_msg 是对 socket 的 egress traffic 进行处理:    


                从用户态 sendmsg() 发送下来的 egress packet,在放进 socket TXQ 之前,执行 prog_sk_msg。

                prog_sk_msg 可以将该 egress packet,redirect 到 socketmap 中另外一个 socket 的 RXQ 或者 TXQ。

                否则,不进行 redirect 的话,则正常进入原来socket 的 TXQ。                


===============================================================================================================

@@ 看起来好好,不是吗? --- 但是,可能没有想象得那么好。有很多限制。


===============================================================================================================

@@ 限制 #1. 只支持 TCP socket,不支持 UDP socket


 虽然,看起来支持 UDP socket 也能够做到,但是 **我个人的猜测理解**,不支持 UDP socket 是有原因的。


    TCP socket 是 有连接 的。只有 alive TCP socket,才能够被加入到 socketmap 中去,当 TCP connection 断开时,TCP socket 自动从 socketmap 移除。

    并且,TCP socket 是两端都会有反馈, 一端 发送包过去,另一段会返回 ACK,表明TCP connection仍然存在。

    只要 TCP connection 仍然存在,就能够继续愉快地 redirect packet。


        
    而 UDP socket 是无连接的 connectionless 。一端发送包,另一端不一定会返回任何包。甚至都不知道,对端是不是真的存在。

    这样的话,如果在2个 UDP sockets 之间 一直 redirect packet,    就,可能看不到反馈,发送到黑洞里去了,都不知道。 --- 就感觉不太好。


    --- 一个办法,在用户态在 UDP sockets 上 实现某种两端反馈机制。 但这是很自定义的机制,没什么通用性。 --- 不通用的东西,可能 kernel 也懒得去考虑。


    

    另外一些原因,是和 UDP socket 的收发包的一些细节有关(__实际上,也还是因为 UDP 是 connection less)。

 当然,要强行去实现支持UDP socket,好像也不是不可以,那就需要改kernel了,并且,也是很私人的修改,上不了台面,不产生问题就不错了。


===============================================================================================================

@@ 限制 #2. 只支持 “单播”的 redirect,不支持 “多播”的 redirect


 可能会有,将一个packet,同时 redirect 到多个 socket 的想法。 --- “多播”嘛。


 但是,当前不支持。


 当前,只支持,将一个 packet,从一个 socket,“单播”地 redirect 到另一个 socket。


 
 原因嘛? 我现在想想,也想不出来自己说得通的原因,但总感觉这样不好。


 
 同样,要强行去实现“多播”,好像也不是不可以,那就需要改kernel了,并且,也是很私人的修改,上不了台面,不产生问题就不错了。


 类似之前想过的,

        在 eBPF/XDP 中实现 L2 的转发“多播”        # https://blog.csdn.net/xzhao28/article/details/110247359

 也是这样的上不了台面。


===============================================================================================================

@@ <extra tip>: prog_type = BPF_PROG_TYPE_SK_SKB 实际上有2个 attach_type = BPF_SK_SKB_STREAM_PARSER 和 BPF_SK_SKB_STREAM_VERDICT,前者 是基于 stream_parser 框架进行 parsing,后者才是做 redirect,一前一后先后执行的关系。 --- 但好像( 个人觉得), parsing / redirect 之间,好像当前并没有太符合 stream_parser(strparser) 原本的框架的设计期望。 --- 细节太多了,无法展开说 --- 但是,感觉 之后 eBPF 的这两个 prog_type 肯定还会继续完善和进化吧。


===============================================================================================================
 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值