From patchwork Sun Nov 29 03:32:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: hepeng X-Patchwork-Id: 1407787 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=bytedance.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=bytedance-com.20150623.gappssmtp.com header.i=@bytedance-com.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=rv9yDSOw; dkim-atps=neutral Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CkDV22YF0z9sSf for ; Sun, 29 Nov 2020 14:33:30 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 792228753C; Sun, 29 Nov 2020 03:33:28 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Rb6+9O7f04rN; Sun, 29 Nov 2020 03:33:26 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 2B70787538; Sun, 29 Nov 2020 03:33:26 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 12BBAC0891; Sun, 29 Nov 2020 03:33:26 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 889D1C0052 for ; Sun, 29 Nov 2020 03:33:24 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 7FA84875A1 for ; Sun, 29 Nov 2020 03:33:24 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id f6IWnw2MIYkS for ; Sun, 29 Nov 2020 03:33:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by whitealder.osuosl.org (Postfix) with ESMTPS id 340E98732A for ; Sun, 29 Nov 2020 03:33:21 +0000 (UTC) Received: by mail-pf1-f196.google.com with SMTP id w6so7951569pfu.1 for ; Sat, 28 Nov 2020 19:33:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=X1osJ3Nmndc5e8Kh6pYmRhzilsDkGZ5EU3aVoiZNM/c=; b=rv9yDSOwVtq5hit/5+PUyiAoBVLHRlAPwLMtCbqrjt9IydcUBPYQ6Fi1KPn4WV/sfW bElTR2uJsC55JlVH09I/B2X8GjimgeGxjxRm6UNDT7twiMuGkxj9xU23B/tt5IWZxvyD 2KxnlKToueAtjwO648142O06gVLrxtYZLX2npxw0m0eGELahFDNqf+UPu5Ij5AmJCxtp Jlo57hW1rey2fbT/4vqDGw0oH7LYIYBWerO2K73ivO8WRp9fHtVP1oWS5ywt2eexxNoT MiqgGBzMNAS4LQju41g0F5gZENPqBlP1APESv/CR217eSSnyMPXNJuHHEaawRR5ry+X7 Zidw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=X1osJ3Nmndc5e8Kh6pYmRhzilsDkGZ5EU3aVoiZNM/c=; b=n/NgJfeyl1kgyYBH6oedLe/cu/JPHmtfCkk2tm2sbT2xe4dyz6c0w54Siy7zEICUxG 8nw58ipl1SDA8O4bZrG4bgvyZNvxhyEtrXZ+1fN1AxgTPjucl4QbLSEywvhwhlrmIh8+ ifzVChwPJxcE+LgnZPSOISf7Z/FHXJ3SnzXmKda7fiAp9IPgKe40Q9lM8/dR2TSvT5sq tTttZ1KiFj6SH9Clnl7NDxQcgwEX0ltKHju7ROuQmcwe8L4W3HqNTkG8Xm7Xgib37+yE 0E8GKVWHa7Fl18ePqrvRikRiVXpUaOZZ5yxvgDdV1OT3y2nM+efWwAO3yGExv4XPARm6 lNYg== X-Gm-Message-State: AOAM533wBnotekTg5xhbdBwFeUOcnWt08rmyvOtEnIY2A7BBCo1HajjU tB5N11o90Z+fmKVwVWm80kXweEuM5IupyA== X-Google-Smtp-Source: ABdhPJwQ/8FK9p/ZujXiSzdN0BdFdSedFkfRhcO192qF61VWAN/5A0fe/ZrR/Oi2BfuEJUQdyUxrCQ== X-Received: by 2002:a17:90a:154a:: with SMTP id y10mr19393271pja.6.1606620800538; Sat, 28 Nov 2020 19:33:20 -0800 (PST) Received: from localhost ([103.136.221.73]) by smtp.gmail.com with ESMTPSA id e17sm11582634pfm.155.2020.11.28.19.33.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Nov 2020 19:33:20 -0800 (PST) From: "hepeng.0320" To: dev@openvswitch.org, u9012063@gmail.com Date: Sun, 29 Nov 2020 11:32:53 +0800 Message-Id: <20201129033255.64647-3-hepeng.0320@bytedance.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20201129033255.64647-1-hepeng.0320@bytedance.com> References: <20201129033255.64647-1-hepeng.0320@bytedance.com> MIME-Version: 1.0 Cc: i.maximets@ovn.org Subject: [ovs-dev] [PATCH 2/4] conntrack: remove redundant comparation in nat_packet and un_nat_packet X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: hepeng In this patch, we split pat_packet and un_pat_packet function into _src and _dst two functions. When calling this two functions, we can usually infer the specific nat actions from the caller. This patch makes the conntrack code cleaner. Signed-off-by: Peng He --- lib/conntrack.c | 261 ++++++++++++++++++++++++++++-------------------- 1 file changed, 152 insertions(+), 109 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index 73d3a2fb2..a22252a63 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -701,24 +701,26 @@ handle_alg_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, } static void -pat_packet(struct dp_packet *pkt, const struct conn *conn) +pat_packet_src(struct dp_packet *pkt, const struct conn *conn) { - if (conn->conn_flags & NAT_ACTION_SRC) { - if (conn->key.nw_proto == IPPROTO_TCP) { - struct tcp_header *th = dp_packet_l4(pkt); - packet_set_tcp_port(pkt, conn->rev_key.dst.port, th->tcp_dst); - } else if (conn->key.nw_proto == IPPROTO_UDP) { - struct udp_header *uh = dp_packet_l4(pkt); - packet_set_udp_port(pkt, conn->rev_key.dst.port, uh->udp_dst); - } - } else if (conn->conn_flags & NAT_ACTION_DST) { - if (conn->key.nw_proto == IPPROTO_TCP) { - struct tcp_header *th = dp_packet_l4(pkt); - packet_set_tcp_port(pkt, th->tcp_src, conn->rev_key.src.port); - } else if (conn->key.nw_proto == IPPROTO_UDP) { - struct udp_header *uh = dp_packet_l4(pkt); - packet_set_udp_port(pkt, uh->udp_src, conn->rev_key.src.port); - } + if (conn->key.nw_proto == IPPROTO_TCP) { + struct tcp_header *th = dp_packet_l4(pkt); + packet_set_tcp_port(pkt, conn->rev_key.dst.port, th->tcp_dst); + } else if (conn->key.nw_proto == IPPROTO_UDP) { + struct udp_header *uh = dp_packet_l4(pkt); + packet_set_udp_port(pkt, conn->rev_key.dst.port, uh->udp_dst); + } +} + +static void +pat_packet_dst(struct dp_packet *pkt, const struct conn *conn) +{ + if (conn->key.nw_proto == IPPROTO_TCP) { + struct tcp_header *th = dp_packet_l4(pkt); + packet_set_tcp_port(pkt, th->tcp_src, conn->rev_key.src.port); + } else if (conn->key.nw_proto == IPPROTO_UDP) { + struct udp_header *uh = dp_packet_l4(pkt); + packet_set_udp_port(pkt, uh->udp_src, conn->rev_key.src.port); } } @@ -738,7 +740,7 @@ nat_packet(struct dp_packet *pkt, const struct conn *conn, bool related) &conn->rev_key.dst.addr.ipv6, true); } if (!related) { - pat_packet(pkt, conn); + pat_packet_src(pkt, conn); } } else if (conn->conn_flags & NAT_ACTION_DST) { pkt->md.ct_state |= CS_DST_NAT; @@ -753,61 +755,92 @@ nat_packet(struct dp_packet *pkt, const struct conn *conn, bool related) &conn->rev_key.src.addr.ipv6, true); } if (!related) { - pat_packet(pkt, conn); + pat_packet_dst(pkt, conn); } } } static void -un_pat_packet(struct dp_packet *pkt, const struct conn *conn) +un_pat_packet_src(struct dp_packet *pkt, const struct conn *conn) { - if (conn->conn_flags & NAT_ACTION_SRC) { - if (conn->key.nw_proto == IPPROTO_TCP) { - struct tcp_header *th = dp_packet_l4(pkt); - packet_set_tcp_port(pkt, th->tcp_src, conn->key.src.port); - } else if (conn->key.nw_proto == IPPROTO_UDP) { - struct udp_header *uh = dp_packet_l4(pkt); - packet_set_udp_port(pkt, uh->udp_src, conn->key.src.port); - } - } else if (conn->conn_flags & NAT_ACTION_DST) { - if (conn->key.nw_proto == IPPROTO_TCP) { - struct tcp_header *th = dp_packet_l4(pkt); - packet_set_tcp_port(pkt, conn->key.dst.port, th->tcp_dst); - } else if (conn->key.nw_proto == IPPROTO_UDP) { - struct udp_header *uh = dp_packet_l4(pkt); - packet_set_udp_port(pkt, conn->key.dst.port, uh->udp_dst); - } + if (conn->key.nw_proto == IPPROTO_TCP) { + struct tcp_header *th = dp_packet_l4(pkt); + packet_set_tcp_port(pkt, th->tcp_src, conn->key.src.port); + } else if (conn->key.nw_proto == IPPROTO_UDP) { + struct udp_header *uh = dp_packet_l4(pkt); + packet_set_udp_port(pkt, uh->udp_src, conn->key.src.port); } } static void -reverse_pat_packet(struct dp_packet *pkt, const struct conn *conn) +un_pat_packet_dst(struct dp_packet *pkt, const struct conn *conn) { - if (conn->conn_flags & NAT_ACTION_SRC) { - if (conn->key.nw_proto == IPPROTO_TCP) { - struct tcp_header *th_in = dp_packet_l4(pkt); - packet_set_tcp_port(pkt, conn->key.src.port, - th_in->tcp_dst); - } else if (conn->key.nw_proto == IPPROTO_UDP) { - struct udp_header *uh_in = dp_packet_l4(pkt); - packet_set_udp_port(pkt, conn->key.src.port, - uh_in->udp_dst); - } - } else if (conn->conn_flags & NAT_ACTION_DST) { - if (conn->key.nw_proto == IPPROTO_TCP) { - struct tcp_header *th_in = dp_packet_l4(pkt); - packet_set_tcp_port(pkt, th_in->tcp_src, - conn->key.dst.port); - } else if (conn->key.nw_proto == IPPROTO_UDP) { - struct udp_header *uh_in = dp_packet_l4(pkt); - packet_set_udp_port(pkt, uh_in->udp_src, - conn->key.dst.port); - } + if (conn->key.nw_proto == IPPROTO_TCP) { + struct tcp_header *th = dp_packet_l4(pkt); + packet_set_tcp_port(pkt, conn->key.dst.port, th->tcp_dst); + } else if (conn->key.nw_proto == IPPROTO_UDP) { + struct udp_header *uh = dp_packet_l4(pkt); + packet_set_udp_port(pkt, conn->key.dst.port, uh->udp_dst); + } +} + +static void +reverse_pat_packet_src(struct dp_packet *pkt, const struct conn *conn) +{ + if (conn->key.nw_proto == IPPROTO_TCP) { + struct tcp_header *th_in = dp_packet_l4(pkt); + packet_set_tcp_port(pkt, conn->key.src.port, + th_in->tcp_dst); + } else if (conn->key.nw_proto == IPPROTO_UDP) { + struct udp_header *uh_in = dp_packet_l4(pkt); + packet_set_udp_port(pkt, conn->key.src.port, + uh_in->udp_dst); } } static void -reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn) +reverse_pat_packet_dst(struct dp_packet *pkt, const struct conn *conn) +{ + if (conn->key.nw_proto == IPPROTO_TCP) { + struct tcp_header *th_in = dp_packet_l4(pkt); + packet_set_tcp_port(pkt, th_in->tcp_src, + conn->key.dst.port); + } else if (conn->key.nw_proto == IPPROTO_UDP) { + struct udp_header *uh_in = dp_packet_l4(pkt); + packet_set_udp_port(pkt, uh_in->udp_src, + conn->key.dst.port); + } +} + +static void do_nat4_src(struct dp_packet *pkt, struct ip_header *inner_l3, const struct conn *conn) +{ + packet_set_ipv4_addr(pkt, &inner_l3->ip_src, conn->key.src.addr.ipv4); + reverse_pat_packet_src(pkt, conn); +} + +static void do_nat4_dst(struct dp_packet *pkt, struct ip_header *inner_l3, const struct conn *conn) +{ + packet_set_ipv4_addr(pkt, &inner_l3->ip_dst, conn->key.dst.addr.ipv4); + reverse_pat_packet_dst(pkt, conn); +} + +static void do_nat6_src(struct dp_packet *pkt, struct ovs_16aligned_ip6_hdr *inner_l3_6, const struct conn *conn) +{ + packet_set_ipv6_addr(pkt, conn->key.nw_proto, inner_l3_6->ip6_src.be32, + &conn->key.src.addr.ipv6, true); + reverse_pat_packet_src(pkt, conn); +} + +static void do_nat6_dst(struct dp_packet *pkt, struct ovs_16aligned_ip6_hdr *inner_l3_6, const struct conn *conn) +{ + packet_set_ipv6_addr(pkt, conn->key.nw_proto, inner_l3_6->ip6_dst.be32, + &conn->key.dst.addr.ipv6, true); + reverse_pat_packet_dst(pkt, conn); +} + +static void +reverse_nat_packet4(struct dp_packet *pkt, const struct conn *conn, + void (*do_nat4)(struct dp_packet *, struct ip_header *, const struct conn *conn)) { char *tail = dp_packet_tail(pkt); uint8_t pad = dp_packet_l2_pad_size(pkt); @@ -816,57 +849,67 @@ reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn) uint16_t orig_l3_ofs = pkt->l3_ofs; uint16_t orig_l4_ofs = pkt->l4_ofs; - if (conn->key.dl_type == htons(ETH_TYPE_IP)) { - struct ip_header *nh = dp_packet_l3(pkt); - struct icmp_header *icmp = dp_packet_l4(pkt); - struct ip_header *inner_l3 = (struct ip_header *) (icmp + 1); - /* This call is already verified to succeed during the code path from - * 'conn_key_extract()' which calls 'extract_l4_icmp()'. */ - extract_l3_ipv4(&inner_key, inner_l3, tail - ((char *)inner_l3) - pad, - &inner_l4, false); - pkt->l3_ofs += (char *) inner_l3 - (char *) nh; - pkt->l4_ofs += inner_l4 - (char *) icmp; - - if (conn->conn_flags & NAT_ACTION_SRC) { - packet_set_ipv4_addr(pkt, &inner_l3->ip_src, - conn->key.src.addr.ipv4); - } else if (conn->conn_flags & NAT_ACTION_DST) { - packet_set_ipv4_addr(pkt, &inner_l3->ip_dst, - conn->key.dst.addr.ipv4); - } + struct ip_header *nh = dp_packet_l3(pkt); + struct icmp_header *icmp = dp_packet_l4(pkt); + struct ip_header *inner_l3 = (struct ip_header *) (icmp + 1); + /* This call is already verified to succeed during the code path from + * 'conn_key_extract()' which calls 'extract_l4_icmp()'. */ + extract_l3_ipv4(&inner_key, inner_l3, tail - ((char *)inner_l3) - pad, + &inner_l4, false); + pkt->l3_ofs += (char *) inner_l3 - (char *) nh; + pkt->l4_ofs += inner_l4 - (char *) icmp; - reverse_pat_packet(pkt, conn); - icmp->icmp_csum = 0; - icmp->icmp_csum = csum(icmp, tail - (char *) icmp - pad); - } else { - struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt); - struct icmp6_data_header *icmp6 = dp_packet_l4(pkt); - struct ovs_16aligned_ip6_hdr *inner_l3_6 = - (struct ovs_16aligned_ip6_hdr *) (icmp6 + 1); - /* This call is already verified to succeed during the code path from - * 'conn_key_extract()' which calls 'extract_l4_icmp6()'. */ - extract_l3_ipv6(&inner_key, inner_l3_6, - tail - ((char *)inner_l3_6) - pad, - &inner_l4); - pkt->l3_ofs += (char *) inner_l3_6 - (char *) nh6; - pkt->l4_ofs += inner_l4 - (char *) icmp6; - - if (conn->conn_flags & NAT_ACTION_SRC) { - packet_set_ipv6_addr(pkt, conn->key.nw_proto, - inner_l3_6->ip6_src.be32, - &conn->key.src.addr.ipv6, true); - } else if (conn->conn_flags & NAT_ACTION_DST) { - packet_set_ipv6_addr(pkt, conn->key.nw_proto, - inner_l3_6->ip6_dst.be32, - &conn->key.dst.addr.ipv6, true); - } - reverse_pat_packet(pkt, conn); - icmp6->icmp6_base.icmp6_cksum = 0; - icmp6->icmp6_base.icmp6_cksum = packet_csum_upperlayer6(nh6, icmp6, + do_nat4(pkt, inner_l3, conn); + icmp->icmp_csum = 0; + icmp->icmp_csum = csum(icmp, tail - (char *) icmp - pad); + + pkt->l3_ofs = orig_l3_ofs; + pkt->l4_ofs = orig_l4_ofs; +} + +static void +reverse_nat_packet6(struct dp_packet *pkt, const struct conn *conn, + void (*do_nat6)(struct dp_packet *, struct ovs_16aligned_ip6_hdr *, const struct conn *)) +{ + char *tail = dp_packet_tail(pkt); + uint8_t pad = dp_packet_l2_pad_size(pkt); + struct conn_key inner_key; + const char *inner_l4 = NULL; + uint16_t orig_l3_ofs = pkt->l3_ofs; + uint16_t orig_l4_ofs = pkt->l4_ofs; + + struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt); + struct icmp6_data_header *icmp6 = dp_packet_l4(pkt); + struct ovs_16aligned_ip6_hdr *inner_l3_6 = + (struct ovs_16aligned_ip6_hdr *) (icmp6 + 1); + /* This call is already verified to succeed during the code path from + * 'conn_key_extract()' which calls 'extract_l4_icmp6()'. */ + extract_l3_ipv6(&inner_key, inner_l3_6, + tail - ((char *)inner_l3_6) - pad, + &inner_l4); + pkt->l3_ofs += (char *) inner_l3_6 - (char *) nh6; + pkt->l4_ofs += inner_l4 - (char *) icmp6; + + do_nat6(pkt, inner_l3_6, conn); + icmp6->icmp6_base.icmp6_cksum = 0; + icmp6->icmp6_base.icmp6_cksum = packet_csum_upperlayer6(nh6, icmp6, IPPROTO_ICMPV6, tail - (char *) icmp6 - pad); - } + pkt->l3_ofs = orig_l3_ofs; pkt->l4_ofs = orig_l4_ofs; + +} + +static void +reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn, + void (*do_nat4)(struct dp_packet *, struct ip_header *, const struct conn *), + void (*do_nat6)(struct dp_packet *, struct ovs_16aligned_ip6_hdr *, const struct conn *)) +{ + if (conn->key.dl_type == htons(ETH_TYPE_IP)) { + reverse_nat_packet4(pkt, conn, do_nat4); + } else { + reverse_nat_packet6(pkt, conn, do_nat6); + } } static void @@ -886,9 +929,9 @@ un_nat_packet(struct dp_packet *pkt, const struct conn *conn, bool related) } if (OVS_UNLIKELY(related)) { - reverse_nat_packet(pkt, conn); + reverse_nat_packet(pkt, conn, do_nat4_src, do_nat6_src); } else { - un_pat_packet(pkt, conn); + un_pat_packet_src(pkt, conn); } } else if (conn->conn_flags & NAT_ACTION_DST) { pkt->md.ct_state |= CS_SRC_NAT; @@ -904,9 +947,9 @@ un_nat_packet(struct dp_packet *pkt, const struct conn *conn, bool related) } if (OVS_UNLIKELY(related)) { - reverse_nat_packet(pkt, conn); + reverse_nat_packet(pkt, conn, do_nat4_dst, do_nat6_dst); } else { - un_pat_packet(pkt, conn); + un_pat_packet_dst(pkt, conn); } } }