From patchwork Mon Jul 9 23:48:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrell Ball X-Patchwork-Id: 941746 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; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LTLnvqF5"; 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 41PhvV1Xspz9s0W for ; Tue, 10 Jul 2018 09:52:06 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 46CD6FB3; Mon, 9 Jul 2018 23:48:43 +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 5BB7BEB0 for ; Mon, 9 Jul 2018 23:48:41 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf0-f193.google.com (mail-pf0-f193.google.com [209.85.192.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C3F7AE2 for ; Mon, 9 Jul 2018 23:48:40 +0000 (UTC) Received: by mail-pf0-f193.google.com with SMTP id e10-v6so14758255pfn.1 for ; Mon, 09 Jul 2018 16:48:40 -0700 (PDT) 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=6PSrfwPEiKuTyaONjw/k2J+TWzKCTLrgt/QzLwC1mOk=; b=LTLnvqF53GQBMaitNkgpSlhS5bIa3YpMUuENAE+Y3oIRiRrWipBXoR3HE6BvMgUFyl 83vnKk58DNt5HfbIJ5nUrkvz2OtExz4mc4Q5GSCcs5XKIIbcRJPDy11eJBdr0uml/5rv b1Kfgm5stcMEgoc8fs9kRXjcSTpoCtBaY0SABWiGbOLqOElyobdrSliQ3H7ijQaI5KZb KjeDa5soaCVKclQAbVdpGHxWhWuUyM4wSDa851Tf7o9n15tis+Pkh/cpU5XyR5o52zxv Jrr0IiCknmomS+8rJECRVOteSdQfU6v3VLWy2Vx4DM26RtIdWpaTxv8itWcWW9Yrs4pd Ondg== 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=6PSrfwPEiKuTyaONjw/k2J+TWzKCTLrgt/QzLwC1mOk=; b=aUHxmRKeZCNfTFSEipCdKybZqVDOoHTtCuL3fAg4rtGGKt7DtlH5MzKDSHW/PRPCnQ kU8LaPyDGkBcI+vZtSz1fQuQ6EHb5cxplc1zPgz+xNqDJXQBQ613naq5IWBwxQDRT8sr 11z5TxrMxBst906i2tBwQTYPfI6lz7NcBjV24GbdTIkvBnKZqMo75P+WUf6GsHTH3yA0 ta8w6Gvsz8evHJjh+TAV/sRR4GUkoc+uEAy5b+M2BtyZHgvnHvbMWIPHRGK/slSb8Zjo sVvzH4gfj0CvpK679OAteeaCgMgDqrriXXeTRe8VIbMbJiaB2BRjNonGaX9DGXx6qRyD MVeg== X-Gm-Message-State: APt69E3Aes5D+jbhE6t2CJss9xOfBKKoHaaZRddl9ROUOWoL70AUgEcT it0vShSGFLFlV7WazVJuX+o= X-Google-Smtp-Source: AAOMgpeBfg4JRvPTCKq77sWPKaklE+edKu49p1QlsqBM7x6cihazmw83jyjGzuKh3JTnGE80Aez4sg== X-Received: by 2002:a63:ec14:: with SMTP id j20-v6mr20264503pgh.28.1531180120376; Mon, 09 Jul 2018 16:48:40 -0700 (PDT) Received: from ubuntu.localdomain ([208.91.3.26]) by smtp.gmail.com with ESMTPSA id r188-v6sm30849988pgr.78.2018.07.09.16.48.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Jul 2018 16:48:39 -0700 (PDT) From: Darrell Ball To: dlu998@gmail.com, dev@openvswitch.org, jpettit@ovn.org Date: Mon, 9 Jul 2018 16:48:13 -0700 Message-Id: <1531180095-74941-8-git-send-email-dlu998@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1531180095-74941-1-git-send-email-dlu998@gmail.com> References: <1531180095-74941-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 v7 7/9] 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-min-frag" is added for userspace datapath conntrack fragmentation support. Signed-off-by: Darrell Ball --- NEWS | 2 ++ lib/ct-dpif.c | 8 ++++++++ lib/ct-dpif.h | 2 ++ lib/dpctl.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/dpctl.man | 9 +++++++++ lib/dpif-netdev.c | 8 ++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 3 +++ lib/ipf.c | 23 +++++++++++++++++++++++ lib/ipf.h | 2 ++ 10 files changed, 98 insertions(+) diff --git a/NEWS b/NEWS index 96fa05b..9ab9970 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ Post-v2.9.0 conntrack fragmentation support. * New "ovs-appctl dpctl/ipf-set-disabled" command for userspace datapath conntrack fragmentation support. + * New "ovs-appctl dpctl/ipf-set-min-frag" command for userspace + datapath conntrack fragmentation support. - ovs-vsctl: New commands "add-bond-iface" and "del-bond-iface". - OpenFlow: * OFPT_ROLE_STATUS is now available in OpenFlow 1.3. diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index b1f29dc..d5596af 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -172,6 +172,14 @@ ct_dpif_ipf_set_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 bd6234d..6eb55b4 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" @@ -201,6 +202,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_set_enabled(struct dpif *, bool v6, bool enable); +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 ad7ca8d..e74d713 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1726,6 +1726,44 @@ dpctl_ipf_set_disabled(int argc, const char *argv[], return ipf_set_enabled__(argc, argv, dpctl_p, false); } +static int +dpctl_ipf_set_min_frag(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + struct dpif *dpif; + int error = opt_dpif_open(argc, argv, dpctl_p, 4, &dpif); + 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, + "requested minimum fragment size too small;" + " see documentation"); + } + } 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 @@ -2029,6 +2067,8 @@ static const struct dpctl_command all_commands[] = { dpctl_ipf_set_enabled, DP_RW }, { "ipf-set-disabled", "[dp] v4 | v6", 1, 2, dpctl_ipf_set_disabled, DP_RW }, + { "ipf-set-min-frag", "[dp] v4 | v6 minfragment", 2, 3, + dpctl_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 43d161a..900900d 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -287,3 +287,12 @@ after conntrack. Both v4 and v6 are enabled by default. Disables fragmentation handling for the userspace datapath connection tracker. Either \fBv4\fR or \fBv6\fR must be specified. Both v4 and v6 are enabled by default. +. +.TP +\*(DX\fBipf\-set\-min\-frag\fR [\fIdp\fR] \fBv4\fR | \fBv6\fR \fIminfrag\fR +Sets the minimum fragment size, which applies to non-last fragments, +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, with a clamped minimum of 400, for +testing flexibility. The maximum frag size is not clamped, however setting +this value too high might result in valid fragments being dropped. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index ddab09e..653c313 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -6539,6 +6539,13 @@ dpif_netdev_ipf_set_enabled(struct dpif *dpif OVS_UNUSED, bool v6, return ipf_set_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, @@ -6588,6 +6595,7 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ct_get_maxconns, dpif_netdev_ct_get_nconns, dpif_netdev_ipf_set_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 e1331e4..043398d 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -3007,6 +3007,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ct_get_maxconns */ NULL, /* ct_get_nconns */ NULL, /* ipf_set_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 db65227..62a4574 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 @@ -446,6 +447,8 @@ struct dpif_class { /* IP Fragmentation. */ int (*ipf_set_enabled)(struct dpif *, bool v6, bool enabled); + /* Set minimum fragment allowed. */ + int (*ipf_set_min_frag)(struct dpif *, bool v6, uint32_t min_frag); /* Meters */ /* Queries 'dpif' for supported meter features. diff --git a/lib/ipf.c b/lib/ipf.c index dfb51e4..2b435c7 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -1271,3 +1271,26 @@ ipf_set_enabled(bool v6, bool enable) atomic_store_relaxed(v6 ? &ifp_v6_enabled : &ifp_v4_enabled, 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 da47dcb..fa6da5d 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -59,4 +59,6 @@ void ipf_destroy(void); int ipf_set_enabled(bool v6, bool enable); +int ipf_set_min_frag(bool v6, uint32_t value); + #endif /* ipf.h */