diff options
author | Mauro Sardara <msardara@cisco.com> | 2020-11-09 19:56:31 +0100 |
---|---|---|
committer | Mauro Sardara <msardara@cisco.com> | 2020-11-10 12:34:12 +0000 |
commit | f87f19fa389a1edea861faaabc972d508a58985c (patch) | |
tree | 9305042a486c234e61d048ea43f59fc36da63147 | |
parent | c1de1ea148175650dfeab648d946e3266fdee117 (diff) |
[HICN-651] Offload checksum computation to VPP.
Signed-off-by: Mauro Sardara <msardara@cisco.com>
Change-Id: I42d69455542f3def0076fe58020f8f10347ef83f
-rw-r--r-- | hicn-plugin/src/faces/face_node.c | 23 | ||||
-rw-r--r-- | lib/includes/hicn/error.h | 21 | ||||
-rw-r--r-- | lib/src/protocol/tcp.c | 34 | ||||
-rw-r--r-- | libtransport/src/core/forwarder_interface.h | 3 |
4 files changed, 60 insertions, 21 deletions
diff --git a/hicn-plugin/src/faces/face_node.c b/hicn-plugin/src/faces/face_node.c index e1fd81ca0..fd8649e6b 100644 --- a/hicn-plugin/src/faces/face_node.c +++ b/hicn-plugin/src/faces/face_node.c @@ -558,19 +558,34 @@ hicn_face_rewrite_interest (vlib_main_t * vm, vlib_buffer_t * b0, /* return; */ hicn_header_t *hicn = vlib_buffer_get_current (b0); + size_t l3_header_size = sizeof(ip6_header_t); //hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; ip46_address_t temp_addr; ip46_address_reset (&temp_addr); hicn_type_t type = hicn_get_buffer (b0)->type; - hicn_ops_vft[type.l1]->rewrite_interest (type, &hicn->protocol, - &face->nat_addr, &temp_addr); + int ret = hicn_ops_vft[type.l1]->rewrite_interest (type, &hicn->protocol, + &face->nat_addr, &temp_addr); - if (ip46_address_is_ip4(&face->nat_addr)) + if (ip46_address_is_ip4(&face->nat_addr)) { b0->flags |= VNET_BUFFER_F_OFFLOAD_IP_CKSUM; + l3_header_size = sizeof(ip4_header_t); + } + + if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED) { + b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM; - b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM; + /* Make sure l3_hdr_offset and l4_hdr_offset are set */ + if (!(b0->flags & VNET_BUFFER_F_L3_HDR_OFFSET_VALID)) { + b0->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID; + vnet_buffer (b0)->l3_hdr_offset = b0->current_data; + } + if (!(b0->flags & VNET_BUFFER_F_L4_HDR_OFFSET_VALID)) { + b0->flags |= VNET_BUFFER_F_L4_HDR_OFFSET_VALID; + vnet_buffer (b0)->l4_hdr_offset = vnet_buffer (b0)->l3_hdr_offset + l3_header_size; + } + } ASSERT(face->flags & HICN_FACE_FLAGS_FACE); diff --git a/lib/includes/hicn/error.h b/lib/includes/hicn/error.h index 3e027c4e5..9303aeb7e 100644 --- a/lib/includes/hicn/error.h +++ b/lib/includes/hicn/error.h @@ -24,16 +24,17 @@ * Error definitions ******************************************************************************/ -#define foreach_libhicn_error \ -_(NONE, 0, "OK") \ -_(UNSPECIFIED, 128, "Unspecified Error") \ -_(NOT_IMPLEMENTED, 180, "Function not yet implemented") \ -_(NOT_HICN, 202, "Non hICN packet") \ -_(UNKNOWN_ADDRESS, 210, "Unknown address") \ -_(INVALID_PARAMETER, 220, "Invalid parameter") \ -_(INVALID_IP_ADDRESS, 221, "Invalid IP address") \ -_(CORRUPTED_PACKET, 222, "Corrupted packet ") \ -_(UNEXPECTED, 298, "Unexpected error") +#define foreach_libhicn_error \ +_(NONE, 0, "OK") \ +_(UNSPECIFIED, 128, "Unspecified Error") \ +_(NOT_IMPLEMENTED, 180, "Function not yet implemented") \ +_(NOT_HICN, 202, "Non hICN packet") \ +_(UNKNOWN_ADDRESS, 210, "Unknown address") \ +_(INVALID_PARAMETER, 220, "Invalid parameter") \ +_(INVALID_IP_ADDRESS, 221, "Invalid IP address") \ +_(CORRUPTED_PACKET, 222, "Corrupted packet ") \ +_(REWRITE_CKSUM_REQUIRED, 223, "Incremental csum calculation error: cksum required.") \ +_(UNEXPECTED, 298, "Unexpected error") typedef enum { diff --git a/lib/src/protocol/tcp.c b/lib/src/protocol/tcp.c index 31c495ff4..7b7c44ef7 100644 --- a/lib/src/protocol/tcp.c +++ b/lib/src/protocol/tcp.c @@ -48,15 +48,20 @@ DECLARE_set_payload_length (tcp, UNEXPECTED); int tcp_init_packet_header (hicn_type_t type, hicn_protocol_t * h) { - h->tcp = (_tcp_header_t) - { - .sport = htons (TCP_DEFAULT_SRC_PORT),.dport = - htons (TCP_DEFAULT_DST_PORT),.seq = 0,.seq_ack = - 0,.data_offset_and_reserved = TCP_DEFAULT_DATA_OFFSET_RES,.flags = + h->tcp = (_tcp_header_t) { + .sport = htons (TCP_DEFAULT_SRC_PORT), + .dport = htons (TCP_DEFAULT_DST_PORT), + .seq = 0, + .seq_ack = 0, + .data_offset_and_reserved = TCP_DEFAULT_DATA_OFFSET_RES, + .flags = TCP_DEFAULT_CWR << 7 | TCP_DEFAULT_ECE << 6 | TCP_DEFAULT_URG << 5 | TCP_DEFAULT_ACK << 4 | TCP_DEFAULT_PSH << 3 | TCP_DEFAULT_RST << 2 | - TCP_DEFAULT_SYN << 1 | TCP_DEFAULT_FIN << 0,.window = - htons (TCP_DEFAULT_WINDOW_SIZE),.csum = 0,.urg_ptr = 65000,}; + TCP_DEFAULT_SYN << 1 | TCP_DEFAULT_FIN << 0, + .window = htons (TCP_DEFAULT_WINDOW_SIZE), + .csum = 0xffff, + .urg_ptr = 65000, + }; uint8_t ah_flag = type.l2 == IPPROTO_AH ? AH_FLAG : 0; @@ -253,6 +258,21 @@ tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t * h, { u16 *tcp_checksum = &(h->tcp.csum); + /* As per RFC1624 + * In one's complement, there are two representations of zero: the all + * zero and the all one bit values, often referred to as +0 and -0. + * One's complement addition of non-zero inputs can produce -0 as a + * result, but never +0. Since there is guaranteed to be at least one + * non-zero field in the IP header, and the checksum field in the + * protocol header is the complement of the sum, the checksum field can + * never contain ~(+0), which is -0 (0xFFFF). It can, however, contain + * ~(-0), which is +0 (0x0000). + */ + if (*tcp_checksum == 0xffff) { + /* Invalid checksum, no need to compute incremental update */ + return HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED; + } + /* * Padding fields are set to zero so we can apply checksum on the * whole struct by interpreting it as IPv6 in all cases diff --git a/libtransport/src/core/forwarder_interface.h b/libtransport/src/core/forwarder_interface.h index 3b016c4bb..772cfbb52 100644 --- a/libtransport/src/core/forwarder_interface.h +++ b/libtransport/src/core/forwarder_interface.h @@ -95,7 +95,10 @@ class ForwarderInterface { packet.setLocator(inet6_address_); } +#ifndef __vpp__ + /* In the case of VPP we try to offload checksum computation to hardware */ packet.setChecksum(); +#endif connector_.send(packet.acquireMemBufReference()); } |