请在上面函数的基础上实现gtpu对消息类型和序列号的处理
时间: 2024-03-21 21:39:11 浏览: 103
在上述函数的基础上,我们可以增加处理消息类型和序列号的代码,如下所示:
```
static_always_inline void
gtpu_echo_request (vlib_main_t * vm, vlib_node_runtime_t * node,
gtpu_header_t * gtpu, u32 sw_if_index0)
{
vnet_main_t *vnm = vnet_get_main ();
vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index0);
/* Set MTU of the tunnel interface. This is an estimate since we do not
know how many labels the packet will have, but it is better than nothing. */
gtpu4_tunnel_t *t = gtpu4_tunnel_from_gtpu_header (gtpu);
u32 mtu =
si->mtu_bytes - sizeof (ip4_header_t) - sizeof (udp_header_t) -
sizeof (gtpu_header_t);
t->mtu = clib_min (t->mtu, mtu);
/* Just swap IP src/dst and send it back */
ip4_header_t *ip4 = &t->ip4;
ip_csum_t sum0 = ip4->checksum;
ip4->checksum = 0;
ip4->src_address.as_u32 = ip4->dst_address.as_u32;
ip4->dst_address.as_u32 = gtpu->ip4.src_address.as_u32;
ip4->checksum = ip4_header_checksum (ip4);
udp_header_t *udp = &t->udp;
udp->src_port = udp->dst_port;
udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_GTPU);
/* Process GTPU message type and sequence number */
gtpu->flags = GTPU_ECHO_RSP;
gtpu->message_type = GTPU_ECHO_REQUEST;
gtpu->sequence_number = gtpu->sequence_number + 1;
vlib_buffer_t *b = vlib_buffer_from_rte_mbuf (gtpu->buffer);
vlib_buffer_advance (b, -(word) sizeof (ip4_header_t));
b->current_data -= sizeof (ip4_header_t);
b->current_length += sizeof (ip4_header_t);
b->total_length_not_including_first_buffer += sizeof (ip4_header_t);
sum0 = ip_csum_update (sum0, 0, 0, ip4->src_address.as_u32);
sum0 = ip_csum_update (sum0, 0, 0, ip4->dst_address.as_u32);
udp->length = clib_host_to_net_u16 (b->current_length);
sum0 = ip_csum_update (sum0, 0, 0, udp->length);
gtpu->length = clib_host_to_net_u16 (b->current_length - sizeof (*ip4) -
sizeof (*udp));
sum0 = ip_csum_update (sum0, 0, 0, gtpu->length);
/* Process GTPU message checksum */
sum0 = ip_csum_with_carry (sum0, gtpu->flags);
sum0 = ip_csum_with_carry (sum0, gtpu->message_type);
sum0 = ip_csum_with_carry (sum0, clib_host_to_net_u16 (gtpu->length));
sum0 = ip_csum_with_carry (sum0, clib_host_to_net_u32 (gtpu->teid));
sum0 = ip_csum_with_carry (sum0, clib_host_to_net_u16 (gtpu->sequence_number));
gtpu->checksum = ~ip_csum_fold (sum0);
vlib_buffer_enqueue_to_next (vm, node, &b, 1, /* next_index */ 1);
}
```
在这个函数中,我们首先对消息类型进行处理,将其设置为Echo Request。然后,我们还对序列号进行处理,将其加1后设置为Echo Response的序列号。最后,我们根据GTPU协议的要求,计算出消息的校验和,并将其写入到GTPU头中。这样,我们就完成了对消息类型和序列号的处理。
阅读全文