From patchwork Thu May 25 21:11:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chandran, Sugesh" X-Patchwork-Id: 767127 X-Patchwork-Delegate: dlu998@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wYhl80yXLz9s8N for ; Fri, 26 May 2017 07:11:16 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id EC8B6CB7; Thu, 25 May 2017 21:11:13 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id E8F69CAA for ; Thu, 25 May 2017 21:11:11 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 4792A19C for ; Thu, 25 May 2017 21:11:11 +0000 (UTC) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 May 2017 14:11:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,393,1491289200"; d="scan'208";a="91505260" Received: from silpixa00389816.ir.intel.com ([10.237.223.131]) by orsmga004.jf.intel.com with ESMTP; 25 May 2017 14:11:04 -0700 From: Sugesh Chandran To: ovs-dev@openvswitch.org Date: Thu, 25 May 2017 22:11:04 +0100 Message-Id: <1495746664-48559-1-git-send-email-sugesh.chandran@intel.com> X-Mailer: git-send-email 2.7.4 X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH] conntrack : Use Rx checksum offload feature on DPDK ports for conntrack. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Avoiding checksum validation in conntrack module if it is already verified in DPDK physical NIC ports. Signed-off-by: Sugesh Chandran --- lib/conntrack.c | 58 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index cb30ac7..af6a372 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -642,10 +642,13 @@ extract_l3_ipv6(struct conn_key *key, const void *data, size_t size, static inline bool checksum_valid(const struct conn_key *key, const void *data, size_t size, - const void *l3) + const void *l3, bool validate_checksum) { uint32_t csum = 0; + if (!validate_checksum) { + return true; + } if (key->dl_type == htons(ETH_TYPE_IP)) { csum = packet_csum_pseudoheader(l3); } else if (key->dl_type == htons(ETH_TYPE_IPV6)) { @@ -661,7 +664,7 @@ checksum_valid(const struct conn_key *key, const void *data, size_t size, static inline bool check_l4_tcp(const struct conn_key *key, const void *data, size_t size, - const void *l3) + const void *l3, bool validate_checksum) { const struct tcp_header *tcp = data; if (size < sizeof *tcp) { @@ -673,12 +676,12 @@ check_l4_tcp(const struct conn_key *key, const void *data, size_t size, return false; } - return checksum_valid(key, data, size, l3); + return checksum_valid(key, data, size, l3, validate_checksum); } static inline bool check_l4_udp(const struct conn_key *key, const void *data, size_t size, - const void *l3) + const void *l3, bool validate_checksum) { const struct udp_header *udp = data; if (size < sizeof *udp) { @@ -692,20 +695,23 @@ check_l4_udp(const struct conn_key *key, const void *data, size_t size, /* Validation must be skipped if checksum is 0 on IPv4 packets */ return (udp->udp_csum == 0 && key->dl_type == htons(ETH_TYPE_IP)) - || checksum_valid(key, data, size, l3); + || checksum_valid(key, data, size, l3, validate_checksum); } static inline bool -check_l4_icmp(const void *data, size_t size) +check_l4_icmp(const void *data, size_t size, bool validate_checksum) { - return csum(data, size) == 0; + if (validate_checksum) { + return csum(data, size) == 0; + } + return true; } static inline bool check_l4_icmp6(const struct conn_key *key, const void *data, size_t size, - const void *l3) + const void *l3, bool validate_checksum) { - return checksum_valid(key, data, size, l3); + return checksum_valid(key, data, size, l3, validate_checksum); } static inline bool @@ -741,7 +747,8 @@ extract_l4_udp(struct conn_key *key, const void *data, size_t size) } static inline bool extract_l4(struct conn_key *key, const void *data, - size_t size, bool *related, const void *l3); + size_t size, bool *related, const void *l3, + bool validate_checksum); static uint8_t reverse_icmp_type(uint8_t type) @@ -830,7 +837,7 @@ extract_l4_icmp(struct conn_key *key, const void *data, size_t size, key->dst = inner_key.dst; key->nw_proto = inner_key.nw_proto; - ok = extract_l4(key, l4, tail - l4, NULL, l3); + ok = extract_l4(key, l4, tail - l4, NULL, l3, false); if (ok) { conn_key_reverse(key); *related = true; @@ -920,7 +927,7 @@ extract_l4_icmp6(struct conn_key *key, const void *data, size_t size, key->dst = inner_key.dst; key->nw_proto = inner_key.nw_proto; - ok = extract_l4(key, l4, tail - l4, NULL, l3); + ok = extract_l4(key, l4, tail - l4, NULL, l3, false); if (ok) { conn_key_reverse(key); *related = true; @@ -945,21 +952,22 @@ extract_l4_icmp6(struct conn_key *key, const void *data, size_t size, * in an ICMP error. In this case, we skip checksum and length validation. */ static inline bool extract_l4(struct conn_key *key, const void *data, size_t size, bool *related, - const void *l3) + const void *l3, bool validate_checksum) { if (key->nw_proto == IPPROTO_TCP) { - return (!related || check_l4_tcp(key, data, size, l3)) - && extract_l4_tcp(key, data, size); + return (!related || check_l4_tcp(key, data, size, l3, + validate_checksum)) && extract_l4_tcp(key, data, size); } else if (key->nw_proto == IPPROTO_UDP) { - return (!related || check_l4_udp(key, data, size, l3)) - && extract_l4_udp(key, data, size); + return (!related || check_l4_udp(key, data, size, l3, + validate_checksum)) && extract_l4_udp(key, data, size); } else if (key->dl_type == htons(ETH_TYPE_IP) && key->nw_proto == IPPROTO_ICMP) { - return (!related || check_l4_icmp(data, size)) + return (!related || check_l4_icmp(data, size, validate_checksum)) && extract_l4_icmp(key, data, size, related); } else if (key->dl_type == htons(ETH_TYPE_IPV6) && key->nw_proto == IPPROTO_ICMPV6) { - return (!related || check_l4_icmp6(key, data, size, l3)) + return (!related || check_l4_icmp6(key, data, size, l3, + validate_checksum)) && extract_l4_icmp6(key, data, size, related); } else { return false; @@ -975,6 +983,8 @@ conn_key_extract(struct conntrack *ct, struct dp_packet *pkt, ovs_be16 dl_type, const char *l4 = dp_packet_l4(pkt); const char *tail = dp_packet_tail(pkt); bool ok; + bool valid_l4_csum = 0; + bool valid_l3_csum = 0; memset(ctx, 0, sizeof *ctx); @@ -1018,7 +1028,10 @@ conn_key_extract(struct conntrack *ct, struct dp_packet *pkt, ovs_be16 dl_type, */ ctx->key.dl_type = dl_type; if (ctx->key.dl_type == htons(ETH_TYPE_IP)) { - ok = extract_l3_ipv4(&ctx->key, l3, tail - (char *) l3, NULL, true); + valid_l3_csum = dp_packet_ip_checksum_valid(pkt); + /* Validate the checksum only when the csum is invalid */ + ok = extract_l3_ipv4(&ctx->key, l3, tail - (char *) l3, NULL, + !valid_l3_csum); } else if (ctx->key.dl_type == htons(ETH_TYPE_IPV6)) { ok = extract_l3_ipv6(&ctx->key, l3, tail - (char *) l3, NULL); } else { @@ -1026,7 +1039,10 @@ conn_key_extract(struct conntrack *ct, struct dp_packet *pkt, ovs_be16 dl_type, } if (ok) { - if (extract_l4(&ctx->key, l4, tail - l4, &ctx->related, l3)) { + valid_l4_csum = dp_packet_l4_checksum_valid(pkt); + /* Validate the ckecksum only when the checksum is not valid/unset */ + if (extract_l4(&ctx->key, l4, tail - l4, &ctx->related, l3, + !valid_l4_csum)) { ctx->hash = conn_key_hash(&ctx->key, ct->hash_basis); return true; }