summaryrefslogtreecommitdiffstats
path: root/src/vnet/ip/ip4_input.h
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2018-06-18 22:21:40 +0200
committerDamjan Marion <dmarion@me.com>2018-06-28 10:00:05 +0000
commit08bca80c998bdae87060306350124714606a1604 (patch)
treeb207c71fc42030e9beb26addf5e4e4056a39e73d /src/vnet/ip/ip4_input.h
parent0d427d8d8a48af404dfc6535ae72d334b790f809 (diff)
ip: vectorized ip checksum
Change-Id: Ida678e6f31daa8decb18189da712a350336326e2 Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vnet/ip/ip4_input.h')
-rw-r--r--src/vnet/ip/ip4_input.h97
1 files changed, 28 insertions, 69 deletions
diff --git a/src/vnet/ip/ip4_input.h b/src/vnet/ip/ip4_input.h
index e0873039990..889b423d700 100644
--- a/src/vnet/ip/ip4_input.h
+++ b/src/vnet/ip/ip4_input.h
@@ -56,6 +56,26 @@ typedef enum
IP4_INPUT_N_NEXT,
} ip4_input_next_t;
+static_always_inline void
+check_ver_opt_csum (ip4_header_t * ip, u8 * error, int verify_checksum)
+{
+ if (PREDICT_FALSE (ip->ip_version_and_header_length != 0x45))
+ {
+ if ((ip->ip_version_and_header_length & 0xf) != 5)
+ {
+ *error = IP4_ERROR_OPTIONS;
+ if (verify_checksum && ip_csum (ip, ip4_header_bytes (ip)) != 0)
+ *error = IP4_ERROR_BAD_CHECKSUM;
+ }
+ else
+ *error = IP4_ERROR_VERSION;
+ }
+ else
+ if (PREDICT_FALSE (verify_checksum &&
+ ip_csum (ip, sizeof (ip4_header_t)) != 0))
+ *error = IP4_ERROR_BAD_CHECKSUM;
+}
+
always_inline void
ip4_input_check_x4 (vlib_main_t * vm,
vlib_node_runtime_t * error_node,
@@ -71,22 +91,10 @@ ip4_input_check_x4 (vlib_main_t * vm,
error0 = error1 = error2 = error3 = IP4_ERROR_NONE;
- /* Punt packets with options or wrong version. */
- if (PREDICT_FALSE (ip[0]->ip_version_and_header_length != 0x45))
- error0 = (ip[0]->ip_version_and_header_length & 0xf) != 5 ?
- IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
-
- if (PREDICT_FALSE (ip[1]->ip_version_and_header_length != 0x45))
- error1 = (ip[1]->ip_version_and_header_length & 0xf) != 5 ?
- IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
-
- if (PREDICT_FALSE (ip[2]->ip_version_and_header_length != 0x45))
- error2 = (ip[2]->ip_version_and_header_length & 0xf) != 5 ?
- IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
-
- if (PREDICT_FALSE (ip[3]->ip_version_and_header_length != 0x45))
- error3 = (ip[3]->ip_version_and_header_length & 0xf) != 5 ?
- IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
+ check_ver_opt_csum (ip[0], &error0, verify_checksum);
+ check_ver_opt_csum (ip[1], &error1, verify_checksum);
+ check_ver_opt_csum (ip[2], &error2, verify_checksum);
+ check_ver_opt_csum (ip[3], &error3, verify_checksum);
if (PREDICT_FALSE (ip[0]->ttl < 1))
error0 = IP4_ERROR_TIME_EXPIRED;
@@ -97,26 +105,6 @@ ip4_input_check_x4 (vlib_main_t * vm,
if (PREDICT_FALSE (ip[3]->ttl < 1))
error3 = IP4_ERROR_TIME_EXPIRED;
- /* Verify header checksum. */
- if (verify_checksum)
- {
- ip_csum_t sum0, sum1, sum2, sum3;
-
- ip4_partial_header_checksum_x1 (ip[0], sum0);
- ip4_partial_header_checksum_x1 (ip[1], sum1);
- ip4_partial_header_checksum_x1 (ip[2], sum2);
- ip4_partial_header_checksum_x1 (ip[3], sum3);
-
- error0 = 0xffff != ip_csum_fold (sum0) ?
- IP4_ERROR_BAD_CHECKSUM : error0;
- error1 = 0xffff != ip_csum_fold (sum1) ?
- IP4_ERROR_BAD_CHECKSUM : error1;
- error2 = 0xffff != ip_csum_fold (sum2) ?
- IP4_ERROR_BAD_CHECKSUM : error2;
- error3 = 0xffff != ip_csum_fold (sum3) ?
- IP4_ERROR_BAD_CHECKSUM : error3;
- }
-
/* Drop fragmentation offset 1 packets. */
error0 = ip4_get_fragment_offset (ip[0]) == 1 ?
IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
@@ -226,34 +214,14 @@ ip4_input_check_x2 (vlib_main_t * vm,
error0 = error1 = IP4_ERROR_NONE;
- /* Punt packets with options or wrong version. */
- if (PREDICT_FALSE (ip0->ip_version_and_header_length != 0x45))
- error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ?
- IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
-
- if (PREDICT_FALSE (ip1->ip_version_and_header_length != 0x45))
- error1 = (ip1->ip_version_and_header_length & 0xf) != 5 ?
- IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
+ check_ver_opt_csum (ip0, &error0, verify_checksum);
+ check_ver_opt_csum (ip1, &error1, verify_checksum);
if (PREDICT_FALSE (ip0->ttl < 1))
error0 = IP4_ERROR_TIME_EXPIRED;
if (PREDICT_FALSE (ip1->ttl < 1))
error1 = IP4_ERROR_TIME_EXPIRED;
- /* Verify header checksum. */
- if (verify_checksum)
- {
- ip_csum_t sum0, sum1;
-
- ip4_partial_header_checksum_x1 (ip0, sum0);
- ip4_partial_header_checksum_x1 (ip1, sum1);
-
- error0 = 0xffff != ip_csum_fold (sum0) ?
- IP4_ERROR_BAD_CHECKSUM : error0;
- error1 = 0xffff != ip_csum_fold (sum1) ?
- IP4_ERROR_BAD_CHECKSUM : error1;
- }
-
/* Drop fragmentation offset 1 packets. */
error0 = ip4_get_fragment_offset (ip0) == 1 ?
IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
@@ -320,22 +288,13 @@ ip4_input_check_x1 (vlib_main_t * vm,
error0 = IP4_ERROR_NONE;
+ check_ver_opt_csum (ip0, &error0, verify_checksum);
+
/* Punt packets with options or wrong version. */
if (PREDICT_FALSE (ip0->ip_version_and_header_length != 0x45))
error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ?
IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
- /* Verify header checksum. */
- if (verify_checksum)
- {
- ip_csum_t sum0;
-
- ip4_partial_header_checksum_x1 (ip0, sum0);
-
- error0 = 0xffff != ip_csum_fold (sum0) ?
- IP4_ERROR_BAD_CHECKSUM : error0;
- }
-
/* Drop fragmentation offset 1 packets. */
error0 = ip4_get_fragment_offset (ip0) == 1 ?
IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;