aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Sardara <msardara@cisco.com>2020-11-09 19:56:31 +0100
committerMauro Sardara <msardara@cisco.com>2020-11-10 12:34:12 +0000
commitf87f19fa389a1edea861faaabc972d508a58985c (patch)
tree9305042a486c234e61d048ea43f59fc36da63147
parentc1de1ea148175650dfeab648d946e3266fdee117 (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.c23
-rw-r--r--lib/includes/hicn/error.h21
-rw-r--r--lib/src/protocol/tcp.c34
-rw-r--r--libtransport/src/core/forwarder_interface.h3
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());
}