From patchwork Sun Feb 4 16:22:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869044 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="i85hm8Ba"; dkim-atps=neutral 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 3zZGHZ2vz8z9s7M for ; Mon, 5 Feb 2018 03:23:38 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2361BF18; Sun, 4 Feb 2018 16:23:03 +0000 (UTC) X-Original-To: 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 058BCF04 for ; Sun, 4 Feb 2018 16:23:01 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f66.google.com (mail-pl0-f66.google.com [209.85.160.66]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id ADE2A305 for ; Sun, 4 Feb 2018 16:23:00 +0000 (UTC) Received: by mail-pl0-f66.google.com with SMTP id ay8so10121637plb.4 for ; Sun, 04 Feb 2018 08:23:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=sW1uQxFx8LNPIdjVLSA3IhnNI1wj2ficwrAnn9ns9mA=; b=i85hm8BavS79Q2NwOf0kgZSPYdomydcUOCf6tsL1NpWyD2OTWNedeF1hNlkltXosvS 6rnIMZcqTcdNo+b9+0EIg7/BsJ4SZLFAjU+ouT5ubca7h+fVIoKJC3TQpxfBZOCSTJvp mV6ElZ4gBKyxXckDFh6FbWQI+fcKrtwbdHYZujA/A4AopjxG5Ymz1wUB5vIcb6pLoEzW VFTGLSJ9g+EfsItfSPH39cNksG4PMu3a80r2HAteiJa1iB1sEvHKhW9pJSJYaw/SGw93 Adhgpnq94HcY+6cUGEBnI8ENrL8wErcYEz/pMxAUDI4PKqy9NHbRxsng9oN/xQSoxLtm aD8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=sW1uQxFx8LNPIdjVLSA3IhnNI1wj2ficwrAnn9ns9mA=; b=T4QWUNHYaGoMAqgYyGDgkq2QoP0nW84MmKF1ZHpsRW71io8p9TFN3GLt6Ye7KfdZ1G 7IwXhcS+t2yCrHHGqqAJrJ11bUlPCCpmzUHJyAyfMtEpzQD38AJO+RuA1ll1ekJA00we ns2wPO6/S4CjwJ7vbX6dPYLB4WamPXpGKCw7IevypYeu0PcYuTKHO+1jv4bg0b9nlXgg ZO/YTLaIe2omXsPlSQi5AaL8VBQUjVLuXLRBEsirdb98I6LZYqUUZPfJ0k1CB7SrINIT MQ33AP3vNF3voTSV5E20DlL4dEdItqPjpzFIc/Eu+JAmXhev4/XMZkFTyIs5BQudPGC2 0Dlg== X-Gm-Message-State: AKwxytdGgP+qxEc1BWfLLxAAGtDphKnL5kVIsEXAZkdihvG2LhGXefWt K/ezRO5Mr0MWhXkqwKfSGoHHAg== X-Google-Smtp-Source: AH8x2257MRgbdzgfy7IBOYSRMLDc57gKTO9DcfJpgkjmZ05VbE49NatQOI11Cg9vSHWspMF8TSexAQ== X-Received: by 2002:a17:902:d904:: with SMTP id c4-v6mr20867376plz.125.1517761380349; Sun, 04 Feb 2018 08:23:00 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.22.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:22:59 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:34 -0800 Message-Id: <1517761364-17655-2-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 01/11] dp-packet: Add const qualifiers for checksum apis. 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 Signed-off-by: Darrell Ball Acked-by: Justin Pettit --- lib/dp-packet.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dp-packet.h b/lib/dp-packet.h index b4b721c..61d4cd4 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -637,7 +637,7 @@ dp_packet_mbuf_init(struct dp_packet *p OVS_UNUSED) } static inline bool -dp_packet_ip_checksum_valid(struct dp_packet *p OVS_UNUSED) +dp_packet_ip_checksum_valid(const struct dp_packet *p OVS_UNUSED) { #ifdef DPDK_NETDEV return (p->mbuf.ol_flags & PKT_RX_IP_CKSUM_MASK) == @@ -648,7 +648,7 @@ dp_packet_ip_checksum_valid(struct dp_packet *p OVS_UNUSED) } static inline bool -dp_packet_ip_checksum_bad(struct dp_packet *p OVS_UNUSED) +dp_packet_ip_checksum_bad(const struct dp_packet *p OVS_UNUSED) { #ifdef DPDK_NETDEV return (p->mbuf.ol_flags & PKT_RX_IP_CKSUM_MASK) == From patchwork Sun Feb 4 16:22:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869045 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="GV0uCOsj"; dkim-atps=neutral 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 3zZGJC3CtDz9s7v for ; Mon, 5 Feb 2018 03:24:11 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 01AFAF46; Sun, 4 Feb 2018 16:23:04 +0000 (UTC) X-Original-To: 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 E7404F21 for ; Sun, 4 Feb 2018 16:23:01 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f68.google.com (mail-pl0-f68.google.com [209.85.160.68]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 9671B305 for ; Sun, 4 Feb 2018 16:23:01 +0000 (UTC) Received: by mail-pl0-f68.google.com with SMTP id 13so10122000plb.5 for ; Sun, 04 Feb 2018 08:23:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=9mh92J/nvuUIG3sa0DER1PmJsmHisHlZHLuek82WkrY=; b=GV0uCOsj590EbMfs6951KY783Z++5PD4v7jkk1ms+F5dx/maOv5CDaFjzoVRnM0drO 2NuTA6N6K0UwfFsg5U9QxtiF9TumeWt0X2io7i6NR4wex4TVu+0I6iJrokkycWX/h9yY Lt+D+cMlXk+0WchYfsZtgtPLzSt2Nf+UREzjRSlrcjjFsSYayiP9UeMoPAjB+0q6hyKO wiRTLZRiM2PuNUfXkuF0rTgaVheiH3US9Xv7A2XEdjcLZ7SbRQ2859E8ellw1nRwkkTE r2+PHiBF3b7W8McMXt7z0yu3vYLXqnMtK0J05WedDJLBx/+bCi4Z5SXXkSvLWe3vj29r 5B2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=9mh92J/nvuUIG3sa0DER1PmJsmHisHlZHLuek82WkrY=; b=oVvB38m3Q+wQRP0IIbitmz+w6A3dFjVRh84ytSCWCnfKN+vv24+pbzunBgQrpfHQ8+ iDeJgo/kIRhbQXeS21HMsDZglrTy6evGBmePpg4pt6SjSkDLM5TUMEYzgTRjLFGal+hS /+MxcZQoYX52ZNfTj05PXrXbxzT9/sL4uWgL94Q9xGsha9nt6EBjOClwtfiLJR6rHwK6 6aG1vVe32reb9zW2rU30nt5bsZEtNDU7p+LhPU5DwItlEwRTR6Jbk78bG5CiNRvR7dEr M4hc2x/qA1JiPWFFmKe3Lo+dvxrvEOdP4qrm8tNlkYeZwgipo/1DPrfu4focxglSilFL TLfg== X-Gm-Message-State: AKwxytcM2SMUGTxPG1p2ppq2Bs/HjTVsq71HEteJD6m6W8U5F8ddWhaT zLW9OugAkKuVaM3NtTvnNz8= X-Google-Smtp-Source: AH8x224MeNKq8KOrPNpT2U2jiGANZsiMhgyydscgBaX6mxrSj6CmaZikojW18LA92jzPW5pKodhX6w== X-Received: by 2002:a17:902:a589:: with SMTP id az9-v6mr20186034plb.298.1517761381148; Sun, 04 Feb 2018 08:23:01 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:00 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:35 -0800 Message-Id: <1517761364-17655-3-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 02/11] flow: Enhance parse_ipv6_ext_hdrs. 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 Enhance the api parse_ipv6_ext_hdrs to return the fragmentation header to be used in later patches. Signed-off-by: Darrell Ball Acked-by: Justin Pettit --- lib/conntrack.c | 5 +++-- lib/flow.c | 23 ++++++++++++++--------- lib/flow.h | 3 ++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index fe5fd0f..d34eb32 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -1308,7 +1308,6 @@ conntrack_execute(struct conntrack *ct, struct dp_packet_batch *pkt_batch, const struct nat_action_info_t *nat_action_info, long long now) { - struct dp_packet *packet; struct conn_lookup_ctx ctx; @@ -1566,7 +1565,9 @@ extract_l3_ipv6(struct conn_key *key, const void *data, size_t size, uint8_t nw_proto = ip6->ip6_nxt; uint8_t nw_frag = 0; - if (!parse_ipv6_ext_hdrs(&data, &size, &nw_proto, &nw_frag)) { + const struct ovs_16aligned_ip6_frag *frag_hdr; + if (!parse_ipv6_ext_hdrs(&data, &size, &nw_proto, &nw_frag, + &frag_hdr)) { return false; } diff --git a/lib/flow.c b/lib/flow.c index 38ff29c..0283e6d 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -455,7 +455,8 @@ invalid: static inline bool parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto, - uint8_t *nw_frag) + uint8_t *nw_frag, + const struct ovs_16aligned_ip6_frag **frag_hdr) { while (1) { if (OVS_LIKELY((*nw_proto != IPPROTO_HOPOPTS) @@ -502,17 +503,17 @@ parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto, return false; } } else if (*nw_proto == IPPROTO_FRAGMENT) { - const struct ovs_16aligned_ip6_frag *frag_hdr = *datap; + *frag_hdr = *datap; - *nw_proto = frag_hdr->ip6f_nxt; - if (!data_try_pull(datap, sizep, sizeof *frag_hdr)) { + *nw_proto = (*frag_hdr)->ip6f_nxt; + if (!data_try_pull(datap, sizep, sizeof **frag_hdr)) { return false; } /* We only process the first fragment. */ - if (frag_hdr->ip6f_offlg != htons(0)) { + if ((*frag_hdr)->ip6f_offlg != htons(0)) { *nw_frag = FLOW_NW_FRAG_ANY; - if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) { + if (((*frag_hdr)->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) { *nw_frag |= FLOW_NW_FRAG_LATER; *nw_proto = IPPROTO_FRAGMENT; return true; @@ -524,9 +525,11 @@ parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto, bool parse_ipv6_ext_hdrs(const void **datap, size_t *sizep, uint8_t *nw_proto, - uint8_t *nw_frag) + uint8_t *nw_frag, + const struct ovs_16aligned_ip6_frag **frag_hdr) { - return parse_ipv6_ext_hdrs__(datap, sizep, nw_proto, nw_frag); + return parse_ipv6_ext_hdrs__(datap, sizep, nw_proto, nw_frag, + frag_hdr); } bool @@ -840,7 +843,9 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) nw_ttl = nh->ip6_hlim; nw_proto = nh->ip6_nxt; - if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag)) { + const struct ovs_16aligned_ip6_frag *frag_hdr; + if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag, + &frag_hdr)) { goto out; } } else { diff --git a/lib/flow.h b/lib/flow.h index 770a07a..7a9eb47 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -129,7 +129,8 @@ void flow_compose(struct dp_packet *, const struct flow *, void packet_expand(struct dp_packet *, const struct flow *, size_t size); bool parse_ipv6_ext_hdrs(const void **datap, size_t *sizep, uint8_t *nw_proto, - uint8_t *nw_frag); + uint8_t *nw_frag, + const struct ovs_16aligned_ip6_frag **frag_hdr); ovs_be16 parse_dl_type(const struct eth_header *data_, size_t size); bool parse_nsh(const void **datap, size_t *sizep, struct ovs_key_nsh *key); From patchwork Sun Feb 4 16:22:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869047 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PlWj7ejY"; dkim-atps=neutral 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 3zZGKg6TfFz9s7v for ; Mon, 5 Feb 2018 03:25:27 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2142CF98; Sun, 4 Feb 2018 16:23:07 +0000 (UTC) X-Original-To: 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 AE346F4C for ; Sun, 4 Feb 2018 16:23:04 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f44.google.com (mail-pl0-f44.google.com [209.85.160.44]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id B24AB305 for ; Sun, 4 Feb 2018 16:23:02 +0000 (UTC) Received: by mail-pl0-f44.google.com with SMTP id q17so7906362pll.1 for ; Sun, 04 Feb 2018 08:23:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=RSisW7CV1kDNiUbQbhv6AWNLZFbM92M6k8jgyG9REos=; b=PlWj7ejYXVFgOe20u0/jAmWW2Y3utvzHGt7Zfu99ysQrTE9qfm3d4h+vfHP6Usfz2w UNJ2wPAeX0BTCWQgz31Nf0Zrd7QEf1RYojgISUVfp4tdhB9XzzjIqenf/+D+yvohITBL nECPuvPorXMWwtT+GHSyvebRKn9cLBs5tJhvu2VMLW/Pu0OkZQb/A2TcCmdtA1Zd/5Qk Pn8q0JwCeKrwwkYN+PKuHPjffZ6XUe2CCVSz93gLcNvPv6s9lsKoP1gr2hR/s/VHhryB 3t7tDhgT+olVDMMybH8MoVK9wHvZfyLlDXcaBdLBfld7DZhjR2m4d0V47+gNkhLVE1wi bEtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=RSisW7CV1kDNiUbQbhv6AWNLZFbM92M6k8jgyG9REos=; b=g0y0UtAtTGgWjoHsv30qKU74pzFDinKNcRa8SwYZYwjCmR2plwEO9puhryGHBTDCia Kb3d9RY/CRsk87AwU1GEYXLEV1ya8AafGp6mPdKaQv/DFj6yhhcdJ8yU61ON2ZLx9Rtu EvWSbpC6Alcs4nDGs6rrvXHVWNOr40ZheJy0ooSJzJs8d+2GJhA6ZB++yOeMjXUftuPS 2nAZKfb5xWYnasl5SvHiXJZgmicySZoxfPpfIQCqr61GHxDQorcWhQGPNvb2unFFI8FZ OAXvnYLx8eLTFugD96Lxl2RXaqLDL5MinKoRycm+Pa4jw54oY2uHzK1YAvjRxd/fhYKH KyfA== X-Gm-Message-State: AKwxyter4J/IQHTZZNt3vSj8M88FpCo0PakYwlc4iWjX+qESX3bQlPjT Wu8HDP5nwbQ/XKx9Jf744MU= X-Google-Smtp-Source: AH8x224FMxEZEV6sl5uE9oPGsxwh3jIlqjh8rHYKMh9GR4L4B6Il0L9dXg2fD/oiEGP0x6coycpEEg== X-Received: by 2002:a17:902:1703:: with SMTP id i3-v6mr31709329pli.145.1517761382086; Sun, 04 Feb 2018 08:23:02 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:01 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:36 -0800 Message-Id: <1517761364-17655-4-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 03/11] Userspace datapath: Add fragmentation handling. 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 Fragmentation handling is added for supporting conntrack. Fragmentation handling is disabled by default and enabled via a user commands implemented in a subsequent patch. Both v4 and v6 are supported. Signed-off-by: Darrell Ball --- include/sparse/netinet/ip6.h | 1 + lib/automake.mk | 2 + lib/ipf.c | 1240 ++++++++++++++++++++++++++++++++++++++++++ lib/ipf.h | 63 +++ 4 files changed, 1306 insertions(+) create mode 100644 lib/ipf.c create mode 100644 lib/ipf.h diff --git a/include/sparse/netinet/ip6.h b/include/sparse/netinet/ip6.h index d2a54de..bfa637a 100644 --- a/include/sparse/netinet/ip6.h +++ b/include/sparse/netinet/ip6.h @@ -64,5 +64,6 @@ struct ip6_frag { }; #define IP6F_OFF_MASK ((OVS_FORCE ovs_be16) 0xfff8) +#define IP6F_MORE_FRAG ((OVS_FORCE ovs_be16) 0x0001) #endif /* netinet/ip6.h sparse */ diff --git a/lib/automake.mk b/lib/automake.mk index 38d2a99..ee8f2fc 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -107,6 +107,8 @@ lib_libopenvswitch_la_SOURCES = \ lib/hmapx.h \ lib/id-pool.c \ lib/id-pool.h \ + lib/ipf.c \ + lib/ipf.h \ lib/jhash.c \ lib/jhash.h \ lib/json.c \ diff --git a/lib/ipf.c b/lib/ipf.c new file mode 100644 index 0000000..aa8eeaa --- /dev/null +++ b/lib/ipf.c @@ -0,0 +1,1240 @@ +/* + * Copyright (c) 2018 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coverage.h" +#include "csum.h" +#include "ipf.h" +#include "openvswitch/hmap.h" +#include "openvswitch/vlog.h" +#include "ovs-atomic.h" +#include "packets.h" +#include "util.h" + +VLOG_DEFINE_THIS_MODULE(ipf); +COVERAGE_DEFINE(ipf_stuck_frag_list_purged); + +enum { + IPV4_PACKET_MAX_HDR_SIZE = 60, + IPV4_PACKET_MAX_SIZE = 65535, + IPV6_PACKET_MAX_DATA = 65535, +}; + +enum ipf_list_state { + IPF_LIST_STATE_UNUSED, + IPF_LIST_STATE_REASS_FAIL, + IPF_LIST_STATE_OTHER_SEEN, + IPF_LIST_STATE_FIRST_SEEN, + IPF_LIST_STATE_LAST_SEEN, + IPF_LIST_STATE_FIRST_LAST_SEEN, + IPF_LIST_STATE_COMPLETED, + IPF_LIST_STATE_NUM, +}; + +enum ipf_list_type { + IPF_FRAG_COMPLETED_LIST, + IPF_FRAG_EXPIRY_LIST, +}; + +enum { + IPF_INVALID_IDX = -1, + IPF_V4_FRAG_SIZE_LBOUND = 400, + IPF_V4_FRAG_SIZE_MIN_DEF = 1200, + IPF_V6_FRAG_SIZE_LBOUND = 1280, + IPF_V6_FRAG_SIZE_MIN_DEF = 1280, + IPF_MAX_FRAGS_DEFAULT = 1000, + IPF_NFRAG_UBOUND = 5000, +}; + +enum ipf_counter_type { + IPF_COUNTER_NFRAGS, + IPF_COUNTER_NFRAGS_ACCEPTED, + IPF_COUNTER_NFRAGS_COMPL_SENT, + IPF_COUNTER_NFRAGS_EXPD_SENT, + IPF_COUNTER_NFRAGS_TOO_SMALL, + IPF_COUNTER_NFRAGS_OVERLAP, +}; + +struct ipf_addr { + union { + ovs_16aligned_be32 ipv4; + union ovs_16aligned_in6_addr ipv6; + ovs_be32 ipv4_aligned; + struct in6_addr ipv6_aligned; + }; +}; + +struct ipf_frag { + struct dp_packet *pkt; + uint16_t start_data_byte; + uint16_t end_data_byte; +}; + +struct ipf_list_key { + struct ipf_addr src_addr; + struct ipf_addr dst_addr; + uint32_t recirc_id; + ovs_be32 ip_id; /* V6 is 32 bits. */ + ovs_be16 dl_type; + uint16_t zone; + uint8_t nw_proto; +}; + +struct ipf_list { + struct hmap_node node; + struct ovs_list exp_node; + struct ovs_list complete_node; + struct ipf_frag *frag_list; + struct ipf_list_key key; + struct dp_packet *reass_execute_ctx; + long long expiration; + int last_sent_idx; + int last_inuse_idx; + int size; + uint8_t state; +}; + +struct reassembled_pkt { + struct ovs_list rp_list_node; + struct dp_packet *pkt; + struct ipf_list *list; +}; + +struct OVS_LOCKABLE ipf_lock { + struct ovs_mutex lock; +}; + +static int max_v4_frag_list_size; + +static struct hmap frag_lists OVS_GUARDED; +static struct ovs_list frag_exp_list OVS_GUARDED; +static struct ovs_list frag_complete_list OVS_GUARDED; +static struct ovs_list reassembled_pkt_list OVS_GUARDED; + +static atomic_bool ifp_v4_enabled; +static atomic_bool ifp_v6_enabled; +static atomic_uint nfrag_max; +/* Will be clamped above 400 bytes; the value chosen should handle + * alg control packets of interest that use string encoding of mutable + * IP fields; meaning, the control packets should not be fragmented. */ +static atomic_uint min_v4_frag_size; +static atomic_uint min_v6_frag_size; + +static atomic_count nfrag; +static atomic_count n4frag_accepted; +static atomic_count n4frag_completed_sent; +static atomic_count n4frag_expired_sent; +static atomic_count n4frag_too_small; +static atomic_count n4frag_overlap; +static atomic_count n6frag_accepted; +static atomic_count n6frag_completed_sent; +static atomic_count n6frag_expired_sent; +static atomic_count n6frag_too_small; +static atomic_count n6frag_overlap; + +static struct ipf_lock ipf_lock; + +static void ipf_lock_init(struct ipf_lock *lock) +{ + ovs_mutex_init_adaptive(&lock->lock); +} + +static void ipf_lock_lock(struct ipf_lock *lock) + OVS_ACQUIRES(lock) + OVS_NO_THREAD_SAFETY_ANALYSIS +{ + ovs_mutex_lock(&lock->lock); +} + +static void ipf_lock_unlock(struct ipf_lock *lock) + OVS_RELEASES(lock) + OVS_NO_THREAD_SAFETY_ANALYSIS +{ + ovs_mutex_unlock(&lock->lock); +} + +static void ipf_lock_destroy(struct ipf_lock *lock) +{ + ovs_mutex_destroy(&lock->lock); +} + +static void +ipf_count(bool v4, enum ipf_counter_type cntr) +{ + if (v4) { + switch (cntr) { + case IPF_COUNTER_NFRAGS_ACCEPTED: + atomic_count_inc(&n4frag_accepted); + break; + case IPF_COUNTER_NFRAGS_COMPL_SENT: + atomic_count_inc(&n4frag_completed_sent); + break; + case IPF_COUNTER_NFRAGS_EXPD_SENT: + atomic_count_inc(&n4frag_expired_sent); + break; + case IPF_COUNTER_NFRAGS_TOO_SMALL: + atomic_count_inc(&n4frag_too_small); + break; + case IPF_COUNTER_NFRAGS_OVERLAP: + atomic_count_inc(&n4frag_overlap); + break; + case IPF_COUNTER_NFRAGS: + default: + OVS_NOT_REACHED(); + } + } else { + switch (cntr) { + case IPF_COUNTER_NFRAGS_ACCEPTED: + atomic_count_inc(&n6frag_accepted); + break; + case IPF_COUNTER_NFRAGS_COMPL_SENT: + atomic_count_inc(&n6frag_completed_sent); + break; + case IPF_COUNTER_NFRAGS_EXPD_SENT: + atomic_count_inc(&n6frag_expired_sent); + break; + case IPF_COUNTER_NFRAGS_TOO_SMALL: + atomic_count_inc(&n6frag_too_small); + break; + case IPF_COUNTER_NFRAGS_OVERLAP: + atomic_count_inc(&n6frag_overlap); + break; + case IPF_COUNTER_NFRAGS: + default: + OVS_NOT_REACHED(); + } + } +} + +static bool +ipf_get_enabled(void) +{ + bool ifp_v4_enabled_; + bool ifp_v6_enabled_; + atomic_read_relaxed(&ifp_v4_enabled, &ifp_v4_enabled_); + atomic_read_relaxed(&ifp_v6_enabled, &ifp_v6_enabled_); + return ifp_v4_enabled_ || ifp_v6_enabled_; +} + +static bool +ipf_get_v4_enabled(void) +{ + bool ifp_v4_enabled_; + atomic_read_relaxed(&ifp_v4_enabled, &ifp_v4_enabled_); + return ifp_v4_enabled_; +} + +static bool +ipf_get_v6_enabled(void) +{ + bool ifp_v6_enabled_; + atomic_read_relaxed(&ifp_v6_enabled, &ifp_v6_enabled_); + return ifp_v6_enabled_; +} + +static uint32_t +ipf_addr_hash_add(uint32_t hash, const struct ipf_addr *addr) +{ + BUILD_ASSERT_DECL(sizeof *addr % 4 == 0); + return hash_add_bytes32(hash, (const uint32_t *) addr, sizeof *addr); +} + +static void +ipf_expiry_list_add(struct ipf_list *ipf_list, long long now) + OVS_REQUIRES(ipf_lock) +{ + enum { + IPF_FRAG_LIST_TIMEOUT_DEFAULT = 15000, + }; + + ipf_list->expiration = now + IPF_FRAG_LIST_TIMEOUT_DEFAULT; + ovs_list_push_back(&frag_exp_list, &ipf_list->exp_node); +} + +static void +ipf_completed_list_add(struct ipf_list *ipf_list) + OVS_REQUIRES(ipf_lock) +{ + ovs_list_push_back(&frag_complete_list, &ipf_list->complete_node); +} + +static void +ipf_reassembled_list_add(struct reassembled_pkt *rp) + OVS_REQUIRES(ipf_lock) +{ + ovs_list_push_back(&reassembled_pkt_list, &rp->rp_list_node); +} + +static void +ipf_expiry_list_remove(struct ipf_list *ipf_list) + OVS_REQUIRES(ipf_lock) +{ + ovs_list_remove(&ipf_list->exp_node); +} + +static void +ipf_completed_list_remove(struct ipf_list *ipf_list) + OVS_REQUIRES(ipf_lock) +{ + ovs_list_remove(&ipf_list->complete_node); +} + +static void +ipf_reassembled_list_remove(struct reassembled_pkt *rp) + OVS_REQUIRES(ipf_lock) +{ + ovs_list_remove(&rp->rp_list_node); +} + +/* Symmetric */ +static uint32_t +ipf_list_key_hash(const struct ipf_list_key *key, uint32_t basis) +{ + uint32_t hsrc, hdst, hash; + hsrc = hdst = basis; + hsrc = ipf_addr_hash_add(hsrc, &key->src_addr); + hdst = ipf_addr_hash_add(hdst, &key->dst_addr); + hash = hsrc ^ hdst; + + /* Hash the rest of the key. */ + hash = hash_words((uint32_t *) (&key->dst_addr + 1), + (uint32_t *) (key + 1) - + (uint32_t *) (&key->dst_addr + 1), + hash); + + return hash_finish(hash, 0); +} + +static bool +ipf_is_first_v4_frag(const struct dp_packet *pkt) +{ + const struct ip_header *l3 = dp_packet_l3(pkt); + if (!(l3->ip_frag_off & htons(IP_FRAG_OFF_MASK)) && + l3->ip_frag_off & htons(IP_MORE_FRAGMENTS)) { + return true; + } + return false; +} + +static bool +ipf_is_last_v4_frag(const struct dp_packet *pkt) +{ + const struct ip_header *l3 = dp_packet_l3(pkt); + if (l3->ip_frag_off & htons(IP_FRAG_OFF_MASK) && + !(l3->ip_frag_off & htons(IP_MORE_FRAGMENTS))) { + return true; + } + return false; +} + +static bool +ipf_is_v6_frag(ovs_be16 ip6f_offlg) +{ + if (ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG)) { + return true; + } + return false; +} + +static bool +ipf_is_first_v6_frag(ovs_be16 ip6f_offlg) +{ + if (!(ip6f_offlg & IP6F_OFF_MASK) && + ip6f_offlg & IP6F_MORE_FRAG) { + return true; + } + return false; +} + +static bool +ipf_is_last_v6_frag(ovs_be16 ip6f_offlg) +{ + if ((ip6f_offlg & IP6F_OFF_MASK) && + !(ip6f_offlg & IP6F_MORE_FRAG)) { + return true; + } + return false; +} + +static bool +ipf_list_complete(const struct ipf_list *ipf_list) + OVS_REQUIRES(ipf_lock) +{ + for (int i = 0; i < ipf_list->last_inuse_idx; i++) { + if (ipf_list->frag_list[i].end_data_byte + 1 + != ipf_list->frag_list[i+1].start_data_byte) { + return false; + } + } + return true; +} + +/* Runs O(n) for a sorted or almost sorted list. */ +static void +ipf_sort(struct ipf_frag *frag_list, size_t last_idx) + OVS_REQUIRES(ipf_lock) +{ + int running_last_idx = 1; + struct ipf_frag ipf_frag; + while (running_last_idx <= last_idx) { + ipf_frag = frag_list[running_last_idx]; + int frag_list_idx = running_last_idx - 1; + while (frag_list_idx >= 0 && + frag_list[frag_list_idx].start_data_byte > + ipf_frag.start_data_byte) { + frag_list[frag_list_idx + 1] = frag_list[frag_list_idx]; + frag_list_idx -= 1; + } + frag_list[frag_list_idx + 1] = ipf_frag; + running_last_idx++; + } +} + +/* Called on a sorted complete list of fragments. */ +static struct dp_packet * +ipf_reassemble_v4_frags(struct ipf_list *ipf_list) + OVS_REQUIRES(ipf_lock) +{ + struct ipf_frag *frag_list = ipf_list->frag_list; + struct dp_packet *pkt = dp_packet_clone(frag_list[0].pkt); + struct ip_header *l3 = dp_packet_l3(pkt); + int len = ntohs(l3->ip_tot_len); + size_t add_len; + size_t ip_hdr_len = IP_IHL(l3->ip_ihl_ver) * 4; + + for (int i = 1; i <= ipf_list->last_inuse_idx; i++) { + add_len = frag_list[i].end_data_byte - + frag_list[i].start_data_byte + 1; + len += add_len; + if (len > IPV4_PACKET_MAX_SIZE) { + dp_packet_delete(pkt); + return NULL; + } + l3 = dp_packet_l3(frag_list[i].pkt); + dp_packet_put(pkt, (char *)l3 + ip_hdr_len, add_len); + } + l3 = dp_packet_l3(pkt); + ovs_be16 new_ip_frag_off = l3->ip_frag_off & ~htons(IP_MORE_FRAGMENTS); + l3->ip_csum = recalc_csum16(l3->ip_csum, l3->ip_frag_off, + new_ip_frag_off); + l3->ip_csum = recalc_csum16(l3->ip_csum, l3->ip_tot_len, htons(len)); + l3->ip_tot_len = htons(len); + l3->ip_frag_off = new_ip_frag_off; + + return pkt; +} + +/* Called on a sorted complete list of fragments. */ +static struct dp_packet * +ipf_reassemble_v6_frags(struct ipf_list *ipf_list) + OVS_REQUIRES(ipf_lock) +{ + struct ipf_frag *frag_list = ipf_list->frag_list; + struct dp_packet *pkt = dp_packet_clone(frag_list[0].pkt); + struct ovs_16aligned_ip6_hdr *l3 = dp_packet_l3(pkt); + int pl = ntohs(l3->ip6_plen) - sizeof(struct ovs_16aligned_ip6_frag); + const char *tail = dp_packet_tail(pkt); + uint8_t pad = dp_packet_l2_pad_size(pkt); + const char *l4 = dp_packet_l4(pkt); + size_t l3_size = tail - (char *)l3 -pad; + size_t l4_size = tail - (char *)l4 -pad; + size_t l3_hlen = l3_size - l4_size; + size_t add_len; + + for (int i = 1; i <= ipf_list->last_inuse_idx; i++) { + add_len = frag_list[i].end_data_byte - + frag_list[i].start_data_byte + 1; + pl += add_len; + if (pl > IPV6_PACKET_MAX_DATA) { + dp_packet_delete(pkt); + return NULL; + } + l3 = dp_packet_l3(frag_list[i].pkt); + dp_packet_put(pkt, (char *)l3 + l3_hlen, add_len); + } + l3 = dp_packet_l3(pkt); + l4 = dp_packet_l4(pkt); + tail = dp_packet_tail(pkt); + pad = dp_packet_l2_pad_size(pkt); + l3_size = tail - (char *)l3 -pad; + + uint8_t nw_proto = l3->ip6_nxt; + uint8_t nw_frag = 0; + const void *data = l3 + 1; + size_t datasize = l3_size - sizeof *l3; + + const struct ovs_16aligned_ip6_frag *frag_hdr = NULL; + if (!parse_ipv6_ext_hdrs(&data, &datasize, &nw_proto, &nw_frag, &frag_hdr) + || !nw_frag || !frag_hdr) { + return NULL; + } + + struct ovs_16aligned_ip6_frag *fh = + CONST_CAST(struct ovs_16aligned_ip6_frag *, frag_hdr); + fh->ip6f_offlg = 0;; + l3->ip6_plen = htons(pl); + l3->ip6_ctlun.ip6_un1.ip6_un1_nxt = nw_proto; + return pkt; +} + +/* Called when a valid fragment is added. */ +static void +ipf_list_state_transition(struct ipf_list *ipf_list, bool ff, bool lf, + bool v4) + OVS_REQUIRES(ipf_lock) +{ + enum ipf_list_state curr_state = ipf_list->state; + enum ipf_list_state next_state; + switch (curr_state) { + case IPF_LIST_STATE_UNUSED: + case IPF_LIST_STATE_OTHER_SEEN: + if (ff) { + next_state = IPF_LIST_STATE_FIRST_SEEN; + } else if (lf) { + next_state = IPF_LIST_STATE_LAST_SEEN; + } else { + next_state = IPF_LIST_STATE_OTHER_SEEN; + } + break; + case IPF_LIST_STATE_FIRST_SEEN: + if (ff) { + next_state = IPF_LIST_STATE_FIRST_SEEN; + } else if (lf) { + next_state = IPF_LIST_STATE_FIRST_LAST_SEEN; + } else { + next_state = IPF_LIST_STATE_FIRST_SEEN; + } + break; + case IPF_LIST_STATE_LAST_SEEN: + if (ff) { + next_state = IPF_LIST_STATE_FIRST_LAST_SEEN; + } else if (lf) { + next_state = IPF_LIST_STATE_LAST_SEEN; + } else { + next_state = IPF_LIST_STATE_LAST_SEEN; + } + break; + case IPF_LIST_STATE_FIRST_LAST_SEEN: + next_state = IPF_LIST_STATE_FIRST_LAST_SEEN; + ipf_sort(ipf_list->frag_list, ipf_list->last_inuse_idx); + break; + case IPF_LIST_STATE_COMPLETED: + next_state = curr_state; + break; + case IPF_LIST_STATE_REASS_FAIL: + case IPF_LIST_STATE_NUM: + default: + OVS_NOT_REACHED(); + } + + if (next_state == IPF_LIST_STATE_FIRST_LAST_SEEN && + ipf_list_complete(ipf_list)) { + struct dp_packet *reass_pkt = NULL; + if (v4) { + reass_pkt = ipf_reassemble_v4_frags(ipf_list); + } else { + reass_pkt = ipf_reassemble_v6_frags(ipf_list); + } + if (reass_pkt) { + struct reassembled_pkt *rp = xzalloc(sizeof *rp); + rp->pkt = reass_pkt; + rp->list = ipf_list; + ipf_reassembled_list_add(rp); + ipf_expiry_list_remove(ipf_list); + next_state = IPF_LIST_STATE_COMPLETED; + } else { + next_state = IPF_LIST_STATE_REASS_FAIL; + } + } + ipf_list->state = next_state; +} + +static bool +ipf_v4_key_extract(const struct dp_packet *pkt, ovs_be16 dl_type, + uint16_t zone, struct ipf_list_key *key, + uint16_t *start_data_byte, uint16_t *end_data_byte, + bool *ff, bool *lf) +{ + if (dp_packet_ip_checksum_bad(pkt)) { + return false; + } + + const struct eth_header *l2 = dp_packet_eth(pkt); + const struct ip_header *l3 = dp_packet_l3(pkt); + + if (!l2 || !l3) { + return false; + } + + const char *tail = dp_packet_tail(pkt); + uint8_t pad = dp_packet_l2_pad_size(pkt); + size_t size = tail - (char *)l3 -pad; + if (OVS_UNLIKELY(size < IP_HEADER_LEN)) { + return false; + } + + uint16_t ip_tot_len = ntohs(l3->ip_tot_len); + if (ip_tot_len != size) { + return false; + } + + if (!(IP_IS_FRAGMENT(l3->ip_frag_off))) { + return false; + } + + size_t ip_hdr_len = IP_IHL(l3->ip_ihl_ver) * 4; + if (OVS_UNLIKELY(ip_hdr_len < IP_HEADER_LEN)) { + return false; + } + if (OVS_UNLIKELY(size < ip_hdr_len)) { + return false; + } + + if (!dp_packet_ip_checksum_valid(pkt) && csum(l3, ip_hdr_len) != 0) { + return false; + } + + uint32_t min_v4_frag_size_; + atomic_read_relaxed(&min_v4_frag_size, &min_v4_frag_size_); + *lf = ipf_is_last_v4_frag(pkt); + if (!*lf && dp_packet_size(pkt) <= min_v4_frag_size_) { + ipf_count(true, IPF_COUNTER_NFRAGS_TOO_SMALL); + return false; + } + + *start_data_byte = ntohs(l3->ip_frag_off & htons(IP_FRAG_OFF_MASK)) * 8; + *end_data_byte = *start_data_byte + ip_tot_len - ip_hdr_len - 1; + *ff = ipf_is_first_v4_frag(pkt); + memset(key, 0, sizeof *key); + key->ip_id = be16_to_be32(l3->ip_id); + key->dl_type = dl_type; + key->src_addr.ipv4 = l3->ip_src; + key->dst_addr.ipv4 = l3->ip_dst; + key->nw_proto = l3->ip_proto; + key->zone = zone; + key->recirc_id = pkt->md.recirc_id; + return true; +} + +static bool +ipf_v6_key_extract(const struct dp_packet *pkt, ovs_be16 dl_type, + uint16_t zone, struct ipf_list_key *key, + uint16_t *start_data_byte, uint16_t *end_data_byte, + bool *ff, bool *lf) +{ + const struct eth_header *l2 = dp_packet_eth(pkt); + const struct ovs_16aligned_ip6_hdr *l3 = dp_packet_l3(pkt); + const char *l4 = dp_packet_l4(pkt); + + if (!l2 || !l3 || !l4) { + return false; + } + + const char *tail = dp_packet_tail(pkt); + uint8_t pad = dp_packet_l2_pad_size(pkt); + size_t l3_size = tail - (char *)l3 -pad; + size_t l4_size = tail - (char *)l4 -pad; + size_t l3_hdr_size = sizeof *l3; + + if (OVS_UNLIKELY(l3_size < l3_hdr_size)) { + return false; + } + + int pl = ntohs(l3->ip6_plen); + if (pl + l3_hdr_size != l3_size) { + return false; + } + + uint8_t nw_frag = 0; + uint8_t nw_proto = l3->ip6_nxt; + const void *data = l3 + 1; + size_t datasize = l3_size - l3_hdr_size; + const struct ovs_16aligned_ip6_frag *frag_hdr = NULL; + if (!parse_ipv6_ext_hdrs(&data, &datasize, &nw_proto, &nw_frag, + &frag_hdr) || !nw_frag || !frag_hdr) { + return false; + } + + ovs_be16 ip6f_offlg = frag_hdr->ip6f_offlg; + + if (!(ipf_is_v6_frag(ip6f_offlg))) { + return false; + } + + uint32_t min_v6_frag_size_; + atomic_read_relaxed(&min_v6_frag_size, &min_v6_frag_size_); + *lf = ipf_is_last_v6_frag(ip6f_offlg); + + if (!(*lf) && dp_packet_size(pkt) <= min_v6_frag_size_) { + ipf_count(false, IPF_COUNTER_NFRAGS_TOO_SMALL); + return false; + } + + *start_data_byte = ntohs(ip6f_offlg & IP6F_OFF_MASK) + + sizeof (struct ovs_16aligned_ip6_frag); + *end_data_byte = *start_data_byte + l4_size - 1; + *ff = ipf_is_first_v6_frag(ip6f_offlg); + memset(key, 0, sizeof *key); + key->ip_id = get_16aligned_be32(&frag_hdr->ip6f_ident); + key->dl_type = dl_type; + key->src_addr.ipv6 = l3->ip6_src; + /* We are not supporting parsing of the routing header header + * to use as the dst address part of the key. */ + key->dst_addr.ipv6 = l3->ip6_dst; + /* Not used for key for V6. */ + key->nw_proto = 0; + key->zone = zone; + key->recirc_id = pkt->md.recirc_id; + return true; +} + +static int +ipf_list_key_cmp(const struct ipf_list_key *key1, + const struct ipf_list_key *key2) + OVS_REQUIRES(ipf_lock) +{ + if (!memcmp(&key1->src_addr, &key2->src_addr, sizeof key1->src_addr) && + !memcmp(&key1->dst_addr, &key2->dst_addr, sizeof key1->dst_addr) && + (key1->dl_type == key2->dl_type) && + (key1->ip_id == key2->ip_id) && + (key1->zone == key2->zone) && + (key1->nw_proto == key2->nw_proto) && + (key1->recirc_id == key2->recirc_id)) { + return 0; + } + return 1; +} + +static struct ipf_list * +ipf_list_key_lookup(struct hmap *frag_lists, + const struct ipf_list_key *key, + uint32_t hash) + OVS_REQUIRES(ipf_lock) +{ + struct ipf_list *ipf_list; + HMAP_FOR_EACH_WITH_HASH (ipf_list, node, hash, frag_lists) { + if (!ipf_list_key_cmp(&ipf_list->key, key)) { + return ipf_list; + } + } + return NULL; +} + +static bool +ipf_is_frag_duped(const struct ipf_frag *frag_list, int last_inuse_idx, + size_t start_data_byte, size_t end_data_byte) + OVS_REQUIRES(ipf_lock) +{ + for (int i = 0; i <= last_inuse_idx; i++) { + if (((start_data_byte >= frag_list[i].start_data_byte) && + (start_data_byte <= frag_list[i].end_data_byte)) || + ((end_data_byte >= frag_list[i].start_data_byte) && + (end_data_byte <= frag_list[i].end_data_byte))) { + return true; + } + } + return false; +} + +static bool +ipf_process_frag(struct ipf_list *ipf_list, struct dp_packet *pkt, + uint16_t start_data_byte, uint16_t end_data_byte, + bool ff, bool lf, bool v4) + OVS_REQUIRES(ipf_lock) +{ + bool duped_frag = ipf_is_frag_duped(ipf_list->frag_list, + ipf_list->last_inuse_idx, start_data_byte, end_data_byte); + int last_inuse_idx = ipf_list->last_inuse_idx; + + if (!duped_frag) { + if (last_inuse_idx < ipf_list->size - 1) { + /* In the case of dpdk, it would be unfortunate if we had + * to create a clone fragment outside the dpdk mp due to the + * mempool size being too limited. We will otherwise need to + * recommend not setting the mempool number of buffers too low + * and also clamp the number of fragments. */ + ipf_list->frag_list[last_inuse_idx + 1].pkt = pkt; + ipf_list->frag_list[last_inuse_idx + 1].start_data_byte = + start_data_byte; + ipf_list->frag_list[last_inuse_idx + 1].end_data_byte = + end_data_byte; + ipf_list->last_inuse_idx++; + atomic_count_inc(&nfrag); + ipf_count(v4, IPF_COUNTER_NFRAGS_ACCEPTED); + ipf_list_state_transition(ipf_list, ff, lf, v4); + } else { + OVS_NOT_REACHED(); + } + } else { + ipf_count(v4, IPF_COUNTER_NFRAGS_OVERLAP); + pkt->md.ct_state = CS_INVALID; + return false; + } + return true; +} + +static bool +ipf_handle_frag(struct dp_packet *pkt, ovs_be16 dl_type, uint16_t zone, + long long now, uint32_t hash_basis) + OVS_REQUIRES(ipf_lock) +{ + struct ipf_list_key key; + uint16_t start_data_byte; + uint16_t end_data_byte; + bool ff; + bool lf; + bool v4; + + if (dl_type == htons(ETH_TYPE_IP) && ipf_get_v4_enabled()) { + if (!ipf_v4_key_extract(pkt, dl_type, zone, &key, &start_data_byte, + &end_data_byte, &ff, &lf)) { + return false; + } + v4 = true; + } else if (dl_type == htons(ETH_TYPE_IPV6) && ipf_get_v6_enabled()) { + if (!ipf_v6_key_extract(pkt, dl_type, zone, &key, &start_data_byte, + &end_data_byte, &ff, &lf)) { + return false; + } + v4 = false; + } else { + return false; + } + + unsigned int nfrag_max_; + atomic_read_relaxed(&nfrag_max, &nfrag_max_); + if (atomic_count_get(&nfrag) >= nfrag_max_) { + return false; + } + + uint32_t hash = ipf_list_key_hash(&key, hash_basis); + struct ipf_list *ipf_list = + ipf_list_key_lookup(&frag_lists, &key, hash); + enum { + IPF_FRAG_LIST_MIN_INCREMENT = 4, + IPF_UNBOUNDED_FRAG_LIST_SIZE = 65535, + }; + + int max_frag_list_size; + if (v4) { + max_frag_list_size = max_v4_frag_list_size; + } else { + max_frag_list_size = IPF_UNBOUNDED_FRAG_LIST_SIZE; + } + + if (!ipf_list) { + ipf_list = xzalloc(sizeof *ipf_list); + ipf_list->key = key; + ipf_list->last_inuse_idx = IPF_INVALID_IDX; + ipf_list->last_sent_idx = IPF_INVALID_IDX; + ipf_list->size = + MIN(max_frag_list_size, IPF_FRAG_LIST_MIN_INCREMENT); + ipf_list->frag_list = + xzalloc(ipf_list->size * sizeof *ipf_list->frag_list); + hmap_insert(&frag_lists, &ipf_list->node, hash); + ipf_expiry_list_add(ipf_list, now); + } else if (ipf_list->state == IPF_LIST_STATE_REASS_FAIL) { + /* Bail out as early as possible. */ + return false; + } else if (ipf_list->last_inuse_idx + 1 >= ipf_list->size) { + int increment = MIN(IPF_FRAG_LIST_MIN_INCREMENT, + max_frag_list_size - ipf_list->size); + /* Enforce limit. */ + if (increment > 0) { + ipf_list->frag_list = + xrealloc(ipf_list->frag_list, (ipf_list->size + increment) * + sizeof *ipf_list->frag_list); + ipf_list->size += increment; + } else { + return false; + } + } + + return ipf_process_frag(ipf_list, pkt, start_data_byte, end_data_byte, ff, + lf, v4); +} + +/* Handles V4 fragments right now. */ +static void +ipf_extract_frags_from_batch(struct dp_packet_batch *pb, ovs_be16 dl_type, + uint16_t zone, long long now, uint32_t hash_basis) +{ + const size_t pb_cnt = dp_packet_batch_size(pb); + int pb_idx; /* Index in a packet batch. */ + struct dp_packet *pkt; + + DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) { + ipf_lock_lock(&ipf_lock); + + if (!ipf_handle_frag(pkt, dl_type, zone, now, hash_basis)) { + dp_packet_batch_refill(pb, pkt, pb_idx); + } + + ipf_lock_unlock(&ipf_lock); + } +} + +/* In case of DPDK, a memory source check is done, as DPDK memory pool + * management has trouble dealing with multiple source types. The + * check_source paramater is used to indicate when this check is needed. */ +static bool +ipf_dp_packet_batch_add(struct dp_packet_batch *pb , struct dp_packet *pkt, + bool check_source OVS_UNUSED) + OVS_REQUIRES(ipf_lock) +{ +#ifdef DPDK_NETDEV + if ((pb->count >= NETDEV_MAX_BURST) || + /* DPDK cannot handle multiple sources in a batch. */ + (check_source && pb->count && pb->packets[0]->source != pkt->source)) { +#else + if (pb->count >= NETDEV_MAX_BURST) { +#endif + return false; + } + + dp_packet_batch_add(pb, pkt); + return true; +} + +/* This would be used in a rare case where a list cannot be sent. The only + * reason known right now is a mempool source check,which exists due to DPDK + * support, where packets are no longer being received on any port with a + * source matching the fragment. + * Returns true if the list was purged. */ +static bool +ipf_purge_list_check(struct ipf_list *ipf_list OVS_UNUSED, + long long now OVS_UNUSED) + OVS_REQUIRES(ipf_lock) +{ + enum { + /* 10 minutes. */ + IPF_FRAG_LIST_TIMEOUT_PURGE = 600000, + }; + + if (now < ipf_list->expiration + IPF_FRAG_LIST_TIMEOUT_PURGE) { + return false; + } + + struct dp_packet *pkt; + while (ipf_list->last_sent_idx < ipf_list->last_inuse_idx) { + pkt = ipf_list->frag_list[ipf_list->last_sent_idx + 1].pkt; + dp_packet_delete(pkt); + atomic_count_dec(&nfrag); + ipf_list->last_sent_idx++; + } + + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); + VLOG_WARN_RL(&rl, "Fragments dropped due to stuck fragment list purge."); + COVERAGE_INC(ipf_stuck_frag_list_purged); + return true; +} + +static bool +ipf_send_frags_in_list(struct ipf_list *ipf_list, struct dp_packet_batch *pb, + enum ipf_list_type list_type, bool v4, long long now) + OVS_REQUIRES(ipf_lock) +{ + if (ipf_purge_list_check(ipf_list, now)) { + return true; + } + + struct dp_packet *pkt; + while (ipf_list->last_sent_idx < ipf_list->last_inuse_idx) { + pkt = ipf_list->frag_list[ipf_list->last_sent_idx + 1].pkt; + if (ipf_dp_packet_batch_add(pb, pkt, true)) { + + ipf_list->last_sent_idx++; + atomic_count_dec(&nfrag); + + if (list_type == IPF_FRAG_COMPLETED_LIST) { + ipf_count(v4, IPF_COUNTER_NFRAGS_COMPL_SENT); + } else { + ipf_count(v4, IPF_COUNTER_NFRAGS_EXPD_SENT); + pkt->md.ct_state = CS_INVALID; + } + + if (ipf_list->last_sent_idx == ipf_list->last_inuse_idx) { + return true; + } + } else { + return false; + } + } + OVS_NOT_REACHED(); +} + +static void +ipf_list_remove(struct ipf_list *ipf_list, enum ipf_list_type list_type) + OVS_REQUIRES(ipf_lock) +{ + if (list_type == IPF_FRAG_COMPLETED_LIST) { + ipf_completed_list_remove(ipf_list); + } else { + ipf_expiry_list_remove(ipf_list); + } + hmap_remove(&frag_lists, &ipf_list->node); + free(ipf_list->frag_list); + free(ipf_list); +} + +static void +ipf_send_completed_frags(struct dp_packet_batch *pb, long long now, bool v4) +{ + if (ovs_list_is_empty(&frag_complete_list)) { + return; + } + + ipf_lock_lock(&ipf_lock); + struct ipf_list *ipf_list, *next; + + LIST_FOR_EACH_SAFE (ipf_list, next, complete_node, &frag_complete_list) { + if (ipf_send_frags_in_list(ipf_list, pb, IPF_FRAG_COMPLETED_LIST, + v4, now)) { + ipf_list_remove(ipf_list, IPF_FRAG_COMPLETED_LIST); + } else { + break; + } + } + ipf_lock_unlock(&ipf_lock); +} + +static void +ipf_send_expired_frags(struct dp_packet_batch *pb, long long now, bool v4) +{ + enum { + /* Very conservative, due to DOS probability. */ + IPF_FRAG_LIST_MAX_EXPIRED = 1, + }; + + + if (ovs_list_is_empty(&frag_exp_list)) { + return; + } + + ipf_lock_lock(&ipf_lock); + struct ipf_list *ipf_list, *next; + size_t lists_removed = 0; + + LIST_FOR_EACH_SAFE (ipf_list, next, exp_node, &frag_exp_list) { + if (!(now > ipf_list->expiration) || + lists_removed >= IPF_FRAG_LIST_MAX_EXPIRED) { + break; + } + + if (ipf_send_frags_in_list(ipf_list, pb, IPF_FRAG_EXPIRY_LIST, v4, + now)) { + ipf_list_remove(ipf_list, IPF_FRAG_EXPIRY_LIST); + lists_removed++; + } else { + break; + } + } + ipf_lock_unlock(&ipf_lock); +} + +static void +ipf_execute_reass_pkts(struct dp_packet_batch *pb) +{ + if (ovs_list_is_empty(&reassembled_pkt_list)) { + return; + } + + ipf_lock_lock(&ipf_lock); + struct reassembled_pkt *rp, *next; + + LIST_FOR_EACH_SAFE (rp, next, rp_list_node, &reassembled_pkt_list) { + if (!rp->list->reass_execute_ctx && + ipf_dp_packet_batch_add(pb, rp->pkt, false)) { + rp->list->reass_execute_ctx = rp->pkt; + } + } + ipf_lock_unlock(&ipf_lock); +} + +static void +ipf_post_execute_reass_pkts(struct dp_packet_batch *pb, bool v4) +{ + if (ovs_list_is_empty(&reassembled_pkt_list)) { + return; + } + + ipf_lock_lock(&ipf_lock); + struct reassembled_pkt *rp, *next; + + LIST_FOR_EACH_SAFE (rp, next, rp_list_node, &reassembled_pkt_list) { + const size_t pb_cnt = dp_packet_batch_size(pb); + int pb_idx; + struct dp_packet *pkt; + /* Inner batch loop is constant time since batch size is <= + * NETDEV_MAX_BURST. */ + DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) { + if (pkt == rp->list->reass_execute_ctx) { + for (int i = 0; i <= rp->list->last_inuse_idx; i++) { + rp->list->frag_list[i].pkt->md.ct_label = pkt->md.ct_label; + rp->list->frag_list[i].pkt->md.ct_mark = pkt->md.ct_mark; + rp->list->frag_list[i].pkt->md.ct_state = pkt->md.ct_state; + rp->list->frag_list[i].pkt->md.ct_zone = pkt->md.ct_zone; + rp->list->frag_list[i].pkt->md.ct_orig_tuple_ipv6 = + pkt->md.ct_orig_tuple_ipv6; + if (pkt->md.ct_orig_tuple_ipv6) { + rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv6 = + pkt->md.ct_orig_tuple.ipv6; + } else { + rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv4 = + pkt->md.ct_orig_tuple.ipv4; + } + } + + const char *tail_frag = + dp_packet_tail(rp->list->frag_list[0].pkt); + uint8_t pad_frag = + dp_packet_l2_pad_size(rp->list->frag_list[0].pkt); + + void *l4_frag = dp_packet_l4(rp->list->frag_list[0].pkt); + void *l4_reass = dp_packet_l4(pkt); + memcpy(l4_frag, l4_reass, + tail_frag - (char *) l4_frag - pad_frag); + + if (v4) { + struct ip_header *l3_frag = + dp_packet_l3(rp->list->frag_list[0].pkt); + struct ip_header *l3_reass = dp_packet_l3(pkt); + ovs_be32 reass_ip = get_16aligned_be32(&l3_reass->ip_src); + ovs_be32 frag_ip = get_16aligned_be32(&l3_frag->ip_src); + l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum, + frag_ip, reass_ip); + l3_frag->ip_src = l3_reass->ip_src; + + reass_ip = get_16aligned_be32(&l3_reass->ip_dst); + frag_ip = get_16aligned_be32(&l3_frag->ip_dst); + l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum, + frag_ip, reass_ip); + l3_frag->ip_dst = l3_reass->ip_dst; + } else { + struct ovs_16aligned_ip6_hdr *l3_frag = + dp_packet_l3(rp->list->frag_list[0].pkt); + struct ovs_16aligned_ip6_hdr *l3_reass = + dp_packet_l3(pkt); + l3_frag->ip6_src = l3_reass->ip6_src; + l3_frag->ip6_dst = l3_reass->ip6_dst; + } + + ipf_completed_list_add(rp->list); + ipf_reassembled_list_remove(rp); + dp_packet_delete(rp->pkt); + free(rp); + } else { + dp_packet_batch_refill(pb, pkt, pb_idx); + } + } + } + ipf_lock_unlock(&ipf_lock); +} + +void +ipf_preprocess_conntrack(struct dp_packet_batch *pb, long long now, + ovs_be16 dl_type, uint16_t zone, uint32_t hash_basis) +{ + if (ipf_get_enabled()) { + ipf_extract_frags_from_batch(pb, dl_type, zone, now, hash_basis); + } + + if (ipf_get_enabled() || atomic_count_get(&nfrag)) { + ipf_execute_reass_pkts(pb); + } +} + +void +ipf_postprocess_conntrack(struct dp_packet_batch *pb, long long now, + ovs_be16 dl_type) +{ + if (ipf_get_enabled() || atomic_count_get(&nfrag)) { + ipf_post_execute_reass_pkts(pb, dl_type == htons(ETH_TYPE_IP)); + ipf_send_completed_frags(pb, dl_type == htons(ETH_TYPE_IP), now); + ipf_send_expired_frags(pb, now, dl_type == htons(ETH_TYPE_IP)); + } +} + +void +ipf_init(void) +{ + ipf_lock_init(&ipf_lock); + ipf_lock_lock(&ipf_lock); + hmap_init(&frag_lists); + ovs_list_init(&frag_exp_list); + ovs_list_init(&frag_complete_list); + ovs_list_init(&reassembled_pkt_list); + atomic_init(&min_v4_frag_size, IPF_V4_FRAG_SIZE_MIN_DEF); + atomic_init(&min_v6_frag_size, IPF_V6_FRAG_SIZE_MIN_DEF); + max_v4_frag_list_size = DIV_ROUND_UP( + IPV4_PACKET_MAX_SIZE - IPV4_PACKET_MAX_HDR_SIZE, + min_v4_frag_size - IPV4_PACKET_MAX_HDR_SIZE); + ipf_lock_unlock(&ipf_lock); + atomic_count_init(&nfrag, 0); + atomic_count_init(&n4frag_accepted, 0); + atomic_count_init(&n4frag_completed_sent, 0); + atomic_count_init(&n4frag_expired_sent, 0); + atomic_count_init(&n4frag_too_small, 0); + atomic_count_init(&n4frag_overlap, 0); + atomic_count_init(&n6frag_accepted, 0); + atomic_count_init(&n6frag_completed_sent, 0); + atomic_count_init(&n6frag_expired_sent, 0); + atomic_count_init(&n6frag_too_small, 0); + atomic_count_init(&n6frag_overlap, 0); + atomic_init(&nfrag_max, IPF_MAX_FRAGS_DEFAULT); + atomic_init(&ifp_v4_enabled, false); + atomic_init(&ifp_v6_enabled, false); +} + +void +ipf_destroy(void) +{ + ipf_lock_lock(&ipf_lock); + + struct ipf_list *ipf_list; + HMAP_FOR_EACH_POP (ipf_list, node, &frag_lists) { + struct dp_packet *pkt; + while (ipf_list->last_sent_idx < ipf_list->last_inuse_idx) { + pkt = ipf_list->frag_list[ipf_list->last_sent_idx + 1].pkt; + dp_packet_delete(pkt); + atomic_count_dec(&nfrag); + ipf_list->last_sent_idx++; + } + free(ipf_list->frag_list); + free(ipf_list); + } + + struct reassembled_pkt * rp; + LIST_FOR_EACH_POP (rp, rp_list_node, &reassembled_pkt_list) { + dp_packet_delete(rp->pkt); + free(rp); + } + + hmap_destroy(&frag_lists); + ovs_list_poison(&frag_exp_list); + ovs_list_poison(&frag_complete_list); + ovs_list_poison(&reassembled_pkt_list); + ipf_lock_unlock(&ipf_lock); + ipf_lock_destroy(&ipf_lock); +} diff --git a/lib/ipf.h b/lib/ipf.h new file mode 100644 index 0000000..5861e96 --- /dev/null +++ b/lib/ipf.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IPF_H +#define IPF_H 1 + +#include "dp-packet.h" +#include "openvswitch/types.h" + +struct ipf_status { + bool ifp_v4_enabled; + unsigned int min_v4_frag_size; + unsigned int nfrag_max; + unsigned int nfrag; + unsigned int n4frag_accepted; + unsigned int n4frag_completed_sent; + unsigned int n4frag_expired_sent; + unsigned int n4frag_too_small; + unsigned int n4frag_overlap; + bool ifp_v6_enabled; + unsigned int min_v6_frag_size; + unsigned int n6frag_accepted; + unsigned int n6frag_completed_sent; + unsigned int n6frag_expired_sent; + unsigned int n6frag_too_small; + unsigned int n6frag_overlap; +}; + +/* Collects and reassembles fragments which are to be sent through + * conntrack, if fragment processing is enabled or fragments are + * in flight. */ +void +ipf_preprocess_conntrack(struct dp_packet_batch *pb, long long now, + ovs_be16 dl_type, uint16_t zone, uint32_t hash_basis); + +/* Updates the state of fragments associated with reassembled packets and + * sends out fragments that are either associated with completed + * packets or expired, if fragment processing is enabled or fragments are + * in flight. */ +void +ipf_postprocess_conntrack(struct dp_packet_batch *pb, long long now, + ovs_be16 dl_type); + +void +ipf_init(void); + +void +ipf_destroy(void); + +#endif /* ipf.h */ From patchwork Sun Feb 4 16:22:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869046 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ovFROQVK"; dkim-atps=neutral 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 3zZGK65MLmz9s7v for ; Mon, 5 Feb 2018 03:24:58 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 20A48F7D; Sun, 4 Feb 2018 16:23:06 +0000 (UTC) X-Original-To: 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 B32D6F34 for ; Sun, 4 Feb 2018 16:23:03 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f66.google.com (mail-pl0-f66.google.com [209.85.160.66]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 7918132F for ; Sun, 4 Feb 2018 16:23:03 +0000 (UTC) Received: by mail-pl0-f66.google.com with SMTP id 11so10122984plc.9 for ; Sun, 04 Feb 2018 08:23:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=eqY3xfujSM48UHy8VlH3MQA8qj90UUAsJIjkL9tyErs=; b=ovFROQVKQobSzoQySrv7ff1l3wPdgc/RC9xXPSfiuRkjxhItBHXRSmWJIEt9/iSy/v aqsMCCi+wApuMSWpgXx6w9Uk8xqMdYhFXwmfe2pEmAYcLe3TgskdKxwpxqArOOnMoOB3 V794FufYPRa3MNNub1EI+z/9E7WB3YctVbuguBg79fvFna4E6Oo8rjzp/fhnbOcfCgIQ yOV1MCZZEuzrK9Fu7bsWulImjYxZq8SUzjFveo3RepgUEG6+7qQ/KnOUKiwWUSiKxDyw HmNL46FwzIckJSzm0PVZIlDu189fFPrKQw354ssjFutGwKGwFF9usvMmASeaw34XWTGD FtYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=eqY3xfujSM48UHy8VlH3MQA8qj90UUAsJIjkL9tyErs=; b=q7bLpyIemZCUD4d9+FrPGCz1y2sWBcS3Em36Pn9iwELi7sJNn2GCumsOMEw0KaBfWR yEEmfrrVwKDVePRoxgVzcTQER+yIDvZc1bFXNj2PliILMkDRC9v9Qezhdh7vr4xnERIX psoS8Eknyz8MM16ot3EYwzOG3pKUhhgiqUGygU2s+d/N7wCLXb5zgB6Bsp6i6a2AfIut yaoZJ8vdxTQFupZBYYi43iSaINmj5eMoR6c69pGCxyj9qLgNGF+fUl/CGKz8xYIUr0+c Z8K2O2nSQjdaPWkMTDijDv4MkVm1Z8rFYcmAqJACFFlxXupd8Si8vpOZ+6oNtxqLmU3M VcZA== X-Gm-Message-State: AKwxytd1fdW1nh7CghA6WhGi+6C0ep+rGGDlzxZVf7sVk0C10xhsqdov p/v1gIcziCrJX1anJt/wLbsGOA== X-Google-Smtp-Source: AH8x224yxtGotnH/hzqwYMxrYUvcwGzNC6iIABKrw51DpzVSKRvHvaKCoayrkAMCr0YguIvZeRHnFA== X-Received: by 2002:a17:902:66e6:: with SMTP id e93-v6mr40479430plk.173.1517761383147; Sun, 04 Feb 2018 08:23:03 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:02 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:37 -0800 Message-Id: <1517761364-17655-5-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 04/11] conntrack: Support fragmentation. 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 The conntrack module now calls fragmentation support apis. Signed-off-by: Darrell Ball --- NEWS | 2 ++ lib/conntrack.c | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/NEWS b/NEWS index 8c360ba..ee1f272 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ Post-v2.9.0 "table#". These are not helpful names for the purpose of accepting and displaying table names, so now tables by default have no names. + - Userspace datapath: + * Add v4/v6 fragmentation support for conntrack. v2.9.0 - xx xxx xxxx -------------------- diff --git a/lib/conntrack.c b/lib/conntrack.c index d34eb32..2894a77 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -30,6 +30,7 @@ #include "ct-dpif.h" #include "dp-packet.h" #include "flow.h" +#include "ipf.h" #include "netdev.h" #include "odp-netlink.h" #include "openvswitch/hmap.h" @@ -340,6 +341,7 @@ conntrack_init(struct conntrack *ct) atomic_init(&ct->n_conn_limit, DEFAULT_N_CONN_LIMIT); latch_init(&ct->clean_thread_exit); ct->clean_thread = ovs_thread_create("ct_clean", clean_thread_main, ct); + ipf_init(); } /* Destroys the connection tracker 'ct' and frees all the allocated memory. */ @@ -382,6 +384,7 @@ conntrack_destroy(struct conntrack *ct) hindex_destroy(&ct->alg_expectation_refs); ct_rwlock_unlock(&ct->resources_lock); ct_rwlock_destroy(&ct->resources_lock); + ipf_destroy(); } static unsigned hash_to_bucket(uint32_t hash) @@ -1308,6 +1311,8 @@ conntrack_execute(struct conntrack *ct, struct dp_packet_batch *pkt_batch, const struct nat_action_info_t *nat_action_info, long long now) { + ipf_preprocess_conntrack(pkt_batch, now, dl_type, zone, ct->hash_basis); + struct dp_packet *packet; struct conn_lookup_ctx ctx; @@ -1321,6 +1326,8 @@ conntrack_execute(struct conntrack *ct, struct dp_packet_batch *pkt_batch, setlabel, nat_action_info, tp_src, tp_dst, helper); } + ipf_postprocess_conntrack(pkt_batch, now, dl_type); + return 0; } From patchwork Sun Feb 4 16:22:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869048 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bjYQYJoj"; dkim-atps=neutral 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 3zZGLP0Z1qz9s7v for ; Mon, 5 Feb 2018 03:26:05 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 66325FE1; Sun, 4 Feb 2018 16:23:08 +0000 (UTC) X-Original-To: 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 F0F18F5E for ; Sun, 4 Feb 2018 16:23:04 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f68.google.com (mail-pl0-f68.google.com [209.85.160.68]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6CB5E32F for ; Sun, 4 Feb 2018 16:23:04 +0000 (UTC) Received: by mail-pl0-f68.google.com with SMTP id f4so10110634plr.10 for ; Sun, 04 Feb 2018 08:23:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=09cVJ+QyzzPOjgJa/DmEFX8/QU4T7ybhxsXPb+lLcpk=; b=bjYQYJoj4JmxhRhYhHd6rnUHCV0GCwPxlZuz2CPkT/CuNzlVRqk7sZ2QP2k/Ju4pq9 NeQPeK+nbRpt30RXrk6N2u8x621S5w/UyILqcjzY5zPDLdDFVXD5oOOt/N9Jhf4jeBZV eOftJT5EZD+MMdMqeTCpGKMIaIaCfx3KeBolt6MW065SGqjgDkr1PKXfXViWQY+7zYA1 yUK5fLa7eNRilWQzcL5mBtkswU6vxPPYyhnFnNLq6Z2zDnmaYCr8JkegKz4JiQRhtN0g b4QE93QR9MoETbGqq23b/5er7VMT0m+pSCMXEfXEjbHLwcAscSNuzb6Vdedj5hrDB2uM N23Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=09cVJ+QyzzPOjgJa/DmEFX8/QU4T7ybhxsXPb+lLcpk=; b=UXIMSAxnDB8v6xYwXM0dBQQsuhwpfi9W+yagl0jFr2VuDc8nQAOF4mtflgCCOYKTXT UKwFIedUBsIIytqhBW9mhID/monKEcMG0Yn4uQJNuS5DNJU8P7l05DOR87Q7fEnCG3YD DoKxzl0VD/lNbr6/jSsXHwYrNJ61VSrqQAfVtbSekZp6ODK5n2rY/DGICR5VDluTZarn U0a722/1DhfucCN4UMFFJsTpg7EcQWG6sWWZoZZtwr1GdrCmtkC3f8Ov5vzE4mixL6TR SmX0pgQAqpLnD6KpQElNvJqrvaFGOce9O2DEsBukJKeICRxGyHJVzC05UFJUdnd/MoKU R1JQ== X-Gm-Message-State: AKwxytc0LZqQW11HwgNk+hWFcesmnlKBDJ4/2gerrm4UOOBvwVhtMlMU 9YAeJocjrmN2FVZilVmCfZI= X-Google-Smtp-Source: AH8x227uqyQieSOFh/1ATCS0l44VXnAkePILSQE27qYTpl2UYNVSQF3XbWTsPwyCDoaFE5oDfWpvSw== X-Received: by 2002:a17:902:6716:: with SMTP id f22-v6mr41999057plk.180.1517761384008; Sun, 04 Feb 2018 08:23:04 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:03 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:38 -0800 Message-Id: <1517761364-17655-6-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 05/11] ipf: Add command to enable fragmentation handling. 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 A new command "ovs-appctl dpctl/ipf-set-enabled" is added to enable/disable userspace datapath conntrack fragmentation support. Signed-off-by: Darrell Ball --- NEWS | 2 ++ lib/ct-dpif.c | 8 ++++++++ lib/ct-dpif.h | 1 + lib/dpctl.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/dpctl.man | 11 +++++++++++ lib/dpif-netdev.c | 9 +++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 2 ++ lib/ipf.c | 15 +++++++++++++++ lib/ipf.h | 3 +++ 10 files changed, 92 insertions(+) diff --git a/NEWS b/NEWS index ee1f272..d53d95d 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ Post-v2.9.0 - Userspace datapath: * Add v4/v6 fragmentation support for conntrack. + * New "ovs-appctl dpctl/ipf-set-enabled" command for userspace datapath + conntrack fragmentation support. v2.9.0 - xx xxx xxxx -------------------- diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 5fa3a97..32d55c1 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -164,6 +164,14 @@ ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns) : EOPNOTSUPP); } +int +ct_dpif_ipf_change_enabled(struct dpif *dpif, bool v6, bool enable) +{ + return (dpif->dpif_class->ipf_change_enabled + ? dpif->dpif_class->ipf_change_enabled(dpif, v6, enable) + : EOPNOTSUPP); +} + void ct_dpif_entry_uninit(struct ct_dpif_entry *entry) { diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 09e7698..3f0bce5 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -200,6 +200,7 @@ int ct_dpif_flush(struct dpif *, const uint16_t *zone, int ct_dpif_set_maxconns(struct dpif *dpif, uint32_t maxconns); int ct_dpif_get_maxconns(struct dpif *dpif, uint32_t *maxconns); int ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns); +int ct_dpif_ipf_change_enabled(struct dpif *, bool, bool); void ct_dpif_entry_uninit(struct ct_dpif_entry *); void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *, bool verbose, bool print_stats); diff --git a/lib/dpctl.c b/lib/dpctl.c index 87f0412..7d332aa 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1746,6 +1746,44 @@ dpctl_ct_get_nconns(int argc, const char *argv[], return error; } +static int +dpctl_ct_ipf_change_enabled(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + struct dpif *dpif; + int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 4); + if (!error) { + char v4_or_v6[3] = {0}; + if (ovs_scan(argv[argc - 2], "%2s", v4_or_v6) && + (!strncmp(v4_or_v6, "v4", 2) || !strncmp(v4_or_v6, "v6", 2))) { + uint32_t enabled; + if (ovs_scan(argv[argc - 1], "%"SCNu32, &enabled)) { + error = ct_dpif_ipf_change_enabled( + dpif, !strncmp(v4_or_v6, "v6", 2), enabled); + if (!error) { + dpctl_print(dpctl_p, + "changing fragmentation enabled successful"); + } else { + dpctl_error(dpctl_p, error, + "changing fragmentation enabled failed"); + } + } else { + error = EINVAL; + dpctl_error( + dpctl_p, error, + "parameter missing: 0 for disabled or 1 for enabled"); + } + } else { + error = EINVAL; + dpctl_error(dpctl_p, error, + "parameter missing: v4 for ipv4 or v6 for ipv6"); + } + dpif_close(dpif); + } + + return error; +} + /* Undocumented commands for unit testing. */ static int @@ -2045,6 +2083,8 @@ static const struct dpctl_command all_commands[] = { { "ct-set-maxconns", "[dp] maxconns", 1, 2, dpctl_ct_set_maxconns, DP_RW }, { "ct-get-maxconns", "[dp]", 0, 1, dpctl_ct_get_maxconns, DP_RO }, { "ct-get-nconns", "[dp]", 0, 1, dpctl_ct_get_nconns, DP_RO }, + { "ipf-set-enabled", "[dp] v4_or_v6 enabled", 2, 3, + dpctl_ct_ipf_change_enabled, DP_RW }, { "help", "", 0, INT_MAX, dpctl_help, DP_RO }, { "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO }, diff --git a/lib/dpctl.man b/lib/dpctl.man index 9e9d2dc..491de0b 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -268,3 +268,14 @@ Only supported for userspace datapath. \*(DX\fBct\-get\-nconns\fR [\fIdp\fR] Read the current number of connection tracker connections. Only supported for userspace datapath. +. +.TP +\*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] [\fIv4 or v6\fR] \fBenable\fR +Enables or disables fragmentation handling for the userspace datapath +connection tracker. Either v4 or v6 must be specified. Both v4 and v6 +are disabled by default. When fragmentation handling is enabled, the +rules for handling fragments before entering conntrack should not +differentiate between first and other fragments. Although, this would +logically happen naturally anyways, it is mentioned for clarity. If there +is a need to differentiate between first and other fragments, do it after +conntrack. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index ba62128..d4d0f07 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -47,6 +47,7 @@ #include "flow.h" #include "hmapx.h" #include "id-pool.h" +#include "ipf.h" #include "latch.h" #include "netdev.h" #include "netdev-vport.h" @@ -5871,6 +5872,13 @@ dpif_netdev_ct_get_nconns(struct dpif *dpif, uint32_t *nconns) return conntrack_get_nconns(&dp->conntrack, nconns); } +static int +dpif_netdev_ipf_change_enabled(struct dpif *dpif OVS_UNUSED, bool v6, + bool enable) +{ + return ipf_change_enabled(v6, enable); +} + const struct dpif_class dpif_netdev_class = { "netdev", dpif_netdev_init, @@ -5919,6 +5927,7 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ct_set_maxconns, dpif_netdev_ct_get_maxconns, dpif_netdev_ct_get_nconns, + dpif_netdev_ipf_change_enabled, dpif_netdev_meter_get_features, dpif_netdev_meter_set, dpif_netdev_meter_get, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index f8d75eb..f089617 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -2992,6 +2992,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ct_set_maxconns */ NULL, /* ct_get_maxconns */ NULL, /* ct_get_nconns */ + NULL, /* ipf_change_enabled */ dpif_netlink_meter_get_features, dpif_netlink_meter_set, dpif_netlink_meter_get, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 62b3598..08e0944 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -444,6 +444,8 @@ struct dpif_class { /* Get number of connections tracked. */ int (*ct_get_nconns)(struct dpif *, uint32_t *nconns); + /* IP Fragmentation. */ + int (*ipf_change_enabled)(struct dpif *, bool, bool); /* Meters */ /* Queries 'dpif' for supported meter features. diff --git a/lib/ipf.c b/lib/ipf.c index aa8eeaa..31d31e9 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -1238,3 +1238,18 @@ ipf_destroy(void) ipf_lock_unlock(&ipf_lock); ipf_lock_destroy(&ipf_lock); } + +int +ipf_change_enabled(bool v6, bool enable) +{ + if ((v6 != true && v6 != false) || + (enable != true && enable != false)) { + return 1; + } + if (v6) { + atomic_store_relaxed(&ifp_v6_enabled, enable); + } else { + atomic_store_relaxed(&ifp_v4_enabled, enable); + } + return 0; +} diff --git a/lib/ipf.h b/lib/ipf.h index 5861e96..0b45de9 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -60,4 +60,7 @@ ipf_init(void); void ipf_destroy(void); +int +ipf_change_enabled(bool v6, bool enable); + #endif /* ipf.h */ From patchwork Sun Feb 4 16:22:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869049 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="EO4SdYyG"; dkim-atps=neutral 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 3zZGLx06Qdz9s7v for ; Mon, 5 Feb 2018 03:26:33 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 5D5DFFC1; Sun, 4 Feb 2018 16:23:09 +0000 (UTC) X-Original-To: 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 70D27F87 for ; Sun, 4 Feb 2018 16:23:06 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f67.google.com (mail-pl0-f67.google.com [209.85.160.67]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 7C3F3305 for ; Sun, 4 Feb 2018 16:23:05 +0000 (UTC) Received: by mail-pl0-f67.google.com with SMTP id k8so7906095pli.8 for ; Sun, 04 Feb 2018 08:23:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=pngLDUf7x8zTDuGptJCKN/7m2e2roKYw6labjf7iP+s=; b=EO4SdYyGAdjL60uiE9315hS47yPPa2/BM2V1pUW219owo9FLrmVjghI4DouHNENTvP sw2ij/xnScG/L6bqz1yKvmEQQrcfpKuhwofAEnNY8gcdRLzS1GcDb8OYSnueoLuYZ6Uy rc+2KQTIhCKdrZ/le3LHymaC0OtUjNSodA5q0dWwEIJf8pGwx4N7UIjriEQplf5EEXXX 7aWMksX+O1w+T05GZEnMTnQBE+wL/LADDQzqWJCZjsIX6PHTgroFh1QCJHfMj8C/YymV dgJ+YZzSkQLDWqQJbXNtrgObgxX2uSiyEWMrFkpOCJDDZRKbhkrq8dPEz2Z801gtF7xQ PwTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=pngLDUf7x8zTDuGptJCKN/7m2e2roKYw6labjf7iP+s=; b=GSe63xjgsgp1KIwSvmaSHh6QrjYv3EsHYsI97zrSIAizfpUssUfSg12I6XAYbDZh3/ 3S9910CLJ4gehZ4U5QUu1SK+zbUTp73IvQZUzv3cF1p0ZypqdNFv/9EiObX+LdeKFdyk Gc/Vd0P+rOFTcsjYQQcz42P6t+T0Jaa874jJ1clHzm9SwnEB1QeHa7wsVX/UhpnyUS19 Sh3lID29pBGM0elkjXWK1r8mHnmEB2Qu18XF57W7Mem/SwVwC55gsU8V5Q2Q6bCBBUfy v5aUtkQze8anDaWMOAYoa+S+bLHpg6cbno8a0xauYWjyWL395Bi36BMQbx+pzc6Kw2J3 X+rA== X-Gm-Message-State: AKwxytcZ8zOwZLXYmUDHVa9JlO5rztwUI6UdU2bFyuWislkWO5CDQ+w9 ppysGNF0IJzq3olc/bbx6pE= X-Google-Smtp-Source: AH8x227Zi3qKdiCe/q+6DRCuORan1b9ZzSQw0FFAt0Z8rplpuXs0f2W9R6FOgt/a2s7gBO9ccz05Zg== X-Received: by 2002:a17:902:8284:: with SMTP id y4-v6mr20313606pln.194.1517761385100; Sun, 04 Feb 2018 08:23:05 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:04 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:39 -0800 Message-Id: <1517761364-17655-7-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 06/11] ipf: Add set minimum fragment size command. 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 A new command "ovs-appctl dpctl/ipf-set-minfrag" is added for userspace datapath conntrack fragmentation support. Signed-off-by: Darrell Ball --- NEWS | 2 ++ lib/ct-dpif.c | 8 ++++++++ lib/ct-dpif.h | 1 + lib/dpctl.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/dpctl.man | 7 +++++++ lib/dpif-netdev.c | 8 ++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 2 ++ lib/ipf.c | 23 +++++++++++++++++++++++ lib/ipf.h | 3 +++ 10 files changed, 95 insertions(+) diff --git a/NEWS b/NEWS index d53d95d..e98c990 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ Post-v2.9.0 * Add v4/v6 fragmentation support for conntrack. * New "ovs-appctl dpctl/ipf-set-enabled" command for userspace datapath conntrack fragmentation support. + * New "ovs-appctl dpctl/ipf-set-minfragment" command for userspace + datapath conntrack fragmentation support. v2.9.0 - xx xxx xxxx -------------------- diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 32d55c1..4a93bf6 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -172,6 +172,14 @@ ct_dpif_ipf_change_enabled(struct dpif *dpif, bool v6, bool enable) : EOPNOTSUPP); } +int +ct_dpif_ipf_set_min_frag(struct dpif *dpif, bool v6, uint32_t min_frag) +{ + return (dpif->dpif_class->ipf_set_min_frag + ? dpif->dpif_class->ipf_set_min_frag(dpif, v6, min_frag) + : EOPNOTSUPP); +} + void ct_dpif_entry_uninit(struct ct_dpif_entry *entry) { diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 3f0bce5..449f958 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -201,6 +201,7 @@ int ct_dpif_set_maxconns(struct dpif *dpif, uint32_t maxconns); int ct_dpif_get_maxconns(struct dpif *dpif, uint32_t *maxconns); int ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns); int ct_dpif_ipf_change_enabled(struct dpif *, bool, bool); +int ct_dpif_ipf_set_min_frag(struct dpif *, bool, uint32_t); void ct_dpif_entry_uninit(struct ct_dpif_entry *); void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *, bool verbose, bool print_stats); diff --git a/lib/dpctl.c b/lib/dpctl.c index 7d332aa..3464afe 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1784,6 +1784,44 @@ dpctl_ct_ipf_change_enabled(int argc, const char *argv[], return error; } +static int +dpctl_ct_ipf_set_min_frag(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + struct dpif *dpif; + int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 4); + if (!error) { + char v4_or_v6[3] = {0}; + if (ovs_scan(argv[argc - 2], "%2s", v4_or_v6) && + (!strncmp(v4_or_v6, "v4", 2) || !strncmp(v4_or_v6, "v6", 2))) { + uint32_t min_fragment; + if (ovs_scan(argv[argc - 1], "%"SCNu32, &min_fragment)) { + error = ct_dpif_ipf_set_min_frag( + dpif, !strncmp(v4_or_v6, "v6", 2), min_fragment); + + if (!error) { + dpctl_print(dpctl_p, + "setting minimum fragment size successful"); + } else { + dpctl_error(dpctl_p, error, + "setting minimum fragment size failed"); + } + } else { + error = EINVAL; + dpctl_error(dpctl_p, error, + "parameter missing for minimum fragment size"); + } + } else { + error = EINVAL; + dpctl_error(dpctl_p, error, + "parameter missing: v4 for ipv4 or v6 for ipv6"); + } + dpif_close(dpif); + } + + return error; +} + /* Undocumented commands for unit testing. */ static int @@ -2085,6 +2123,8 @@ static const struct dpctl_command all_commands[] = { { "ct-get-nconns", "[dp]", 0, 1, dpctl_ct_get_nconns, DP_RO }, { "ipf-set-enabled", "[dp] v4_or_v6 enabled", 2, 3, dpctl_ct_ipf_change_enabled, DP_RW }, + { "ipf-set-minfragment", "[dp] v4_or_v6 minfragment", 2, 3, + dpctl_ct_ipf_set_min_frag, DP_RW }, { "help", "", 0, INT_MAX, dpctl_help, DP_RO }, { "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO }, diff --git a/lib/dpctl.man b/lib/dpctl.man index 491de0b..87067f9 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -279,3 +279,10 @@ differentiate between first and other fragments. Although, this would logically happen naturally anyways, it is mentioned for clarity. If there is a need to differentiate between first and other fragments, do it after conntrack. +. +.TP +\*(DX\fBipf\-set\-minfrag\fR [\fIdp\fR] [\fIv4 or v6\fR] \fBminfrag\fR +Sets the minimum fragment size supported by the userspace datapath +connection tracker. Either v4 or v6 must be specified. The default v4 +value is 1200 and the clamped minimum is 400. The default v6 value is +1280, which is also the clamped minimum. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index d4d0f07..44e511f 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5879,6 +5879,13 @@ dpif_netdev_ipf_change_enabled(struct dpif *dpif OVS_UNUSED, bool v6, return ipf_change_enabled(v6, enable); } +static int +dpif_netdev_ipf_set_min_frag(struct dpif *dpif OVS_UNUSED, bool v6, + uint32_t min_frag) +{ + return ipf_set_min_frag(v6, min_frag); +} + const struct dpif_class dpif_netdev_class = { "netdev", dpif_netdev_init, @@ -5928,6 +5935,7 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ct_get_maxconns, dpif_netdev_ct_get_nconns, dpif_netdev_ipf_change_enabled, + dpif_netdev_ipf_set_min_frag, dpif_netdev_meter_get_features, dpif_netdev_meter_set, dpif_netdev_meter_get, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index f089617..8366de8 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -2993,6 +2993,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ct_get_maxconns */ NULL, /* ct_get_nconns */ NULL, /* ipf_change_enabled */ + NULL, /* ipf_set_min_frag */ dpif_netlink_meter_get_features, dpif_netlink_meter_set, dpif_netlink_meter_get, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 08e0944..aa9c490 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -446,6 +446,8 @@ struct dpif_class { /* IP Fragmentation. */ int (*ipf_change_enabled)(struct dpif *, bool, bool); + /* Set minimum fragment allowed. */ + int (*ipf_set_min_frag)(struct dpif *, bool, uint32_t); /* Meters */ /* Queries 'dpif' for supported meter features. diff --git a/lib/ipf.c b/lib/ipf.c index 31d31e9..e78abb4 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -1253,3 +1253,26 @@ ipf_change_enabled(bool v6, bool enable) } return 0; } + +int +ipf_set_min_frag(bool v6, uint32_t value) +{ + /* If the user specifies an unreasonably large number, fragmentation + * will not work well but it will not blow up. */ + if ((!v6 && value < IPF_V4_FRAG_SIZE_LBOUND) || + (v6 && value < IPF_V6_FRAG_SIZE_LBOUND)) { + return 1; + } + + ipf_lock_lock(&ipf_lock); + if (v6) { + atomic_store_relaxed(&min_v6_frag_size, value); + } else { + atomic_store_relaxed(&min_v4_frag_size, value); + max_v4_frag_list_size = DIV_ROUND_UP( + IPV4_PACKET_MAX_SIZE - IPV4_PACKET_MAX_HDR_SIZE, + min_v4_frag_size - IPV4_PACKET_MAX_HDR_SIZE); + } + ipf_lock_unlock(&ipf_lock); + return 0; +} diff --git a/lib/ipf.h b/lib/ipf.h index 0b45de9..277852d 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -63,4 +63,7 @@ ipf_destroy(void); int ipf_change_enabled(bool v6, bool enable); +int +ipf_set_min_frag(bool v6, uint32_t value); + #endif /* ipf.h */ From patchwork Sun Feb 4 16:22:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869054 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="G5a5r1Gm"; dkim-atps=neutral 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 3zZGPl3T7wz9s8J for ; Mon, 5 Feb 2018 03:28:59 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 8BB65104F; Sun, 4 Feb 2018 16:23:15 +0000 (UTC) X-Original-To: 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 5FED3FEF for ; Sun, 4 Feb 2018 16:23:12 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f67.google.com (mail-pl0-f67.google.com [209.85.160.67]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 4A84B322 for ; Sun, 4 Feb 2018 16:23:06 +0000 (UTC) Received: by mail-pl0-f67.google.com with SMTP id v3so10110535plg.3 for ; Sun, 04 Feb 2018 08:23:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=jrKb0wA114boXYsjNu1AMmZinCMZzPd6gd36yvoXKbk=; b=G5a5r1GmFk9A3hex0J4X2cDKfslOV6iXo2OT21BEzeHP5TFoQlvjtxZNG4RRhAVpyC CUtJt0OSPF+UOtqYFEAqByBPajujXLqT0vKnIGpw4C29hI5ToaJv9cVbn36goTzt3Nea FQbE79aoKQxi41t3loRO8vsHcaKeWI3nGhO8iOzIy/BLjO+YU490VDLUPD/C2XyAGMmo 3iyicQANgIDmhLsPF3h1hTRJT9WQgonmywv9KRVTPIm07dtqhiv66bv3CL69BEH54rll 6cJBVLec9uMHhjt0MSyAWfpj0oQXtS58hBWD6MuJLyIfW0LizAr266lqxDCNIMVEeFm6 Vl3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=jrKb0wA114boXYsjNu1AMmZinCMZzPd6gd36yvoXKbk=; b=eeUi/ahv7tA+cId2oVCTAcwHQPnNKMsJFSw56NloIdj+TlCe+AQfN84RtcB3hLq/K5 J//x4jpif/JT8v+dQhfJW1zL1gVJlcs+0CNsVpUs/0a6Qzx/the4sqlP3wmS7DlCqjDx hayStb2FsEcTPIi+U3NXdH/iHq5gpR/egQljaBPjQLWxuhk8a8WJKwNTqO6nU/6LKlL8 jN+YqnUNtiYIIdDcvxjDaPRIJ3M8G27gPqO1K1Tk1VRoWva5zgu+9BkyDL4hRfV6jTTC 4qWY9XSUhE80pfXmXtiI95dZC1mhYFU7SR6sqvZGM9GZhWXMP6rRwnF+M/qZi9ybf2R6 A6Qw== X-Gm-Message-State: AKwxytdDE6CBOU2i8hB6JAyqrL3ZiRXnfti6GN8ivevFsbBpjhNEOb3Z D9P9oawj2QvXoBLKewt+9QU= X-Google-Smtp-Source: AH8x226p86DqOPbOrysumxMdk6L7GWZiS8SHYWEk34nXNkAgg3c7OOm7c2WItTKf8ps4HbtmzKB3Pg== X-Received: by 2002:a17:902:6c0e:: with SMTP id q14-v6mr41782950plk.445.1517761385884; Sun, 04 Feb 2018 08:23:05 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:05 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:40 -0800 Message-Id: <1517761364-17655-8-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 07/11] ipf: Add set maximum fragments supported command. 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 A new command "ovs-appctl dpctl/ipf-set-maxfrags" is added for userspace datapath conntrack fragmentation support. Signed-off-by: Darrell Ball --- NEWS | 2 ++ lib/ct-dpif.c | 8 ++++++++ lib/ct-dpif.h | 1 + lib/dpctl.c | 31 +++++++++++++++++++++++++++++++ lib/dpctl.man | 8 ++++++++ lib/dpif-netdev.c | 8 ++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 2 ++ lib/ipf.c | 10 ++++++++++ lib/ipf.h | 3 +++ 10 files changed, 74 insertions(+) diff --git a/NEWS b/NEWS index e98c990..65ac7ac 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ Post-v2.9.0 conntrack fragmentation support. * New "ovs-appctl dpctl/ipf-set-minfragment" command for userspace datapath conntrack fragmentation support. + * New "ovs-appctl dpctl/ipf-set-maxfrags" command for userspace datapath + conntrack fragmentation support. v2.9.0 - xx xxx xxxx -------------------- diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 4a93bf6..81f9d92 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -180,6 +180,14 @@ ct_dpif_ipf_set_min_frag(struct dpif *dpif, bool v6, uint32_t min_frag) : EOPNOTSUPP); } +int +ct_dpif_ipf_set_nfrag_max(struct dpif *dpif, uint32_t max_frags) +{ + return (dpif->dpif_class->ipf_set_nfrag_max + ? dpif->dpif_class->ipf_set_nfrag_max(dpif, max_frags) + : EOPNOTSUPP); +} + void ct_dpif_entry_uninit(struct ct_dpif_entry *entry) { diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 449f958..4ce4dd4 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -202,6 +202,7 @@ int ct_dpif_get_maxconns(struct dpif *dpif, uint32_t *maxconns); int ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns); int ct_dpif_ipf_change_enabled(struct dpif *, bool, bool); int ct_dpif_ipf_set_min_frag(struct dpif *, bool, uint32_t); +int ct_dpif_ipf_set_nfrag_max(struct dpif *, uint32_t); void ct_dpif_entry_uninit(struct ct_dpif_entry *); void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *, bool verbose, bool print_stats); diff --git a/lib/dpctl.c b/lib/dpctl.c index 3464afe..12cccba 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1822,6 +1822,35 @@ dpctl_ct_ipf_set_min_frag(int argc, const char *argv[], return error; } +static int +dpctl_ct_ipf_set_nfrag_max(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + struct dpif *dpif; + int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 3); + if (!error) { + uint32_t nfrags_max; + if (ovs_scan(argv[argc - 1], "%"SCNu32, &nfrags_max)) { + error = ct_dpif_ipf_set_nfrag_max(dpif, nfrags_max); + + if (!error) { + dpctl_print(dpctl_p, + "setting maximum fragments successful"); + } else { + dpctl_error(dpctl_p, error, + "setting maximum fragments failed"); + } + } else { + error = EINVAL; + dpctl_error(dpctl_p, error, + "parameter missing for maximum fragments"); + } + dpif_close(dpif); + } + + return error; +} + /* Undocumented commands for unit testing. */ static int @@ -2125,6 +2154,8 @@ static const struct dpctl_command all_commands[] = { dpctl_ct_ipf_change_enabled, DP_RW }, { "ipf-set-minfragment", "[dp] v4_or_v6 minfragment", 2, 3, dpctl_ct_ipf_set_min_frag, DP_RW }, + { "ipf-set-maxfrags", "[dp] maxfrags", 1, 2, + dpctl_ct_ipf_set_nfrag_max, DP_RW }, { "help", "", 0, INT_MAX, dpctl_help, DP_RO }, { "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO }, diff --git a/lib/dpctl.man b/lib/dpctl.man index 87067f9..53b3cdc 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -286,3 +286,11 @@ Sets the minimum fragment size supported by the userspace datapath connection tracker. Either v4 or v6 must be specified. The default v4 value is 1200 and the clamped minimum is 400. The default v6 value is 1280, which is also the clamped minimum. +. +.TP +\*(DX\fBipf\-set\-maxfrags\fR [\fIdp\fR] \fBmaxfrags\fR +Sets the maximum number of fragments tracked by the userspace datapath +connection tracker. The default value is 1000 and the clamped maximum +is 5000. Note that packet buffers can be held by the fragmentation +module while fragments are incomplete, but will timeout after 15 seconds. +Memory pool sizing should be set accordingly when fragmentation is enabled. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 44e511f..925917d 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5886,6 +5886,13 @@ dpif_netdev_ipf_set_min_frag(struct dpif *dpif OVS_UNUSED, bool v6, return ipf_set_min_frag(v6, min_frag); } +static int +dpif_netdev_ipf_set_nfrag_max(struct dpif *dpif OVS_UNUSED, + uint32_t max_frags) +{ + return ipf_set_nfrag_max(max_frags); +} + const struct dpif_class dpif_netdev_class = { "netdev", dpif_netdev_init, @@ -5936,6 +5943,7 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ct_get_nconns, dpif_netdev_ipf_change_enabled, dpif_netdev_ipf_set_min_frag, + dpif_netdev_ipf_set_nfrag_max, dpif_netdev_meter_get_features, dpif_netdev_meter_set, dpif_netdev_meter_get, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 8366de8..6fd3ea8 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -2994,6 +2994,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ct_get_nconns */ NULL, /* ipf_change_enabled */ NULL, /* ipf_set_min_frag */ + NULL, /* ipf_set_nfrag_max */ dpif_netlink_meter_get_features, dpif_netlink_meter_set, dpif_netlink_meter_get, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index aa9c490..7679169 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -448,6 +448,8 @@ struct dpif_class { int (*ipf_change_enabled)(struct dpif *, bool, bool); /* Set minimum fragment allowed. */ int (*ipf_set_min_frag)(struct dpif *, bool, uint32_t); + /* Set maximum number of fragments tracked. */ + int (*ipf_set_nfrag_max)(struct dpif *, uint32_t); /* Meters */ /* Queries 'dpif' for supported meter features. diff --git a/lib/ipf.c b/lib/ipf.c index e78abb4..cddd59a 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -1276,3 +1276,13 @@ ipf_set_min_frag(bool v6, uint32_t value) ipf_lock_unlock(&ipf_lock); return 0; } + +int +ipf_set_nfrag_max(uint32_t value) +{ + if (value > IPF_NFRAG_UBOUND) { + return 1; + } + atomic_store_relaxed(&nfrag_max, value); + return 0; +} diff --git a/lib/ipf.h b/lib/ipf.h index 277852d..fb24078 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -66,4 +66,7 @@ ipf_change_enabled(bool v6, bool enable); int ipf_set_min_frag(bool v6, uint32_t value); +int +ipf_set_nfrag_max(uint32_t value); + #endif /* ipf.h */ From patchwork Sun Feb 4 16:22:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869050 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="oMP1Vsaj"; dkim-atps=neutral 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 3zZGMX224cz9s7v for ; Mon, 5 Feb 2018 03:27:04 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 3ED2FFEA; Sun, 4 Feb 2018 16:23:10 +0000 (UTC) X-Original-To: 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 DCF46F24 for ; Sun, 4 Feb 2018 16:23:07 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f65.google.com (mail-pl0-f65.google.com [209.85.160.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1FF0532F for ; Sun, 4 Feb 2018 16:23:07 +0000 (UTC) Received: by mail-pl0-f65.google.com with SMTP id 36so10123110ple.13 for ; Sun, 04 Feb 2018 08:23:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=B6T0jMf0OhDbW1jVycUYqm46lMoLef/TDvLARwAylF0=; b=oMP1VsajaWnwWmEvdLabAnv/OELhxgPCGD6KgnT5x+M3FEFpRJ+lgEHAKsCFevOu9E zKlTIeX7MVIV0dTZnSD7BJH++1RsaEDiNST3ooghMnDE3Lfh4OKUg+4yInQzJSny95jJ HbQy+/MrUQd6l88UOLm/aqg2nHj1OqBqnCRcP4M/0z6zsK2xg672YMnPm1F0/f2w44Xi yPQb10+l8y7+GHQN+8ro5Ym/I/Z5wP7At4dOlWKb3CZdz+dggTPNfzUrPR92SkP4xWTK PANOIjg6SFwNPOn8Iv4IBAb4f1vYwGM51OfIyh4RZHfaxSysI8XZwfA0oucSVeTx9xk7 nyBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=B6T0jMf0OhDbW1jVycUYqm46lMoLef/TDvLARwAylF0=; b=lwwOyT2iHwWEtAFFkOD2QUzheSVHLat7ZP/rhq/NWTUSOAvGlkMB9Tb/bXhxHH9loG l3xEaT7bPpiuBIyPvpo1jyHrnxZUMonBhFcx/Y2JtRgriI5cw6e65CydAYZqwh5/LbKV izmdLWUJsy3D5aBSp2iIqpanOPFjLnQ8o7BN6OZrEJc+oBHazMIuUo32oNDOSHK3IaYR mx7Nq1HxY8HlotfnV7Xsaug1vU14wvbb5oF2a+06tbH7x6AIqUtRFggRnN+KzZlU7HRh jW4f170yKGHv6hOWwP98dpolyMCrbREHWQGhSFXnorfL9eOcD6au1je7zQSrZwpNGBbC 1HCA== X-Gm-Message-State: AKwxytc1foIykW1sXHuUbEMFeHR7rw91F83EMUSzFehyoLVZ3OdK1OTC HmfJh7tTCQzpLcEcXfCAjK8= X-Google-Smtp-Source: AH8x226h4xOCMV2B3Xno6zOWtVhlQBFSgfeAw0DcL9tGQoy7IxBgPGfXlT77Y6xN3ZC/tqmB6czZxg== X-Received: by 2002:a17:902:526d:: with SMTP id z100-v6mr17335690plh.396.1517761386681; Sun, 04 Feb 2018 08:23:06 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:06 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:41 -0800 Message-Id: <1517761364-17655-9-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 08/11] ipf: Add command to get fragmentation handling status. 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 A new command "ovs-appctl dpctl/ipf-get-status" is added for userspace datapath conntrack fragmentation support. The command shows the configuration status as well as fragment counters. Signed-off-by: Darrell Ball --- NEWS | 2 ++ lib/ct-dpif.c | 21 ++++++++++++++++ lib/ct-dpif.h | 6 +++++ lib/dpctl.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/dpctl.man | 5 ++++ lib/dpif-netdev.c | 33 ++++++++++++++++++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 7 ++++++ lib/ipf.c | 26 +++++++++++++++++++ lib/ipf.h | 3 +++ 10 files changed, 176 insertions(+) diff --git a/NEWS b/NEWS index 65ac7ac..cefa7ff 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ Post-v2.9.0 datapath conntrack fragmentation support. * New "ovs-appctl dpctl/ipf-set-maxfrags" command for userspace datapath conntrack fragmentation support. + * New "ovs-appctl dpctl/ipf-get-status" command for userspace datapath + conntrack fragmentation support. v2.9.0 - xx xxx xxxx -------------------- diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 81f9d92..60c8986 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -188,6 +188,27 @@ ct_dpif_ipf_set_nfrag_max(struct dpif *dpif, uint32_t max_frags) : EOPNOTSUPP); } +int ct_dpif_ipf_get_status(struct dpif *dpif, bool *ipf_v4_enabled, + unsigned int *min_v4_frag_size, unsigned int *nfrag_max, + unsigned int *nfrag, unsigned int *n4frag_accepted, + unsigned int *n4frag_completed_sent, + unsigned int *n4frag_expired_sent, unsigned int *n4frag_too_small, + unsigned int *n4frag_overlap, bool *ipf_v6_enabled, + unsigned int *min_v6_frag_size, unsigned int *n6frag_accepted, + unsigned int *n6frag_completed_sent, + unsigned int *n6frag_expired_sent, unsigned int *n6frag_too_small, + unsigned int *n6frag_overlap) +{ + return (dpif->dpif_class->ipf_get_status + ? dpif->dpif_class->ipf_get_status(dpif, ipf_v4_enabled, + min_v4_frag_size, nfrag_max, nfrag, n4frag_accepted, + n4frag_completed_sent, n4frag_expired_sent, n4frag_too_small, + n4frag_overlap, ipf_v6_enabled, min_v6_frag_size, n6frag_accepted, + n6frag_completed_sent, n6frag_expired_sent, n6frag_too_small, + n6frag_overlap) + : EOPNOTSUPP); +} + void ct_dpif_entry_uninit(struct ct_dpif_entry *entry) { diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 4ce4dd4..8a24128 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -203,6 +203,12 @@ int ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns); int ct_dpif_ipf_change_enabled(struct dpif *, bool, bool); int ct_dpif_ipf_set_min_frag(struct dpif *, bool, uint32_t); int ct_dpif_ipf_set_nfrag_max(struct dpif *, uint32_t); +int ct_dpif_ipf_get_status(struct dpif *dpif, bool *, unsigned int *, + unsigned int *, unsigned int *, unsigned int *, + unsigned int *, unsigned int *, unsigned int *, + unsigned int *, bool *, unsigned int *, + unsigned int *, unsigned int *, unsigned int *, + unsigned int *, unsigned int *); void ct_dpif_entry_uninit(struct ct_dpif_entry *); void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *, bool verbose, bool print_stats); diff --git a/lib/dpctl.c b/lib/dpctl.c index 12cccba..8860903 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1851,6 +1851,77 @@ dpctl_ct_ipf_set_nfrag_max(int argc, const char *argv[], return error; } +static int +dpctl_ct_ipf_get_status(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + struct dpif *dpif; + int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 2); + if (!error) { + bool ipf_v4_enabled; + unsigned int min_v4_frag_size; + unsigned int nfrag_max; + unsigned int nfrag; + unsigned int n4frag_accepted; + unsigned int n4frag_completed_sent; + unsigned int n4frag_expired_sent; + unsigned int n4frag_too_small; + unsigned int n4frag_overlap; + unsigned int min_v6_frag_size; + bool ipf_v6_enabled; + unsigned int n6frag_accepted; + unsigned int n6frag_completed_sent; + unsigned int n6frag_expired_sent; + unsigned int n6frag_too_small; + unsigned int n6frag_overlap; + error = ct_dpif_ipf_get_status(dpif, &ipf_v4_enabled, + &min_v4_frag_size, &nfrag_max, &nfrag, &n4frag_accepted, + &n4frag_completed_sent, &n4frag_expired_sent, &n4frag_too_small, + &n4frag_overlap, &ipf_v6_enabled, &min_v6_frag_size, + &n6frag_accepted, &n6frag_completed_sent, &n6frag_expired_sent, + &n6frag_too_small, &n6frag_overlap); + + if (!error) { + dpctl_print(dpctl_p, "\tFragmentation Module Status\n"); + dpctl_print(dpctl_p, "\t---------------------------\n"); + dpctl_print(dpctl_p, "\tv4 enabled: %u\n", ipf_v4_enabled); + dpctl_print(dpctl_p, "\tv6 enabled: %u\n", ipf_v6_enabled); + dpctl_print(dpctl_p, "\tmax num frags (v4/v6): %u\n", nfrag_max); + dpctl_print(dpctl_p, "\tnum frag: %u\n", nfrag); + dpctl_print(dpctl_p, "\tmin v4 frag size: %u\n", + min_v4_frag_size); + dpctl_print(dpctl_p, "\tv4 frags accepted: %u\n", + n4frag_accepted); + dpctl_print(dpctl_p, "\tv4 frags completed: %u\n", + n4frag_completed_sent); + dpctl_print(dpctl_p, "\tv4 frags expired: %u\n", + n4frag_expired_sent); + dpctl_print(dpctl_p, "\tv4 frags too small: %u\n", + n4frag_too_small); + dpctl_print(dpctl_p, "\tv4 frags overlapped: %u\n", + n4frag_overlap); + dpctl_print(dpctl_p, "\tmin v6 frag size: %u\n", + min_v6_frag_size); + dpctl_print(dpctl_p, "\tv6 frags accepted: %u\n", + n6frag_accepted); + dpctl_print(dpctl_p, "\tv6 frags completed: %u\n", + n6frag_completed_sent); + dpctl_print(dpctl_p, "\tv6 frags expired: %u\n", + n6frag_expired_sent); + dpctl_print(dpctl_p, "\tv6 frags too small: %u\n", + n6frag_too_small); + dpctl_print(dpctl_p, "\tv6 frags overlapped: %u\n", + n6frag_overlap); + } else { + dpctl_error(dpctl_p, error, + "ipf status could not be retrieved"); + } + dpif_close(dpif); + } + + return error; +} + /* Undocumented commands for unit testing. */ static int @@ -2156,6 +2227,7 @@ static const struct dpctl_command all_commands[] = { dpctl_ct_ipf_set_min_frag, DP_RW }, { "ipf-set-maxfrags", "[dp] maxfrags", 1, 2, dpctl_ct_ipf_set_nfrag_max, DP_RW }, + { "ipf-get-status", "[dp]", 0, 1, dpctl_ct_ipf_get_status, DP_RO }, { "help", "", 0, INT_MAX, dpctl_help, DP_RO }, { "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO }, diff --git a/lib/dpctl.man b/lib/dpctl.man index 53b3cdc..e56eb26 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -294,3 +294,8 @@ connection tracker. The default value is 1000 and the clamped maximum is 5000. Note that packet buffers can be held by the fragmentation module while fragments are incomplete, but will timeout after 15 seconds. Memory pool sizing should be set accordingly when fragmentation is enabled. +. +.TP +\*(DX\fBipf\-get\-status\fR [\fIdp\fR] +Gets the configuration settings and fragment counters associated with the +fragmentation handling of the userspace datapath connection tracker. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 925917d..5add8ee 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5893,6 +5893,38 @@ dpif_netdev_ipf_set_nfrag_max(struct dpif *dpif OVS_UNUSED, return ipf_set_nfrag_max(max_frags); } +static int +dpif_netdev_ipf_get_status(struct dpif *dpif OVS_UNUSED, + bool *ipf_v4_enabled, unsigned int *min_v4_frag_size, + unsigned int *nfrag_max, unsigned int *nfrag, + unsigned int *n4frag_accepted, unsigned int *n4frag_completed_sent, + unsigned int *n4frag_expired_sent, unsigned int *n4frag_too_small, + unsigned int *n4frag_overlap, bool *ipf_v6_enabled, + unsigned int *min_v6_frag_size, unsigned int *n6frag_accepted, + unsigned int *n6frag_completed_sent, unsigned int *n6frag_expired_sent, + unsigned int *n6frag_too_small, unsigned int *n6frag_overlap) +{ + struct ipf_status ipf_status; + ipf_get_status(&ipf_status); + *ipf_v4_enabled = ipf_status.ifp_v4_enabled; + *min_v4_frag_size = ipf_status.min_v4_frag_size; + *nfrag_max = ipf_status.nfrag_max; + *nfrag = ipf_status.nfrag; + *n4frag_accepted = ipf_status.n4frag_accepted; + *n4frag_completed_sent = ipf_status.n4frag_completed_sent; + *n4frag_expired_sent = ipf_status.n4frag_expired_sent; + *n4frag_too_small = ipf_status.n4frag_too_small; + *n4frag_overlap = ipf_status.n4frag_overlap; + *ipf_v6_enabled = ipf_status.ifp_v6_enabled; + *min_v6_frag_size = ipf_status.min_v6_frag_size; + *n6frag_accepted = ipf_status.n6frag_accepted; + *n6frag_completed_sent = ipf_status.n6frag_completed_sent; + *n6frag_expired_sent = ipf_status.n6frag_expired_sent; + *n6frag_too_small = ipf_status.n6frag_too_small; + *n6frag_overlap = ipf_status.n6frag_overlap; + return 0; +} + const struct dpif_class dpif_netdev_class = { "netdev", dpif_netdev_init, @@ -5944,6 +5976,7 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ipf_change_enabled, dpif_netdev_ipf_set_min_frag, dpif_netdev_ipf_set_nfrag_max, + dpif_netdev_ipf_get_status, dpif_netdev_meter_get_features, dpif_netdev_meter_set, dpif_netdev_meter_get, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 6fd3ea8..cac931c 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -2995,6 +2995,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ipf_change_enabled */ NULL, /* ipf_set_min_frag */ NULL, /* ipf_set_nfrag_max */ + NULL, /* ipf_get_status */ dpif_netlink_meter_get_features, dpif_netlink_meter_set, dpif_netlink_meter_get, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 7679169..82fbbfc 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -450,6 +450,13 @@ struct dpif_class { int (*ipf_set_min_frag)(struct dpif *, bool, uint32_t); /* Set maximum number of fragments tracked. */ int (*ipf_set_nfrag_max)(struct dpif *, uint32_t); + /* Get fragmentation configuration status and counters. */ + int (*ipf_get_status)(struct dpif *, bool *, unsigned int *, + unsigned int *, unsigned int *, unsigned int *, + unsigned int *, unsigned int *, unsigned int *, + unsigned int *, bool *, unsigned int *, unsigned int *, + unsigned int *, unsigned int *, unsigned int *, + unsigned int *); /* Meters */ /* Queries 'dpif' for supported meter features. diff --git a/lib/ipf.c b/lib/ipf.c index cddd59a..dd92864 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -1286,3 +1286,29 @@ ipf_set_nfrag_max(uint32_t value) atomic_store_relaxed(&nfrag_max, value); return 0; } + +int +ipf_get_status(struct ipf_status *ipf_status) +{ + atomic_read_relaxed(&ifp_v4_enabled, &ipf_status->ifp_v4_enabled); + atomic_read_relaxed(&min_v4_frag_size, &ipf_status->min_v4_frag_size); + atomic_read_relaxed(&nfrag_max, &ipf_status->nfrag_max); + ipf_status->nfrag = atomic_count_get(&nfrag); + ipf_status->n4frag_accepted = atomic_count_get(&n4frag_accepted); + ipf_status->n4frag_completed_sent = + atomic_count_get(&n4frag_completed_sent); + ipf_status->n4frag_expired_sent = + atomic_count_get(&n4frag_expired_sent); + ipf_status->n4frag_too_small = atomic_count_get(&n4frag_too_small); + ipf_status->n4frag_overlap = atomic_count_get(&n4frag_overlap); + atomic_read_relaxed(&ifp_v6_enabled, &ipf_status->ifp_v6_enabled); + atomic_read_relaxed(&min_v6_frag_size, &ipf_status->min_v6_frag_size); + ipf_status->n6frag_accepted = atomic_count_get(&n6frag_accepted); + ipf_status->n6frag_completed_sent = + atomic_count_get(&n6frag_completed_sent); + ipf_status->n6frag_expired_sent = + atomic_count_get(&n6frag_expired_sent); + ipf_status->n6frag_too_small = atomic_count_get(&n6frag_too_small); + ipf_status->n6frag_overlap = atomic_count_get(&n6frag_overlap); + return 0; +} diff --git a/lib/ipf.h b/lib/ipf.h index fb24078..a9fee06 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -69,4 +69,7 @@ ipf_set_min_frag(bool v6, uint32_t value); int ipf_set_nfrag_max(uint32_t value); +int +ipf_get_status(struct ipf_status *ipf_status); + #endif /* ipf.h */ From patchwork Sun Feb 4 16:22:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869051 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="n817rfSs"; dkim-atps=neutral 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 3zZGN810C9z9s7v for ; Mon, 5 Feb 2018 03:27:36 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4A56F100C; Sun, 4 Feb 2018 16:23:11 +0000 (UTC) X-Original-To: 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 880BCFE8 for ; Sun, 4 Feb 2018 16:23:08 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f65.google.com (mail-pl0-f65.google.com [209.85.160.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id CC737305 for ; Sun, 4 Feb 2018 16:23:07 +0000 (UTC) Received: by mail-pl0-f65.google.com with SMTP id 11so10123061plc.9 for ; Sun, 04 Feb 2018 08:23:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=hRaxjMwutepRK1troeUqgp0Mvufzt2VaACCfJUOTFNg=; b=n817rfSsbobG6XOhJLwuhlkQpYWX6lOhxd1B4rsxtwIh2ffiTUxccHWqBWkr+JmGy7 kOoxCD7qffEUNc6JHUVUNzxxS0AeXoRrT6Tl/YLTros6jr2427sVtOXv8lbB/S2RfZV1 FDXu2FhyFocTUmEt6RAFQPz4KfJZp1Xn+KPqOQKAyIyAs3kbWbxvOl9kivASG517vwTI Z8uafmmnBPLbNsisU1jvdH0c+ABUWd4b7d/7PKX8a5QBtmNxA2PRqsFrCRuFF3egwz58 M5W7/A7ejqiH3X+GfwfXld2tLoLU62sZTNOYYDpYLQQARjuySSkOpmHlWnGM/aOe0Xt4 S9KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=hRaxjMwutepRK1troeUqgp0Mvufzt2VaACCfJUOTFNg=; b=K3N44iwxVb/gQ9lg+m+2kgqvrn5m67kS8q0E7PnqudWBnvYhREAoTZI4BLUMQrUagc nsDzfTEuXIdqLngpbAgZpxjuz+yZPgf+NTmaTYLxD6rPlCZhYfbnI3FjcJAB5axYfw0i azImfjk6Yznr2yZ7CpeGsv50RBaFpbJ9+90Zu7o1CinF7FSJ1UoYXfX5r55NTRF5Ep8A k6tiRQSbAznPAuQgFgXEwi5gVOxyxBctFs0x1M3zwABqrdagsrswUS9Vqaeri28yS1gR Xcu6+A/tIpIG2neWwHCBTW5JdFekPbynKy2DeDTPfxJpWCmjfybJhBXg1KneCZrLFmfq FHKQ== X-Gm-Message-State: AKwxytcHbjCaTYih5msXoxXEoK8nxVU6LTeg9IkatqVROFFq39E3kyxZ YvGKasCc4FF304ntoH+UO78qyg== X-Google-Smtp-Source: AH8x226mBRj9pswMd6DY4XAV+SCTwI/Bi4APEBIbFgYRmCRhOp6XaBoNZMJ5L0Yf2eCLqclx+rAbcA== X-Received: by 2002:a17:902:2884:: with SMTP id f4-v6mr18898876plb.35.1517761387490; Sun, 04 Feb 2018 08:23:07 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:06 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:42 -0800 Message-Id: <1517761364-17655-10-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 09/11] ipf: Enhance ipf_get_status. 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 A verbose option is added to dump the frag lists. Signed-off-by: Darrell Ball --- lib/ct-dpif.c | 24 +++++++++++++++++ lib/ct-dpif.h | 4 +++ lib/dpctl.c | 37 ++++++++++++++++++++++++-- lib/dpctl.man | 5 ++-- lib/dpif-netdev.c | 25 ++++++++++++++++++ lib/dpif-netlink.c | 3 +++ lib/dpif-provider.h | 5 ++++ lib/ipf.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ipf.h | 11 ++++++++ 9 files changed, 186 insertions(+), 4 deletions(-) diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 60c8986..adcf42b 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -209,6 +209,30 @@ int ct_dpif_ipf_get_status(struct dpif *dpif, bool *ipf_v4_enabled, : EOPNOTSUPP); } +int +ct_dpif_ipf_dump_start(struct dpif *dpif, struct ipf_dump_ctx **dump_ctx) +{ + return (dpif->dpif_class->ipf_dump_start + ? dpif->dpif_class->ipf_dump_start(dpif, dump_ctx) + : EOPNOTSUPP); +} + +int +ct_dpif_ipf_dump_next(struct dpif *dpif, void *dump_ctx, char **dump) +{ + return (dpif->dpif_class->ipf_dump_next + ? dpif->dpif_class->ipf_dump_next(dpif, dump_ctx, dump) + : EOPNOTSUPP); +} + +int +ct_dpif_ipf_dump_done(struct dpif *dpif, void *dump_ctx) +{ + return (dpif->dpif_class->ipf_dump_done + ? dpif->dpif_class->ipf_dump_done(dpif, dump_ctx) + : EOPNOTSUPP); +} + void ct_dpif_entry_uninit(struct ct_dpif_entry *entry) { diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 8a24128..0db17d9 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -17,6 +17,7 @@ #ifndef CT_DPIF_H #define CT_DPIF_H +#include "ipf.h" #include "openvswitch/types.h" #include "packets.h" @@ -209,6 +210,9 @@ int ct_dpif_ipf_get_status(struct dpif *dpif, bool *, unsigned int *, unsigned int *, bool *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *); +int ct_dpif_ipf_dump_start(struct dpif *dpif, struct ipf_dump_ctx **); +int ct_dpif_ipf_dump_next(struct dpif *dpif, void *, char **); +int ct_dpif_ipf_dump_done(struct dpif *dpif, void *); void ct_dpif_entry_uninit(struct ct_dpif_entry *); void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *, bool verbose, bool print_stats); diff --git a/lib/dpctl.c b/lib/dpctl.c index 8860903..58b4ba9 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -35,6 +35,7 @@ #include "dpif.h" #include "openvswitch/dynamic-string.h" #include "flow.h" +#include "ipf.h" #include "openvswitch/match.h" #include "netdev.h" #include "netdev-dpdk.h" @@ -1851,12 +1852,37 @@ dpctl_ct_ipf_set_nfrag_max(int argc, const char *argv[], return error; } +static void +dpctl_dump_ipf(struct dpif *dpif, struct dpctl_params *dpctl_p) +{ + struct ipf_dump_ctx *dump_ctx; + char *dump; + + int error = ct_dpif_ipf_dump_start(dpif, &dump_ctx); + if (error) { + dpctl_error(dpctl_p, error, "starting ipf dump"); + return; + } + + dpctl_print(dpctl_p, "\n\tFragment Lists:\n\n"); + while (!(error = ct_dpif_ipf_dump_next(dpif, dump_ctx, &dump))) { + dpctl_print(dpctl_p, "%s\n", dump); + free(dump); + } + + if (error && error != EOF) { + dpctl_error(dpctl_p, error, "dumping ipf entry"); + } + + ct_dpif_ipf_dump_done(dpif, dump_ctx); +} + static int dpctl_ct_ipf_get_status(int argc, const char *argv[], struct dpctl_params *dpctl_p) { struct dpif *dpif; - int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 2); + int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 3); if (!error) { bool ipf_v4_enabled; unsigned int min_v4_frag_size; @@ -1915,7 +1941,13 @@ dpctl_ct_ipf_get_status(int argc, const char *argv[], } else { dpctl_error(dpctl_p, error, "ipf status could not be retrieved"); + return error; + } + + if (argc > 1 && !strncmp(argv[argc - 1], "verbose", 7)) { + dpctl_dump_ipf(dpif, dpctl_p); } + dpif_close(dpif); } @@ -2227,7 +2259,8 @@ static const struct dpctl_command all_commands[] = { dpctl_ct_ipf_set_min_frag, DP_RW }, { "ipf-set-maxfrags", "[dp] maxfrags", 1, 2, dpctl_ct_ipf_set_nfrag_max, DP_RW }, - { "ipf-get-status", "[dp]", 0, 1, dpctl_ct_ipf_get_status, DP_RO }, + { "ipf-get-status", "[dp] [verbose]", 0, 2, dpctl_ct_ipf_get_status, + DP_RO }, { "help", "", 0, INT_MAX, dpctl_help, DP_RO }, { "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO }, diff --git a/lib/dpctl.man b/lib/dpctl.man index e56eb26..8cb144a 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -296,6 +296,7 @@ module while fragments are incomplete, but will timeout after 15 seconds. Memory pool sizing should be set accordingly when fragmentation is enabled. . .TP -\*(DX\fBipf\-get\-status\fR [\fIdp\fR] +\*(DX\fBipf\-get\-status\fR [\fIdp\fR] [\fIverbose\fR] Gets the configuration settings and fragment counters associated with the -fragmentation handling of the userspace datapath connection tracker. +fragmentation handling of the userspace datapath connection tracker. If +verbose is specified, also dumps the ipf list entries. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 5add8ee..7dd4784 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5925,6 +5925,28 @@ dpif_netdev_ipf_get_status(struct dpif *dpif OVS_UNUSED, return 0; } +static int +dpif_netdev_ipf_dump_start(struct dpif *dpif OVS_UNUSED, + struct ipf_dump_ctx **ipf_dump_ctx) +{ + return ipf_dump_start(ipf_dump_ctx); +} + +static int +dpif_netdev_ipf_dump_next(struct dpif *dpif OVS_UNUSED, + void *ipf_dump_ctx, char **dump) +{ + return ipf_dump_next(ipf_dump_ctx, dump); +} + +static int +dpif_netdev_ipf_dump_done(struct dpif *dpif OVS_UNUSED, + void *ipf_dump_ctx) +{ + return ipf_dump_done(ipf_dump_ctx); + +} + const struct dpif_class dpif_netdev_class = { "netdev", dpif_netdev_init, @@ -5977,6 +5999,9 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ipf_set_min_frag, dpif_netdev_ipf_set_nfrag_max, dpif_netdev_ipf_get_status, + dpif_netdev_ipf_dump_start, + dpif_netdev_ipf_dump_next, + dpif_netdev_ipf_dump_done, dpif_netdev_meter_get_features, dpif_netdev_meter_set, dpif_netdev_meter_get, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index cac931c..16edd2c 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -2996,6 +2996,9 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ipf_set_min_frag */ NULL, /* ipf_set_nfrag_max */ NULL, /* ipf_get_status */ + NULL, /* ipf_dump_start */ + NULL, /* ipf_dump_next */ + NULL, /* ipf_dump_done */ dpif_netlink_meter_get_features, dpif_netlink_meter_set, dpif_netlink_meter_get, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 82fbbfc..385394f 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -24,6 +24,7 @@ #include "openflow/openflow.h" #include "dpif.h" +#include "ipf.h" #include "util.h" #ifdef __cplusplus @@ -457,6 +458,10 @@ struct dpif_class { unsigned int *, bool *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *); + int (*ipf_dump_start)(struct dpif *, struct ipf_dump_ctx **); + /* Gets an ipf list entry to display. */ + int (*ipf_dump_next)(struct dpif *, void *, char **); + int (*ipf_dump_done)(struct dpif *, void *); /* Meters */ /* Queries 'dpif' for supported meter features. diff --git a/lib/ipf.c b/lib/ipf.c index dd92864..150d74b 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -52,6 +52,10 @@ enum ipf_list_state { IPF_LIST_STATE_NUM, }; +static char *ipf_state_name[IPF_LIST_STATE_NUM] = + {"unused", "reassemble fail", "other frag", "first frag", "last frag", + "first/last frag", "complete"}; + enum ipf_list_type { IPF_FRAG_COMPLETED_LIST, IPF_FRAG_EXPIRY_LIST, @@ -1312,3 +1316,75 @@ ipf_get_status(struct ipf_status *ipf_status) ipf_status->n6frag_overlap = atomic_count_get(&n6frag_overlap); return 0; } + +struct ipf_dump_ctx { + struct hmap_position bucket_pos; +}; + +int +ipf_dump_start(struct ipf_dump_ctx **ipf_dump_ctx) +{ + *ipf_dump_ctx = xzalloc(sizeof **ipf_dump_ctx); + return 0; +} + +static void +ipf_dump_create(const struct ipf_list *ipf_list, struct ds *ds) +{ + + ds_put_cstr(ds, "frag list elem=("); + if (ipf_list->key.dl_type == htons(ETH_TYPE_IP)) { + ds_put_format(ds, "src="IP_FMT",dst="IP_FMT",", + IP_ARGS(ipf_list->key.src_addr.ipv4_aligned), + IP_ARGS(ipf_list->key.dst_addr.ipv4_aligned)); + } else { + ds_put_cstr(ds, "src="); + ipv6_format_addr(&ipf_list->key.src_addr.ipv6_aligned, ds); + ds_put_cstr(ds, ",dst="); + ipv6_format_addr(&ipf_list->key.dst_addr.ipv6_aligned, ds); + ds_put_cstr(ds, ","); + } + + ds_put_format(ds, "recirc_id=%u,ip_id=%u,dl_type=0x%x,zone=%u,nw_proto=%u", + ipf_list->key.recirc_id, ntohl(ipf_list->key.ip_id), + ntohs(ipf_list->key.dl_type), ipf_list->key.zone, + ipf_list->key.nw_proto); + + ds_put_format(ds, ",num_fragments=%u,state=%s", + ipf_list->last_inuse_idx + 1, + ipf_state_name[ipf_list->state]); + + ds_put_cstr(ds, ")"); +} + +int +ipf_dump_next(struct ipf_dump_ctx *ipf_dump_ctx, char **dump) +{ + struct ds ds = DS_EMPTY_INITIALIZER; + ipf_lock_lock(&ipf_lock); + + for (;;) { + struct hmap_node *node = hmap_at_position(&frag_lists, + &ipf_dump_ctx->bucket_pos); + if (!node) { + ipf_lock_unlock(&ipf_lock); + return EOF; + } else { + struct ipf_list *ipf_list_; + INIT_CONTAINER(ipf_list_, node, node); + struct ipf_list ipf_list = *ipf_list_; + ipf_lock_unlock(&ipf_lock); + ipf_dump_create(&ipf_list, &ds); + *dump = xstrdup(ds.string); + ds_destroy(&ds); + return 0; + } + } +} + +int +ipf_dump_done(struct ipf_dump_ctx *ipf_dump_ctx) +{ + free(ipf_dump_ctx); + return 0; +} diff --git a/lib/ipf.h b/lib/ipf.h index a9fee06..866c711 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -72,4 +72,15 @@ ipf_set_nfrag_max(uint32_t value); int ipf_get_status(struct ipf_status *ipf_status); +struct ipf_dump_ctx; + +int +ipf_dump_start(struct ipf_dump_ctx **ipf_dump_ctx); + +int +ipf_dump_next(struct ipf_dump_ctx *ipf_dump_ctx, char **dump); + +int +ipf_dump_done(struct ipf_dump_ctx *ipf_dump_ctx); + #endif /* ipf.h */ From patchwork Sun Feb 4 16:22:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869052 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="GL2lkvXy"; dkim-atps=neutral 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 3zZGNd6dQQz9s7v for ; Mon, 5 Feb 2018 03:28:01 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 40D281010; Sun, 4 Feb 2018 16:23:12 +0000 (UTC) X-Original-To: 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 D2008FF2 for ; Sun, 4 Feb 2018 16:23:08 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f67.google.com (mail-pl0-f67.google.com [209.85.160.67]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id A4AFC305 for ; Sun, 4 Feb 2018 16:23:08 +0000 (UTC) Received: by mail-pl0-f67.google.com with SMTP id g18so10116691plo.7 for ; Sun, 04 Feb 2018 08:23:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=pIapAmr+NOrvfJJVbRqkLBwvc7Mh+4pWbvb977oTckE=; b=GL2lkvXyQdDMA8O0QO06Vz3dSVzc3jwlCUXsYGv/AR8CCqY8sz0JATEEfNVDdrUHDj sICZZ9m6wqkwKbkrujMJl3H04XwzH4iKcNLpqkUWCZdzPQMBfb2OV2irSc5Yg4GjKf3t uUgsY+9oVtloMJQC5pKeYhfAzsOWSGWAPIJb3Y+Zu9LMmv/Ef+vD6J9U8wzejgmdQu3c SIHHeFBGuid1n1OhNLwtlKLXrCEko8V8uXwB/ShG8g6FHrfYbCqJrfwBPx2+FX4EeETD XEIVRoIq9jBn5YGgdwYQ3VwCBBsrw9vXV1w4GozVZn39KMoyf3LRK33HbuKuS8+dpSZD t1JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=pIapAmr+NOrvfJJVbRqkLBwvc7Mh+4pWbvb977oTckE=; b=T7Z9AzA1cHzb7X/9exDD3L+n7U/sRtl03zQQYk/TzYY+8PIUwwJpGiWcnoD/de8l+U A/UydsmaKtEJPnhAUoqYO1V4yipxvPmrthV8YpJMZBjI2o72QImcWvNhUi5EQ7hvMO+J 3q7TANlLbRTKr8jk/u/tS1fkKh6yxc4MCcm9dR+MNOpvHHmaqZ7hcizH/9HiTY17lPAo plBDCzroe093DGJB327jxEeP23qgzo/0OMRoy+l2r7cxdy/TBUW4Yu3ShRMvExz7wcPc SB2U2R/+Vm62/5x338YiXkoLqwpNLpAKaJGYd6pbuQa7w85Zwe+JAtk+u8u0pdtFYI8h EW5g== X-Gm-Message-State: AKwxytdHP+Hs5MThYYNhsNh+59275uAKeupowGtjZPqo0y66deh4E5bx txgIUUyjgHbkyuGUuLC3Z1E= X-Google-Smtp-Source: AH8x224tb/AgF1YOmxlE3cA4KPlzSCRU7xHH7Mq2myfgw4iaSl32yWmXV3fYMxtAHbGZOOJziNBGRg== X-Received: by 2002:a17:902:8496:: with SMTP id c22-v6mr20413848plo.36.1517761388369; Sun, 04 Feb 2018 08:23:08 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:07 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:43 -0800 Message-Id: <1517761364-17655-11-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 10/11] tests: Add missed local stack checks. 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 Signed-off-by: Darrell Ball --- tests/system-traffic.at | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/system-traffic.at b/tests/system-traffic.at index dbd5640..5b59392 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -2093,6 +2093,7 @@ AT_SETUP([conntrack - Fragmentation over vxlan]) OVS_CHECK_VXLAN() CHECK_CONNTRACK() CHECK_CONNTRACK_FRAG() +CHECK_CONNTRACK_LOCAL_STACK() OVS_TRAFFIC_VSWITCHD_START() ADD_BR([br-underlay]) @@ -2145,6 +2146,7 @@ AT_SETUP([conntrack - IPv6 Fragmentation over vxlan]) OVS_CHECK_VXLAN() CHECK_CONNTRACK() CHECK_CONNTRACK_FRAG() +CHECK_CONNTRACK_LOCAL_STACK() OVS_TRAFFIC_VSWITCHD_START() ADD_BR([br-underlay]) From patchwork Sun Feb 4 16:22:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 869053 X-Patchwork-Delegate: ian.stokes@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hiNkYn95"; dkim-atps=neutral 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 3zZGPF4x4rz9s71 for ; Mon, 5 Feb 2018 03:28:33 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id AF5E310BC; Sun, 4 Feb 2018 16:23:14 +0000 (UTC) X-Original-To: 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 A585F1022 for ; Sun, 4 Feb 2018 16:23:10 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f65.google.com (mail-pl0-f65.google.com [209.85.160.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C5AF2305 for ; Sun, 4 Feb 2018 16:23:09 +0000 (UTC) Received: by mail-pl0-f65.google.com with SMTP id o13so10111423pli.6 for ; Sun, 04 Feb 2018 08:23:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=xL4tMIvFvgxFGYoejf65xfA2C/Tn6Z8MrnOidLtcTFM=; b=hiNkYn95mODr7EX+Jm6/kdGP9LqxDijNotMWDUFOYTcGyYAgJogN6KciN3k5DODuW0 wvxaJVbVuOZGYaDwmHCV6m0kIzDp3uL5HcXABMySPhWuGvt31zc7PJnmMCs07IUPSFA+ 1sTlBxLCRhZmyFEvEeZMaBo/44JC/Ndl6HoLvZb23kYHk6iRCOcLVKXW1u5DZh7lnNlb ed+NTqnetGVAsPwKQdqgCY29l65DLaAFnhKX5/2GymFi0tFUT68j8RykHiGXnym84sV3 DmqeMDFQ9+4RSoHL6ythVN4kPSn6jx3O0kX9BxUFukThtu+wUWAUyBmkj5Y8ZOiY8YaK u+fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=xL4tMIvFvgxFGYoejf65xfA2C/Tn6Z8MrnOidLtcTFM=; b=q0/TxQlupqW09hqPpPQqYvdp0SwvczLfWGNGaS0JlqOv5jsXnwJdIM93n1w3ngpWtr fQLiQX/o3icoacBylWDWjZHYnkjpSfD+Xn6n9AvSNeRYYvjlzaMA2oPp9wqT0ERFdFpz 6k1YsrUTW2ro1B5WaqMJKgLMek5AsLFd07893S0AtgSrp1skHnitz+WeKz23EgkmHW5V TNMCpsDTUhlFwcAN5JJMh06XJxWO0at/oiQp6I4Ep2B8nYKtgvkvDHFy/5ATL1PRcfN9 RrHo8R3+rLhgOJrhHx8zhcpJAKj9xTkSknHF+UZAukXKgnZusFo5tkj0gvThEE9uQVeu oWDA== X-Gm-Message-State: AKwxytdkdZm3GatyjlxBJVc8+ZNxOCAfpVoyaL8L0mQq0u1o406pvfk3 cPh/M0hIvUzyinkGWetbjqY= X-Google-Smtp-Source: AH8x224gbjzaXfd9H474HOAX2AoNa0bsKX7hvFrJB0Dlqo8aeTPRRU/dxske7QFq7DH5EJ+MCXcVeg== X-Received: by 2002:a17:902:8585:: with SMTP id e5-v6mr24378273plo.165.1517761389266; Sun, 04 Feb 2018 08:23:09 -0800 (PST) Received: from ubuntu.localdomain (c-73-162-236-45.hsd1.ca.comcast.net. [73.162.236.45]) by smtp.gmail.com with ESMTPSA id e9sm10109503pgv.14.2018.02.04.08.23.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Feb 2018 08:23:08 -0800 (PST) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org Date: Sun, 4 Feb 2018 08:22:44 -0800 Message-Id: <1517761364-17655-12-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517761364-17655-1-git-send-email-dlu998@gmail.com> References: <1517761364-17655-1-git-send-email-dlu998@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [patch v5 11/11] tests: Enable fragmentation for userspace datapath. 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 Signed-off-by: Darrell Ball --- tests/system-kmod-macros.at | 30 ++++++++-- tests/system-traffic.at | 43 ++++++++++---- tests/system-userspace-macros.at | 125 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 173 insertions(+), 25 deletions(-) diff --git a/tests/system-kmod-macros.at b/tests/system-kmod-macros.at index 12b0adf..77faa6b 100644 --- a/tests/system-kmod-macros.at +++ b/tests/system-kmod-macros.at @@ -76,12 +76,6 @@ m4_define([CHECK_CONNTRACK], # m4_define([CHECK_CONNTRACK_ALG]) -# CHECK_CONNTRACK_FRAG() -# -# Perform requirements checks for running conntrack fragmentations tests. -# The kernel always supports fragmentation, so no check is needed. -m4_define([CHECK_CONNTRACK_FRAG]) - # CHECK_CONNTRACK_LOCAL_STACK() # # Perform requirements checks for running conntrack tests with local stack. @@ -123,3 +117,27 @@ m4_define([CHECK_CT_DPIF_GET_NCONNS], [ AT_SKIP_IF([:]) ]) + +# DPCTL_ENABLE_FRAGMENTATION() +# +# The kernel does not support this command. +m4_define([DPCTL_ENABLE_FRAGMENTATION], +[ + +]) + +# DPCTL_CHECK_FRAGMENTATION() +# +# The kernel does not support this command. +m4_define([DPCTL_CHECK_FRAGMENTATION], +[ + +]) + +# DPCTL_CHECK_FRAGMENTATION_FAIL() +# +# The kernel does not support this command. +m4_define([DPCTL_CHECK_FRAGMENTATION], +[ + +]) diff --git a/tests/system-traffic.at b/tests/system-traffic.at index 5b59392..0302823 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -1759,7 +1759,6 @@ AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) @@ -1778,6 +1777,9 @@ priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1 AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms @@ -1788,12 +1790,14 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) +dnl Check userspace conntrack fragmentation counters. +DPCTL_CHECK_FRAGMENTATION() + OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation expiry]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) @@ -1814,17 +1818,22 @@ priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1 AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 1 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 7 packets transmitted, 0 received, 100% packet loss, time 0ms ]) +dnl Check userspace conntrack fragmentation counters. +DPCTL_CHECK_FRAGMENTATION_FAIL() + OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation + vlan]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) @@ -1845,6 +1854,9 @@ priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1 AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms @@ -1855,12 +1867,14 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) +dnl Check userspace conntrack fragmentation counters. +DPCTL_CHECK_FRAGMENTATION() + OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation + cvlan]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() @@ -1888,6 +1902,9 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms @@ -1913,7 +1930,6 @@ AT_CLEANUP AT_SETUP([conntrack - IPv6 fragmentation]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) @@ -1938,6 +1954,9 @@ dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Ipv6 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms @@ -1953,7 +1972,6 @@ AT_CLEANUP AT_SETUP([conntrack - IPv6 fragmentation expiry]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) @@ -1982,6 +2000,9 @@ dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Send an IPv6 fragment. Some time later, it should expire. NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 1 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 7 packets transmitted, 0 received, 100% packet loss, time 0ms @@ -1994,7 +2015,6 @@ AT_CLEANUP AT_SETUP([conntrack - IPv6 fragmentation + vlan]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) @@ -2022,6 +2042,9 @@ dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00:1::4 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms @@ -2037,7 +2060,6 @@ AT_CLEANUP AT_SETUP([conntrack - IPv6 fragmentation + cvlan]) CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() @@ -2066,6 +2088,9 @@ AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00:1::4]) +dnl Enable userspace conntrack fragmentation handling. +DPCTL_ENABLE_FRAGMENTATION() + dnl Ipv6 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00:1::4 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms @@ -2092,7 +2117,6 @@ AT_CLEANUP AT_SETUP([conntrack - Fragmentation over vxlan]) OVS_CHECK_VXLAN() CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() CHECK_CONNTRACK_LOCAL_STACK() OVS_TRAFFIC_VSWITCHD_START() @@ -2145,7 +2169,6 @@ AT_CLEANUP AT_SETUP([conntrack - IPv6 Fragmentation over vxlan]) OVS_CHECK_VXLAN() CHECK_CONNTRACK() -CHECK_CONNTRACK_FRAG() CHECK_CONNTRACK_LOCAL_STACK() OVS_TRAFFIC_VSWITCHD_START() diff --git a/tests/system-userspace-macros.at b/tests/system-userspace-macros.at index 20a8635..85b0bf4 100644 --- a/tests/system-userspace-macros.at +++ b/tests/system-userspace-macros.at @@ -73,15 +73,6 @@ m4_define([CHECK_CONNTRACK], # m4_define([CHECK_CONNTRACK_ALG]) -# CHECK_CONNTRACK_FRAG() -# -# Perform requirements checks for running conntrack fragmentations tests. -# The userspace doesn't support fragmentation yet, so skip the tests. -m4_define([CHECK_CONNTRACK_FRAG], -[ - AT_SKIP_IF([:]) -]) - # CHECK_CONNTRACK_LOCAL_STACK() # # Perform requirements checks for running conntrack tests with local stack. @@ -121,3 +112,119 @@ m4_define([CHECK_CT_DPIF_SET_GET_MAXCONNS]) # Perform requirements checks for running ovs-dpctl ct-get-nconns. The # userspace datapath does support this feature. m4_define([CHECK_CT_DPIF_GET_NCONNS]) + +# DPCTL_ENABLE_FRAGMENTATION() +# +# The userspace datapath supports this command and needs it to enable +# fragmentation handling. +m4_define([DPCTL_ENABLE_FRAGMENTATION], +[ +AT_CHECK([ovs-appctl dpctl/ipf-set-enabled v4 1], [], [dnl +changing fragmentation enabled successful +]) +AT_CHECK([ovs-appctl dpctl/ipf-set-enabled v6 1], [], [dnl +changing fragmentation enabled successful +]) +AT_CHECK([ovs-appctl dpctl/ipf-set-minfragment v4 1111], [], [dnl +setting minimum fragment size successful +]) +AT_CHECK([ovs-appctl dpctl/ipf-set-maxfrags 500], [], [dnl +setting maximum fragments successful +]) +AT_CHECK([ovs-appctl dpctl/ipf-get-status], [], [dnl + Fragmentation Module Status + --------------------------- + v4 enabled: 1 + v6 enabled: 1 + max num frags (v4/v6): 500 + num frag: 0 + min v4 frag size: 1111 + v4 frags accepted: 0 + v4 frags completed: 0 + v4 frags expired: 0 + v4 frags too small: 0 + v4 frags overlapped: 0 + min v6 frag size: 1280 + v6 frags accepted: 0 + v6 frags completed: 0 + v6 frags expired: 0 + v6 frags too small: 0 + v6 frags overlapped: 0 +]) +]) + +# DPCTL_CHECK_FRAGMENTATION() +# +# Used to check fragmentation counters for some fragmentation tests using +# the userspace datapath. +m4_define([DPCTL_CHECK_FRAGMENTATION], +[ +AT_CHECK([ovs-appctl dpctl/ipf-get-status verbose], [], [dnl + Fragmentation Module Status + --------------------------- + v4 enabled: 1 + v6 enabled: 1 + max num frags (v4/v6): 500 + num frag: 0 + min v4 frag size: 1111 + v4 frags accepted: 30 + v4 frags completed: 30 + v4 frags expired: 0 + v4 frags too small: 0 + v4 frags overlapped: 0 + min v6 frag size: 1280 + v6 frags accepted: 0 + v6 frags completed: 0 + v6 frags expired: 0 + v6 frags too small: 0 + v6 frags overlapped: 0 + + Fragment Lists: + +]) +]) + +# FORMAT_FRAG_LIST([]) +# +# Strip content from the piped input which can differ from test to test; recirc_id +# and ip_id fields in an ipf_list vary from test to test and hence are cleared. +m4_define([FORMAT_FRAG_LIST], + [[sed -e 's/ip_id=[0-9]*/ip_id=/g' -e 's/recirc_id=[0-9]*/recirc_id=/g']]) + +# DPCTL_CHECK_FRAGMENTATION_FAIL() +# +# Used to check fragmentation counters for some fragmentation tests using +# the userspace datapath, when failure to transmit fragments is expected. +m4_define([DPCTL_CHECK_FRAGMENTATION_FAIL], +[ +AT_CHECK([ovs-appctl dpctl/ipf-get-status verbose | FORMAT_FRAG_LIST()], [], [dnl + Fragmentation Module Status + --------------------------- + v4 enabled: 1 + v6 enabled: 1 + max num frags (v4/v6): 500 + num frag: 7 + min v4 frag size: 1111 + v4 frags accepted: 7 + v4 frags completed: 0 + v4 frags expired: 0 + v4 frags too small: 0 + v4 frags overlapped: 0 + min v6 frag size: 1280 + v6 frags accepted: 0 + v6 frags completed: 0 + v6 frags expired: 0 + v6 frags too small: 0 + v6 frags overlapped: 0 + + Fragment Lists: + +frag list elem=(src=10.1.1.1,dst=10.1.1.2,recirc_id=,ip_id=,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag) +frag list elem=(src=10.1.1.1,dst=10.1.1.2,recirc_id=,ip_id=,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag) +frag list elem=(src=10.1.1.1,dst=10.1.1.2,recirc_id=,ip_id=,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag) +frag list elem=(src=10.1.1.1,dst=10.1.1.2,recirc_id=,ip_id=,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag) +frag list elem=(src=10.1.1.1,dst=10.1.1.2,recirc_id=,ip_id=,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag) +frag list elem=(src=10.1.1.1,dst=10.1.1.2,recirc_id=,ip_id=,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag) +frag list elem=(src=10.1.1.1,dst=10.1.1.2,recirc_id=,ip_id=,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag) +]) +])