实验背景
报文转发流程
采用示例说明SRv6的报文转发流程。
如图所示,假设有报文需要从主机1转发到主机2,主机1将报文发送给节点A处理。节点A、B、D、E均支持SRv6,节点C不支持SRv6,只支持IPv6。我们在源节点A上进行网络编程,希望报文经过B-C、C-D链路,送达节点E,由E节点送达主机2。

报文转发流程分为以下几步:
- 源节点A将SRv6路径信息封装在SRH中,指定B-C,C-D链路的SID,另外封装E点发布的SID A5::10(此SID对应于节点E的一个IPv4 VPN),共3个SID,按照逆序形式压入SID序列。此时SL(Segment Left)=2,将Segment List[2]值复制到目的地址DA字段,按照最长匹配原则查找IPv6路由表,将其转发到节点B。
- 报文到达节点B,B节点查找本地SID表(存储本节点生成的SRv6 SID信息),命中自身的SID(End.X SID),执行SID对应的指令动作。SL值减1,并将Segment List[1]值复制到DA字段,同时将报文从SID绑定的链路(B-C)发送出去。
报文到达节点C,C无SRv6能力,无法识别SRH,按照正常IPv6报文处理流程,按照最长匹配原则查找IPv6路由表,将其转发到当前目的地址所代表的节点D。 - 节点D收报文后根据目的地址A4::45查找本地SID表,命中自身的SID(End.X SID)。同节点B,SL值减1,将A5::10作为DA,并将报文发送出去。
- 节点E收到报文后根据A5::10查找本地SID表,命中自身SID(End.DT4 SID),执行对应的指令动作,解封装报文,去除IPv6报文头,并将内层IPv4报文在SID绑定的VPN实例的IPv4路由表中进程查表转发,最终将报文发送给主机2。
srv6简化实验
本实验进行了简化,仅使用两个交换机作为源节点和end节点

实验实现流程:当h1向h2通信时,s1作为源节点,插入路径s1、s2。当s2接收到来在s1的报文,检查发现自己为end节点,执行srv6_pop操作,去掉srv6报文头并将安装ipv6地址进行转发到达h2
p4文件
#include <core.p4>
#include <v1model.p4>
/************************************************************************
************************** Defines **************************************
*************************************************************************/
#define ETH_TYPE_IPV4 0x0800
#define ETH_TYPE_IPV6 0x86dd
#define IP_PROTO_TCP 8w6
#define IP_PROTO_UDP 8w17
#define IP_PROTO_SRV6 8w43
#define IP_VERSION_4 4w4
#define SRV6_MAX_HOPS 6
typedef bit<48> mac_addr_t;
typedef bit<32> ipv4_addr_t;
typedef bit<128> ipv6_addr_t;
typedef bit<9> port_t;
const port_t CPU_PORT = 255;
/************************************************************************
************************** Headers **************************************
*************************************************************************/
@controller_header("packet_in")
header packet_in_header_t {
bit<9> ingress_port;
bit<7> _padding;
}
@controller_header("packet_out")
header packet_out_header_t {
bit<9> egress_port;
bit<7> _padding;
}
header ethernet_t {
bit<48> dst_addr;
bit<48> src_addr;
bit<16> ether_type;
}
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<6> dscp;
bit<2> ecn;
bit<16> len;
bit<16> identification;
bit<3> flags;
bit<13> frag_offset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdr_checksum;
bit<32> src_addr;
bit<32> dst_addr;
}
header ipv6_t {
bit<4> version;
bit<8> traffic_class;
bit<20> flow_label;
bit<16> payload_len;
bit<8> next_hdr;
bit<8> hop_limit;
bit<128> src_addr;
bit<128> dst_addr;
}
header srv6_header_t {
bit<8> next_hdr;
bit<8> hdr_ext_len;
bit<8> routing_type;
bit<8> segment_left;
bit<8> last_entry;
bit<8> flags;
bit<16> tag;
}
header srv6_segment_list_t{
bit<128> sid;
}
header tcp_t {
bit<16> src_port;
bit<16> dst_port;
bit<32> seq_no;
bit<32> ack_no;
bit<4> data_offset;
bit<3> res;
bit<3> ecn;
bit<6> ctrl;
bit<16> window;
bit<16> checksum;
bit<16> urgent_ptr;
}
header udp_t {
bit<16> src_port;
bit<16> dst_port;
bit<16> length_;
bit<16> checksum;
}
/************************************************************************
*********************** Custom Headers *********************************
*************************************************************************/
struct headers_t {
packet_out_header_t packet_out;
packet_in_header_t packet_in;
ethernet_t ethernet;
ipv4_t ipv4;
ipv6_t ipv6;
srv6_header_t srh;
srv6_segment_list_t[SRV6_MAX_HOPS] segment_list;
tcp_t tcp;
udp_t udp;
}
struct local_metadata_t {
bit<16> l4_src_port;
bit<16> l4_dst_port

本文详细介绍了SRv6(Segment Routing with IPv6)的报文转发流程,通过主机1经节点A、B、C、D、E到主机2的示例,展示了如何在支持SRv6的节点间利用SRH和SID进行路径选择与报文传递。重点涉及封装、路由查找和节点间的交互操作。
最低0.47元/天 解锁文章
3273





