P4 tutorials实验 - basic-tunnel

P4 tutorials实验 - basic-tunnel

基础知识

  • 隧道(tunnel):可以将IP隧道视为一对节点之间的虚拟点对点链路
  • 虚拟链路是在隧道入口处的路由器内创建的,当隧道入口处的路由器想通过这个虚拟链路发送数据包时,就将数据包封装在IP数据报中,IP报头中,目标地址是隧道远端路由器的地址,源地址是封装路由器的地址
  • P4程序定义了数据包处理流水线,但每个表中的规则是由控制平面插入。当一个规则匹配一个数据包时,它的操作将使用控制平面提供的参数,作为规则的一部分进行调用
  • 表(table):定义匹配域以及对应的执行动作,定义了匹配字段(key)、可选的动作(action)和一些其他相关属性

实验预览

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

本实验为basic实验中实现的IP路由器,添加对基本的隧道协议的支持。basic交换机是基于目标IP地址进行转发的,我们的工作是定义一个新的header类型来封装IP数据包,并修改交换机的代码,使得交换机使用新的隧道报头来决定目标端口。

新的header类型会包含一个协议ID,用来表示封装的数据包的类型,还会包含一个用于路由的目的ID

我们能够根据自定义封装报头的内容进行转发,并且在数据包中不存在封装报头的情况下,执行正常的IP转发

注意到header结构体中,多了一个新的header类型myTunnel:

struct headers {
    ethernet_t   ethernet;
    myTunnel_t   myTunnel;
    ipv4_t       ipv4;
}

todo1:修改parser部分,使其也能够解析mytunnel报头

todo2:定义一个新的action,名称为myTunnel_forward,操作是将出端口(例如standard_metadata中的egress_spec字段)设置为控制平面提供的端口号

todo3:定义一个新的table,名称为myTunnel_exact,这个表在myTunnel报头的dst_id字段进行精确匹配,如果表中存在匹配项,应该调用myTunnel_forward操作,如果没有,调用丢包操作

todo4:更新apply语句,使得当myTunnel报头有效时,应用新定义的myTunnel_exact表,否则,如果ipv4报头有效,调用ipv4_ipm表

todo5:更新deparser,提交以太网报头、myTunnel报头和ipv4报头,deparser仅在报头有效时才会进行emit,因为header的隐含有效位是由parser在提取时设置的,所以这里不需要检查header的有效性

具体实验

step 1:未使用隧道技术

step 2:修改basic_tunnel.p4

  • parser部分
parser MyParser(packet_in packet,
                out headers hdr,
                inout metadata meta,
                inout standard_metadata_t standard_metadata) {
    state start{
        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType){
        //根据etherType字段,提取出mytunnel报头或ipv4报头
            TYPE_IPV4: ipv4_parser;
            TYPE_MYTUNNEL:mytunnel_parser;
            //如果匹配TYPE_MYTUNNEL的值,则跳转到mytunnel_parser状态
            default: accept;
        }
        state ipv4_parser{//ipv4解析部分
            packet.extract(hdr.ipv4);//取出ipv4包头
            transition accept;
        }
        state mytunnel_parser{//mytunnel解析部分
        	packet.extract(hdr.myTunnel);
        	transition select(hdr.myTunnel.proto_id){
        		TYPE_IPV4:ipv4_parser;
        	//proto_id是被封装的数据包的类型
        	//如果proto_id==TYPE_IPV4,说明被封装的是ipv4报文,解析器在mytunnel报头之后,还需要提取ipv4报头
        		default:accept;
        	}
        }
    }
}
  • control部分

key由一个个表单对组成(e:m),其中e是对应数据包中匹配的字段,而m是一个match_kind常数,用来表示匹配的算法,默认的有:lpm最长前缀匹配,exact精确匹配,ternary三元匹配

action myTunnel_forward(egressSpec_t port) {
	standard_metadata.egress_spec = port;
	//port是控制平面提供的端口号
	//通过修改egress_spec字段,来实现对应功能
}

table myTunnel_exact {
    key = {
        hdr.myTunnel.dst_id: exact;//exact:精确匹配
        //dst_id是目标主机的ID,是要进行精确匹配的字段
    }
    actions = {//可选的动作
        myTunnel_forward;
        drop;
        NoAction;
    }
    size = 1024; //size是表的大小,定义表里最多可以有多少个 entries,不定义也可以
    default_action = drop();//default_action是当table miss的时候执行的动作
}

apply{
	if(hdr.myTunnel.isValid()){//当myTunnel报头有效时
		myTunnel_exact.apply();//应用新定义的myTunnel_exact表
	}
	else if(hdr.ipv4.isValid()){
		ipv4_lpm.apply();//否则,如果ipv4报头有效,调用ipv4_ipm表
	}
	//注意要进行apply()才会用上对应的table
}
  • deparser部分
control MyDeparser(packet_out packet, in headers hdr) {
    apply {
        packet.emit(hdr.ethernet);
        packet.emit(hdr.myTunnel);//对myTunnel报头进行emit
        packet.emit(hdr.ipv4);
    }
}

step 3:使用隧道技术的效果

如果将ip地址改为h3的ip地址,发现交换机实现隧道转发,根据dst指定的地址进行转发,不受到ip地址的影响:

posted @ 2022-11-03 15:04  瑞图恩灵  阅读(334)  评论(0编辑  收藏  举报