派生数据类型
header类型
header是用于定义协议头部结构的关键数据结构。header的作用是将原始比特流映射为具有明确语义的字段集合,以便在后续处理数据包时访问和操作这些字段。
header <header_name> {
<field_type> <field_name>;
...
}
- header_name:头部的名字,通常以协议名称命名。例如ethernet_t、ipv4_t。
- field_type:字段的类型,通常是固定宽度的位类型。例如bit<16>。
- field_name:字段的名字,用于标识协议的某个具体属性。
- header_name与field_name不能作为DSL语言的关键字,如action、match_kind等,且仅能由数字、大小写字母、下划线组成,且不能为数字开头。
以下代码块展示了ethernet_t的定义。
typedef bit<48> macAddr_t;
header ethernet_t {
macAddr_t dstAddr; // 目的MAC地址
macAddr_t srcAddr; // 源MAC地址
bit<16> etherType; // 协议类型字段
}
header数据类型支持setValid()、isValid()和setInvalid()方法:
- setValid():标记header中生效的协议类型,当报文解析的extract()函数生效后会进行调用。
- isValid():判断header中协议类型是否生效。在使用该协议层的数据时需先判断该层协议是否生效,若不判断直接使用header的数据可能会导致空指针异常,致使功能异常。
- setInvalid() : 标记header中不生效的协议类型。
- 架构文件hydra_headers.hdr中会提供常见协议头供用户使用。
- header的成员类型只能为基础类型。
header_union类型
header_union是数据类型类似于C语言中的union类型,作用是定义一组协议类型,并在处理数据包时动态选择使用哪一个。其中,header_union的每个成员必须是header类型。
header_union <header_union_name> {
header <header_name>;
...
}
- header_union_name:该组协议类型的名字(例如ip_union)。不能作为DSL语言的关键字,如action、match_kind等,且仅能由数字、大小写字母、下划线组成,且不能为数字开头。
以下代码块展示了ip_union的定义,ip_union类型表示IPv4报文头和IPv6报文头的union:
header_union ip_union {
ipv4_t ipv4;
ipv6_t ipv6;
}
- header_union的成员只能是header类型。
- header_union不能作为泛型参数传递。
- header_union不能作为action的控制面参数。
struct类型
在DSL语言中,struct是用于定义更通用数据结构的数据类型。struct并非header那样直接映射到数据包的比特流,而是用于存储与数据包相关的元数据或中间处理数据,或者用于存储网络多层header合集。它的灵活性使其适合在程序的逻辑处理中保存额外信息。
struct的定义语法如下所示。
struct <struct_name> {
<field_type> <field_name>;
...
}
- struct_name:数据结构的名称,通常以描述其功能的名字命名。例如metadata_t、headers。
- field_type:字段的类型,可以是bit<N>、布尔类型、枚举类型甚至嵌套的struct。
- field_name:字段的名称,用于标识数据结构中的具体属性。
- field_name与struct_name不能作为DSL语言的关键字,如action、match_kind等,且仅能由数字、大小写字母、下划线组成,且不能为数字开头。
enum类型
枚举类型,用于声明一组命名的常量,适用于变量仅允许在定义的有限选项中选择的场景。例如,Hydra架构文件hydra_core.hdr中用枚举类型表示报文的层级类型。
enum layers_e {
l2,
l3,
l4,
tunnel,
inner_l2,
inner_l3,
inner_l4
}
还可以指定枚举的底层表示,如bit<8>,并为每个成员指定具体的值。
enum bit<8> E {
e1 = 0,
e2 = 1,
e3 = 2
}
- 枚举类名与成员名不能作为DSL语言的关键字,如action、match_kind等,且仅能由数字、大小写字母、下划线组成,且不能为数字开头。
泛型类型
泛型类型表示尚未确定的类型,必须由用户提供。用于extern function及package。例如,以下extern function用于修改报文字段:
extern void hdr_packet_modify<T>(in T field, in T value);
在用户调用该extern function时,类型T须被实例化,且可为任意类型:
hdr_packet_modify(hdr.ipv4.sip, new_sip); hdr_packet_modify(hdr.ethernet.smac, new_smac);
其中sip类型为bit<32>,smac类型为bit<48>。
- extern function的泛型类型不可实例化为struct。
- 用户可以使用上述数据类型定义变量,例如:<field_type> <field_name>。
- field_name不能作为DSL语言的关键字,如action、match_kind等。field_name仅能由数字、大小写字母、下划线组成,且不能为数字开头。
父主题: 数据类型