X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip4_input.h;h=5df2154b2c35dad1db67dd554ca3ca495c88f1fe;hb=bf4d126b811c6ad00068fd04af652c982dc289c1;hp=e0873039990682f08ebd45a1fbd044bcb3713087;hpb=3ade6b668e0198611934e28c937f69ce6a12db16;p=vpp.git diff --git a/src/vnet/ip/ip4_input.h b/src/vnet/ip/ip4_input.h index e0873039990..5df2154b2c3 100644 --- a/src/vnet/ip/ip4_input.h +++ b/src/vnet/ip/ip4_input.h @@ -49,6 +49,7 @@ typedef enum { IP4_INPUT_NEXT_DROP, IP4_INPUT_NEXT_PUNT, + IP4_INPUT_NEXT_OPTIONS, IP4_INPUT_NEXT_LOOKUP, IP4_INPUT_NEXT_LOOKUP_MULTICAST, IP4_INPUT_NEXT_ICMP_ERROR, @@ -56,6 +57,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 +92,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 +106,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; @@ -165,7 +154,7 @@ ip4_input_check_x4 (vlib_main_t * vm, } else next[0] = error0 != IP4_ERROR_OPTIONS ? - IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT; + IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_OPTIONS; p[0]->error = error_node->errors[error0]; } if (PREDICT_FALSE (error1 != IP4_ERROR_NONE)) @@ -179,7 +168,7 @@ ip4_input_check_x4 (vlib_main_t * vm, } else next[1] = error1 != IP4_ERROR_OPTIONS ? - IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT; + IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_OPTIONS; p[1]->error = error_node->errors[error1]; } if (PREDICT_FALSE (error2 != IP4_ERROR_NONE)) @@ -193,7 +182,7 @@ ip4_input_check_x4 (vlib_main_t * vm, } else next[2] = error2 != IP4_ERROR_OPTIONS ? - IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT; + IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_OPTIONS; p[2]->error = error_node->errors[error2]; } if (PREDICT_FALSE (error3 != IP4_ERROR_NONE)) @@ -207,7 +196,7 @@ ip4_input_check_x4 (vlib_main_t * vm, } else next[3] = error3 != IP4_ERROR_OPTIONS ? - IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT; + IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_OPTIONS; p[3]->error = error_node->errors[error3]; } } @@ -226,34 +215,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; @@ -288,7 +257,7 @@ ip4_input_check_x2 (vlib_main_t * vm, } else *next0 = error0 != IP4_ERROR_OPTIONS ? - IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT; + IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_OPTIONS; p0->error = error_node->errors[error0]; } if (PREDICT_FALSE (error1 != IP4_ERROR_NONE)) @@ -302,10 +271,9 @@ ip4_input_check_x2 (vlib_main_t * vm, } else *next1 = error1 != IP4_ERROR_OPTIONS ? - IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT; + IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_OPTIONS; p1->error = error_node->errors[error1]; } - } always_inline void @@ -320,21 +288,10 @@ ip4_input_check_x1 (vlib_main_t * vm, error0 = 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; + check_ver_opt_csum (ip0, &error0, verify_checksum); - /* 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; - } + if (PREDICT_FALSE (ip0->ttl < 1)) + error0 = IP4_ERROR_TIME_EXPIRED; /* Drop fragmentation offset 1 packets. */ error0 = ip4_get_fragment_offset (ip0) == 1 ? @@ -363,10 +320,9 @@ ip4_input_check_x1 (vlib_main_t * vm, } else *next0 = error0 != IP4_ERROR_OPTIONS ? - IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT; + IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_OPTIONS; p0->error = error_node->errors[error0]; } - } /*