eBPF/XDP --- 如果一定要实现 redirect-to-dev 的多播,该怎么办

1 篇文章 0 订阅

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

之前一个大哥的博文:

    https://blog.csdn.net/dog250/article/details/102982948      实现一个基于XDP/eBPF的学习型网桥


我留言:

    这几天学习过程中正好想到了这个问题,就见到了这篇文,受教了。 一点小建议,可以强调这一点,XDP helper_function BPF_FUNC_redirect 和 BPF_FUNC_redirect_map,只能实现到一个egress interface 的 packet redirect,无法实现 到多个 interfaces 的 multicast flooding,所以无法在 xdp_prog 中做到 flooding of MC packet or unknown UC DMAC packet,所以需要XDP_PASS到 bridge 中 做 flooding。


今天偶然再想到这个问题:

    当前,eBPF XDP 的 BPF_FUNC_redirect 和 BPF_FUNC_redirect_map,是只能将 packet 重定向到 另一个 interface 的 egress 的。

    没有 将一个 packet 重定向到 多个 interfaces 的机制。

那么,如果一定要在 XDP 中 实现,多播 的机制呢? 可以怎样来做到呢? 那只能自己动手改了。


这里说一说自己的思路。     # 没环境和时间去代码。


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


先说明一下,XDP helper_func 的 BPF_FUNC_redirect 和 BPF_FUNC_redirect_map 的内部实现机制。


redirect 分为两个 stages:


    stage #1. xdp_prog 调用 helper_function,只是 make redirect decision,将 redirect_info 记录在 per-CPU variable "bpf_redirect_info" 中

            struct bpf_redirect_info {
                u32 flags;
                u32 tgt_index;
                void *tgt_value;
                struct bpf_map *map;
                u32 kern_flags;
            };

    stage #2. 真正的 redirect 操作,是从 xdp_prog 执行返回到 hook point 之后,再由 返回之后的代码 来实现的,根据 redirect_info 来进行实际的 redirect 操作,大致是 enqueue to and flush (__ flush 到 target_dev 的 "ndo_xdp_xmit()" method

下面说一说,如何就这两个 stages 进行修改。


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

--- 先在 per-CPU variable "struct bpf_redirect_info" 中,增加 fields


struct bpf_redirect_info {
    u32 flags;
    u32 tgt_index;

+   u32 tgt_mc_index[64];       # 随意定个64的大小。

    void *tgt_value;
    struct bpf_map *map;
    u32 kern_flags;
};


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

--- stage #1 的修改. 新定义一个 helper_func: BPF_FUNC_redirect_map_multicast( struct bpf_map *map, u32 key[], u64 flags )


  可以模仿着:

        BPF_CALL_3(bpf_xdp_redirect_map, struct bpf_map *, map, u32, ifindex,
               u64, flags)


 来实现。


 
 大致逻辑是:


    将 devmap 的 多个 ifindex,存放进 per-CPU variable "struct bpf_redirect_info->tgt_mc_index[]" array 即可。


    return XDP_REDIRECT_MC;     # 新定义的一个 return value。


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

--- stage #2 的修改 --- 对于 generic_xdp,如何修改 stage #2。


int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb)


        act = netif_receive_generic_xdp(skb, &xdp, xdp_prog);
        if (act != XDP_PASS) {
            switch (act) {
            case XDP_REDIRECT:
                err = xdp_do_generic_redirect(skb->dev, skb,
                                  &xdp, xdp_prog);


                break;


            #
            # 这个 xdp_do_generic_redirect_mc(),可以模仿 xdp_do_generic_redirect() 来写。
            #
            # 其大致逻辑是:
            #
            #       从 skb 创建多个 skb clone,然后 发送到 
            #       "struct bpf_redirect_info->tgt_mc_index[]" 指定的多个 net_device。
            #

+           case XDP_REDIRECT_MC:
+
+               err = xdp_do_generic_redirect_mc(skb->dev, skb, &xdp, xdp_prog ).
+
+               break;
+


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


--- stage #2 的修改 --- 如何修改 stage #2。 --- 这会比较复杂,因为 native_xdp 都是在具体的 physical NIC driver 中的,所以,需要修改不同的 physical NIC driver 的相关code。并且,有非常多的细节需要处理。


 大致逻辑,也是类似 generic_xdp 的 修改。


 这里以 ixgbe driver 来说一下大致思路。


     ixgbe_run_xdp(struct ixgbe_adapter *adapter,
                     struct ixgbe_ring *rx_ring,
                     struct xdp_buff *xdp)


            case XDP_REDIRECT:
                err = xdp_do_redirect(adapter->netdev, xdp, xdp_prog);

                break;


            #
            # 模仿着 xdp_do_redirect() 来写。
            #
            # 其中,创建从原始的 "xdp_buff",复制创建多份 "xdp_buff"。
            #
            #
            # [*][*] 注意,需要增加 xdp_buff 所引用到的 packet data 所在的 page 的 page count。  # --- 以和发送完毕之后的 xdp_return_frame() 处理 相对应。
            #

+   
+           case XDP_REDIRECT_MC:
+               err = xdp_do_redirect_mc(adapter->netdev, xdp, xdp_prog);
+
+               break;
+


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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值