去堆叠模式下ubuntu22.04修改内核源码支持ARP双发

本文介绍了在网络规模扩大导致传统堆叠技术问题频发的背景下,如何通过去堆叠技术中的ARP转主机路由方式,实现在Ubuntu22.04系统上使用bond模式的网络架构,实现ARP双发功能,并解决BGP模式下路由收敛时间过长的问题。
摘要由CSDN通过智能技术生成

1. 背景

过去传统的网络聚合方案是使用交换机堆叠技术,两台交换机之间需要堆叠线缆连接,这种使用方式一直沿用。随着互联网规模越来越大,交换机数量成倍增加,质量问题也越来越严重,传统的堆叠技术也面临着诸多挑战,其中成员交换机故障风险、交换机系统bug、软件版本升级问题等都会对网络可用性造成影响,因此网络技术发展出了去堆叠的方案,这种方案在物理形态上去掉了传统的堆叠线缆,两台交换机独立工作,同时服务器依然采用双上联bond模式,提高了网络可靠性。

2. 方案

关于去堆叠技术的设计方案,网上有很多介绍,这里我们选择了去堆叠技术中的ARP转主机路由的方式,这种方式服务器侧的网络配置不变,但是需要修改linux内核支持ARP双发。

网络架构

去堆叠方案

3. 实现

目前我们使用的操作系统是ubuntu22.04,内核使用的是5.15.0操作系统标配内核未做任何修改,之前我们基于3.10的内核做过ARP收发的分析:

#内核在发送arp请求时函数调用栈为:
arp_solicit
|
arp_send_dst  ->  arp_create
|
arp_xmit
|
dev_queue_xmit 
|
dev_hard_start_xmit:此时网卡为虚拟网卡bond0,不存在队列queue,因此没有通过队列直接发送数据,而进入到此函数
|
netdev_start_xmit:根据bond的模式,会进入不同的net_device_ops,对于mode4模式,外出流量的slave选举是基于传输hash策略实现的,该策略能够经过xmit_hash_policy选项从缺省的XOR策略改变到其余策略,因此实际需要关注的是XOR模式,实现函数是bond_3ad_xor_xmit
|
bond_3ad_xor_xmit -> bond_xmit_hash:选择bond的一个slave网卡

#了解一下bond的7种模式

通过之前的分析,套用到此次ubuntu22.04的系统上,同样需要关注bond_3ad_xor_xmit函数,来修改和配置ARP报文的发送。在原本的发送过程中:根据流量HASH原理,ARP报文会按照算法选择BOND成员网卡中的一个进行发送。

#通过hash选择其中一个绑定的网卡成员
slave = bond->arr[bond_xmit_hash(bond, skb) % count];  

因此,为了广播ARP包,我们在bond_3ad_xor_xmit中,检查数据包的类型,如果是ARP报文,则进行广播发送,广播发送的实现函数bond_xmit_broadcast,相关修改代码

#切换到源码目录
vim ./drivers/net/bonding/bond_main.c
#改变内容如下
#static netdev_tx_t bond_xmit_broadcast本来存在,不要动,但是需要在bond_3ad_xor_xmit之前再定义一次,避免编译器无法找到bond_xmit_broadcast函数的声明,防止编译过程报错

static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev);
static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb,
                                     struct net_device *dev)
{
        struct bonding *bond = netdev_priv(dev);
        struct bond_up_slave *slaves;
        struct slave *slave;

        **//判断数据包的类型是否为ARP包
        if (skb->protocol == htons(ETH_P_ARP)){
                //ARP包进行广播发送
                return bond_xmit_broadcast(skb, dev);
        }**

        slaves = rcu_dereference(bond->usable_slaves);
        slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves);
        if (likely(slave))
                return bond_dev_queue_xmit(bond, skb, slave->dev);

        return bond_tx_drop(dev, skb);
}

修改完代码以后,测试效果如下:
在这里插入图片描述
通过tcpdump any arp 我们可以看到bond模式下的eth0、eth1都在发送ARP广播,最终实现ARP双发的能力,支持去堆叠方案。

4. 扩展

记录整体实现过程

#下载源码
apt install linux-source
#安装必要软件
apt install openssl flex bison ncurses* libelf-dev libssl-dev libffi-dev build-essential dwarves
#配置
make menuconfig
vim .config
CONFIG_DEBUG_INFO_BTF=n
CONFIG_SYSTEM_TRUSTED_KEYSEYS=""
CONFIG_SYSTEM_REVOCATION_KEYS=""
#修改内核源码
vim ./drivers/net/bonding/bond_main.c
static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev);
static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb,
                                     struct net_device *dev)
{
        struct bonding *bond = netdev_priv(dev);
        struct bond_up_slave *slaves;
        struct slave *slave;

        //判断数据包的类型是否为ARP包
        if (skb->protocol == htons(ETH_P_ARP)){
                //ARP包进行广播发送
                return bond_xmit_broadcast(skb, dev);
        }

        slaves = rcu_dereference(bond->usable_slaves);
        slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves);
        if (likely(slave))
                return bond_dev_queue_xmit(bond, skb, slave->dev);

        return bond_tx_drop(dev, skb);
}

#编译,64为CPU核心数
make -j 64 CFLAGS_MODULE=-fno-strict-aliasing
#安装模块
make modules_install
#安装内核,注意安装内核完毕后的系统启动问题
make install
#可选操作,制作deb内核文件,后续可以做内核升级使用,并推到线上
make bindeb-pkg -j 64 #64为CPU核心数
  • 网络BGP模式下bond成员端口up/down后的路由收敛时间过长的问题,目前使用ifplugd进程监控物理连接,bond成员端口发生up/down时执行相应ARP Ping和路由修改操作。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值