当SONiC遇到P4之二
P4描述SAI
在当SONiC遇到P4中介绍了用P4来实现SAI Model的方式,这种方式利用了P4数据平面编程的功能实现了SAI模型,将P4和SONiC这两个分别位于网络数据平面和控制平面的开源编程实现结合起来了,看起来是强强联合。
可是问题是SAI支持的模型就是固定Pipeline的那几种,每一步做什么操作都定义的清清楚楚,好处是方便把不同交换芯片的共同点抽取出来,方便芯片供应商通过各自的闭源驱动程序实现对SAI接口的支持。用P4去实现SAI的Pipeline就是削足适履,完全放弃了P4通过编程实现灵活网络功能的特点。SONiC通过对P4的支持收获是得到了一个软件交换机,方便没有硬件平台的同学也可以用P4-BM软件交换机体验一下SONiC。
P4支持SAI模型的部分代码如下,代码描述的结构和这篇SONiC SAI结构4 L3介绍的SAI模型相同。
#include "../inc/headers.p4"
#include "../inc/parser.p4"
#include "../inc/defines.p4"
#include "../inc/field_lists.p4"
#include "tables.p4"
#include "actions.p4"
control ingress {
if (ingress_metadata.cpu_port == 0) {
control_ingress_port();
if((ingress_metadata.l2_if_type == L2_1Q_BRIDGE) or (ingress_metadata.l2_if_type == L2_1D_BRIDGE)) {
control_bridge();
}
if ((ingress_metadata.l2_if_type == L2_ROUTER_TYPE)) {
control_router_flow();
}
}
}
control control_bridge {
if(ingress_metadata.l2_if_type == L2_1D_BRIDGE){
control_1d_bridge_flow();
} else{
control_1q_bridge_flow();
}
if (standard_metadata.ingress_port != PORT_BRIDGE_ROUTER) {
apply(table_learn_fdb);
}
if((ethernet.dstAddr&0x010000000000)==0x0){
control_unicast_fdb();
} else if(ethernet.dstAddr==0xffffffffffff){
control_bc_fdb();
} else {
control_mc_fdb();
}
}
control control_ingress_port{
apply(table_ingress_lag);
apply(table_port_configurations);
if (ingress_metadata.is_tagged==1) {
apply(table_port_set_packet_vid_internal);
apply(table_drop_tagged_internal);
} else {
apply(table_drop_untagged_internal);
}
apply(table_l2_trap);
apply(table_trap_id);
if(ingress_metadata.bind_mode == PORT_MODE_PORT)
apply(table_port_ingress_interface_type);
else
apply(table_subport_ingress_interface_type);
}
control control_1d_bridge_flow{
apply(table_bridge_id_1d);
apply(table_vbridge_STP);
}
control control_1q_bridge_flow{
apply(table_bridge_id_1q);
apply(table_ingress_vlan_filtering);
apply(table_xSTP_instance);
apply(table_xSTP);
}
control control_router_flow{
}
control control_unicast_fdb{
apply(table_l3_interface){
miss{
apply(table_fdb) {
miss {
apply(table_flood);
}
}
}
}
}
control control_bc_fdb{
apply(table_broadcast);
}
control control_mc_fdb{
apply(table_mc_lookup_mode);
if((ingress_metadata.isip==0) or (ingress_metadata.mcast_mode==MAC_BASE_MC_LOOKUP))
apply(table_mc_fdb);
else if((ingress_metadata.isip==1) and (ingress_metadata.mcast_mode==SG_IP_BASE_MC_LOOKUP))
apply(table_mc_l2_sg_g);
if(ingress_metadata.mc_fdb_miss==1)
{
if(ingress_metadata.isip==1)
apply(table_unknown_multicast_ipv4);
else
apply(table_unknown_multicast_nonip);
}
}
control egress{
if (ingress_metadata.cpu_port == 1) {
control_cpu();
} else {
apply(table_egress_br_port_to_if);
if ((ingress_metadata.bridge_port == egress_metadata.bridge_port) and (standard_metadata.instance_type != 1)) {
apply(table_bridge_loopback_filter);
}
if(ingress_metadata.l2_if_type == L2_1D_BRIDGE){
apply(table_egress_vbridge_STP);
}
if(ingress_metadata.l2_if_type == L2_1Q_BRIDGE){
apply(table_egress_xSTP);
apply(table_egress_vlan_filtering);
}
if(ingress_metadata.l2_if_type == L2_1D_BRIDGE){
apply(table_egress_set_vlan);
}
apply(table_egress_vlan_tag);
if (egress_metadata.out_if_type == OUT_IF_IS_LAG) {
apply(table_lag_hash);
apply(table_egress_lag);
}
else if(egress_metadata.out_if == OUT_IF_IS_ROUTER){
control_1q_egress_uni_router();
}
apply(table_egress_clone_internal) {
hit {
apply(table_hostif_vlan_tag);
}
}
}
}
control control_cpu {
apply(table_cpu_forward);
}
control control_1q_egress_uni_router {
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)