鲲鹏社区首页
中文
注册
开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

接口详情

hydra_core.hdr架构文件中提供了用于报文解析的packet_in extern object。

extern packet_in {
    void extract<T>(out T hdr, in bit<32> type, in layers_e layer);
    void extractOpt<T>(out T hdr);
    void advance(in bit<32> sizeInBits);
}

其中,各个函数的含义如表1所示。

表1 函数说明

函数名

入参

效果

示例

extract

hdr:header结构体中定义的报文头。

按照header结构体中的定义,将协议的某个字段从报文中提取出来。

packet.extract(hdr.ethernet, TYPE_ETH, layer.l2);

type:报文类型值,基础报文的type在hydra_core.hdr架构文件中有提供。

layer:协议所在层级,hydra_core.hdr架构文件中有提供层级枚举。

extractOpt

hdr:struct中定义的optional的header字段。例如GRE的可选字段。

提取报文中的可选字段。

if (hdr.gre.C == 1w1) {

packet.extractOpt(hdr.gre_opt_c);

}

advance

sizeInBits:要移动的长度,以bit为单位。

将报文解析流程当前指向的位置指针向后移动。

packet.advance(((bit<32>) hdr.inner_ipv4.ihl - 32w5) * 32w32);

hdr_last_layer_get

/

layers_e hdr_last_layer_get();

获取已硬件解析完成的最后一层报文的层级

hdr_last_layer_type_get

/

bit<16> hdr_last_layer_type_get();

获取已硬件解析完成的最后一层报文的协议类型

hydra_externs.hdr架构文件中提供了丰富的extern函数,用户在自定义action中可组合不同的extern函数以实现隧道封装、隧道解封装、报文修改等功能。

表2 函数说明

函数名称

参数

签名

描述

hdr_packet_delete_from_head

len:要删除的报文头长度。

extern void hdr_packet_delete_from_head(in bit<8> len);

从报文首部删除报文,可用于隧道解封装。用户应保证删除总长度不能超过原始报文头总长度,且不超过255B。

hdr_packet_insert_from_head

hdr:要插入的报文头,类型为header。

extern void hdr_packet_insert_from_head<T>(in T hdr);

从报文首部插入报文,可用于隧道封装。对于发往网络侧的报文用户应保证插入总长度不超过128B;对于发往主机侧的报文用户应保证插入总长度不超过64B。

hdr_packet_modify

  • field:要修改的报文头字段。
  • value:修改的值。
extern void hdr_packet_modify<T>(in T field, in T value);

修改报文头的指定字段。

hdr_packet_calc_checksum_incr

  • modified_field:修改的报文字段。
  • cs_field:要修改的checksum字段。
  • params:结构体类型,用于参数配置,具体成员如下:
    • old_val:在修改报文头相关字段场景且需增量更新报文头checksum场景下,该成员为待修改字段的旧值。
    • new_val:在修改报文头相关字段场景且需增量更新报文头checksum场景下,该成员为待修改字段的新值。
    • old_cs:在修改报文头相关字段场景且需增量更新报文头checksum场景下,该成员为待修改报文头的旧checksum值。
    • cs_alg:checksum算法选择,hydra_externs.hdr架构文件中有提供算法枚举供用户选择。
extern void hdr_packet_calc_checksum_incr<M,C>(in M modified_field,in C cs_field,in packet_incr_cs_param params);

增量修改原始报文头中的checksum字段。

示例如下:

修改IPv4的TTL字段后更新checksum。

packet_incr_cs_param incr_checksum_para;
incr_checksum_para.old_val = (bit<32>)hdr.ipv4.ttl; //待修改字段的旧值
incr_checksum_para.new_val = (bit<32>)(hdr.ipv4.ttl - 1); //待修改字段的新值
incr_checksum_para.old_cs = hdr.ipv4.hdr_checksum; //待修改报文头的旧checksum值
incr_checksum_para.cs_alg = RFC.RFC_1624; //使用RFC_1624算法
hdr_packet_modify(hdr.ipv4.ttl, hdr.ipv4.ttl - 1); //先修改ttl字段
hdr_packet_calc_checksum_incr(hdr.ipv4.ttl,hdr.ipv4.hdr_checksum,incr_checksum_para); //更新checksum字段

hdr_packet_calc_inserted_checksum_incr

  • 前三个参数含义同接口hdr_packet_calc_checksum_incr。
  • offset:待计算协议头在所插入报文头中的偏移。
extern void hdr_packet_calc_inserted_checksum_incr<M, C>(in M modified_field,in C cs_field,in packet_incr_cs_param param,in bit<32> offset);

增量修改新插入报文头中的checksum字段。用户应保证offset小于用户插入的报文头总长度。

hdr_packet_calc_checksum

  • cs_field的含义同hdr_packet_calc_checksum_incr
  • param:结构体类型,用于参数配置,具体成员如下:
    • init_value:当前原始报文头的初始checksum value,需设置为0。
    • mask:用于标识原始报文头中需要参与checksum计算的字段。掩码长度为64比特,每位对应报文中连续的2个字节,对应总计128字节的报文长度。掩码位为‘0’时,表示其对应的报文字节段需参与计算。若需要掩去IPv4层的checksum字段(位于第11字节),mask取值为0x 0400000000000000。
    • cs_alg:checksum算法选择,hydra_externs.hdr架构文件中有提供算法枚举供用户选择。
extern void hdr_packet_calc_checksum<T>(in T cs_field,in packet_checksum_param param);

全量修改原始报文头中的checksum字段。

  • 目前该接口不支持包含伪首部的协议的checksum计算,例如TCP和UDP。
  • 该接口需在报文头字段不再被修改后调用。

hdr_packet_calc_inserted_checksum

  • cs_field和param的含义同hdr_packet_calc_checksum。
  • layer_offset:待计算协议头在所插入报文头中的偏移。
  • layer_len:待计算协议头的长度。
extern void hdr_packet_calc_inserted_checksum<T>(in T cs_field,in  packet_checksum_param param,in bit<32> layer_offset,in bit<32>layer_len);

全量修改新插入报文头中的checksum字段。

  • 计算插入报文头的checksum时,计算顺序应严格按照从外层到内层。
  • 目前该接口不支持包含伪首部的协议的checksum计算,例如TCP和UDP。

hdr_ovs_pipeline_action_upcall

/

extern void hdr_ovs_pipeline_action_upcall();

执行上送操作,注意只可用于前置control流程中,不可用于后置control流程。

hdr_ovs_pipeline_action_drop

/

extern void
hdr_ovs_pipeline_action_drop();

执行丢包操作,可用于前置control流程和后置control流程中。

hdr_input_port_id_get

/

extern bit<16> hdr_input_port_id_get();

获取当前报文输入的port_id。

Hydra在架构文件hydra_log.hdr中提供了USER_LOG宏用于日志打印。

#define USER_LOG(type,fmt,args...)hydra_log_##type(FILE_ID,__LINE__,0,fmt,##args)
  • type:日志级别。取值范围:ERR、WARN、INFO、DEBUG。
  • fmt:日志信息。字符串类型,最大字符数为128。
  • args:变长参数列表。最多打印4个参数,占位符使用0x%x。

使用范围

  • parser的state内
  • action内
  • control apply内

使用示例

control MyPrePipe(in headers hdr) {
    apply {
        USER_LOG(ERR, "[DSL][MyPrePipe]hdr.ipv4.ttl  0x%x\n", hdr.ipv4.ttl);
    }
}