P4_16入门之header和parser

P4_16程序有五个部分组成:Header,Parser,Table,Actions,Control Program.
其中Header定义:描述一系列字段的顺序和结构,包 括字段的宽度和字段值的限制。
IPv4的包头定义例子。

	/***  HEADER DEFINITIONS ***/
header ethernet_h
{
    bit<48> dst_addr;
    bit<48> src_addr;
    bit<16> ether_type;
}
header vlan_tag_h
{
    bit<3>  pri;
    bit<1>  cfi;
    bit<12> vid;
    bit<16> ether_type;
}
header ipv4_h
{
    bit<4>  version;
    bit<4>  ihl;
    bit<8>  diffserv;
    bit<16> total_len;
    bit<16> identification;
    bit<3>  flags;
    bit<13> frag_offset;
    bit<8>  ttl;
    bit<8>  protocal;
    bit<16> hdr_checksum;
    bit<32> src_addr;
    bit<32> dst_addr;
}

定义格式类似于C语言结构体。header声明,ethernet_h等为header标签,在后续的使用中利用该标签生成对象。这些标签像一个容器,将数据按定义的顺序和长度抓取出来装到该标签对象中去。
bit name;其中bit是基本数据结构声明,另外还有int,varbit一共三种。n为声明的长度。
因此,以ethernet_h为例,里面定义了前48位为dst_addr(目的MAC),48-95位为src_addr(源MAC),96-111位为ether_type(用来区别后面数据是否带有vlan tag或ipv4)。
IPv4的Parser解析器实例代码:

	/***   INGRSS PIPELINE   ***/
struct ingress_headers_t
{
    ethernet_h ehternet;
    vlan_tag_h vlan_tag;
    ipv4_h ipv4;
}
struct ingress_metadata_t{
}


parser IngressParser(packet_in pkt,
    out ingress_headers_t hdr,
    out ingress_metadata_t meta,
    out ingress_intrisic_metadata_t ig_intr_md)
{
    state start{
        pkt.extract(ig_intr_md);
        pkt.advance(PORT_METADATA_SIZE);
        transition parser_ethernet;
    }
    state parser_ethernet
    {
        pkt.extract(hdr.ethernet);
        transition select(hdr.ethernet.ether_type)
        {
            0x8100&&&0xEFFF: parser_vlan_tag;
            0x0800: parser_ipv4;
            default: accept;
        }
    }
    state parser_vlan_tag
    {
        pkt.extract(hdr.vlan_tag);
        transition select(hdr.valn_tag.ether_type)
        {
            0x8000:parser_ipv4;
            default:accept;
        }
    }
    state parser_ipv4
    {
        pkt.extract(hdr.ipv4);
        transition accept;
    }
}

在struct中的元素包含有header的集合。后续一般对struct对象声明,通过struct对象来存储提取出来的header。
header:按顺序收集所含成员。1)字节对齐,2)可以有效也可以无效
Struct:不用按顺序收集成员。1)不用对齐,2)可以由基本类型或者派生类型组成。
Parser中的声明:

parser IngressParser(packet_in pkt,
    out ingress_headers_t hdr,
    out ingress_metadata_t meta,
    out ingress_intrisic_metadata_t ig_intr_md)

packet_in pkt为将数据流存在对象pkt中。
out ingress_headers_t hdr: hdr为ingress_headers_t结构对象,并且是一个输出对象或者说接口(out)。剩下其他类似。
特别的,out ingress_intrisic_metadata_t ig_intr_md,为固有元数据,在编译器中具有特殊定义,用于携带交换机自身的配置信息,如数据包进入交换机时的端口号等。而ingress_metadata_t为用户元数据,可由用户定义。固有元数据表自行查找。
Parser状态转移:

{
    state start{
        pkt.extract(ig_intr_md);
        pkt.advance(PORT_METADATA_SIZE);
        transition parser_ethernet;
    }
    state parser_ethernet
    {
        pkt.extract(hdr.ethernet);
        transition select(hdr.ethernet.ether_type)
        {
            0x8100&&&0xEFFF: parser_vlan_tag;
            0x0800: parser_ipv4;
            default: accept;
        }
    }
    state parser_vlan_tag
    {
        pkt.extract(hdr.vlan_tag);
        transition select(hdr.valn_tag.ether_type)
        {
            0x8000:parser_ipv4;
            default:accept;
        }
    }
    state parser_ipv4
    {
        pkt.extract(hdr.ipv4);
        transition accept;
    }
}

以上代码实际上为一个有限状态机,即从start状态进入进行状态(state)转移直到遇到accept结束状态机并进入下一步。其中pkt.extract()为数据抓取,按对象中定义的结构顺序长度来提取pkt中的数据。transition为状态转移, select()相当于switch()语句。

参考:https://www.sdnlab.com/17882.html
部分为个人理解,可能有误。

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试
应支付0元
点击重新获取
扫码支付

支付成功即可阅读