P4 tutorials实验 - load_balance

P4 tutorials实验 - load_balance

基础知识

  • ECMP: Equal-Cost Multi-Path,等价多路径,参考链接
  • 负载均衡:将负载分配到多个服务器上,避免少数服务器过载
  • 哈希函数:hash()函数有五个参数,分别是存放hash结果、使用的hash算法、base值、哈希因子、count值
  • 本实验中哈希因子选取五元组,即源ip、目的IP、协议、源端口、目的端口(注意两个端口应该在TCP报头获取)
  • 本例中base=0,哈希运算的结果是0到count-1

实验部分

实验链接:https://github.com/p4lang/tutorials/tree/master/exercises/load_balance

本实验实现基于等成本多路径转发的简单版本的负载均衡。我们实现的交换机将会用两个table(ecmp_groupecmp_nhop),将数据包随机地转发到两个目标主机中的一个。ecmp_group表使用哈希函数选择一个目标主机,ecmp_nhop表使用计算出的哈希值将数据包转发到所选的主机。

TODO 1:对五元组进行哈希运算并将运算结果保存到meta.ecmp_select中

action set_ecmp_select(bit<16> ecmp_base, bit<32> ecmp_count) {
    /* TODO: hash on 5-tuple and save the hash result in meta.ecmp_select 
       so that the ecmp_nhop table can use it to make a forwarding decision accordingly */
       hash (meta.ecmp_select, //存放result
       HashAlgorithm.crc16, //选择的hash算法
       ecmp_base,//base值
       {
        	hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort
       },//哈希因子
       ecmp_count);//count值
}

TODO 2: 应用ecmp_group表与ecmp_nhop表

apply {
    if (hdr.ipv4.ttl > 0 && hdr.ipv4.isValid()) {
    //当ipv4头部有效且ttl还没有减到0时
        ecmp_group.apply();
        ecmp_nhop.apply();
    }
}

编译运行,尝试发送多条消息,可以看到h1向同一个目的ip发出的消息可能被h2或者h3接收

tips

问题1:step 1中,直接进行make操作,可能出现以下报错:

AttributeError: Could not find 'MyIngress.ecmp_group' of type tables
make: *** [../../utils/Makefile:35: run] Error 1

在原始的load_balance.p4代码中,确实可以看到MyIngressapply部分为空,但如果在apply部分直接应用这两个表,即直接写入如下代码的话,虽然可以消除报错,但在运行未完整代码时,h2可以收到信息,不满足其实验现象。

ecmp_group.apply();
ecmp_nhop.apply();

解决方案:直接完成apply部分的TODO任务,重新编译运行step 1中的操作,可以满足其实验现象。

further observation

用来进行哈希运算的操作set_ecmp_select的参数ecmp_baseecmp_countsX-runtime.json中下发的,分别取值为0和2,且该表项的match字段是目的ip地址,这意味着只有目的ip为10.0.0.1的数据包才会被这条规则进行负载均衡,如下s1-runtime.json代码显示:

	{
      "table": "MyIngress.ecmp_group",
      "match": {
        "hdr.ipv4.dstAddr": ["10.0.0.1", 32]
      },
      "action_name": "MyIngress.set_ecmp_select",
      "action_params": {
        "ecmp_base": 0,
        "ecmp_count": 2
      }
    },

此外,哈希函数中count值(即本例中的ecmp_count)的限制作用,是<= count-1而不是<= count,可参考sX-runtime.json中下发的规则,其用来存放哈希结果的元数据meta.ecmp_select只有两个匹配值,分别为0和1,分别对应拓扑中的主机h2和h3,(如下s1-runtime.json代码显示),这意味着哈希运算的结果只有0或1两种可能,所以是<= count-1

	{
      "table": "MyIngress.ecmp_nhop",
      "match": {
        "meta.ecmp_select": 0
      },
      "action_name": "MyIngress.set_nhop",
      "action_params": {
        "nhop_dmac": "00:00:00:00:01:02",
        "nhop_ipv4": "10.0.2.2",
	"port" : 2
      }
    },
    {
      "table": "MyIngress.ecmp_nhop",
      "match": {
        "meta.ecmp_select": 1
      },
      "action_name": "MyIngress.set_nhop",
      "action_params": {
        "nhop_dmac": "00:00:00:00:01:03",
        "nhop_ipv4": "10.0.3.3",
	"port" : 3
      }
    },
posted @ 2023-03-10 16:52  瑞图恩灵  阅读(476)  评论(0编辑  收藏  举报